Implement prompt variable processing for Agent Client Protocol - #3
Conversation
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
…l#1122) Bumps the minor group with 16 updates: | Package | From | To | | --- | --- | --- | | [mint](https://github.com/mintlify/mint/tree/HEAD/packages/mint) | `4.2.531` | `4.2.546` | | [@mintlify/cli](https://github.com/mintlify/mint/tree/HEAD/packages/cli) | `4.0.1134` | `4.0.1149` | | [@mintlify/link-rot](https://github.com/mintlify/mint/tree/HEAD/packages/link-rot) | `3.0.1043` | `3.0.1057` | | [@mintlify/prebuild](https://github.com/mintlify/mint/tree/HEAD/packages/prebuild) | `1.0.1008` | `1.0.1022` | | [@mintlify/previewing](https://github.com/mintlify/mint/tree/HEAD/packages/previewing) | `4.0.1069` | `4.0.1083` | | [b4a](https://github.com/holepunchto/b4a) | `1.8.0` | `1.8.1` | | [bare-os](https://github.com/holepunchto/bare-os) | `3.9.0` | `3.9.1` | | [bare-stream](https://github.com/holepunchto/bare-stream) | `2.13.0` | `2.13.1` | | [basic-ftp](https://github.com/patrickjuchli/basic-ftp) | `5.3.0` | `5.3.1` | | [es-toolkit](https://github.com/toss/es-toolkit) | `1.46.0` | `1.46.1` | | [fast-uri](https://github.com/fastify/fast-uri) | `3.1.0` | `3.1.1` | | [ip-address](https://github.com/beaugunderson/ip-address) | `10.1.1` | `10.2.0` | | [nanoid](https://github.com/ai/nanoid) | `3.3.11` | `3.3.12` | | [node-abi](https://github.com/electron/node-abi) | `3.89.0` | `3.90.0` | | [socks](https://github.com/JoshGlazebrook/socks) | `2.8.7` | `2.8.8` | | [yaml](https://github.com/eemeli/yaml) | `2.8.3` | `2.8.4` | Updates `mint` from 4.2.531 to 4.2.546 - [Commits](https://github.com/mintlify/mint/commits/HEAD/packages/mint) Updates `@mintlify/cli` from 4.0.1134 to 4.0.1149 - [Commits](https://github.com/mintlify/mint/commits/HEAD/packages/cli) Updates `@mintlify/link-rot` from 3.0.1043 to 3.0.1057 - [Commits](https://github.com/mintlify/mint/commits/HEAD/packages/link-rot) Updates `@mintlify/prebuild` from 1.0.1008 to 1.0.1022 - [Commits](https://github.com/mintlify/mint/commits/HEAD/packages/prebuild) Updates `@mintlify/previewing` from 4.0.1069 to 4.0.1083 - [Commits](https://github.com/mintlify/mint/commits/HEAD/packages/previewing) Updates `b4a` from 1.8.0 to 1.8.1 - [Release notes](https://github.com/holepunchto/b4a/releases) - [Commits](holepunchto/b4a@v1.8.0...v1.8.1) Updates `bare-os` from 3.9.0 to 3.9.1 - [Release notes](https://github.com/holepunchto/bare-os/releases) - [Commits](holepunchto/bare-os@v3.9.0...v3.9.1) Updates `bare-stream` from 2.13.0 to 2.13.1 - [Release notes](https://github.com/holepunchto/bare-stream/releases) - [Commits](holepunchto/bare-stream@v2.13.0...v2.13.1) Updates `basic-ftp` from 5.3.0 to 5.3.1 - [Release notes](https://github.com/patrickjuchli/basic-ftp/releases) - [Changelog](https://github.com/patrickjuchli/basic-ftp/blob/master/CHANGELOG.md) - [Commits](patrickjuchli/basic-ftp@v5.3.0...v5.3.1) Updates `es-toolkit` from 1.46.0 to 1.46.1 - [Release notes](https://github.com/toss/es-toolkit/releases) - [Changelog](https://github.com/toss/es-toolkit/blob/main/CHANGELOG.md) - [Commits](toss/es-toolkit@v1.46.0...v1.46.1) Updates `fast-uri` from 3.1.0 to 3.1.1 - [Release notes](https://github.com/fastify/fast-uri/releases) - [Commits](fastify/fast-uri@v3.1.0...v3.1.1) Updates `ip-address` from 10.1.1 to 10.2.0 - [Commits](https://github.com/beaugunderson/ip-address/commits) Updates `nanoid` from 3.3.11 to 3.3.12 - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](ai/nanoid@3.3.11...3.3.12) Updates `node-abi` from 3.89.0 to 3.90.0 - [Release notes](https://github.com/electron/node-abi/releases) - [Commits](electron/node-abi@v3.89.0...v3.90.0) Updates `socks` from 2.8.7 to 2.8.8 - [Release notes](https://github.com/JoshGlazebrook/socks/releases) - [Commits](https://github.com/JoshGlazebrook/socks/commits/2.8.8) Updates `yaml` from 2.8.3 to 2.8.4 - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](eemeli/yaml@v2.8.3...v2.8.4) --- updated-dependencies: - dependency-name: mint dependency-version: 4.2.546 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor - dependency-name: "@mintlify/cli" dependency-version: 4.0.1149 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: "@mintlify/link-rot" dependency-version: 3.0.1057 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: "@mintlify/prebuild" dependency-version: 1.0.1022 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: "@mintlify/previewing" dependency-version: 4.0.1083 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: b4a dependency-version: 1.8.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: bare-os dependency-version: 3.9.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: bare-stream dependency-version: 2.13.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: basic-ftp dependency-version: 5.3.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: es-toolkit dependency-version: 1.46.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: fast-uri dependency-version: 3.1.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: ip-address dependency-version: 10.2.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: minor - dependency-name: nanoid dependency-version: 3.3.12 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: node-abi dependency-version: 3.90.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: minor - dependency-name: socks dependency-version: 2.8.8 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor - dependency-name: yaml dependency-version: 2.8.4 dependency-type: indirect update-type: version-update:semver-patch dependency-group: minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#1121) Bumps the minor group with 2 updates: [serde_with](https://github.com/jonasbb/serde_with) and [serde_with_macros](https://github.com/jonasbb/serde_with). Updates `serde_with` from 3.18.0 to 3.19.0 - [Release notes](https://github.com/jonasbb/serde_with/releases) - [Commits](jonasbb/serde_with@v3.18.0...v3.19.0) Updates `serde_with_macros` from 3.18.0 to 3.19.0 - [Release notes](https://github.com/jonasbb/serde_with/releases) - [Commits](jonasbb/serde_with@v3.18.0...v3.19.0) --- updated-dependencies: - dependency-name: serde_with dependency-version: 3.19.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor - dependency-name: serde_with_macros dependency-version: 3.19.0 dependency-type: indirect update-type: version-update:semver-minor dependency-group: minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…otocol#1120) Bumps [crate-ci/typos](https://github.com/crate-ci/typos) from 1.45.2 to 1.46.0. - [Release notes](https://github.com/crate-ci/typos/releases) - [Changelog](https://github.com/crate-ci/typos/blob/master/CHANGELOG.md) - [Commits](crate-ci/typos@7c57295...bbaefad) --- updated-dependencies: - dependency-name: crate-ci/typos dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
…rotocol#1124) * transports: Revisions on streamable-http/ws GET streams Server->client messages are now delivered over two long-lived GET SSE streams per connection: 1. Connection-scoped stream (GET with Acp-Connection-Id) carries connection-level messages, including responses to session/new and session/load which are produced before the client has a sessionId. 2. Session-scoped stream (GET with Acp-Connection-Id + Acp-Session-Id) carries session updates, request_permission, and responses to session-scoped POSTs. Routing is now done by HTTP header rather than by inspecting the sessionId in every JSON-RPC payload, and per-session streams have independent lifetimes (open/close/resume) without disturbing other sessions on the same connection. Updates the elevator pitch, HTTP transport characteristics, routing table, identity model, message flow diagram (with per-stream C/S annotations), content negotiation rules, unified endpoint routing, connection/session struct, MCP comparison, deviations, FAQ, and revision history. * Format streamable-http-websocket-transport.mdx with prettier Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Anna.Zhdan <anna.zhdan@jetbrains.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Still a lot to do, but putting some of the framework in place.
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
…rotocol#1272) For set and disable, these only ever operate on one at a time.
…#1268) ACP to AG-UI is a protocol bridge that connects any ACP-compatible agent to web frontends via AG-UI events over SSE. Tested with Kiro CLI and Claude Agent ACP, supports CopilotKit, AG-UI HttpAgent, and custom UI integrations. Co-authored-by: Naman Rajpal <namanraj@amazon.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: benbrandt <2111074+benbrandt@users.noreply.github.com>
Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
|
@copilot Please rebase this branch onto the latest
These are generated schema docs. After rebasing, regenerate them from the Rust schema (preserving the new Also fix the failing Force-push with |
- Regenerate JSON schemas to include new prompt variable types - Fix PromptVariableType serialization test to correctly handle Select variant - All schema files now include PromptTemplate, PromptVariable, and PromptVariableType - Schema generation covers both stable and unstable versions (v1 and v2) - All 275 tests now pass successfully Co-authored-by: QuantuM <qumusai@proton.me> Co-authored-by: marekdkropiewnicki-dotcom <259442047+marekdkropiewnicki-dotcom@users.noreply.github.com>
Agent-Logs-Url: https://github.com/marekdkropiewnicki-dotcom/agent-client-protocol/sessions/b38ad0ed-dab7-46bc-9426-8a5132e29e5d Co-authored-by: marekdkropiewnicki-dotcom <259442047+marekdkropiewnicki-dotcom@users.noreply.github.com>
Co-authored-by: marekdkropiewnicki-dotcom <259442047+marekdkropiewnicki-dotcom@users.noreply.github.com>
Done in |
There was a problem hiding this comment.
Pull request overview
This PR expands the Agent Client Protocol schema library with prompt templating + variable metadata, introduces experimental MCP-over-ACP transport surfaces behind a feature flag, and updates schemas/docs/CI to reflect recent protocol and tooling changes.
Changes:
- Add
ContentBlock::PromptTemplate+PromptVariable/PromptVariableType(v1 + v2) and thepromptVariablesprompt capability. - Add unstable MCP-over-ACP request/notification plumbing (v1 + v2) behind
unstable_mcp_over_acp. - Update generated schemas and documentation (including auth/logout stabilization, session delete docs, and new draft protocol pages); add CI MSRV + feature-powerset checks.
Reviewed changes
Copilot reviewed 66 out of 70 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/v2/mod.rs | Gate and re-export v2 MCP-over-ACP module behind unstable_mcp_over_acp. |
| src/v2/content.rs | Add prompt template content block + prompt variable types and tests. |
| src/v2/client.rs | Add MCP-over-ACP request/response/notification variants + method names under feature flag. |
| src/v1/mod.rs | Gate and re-export v1 MCP-over-ACP module behind unstable_mcp_over_acp. |
| src/v1/mcp.rs | Introduce v1 MCP-over-ACP transport types and method-name constants. |
| src/v1/content.rs | Add v1 prompt template content block + prompt variable types and tests. |
| src/v1/client.rs | Add MCP-over-ACP request/response/notification variants + method names under feature flag. |
| src/bin/generate.rs | Improve schema docs generation (notes, anchor disambiguation, method mappings). |
| schema/schema.json | Regenerate stable schema (prompt variables, logout stabilization, etc.). |
| schema/meta.v2.unstable.json | Update v2 unstable method-name metadata for new/renamed methods. |
| schema/meta.unstable.json | Update unstable method-name metadata for new/renamed methods. |
| schema/meta.json | Update stable method-name metadata (logout). |
| README.md | Document artifact vs wire protocol versioning semantics. |
| package.json | Bump Mintlify mint dev dependency version. |
| docs/v2-changes.md | Remove old v2 changes placeholder doc. |
| docs/updates.mdx | Add logout stabilization update entry. |
| docs/rfds/v2/prompt.mdx | Add v2 prompt lifecycle draft RFD. |
| docs/rfds/v2/overview.md | Add v2 proposal tracking RFD and organize v2 draft list. |
| docs/rfds/updates.mdx | Add multiple RFD lifecycle update entries (logout, additional dirs, v2 prompting, etc.). |
| docs/rfds/rust-sdk-v1.mdx | Update Rust SDK RFD status/links and revision history. |
| docs/rfds/model-config-category.mdx | Add model_config category RFD. |
| docs/rfds/mcp-over-acp.mdx | Update MCP-over-ACP RFD with revised schema/examples and bidirectional semantics. |
| docs/rfds/logout-method.mdx | Update logout method RFD wording + revision history for completion. |
| docs/rfds/diff-delete.mdx | Fix author link. |
| docs/rfds/custom-llm-endpoint.mdx | Update provider type names in examples to singular forms. |
| docs/rfds/additional-directories.mdx | Update additionalDirectories proposal semantics and examples. |
| docs/protocol/schema.mdx | Regenerate schema docs (adds schema download note; includes logout + prompt template content). |
| docs/protocol/overview.mdx | Add logout to protocol overview and document key casing conventions. |
| docs/protocol/initialization.mdx | Document auth capabilities and logout capability advertisement. |
| docs/protocol/draft/transports.mdx | Add draft transports documentation page. |
| docs/protocol/draft/tool-calls.mdx | Add draft tool calls documentation page. |
| docs/protocol/draft/terminals.mdx | Add draft terminals documentation page. |
| docs/protocol/draft/slash-commands.mdx | Add draft slash commands documentation page. |
| docs/protocol/draft/session-setup.mdx | Update session setup draft (auth note; additionalDirectories semantics). |
| docs/protocol/draft/session-modes.mdx | Add draft session modes documentation page. |
| docs/protocol/draft/session-list.mdx | Update session list draft notes (additionalDirectories semantics; session delete note). |
| docs/protocol/draft/session-delete.mdx | Add draft session delete documentation page. |
| docs/protocol/draft/session-config-options.mdx | Add draft session config options documentation page. |
| docs/protocol/draft/prompt-turn.mdx | Add draft prompt turn documentation page. |
| docs/protocol/draft/overview.mdx | Add draft protocol overview documentation page. |
| docs/protocol/draft/initialization.mdx | Add draft initialization documentation page. |
| docs/protocol/draft/file-system.mdx | Update draft filesystem guidance for additionalDirectories discovery semantics. |
| docs/protocol/draft/extensibility.mdx | Add draft extensibility documentation page. |
| docs/protocol/draft/error.mdx | Add placeholder draft error documentation page. |
| docs/protocol/draft/content.mdx | Add draft content documentation page. |
| docs/protocol/draft/authentication.mdx | Add draft authentication documentation page. |
| docs/protocol/draft/agent-plan.mdx | Add draft agent plan documentation page. |
| docs/protocol/authentication.mdx | Add stable authentication documentation page (including logout). |
| docs/get-started/clients.mdx | Reorganize and expand list of clients/connectors. |
| docs/docs.json | Update docs navigation (add auth page, draft section pages, reorganize RFDs/announcements). |
| docs/announcements/logout-method-stabilized.mdx | Add logout stabilization announcement page. |
| CHANGELOG.md | Add changelog entries for 0.13.0–0.13.3 and related items. |
| Cargo.toml | Bump crate version, set rust-version, adjust unstable feature flags, bump serde_with. |
| Cargo.lock | Lockfile updates for version/dependency bumps. |
| AGENTS.md | Fix markdown table formatting. |
| .gitignore | Ignore additional agent/tool state directories. |
| .github/workflows/sync-registry.yml | Update pinned actions/create-github-app-token SHA. |
| .github/workflows/release-plz.yml | Update pinned action SHAs for GitHub token + release-plz. |
| .github/workflows/ci.yml | Add MSRV job, add conditional feature-powerset checks, update pinned action SHAs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| for variable in &self.variables { | ||
| if let Some(value) = &variable.value { | ||
| let placeholder = format!("{{{{{}}}}}", variable.name); | ||
| result = result.replace(&placeholder, value); | ||
| } | ||
| } |
| #[serde_as] | ||
| #[skip_serializing_none] | ||
| #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] | ||
| #[non_exhaustive] | ||
| pub struct PromptVariable { |
| for variable in &self.variables { | ||
| if let Some(value) = &variable.value { | ||
| let placeholder = format!("{{{{{}}}}}", variable.name); | ||
| result = result.replace(&placeholder, value); | ||
| } | ||
| } |
| #[serde_as] | ||
| #[skip_serializing_none] | ||
| #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] | ||
| #[non_exhaustive] | ||
| pub struct PromptVariable { |
| // Note: substitute() currently only uses explicit values, not defaults | ||
| // This behavior could be enhanced to use effective_value() | ||
| let result = template.substitute(); | ||
| assert_eq!(result, "{{greeting}} Alice!"); | ||
| } |
There was a problem hiding this comment.
26 issues found across 70 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/v2/agent.rs">
<violation number="1" location="src/v2/agent.rs:4988">
P2: Because `ClientRequest` is `#[serde(untagged)]` and `ListSessionsRequest`'s fields are all optional with no `deny_unknown_fields`, a `session/delete` payload (`{"sessionId": ...}`) risks being silently deserialized as `ListSessionsRequest` instead of the newly added `DeleteSessionRequest`, since it's declared right after it in the enum and untagged matching picks the first variant that parses successfully. Consider whether routing actually relies on this enum's untagged deserialization, and if so, add `#[serde(deny_unknown_fields)]` or reorder/tag the variants to avoid ambiguity.</violation>
</file>
<file name="docs/rfds/v2/overview.md">
<violation number="1" location="docs/rfds/v2/overview.md:33">
P3: Broken link: `../session-fork.mds` has a `.mds` extension instead of `.mdx`. This link would resolve to a non-existent file. Other sibling links in the same section use correct extensions (`../message-id.md`, `../streamable-http-websocket-transport.mdx`).</violation>
<violation number="2" location="docs/rfds/v2/overview.md:59">
P3: Duplicate 'will' in this sentence — should read 'How will things play out once this feature exists?'.</violation>
<violation number="3" location="docs/rfds/v2/overview.md:61">
P3: Typo: "lof" should be "lot". Minor readability issue in the Shiny future section.</violation>
</file>
<file name="docs/protocol/draft/session-config-options.mdx">
<violation number="1" location="docs/protocol/draft/session-config-options.mdx:280">
P2: This link uses `../session-modes` while the earlier reference in the `<Info>` block (and every other sibling link in this docs folder) uses `./session-modes`/`./page-name`. Since `session-modes.mdx` is a sibling file in `docs/protocol/draft/`, this will likely resolve to the stable (non-draft) session-modes page instead of the draft one — recommend changing it to `./session-modes` for consistency and correctness.</violation>
</file>
<file name="Cargo.toml">
<violation number="1" location="Cargo.toml:15">
P2: The new `rust-version = "1.88.0"` raises the crate's MSRV above the 1.85 minimum documented in AGENTS.md/CLAUDE.md; please update the docs (or lower rust-version to 1.85 if 1.88 isn't actually required) to keep them consistent.</violation>
</file>
<file name="docs/protocol/draft/initialization.mdx">
<violation number="1" location="docs/protocol/draft/initialization.mdx:176">
P2: The new 'Prompt capabilities' section lists image, audio, and embeddedContext but omits the new `promptVariables` capability that this PR introduces (already present in the generated schema docs). Consumers reading this narrative doc won't learn that they must advertise `promptVariables` to use `ContentBlock::PromptTemplate`.</violation>
</file>
<file name="docs/protocol/draft/content.mdx">
<violation number="1" location="docs/protocol/draft/content.mdx:14">
P2: This new draft content.mdx duplicates the stable content.mdx verbatim and doesn't document the PromptTemplate content block / promptVariables capability that this PR adds to the schema. Consumers reading the draft docs for prompt variable templating won't find any reference to it here, even though it's a core feature of this PR.</violation>
</file>
<file name="docs/protocol/draft/tool-calls.mdx">
<violation number="1" location="docs/protocol/draft/tool-calls.mdx:45">
P2: The tool kind list under `<Expandable title="kinds">` isn't formatted as one bullet per line, so Markdown will render it as a single run-on paragraph with literal dashes rather than a bulleted list (unlike the correctly formatted Permission Options list further down in the same file). Split each `kind` into its own list item for consistent rendering.</violation>
<violation number="2" location="docs/protocol/draft/tool-calls.mdx:183">
P2: The `outcome` ResponseField description mixes the `cancelled` and `selected` cases into a single run-on sentence with inline dashes, so it won't render as a readable list like the Permission Options section does. Consider splitting into a proper bullet list.</violation>
</file>
<file name="docs/docs.json">
<violation number="1" location="docs/docs.json:103">
P2: The draft navigation group was significantly expanded in this PR, but `protocol/draft/schema-v2` (the generated v2 schema doc) isn't added to any `pages` array, so it will be unreachable in the site sidebar despite existing on disk. Consider adding `protocol/draft/schema-v2` alongside `protocol/draft/schema` in the draft group.</violation>
</file>
<file name="docs/protocol/draft/schema.mdx">
<violation number="1" location="docs/protocol/draft/schema.mdx:6403">
P2: The generated docs for `PromptVariableType`'s select variant are misleading/incomplete: the variant is shown as `Object` with an opaque `select` object field, but never documents the actual required `options: string[]` payload needed to use `PromptVariableType::Select`. Consumers reading this schema page won't know how to construct a valid select-type prompt variable.</violation>
</file>
<file name="src/v1/content.rs">
<violation number="1" location="src/v1/content.rs:589">
P1: `substitute()` ignores `default_value` on `PromptVariable`, leaving placeholders unreplaced when only a default is set.
The method only reads `variable.value` but there's already an `effective_value()` helper that falls back to `default_value` when value is `None`. A caller setting `PromptVariable::new("greeting").default_value("Hello")` would expect the placeholder to resolve; instead `{{greeting}}` stays in the output.
Fix by switching from `variable.value` to `variable.effective_value()`.</violation>
<violation number="2" location="src/v1/content.rs:595">
P3: If `variables` contains duplicate `name` entries, only the first one's value is ever applied — later duplicates silently no-op since the placeholder text is already gone. Worth documenting/guarding against duplicate variable names, or de-duplicating before substitution.</violation>
</file>
<file name="docs/protocol/draft/schema-v2.mdx">
<violation number="1" location="docs/protocol/draft/schema-v2.mdx:6403">
P3: The generated docs label the `Select` variant of `PromptVariableType` as `Object` instead of `select`, and omit the nested `options` array field, making this variant's documentation confusing for API consumers compared to the other named variants (string, number, boolean, etc.).</violation>
</file>
<file name="src/v2/content.rs">
<violation number="1" location="src/v2/content.rs:594">
P2: `substitute()` ignores `default_value`/`effective_value()`, so variables with only a default (no explicit `value`) are left as unreplaced `{{placeholder}}` text instead of using their default. This contradicts the documented behavior ('with defaults') and the purpose of the `default_value`/`effective_value()` API.</violation>
<violation number="2" location="src/v2/content.rs:625">
P3: The `required` flag on `PromptVariable` is never enforced during substitution; callers relying on `required` for validation will get silent unreplaced placeholders instead of an error/signal that a required variable is missing.</violation>
</file>
<file name="docs/rfds/additional-directories.mdx">
<violation number="1" location="docs/rfds/additional-directories.mdx:57">
P2: The new cwd-matching condition on changing `additionalDirectories` via `session/load`/`session/resume` doesn't specify the required behavior when the request's `cwd` differs from the session's stored `cwd` (must the request be rejected, or is `additionalDirectories` simply ignored?). This ambiguity could lead to divergent agent implementations for the exact case this clause is trying to constrain.</violation>
</file>
<file name="schema/schema.json">
<violation number="1" location="schema/schema.json:2249">
P2: PromptVariable.default_value is emitted as snake_case in the wire schema while every other field/type in this protocol uses camelCase (loadSession, mcpCapabilities, promptCapabilities, etc.), breaking the established JSON naming convention for consumers. Add `#[serde(rename_all = "camelCase")]` to `PromptVariable` in both src/v1/content.rs and src/v2/content.rs so this field serializes as `defaultValue`.</violation>
</file>
<file name="docs/protocol/schema.mdx">
<violation number="1" location="docs/protocol/schema.mdx:2747">
P3: The new nullable `PromptVariable` fields (`value`, `default_value`, `description`, `type`) don't state whether `null` and an omitted key are equivalent, which the repo's own doc-generation guideline requires for every nullable field in this file.</violation>
<violation number="2" location="docs/protocol/schema.mdx:2788">
P2: The new `PromptVariableType` select variant is documented incorrectly: it's labeled `Object` instead of `select`, and the required `options: string[]` field is missing entirely from the nested Properties block — an implementer following this doc has no way to know a select variable needs {"select":{"options":[...]}}.</violation>
</file>
<file name="docs/rfds/updates.mdx">
<violation number="1" location="docs/rfds/updates.mdx:9">
P2: The Logout Method RFD Completed entry in `docs/rfds/updates.mdx` uses "May 22, 2026", but the authoritative RFD document (`docs/rfds/logout-method.mdx`), the announcement (`docs/announcements/logout-method-stabilized.mdx`), and the main updates page (`docs/updates.mdx`) all record the date as May 21, 2026. This inconsistency will confuse readers tracking RFD lifecycle dates. Change the label to match the date in the RFD document.</violation>
<violation number="2" location="docs/rfds/updates.mdx:40">
P3: Grammar: missing "has" before "been" in the model_config category RFD entry. The sentence reads "The RFD for the `model_config` category been moved" — it should be "The RFD for the `model_config` category **has** been moved".</violation>
<violation number="3" location="docs/rfds/updates.mdx:47">
P3: Grammar: missing "has" before "been" in the v2 Prompting RFD entry. The sentence reads "...protocol been moved" — it should be "...protocol **has** been moved".</violation>
</file>
<file name="src/v2/client.rs">
<violation number="1" location="src/v2/client.rs:2040">
P0: `MessageMcpResponse` will never deserialize correctly from a JSON response. In `ClientResponse` (which is `#[serde(untagged)]`), `ExtMethodResponse(ExtResponse)` is declared before `MessageMcpResponse(MessageMcpResponse)` -- and both are transparent wrappers around `Arc<RawValue>` that accept any JSON. Serde will always match `ExtMethodResponse` first, so incoming `mcp/message` responses will be routed as extension responses instead of MCP message responses. Move the `MessageMcpResponse` variant before `ExtMethodResponse`.</violation>
</file>
<file name="src/v1/client.rs">
<violation number="1" location="src/v1/client.rs:2040">
P0: `MessageMcpResponse` will never deserialize correctly from a JSON response. In `ClientResponse` (which is `#[serde(untagged)]`), `ExtMethodResponse(ExtResponse)` is declared before `MessageMcpResponse(MessageMcpResponse)` -- and both are transparent wrappers around `Arc<RawValue>` that accept any JSON. Serde will always match `ExtMethodResponse` first, so incoming `mcp/message` responses will be routed as extension responses instead of MCP message responses. Move the `MessageMcpResponse` variant before `ExtMethodResponse`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse), | ||
| ExtMethodResponse(ExtResponse), | ||
| #[cfg(feature = "unstable_mcp_over_acp")] | ||
| MessageMcpResponse(MessageMcpResponse), |
There was a problem hiding this comment.
P0: MessageMcpResponse will never deserialize correctly from a JSON response. In ClientResponse (which is #[serde(untagged)]), ExtMethodResponse(ExtResponse) is declared before MessageMcpResponse(MessageMcpResponse) -- and both are transparent wrappers around Arc<RawValue> that accept any JSON. Serde will always match ExtMethodResponse first, so incoming mcp/message responses will be routed as extension responses instead of MCP message responses. Move the MessageMcpResponse variant before ExtMethodResponse.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/v2/client.rs, line 2040:
<comment>`MessageMcpResponse` will never deserialize correctly from a JSON response. In `ClientResponse` (which is `#[serde(untagged)]`), `ExtMethodResponse(ExtResponse)` is declared before `MessageMcpResponse(MessageMcpResponse)` -- and both are transparent wrappers around `Arc<RawValue>` that accept any JSON. Serde will always match `ExtMethodResponse` first, so incoming `mcp/message` responses will be routed as extension responses instead of MCP message responses. Move the `MessageMcpResponse` variant before `ExtMethodResponse`.</comment>
<file context>
@@ -1982,7 +2031,13 @@ pub enum ClientResponse {
+ DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse),
ExtMethodResponse(ExtResponse),
+ #[cfg(feature = "unstable_mcp_over_acp")]
+ MessageMcpResponse(MessageMcpResponse),
}
</file context>
| DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse), | ||
| ExtMethodResponse(ExtResponse), | ||
| #[cfg(feature = "unstable_mcp_over_acp")] | ||
| MessageMcpResponse(MessageMcpResponse), |
There was a problem hiding this comment.
P0: MessageMcpResponse will never deserialize correctly from a JSON response. In ClientResponse (which is #[serde(untagged)]), ExtMethodResponse(ExtResponse) is declared before MessageMcpResponse(MessageMcpResponse) -- and both are transparent wrappers around Arc<RawValue> that accept any JSON. Serde will always match ExtMethodResponse first, so incoming mcp/message responses will be routed as extension responses instead of MCP message responses. Move the MessageMcpResponse variant before ExtMethodResponse.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/v1/client.rs, line 2040:
<comment>`MessageMcpResponse` will never deserialize correctly from a JSON response. In `ClientResponse` (which is `#[serde(untagged)]`), `ExtMethodResponse(ExtResponse)` is declared before `MessageMcpResponse(MessageMcpResponse)` -- and both are transparent wrappers around `Arc<RawValue>` that accept any JSON. Serde will always match `ExtMethodResponse` first, so incoming `mcp/message` responses will be routed as extension responses instead of MCP message responses. Move the `MessageMcpResponse` variant before `ExtMethodResponse`.</comment>
<file context>
@@ -1982,7 +2031,13 @@ pub enum ClientResponse {
+ DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse),
ExtMethodResponse(ExtResponse),
+ #[cfg(feature = "unstable_mcp_over_acp")]
+ MessageMcpResponse(MessageMcpResponse),
}
</file context>
| /// placeholders with their corresponding values from the variables vector. | ||
| /// If a variable is not found or has no value, the placeholder is left unchanged. | ||
| #[must_use] | ||
| pub fn substitute(&self) -> String { |
There was a problem hiding this comment.
P1: substitute() ignores default_value on PromptVariable, leaving placeholders unreplaced when only a default is set.
The method only reads variable.value but there's already an effective_value() helper that falls back to default_value when value is None. A caller setting PromptVariable::new("greeting").default_value("Hello") would expect the placeholder to resolve; instead {{greeting}} stays in the output.
Fix by switching from variable.value to variable.effective_value().
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/v1/content.rs, line 589:
<comment>`substitute()` ignores `default_value` on `PromptVariable`, leaving placeholders unreplaced when only a default is set.
The method only reads `variable.value` but there's already an `effective_value()` helper that falls back to `default_value` when value is `None`. A caller setting `PromptVariable::new("greeting").default_value("Hello")` would expect the placeholder to resolve; instead `{{greeting}}` stays in the output.
Fix by switching from `variable.value` to `variable.effective_value()`.</comment>
<file context>
@@ -518,6 +526,201 @@ pub enum Role {
+ /// placeholders with their corresponding values from the variables vector.
+ /// If a variable is not found or has no value, the placeholder is left unchanged.
+ #[must_use]
+ pub fn substitute(&self) -> String {
+ let mut result = self.template.clone();
+
</file context>
| /// | ||
| /// This method is only available if the agent advertises the `sessionCapabilities.delete` capability. | ||
| #[cfg(feature = "unstable_session_delete")] | ||
| DeleteSessionRequest(DeleteSessionRequest), |
There was a problem hiding this comment.
P2: Because ClientRequest is #[serde(untagged)] and ListSessionsRequest's fields are all optional with no deny_unknown_fields, a session/delete payload ({"sessionId": ...}) risks being silently deserialized as ListSessionsRequest instead of the newly added DeleteSessionRequest, since it's declared right after it in the enum and untagged matching picks the first variant that parses successfully. Consider whether routing actually relies on this enum's untagged deserialization, and if so, add #[serde(deny_unknown_fields)] or reorder/tag the variants to avoid ambiguity.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/v2/agent.rs, line 4988:
<comment>Because `ClientRequest` is `#[serde(untagged)]` and `ListSessionsRequest`'s fields are all optional with no `deny_unknown_fields`, a `session/delete` payload (`{"sessionId": ...}`) risks being silently deserialized as `ListSessionsRequest` instead of the newly added `DeleteSessionRequest`, since it's declared right after it in the enum and untagged matching picks the first variant that parses successfully. Consider whether routing actually relies on this enum's untagged deserialization, and if so, add `#[serde(deny_unknown_fields)]` or reorder/tag the variants to avoid ambiguity.</comment>
<file context>
@@ -4730,6 +4977,15 @@ pub enum ClientRequest {
+ ///
+ /// This method is only available if the agent advertises the `sessionCapabilities.delete` capability.
+ #[cfg(feature = "unstable_session_delete")]
+ DeleteSessionRequest(DeleteSessionRequest),
#[cfg(feature = "unstable_session_fork")]
/// **UNSTABLE**
</file context>
| - Clients that don't support config options **SHOULD** fall back to `modes` | ||
| - Agents **SHOULD** keep both in sync to ensure consistent behavior regardless of which field the Client uses | ||
|
|
||
| <Card icon="gears" horizontal href="../session-modes"> |
There was a problem hiding this comment.
P2: This link uses ../session-modes while the earlier reference in the <Info> block (and every other sibling link in this docs folder) uses ./session-modes/./page-name. Since session-modes.mdx is a sibling file in docs/protocol/draft/, this will likely resolve to the stable (non-draft) session-modes page instead of the draft one — recommend changing it to ./session-modes for consistency and correctness.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/protocol/draft/session-config-options.mdx, line 280:
<comment>This link uses `../session-modes` while the earlier reference in the `<Info>` block (and every other sibling link in this docs folder) uses `./session-modes`/`./page-name`. Since `session-modes.mdx` is a sibling file in `docs/protocol/draft/`, this will likely resolve to the stable (non-draft) session-modes page instead of the draft one — recommend changing it to `./session-modes` for consistency and correctness.</comment>
<file context>
@@ -0,0 +1,282 @@
+- Clients that don't support config options **SHOULD** fall back to `modes`
+- Agents **SHOULD** keep both in sync to ensure consistent behavior regardless of which field the Client uses
+
+<Card icon="gears" horizontal href="../session-modes">
+ Learn about the Session Modes API
+</Card>
</file context>
| <ResponseField name="value" type={"string | null"} > | ||
| The current value of the variable (if set). | ||
| </ResponseField> |
There was a problem hiding this comment.
P3: The new nullable PromptVariable fields (value, default_value, description, type) don't state whether null and an omitted key are equivalent, which the repo's own doc-generation guideline requires for every nullable field in this file.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/protocol/schema.mdx, line 2747:
<comment>The new nullable `PromptVariable` fields (`value`, `default_value`, `description`, `type`) don't state whether `null` and an omitted key are equivalent, which the repo's own doc-generation guideline requires for every nullable field in this file.</comment>
<file context>
@@ -2537,6 +2667,133 @@ in prompt requests for pieces of context that are referenced in the message.
+<ResponseField name="type" type={<><span><a href="#promptvariabletype">PromptVariableType</a></span><span> | null</span></>} >
+ The expected type of this variable's value.
+</ResponseField>
+<ResponseField name="value" type={"string | null"} >
+ The current value of the variable (if set).
+</ResponseField>
</file context>
| <ResponseField name="value" type={"string | null"} > | |
| The current value of the variable (if set). | |
| </ResponseField> | |
| <ResponseField name="value" type={"string | null"} > | |
| The current value of the variable (if set). Omitting this field is equivalent to setting it to `null`. | |
| </ResponseField> |
| <Update label="April 23, 2026" tags={["Draft"]}> | ||
| ## v2 Prompting RFD moves to Draft | ||
|
|
||
| The RFD for how the prompt lifecycle will work in v2 of the protocol been moved to Draft stage. Please review the [RFD](/rfds/v2/prompt) for more information on the current proposal and provide feedback before the feature is stabilized. |
There was a problem hiding this comment.
P3: Grammar: missing "has" before "been" in the v2 Prompting RFD entry. The sentence reads "...protocol been moved" — it should be "...protocol has been moved".
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/rfds/updates.mdx, line 47:
<comment>Grammar: missing "has" before "been" in the v2 Prompting RFD entry. The sentence reads "...protocol been moved" — it should be "...protocol **has** been moved".</comment>
<file context>
@@ -6,6 +6,48 @@ rss: true
+<Update label="April 23, 2026" tags={["Draft"]}>
+## v2 Prompting RFD moves to Draft
+
+The RFD for how the prompt lifecycle will work in v2 of the protocol been moved to Draft stage. Please review the [RFD](/rfds/v2/prompt) for more information on the current proposal and provide feedback before the feature is stabilized.
+
+</Update>
</file context>
| The RFD for how the prompt lifecycle will work in v2 of the protocol been moved to Draft stage. Please review the [RFD](/rfds/v2/prompt) for more information on the current proposal and provide feedback before the feature is stabilized. | |
| The RFD for how the prompt lifecycle will work in v2 of the protocol has been moved to Draft stage. Please review the [RFD](/rfds/v2/prompt) for more information on the current proposal and provide feedback before the feature is stabilized. |
| <Update label="May 7, 2026" tags={["Draft"]}> | ||
| ## model_config Category RFD moves to Draft | ||
|
|
||
| The RFD for the `model_config` category been moved to Draft stage. Please review the [RFD](/rfds/model-config-category) for more information on the current proposal and provide feedback before the feature is stabilized. |
There was a problem hiding this comment.
P3: Grammar: missing "has" before "been" in the model_config category RFD entry. The sentence reads "The RFD for the model_config category been moved" — it should be "The RFD for the model_config category has been moved".
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/rfds/updates.mdx, line 40:
<comment>Grammar: missing "has" before "been" in the model_config category RFD entry. The sentence reads "The RFD for the `model_config` category been moved" — it should be "The RFD for the `model_config` category **has** been moved".</comment>
<file context>
@@ -6,6 +6,48 @@ rss: true
+<Update label="May 7, 2026" tags={["Draft"]}>
+## model_config Category RFD moves to Draft
+
+The RFD for the `model_config` category been moved to Draft stage. Please review the [RFD](/rfds/model-config-category) for more information on the current proposal and provide feedback before the feature is stabilized.
+
+</Update>
</file context>
| The RFD for the `model_config` category been moved to Draft stage. Please review the [RFD](/rfds/model-config-category) for more information on the current proposal and provide feedback before the feature is stabilized. | |
| The RFD for the `model_config` category has been moved to Draft stage. Please review the [RFD](/rfds/model-config-category) for more information on the current proposal and provide feedback before the feature is stabilized. |
|
|
||
| > How will things will play out once this feature exists? | ||
|
|
||
| There is a lof of work to do, especially on the SDK side, to support both versions, but it is likely that we should be able to allow Agents specifically to target v2 apis and gracefully fallback to v1 messages for v1 clients, to avoid huge support issues. |
There was a problem hiding this comment.
P3: Typo: "lof" should be "lot". Minor readability issue in the Shiny future section.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/rfds/v2/overview.md, line 61:
<comment>Typo: "lof" should be "lot". Minor readability issue in the Shiny future section.</comment>
<file context>
@@ -0,0 +1,87 @@
+
+> How will things will play out once this feature exists?
+
+There is a lof of work to do, especially on the SDK side, to support both versions, but it is likely that we should be able to allow Agents specifically to target v2 apis and gracefully fallback to v1 messages for v1 clients, to avoid huge support issues.
+
+However, once all of this work is in place, it should be much easier to make additional breaking changes in the future when necessary, we've been kind of letting this build up given the effort required for the entire ecosystem, but the ACP maintainers will be charting a course forward to make this as smooth as possible!
</file context>
| There is a lof of work to do, especially on the SDK side, to support both versions, but it is likely that we should be able to allow Agents specifically to target v2 apis and gracefully fallback to v1 messages for v1 clients, to avoid huge support issues. | |
| There is a lot of work to do, especially on the SDK side, to support both versions, but it is likely that we should be able to allow Agents specifically to target v2 apis and gracefully fallback to v1 messages for v1 clients, to avoid huge support issues. |
|
|
||
| - [New Prompt Lifecycle](./prompt.md) | ||
| - [Message IDs](../message-id.md) | ||
| - [Fork from specified IDs](../session-fork.mds) |
There was a problem hiding this comment.
P3: Broken link: ../session-fork.mds has a .mds extension instead of .mdx. This link would resolve to a non-existent file. Other sibling links in the same section use correct extensions (../message-id.md, ../streamable-http-websocket-transport.mdx).
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/rfds/v2/overview.md, line 33:
<comment>Broken link: `../session-fork.mds` has a `.mds` extension instead of `.mdx`. This link would resolve to a non-existent file. Other sibling links in the same section use correct extensions (`../message-id.md`, `../streamable-http-websocket-transport.mdx`).</comment>
<file context>
@@ -0,0 +1,87 @@
+
+- [New Prompt Lifecycle](./prompt.md)
+- [Message IDs](../message-id.md)
+ - [Fork from specified IDs](../session-fork.mds)
+- [Remote Transports](../streamable-http-websocket-transport.mdx)
+
</file context>
| - [Fork from specified IDs](../session-fork.mds) | |
| - [Fork from specified IDs](../session-fork.mdx) |
Prompt Variable Processing Implementation
This PR implements a comprehensive prompt variable processing system for the Agent Client Protocol (ACP), enabling dynamic content generation through template substitution.
🚀 Key Features
New Data Structures
PromptVariable: Defines named placeholders with metadata including value, description, type, and validation constraintsPromptVariableType: Enum supporting String, Number, Boolean, DateTime, Url, Email, Text, and Select (with options) typesPromptTemplateContent: New ContentBlock variant supporting{{variable_name}}syntax for variable substitutionpromptVariablescapability: Added toPromptCapabilitiesto indicate agent support for variable processingTemplate Processing
substitute()method forPromptTemplateContentthat replaces{{variable_name}}placeholders with actual valuesCross-Version Compatibility
src/v2/conversion.rs📁 Files Modified
Core Implementation
src/v1/content.rs- Added prompt variable types for v1 compatibilitysrc/v2/content.rs- Main implementation of prompt variable systemsrc/v1/agent.rs- AddedpromptVariablescapability for v1src/v2/agent.rs- AddedpromptVariablescapability for v2src/v2/conversion.rs- Cross-version conversion logicGenerated Schema Files
schema/schema.json- Updated stable schemaschema/schema.unstable.json- Updated unstable schemaschema/schema.v2.unstable.json- Updated v2 unstable schemaschema/meta.*.json- Updated metadata filesdocs/protocol/*.mdx- Updated documentation🧪 Testing
Added comprehensive test coverage including:
💡 Usage Example
🔧 Technical Details
{{variable_name}}syntax for maximum compatibility with existing templating systems_metafields🎯 Protocol Integration
This implementation enables clients and agents to:
Ready for review and integration into the main ACP specification! 🎉
Summary by cubic
Adds prompt variable processing with a new
PromptTemplateblock and variable schema. Also stabilizes thelogoutmethod and introduces experimental MCP-over-ACP messaging; v1/v2 schemas and docs updated.New Features
ContentBlock::PromptTemplatewith{{variable_name}}substitution and asubstitute()helper.PromptVariableandPromptVariableType(String, Number, Boolean, DateTime, Url, Email, Text, Select); defaults supported; missing variables left unchanged.PromptCapabilities.promptVariablesto gate use insession/prompt(v1/v2 with conversion; schemas/docs regenerated).logoutis now stable viaagentCapabilities.auth.logoutwith new authentication docs.unstable_mcp_over_acp(capability:mcpCapabilities.acp), mirrored in v1 and v2.Migration
promptVariables: trueinPromptCapabilitiesto acceptContentBlock::PromptTemplate.PromptTemplateonly when the capability is advertised; otherwise useText.logout: call only whenagentCapabilities.auth.logoutis present.unstable_mcp_over_acpand use only whenmcpCapabilities.acpis advertised.Written for commit 3b3dd37. Summary will update on new commits. Review in cubic
Note
Add prompt variable processing and MCP-over-ACP transport to Agent Client Protocol
PromptTemplateContentas a new content block type with asubstitute()method that replaces{{name}}placeholders with variable values; gated behind thepromptVariablescapability flag in both v1 and v2 schemas.mcp/connect,mcp/message,mcp/disconnect) via new request/response/notification types in both v1 and v2, behind theunstable_mcp_over_acpfeature flag.session/deletemethod withDeleteSessionRequest/DeleteSessionResponsetypes andSessionDeleteCapabilities, behind theunstable_session_deletefeature flag.LogoutRequest,LogoutResponse,AgentAuthCapabilities) from feature-gated (unstable_logout) to unconditional compilation.SetProvidersRequest→SetProviderRequest,DisableProvidersRequest→DisableProviderRequest) across v1, v2, schemas, and conversion impls.additionalDirectoriesas a filter field fromListSessionsRequest; it remains as optional metadata onSessionInfo.Macroscope summarized 3b3dd37.