Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion md/conductor.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ Lazy construction allows an `InstantiateProxiesAndAgent` or
`InstantiateProxies` implementation to inspect and, when appropriate, adjust
the initialize request before choosing components.

With the conductor crate's `unstable_protocol_v2` feature, initialization
selects the v1 or v2 schema from the raw `protocolVersion` before
deserialization. This prevents v2 `info`, `capabilities`, metadata, and future
extension fields from being interpreted as a permissive v1 request and dropped.
An exact-version request whose typed value is unchanged keeps its original raw
parameters, including unknown extensions. A request for a later compatible
protocol version selects v2 and is canonicalized through the selected v2
schema, matching the core protocol router.
The command-line component provider, `AgentOnly`, `ProxiesAndAgent`, and static
proxy vectors accept both versions. Custom instantiators can implement the
feature-gated `instantiate_v2_proxies_and_agent` or `instantiate_v2_proxies`
method; their default implementation rejects v2 with a JSON-RPC response and
leaves the connection in a failed state that rejects later traffic. A modified
typed request is serialized as the new authoritative payload, while its
`protocolVersion` remains pinned to the implementation the conductor selected.

## Agent and Proxy Modes

In **agent mode**, the conductor owns zero or more proxies followed by a final
Expand Down Expand Up @@ -98,6 +114,12 @@ agent-client-protocol-conductor --serve agent "proxy-one" "base-agent"
agent-client-protocol-conductor --trace ./trace.jsons --serve agent "proxy-one" "base-agent"
```

Build the opt-in binary with draft-v2 proxy initialization enabled using:

```bash
cargo build -p agent-client-protocol-conductor --features unstable_protocol_v2
```

There is no conductor `mcp` subcommand. Compatibility for HTTP-capable agents that lack the
native ACP MCP transport lives in `agent-client-protocol-polyfill` and must
be inserted explicitly when needed.
Expand All @@ -118,7 +140,9 @@ ConductorImpl::new_agent("conductor", components)

`ConductorImpl::new_proxy` accepts an `InstantiateProxies` implementation for
the nested-proxy case. Both modes can use dynamic instantiator closures when
the chain depends on initialization data.
the chain depends on v1 initialization data. A custom instantiator type can
implement both initialization methods when dynamic selection is also needed for
v2.

## MCP Compatibility

Expand Down
30 changes: 30 additions & 0 deletions md/protocol-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,36 @@ application wants stream ergonomics, it can fan typed updates out from the
connection handler with an explicit buffering and subscriber policy. MCP
attachment and proxy-session helpers are still v1-only.

## Conductor and proxy initialization

Enable `unstable_protocol_v2` on `agent-client-protocol-conductor` to carry a v2
connection through a conductor proxy chain. The conductor inspects the raw
`protocolVersion` before parsing initialization, rewrites ordinary `initialize`
to `_proxy/initialize` without reserializing its parameters, and restores the
ordinary method before the request reaches the final agent. For an exact v2
request, `info`, `capabilities`, metadata, and unknown extension fields
therefore retain their wire shape across conductor-controlled rewrites. A proxy
implementation can still deliberately replace the request it forwards.

As with the core protocol router, an exact v2 request can retain unknown raw
fields, while a request for a later compatible version is canonicalized through
the selected v2 schema before component instantiation.

Proxy implementations use
`agent_client_protocol::schema::v2::InitializeProxyRequest`; its response is the
v2 `InitializeResponse`. The flat `schema::InitializeProxyRequest` remains the
stable v1 type. Static conductor component providers support both versions.
Custom `InstantiateProxiesAndAgent` and `InstantiateProxies` implementations
opt into v2 by implementing their feature-gated v2 method; the default rejects
v2 rather than interpreting it as v1. Returning the initialize request
unchanged preserves its complete raw parameters for an exact-version request,
including unknown extensions; returning a modified typed request makes that
serialized request authoritative. The conductor pins `protocolVersion` to its
selected implementation even if an instantiator attempts to change it, and
validates the final agent's initialize response against that selection.
The proxy connection also routes v2 `session/new` requests and responses
without interpreting them as v1 payloads.

The SDK handles the `initialize` negotiation at the JSON-RPC boundary:

- A v2 client advertises protocol v2 as its latest supported version.
Expand Down
17 changes: 10 additions & 7 deletions md/protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ request from a notification.
## Proxy Initialization

The conductor sends `_proxy/initialize` to a component that has a successor.
Its parameters are the same fields as a normal v1 `InitializeRequest`. Receiving
this method, rather than `initialize`, tells the component that it is running as
a proxy and may forward messages with `_proxy/successor`.

The response is a normal `InitializeResponse` result. The final agent receives
the ordinary `initialize` method and does not need to understand the proxy
extension.
Its parameters are the same fields as the normal `InitializeRequest` for the
selected ACP version. Receiving this method, rather than `initialize`, tells the
component that it is running as a proxy and may forward messages with
`_proxy/successor`.

The response is the matching version's normal `InitializeResponse` result. The
stable flat `schema::InitializeProxyRequest` type uses v1; with
`unstable_protocol_v2`, `schema::v2::InitializeProxyRequest` preserves the v2
request and response types. The final agent receives the ordinary `initialize`
method and does not need to understand the proxy extension.

## Successor Forwarding

Expand Down
6 changes: 6 additions & 0 deletions src/agent-client-protocol-conductor/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add opt-in protocol-v2 initialization for agent and nested proxy chains
through `unstable_protocol_v2`, including version-aware custom instantiator
methods, raw v2 session creation routing, and the conductor binary.

## [2.0.0](https://github.com/agentclientprotocol/rust-sdk/compare/agent-client-protocol-conductor-v1.3.0...agent-client-protocol-conductor-v2.0.0) - 2026-07-23

### Breaking changes
Expand Down
1 change: 1 addition & 0 deletions src/agent-client-protocol-conductor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ path = "src/main.rs"

[features]
default = []
unstable_protocol_v2 = ["agent-client-protocol/unstable_protocol_v2"]

[dependencies]
agent-client-protocol = { workspace = true, features = ["unstable_mcp_over_acp"] }
Expand Down
3 changes: 3 additions & 0 deletions src/agent-client-protocol-conductor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ The conductor:

```bash
cargo build --release -p agent-client-protocol-conductor

# Include draft ACP v2 proxy initialization
cargo build --release -p agent-client-protocol-conductor --features unstable_protocol_v2
```

Binary will be at `target/release/agent-client-protocol-conductor`.
Expand Down
Loading