Skip to content

Designate @agentclientprotocol/sdk schema as source of truth (or auto-sync spec docs from it) #1251

@YOMXXX

Description

@YOMXXX

Problem

ACP's spec documentation and the SDK's code-generated schema (@agentclientprotocol/sdk/dist/schema/types.gen.d.ts) are not strictly linked. New implementers building agents/clients have to choose:

  • Read the spec docs → may be slightly out of date relative to the SDK release.
  • Read types.gen.d.ts directly → up-to-date but harder to navigate / no rationale.
  • Read existing reference implementations (Gemini CLI, slopus/happy, OpenHands, Zed) → may have non-spec workarounds mixed in.

We hit this when building atomcode (a Rust ACP agent) and when shipping ~20 PRs against slopus/happy's ACP layer. Specific drift / discoverability gaps we tripped over:

  • ContentChunk.content is a ContentBlock (single), not Array<ContentBlock>. Several implementers initially wrote it as an array (mis-read from prose alone).
  • ToolCall.rawInput (the tool-invocation parameters) vs ToolCall.content (an Array<ToolCallContent> of output). Names easy to confuse without the type signatures in front of you; we initially read content as input in slopus/happy and shipped fixes in slopus/happy#1284.
  • UsageUpdate { size, used } — short field names; easy to assume inputTokens / outputTokens would also exist (they don't, that's only on Cost / per-message usage).
  • Mixed naming convention — filed separately in Document the snake_case discriminator vs camelCase field naming convention #1249.

None of these are SDK bugs — the SDK schema is correct. They're discoverability bugs: someone reading the spec doc without also opening the SDK package is likely to write a non-conforming client/server, then debug it for a day. Once you've burned that day, the lesson is "always read types.gen.d.ts first", and the prose spec becomes secondary documentation.

Proposal

Two options, not mutually exclusive:

Option A — Designate the SDK schema as the source of truth (documentation-only)

Add a clear "Source of truth" callout near the top of the spec site that says:

The authoritative shape of every ACP message is the TypeScript / JSON Schema in @agentclientprotocol/sdk. The narrative spec on this site is for orientation and rationale. When the two disagree, the SDK schema wins; please file an issue.

Plus version-pin each spec doc page to a particular SDK release (e.g. "this page documents v0.14.x").

Option B — Auto-generate the wire-format reference from the schema

Run a build step (e.g. in the docs CI) that reads the SDK's JSON Schema (or the TS types) and generates a reference page or block per type. The narrative spec stays human-edited but always renders the canonical field list + types from the schema. This is what Stripe / OpenAI do for their API reference docs.

Why it matters for the broader ecosystem

There are already ≥4 third-party ACP implementations (slopus/happy, OpenHands, atomcode, plus several clients/agents under discussion in adjacent issues). Each independently rediscovered the same drift gaps and shipped workarounds. Without a designated source of truth, the next implementer will do the same — and every spec-adjacent agent we want to land in the ecosystem (Codex, Kimi, OpenCode, …) inherits the same friction.

Happy to draft the docs patch (Option A) if there's interest. Option B is bigger and would want input from whoever owns the SDK release pipeline.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions