Repository navigation
fix: conform the conductor and proxies to the proxy-chains RFD cleanup (#2743) and default v2 entity cancel to -32602 - #482
Merged
Conversation
`proxy/successor` is exchanged only between the conductor and the proxies it initialized, and between a conductor in proxy mode and its own conductor. The conductor used to forward one from its client (agent mode) to the first proxy, which treated it as coming from its successor, and one from the agent to the last proxy double-wrapped. Either side could forge messages that appear to come from the other. The conductor now answers such a request with `-32600` and drops and logs such a notification, as the proxy chains RFD requires. The same applies to a `proxy/successor` wrapped in a second one by a proxy or by the outer conductor of a conductor in proxy mode. Co-Authored-By: Claude <noreply@anthropic.com>
`$/cancel_request` is hop-local. A proxy that cancels a request it sent to its successor used to wrap the notification in `proxy/successor`. Per the proxy chains RFD, senders should send it plain on the hop of the request it cancels, with the ID of the `proxy/successor` request on that connection. `SentRequest::cancel`, `RequestCancellationHandle::cancel` and `ConnectionTo::send_cancel_request_to` now always send it plain. Receivers, including the conductor, still accept the wrapped form and treat it the same way, so a conductor works with proxies built on earlier releases. The conductor maps the cancellation to the request it forwarded on the next hop and re-issues it with that hop's ID. Co-Authored-By: Claude <noreply@anthropic.com>
…th -32602 Neither method has an initialize-time capability. A Client sends one only for a tool call or terminal that advertises `capabilities.cancel`, and the v2 spec answers a request for an unknown, final or non-cancellable one with `-32602`. An `Agent.v2()` agent without a handler for them used to answer `-32601`. It now answers `-32602` with the `toolCallId` or `terminalId` in `data`, matching the TypeScript SDK. A typed or catch-all handler still takes precedence, and before initialization the usual `-32600` applies. v1 and unguarded agents are unchanged: v1 has no such methods. Testy v2 and `simple_agent_v2` answer `-32602` through the new default. Co-Authored-By: Claude <noreply@anthropic.com>
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.
Implements the reference-conductor differences listed in agentclientprotocol/agent-client-protocol#2743 (proxy chains RFD cleanup), plus the v2 default error for
tool_call/cancelandterminal/cancel. It was stacked on #480 and is now rebased ontomain, including #481 (v1::schema/v2::schemapaths). No public API changes.Changes
1. The conductor rejects misplaced
proxy/successor(fix(conductor))proxy/successoris exchanged only between the conductor and the proxies it initialized, and between a conductor in proxy mode and its own conductor. The conductor used to forward aproxy/successorfrom its client (agent mode) to the first proxy, which treated it as coming from its successor, and one from the agent to the last proxy double-wrapped. Either side could forge messages that appear to come from the other.The conductor now answers such a request with
-32600and drops and logs such a notification. The same applies to aproxy/successorwrapped twice, by a proxy or by the outer conductor of a conductor in proxy mode.Tests (
conductor/tests/proxy_wire.rs): agent mode (from the client, from the agent, double-wrapped from a proxy), proxy mode (double-wrapped from the outer conductor), and regressions showing legitimate proxy -> conductor and outer conductor -> proxyproxy/successortraffic still flows.2. Proxies send
$/cancel_requestplain (fix(acp))A proxy cancelling a request it sent to its successor used to wrap
$/cancel_requestinproxy/successor. Per #2743 it now sends it plain, with the ID of theproxy/successorrequest on that hop.SentRequest::cancel,RequestCancellationHandle::cancelandConnectionTo::send_cancel_request_toalways send it plain. Receivers, including the conductor, still accept the wrapped form, so a v5 conductor works with older proxies.Tests: a two-proxy chain (v1 and v2) with tapped proxy connections asserts that every hop carries exactly one plain
$/cancel_requestnaming that hop's request, and that the agent's request is cancelled. Another test checks that the conductor maps both a plain and a wrapped cancel from a proxy to the forwarded request, in agent mode and proxy mode. The existing core tests that expected the wrapped form now expect the plain one.3. v2 default
-32602fortool_call/cancelandterminal/cancel(fix(acp))An initialized
Agent.v2()agent without a handler for these requests answers-32602("the tool call is unknown or not cancellable", with{toolCallId}/{terminalId}indata), matching the spec and the TypeScript SDK. A typed or catch-all handler takes precedence. Before initialization the usual-32600applies. v1 and unguarded (Builder::new) agents still answer-32601. Testy v2 andsimple_agent_v2pick this up through the default.Tests: unhandled ->
-32602, plus-32600before initialization; typed and catch-all handlers win; v1 (Testy) and raw agents still answer-32601; Testy v2 answers-32602.Wire-format changes
$/cancel_requestfrom a proxy to its conductor is now plain instead of wrapped inproxy/successor. The wrapped form is still accepted.proxy/successorfrom the client (agent mode) or the agent with-32600instead of forwarding it.tool_call/cancel/terminal/cancelwith-32602instead of-32601.Docs:
md/conductor.md,md/protocol.md,md/request-cancellation.md,md/protocol-v2.md, the cancellation rustdoc chapter, and migration notes inmd/migration-v5.md.