Skip to content

Commit a19eb3b

Browse files
Add session/setTitle method for client-driven session renaming
1 parent cb1db65 commit a19eb3b

17 files changed

Lines changed: 1116 additions & 0 deletions

File tree

‎agent-client-protocol-schema/Cargo.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ workspace = true
2424
[features]
2525
unstable = [
2626
"unstable_auth_methods",
27+
"unstable_cancel_request",
2728
"unstable_elicitation",
2829
"unstable_llm_providers",
2930
"unstable_mcp_over_acp",
@@ -38,6 +39,7 @@ unstable = [
3839
# version, so it must be opted into explicitly.
3940
unstable_protocol_v2 = []
4041
unstable_auth_methods = []
42+
unstable_cancel_request = []
4143
unstable_elicitation = []
4244
unstable_llm_providers = []
4345
unstable_mcp_over_acp = []

‎agent-client-protocol-schema/src/v1/agent.rs‎

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,6 +2242,92 @@ impl SetSessionModeResponse {
22422242
}
22432243
}
22442244

2245+
/// Request parameters for setting a session title.
2246+
#[serde_as]
2247+
#[skip_serializing_none]
2248+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2249+
#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_TITLE_METHOD_NAME))]
2250+
#[serde(rename_all = "camelCase")]
2251+
#[non_exhaustive]
2252+
pub struct SetSessionTitleRequest {
2253+
/// The ID of the session to set the title for.
2254+
pub session_id: SessionId,
2255+
/// The new title for the session.
2256+
pub title: String,
2257+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
2258+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2259+
/// these keys.
2260+
///
2261+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2262+
#[serde_as(deserialize_as = "DefaultOnError")]
2263+
#[schemars(extend("x-deserialize-default-on-error" = true))]
2264+
#[serde(default)]
2265+
#[serde(rename = "_meta")]
2266+
pub meta: Option<Meta>,
2267+
}
2268+
2269+
impl SetSessionTitleRequest {
2270+
/// Builds [`SetSessionTitleRequest`] with the required request fields set; optional fields start unset or empty.
2271+
#[must_use]
2272+
pub fn new(session_id: impl Into<SessionId>, title: impl Into<String>) -> Self {
2273+
Self {
2274+
session_id: session_id.into(),
2275+
title: title.into(),
2276+
meta: None,
2277+
}
2278+
}
2279+
2280+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
2281+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2282+
/// these keys.
2283+
///
2284+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2285+
#[must_use]
2286+
pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2287+
self.meta = meta.into_option();
2288+
self
2289+
}
2290+
}
2291+
2292+
/// Response to `session/setTitle` method.
2293+
#[serde_as]
2294+
#[skip_serializing_none]
2295+
#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
2296+
#[schemars(extend("x-side" = "agent", "x-method" = SESSION_SET_TITLE_METHOD_NAME))]
2297+
#[serde(rename_all = "camelCase")]
2298+
#[non_exhaustive]
2299+
pub struct SetSessionTitleResponse {
2300+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
2301+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2302+
/// these keys.
2303+
///
2304+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2305+
#[serde_as(deserialize_as = "DefaultOnError")]
2306+
#[schemars(extend("x-deserialize-default-on-error" = true))]
2307+
#[serde(default)]
2308+
#[serde(rename = "_meta")]
2309+
pub meta: Option<Meta>,
2310+
}
2311+
2312+
impl SetSessionTitleResponse {
2313+
/// Builds [`SetSessionTitleResponse`] with the required response fields set; optional fields start unset or empty.
2314+
#[must_use]
2315+
pub fn new() -> Self {
2316+
Self::default()
2317+
}
2318+
2319+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
2320+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
2321+
/// these keys.
2322+
///
2323+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
2324+
#[must_use]
2325+
pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
2326+
self.meta = meta.into_option();
2327+
self
2328+
}
2329+
}
2330+
22452331
// Session config options
22462332

22472333
/// Unique identifier for a session configuration option.
@@ -4293,6 +4379,11 @@ pub struct SessionCapabilities {
42934379
#[schemars(extend("x-deserialize-default-on-error" = true))]
42944380
#[serde(default)]
42954381
pub close: Option<SessionCloseCapabilities>,
4382+
/// Whether the agent supports `session/setTitle`.
4383+
#[serde_as(deserialize_as = "DefaultOnError")]
4384+
#[schemars(extend("x-deserialize-default-on-error" = true))]
4385+
#[serde(default)]
4386+
pub set_title: Option<SessionSetTitleCapabilities>,
42964387
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
42974388
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
42984389
/// these keys.
@@ -4381,6 +4472,13 @@ impl SessionCapabilities {
43814472
self
43824473
}
43834474

4475+
/// Whether the agent supports `session/setTitle`.
4476+
#[must_use]
4477+
pub fn set_title(mut self, set_title: impl IntoOption<SessionSetTitleCapabilities>) -> Self {
4478+
self.set_title = set_title.into_option();
4479+
self
4480+
}
4481+
43844482
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
43854483
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
43864484
/// these keys.
@@ -4636,6 +4734,45 @@ impl SessionCloseCapabilities {
46364734
}
46374735
}
46384736

4737+
/// Capabilities for the `session/setTitle` method.
4738+
///
4739+
/// By supplying `{}` it means that the agent supports setting session titles.
4740+
#[serde_as]
4741+
#[skip_serializing_none]
4742+
#[derive(Default, Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
4743+
#[non_exhaustive]
4744+
pub struct SessionSetTitleCapabilities {
4745+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
4746+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
4747+
/// these keys.
4748+
///
4749+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
4750+
#[serde_as(deserialize_as = "DefaultOnError")]
4751+
#[schemars(extend("x-deserialize-default-on-error" = true))]
4752+
#[serde(default)]
4753+
#[serde(rename = "_meta")]
4754+
pub meta: Option<Meta>,
4755+
}
4756+
4757+
impl SessionSetTitleCapabilities {
4758+
/// Builds an empty [`SessionSetTitleCapabilities`]; use builder methods to advertise supported sub-capabilities.
4759+
#[must_use]
4760+
pub fn new() -> Self {
4761+
Self::default()
4762+
}
4763+
4764+
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
4765+
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
4766+
/// these keys.
4767+
///
4768+
/// See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)
4769+
#[must_use]
4770+
pub fn meta(mut self, meta: impl IntoOption<Meta>) -> Self {
4771+
self.meta = meta.into_option();
4772+
self
4773+
}
4774+
}
4775+
46394776
/// Prompt capabilities supported by the agent in `session/prompt` requests.
46404777
///
46414778
/// Baseline agent functionality requires support for [`ContentBlock::Text`]
@@ -4838,6 +4975,8 @@ pub struct AgentMethodNames {
48384975
pub session_load: &'static str,
48394976
/// Method for setting the mode for a session.
48404977
pub session_set_mode: &'static str,
4978+
/// Method for setting the title for a session.
4979+
pub session_set_title: &'static str,
48414980
/// Method for setting a configuration option for a session.
48424981
pub session_set_config_option: &'static str,
48434982
/// Method for sending a prompt to the agent.
@@ -4905,6 +5044,7 @@ pub const AGENT_METHOD_NAMES: AgentMethodNames = AgentMethodNames {
49055044
session_new: SESSION_NEW_METHOD_NAME,
49065045
session_load: SESSION_LOAD_METHOD_NAME,
49075046
session_set_mode: SESSION_SET_MODE_METHOD_NAME,
5047+
session_set_title: SESSION_SET_TITLE_METHOD_NAME,
49085048
session_set_config_option: SESSION_SET_CONFIG_OPTION_METHOD_NAME,
49095049
session_prompt: SESSION_PROMPT_METHOD_NAME,
49105050
session_cancel: SESSION_CANCEL_METHOD_NAME,
@@ -4958,6 +5098,8 @@ pub(crate) const SESSION_NEW_METHOD_NAME: &str = "session/new";
49585098
pub(crate) const SESSION_LOAD_METHOD_NAME: &str = "session/load";
49595099
/// Method name for setting the mode for a session.
49605100
pub(crate) const SESSION_SET_MODE_METHOD_NAME: &str = "session/set_mode";
5101+
/// Method name for setting the title for a session.
5102+
pub(crate) const SESSION_SET_TITLE_METHOD_NAME: &str = "session/setTitle";
49615103
/// Method name for setting a configuration option for a session.
49625104
pub(crate) const SESSION_SET_CONFIG_OPTION_METHOD_NAME: &str = "session/set_config_option";
49635105
/// Method name for sending a prompt.
@@ -5112,6 +5254,13 @@ pub enum ClientRequest {
51125254
///
51135255
/// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
51145256
SetSessionModeRequest(SetSessionModeRequest),
5257+
/// Sets the title for a session.
5258+
///
5259+
/// Empty titles are valid and request that the agent clear the session title.
5260+
///
5261+
/// This method can be called at any time during a session, whether the Agent is
5262+
/// idle or actively generating a response.
5263+
SetSessionTitleRequest(SetSessionTitleRequest),
51155264
/// Sets the current value for a session configuration option.
51165265
SetSessionConfigOptionRequest(SetSessionConfigOptionRequest),
51175266
/// Processes a user prompt within a session.
@@ -5189,6 +5338,7 @@ impl ClientRequest {
51895338
Self::ResumeSessionRequest(_) => AGENT_METHOD_NAMES.session_resume,
51905339
Self::CloseSessionRequest(_) => AGENT_METHOD_NAMES.session_close,
51915340
Self::SetSessionModeRequest(_) => AGENT_METHOD_NAMES.session_set_mode,
5341+
Self::SetSessionTitleRequest(_) => AGENT_METHOD_NAMES.session_set_title,
51925342
Self::SetSessionConfigOptionRequest(_) => AGENT_METHOD_NAMES.session_set_config_option,
51935343
Self::PromptRequest(_) => AGENT_METHOD_NAMES.session_prompt,
51945344
#[cfg(feature = "unstable_nes")]
@@ -5248,6 +5398,8 @@ pub enum AgentResponse {
52485398
CloseSessionResponse(#[serde(default)] CloseSessionResponse),
52495399
/// Successful result returned for a `session/set_mode` request.
52505400
SetSessionModeResponse(#[serde(default)] SetSessionModeResponse),
5401+
/// Successful result returned for a `session/setTitle` request.
5402+
SetSessionTitleResponse(#[serde(default)] SetSessionTitleResponse),
52515403
/// Successful result returned for a `session/set_config_option` request.
52525404
SetSessionConfigOptionResponse(SetSessionConfigOptionResponse),
52535405
/// Successful result returned for a `session/prompt` request.
@@ -6136,6 +6288,43 @@ mod test_serialization {
61366288
}
61376289
}
61386290

6291+
#[test]
6292+
fn test_set_session_title_request_roundtrip() {
6293+
let original = SetSessionTitleRequest::new("sess_1", "A clearer thread title");
6294+
let json = serde_json::to_value(&original).unwrap();
6295+
assert_eq!(
6296+
json,
6297+
json!({
6298+
"sessionId": "sess_1",
6299+
"title": "A clearer thread title"
6300+
})
6301+
);
6302+
let roundtripped: SetSessionTitleRequest = serde_json::from_value(json).unwrap();
6303+
assert_eq!(original, roundtripped);
6304+
}
6305+
6306+
#[test]
6307+
fn test_set_session_title_response_roundtrip() {
6308+
let original = SetSessionTitleResponse::new();
6309+
let json = serde_json::to_value(&original).unwrap();
6310+
assert_eq!(json, json!({}));
6311+
let roundtripped: SetSessionTitleResponse = serde_json::from_value(json).unwrap();
6312+
assert_eq!(original, roundtripped);
6313+
}
6314+
6315+
#[test]
6316+
fn test_set_session_title_capabilities_serialization() {
6317+
assert_eq!(
6318+
serde_json::to_value(
6319+
SessionCapabilities::new().set_title(SessionSetTitleCapabilities::new())
6320+
)
6321+
.unwrap(),
6322+
json!({
6323+
"setTitle": {}
6324+
})
6325+
);
6326+
}
6327+
61396328
#[cfg(feature = "unstable_boolean_config")]
61406329
#[test]
61416330
fn test_session_config_option_value_id_serialize() {

0 commit comments

Comments
 (0)