pub trait Component: Send + 'static {
// Required method
fn serve(
self,
client: impl Component,
) -> impl Future<Output = Result<(), Error>> + Send;
// Provided method
fn into_server(
self,
) -> (Channel, Pin<Box<dyn Future<Output = Result<(), Error>> + Send>>)
where Self: Sized { ... }
}Expand description
Re-export component types from sacp A component that can participate in the Agent-Client Protocol.
This trait represents anything that can communicate via JSON-RPC messages over channels - agents, proxies, in-process connections, or any ACP-speaking component.
§Component Types
The trait is implemented by several built-in types representing different communication patterns:
ByteStreams: A component communicating over byte streams (stdin/stdout, sockets, etc.)Channel: A component communicating via in-process message channels (for testing or direct connections)AcpAgent: An external agent running in a separate process with stdio communication- Custom components: Proxies, transformers, or any ACP-aware service
§Two Ways to Serve
Components can be used in two ways:
serve(client)- Serve by forwarding to another component (most components implement this)into_server()- Convert into a channel endpoint and server future (base cases implement this)
Most components only need to implement serve(client) - the into_server() method has a default
implementation that creates an intermediate channel and calls serve.
§Implementation Example
use sacp::Component;
struct MyProxy {
config: ProxyConfig,
}
impl Component for MyProxy {
async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
// Set up handler chain that forwards to client
sacp::JrHandlerChain::new()
.name("my-proxy")
.on_receive_request(async |req: MyRequest, cx| {
// Transform and forward request
cx.respond(MyResponse { status: "ok".into() })
})
.serve(client)
.await
}
}§Heterogeneous Collections
For storing different component types in the same collection, use DynComponent:
let components: Vec<DynComponent> = vec![
DynComponent::new(proxy1),
DynComponent::new(proxy2),
DynComponent::new(agent),
];Required Methods§
Sourcefn serve(
self,
client: impl Component,
) -> impl Future<Output = Result<(), Error>> + Send
fn serve( self, client: impl Component, ) -> impl Future<Output = Result<(), Error>> + Send
Serve this component by forwarding to a client component.
Most components implement this method to set up their handler chain and forward messages to the provided client.
§Arguments
client- The component to forward messages to
§Returns
A future that resolves when the component stops serving, either successfully
or with an error. The future must be Send.
Provided Methods§
Sourcefn into_server(
self,
) -> (Channel, Pin<Box<dyn Future<Output = Result<(), Error>> + Send>>)where
Self: Sized,
fn into_server(
self,
) -> (Channel, Pin<Box<dyn Future<Output = Result<(), Error>> + Send>>)where
Self: Sized,
Convert this component into a channel endpoint and server future.
This method returns:
- A
Channelthat can be used to communicate with this component - A
BoxFuturethat runs the component’s server logic
The default implementation creates an intermediate channel pair and calls serve
on one endpoint while returning the other endpoint for the caller to use.
Base cases like Channel and ByteStreams override this to avoid unnecessary copying.
§Returns
A tuple of (Channel, BoxFuture) where the channel is for the caller to use
and the future must be spawned to run the server.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.