Repository navigation
fix(core): embed dialog audio as base64url, not base64 - #15
Merged
Merged
Conversation
draft-ietf-vcon-vcon-core-04's Attachment/Dialog Object schema restricts `encoding` to "base64url", "json", or "none" -- plain "base64" fails schema validation. With the default MEDIA_BACKEND=embed, every vCon core.base_builder produced failed the schema for exactly this reason. Add core/encoding.py with base64url_encode/decode (unpadded, URL-safe, matching the JWS-style base64url the spec points to in Section 2.4 -- RFC 7515 Appendix C / RFC 4648 Section 5) and use it in base_builder's recording-download path instead of base64.b64encode / encoding="base64". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The vapi, pipecat, and elevenlabs builders each defined their own copy of the same _base64url() helper (already correct: unpadded, URL-safe). Import core.encoding.base64url_encode instead of maintaining three byte-identical copies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two tests asserted the pre-fix, schema-invalid shape: encoding == "base64" and base64.b64decode() on the dialog body. Update both to encoding == "base64url" and core.encoding.base64url_decode(), matching what core.base_builder now actually emits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers arbitrary bytes, bytes that force "-" and "_" into the encoded output (the base64url replacements for "+" and "/"), and every input length mod 4 to exercise base64url_decode's padding restoration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The "vCon Structure" example in README.md still showed the pre-04 "vcon": "0.0.1" / mimetype / encoding: "base64" shape. Update it to 0.4.0 / mediatype / encoding: "base64url" and add a lawful basis attachment to the example. Also fix a "base64" mention in adapters/telnyx/BYOK.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With the default
MEDIA_BACKEND=embed, every vCon failed the vCon core draft-04 schema:'base64' is not one of ['base64url', 'json', 'none']atdialog[0].encoding. Embedded dialog audio is nowbase64url.Changes
core/base_builder.py: inline audio is encoded with unpadded base64url and labelledencoding: "base64url"(wasbase64.b64encodeand"base64"). Unpadded follows draft-04's reference to JWS-style base64url (RFC 7515, RFC 4648 §5) and matches what the Vapi, Pipecat and ElevenLabs builders already emitted.core/encoding.py(new):base64url_encode/base64url_decode, the decoder restoring padding. The three identical per-adapter helpers are replaced by it."vcon": "0.4.0",mediatype,encoding: "base64url", a lawful basis attachment);adapters/telnyx/BYOK.mdupdated.full_audio), still decoded as such;core/media_publisher.pykeeps its owncontent_hashencoder, already unpadded base64url and deliberately kept in step with the SIPREC adapter.Consumers
The conserver's transcription links decode by
encoding, including unpadded base64url, since vcon-dev/vcon-server#208. Deployments on an older conserver should upgrade it before these adapters.Tests
tests/test_encoding.py: round trip over all byte values, bytes that produce-and_(no+,/or=in the output), and padding restoration for every length mod 4.tests/test_builder.pyandtests/adapters/telnyx/test_byok_e2e.pynow expect and decode base64url.LAWFUL_BASIS=consentvalidates against the vCon working group schema. SignalWire never embeds audio.pip install -e ".[dev,s3]":ruff check .andblack --check .clean;pytest625 passed (621 on main).Refs CON-1100
🤖 Generated with Claude Code