Skip to content

Implement prompt variable processing for Agent Client Protocol - #3

Merged
marekdkropiewnicki-dotcom merged 154 commits into
mainfrom
cursor/prompt-variable-processing-642f
Jul 13, 2026
Merged

Implement prompt variable processing for Agent Client Protocol#3
marekdkropiewnicki-dotcom merged 154 commits into
mainfrom
cursor/prompt-variable-processing-642f

Conversation

@marekdkropiewnicki-dotcom

@marekdkropiewnicki-dotcom marekdkropiewnicki-dotcom commented May 14, 2026

Copy link
Copy Markdown
Owner

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 constraints
  • PromptVariableType: Enum supporting String, Number, Boolean, DateTime, Url, Email, Text, and Select (with options) types
  • PromptTemplateContent: New ContentBlock variant supporting {{variable_name}} syntax for variable substitution
  • promptVariables capability: Added to PromptCapabilities to indicate agent support for variable processing

Template Processing

  • substitute() method for PromptTemplateContent that replaces {{variable_name}} placeholders with actual values
  • Support for default values when variables are not provided
  • Graceful handling of missing variables (leaves placeholders unchanged)
  • Rich metadata support for each variable (descriptions, types, required/optional flags)

Cross-Version Compatibility

  • Full implementation in both ACP v1 and v2
  • Conversion logic between protocol versions in src/v2/conversion.rs
  • Backward compatibility maintained through versioning system

📁 Files Modified

Core Implementation

  • src/v1/content.rs - Added prompt variable types for v1 compatibility
  • src/v2/content.rs - Main implementation of prompt variable system
  • src/v1/agent.rs - Added promptVariables capability for v1
  • src/v2/agent.rs - Added promptVariables capability for v2
  • src/v2/conversion.rs - Cross-version conversion logic

Generated Schema Files

  • schema/schema.json - Updated stable schema
  • schema/schema.unstable.json - Updated unstable schema
  • schema/schema.v2.unstable.json - Updated v2 unstable schema
  • schema/meta.*.json - Updated metadata files
  • docs/protocol/*.mdx - Updated documentation

🧪 Testing

Added comprehensive test coverage including:

  • Variable creation and value resolution
  • Template substitution with various scenarios
  • Cross-version conversion validation
  • JSON serialization/deserialization roundtrips
  • 275 tests passing

💡 Usage Example

use agent_client_protocol_schema::v2::{PromptVariable, PromptTemplateContent, PromptVariableType};

// Create variables
let variables = vec![
    PromptVariable::new("user")
        .value("Alice")
        .description("The user's name")
        .variable_type(PromptVariableType::String)
        .required(true),
    PromptVariable::new("task")
        .value("code review")
        .variable_type(PromptVariableType::Select { 
            options: vec!["code review".to_string(), "testing".to_string()] 
        })
];

// Create template
let template = PromptTemplateContent::new(
    "Hello {{user}}, let's work on {{task}}!",
    variables
);

// Substitute variables
let result = template.substitute();
// Result: "Hello Alice, let's work on code review!"

🔧 Technical Details

  • Uses {{variable_name}} syntax for maximum compatibility with existing templating systems
  • Supports rich type system with validation constraints
  • Maintains protocol extensibility through _meta fields
  • Graceful degradation for unsupported variable types
  • Schema generation via Rust's JsonSchema derive macro

🎯 Protocol Integration

This implementation enables clients and agents to:

  1. Exchange rich prompt templates with variable definitions
  2. Validate user inputs against variable type constraints
  3. Generate dynamic prompts with context-aware substitution
  4. Build reusable prompt libraries with parameterized templates

Ready for review and integration into the main ACP specification! 🎉

Open in Web Open in Cursor 

Summary by cubic

Adds prompt variable processing with a new PromptTemplate block and variable schema. Also stabilizes the logout method and introduces experimental MCP-over-ACP messaging; v1/v2 schemas and docs updated.

  • New Features

    • ContentBlock::PromptTemplate with {{variable_name}} substitution and a substitute() helper.
    • PromptVariable and PromptVariableType (String, Number, Boolean, DateTime, Url, Email, Text, Select); defaults supported; missing variables left unchanged.
    • PromptCapabilities.promptVariables to gate use in session/prompt (v1/v2 with conversion; schemas/docs regenerated).
    • logout is now stable via agentCapabilities.auth.logout with new authentication docs.
    • Experimental MCP-over-ACP types and methods added behind unstable_mcp_over_acp (capability: mcpCapabilities.acp), mirrored in v1 and v2.
  • Migration

    • Agents: advertise promptVariables: true in PromptCapabilities to accept ContentBlock::PromptTemplate.
    • Clients: send PromptTemplate only when the capability is advertised; otherwise use Text.
    • logout: call only when agentCapabilities.auth.logout is present.
    • MCP-over-ACP: enable unstable_mcp_over_acp and use only when mcpCapabilities.acp is advertised.

Written for commit 3b3dd37. Summary will update on new commits. Review in cubic


Open with GitKraken

Note

Add prompt variable processing and MCP-over-ACP transport to Agent Client Protocol

  • Adds PromptTemplateContent as a new content block type with a substitute() method that replaces {{name}} placeholders with variable values; gated behind the promptVariables capability flag in both v1 and v2 schemas.
  • Introduces MCP-over-ACP transport support (mcp/connect, mcp/message, mcp/disconnect) via new request/response/notification types in both v1 and v2, behind the unstable_mcp_over_acp feature flag.
  • Adds session/delete method with DeleteSessionRequest/DeleteSessionResponse types and SessionDeleteCapabilities, behind the unstable_session_delete feature flag.
  • Promotes logout-related types (LogoutRequest, LogoutResponse, AgentAuthCapabilities) from feature-gated (unstable_logout) to unconditional compilation.
  • Renames provider management types from plural to singular (SetProvidersRequestSetProviderRequest, DisableProvidersRequestDisableProviderRequest) across v1, v2, schemas, and conversion impls.
  • Removes additionalDirectories as a filter field from ListSessionsRequest; it remains as optional metadata on SessionInfo.
  • Adds draft protocol documentation covering terminals, tool calls, transports, authentication, prompt variables, session deletion, and MCP-over-ACP.
  • Risk: The plural-to-singular provider type renames are a breaking API change requiring callers to update type references.

Macroscope summarized 3b3dd37.

rohitpaulk and others added 30 commits May 1, 2026 17:04
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>
acp-release-bot Bot and others added 17 commits May 20, 2026 22:46
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>
@marekdkropiewnicki-dotcom

Copy link
Copy Markdown
Owner Author

@copilot Please rebase this branch onto the latest main and resolve the merge conflicts in the following files:

  • docs/protocol/draft/schema-v2.mdx
  • docs/protocol/draft/schema.mdx
  • docs/protocol/schema.mdx

These are generated schema docs. After rebasing, regenerate them from the Rust schema (preserving the new PromptTemplateContent, PromptVariable, PromptVariableType, and promptVariables capability additions from this PR) and merge them with the upstream changes from main.

Also fix the failing CI / Build (pull_request) check — please run cargo test, cargo fmt --check, and cargo clippy --all-targets --all-features -- -D warnings locally and address any failures.

Force-push with --force-with-lease when done. Leave this PR in Draft until CI is green.

cursoragent and others added 3 commits May 24, 2026 12:41
- 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>

Copilot AI commented May 24, 2026

Copy link
Copy Markdown

@copilot Please rebase this branch onto the latest main and resolve the merge conflicts in the following files:

  • docs/protocol/draft/schema-v2.mdx
    ...

Done in 0aecafa (with branch sync commit 3b3dd37). I rebased onto latest main, resolved the three schema doc conflicts by regenerating from Rust schema, preserved PromptTemplateContent / PromptVariable / PromptVariableType / promptVariables, and updated generated schema artifacts. I also fixed CI failures and verified locally: cargo test, cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, plus npm run format:check all pass.

@marekdkropiewnicki-dotcom
marekdkropiewnicki-dotcom marked this pull request as ready for review July 13, 2026 18:12
Copilot AI review requested due to automatic review settings July 13, 2026 18:12
@marekdkropiewnicki-dotcom
marekdkropiewnicki-dotcom merged commit c1af863 into main Jul 13, 2026
1 check passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 the promptVariables prompt 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.

Comment thread src/v2/content.rs
Comment on lines +593 to +598
for variable in &self.variables {
if let Some(value) = &variable.value {
let placeholder = format!("{{{{{}}}}}", variable.name);
result = result.replace(&placeholder, value);
}
}
Comment thread src/v2/content.rs
Comment on lines +609 to +613
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[non_exhaustive]
pub struct PromptVariable {
Comment thread src/v1/content.rs
Comment on lines +592 to +597
for variable in &self.variables {
if let Some(value) = &variable.value {
let placeholder = format!("{{{{{}}}}}", variable.name);
result = result.replace(&placeholder, value);
}
}
Comment thread src/v1/content.rs
Comment on lines +608 to +612
#[serde_as]
#[skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)]
#[non_exhaustive]
pub struct PromptVariable {
Comment thread src/v2/content.rs
Comment on lines +876 to +880
// 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!");
}

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/v2/client.rs
DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse),
ExtMethodResponse(ExtResponse),
#[cfg(feature = "unstable_mcp_over_acp")]
MessageMcpResponse(MessageMcpResponse),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread src/v1/client.rs
DisconnectMcpResponse(#[serde(default)] DisconnectMcpResponse),
ExtMethodResponse(ExtResponse),
#[cfg(feature = "unstable_mcp_over_acp")]
MessageMcpResponse(MessageMcpResponse),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread src/v1/content.rs
/// 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 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread src/v2/agent.rs
///
/// This method is only available if the agent advertises the `sessionCapabilities.delete` capability.
#[cfg(feature = "unstable_session_delete")]
DeleteSessionRequest(DeleteSessionRequest),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

Comment thread docs/protocol/schema.mdx
Comment on lines +2747 to +2749
<ResponseField name="value" type={"string | null"} >
The current value of the variable (if set).
</ResponseField>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
<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>

Comment thread docs/rfds/updates.mdx
<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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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.

Comment thread docs/rfds/updates.mdx
<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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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.

Comment thread docs/rfds/v2/overview.md

> 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
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.

Comment thread docs/rfds/v2/overview.md

- [New Prompt Lifecycle](./prompt.md)
- [Message IDs](../message-id.md)
- [Fork from specified IDs](../session-fork.mds)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
- [Fork from specified IDs](../session-fork.mds)
- [Fork from specified IDs](../session-fork.mdx)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.