Skip to content

Commit 486b555

Browse files
authored
feat(unstable): Add initial support for session config options (#36)
1 parent bbfc7df commit 486b555

File tree

6 files changed

+138
-3
lines changed

6 files changed

+138
-3
lines changed

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 = { version = "=0.10.4" }
30+
agent-client-protocol-schema = { version = "=0.10.5" }
3131

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

examples/agent.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,25 @@ impl acp::Agent for ExampleAgent {
142142
Ok(acp::SetSessionModelResponse::default())
143143
}
144144

145+
#[cfg(feature = "unstable_session_config_options")]
146+
async fn set_session_config_option(
147+
&self,
148+
args: acp::SetSessionConfigOptionRequest,
149+
) -> Result<acp::SetSessionConfigOptionResponse, acp::Error> {
150+
log::info!("Received set session config option request {args:?}");
151+
Ok(acp::SetSessionConfigOptionResponse::new(vec![
152+
acp::SessionConfigOption::select(
153+
args.config_id,
154+
"Example Option",
155+
args.value,
156+
vec![
157+
acp::SessionConfigSelectOption::new("option1", "Option 1"),
158+
acp::SessionConfigSelectOption::new("option2", "Option 2"),
159+
]),
160+
),
161+
]))
162+
}
163+
145164
async fn ext_method(&self, args: acp::ExtRequest) -> Result<acp::ExtResponse, acp::Error> {
146165
log::info!(
147166
"Received extension method call: method={}, params={:?}",

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use agent_client_protocol_schema::{ForkSessionRequest, ForkSessionResponse};
1212
use agent_client_protocol_schema::{ListSessionsRequest, ListSessionsResponse};
1313
#[cfg(feature = "unstable_session_resume")]
1414
use agent_client_protocol_schema::{ResumeSessionRequest, ResumeSessionResponse};
15+
#[cfg(feature = "unstable_session_config_options")]
16+
use agent_client_protocol_schema::{SetSessionConfigOptionRequest, SetSessionConfigOptionResponse};
1517
#[cfg(feature = "unstable_session_model")]
1618
use agent_client_protocol_schema::{SetSessionModelRequest, SetSessionModelResponse};
1719
use serde_json::value::RawValue;
@@ -132,6 +134,25 @@ pub trait Agent {
132134
Err(Error::method_not_found())
133135
}
134136

137+
/// **UNSTABLE**
138+
///
139+
/// This capability is not part of the spec yet, and may be removed or changed at any point.
140+
///
141+
/// Sets the current value for a session configuration option.
142+
///
143+
/// Configuration options allow agents to expose arbitrary selectors (like model choice,
144+
/// reasoning level, etc.) that clients can display and modify.
145+
///
146+
/// The response returns the full list of configuration options with their current values,
147+
/// as changing one option may affect others.
148+
#[cfg(feature = "unstable_session_config_options")]
149+
async fn set_session_config_option(
150+
&self,
151+
_args: SetSessionConfigOptionRequest,
152+
) -> Result<SetSessionConfigOptionResponse> {
153+
Err(Error::method_not_found())
154+
}
155+
135156
/// **UNSTABLE**
136157
///
137158
/// This capability is not part of the spec yet, and may be removed or changed at any point.
@@ -225,6 +246,13 @@ impl<T: Agent> Agent for Rc<T> {
225246
) -> Result<SetSessionModelResponse> {
226247
self.as_ref().set_session_model(args).await
227248
}
249+
#[cfg(feature = "unstable_session_config_options")]
250+
async fn set_session_config_option(
251+
&self,
252+
args: SetSessionConfigOptionRequest,
253+
) -> Result<SetSessionConfigOptionResponse> {
254+
self.as_ref().set_session_config_option(args).await
255+
}
228256
#[cfg(feature = "unstable_session_list")]
229257
async fn list_sessions(&self, args: ListSessionsRequest) -> Result<ListSessionsResponse> {
230258
self.as_ref().list_sessions(args).await
@@ -278,6 +306,13 @@ impl<T: Agent> Agent for Arc<T> {
278306
) -> Result<SetSessionModelResponse> {
279307
self.as_ref().set_session_model(args).await
280308
}
309+
#[cfg(feature = "unstable_session_config_options")]
310+
async fn set_session_config_option(
311+
&self,
312+
args: SetSessionConfigOptionRequest,
313+
) -> Result<SetSessionConfigOptionResponse> {
314+
self.as_ref().set_session_config_option(args).await
315+
}
281316
#[cfg(feature = "unstable_session_list")]
282317
async fn list_sessions(&self, args: ListSessionsRequest) -> Result<ListSessionsResponse> {
283318
self.as_ref().list_sessions(args).await

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,19 @@ impl Agent for ClientSideConnection {
185185
.await
186186
}
187187

188+
#[cfg(feature = "unstable_session_config_options")]
189+
async fn set_session_config_option(
190+
&self,
191+
args: SetSessionConfigOptionRequest,
192+
) -> Result<SetSessionConfigOptionResponse> {
193+
self.conn
194+
.request(
195+
AGENT_METHOD_NAMES.session_set_config_option,
196+
Some(ClientRequest::SetSessionConfigOptionRequest(args)),
197+
)
198+
.await
199+
}
200+
188201
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse> {
189202
self.conn
190203
.request(
@@ -560,6 +573,12 @@ impl Side for AgentSide {
560573
m if m == AGENT_METHOD_NAMES.session_resume => serde_json::from_str(params.get())
561574
.map(ClientRequest::ResumeSessionRequest)
562575
.map_err(Into::into),
576+
#[cfg(feature = "unstable_session_config_options")]
577+
m if m == AGENT_METHOD_NAMES.session_set_config_option => {
578+
serde_json::from_str(params.get())
579+
.map(ClientRequest::SetSessionConfigOptionRequest)
580+
.map_err(Into::into)
581+
}
563582
m if m == AGENT_METHOD_NAMES.session_prompt => serde_json::from_str(params.get())
564583
.map(ClientRequest::PromptRequest)
565584
.map_err(Into::into),
@@ -644,6 +663,11 @@ impl<T: Agent> MessageHandler<AgentSide> for T {
644663
let response = self.resume_session(args).await?;
645664
Ok(AgentResponse::ResumeSessionResponse(response))
646665
}
666+
#[cfg(feature = "unstable_session_config_options")]
667+
ClientRequest::SetSessionConfigOptionRequest(args) => {
668+
let response = self.set_session_config_option(args).await?;
669+
Ok(AgentResponse::SetSessionConfigOptionResponse(response))
670+
}
647671
ClientRequest::ExtMethodRequest(args) => {
648672
let response = self.ext_method(args).await?;
649673
Ok(AgentResponse::ExtMethodResponse(response))

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,30 @@ impl Agent for TestAgent {
252252
Ok(agent_client_protocol_schema::ResumeSessionResponse::new())
253253
}
254254

255+
#[cfg(feature = "unstable_session_config_options")]
256+
async fn set_session_config_option(
257+
&self,
258+
args: agent_client_protocol_schema::SetSessionConfigOptionRequest,
259+
) -> Result<agent_client_protocol_schema::SetSessionConfigOptionResponse> {
260+
Ok(
261+
agent_client_protocol_schema::SetSessionConfigOptionResponse::new(vec![
262+
agent_client_protocol_schema::SessionConfigOption::select(
263+
args.config_id,
264+
"Test Option",
265+
args.value,
266+
vec![
267+
agent_client_protocol_schema::SessionConfigSelectOption::new(
268+
"value1", "Value 1",
269+
),
270+
agent_client_protocol_schema::SessionConfigSelectOption::new(
271+
"value2", "Value 2",
272+
),
273+
],
274+
),
275+
]),
276+
)
277+
}
278+
255279
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse> {
256280
dbg!();
257281
match dbg!(args.method.as_ref()) {
@@ -872,3 +896,36 @@ async fn test_session_info_update() {
872896
})
873897
.await;
874898
}
899+
900+
#[cfg(feature = "unstable_session_config_options")]
901+
#[tokio::test]
902+
async fn test_set_session_config_option() {
903+
let local_set = tokio::task::LocalSet::new();
904+
local_set
905+
.run_until(async {
906+
let client = TestClient::new();
907+
let agent = TestAgent::new();
908+
909+
let (agent_conn, _client_conn) = create_connection_pair(&client, &agent);
910+
911+
// Set a config option
912+
let response = agent_conn
913+
.set_session_config_option(
914+
agent_client_protocol_schema::SetSessionConfigOptionRequest::new(
915+
"test-session",
916+
"mode",
917+
"value2",
918+
),
919+
)
920+
.await
921+
.expect("set_session_config_option failed");
922+
923+
// Verify we got config options back
924+
assert_eq!(response.config_options.len(), 1);
925+
assert_eq!(
926+
response.config_options[0].id,
927+
agent_client_protocol_schema::SessionConfigId::new("mode")
928+
);
929+
})
930+
.await;
931+
}

0 commit comments

Comments
 (0)