Skip to content

Commit 0192dbd

Browse files
committed
docs(sacp): make cookbook examples compile
Convert ignore doctests to real compiling examples for: - reusable_components: Component impl with InitializeRequest handler - custom_message_handlers: JrMessageHandler impl with MatchMessage - global_mcp_server: McpServer with tool_fn in proxy Component The connecting_as_client and per_session_mcp_server patterns remain as ignore examples since they require runtime infrastructure.
1 parent 489b817 commit 0192dbd

1 file changed

Lines changed: 60 additions & 28 deletions

File tree

src/sacp/src/cookbook.rs

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -93,26 +93,35 @@ pub mod reusable_components {
9393
//!
9494
//! # Example
9595
//!
96-
//! ```ignore
96+
//! ```
9797
//! use sacp::{Component, AgentToClient};
98-
//! use sacp::schema::{PromptRequest, PromptResponse};
98+
//! use sacp::schema::{
99+
//! InitializeRequest, InitializeResponse, AgentCapabilities,
100+
//! };
99101
//!
100102
//! struct MyAgent {
101-
//! config: AgentConfig,
103+
//! name: String,
102104
//! }
103105
//!
104106
//! impl Component for MyAgent {
105107
//! async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
106108
//! AgentToClient::builder()
107-
//! .name("my-agent")
108-
//! .on_receive_request(async move |req: PromptRequest, request_cx, cx| {
109-
//! let response = self.process_prompt(&req).await?;
110-
//! request_cx.respond(response)
109+
//! .name(&self.name)
110+
//! .on_receive_request(async move |req: InitializeRequest, request_cx, _cx| {
111+
//! request_cx.respond(InitializeResponse {
112+
//! protocol_version: req.protocol_version,
113+
//! agent_capabilities: AgentCapabilities::default(),
114+
//! auth_methods: vec![],
115+
//! agent_info: None,
116+
//! meta: None,
117+
//! })
111118
//! }, sacp::on_receive_request!())
112119
//! .serve(client)
113120
//! .await
114121
//! }
115122
//! }
123+
//!
124+
//! let agent = MyAgent { name: "my-agent".into() };
116125
//! ```
117126
//!
118127
//! # Important: Don't block the event loop
@@ -136,30 +145,31 @@ pub mod custom_message_handlers {
136145
//!
137146
//! # Example
138147
//!
139-
//! ```ignore
140-
//! use std::sync::Arc;
141-
//! use tokio::sync::Mutex;
148+
//! ```
142149
//! use sacp::{JrMessageHandler, MessageCx, Handled, JrConnectionCx};
150+
//! use sacp::schema::{InitializeRequest, InitializeResponse, AgentCapabilities};
143151
//! use sacp::util::MatchMessage;
144152
//!
145-
//! struct MyHandler {
146-
//! state: Arc<Mutex<State>>,
147-
//! }
153+
//! struct MyHandler;
148154
//!
149155
//! impl JrMessageHandler for MyHandler {
150156
//! type Role = sacp::role::UntypedRole;
151157
//!
152158
//! async fn handle_message(
153159
//! &mut self,
154160
//! message: MessageCx,
155-
//! cx: JrConnectionCx<Self::Role>,
161+
//! _cx: JrConnectionCx<Self::Role>,
156162
//! ) -> Result<Handled<MessageCx>, sacp::Error> {
157163
//! MatchMessage::new(message)
158-
//! .if_request(async |req: MyRequest, request_cx| {
159-
//! let mut state = self.state.lock().await;
160-
//! state.count += 1;
161-
//! request_cx.respond(MyResponse { count: state.count })
162-
//! }, sacp::if_request!())
164+
//! .if_request(async |req: InitializeRequest, request_cx| {
165+
//! request_cx.respond(InitializeResponse {
166+
//! protocol_version: req.protocol_version,
167+
//! agent_capabilities: AgentCapabilities::default(),
168+
//! auth_methods: vec![],
169+
//! agent_info: None,
170+
//! meta: None,
171+
//! })
172+
//! })
163173
//! .await
164174
//! .done()
165175
//! }
@@ -247,20 +257,42 @@ pub mod global_mcp_server {
247257
//!
248258
//! # Example
249259
//!
250-
//! ```ignore
260+
//! ```
251261
//! use sacp::mcp_server::McpServer;
252-
//! use sacp::ProxyToConductor;
262+
//! use sacp::{Component, JrResponder, ProxyToConductor};
263+
//! use schemars::JsonSchema;
264+
//! use serde::{Deserialize, Serialize};
265+
//!
266+
//! #[derive(Debug, Deserialize, JsonSchema)]
267+
//! struct EchoParams { message: String }
268+
//!
269+
//! #[derive(Debug, Serialize, JsonSchema)]
270+
//! struct EchoOutput { echoed: String }
253271
//!
272+
//! // Build the MCP server with tools
254273
//! let mcp_server = McpServer::builder("my-tools")
255-
//! .tool_fn("echo", "Echoes the input", async |params: EchoParams, _cx| {
256-
//! Ok(EchoOutput { message: params.message })
257-
//! }, sacp::tool_fn!())
274+
//! .tool_fn("echo", "Echoes the input",
275+
//! async |params: EchoParams, _cx| {
276+
//! Ok(EchoOutput { echoed: params.message })
277+
//! },
278+
//! sacp::tool_fn!())
258279
//! .build();
259280
//!
260-
//! ProxyToConductor::builder()
261-
//! .with_mcp_server(mcp_server)
262-
//! .serve(transport)
263-
//! .await?;
281+
//! // The proxy component is generic over the MCP server's responder type
282+
//! struct MyProxy<R> {
283+
//! mcp_server: McpServer<ProxyToConductor, R>,
284+
//! }
285+
//!
286+
//! impl<R: JrResponder<ProxyToConductor> + Send + 'static> Component for MyProxy<R> {
287+
//! async fn serve(self, client: impl Component) -> Result<(), sacp::Error> {
288+
//! ProxyToConductor::builder()
289+
//! .with_mcp_server(self.mcp_server)
290+
//! .serve(client)
291+
//! .await
292+
//! }
293+
//! }
294+
//!
295+
//! let proxy = MyProxy { mcp_server };
264296
//! ```
265297
//!
266298
//! # How it works

0 commit comments

Comments
 (0)