Align with RFD #533 (multi-client session attach)#3
Open
lsaether wants to merge 1 commit into
Open
Conversation
Implement the proposed Multi-Client Session Attach RFD on top of amux's
existing multi-subscriber proxy. Existing amux clients keep working
unchanged via dual-emit; RFD-aware clients can use the standard methods
and frames directly.
New surface:
- session/attach and session/detach intercepted by the proxy; never
reach the agent. Attach returns { sessionId, clientId, historyPolicy,
connectedClients[], history? } and re-issues unresolved
session/request_permission to the attaching client so it's actionable.
- historyPolicy: full (default), pending_only, none, after_message
(falls back to full until the Message ID RFD is adopted).
- session/update siblings of every amux/* metadata frame, emitted when
an ACP session id is known: prompt_received, turn_complete,
permission_resolved, client_disconnected. Distinguished from
agent-emitted updates by update.type vs update.kind.
- initialize advertises agentCapabilities.sessionCapabilities.attach,
synthesized by the proxy on top of the upstream agent's reply.
Internals:
- New protocol::attach module with typed AttachParams/AttachResult and
RFD error codes.
- New protocol::session_update module with builders for the four
proxy-emitted update variants.
- SessionInner gains pending_permission_frames: HashMap<Id, Bytes> so
in-flight session/request_permission frames can be re-issued to a
late attacher.
- route_agent_request now takes the method so it can populate the
permission map only for actionable requests.
- inject_attach_capability mutates the cached initialize result; the
helper is idempotent and runs on both the first-time send and the
cached short-circuit path.
This was referenced May 22, 2026
Closed
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.
Summary
Implements agentclientprotocol/agent-client-protocol#533 — Multi-Client Session Attach — on top of amux's existing multi-subscriber proxy. amux already solved ~80% of the RFD; this PR adds the standard method names, the
session/updatevariants, the capability advertisement, and the pending-permission re-issue.Existing amux clients keep working unchanged via dual-emit. RFD-aware clients can use the standard methods and frames directly without knowing anything about the
amux/*namespace.What changed
New methods (proxy-handled, never forwarded to the agent)
session/attach { sessionId?, historyPolicy?, clientId?, clientInfo? }→{ sessionId, clientId, historyPolicy, connectedClients[], history? }. Re-issues unresolvedsession/request_permissionto the attaching client so it's actionable.session/detach→{ sessionId, status: \"detached\" }, then closes the WS with code 1000.New
session/updatesiblings ofamux/*(dual-emit, fire only when an ACP session id is cached)update.type)prompt_receivedamux/turn_startedturn_completeamux/turn_completepermission_resolvedamux/agent_request_resolvedclient_disconnectedamux/peer_leftDistinguished from agent-emitted updates by
update.type(proxy) vsupdate.kind(agent).initializemutationThe proxy now injects
agentCapabilities.sessionCapabilities.attach: trueinto the upstream agent's reply — both on first cache and on the cached short-circuit path — so RFD-aware clients can detect multi-client support without knowing about amux.historyPolicyfull(default) — broadcast log projected to{ method, params }entriespending_only— just the unresolvedsession/request_permissionframesnone— omits the fieldafter_message— accepted but falls back tofulluntil the Message ID RFD is adoptedInternals
protocol::attachandprotocol::session_updatemodules with typed builders + the RFD error codes.SessionInner.pending_permission_frames: HashMap<Id, Bytes>keeps the original frame for every InFlight permission so it can be re-delivered to a late attacher with the same id (the existing first-writer-wins gate handles the reply normally).route_agent_requestnow takes the method so the permission map is only populated for actionable requests.inject_attach_capabilityis idempotent and runs on both code paths.What amux still has beyond the RFD
amux/*namespace includingamuxTurnId,amux/session_busy { heldBy },role.mux_id).initialize/session/newcaching for late joiners.-32001andamux/session_busy./debug/sessions.--session-ttl-seconds).?session=&peer_id=&peer_name=&role=)./healthz,/debug/sessions,--replay-turns,--agent-cmd.Caveats
historyentries are raw{ method, params }rather than the RFD's typed shape — keeps amux envelope-only; documented as a deviation.after_messageis accepted but falls back tofull(depends on the Message ID RFD).Test plan
cargo test— 67 tests pass (5 new RFD-#533 alignment tests on top of the existing 62)cargo clippy --all-targets -- -D warningscleancargo fmt --checkcleanhermes acp) to confirminitializecapability injection andsession/attachend-to-end