Skip to content

Commit 75fa06c

Browse files
authored
Merge pull request agentclientprotocol#105 from nikomatsakis/main
feat(deps)!: upgrade agent-client-protocol-schema to 0.10.5
2 parents 215b175 + 89610a0 commit 75fa06c

35 files changed

Lines changed: 343 additions & 601 deletions

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ tokio = { version = "1.48", features = ["full"] }
2020
tokio-util = { version = "0.7", features = ["compat"] }
2121

2222
# Protocol
23-
agent-client-protocol-schema = "0.6.3"
23+
agent-client-protocol-schema = "0.10.5"
2424

2525
# Serialization
2626
serde = { version = "1.0", features = ["derive"] }

src/elizacp/src/lib.rs

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,10 @@ impl ElizaAgent {
7878
tracing::debug!("New session request with cwd: {:?}", request.cwd);
7979

8080
// Generate a new session ID
81-
let session_id = SessionId(Arc::from(uuid::Uuid::new_v4().to_string()));
81+
let session_id = SessionId::new(uuid::Uuid::new_v4().to_string());
8282
self.create_session(&session_id, request.mcp_servers);
8383

84-
let response = NewSessionResponse {
85-
session_id,
86-
modes: None,
87-
meta: None,
88-
};
89-
90-
request_cx.respond(response)
84+
request_cx.respond(NewSessionResponse::new(session_id))
9185
}
9286

9387
async fn handle_load_session(
@@ -100,12 +94,7 @@ impl ElizaAgent {
10094
// For Eliza, we just create a fresh session with no MCP servers
10195
self.create_session(&request.session_id, vec![]);
10296

103-
let response = LoadSessionResponse {
104-
modes: None,
105-
meta: None,
106-
};
107-
108-
request_cx.respond(response)
97+
request_cx.respond(LoadSessionResponse::new())
10998
}
11099

111100
/// Process the prompt and send response - this runs in a spawned task
@@ -171,20 +160,13 @@ impl ElizaAgent {
171160
?final_response,
172161
"Eliza sending SessionNotification"
173162
);
174-
cx.send_notification(SessionNotification {
175-
session_id: session_id.clone(),
176-
update: SessionUpdate::AgentMessageChunk(ContentChunk {
177-
content: final_response.into(),
178-
meta: None,
179-
}),
180-
meta: None,
181-
})?;
163+
cx.send_notification(SessionNotification::new(
164+
session_id.clone(),
165+
SessionUpdate::AgentMessageChunk(ContentChunk::new(final_response.into())),
166+
))?;
182167

183168
// Complete the request
184-
request_cx.respond(PromptResponse {
185-
stop_reason: StopReason::EndTurn,
186-
meta: None,
187-
})
169+
request_cx.respond(PromptResponse::new(StopReason::EndTurn))
188170
}
189171

190172
/// Helper function to execute an operation with an MCP client
@@ -213,34 +195,33 @@ impl ElizaAgent {
213195
let mcp_server = mcp_servers
214196
.iter()
215197
.find(|server| match server {
216-
McpServer::Stdio { name, .. } => name == server_name,
217-
McpServer::Http { name, .. } => name == server_name,
218-
McpServer::Sse { name, .. } => name == server_name,
198+
McpServer::Stdio(stdio) => stdio.name == server_name,
199+
McpServer::Http(http) => http.name == server_name,
200+
McpServer::Sse(sse) => sse.name == server_name,
201+
_ => false,
219202
})
220203
.ok_or_else(|| anyhow::anyhow!("MCP server '{}' not found", server_name))?;
221204

222205
// Spawn MCP client based on server type
223206
match mcp_server {
224-
McpServer::Stdio {
225-
command, args, env, ..
226-
} => {
207+
McpServer::Stdio(stdio) => {
227208
tracing::debug!(
228-
command = ?command,
229-
args = ?args,
209+
command = ?stdio.command,
210+
args = ?stdio.args,
230211
server_name = %server_name,
231212
"Starting MCP client"
232213
);
233214

234215
// Create MCP client by spawning the process
235216
let mcp_client = ()
236-
.serve(TokioChildProcess::new(Command::new(command).configure(
237-
|cmd| {
238-
cmd.args(args);
239-
for env_var in env {
217+
.serve(TokioChildProcess::new(
218+
Command::new(&stdio.command).configure(|cmd| {
219+
cmd.args(&stdio.args);
220+
for env_var in &stdio.env {
240221
cmd.env(&env_var.name, &env_var.value);
241222
}
242-
},
243-
))?)
223+
}),
224+
)?)
244225
.await?;
245226

246227
tracing::debug!("MCP client connected");
@@ -250,18 +231,18 @@ impl ElizaAgent {
250231

251232
Ok(result)
252233
}
253-
McpServer::Http { url, .. } => {
234+
McpServer::Http(http) => {
254235
use rmcp::transport::StreamableHttpClientTransport;
255236

256237
tracing::debug!(
257-
url = %url,
238+
url = %http.url,
258239
server_name = %server_name,
259240
"Starting HTTP MCP client"
260241
);
261242

262243
// Create HTTP MCP client
263244
let mcp_client =
264-
().serve(StreamableHttpClientTransport::from_uri(url.as_str()))
245+
().serve(StreamableHttpClientTransport::from_uri(http.url.as_str()))
265246
.await?;
266247

267248
tracing::debug!("HTTP MCP client connected");
@@ -271,7 +252,8 @@ impl ElizaAgent {
271252

272253
Ok(result)
273254
}
274-
McpServer::Sse { .. } => Err(anyhow::anyhow!("SSE MCP servers not yet supported")),
255+
McpServer::Sse(_) => Err(anyhow::anyhow!("SSE MCP servers not yet supported")),
256+
_ => Err(anyhow::anyhow!("Unknown MCP server type")),
275257
}
276258
}
277259

@@ -394,18 +376,10 @@ impl Component<sacp::link::AgentToClient> for ElizaAgent {
394376
async |initialize: InitializeRequest, request_cx, _cx| {
395377
tracing::debug!("Received initialize request");
396378

397-
request_cx.respond(InitializeResponse {
398-
protocol_version: initialize.protocol_version,
399-
agent_capabilities: AgentCapabilities {
400-
load_session: Default::default(),
401-
prompt_capabilities: Default::default(),
402-
mcp_capabilities: Default::default(),
403-
meta: Default::default(),
404-
},
405-
auth_methods: Default::default(),
406-
agent_info: Default::default(),
407-
meta: Default::default(),
408-
})
379+
request_cx.respond(
380+
InitializeResponse::new(initialize.protocol_version)
381+
.agent_capabilities(AgentCapabilities::new()),
382+
)
409383
},
410384
sacp::on_receive_request!(),
411385
)

src/elizacp/tests/mcp_tool_invocation.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use expect_test::expect;
55
use sacp::Component;
66
use sacp::link::UntypedLink;
77
use sacp::schema::{
8-
ContentBlock, InitializeRequest, McpServer, NewSessionRequest, PromptRequest,
9-
SessionNotification, TextContent,
8+
ContentBlock, InitializeRequest, McpServer, McpServerStdio, NewSessionRequest, PromptRequest,
9+
ProtocolVersion, SessionNotification, TextContent,
1010
};
1111
use sacp_test::test_binaries;
1212
use std::path::PathBuf;
@@ -61,41 +61,29 @@ async fn test_elizacp_mcp_tool_call() -> Result<(), sacp::Error> {
6161
})
6262
.run_until(transport, async |client_cx| {
6363
// Initialize
64-
let _init_response = recv(client_cx.send_request(InitializeRequest {
65-
protocol_version: Default::default(),
66-
client_capabilities: Default::default(),
67-
meta: None,
68-
client_info: None,
69-
}))
70-
.await?;
64+
let _init_response =
65+
recv(client_cx.send_request(InitializeRequest::new(ProtocolVersion::LATEST)))
66+
.await?;
7167

7268
// Create session with an MCP server
7369
// Use the mcp-echo-server from sacp-test (pre-built binary)
7470
let mcp_server_binary = test_binaries::mcp_echo_server_binary();
75-
let session_response = recv(client_cx.send_request(NewSessionRequest {
76-
cwd: PathBuf::from("/tmp"),
77-
mcp_servers: vec![McpServer::Stdio {
78-
name: "test".to_string(),
79-
command: mcp_server_binary,
80-
args: vec![],
81-
env: vec![],
82-
}],
83-
meta: None,
84-
}))
71+
let session_response = recv(client_cx.send_request(
72+
NewSessionRequest::new(PathBuf::from("/tmp")).mcp_servers(vec![McpServer::Stdio(
73+
McpServerStdio::new("test".to_string(), mcp_server_binary),
74+
)]),
75+
))
8576
.await?;
8677

8778
let session_id = session_response.session_id;
8879

8980
// Send a prompt to invoke the MCP tool
90-
let _prompt_response = recv(client_cx.send_request(PromptRequest {
91-
session_id: session_id.clone(),
92-
prompt: vec![ContentBlock::Text(TextContent {
93-
annotations: None,
94-
text: r#"Use tool test::echo with {"message": "Hello from test!"}"#.to_string(),
95-
meta: None,
96-
})],
97-
meta: None,
98-
}))
81+
let _prompt_response = recv(client_cx.send_request(PromptRequest::new(
82+
session_id.clone(),
83+
vec![ContentBlock::Text(TextContent::new(
84+
r#"Use tool test::echo with {"message": "Hello from test!"}"#.to_string(),
85+
))],
86+
)))
9987
.await?;
10088

10189
Ok(())

src/sacp-conductor/src/conductor.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ where
971971
.if_request(async |_request: InitializeProxyRequest, request_cx| {
972972
request_cx.respond_with_error(
973973
sacp::Error::invalid_request()
974-
.with_data("initialize/proxy requests are only sent by the conductor"),
974+
.data("initialize/proxy requests are only sent by the conductor"),
975975
)
976976
})
977977
.await
@@ -1021,7 +1021,7 @@ where
10211021
.if_request(async |_request: InitializeProxyRequest, request_cx| {
10221022
request_cx.respond_with_error(
10231023
sacp::Error::invalid_request()
1024-
.with_data("initialize/proxy requests are only sent by the conductor"),
1024+
.data("initialize/proxy requests are only sent by the conductor"),
10251025
)
10261026
})
10271027
.await
@@ -1514,8 +1514,7 @@ impl ConductorLink for ConductorToClient {
15141514
instantiator: Self::Instantiator,
15151515
responder: &mut ConductorResponder<Self>,
15161516
) -> Result<MessageCx, sacp::Error> {
1517-
let invalid_request =
1518-
|| Error::invalid_request().with_data("expected `initialize` request");
1517+
let invalid_request = || Error::invalid_request().data("expected `initialize` request");
15191518

15201519
// Not yet initialized - expect an initialize request.
15211520
// Error if we get anything else.
@@ -1614,8 +1613,7 @@ impl ConductorLink for ConductorToConductor {
16141613
instantiator: Self::Instantiator,
16151614
responder: &mut ConductorResponder<Self>,
16161615
) -> Result<MessageCx, sacp::Error> {
1617-
let invalid_request =
1618-
|| Error::invalid_request().with_data("expected `initialize` request");
1616+
let invalid_request = || Error::invalid_request().data("expected `initialize` request");
16191617

16201618
// Not yet initialized - expect an InitializeProxy request.
16211619
// Error if we get anything else.

src/sacp-conductor/src/conductor/mcp_bridge.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::collections::HashMap;
66
use std::path::PathBuf;
77

88
use futures::{SinkExt, channel::mpsc};
9-
use sacp::schema::McpServer;
9+
use sacp::schema::{McpServer, McpServerHttp, McpServerStdio};
1010
use sacp::{self, JrLink};
1111
use sacp::{JrConnectionCx, MessageCx};
1212
use tokio::net::TcpListener;
@@ -67,18 +67,21 @@ impl McpBridgeListeners {
6767
) -> Result<(), sacp::Error> {
6868
use sacp::schema::McpServer;
6969

70-
let McpServer::Http { name, url, headers } = mcp_server else {
70+
let McpServer::Http(http) = mcp_server else {
7171
return Ok(());
7272
};
7373

74-
if !url.starts_with("acp:") {
74+
if !http.url.starts_with("acp:") {
7575
return Ok(());
7676
}
7777

78-
if !headers.is_empty() {
78+
if !http.headers.is_empty() {
7979
return Err(sacp::Error::internal_error());
8080
}
8181

82+
let name = &http.name;
83+
let url = &http.url;
84+
8285
info!(
8386
server_name = name,
8487
acp_url = url,
@@ -114,22 +117,24 @@ impl McpBridgeListeners {
114117
info!(acp_url = acp_url, tcp_port, "Bound listener for MCP bridge");
115118

116119
let new_server = match mcp_bridge_mode {
117-
crate::McpBridgeMode::Stdio { conductor_command } => McpServer::Stdio {
118-
name: server_name.to_string(),
119-
command: PathBuf::from(&conductor_command[0]),
120-
args: conductor_command[1..]
121-
.iter()
122-
.cloned()
123-
.chain(vec!["mcp".to_string(), format!("{tcp_port}")])
124-
.collect(),
125-
env: Default::default(),
126-
},
127-
128-
crate::McpBridgeMode::Http => McpServer::Http {
129-
name: server_name.to_string(),
130-
url: format!("http://localhost:{tcp_port}"),
131-
headers: vec![],
132-
},
120+
crate::McpBridgeMode::Stdio { conductor_command } => McpServer::Stdio(
121+
McpServerStdio::new(
122+
server_name.to_string(),
123+
PathBuf::from(&conductor_command[0]),
124+
)
125+
.args(
126+
conductor_command[1..]
127+
.iter()
128+
.cloned()
129+
.chain(vec!["mcp".to_string(), format!("{tcp_port}")])
130+
.collect::<Vec<_>>(),
131+
),
132+
),
133+
134+
crate::McpBridgeMode::Http => McpServer::Http(McpServerHttp::new(
135+
server_name.to_string(),
136+
format!("http://localhost:{tcp_port}"),
137+
)),
133138
};
134139

135140
// remember for later

0 commit comments

Comments
 (0)