Repository navigation
Conversation
Remove `Builder::with_v2_protocol_guard`, a v2-named method on the
version-neutral builder with no v1 or proxy counterpart and no callers.
Merge `ConnectionTo::spawn_connection_with_context` into
`spawn_connection`, which now returns the connection type the child
builder's callbacks receive, as the v1 and v2 connections already did.
`ConnectionTo::into_protocol::<P>()` now returns a `Result` and fails
when the builder's guard selected a different version, so a v1
connection can no longer be retyped to send v2 payloads. Add
`ConnectionTo::protocol_version()`.
The typed `send_cancel_request(_to)` on `v1::ConnectionTo` and
`v2::ConnectionTo` take the version's own request ID, so v2 can no
longer send `{"requestId": null}`.
`v1::ConnectionTo` and `v2::ConnectionTo` convert into the root
`ConnectionTo` with `From`, and `Protocol::Connection` requires it, so
`P`-generic code can reach the raw connection.
Findings F01, F15, F18, F04, G82.
BREAKING CHANGE: `Builder::with_v2_protocol_guard` and
`ConnectionTo::spawn_connection_with_context` are removed;
`ConnectionTo::spawn_connection` returns `P::Connection` and takes two
type parameters; `ConnectionTo::into_protocol` returns a `Result`; the
typed `send_cancel_request(_to)` methods take typed request IDs.
Co-Authored-By: Claude <noreply@anthropic.com>
`InitializationVersionMismatch` and `SelectedInitializeResponse` are not tied to protocol v2: every later version's negotiation reports a lower selection with them. They now live at the crate root (still behind `unstable_protocol_v2`, the first feature under which a lower version can be selected). `v2::InitializeOutcome` stays in `v2`. Drop the redundant `InitializationVersionMismatch::selected` field in favor of a `selected()` method that reads the response's version, so the two can no longer disagree. Findings F20, F75. BREAKING CHANGE: `v2::InitializationVersionMismatch` and `v2::SelectedInitializeResponse` move to the crate root, and `InitializationVersionMismatch::selected` is now a method. Co-Authored-By: Claude <noreply@anthropic.com>
…lize `ProxyProtocolRouter` closed the connection on the first rejected `proxy/initialize`, unsupported version, or malformed frame, while its rustdoc said it selected "exactly as `Agent::protocol_router` does". Both routers now share one selection loop that answers each rejected frame and keeps reading, so a conductor can retry `proxy/initialize` the same way a client can retry `initialize`. Finding F27. Co-Authored-By: Claude <noreply@anthropic.com>
- `Channel` is `#[non_exhaustive]` with `Channel::new` and `Channel::into_parts`, and documents that the unbounded mpsc pair is the intended contract, so fields can be added later. - `JsonRpcMessage::parse_message` takes `params: &serde_json::Value` instead of `&impl Serialize`. Every SDK caller already passes a JSON value, and a concrete type lets implementations avoid a serialize round trip later without another break. The derive macros generate the new signature. - `SentRequest` and `PreparedRequest` gain `into_raw` and, on `Raw` handles, `into_protocol`, like `Responder` and `ResponseRouter`. Findings F38, F39, F50. BREAKING CHANGE: `Channel` can no longer be built or destructured exhaustively outside the crate; hand-written `JsonRpcMessage` implementations must change the `parse_message` signature. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Removing with_v2_protocol_guard left the import unused when only unstable_protocol_v2 is enabled. Co-Authored-By: Claude <noreply@anthropic.com>
…tics ProxyProtocolRouter no longer finishes after a rejected proxy/initialize, so the rejection-drain tests no longer applied. Check instead that the rejection reaches the wire while input stays open and that the router finishes on input EOF. Co-Authored-By: Claude <noreply@anthropic.com>
A version mismatch in `ConnectionTo::into_protocol` is a local programming error. Reporting it as Invalid Request (-32600) told the remote peer its request was malformed when a handler propagated it with `?`. It is now an Internal error (-32603). Also tidy the migration and protocol-v2 notes: the v1 `send_cancel_request` change is source-compatible for `RawJsonRpcId` arguments, and the crate-root initialize mismatch types are described without claiming every version uses them. Co-Authored-By: Claude <noreply@anthropic.com>
…router Co-Authored-By: Claude <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the 5.0 public-API cleanup. Tightens the version-neutral root connection and builder surface so that adding later protocol versions stays additive.
Addressed
Builder::with_v2_protocol_guard(all four impls). The 2.1.0 changelog entry is left as history; the migration guide records the removal.ConnectionTo::spawn_connection_with_contextintospawn_connection, which now returnsP::Connection<R::Counterpart>(a raw builder still returns the rawConnectionTo).ConnectionTo::into_protocol::<P>()returnsResultand fails with an Internal error (-32603) when the builder's guard selected another version. The mismatch is a local programming error, so it is not reported to the peer as Invalid Request. AddsConnectionTo::protocol_version().send_cancel_request(_to)takeimpl Into<schema::v1::RequestId>/impl Into<schema::v2::RequestId>. v1 stays source-compatible becauseRawJsonRpcIdconverts intoschema::v1::RequestId. Only v2 callers passing aRawJsonRpcIdmust switch.From<v1::ConnectionTo<C>>andFrom<v2::ConnectionTo<C>>forConnectionTo<C>, andProtocol::ConnectionrequiresInto<ConnectionTo<C>>.InitializationVersionMismatchandSelectedInitializeResponsemove to the crate root (still behindunstable_protocol_v2).InitializeOutcomestays inv2::.InitializationVersionMismatch::selectedfield. Use theselected()method instead.ProxyProtocolRoutersharesAgentProtocolRouter's answer-and-continue selection loop. It no longer closes the connection on the first rejected or malformed frame. Adds a retry test and a test for a v1+v2 router that answers invalid JSON and a batch withid: nullerrors, then forwards the next validproxy/initializeto the selected implementation unchanged. The rejection-drain tests inprotocol_driver_finish.rsare replaced by one that checks the rejection is flushed overLineswhile input stays open and that the router finishes on input EOF.Channelis#[non_exhaustive], withChannel::newandChannel::into_parts. The rustdoc now states that the unbounded mpsc pair is the contract.JsonRpcMessage::parse_messagetakesparams: &serde_json::Value. This changes the signature only, and the derive macro output is updated to match.SentRequestandPreparedRequestgaininto_rawand, onRaw,into_protocol.Skipped
SelectedInitializeRequestis defined in the conductor crate, not in core. It belongs to the conductor cleanup.Notes
..inChannelpatterns and the newparse_messagecallers.session.rs'sensure_v1_session_protocolis now effectively unreachable, becauseinto_protocol::<V1>()rejects v2 connections. I left it alone because fix(acp)!: v1 session stream reports prompt errors and full responses #474 rewrites much of that file. It should be removed or turned into adebug_assert!there or in a follow-up.AgentProtocolRouterdoes. It used to hand that frame to the v1 implementation.Checks
Rerun at 3791556:
cargo fmt -- --check: passcargo clippy --workspace --all-targets --all-features -- -D warningsandcargo clippy -- -D warnings: passcargo hack check --workspace --feature-powerset --depth 2 --exclude-features default,unstable,wasm_js --no-dev-deps: pass, no warningscargo test --workspace --all-features --locked --no-fail-fast: pass, exceptagent-client-protocol-derive --lib, which fails to load libstd under the local test runner (it does onmaintoo)cargo test -p agent-client-protocol --no-default-features --locked: passRUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-depsfor core, derive, http and test crates: passmdbook build: pass