fix: expose requested AdCP version resolver#855
Merged
Conversation
There was a problem hiding this comment.
LGTM. Follow-ups noted below. Clean, contained additive surface that packages the dispatcher's envelope-field contract for adopters without forking it — right shape: delegates to detect_wire_version and only adds the unnegotiated-default branch on top.
Things I checked
- Helper at
src/adcp/validation/envelope.py:134-162mirrors the dispatcher's envelope-resolution path (src/adcp/server/mcp_tools.py:2101-2182) step-for-step, minus the tool-specific legacy shape probes — and the docstring is explicit about that exclusion. - New "default not in supported" rejection at
envelope.py:160-161closes the edge case both prior reviewers flagged.tests/test_validation_envelope.py:89-93covers it. - Additive change only — no removed or renamed public exports, no signature changes.
feat:-shaped under conventional commits but not breaking, so!is not required. __all__ordering insrc/adcp/server/__init__.py:271,280is consistent with the surrounding block (case-insensitive, not strict ASCII).ad-tech-protocol-expert: sound-with-caveats — no wire-shape footgun for 3.0-vs-3.1 response mismatch, helper compresses dispatch step 1 + step 3 correctly.code-reviewer: sound-with-caveats — semantically equivalent to the dispatcher's envelope-only contract, no layering breaches.
Follow-ups (non-blocking — file as issues)
- Commit prefix. This adds a new public function and re-exports a new error class. Conventional commits says that is
feat:, notfix:. release-please will categorize it as a patch when it should be a minor. Not blocking the merge, but worth catching at the next iteration so the changelog matches the surface. wire_value=defaulton the unnegotiated-default rejection.envelope.py:161raisesUnsupportedVersionError(default, supported)for a buyer that claimed nothing.UnsupportedVersionError.wire_valueis documented as "the original wire value" (envelope.py:52), and the dispatcher echoes it asdetails.claimed_version(mcp_tools.py:2133). The dispatcher does not currently hit this path — only the new public helper can — but if an adopter pipes this exception into the same telemetry,claimed_version: "3.0"will show up for a request where the buyer claimed nothing. Consider either a sentinelwire_value=None+ separatedefaultattribute, or a dedicatedUnsupportedDefaultErrorsubclass. Low-impact for now.SUPPORTED_WIRE_VERSIONSincludes 2.5 viaLEGACY_ADAPTER_VERSIONS. The helper cannot legitimately resolve to 2.5 via envelope fields (2.5 buyers don't carryadcp_version/adcp_major_version), so the legacy entries in the defaultsupported=are dead weight here and invite an adopter to assume this helper handles 2.5 routing. The docstring warns, but the function name does not. Either rename the helper or narrow the defaultsupported=for this entry point.- Docs drift. New public export in
adcp.server— confirmAGENTS.md/README.md/llms.txt/skills/*/SKILL.mdreference the helper where adopters will look for the version-resolution contract. Internal-only addition is fine at minor-release cadence; worth a quick pass before the next 6.2 promotion.
Minor nits (non-blocking)
- Docstring overclaims parity with
detect_wire_version.envelope.py:153-155says the new helper raises "just likedetect_wire_version".detect_wire_versionnever raises for the no-claim case; it returnsNone. The new helper's strict-default branch has no analog. Tighten the wording. - Test module docstring is stale.
tests/test_validation_envelope.py:1still says "Tests foradcp.validation.envelope.detect_wire_version" though four new tests coverresolve_requested_adcp_version. Drop the function suffix. - Coverage gaps in the new tests. No test exercises explicit
adcp_version-rejection routed through the new helper (e.g.{"adcp_version": "9.9"}), and no test passes a customdefault=to confirm the override path. Both are cheap to add.
LGTM. Follow-ups noted.
This was referenced May 26, 2026
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.
What Changed
Adds a public server-facing helper,
resolve_requested_adcp_version(), for adopters that need to apply the same request-version contract as the server dispatcher when shaping handler output.The helper:
adcp_versionfirst and normalizes it to release precisionadcp_major_versionto the base minor when supported3.0supportedsetIt is re-exported from
adcp.serveralongsideUnsupportedVersionError, and tests cover the public import path, explicit 3.1 resolution, legacy 3.0 fallback, and unsupported-default rejection.Why
Issue #851's follow-up noted that the Python SDK still needed a clear, documented version-resolution contract after the 6.1.1 beta improved 3.0/3.1 response shaping. This makes that contract available to adopter handler code without creating a second parser separate from
detect_wire_version().The helper documentation is explicit that it resolves envelope fields only. It does not run the dispatcher's tool-specific legacy shape probes for adapter-routed versions such as 2.5.
Expert Review
3.0even whensupported=("3.1",). Fixed by rejecting unsupported defaults withUnsupportedVersionError.Validation
PYTHONPATH=src pytest tests/test_validation_envelope.py tests/test_schema_validation_server.py tests/test_adcp_version_wire.py tests/test_dispatcher_version_routing.py -qPYTHONPATH=src ruff check src/ tests/test_validation_envelope.pyPYTHONPATH=src mypy src/adcp/server/Also ran
PYTHONPATH=src pytest tests/ -qbefore the final edge-case patch. It reported one unrelated timing-sensitive failure intests/test_permission_denied_budget.py::test_branch_parity_absorbs_registry_variance; rerunning that single test immediately passed.