For the complete documentation index, see llms.txt. This page is also available as Markdown.

πŸ€–LLM Guide: Creating vCon Adapters

Drop-into-context guide for LLMs generating vCon adapter code. Spec target: draft-ietf-vcon-vcon-core-02, syntax 0.4.0. Pairs with the vcon-adapter-template repo.

This page is designed to be pasted into a model's context window when you want it to generate adapter code. It encodes the spec target, the canonical scaffold, the library API, and the legacy-field-name traps in one place.

Ground truth

Spec: IETF draft-ietf-vcon-vcon-core-02. The vcon syntax parameter is the string "0.4.0". Any older value (0.0.1, 0.0.2, 0.2.0, 0.3.0) is wrong.

Canonical scaffold: vcon-dev/vcon-adapter-template. New adapters SHOULD start from this template β€” it ships a vcon_builder.py wrapper, HMAC webhook delivery, retries/DLQ, health + Prometheus endpoints, and 14 spec-compliance smoke tests.

Library: vcon β‰₯ 0.9.4. The lib's helpers are spec-correct out of the box β€” use them instead of writing to vcon_dict[...] directly.

The one rule

Always use the vcon library helpers (add_party, add_dialog, add_attachment, add_analysis, add_tag). Never write directly to vcon_dict[...] except for the four documented quirks below.

Imports

import hashlib
import json
import logging
from abc import ABC, abstractmethod
from base64 import urlsafe_b64encode
from datetime import datetime, timezone
from typing import Any

from vcon import Vcon

Party and Dialog model classes are no longer commonly used β€” pass values as kwargs to add_party() / add_dialog() instead.

Create a vCon (handle the four quirks)

Vcon.build_new() has four spec-incorrect behaviors that every adapter must paper over. The template's new_vcon() helper does it for you:

Always call this (or equivalent) instead of Vcon.build_new() directly.

Base adapter pattern

Parties

Do NOT pass did= β€” the did field was removed in 0.4.0.

Dialogs (text, recording, video)

External media (recordings)

Do NOT emit a hex content_hash. Always sha512-<base64url-of-digest> (no = padding).

Analysis (transcripts, sentiment, summaries)

Field name is schema, NOT schema_version. vendor is REQUIRED β€” the lib raises TypeError if you omit it.

Standard core attachment β€” uses purpose:

The lawful_basis extension is the only documented exception β€” it uses type: "lawful_basis". See Extensions Cookbook.

Tags

Library β‰₯0.9.3 writes party: 0, dialog: 0 on the tags attachment correctly.

Extensions

Every extension used MUST appear in top-level extensions[]. The template includes this in new_vcon().

NEVER write these field names

❌ Never
βœ… Always
Where

appended

amended

top-level metadata

must_support

critical

top-level metadata

schema_version

schema

analysis

type

purpose

attachments (except lawful_basis)

did

(removed)

party

0.2.0, 0.3.0

"0.4.0"

vcon syntax param

Timestamps

Always ISO-8601 with timezone:

Never emit naive datetimes.

Dialog types

Type
Use for

"text"

Messages, chat, IVR prompts, individual transcript turns

"recording"

Audio recordings

"video"

Video recordings / calls

"transfer"

Call transfers β€” see add_transfer_dialog

"incomplete"

Failed/abandoned calls β€” see add_incomplete_dialog

MIME types (mediatype)

  • Text: "text/plain", "text/html"

  • Audio: "audio/wav", "audio/mp3", "audio/ogg", "audio/x-wav"

  • Video: "video/mp4", "video/webm"

  • Email: "message/rfc822"

The field name is mediatype, not mimetype, in the spec (the library accepts both as kwarg names).

Validation

Always end transform_to_vcon with library validation:

For stronger checking, copy the smoke tests from vcon-adapter-template/tests/test_vcon_builder.py.

Testing pattern

Delivery (downstream)

For HTTP webhook delivery, sign the body with HMAC-SHA256 (X-Hub-Signature-256: sha256=<hex>), key the request off the vCon uuid as Idempotency-Key, retry with exponential backoff, persist failures to a dead-letter queue. The template's webhook_delivery.py is the reference implementation. See Operational Patterns.

Key considerations

  1. Use the library helpers; never hand-roll vcon_dict[...] (except the four new_vcon quirks).

  2. Set vcon syntax to "0.4.0".

  3. Drop empty group: [] and redacted: {} from build_new().

  4. Attachments use purpose β€” except lawful_basis, which uses type.

  5. Analysis uses schema, never schema_version. vendor is required.

  6. Transcripts live in analysis[], not attachments[].

  7. content_hash is sha512-<base64url>, never hex.

  8. List every extension you use in top-level extensions[].

  9. Timestamps are ISO-8601 with timezone.

  10. Validate before returning.

When generating adapter code, ground every decision on the Spec Compliance Checklist and the Extensions Cookbook. If you're unsure, prefer the shape used by vcon-adapter-template.

Last updated

Was this helpful?