Skip to content

adcp 10: a server's adcp_version pin doesn't set the version handlers receive; they always get the packaged 3.3-beta.0 #1685

Closed

Description

@bokelley

Observed (adcp 10.0.0b0)

A server pinned to AdCP 3.2 still hands its handlers requests upgraded to the packaged 3.3-beta.0:

import asyncio
from typing import Any

from adcp.server import ADCPHandler
from adcp.server.mcp_tools import create_tool_caller


class Seller(ADCPHandler[Any]):
    _adcp_version = "3.2"

    async def get_products(self, params, context=None):
        print("handler sees adcp_version:", params.get("adcp_version") if isinstance(params, dict) else getattr(params, "adcp_version", None))
        return {"products": []}


call = create_tool_caller(Seller(), "get_products", supported_versions=["3.2"])
asyncio.run(call({"adcp_version": "3.2", "buying_mode": "brief", "brief": "shoes"}))
handler sees adcp_version: 3.3-beta.0

Cause: adcp/server/mcp_tools.py computes application_version = resolve_adcp_version(None), the packaged default, and converts every request from the wire version up to it. The handler's adcp_version pin and the server's supported_versions aren't consulted.

Why this is a bug, not just behaviour

MIGRATION_v9_to_v10.md says both things:

  • "Pin adcp_version="3.2" on a client or server that must keep a 3.2 contract."
  • "A PlatformHandler or create_adcp_server_from_platform(...) with supported_versions=["3.2"] and no adcp_version serves 3.2."

and also:

  • "Handlers receive requests upgraded to 3.3-beta.0."

A seller that must keep a 3.2 contract can't, through any setting: its handler code and models see 3.3 payloads, and responses are converted down afterwards. A seller can't stay on a stable contract while the SDK's default is a pre-release.

Expected

The server's pinned (or newest supported) release is the application version requests are converted to, and responses are converted from. A 3.2-pinned seller's handlers then see 3.2. If that's not intended, the migration guide should say that a server pin governs only the wire, and that handler code always runs on the SDK's packaged release.

Impact

Found while exploring the Embedded Sales Agent on adcp 10 (draft scope3data/embedded-sales-agent#1042). ESA serves AdCP 3.2 natively. Its request hook had to treat an incoming adcp_version: "3.3-beta.0" (written by the SDK's upgrade) as its native 3.2. Its handlers now run on 3.3-beta models, so a pre-release protocol can change behaviour in a production seller.

Activity

  1. added 2 commits that reference this issue on Oct 28, 2026
    f7d32fb
    24d40e0
  2. bokelley commented on Oct 29, 2026

    @bokelley
    ContributorAuthor

    Fixed on next by #1689: a server's pin (or the newest of its supported_versions) sets the release its handlers run on, on every transport. It ships in SDK 10.0.0b1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions