Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 95 additions & 3 deletions agent-client-protocol-schema/src/v1/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,9 @@ pub struct NewSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[serde_as(deserialize_as = "DefaultOnNull")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-null" = true)))]
Expand Down Expand Up @@ -1342,7 +1344,9 @@ impl NewSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[must_use]
pub fn config_options(mut self, config_options: Vec<InitialSessionConfigOption>) -> Self {
Expand Down Expand Up @@ -1710,6 +1714,29 @@ pub struct ForkSessionRequest {
/// for the source session.
#[serde(default)]
pub system_prompt: Option<SystemPrompt>,
/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Initial values for the forked session's config options.
///
/// Optional. Omitted and `null` are equivalent to an empty list. Clients MUST only send
/// this when the Agent advertises `sessionCapabilities.options`.
///
/// The Agent applies the entries in list order on top of the configuration the fork
/// starts with, as if the Client had called `session/set_config_option` for each entry
/// after the session was set up. Malformed entries and duplicate `configId` values fail
/// the request with `-32602`. The Agent MUST ignore an entry whose `configId` is unknown,
/// whose `type` does not match the option, or whose value is not allowed when it is
/// applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[serde_as(deserialize_as = "DefaultOnNull")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-null" = true)))]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub config_options: Vec<InitialSessionConfigOption>,
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
/// these keys.
Expand All @@ -1733,6 +1760,8 @@ impl ForkSessionRequest {
additional_directories: vec![],
mcp_servers: vec![],
system_prompt: None,
#[cfg(feature = "unstable_session_options")]
config_options: vec![],
meta: None,
}
}
Expand All @@ -1758,6 +1787,31 @@ impl ForkSessionRequest {
self
}

/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Initial values for the forked session's config options.
///
/// Optional. Omitted and `null` are equivalent to an empty list. Clients MUST only send
/// this when the Agent advertises `sessionCapabilities.options`.
///
/// The Agent applies the entries in list order on top of the configuration the fork
/// starts with, as if the Client had called `session/set_config_option` for each entry
/// after the session was set up. Malformed entries and duplicate `configId` values fail
/// the request with `-32602`. The Agent MUST ignore an entry whose `configId` is unknown,
/// whose `type` does not match the option, or whose value is not allowed when it is
/// applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[must_use]
pub fn config_options(mut self, config_options: Vec<InitialSessionConfigOption>) -> Self {
self.config_options = config_options;
self
}

/// The _meta property is reserved by ACP to allow clients and agents to attach additional
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
/// these keys.
Expand Down Expand Up @@ -2324,7 +2378,8 @@ pub enum SessionStatus {
///
/// `session/options` MUST NOT create or resume a session, send `session/update`
/// notifications, add an entry to `session/list`, or change an existing session. Agents
/// SHOULD NOT connect to MCP servers to answer it.
/// SHOULD NOT connect to MCP servers to answer it. Agents MAY start their runtime to resolve
/// the options. The rules above still hold for it.
#[cfg(feature = "unstable_session_options")]
#[serde_as]
#[skip_serializing_none]
Expand Down Expand Up @@ -7811,6 +7866,43 @@ mod test_serialization {
serde_json::to_value(SessionOptionsResponse::new()).unwrap(),
json!({})
);
#[cfg(feature = "unstable_session_fork")]
{
let fork =
ForkSessionRequest::new("sess_abc123", "/home/user/project").config_options(vec![
InitialSessionConfigOption::new(
"model",
SessionConfigOptionValue::value_id("model-2"),
),
]);
let value = serde_json::to_value(&fork).unwrap();
assert_eq!(
value["configOptions"],
json!([{"configId": "model", "value": "model-2"}])
);
assert_eq!(
serde_json::from_value::<ForkSessionRequest>(value).unwrap(),
fork
);
// `null` is an empty list, and a malformed entry fails the request.
assert_eq!(
serde_json::from_value::<ForkSessionRequest>(json!({
"sessionId": "sess_abc123",
"cwd": "/home/user/project",
"configOptions": null
}))
.unwrap(),
ForkSessionRequest::new("sess_abc123", "/home/user/project")
);
assert!(
serde_json::from_value::<ForkSessionRequest>(json!({
"sessionId": "sess_abc123",
"cwd": "/home/user/project",
"configOptions": [{"type": "boolean", "value": true}]
}))
.is_err()
);
}
assert_eq!(
serde_json::to_value(
SessionCapabilities::new().options(SessionOptionsCapabilities::new())
Expand Down
106 changes: 101 additions & 5 deletions agent-client-protocol-schema/src/v2/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,9 @@ pub struct NewSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[serde_as(deserialize_as = "DefaultOnNull")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-null" = true)))]
Expand Down Expand Up @@ -1390,7 +1392,9 @@ impl NewSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[must_use]
pub fn config_options(mut self, config_options: Vec<InitialSessionConfigOption>) -> Self {
Expand Down Expand Up @@ -1549,6 +1553,29 @@ pub struct ForkSessionRequest {
/// source session.
#[serde(default)]
pub system_prompt: Option<SystemPrompt>,
/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Initial values for the forked session's config options.
///
/// Optional. Omitted and `null` are equivalent to an empty list. Clients MUST only send
/// this when the Agent advertises `session.options`.
///
/// The Agent applies the entries in list order on top of the configuration the fork
/// starts with, as if the Client had called `session/set_config_option` for each entry
/// after the session was set up. Malformed entries and duplicate `configId` values fail
/// the request with `-32602`. The Agent MUST ignore an entry whose `configId` is unknown,
/// whose `type` does not match the option, or whose value is not allowed when it is
/// applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[serde_as(deserialize_as = "DefaultOnNull")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-null" = true)))]
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub config_options: Vec<InitialSessionConfigOption>,
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
/// metadata to their interactions. Omitted and `null` are equivalent and mean no metadata.
/// Implementations MUST NOT assign meaning to keys they do not recognize.
Expand All @@ -1572,6 +1599,8 @@ impl ForkSessionRequest {
additional_directories: vec![],
mcp_servers: vec![],
system_prompt: None,
#[cfg(feature = "unstable_session_options")]
config_options: vec![],
meta: None,
}
}
Expand Down Expand Up @@ -1601,6 +1630,31 @@ impl ForkSessionRequest {
self
}

/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Initial values for the forked session's config options.
///
/// Optional. Omitted and `null` are equivalent to an empty list. Clients MUST only send
/// this when the Agent advertises `session.options`.
///
/// The Agent applies the entries in list order on top of the configuration the fork
/// starts with, as if the Client had called `session/set_config_option` for each entry
/// after the session was set up. Malformed entries and duplicate `configId` values fail
/// the request with `-32602`. The Agent MUST ignore an entry whose `configId` is unknown,
/// whose `type` does not match the option, or whose value is not allowed when it is
/// applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
/// and SHOULD NOT send other `session/update` notifications caused by applying them
/// before it responds.
#[cfg(feature = "unstable_session_options")]
#[must_use]
pub fn config_options(mut self, config_options: Vec<InitialSessionConfigOption>) -> Self {
self.config_options = config_options;
self
}

/// The _meta property is reserved by ACP to allow clients and agents to attach additional
/// metadata to their interactions. Implementations MUST NOT assign meaning to keys they
/// do not recognize.
Expand Down Expand Up @@ -1777,7 +1831,9 @@ pub struct ResumeSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries
/// on the requesting connection. If the session is active on other connections, the
/// Agent SHOULD send `config_option_update` on those connections.
///
/// The Agent applies the entries before it replays history for `replayFrom` and before
/// it responds.
Expand Down Expand Up @@ -1867,7 +1923,9 @@ impl ResumeSessionRequest {
/// entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
/// ignore an entry whose `configId` is unknown, whose `type` does not match the option,
/// or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
/// has. The Agent SHOULD NOT send `config_option_update` notifications for these entries
/// on the requesting connection. If the session is active on other connections, the
/// Agent SHOULD send `config_option_update` on those connections.
#[cfg(feature = "unstable_session_options")]
#[must_use]
pub fn config_options(mut self, config_options: Vec<InitialSessionConfigOption>) -> Self {
Expand Down Expand Up @@ -2393,7 +2451,8 @@ pub enum SessionStatus {
///
/// `session/options` MUST NOT create or resume a session, send `session/update`
/// notifications, add an entry to `session/list`, or change an existing session. Agents
/// SHOULD NOT connect to MCP servers to answer it.
/// SHOULD NOT connect to MCP servers to answer it. Agents MAY start their runtime to resolve
/// the options. The rules above still hold for it.
#[cfg(feature = "unstable_session_options")]
#[serde_as]
#[skip_serializing_none]
Expand Down Expand Up @@ -8918,6 +8977,43 @@ mod test_serialization {
serde_json::to_value(SessionOptionsResponse::new()).unwrap(),
json!({})
);
#[cfg(feature = "unstable_session_fork")]
{
let fork =
ForkSessionRequest::new("sess_abc123", "/home/user/project").config_options(vec![
InitialSessionConfigOption::new(
"model",
SessionConfigOptionValue::id("model-2"),
),
]);
let value = serde_json::to_value(&fork).unwrap();
assert_eq!(
value["configOptions"],
json!([{"configId": "model", "type": "id", "value": "model-2"}])
);
assert_eq!(
serde_json::from_value::<ForkSessionRequest>(value).unwrap(),
fork
);
// `null` is an empty list, and a malformed entry fails the request.
assert_eq!(
serde_json::from_value::<ForkSessionRequest>(json!({
"sessionId": "sess_abc123",
"cwd": "/home/user/project",
"configOptions": null
}))
.unwrap(),
ForkSessionRequest::new("sess_abc123", "/home/user/project")
);
assert!(
serde_json::from_value::<ForkSessionRequest>(json!({
"sessionId": "sess_abc123",
"cwd": "/home/user/project",
"configOptions": [{"type": "boolean", "value": true}]
}))
.is_err()
);
}
assert_eq!(
serde_json::to_value(
SessionCapabilities::new().options(SessionOptionsCapabilities::new())
Expand Down
28 changes: 26 additions & 2 deletions docs/protocol/v1/draft/schema.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,27 @@ When omitted or empty, no additional roots are activated. When non-empty,
this is the complete resulting additional-root list for the forked
session.

</ResponseField>
<ResponseField name="configOptions" type={<a href="#initialsessionconfigoption">InitialSessionConfigOption[]</a>} >
**UNSTABLE**

This capability is not part of the spec yet, and may be removed or changed at any point.

Initial values for the forked session's config options.

Optional. Omitted and `null` are equivalent to an empty list. Clients MUST only send
this when the Agent advertises `sessionCapabilities.options`.

The Agent applies the entries in list order on top of the configuration the fork
starts with, as if the Client had called `session/set_config_option` for each entry
after the session was set up. Malformed entries and duplicate `configId` values fail
the request with `-32602`. The Agent MUST ignore an entry whose `configId` is unknown,
whose `type` does not match the option, or whose value is not allowed when it is
applied. The `configOptions` in the response contain the values the session actually
has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
and SHOULD NOT send other `session/update` notifications caused by applying them
before it responds.

</ResponseField>
<ResponseField name="cwd" type={"string"} required>
The working directory for this session. Must be an absolute path.
Expand Down Expand Up @@ -1044,7 +1065,9 @@ The Agent applies the entries in list order, as if the Client had called
entries and duplicate `configId` values fail the request with `-32602`. The Agent MUST
ignore an entry whose `configId` is unknown, whose `type` does not match the option,
or whose value is not allowed when it is applied. The `configOptions` in the response contain the values the session actually
has. The Agent SHOULD NOT send `config_option_update` notifications for these entries.
has. The Agent SHOULD NOT send `config_option_update` notifications for these entries,
and SHOULD NOT send other `session/update` notifications caused by applying them
before it responds.

</ResponseField>
<ResponseField name="cwd" type={"string"} required>
Expand Down Expand Up @@ -1120,7 +1143,8 @@ Only available if the Agent supports the `sessionCapabilities.options` capabilit

`session/options` MUST NOT create or resume a session, send `session/update`
notifications, add an entry to `session/list`, or change an existing session. Agents
SHOULD NOT connect to MCP servers to answer it.
SHOULD NOT connect to MCP servers to answer it. Agents MAY start their runtime to resolve
the options. The rules above still hold for it.

**Type:** Object

Expand Down
Loading
Loading