Skip to content
Open
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
2 changes: 2 additions & 0 deletions agent-client-protocol-schema/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ unstable = [
"unstable_nes",
"unstable_plan_operations",
"unstable_session_fork",
"unstable_subagents",
"unstable_end_turn_token_usage",
"unstable_tool_call_name",
]
Expand All @@ -47,6 +48,7 @@ unstable_mcp_over_acp = []
unstable_nes = []
unstable_plan_operations = []
unstable_session_fork = []
unstable_subagents = []
unstable_end_turn_token_usage = []
unstable_tool_call_name = []

Expand Down
46 changes: 46 additions & 0 deletions agent-client-protocol-schema/src/v1/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use super::{
ClientCapabilities, ContentBlock, ExtNotification, ExtRequest, ExtResponse, Meta, SessionId,
};

#[cfg(feature = "unstable_subagents")]
use super::SubagentCapabilities;

#[cfg(feature = "unstable_mcp_over_acp")]
use super::mcp::{
MCP_MESSAGE_METHOD_NAME, MessageMcpNotification, MessageMcpRequest, MessageMcpResponse,
Expand Down Expand Up @@ -4087,6 +4090,20 @@ pub struct SessionCapabilities {
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub close: Option<SessionCloseCapabilities>,
/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Whether the agent may expose agent-created subagents.
///
/// Optional and non-nullable. Omission means the agent does not advertise support.
/// Supplying `{}` means the agent may send subagent session updates when the client also
/// advertises support.
#[cfg(feature = "unstable_subagents")]
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(with = "SubagentCapabilities", extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub subagents: Option<SubagentCapabilities>,
/// 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 @@ -4175,6 +4192,18 @@ impl SessionCapabilities {
self
}

/// **UNSTABLE**
///
/// This capability is not part of the spec yet, and may be removed or changed at any point.
///
/// Whether the agent may expose agent-created subagents.
#[cfg(feature = "unstable_subagents")]
#[must_use]
pub fn subagents(mut self, subagents: impl IntoOption<SubagentCapabilities>) -> Self {
self.subagents = subagents.into_option();
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 @@ -5228,6 +5257,23 @@ mod test_serialization {
use super::*;
use serde_json::json;

#[cfg(feature = "unstable_subagents")]
#[test]
fn test_subagent_capability_serialization() {
let capabilities = SessionCapabilities::new().subagents(SubagentCapabilities::new());
assert_eq!(
serde_json::to_value(capabilities).unwrap(),
json!({ "subagents": {} })
);

let omitted: SessionCapabilities = serde_json::from_value(json!({})).unwrap();
assert!(omitted.subagents.is_none());

let null: SessionCapabilities =
serde_json::from_value(json!({ "subagents": null })).unwrap();
assert!(null.subagents.is_none());
}

fn test_meta() -> Meta {
json!({ "source": "test" }).as_object().unwrap().clone()
}
Expand Down
Loading