Skip to content

Commit 36f65ff

Browse files
committed
Update to agent-client-protocol-schema 0.7
1 parent 57f7239 commit 36f65ff

31 files changed

Lines changed: 329 additions & 778 deletions

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

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

2929
# Protocol
30-
agent-client-protocol-schema = "0.6.3"
30+
agent-client-protocol-schema = "0.7.0"
3131

3232
# Serialization
3333
serde = { version = "1.0", features = ["derive", "rc"] }

examples/migration/agent_legacy.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
55
use agent_client_protocol::{Agent, AgentSideConnection, Client};
66
use agent_client_protocol_schema::{
7-
AgentCapabilities, AuthenticateRequest, AuthenticateResponse, CancelNotification, Error,
8-
ExtNotification, ExtRequest, ExtResponse, InitializeRequest, InitializeResponse,
9-
LoadSessionRequest, LoadSessionResponse, NewSessionRequest, NewSessionResponse, PromptRequest,
10-
PromptResponse, ReadTextFileRequest, ReadTextFileResponse, Result, SetSessionModeRequest,
7+
AuthenticateRequest, AuthenticateResponse, CancelNotification, Error, ExtNotification,
8+
ExtRequest, ExtResponse, InitializeRequest, InitializeResponse, LoadSessionRequest,
9+
LoadSessionResponse, NewSessionRequest, NewSessionResponse, PromptRequest, PromptResponse,
10+
ReadTextFileRequest, ReadTextFileResponse, Result, SetSessionModeRequest,
1111
SetSessionModeResponse, StopReason, WriteTextFileRequest, WriteTextFileResponse,
1212
};
1313
use futures::FutureExt;
@@ -23,13 +23,7 @@ struct MyAgent {
2323
impl Agent for MyAgent {
2424
async fn initialize(&self, args: InitializeRequest) -> Result<InitializeResponse> {
2525
eprintln!("[{}] Initializing", self.name);
26-
Ok(InitializeResponse {
27-
protocol_version: args.protocol_version,
28-
agent_capabilities: AgentCapabilities::default(),
29-
auth_methods: Default::default(),
30-
agent_info: Default::default(),
31-
meta: Default::default(),
32-
})
26+
Ok(InitializeResponse::new(args.protocol_version))
3327
}
3428

3529
async fn authenticate(&self, _args: AuthenticateRequest) -> Result<AuthenticateResponse> {
@@ -38,21 +32,12 @@ impl Agent for MyAgent {
3832

3933
async fn new_session(&self, _args: NewSessionRequest) -> Result<NewSessionResponse> {
4034
eprintln!("[{}] Creating session", self.name);
41-
Ok(NewSessionResponse {
42-
session_id: "session-1".into(),
43-
modes: None,
44-
meta: Default::default(),
45-
#[cfg(feature = "unstable")]
46-
models: None,
47-
})
35+
Ok(NewSessionResponse::new("session-1".into()))
4836
}
4937

5038
async fn prompt(&self, _args: PromptRequest) -> Result<PromptResponse> {
5139
eprintln!("[{}] Processing prompt", self.name);
52-
Ok(PromptResponse {
53-
stop_reason: StopReason::EndTurn,
54-
meta: Default::default(),
55-
})
40+
Ok(PromptResponse::new(StopReason::EndTurn))
5641
}
5742

5843
async fn cancel(&self, _args: CancelNotification) -> Result<()> {

examples/migration/agent_sacp.rs

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
//! This example shows the handler-based approach for building agents.
44
55
use sacp::schema::{
6-
AgentCapabilities, InitializeRequest, InitializeResponse, NewSessionRequest,
7-
NewSessionResponse, PromptRequest, PromptResponse, ReadTextFileRequest, StopReason,
8-
WriteTextFileRequest,
6+
InitializeRequest, InitializeResponse, NewSessionRequest, NewSessionResponse, PromptRequest,
7+
PromptResponse, ReadTextFileRequest, StopReason, WriteTextFileRequest,
98
};
109
use sacp::{JrHandlerChain, MessageAndCx, UntypedMessage};
1110
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
@@ -20,34 +19,19 @@ async fn main() -> Result<(), sacp::Error> {
2019
// ANCHOR: handler_initialize
2120
.on_receive_request(async move |req: InitializeRequest, cx| {
2221
eprintln!("[{}] Initializing", agent_name);
23-
cx.respond(InitializeResponse {
24-
protocol_version: req.protocol_version,
25-
agent_capabilities: AgentCapabilities::default(),
26-
auth_methods: Default::default(),
27-
agent_info: Default::default(),
28-
meta: Default::default(),
29-
})
22+
cx.respond(InitializeResponse::new(req.protocol_version))
3023
})
3124
// ANCHOR_END: handler_initialize
3225
// ANCHOR: handler_new_session
3326
.on_receive_request(async move |_req: NewSessionRequest, cx| {
3427
eprintln!("[{}] Creating session", agent_name);
35-
cx.respond(NewSessionResponse {
36-
session_id: "session-1".into(),
37-
modes: None,
38-
#[cfg(feature = "unstable")]
39-
models: None,
40-
meta: Default::default(),
41-
})
28+
cx.respond(NewSessionResponse::new("session-1".into()))
4229
})
4330
// ANCHOR_END: handler_new_session
4431
// ANCHOR: handler_prompt
4532
.on_receive_request(async move |_req: PromptRequest, cx| {
4633
eprintln!("[{}] Processing prompt", agent_name);
47-
cx.respond(PromptResponse {
48-
stop_reason: StopReason::EndTurn,
49-
meta: Default::default(),
50-
})
34+
cx.respond(PromptResponse::new(StopReason::EndTurn))
5135
})
5236
// ANCHOR_END: handler_prompt
5337
// ANCHOR: handler_client_requests

examples/migration/agent_with_callbacks_sacp.rs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
//! and the importance of not blocking the message handler.
55
66
use sacp::schema::{
7-
AgentCapabilities, InitializeRequest, InitializeResponse, NewSessionRequest,
8-
NewSessionResponse, PromptRequest, PromptResponse, StopReason,
7+
InitializeRequest, InitializeResponse, NewSessionRequest, NewSessionResponse, PromptRequest,
8+
PromptResponse, StopReason,
99
};
1010
use sacp::{JrHandlerChain, MessageAndCx, UntypedMessage};
1111
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
@@ -15,22 +15,10 @@ async fn main() -> Result<(), sacp::Error> {
1515
JrHandlerChain::new()
1616
.name("callback-agent")
1717
.on_receive_request(async move |req: InitializeRequest, cx| {
18-
cx.respond(InitializeResponse {
19-
protocol_version: req.protocol_version,
20-
agent_capabilities: AgentCapabilities::default(),
21-
auth_methods: Default::default(),
22-
agent_info: Default::default(),
23-
meta: Default::default(),
24-
})
18+
cx.respond(InitializeResponse::new(req.protocol_version))
2519
})
2620
.on_receive_request(async move |_req: NewSessionRequest, cx| {
27-
cx.respond(NewSessionResponse {
28-
session_id: "session-1".into(),
29-
modes: None,
30-
#[cfg(feature = "unstable")]
31-
models: None,
32-
meta: Default::default(),
33-
})
21+
cx.respond(NewSessionResponse::new("session-1".into()))
3422
})
3523
// ANCHOR: blocking_risk
3624
.on_receive_request(async move |_req: PromptRequest, cx| {
@@ -47,10 +35,7 @@ async fn main() -> Result<(), sacp::Error> {
4735
// cx.respond(response)
4836

4937
// ✅ GOOD: Respond immediately
50-
cx.respond(PromptResponse {
51-
stop_reason: StopReason::EndTurn,
52-
meta: Default::default(),
53-
})
38+
cx.respond(PromptResponse::new(StopReason::EndTurn))
5439
})
5540
// ANCHOR_END: blocking_risk
5641
// ANCHOR: spawn_alternative
@@ -66,10 +51,7 @@ async fn main() -> Result<(), sacp::Error> {
6651
});
6752

6853
// Respond immediately
69-
cx.respond(PromptResponse {
70-
stop_reason: StopReason::EndTurn,
71-
meta: Default::default(),
72-
})
54+
cx.respond(PromptResponse::new(StopReason::EndTurn))
7355
})
7456
// ANCHOR_END: spawn_alternative
7557
.on_receive_message(

examples/migration/client_legacy.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22
//!
33
//! This example shows how to connect to an agent and send requests.
44
5-
use agent_client_protocol::{Agent, Client, ClientSideConnection};
6-
use agent_client_protocol_schema::{
7-
CreateTerminalRequest, CreateTerminalResponse, Error, ExtNotification, ExtRequest, ExtResponse,
8-
InitializeRequest, KillTerminalCommandRequest, KillTerminalCommandResponse, NewSessionRequest,
9-
PromptRequest, ReadTextFileRequest, ReadTextFileResponse, ReleaseTerminalRequest,
10-
ReleaseTerminalResponse, RequestPermissionRequest, RequestPermissionResponse, Result,
11-
SessionNotification, TerminalOutputRequest, TerminalOutputResponse, VERSION,
12-
WaitForTerminalExitRequest, WaitForTerminalExitResponse, WriteTextFileRequest,
13-
WriteTextFileResponse,
5+
use agent_client_protocol::{
6+
Agent, Client, ClientSideConnection, CreateTerminalRequest, CreateTerminalResponse, Error,
7+
ExtNotification, ExtRequest, ExtResponse, InitializeRequest, KillTerminalCommandRequest,
8+
KillTerminalCommandResponse, NewSessionRequest, PromptRequest, ReadTextFileRequest,
9+
ReadTextFileResponse, ReleaseTerminalRequest, ReleaseTerminalResponse,
10+
RequestPermissionRequest, RequestPermissionResponse, Result, SessionNotification,
11+
TerminalOutputRequest, TerminalOutputResponse, V1, WaitForTerminalExitRequest,
12+
WaitForTerminalExitResponse, WriteTextFileRequest, WriteTextFileResponse,
1413
};
1514
use futures::FutureExt;
16-
use std::path::PathBuf;
1715
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
1816

1917
// ANCHOR: client_impl
@@ -127,35 +125,18 @@ async fn main() -> Result<()> {
127125
// Now we can send requests using the connection
128126
// ANCHOR: send_requests
129127
// Initialize the agent
130-
let init_response = connection
131-
.initialize(InitializeRequest {
132-
protocol_version: VERSION,
133-
client_capabilities: Default::default(),
134-
client_info: Default::default(),
135-
meta: None,
136-
})
137-
.await?;
128+
let init_response = connection.initialize(InitializeRequest::new(V1)).await?;
138129

139130
eprintln!("Agent initialized: {:?}", init_response.agent_info);
140131

141132
// Create a session
142-
let session_response = connection
143-
.new_session(NewSessionRequest {
144-
mcp_servers: vec![],
145-
cwd: PathBuf::from("/"),
146-
meta: None,
147-
})
148-
.await?;
133+
let session_response = connection.new_session(NewSessionRequest::new("/")).await?;
149134

150135
eprintln!("Session created: {}", session_response.session_id);
151136

152137
// Send a prompt
153138
let prompt_response = connection
154-
.prompt(PromptRequest {
155-
session_id: session_response.session_id,
156-
prompt: vec![],
157-
meta: None,
158-
})
139+
.prompt(PromptRequest::new(session_response.session_id, vec![]))
159140
.await?;
160141

161142
eprintln!("Prompt completed: {:?}", prompt_response.stop_reason);

examples/migration/client_sacp.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use sacp::schema::{
77
InitializeRequest, NewSessionRequest, PromptRequest, ReadTextFileRequest,
88
RequestPermissionRequest, SessionNotification, VERSION, WriteTextFileRequest,
99
};
10-
use std::path::PathBuf;
1110
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
1211

1312
// ANCHOR: setup
@@ -49,36 +48,23 @@ async fn main() -> Result<(), sacp::Error> {
4948
// ANCHOR: send_requests
5049
// Initialize the agent
5150
let init_response = cx
52-
.send_request(InitializeRequest {
53-
protocol_version: VERSION,
54-
client_capabilities: Default::default(),
55-
client_info: Default::default(),
56-
meta: None,
57-
})
51+
.send_request(InitializeRequest::new(VERSION))
5852
.block_task()
5953
.await?;
6054

6155
eprintln!("Agent initialized: {:?}", init_response.agent_info);
6256

6357
// Create a session
6458
let session_response = cx
65-
.send_request(NewSessionRequest {
66-
mcp_servers: vec![],
67-
cwd: PathBuf::from("/"),
68-
meta: None,
69-
})
59+
.send_request(NewSessionRequest::new("/"))
7060
.block_task()
7161
.await?;
7262

7363
eprintln!("Session created: {}", session_response.session_id);
7464

7565
// Send a prompt
7666
let prompt_response = cx
77-
.send_request(PromptRequest {
78-
session_id: session_response.session_id,
79-
prompt: vec![],
80-
meta: None,
81-
})
67+
.send_request(PromptRequest::new(session_response.session_id, vec![]))
8268
.block_task()
8369
.await?;
8470

src/agent-client-protocol/src/lib.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,10 @@ impl Side for ClientSide {
220220
}
221221
_ => {
222222
if let Some(custom_method) = method.strip_prefix('_') {
223-
Ok(AgentRequest::ExtMethodRequest(ExtRequest {
224-
method: custom_method.into(),
225-
params: params.to_owned().into(),
226-
}))
223+
Ok(AgentRequest::ExtMethodRequest(ExtRequest::new(
224+
custom_method,
225+
params.to_owned(),
226+
)))
227227
} else {
228228
Err(Error::method_not_found())
229229
}
@@ -240,10 +240,10 @@ impl Side for ClientSide {
240240
.map_err(Into::into),
241241
_ => {
242242
if let Some(custom_method) = method.strip_prefix('_') {
243-
Ok(AgentNotification::ExtNotification(ExtNotification {
244-
method: custom_method.into(),
245-
params: RawValue::from_string(params.get().to_string())?.into(),
246-
}))
243+
Ok(AgentNotification::ExtNotification(ExtNotification::new(
244+
custom_method,
245+
RawValue::from_string(params.get().to_string())?,
246+
)))
247247
} else {
248248
Err(Error::method_not_found())
249249
}
@@ -291,6 +291,7 @@ impl<T: Client> MessageHandler<ClientSide> for T {
291291
let response = self.ext_method(args).await?;
292292
Ok(ClientResponse::ExtMethodResponse(response))
293293
}
294+
_ => Err(Error::method_not_found()),
294295
}
295296
}
296297

@@ -302,6 +303,8 @@ impl<T: Client> MessageHandler<ClientSide> for T {
302303
AgentNotification::ExtNotification(args) => {
303304
self.ext_notification(args).await?;
304305
}
306+
// Ignore unknown notifications
307+
_ => {}
305308
}
306309
Ok(())
307310
}
@@ -520,10 +523,10 @@ impl Side for AgentSide {
520523
.map_err(Into::into),
521524
_ => {
522525
if let Some(custom_method) = method.strip_prefix('_') {
523-
Ok(ClientRequest::ExtMethodRequest(ExtRequest {
524-
method: custom_method.into(),
525-
params: params.to_owned().into(),
526-
}))
526+
Ok(ClientRequest::ExtMethodRequest(ExtRequest::new(
527+
custom_method,
528+
params.to_owned(),
529+
)))
527530
} else {
528531
Err(Error::method_not_found())
529532
}
@@ -540,10 +543,10 @@ impl Side for AgentSide {
540543
.map_err(Into::into),
541544
_ => {
542545
if let Some(custom_method) = method.strip_prefix('_') {
543-
Ok(ClientNotification::ExtNotification(ExtNotification {
544-
method: custom_method.into(),
545-
params: RawValue::from_string(params.get().to_string())?.into(),
546-
}))
546+
Ok(ClientNotification::ExtNotification(ExtNotification::new(
547+
custom_method,
548+
RawValue::from_string(params.get().to_string())?,
549+
)))
547550
} else {
548551
Err(Error::method_not_found())
549552
}
@@ -588,6 +591,7 @@ impl<T: Agent> MessageHandler<AgentSide> for T {
588591
let response = self.ext_method(args).await?;
589592
Ok(AgentResponse::ExtMethodResponse(response))
590593
}
594+
_ => Err(Error::method_not_found()),
591595
}
592596
}
593597

@@ -599,6 +603,8 @@ impl<T: Agent> MessageHandler<AgentSide> for T {
599603
ClientNotification::ExtNotification(args) => {
600604
self.ext_notification(args).await?;
601605
}
606+
// Ignore unknown notifications
607+
_ => {}
602608
}
603609
Ok(())
604610
}

0 commit comments

Comments
 (0)