refactor(sacp)!: Role-based API replacing Link/Peer system#115
Merged
nikomatsakis merged 19 commits intomainfrom Jan 19, 2026
Merged
refactor(sacp)!: Role-based API replacing Link/Peer system#115nikomatsakis merged 19 commits intomainfrom
nikomatsakis merged 19 commits intomainfrom
Conversation
- JrMessage → JsonRpcMessage - JrRequest → JsonRpcRequest - JrNotification → JsonRpcNotification - JrResponsePayload → JsonRpcResponse - JrRequestCx → JsonRpcRequestCx
Reverts the unintended renames: - JsonRpcMessageHandler → JrMessageHandler - JsonRpcRequestCx → JrRequestCx These were accidentally renamed in f23ac47 but were not part of the requested changes.
Phase 1 of the role-based API refactoring. Adds: - Role trait with Counterpart associated type and default_message_handler - role::HasPeer<Peer> trait with remote_style - RoleId for identifying role instances - Four role types: Client, Agent, Proxy, Conductor Key design decisions: - Proxy::Counterpart = Conductor (who it connects to) - Proxy has HasPeer<Client> and HasPeer<Agent> but NOT HasPeer<Conductor> (conductor is the transport, not a message destination) - ConnectionTo<R> placeholder for Phase 2 This runs parallel to the existing Link/JrPeer system during migration.
- JrResponder trait -> Run - NullResponder -> NullRun - ChainResponder -> ChainRun - SpawnedResponder -> SpawnedRun - Renamed jsonrpc/responder.rs -> jsonrpc/run.rs This frees up 'Responder' for use as the new name for JrRequestCx in Phase 3.
- JrConnectionCx → ConnectionTo - JrRequestCx → Responder - JrResponseCx → ResponseRouter Removed placeholder ConnectionTo from role.rs and fixed type parameter collisions in session.rs (Responder type param → R, run_until R → T).
- spawn_connection now takes (builder, transport) instead of (connection, serve_fn) - JrConnection is now internal (not publicly exported) - Updated all call sites and documentation - Convenience methods serve() and run_until() remain on JrConnectionBuilder
Step 0 of Phase 6 - Link→Role migration. The new name better reflects the semantics: a handler that handles messages from a particular role. Deprecated alias JrMessageHandler is preserved for backward compatibility.
Replace the dual JrLink/JrPeer type system with a single unified Role-based API. This simplifies the mental model: roles are now both the identity (Client, Agent, Proxy, Conductor) and the peer type for message routing. Key changes: - Component<L> → Serve<R>: "I serve someone playing role R" - DynComponent<L> → DynServe<R> - ClientToAgent/AgentToClient → Client/Agent (roles are their own link types) - AgentPeer/ClientPeer → Agent/Client (roles are their own peer types) - Conductor struct → ConductorImpl (Conductor is now a role) - Run trait → RunWithConnectionTo - New module structure: role/acp.rs and role/mcp.rs Removed: - src/sacp/src/peer.rs (JrPeer system) - src/sacp/src/mcp.rs (moved to role/mcp.rs) - src/sacp-tee/ crate (no longer maintained) BREAKING CHANGE: All Component/DynComponent usage must change to Serve/DynServe. All JrLink types (ClientToAgent, etc.) replaced with Role types (Client, Agent). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Serve<R> → ConnectTo<R> - DynServe<R> → DynConnectTo<R> - .serve(transport) → .connect_to(transport) - ::builder() → .connect_from() - .run_until(transport, ...) → .connect_with(transport, ...) - .into_server() → .into_channel_and_future() The new naming better expresses the intent: ConnectTo<R> means "I can connect to something playing role R", and Agent.connect_from() reads as "build a connection from a client to this agent". Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all doctests to use the new API patterns from the big rename: - Replace link types (ClientToAgent, AgentToClient, etc.) with role types (Client, Agent, Proxy, Conductor) - Change .run_until(transport, ...) to .connect_with(transport, ...) - Change .serve(transport) to .connect_to(transport) - Update transport bounds to use ConnectTo<Role> pattern - Update MCP server type parameters to use counterpart roles Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A Dispatch is the combination of an incoming message along with the types needed to process it (Responder for requests, ResponseRouter for responses). This rename clarifies the purpose of the type. - MessageCx → Dispatch - MatchMessage → MatchDispatch - on_receive_message → on_receive_dispatch - message_cx variables → dispatch - Remove JrMessageHandler backward-compat alias Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace abbreviated context variable names with clearer, more descriptive alternatives throughout the codebase. | Old Name | New Name | |----------|----------| | `request_cx` | `responder` | | `response_cx` | `router` | | `connection_cx` | `connection` | | `agent_cx` | `connection_to_agent` | | `client_cx` | `connection_to_client` | | `editor_cx` | `connection_to_editor` | | `conductor_cx` | `connection_to_conductor` | | `mcp_cx` | `mcp_connection` | | `backend_cx` | `backend_connection` | | `json_rpc_cx` | `connection` | | `forward_to_request_cx` | `forward_response_to` | | SessionBuilder field `responder` | `run` | BREAKING CHANGE: All *_cx variable names have been replaced with more descriptive alternatives. Code using these patterns will need to update variable names accordingly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Renames for consistency with Dispatch terminology: - HandleMessageFrom → HandleDispatchFrom - handle_message (trait method) → handle_dispatch_from - handle_message_from → handle_dispatch_from - default_handle_message_from → default_handle_dispatch_from - handle_incoming_message → handle_incoming_dispatch Also adds v10 to v11 upgrade guide (md/v10_to_v11_upgrade.md) documenting all breaking changes and migration patterns. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update all doctests and examples to use the new v11 API: - Replace Link types (ClientToAgent, AgentToClient, ProxyToConductor) with Role types (Client, Agent, Proxy, Conductor) - Replace Component trait with ConnectTo trait - Replace .serve() with .connect_to() and .run_until() with .connect_with() - Rename callback parameters (cx → connection, request_cx → responder) - Update HandleDispatchFrom to use generic parameter instead of associated type - Replace Run with RunWithConnectionTo Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update documentation links across the workspace to use new v11 type and method names: - JrConnection → ConnectFrom - JrResponse → SentRequest - Component → ConnectTo - serve → connect_to - run_until → connect_with - HandleMessageAs → HandleDispatchFrom - RunIn → RunWithConnectionTo - McpContext → McpConnectionTo Also fix link syntax issues in cookbook using inline (sacp::Type) syntax instead of reference-style links. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The mdbook now focuses on design documentation for maintainers and agents working on the codebase. Users building with sacp are directed to the rustdoc and cookbook. Changes: - Remove API usage docs (building-agent.md, building-proxy.md) - covered by cookbook - Remove architecture.md, pacp-components.md, chapter_1.md - redundant - Add sacp-design.md explaining role system, dispatch loop, connections - Rewrite introduction.md with crate structure and rustdoc links - Update conductor.md and protocol.md to remove code examples - Reorganize SUMMARY.md into Core Library / Conductor / Reference sections Co-Authored-By: Claude Opus 4.5 <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.
Summary
This PR introduces a simpler Role-based API that replaces the previous Link/Peer system. The main goals are:
Jrprefix from type names (JrConnectionCx→ConnectionTo,JrResponse→SentRequest)ClientToAgent,AgentToClient), Role types encode one side (Client,Agent).serve()→.connect_to())Agent,Client,Proxy,Conductorserve as role types, peer selectors, AND builder startersThe New API
Building a Client
Building an Agent
Implementing ConnectTo (was Component)
Key Renames
Component<L>ConnectTo<R>ClientToAgent,AgentToClientClient,AgentProxyToConductorProxy,ConductorJrConnectionCx<L>ConnectionTo<R>JrRequestCx<T>Responder<T>JrResponse<T>SentRequest<T>MessageCxDispatch.serve(transport).connect_to(transport).run_until(transport, fn).connect_with(transport, fn)request_cxrespondercxconnectionMigration Guide
A comprehensive migration guide is available at
md/v10_to_v11_upgrade.mdwith:Breaking Changes
This is a breaking change affecting all downstream code. The changes are mostly mechanical renames that can be done with search-and-replace, guided by the migration document.
🤖 Generated with Claude Code