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
96 changes: 61 additions & 35 deletions agent-client-protocol-schema/src/v2/agent.rs

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions agent-client-protocol-schema/src/v2/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ impl SubagentUpdate {
#[non_exhaustive]
pub struct SubagentSessionCapabilities {
/// Permits the client to cancel this child's current work without ending
/// the session. Omitted or `null` means unsupported; an object (including
/// the session. Omitted and `null` are equivalent and mean unsupported; an object (including
/// `{}`) means supported.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
Expand Down Expand Up @@ -1463,6 +1463,8 @@ pub struct UsageUpdate {
/// Total context window size in tokens.
pub size: u64,
/// Cumulative session cost (optional).
///
/// Omitted and `null` are equivalent and mean no cost is reported.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -1648,7 +1650,7 @@ pub struct IdleStateUpdate {
///
/// Token usage for completed foreground work.
///
/// Optional. Omitted or `null` both mean the agent is not reporting token
/// Optional. Omitted and `null` are equivalent and mean the agent is not reporting token
/// usage for this state update.
#[cfg(feature = "unstable_end_turn_token_usage")]
#[serde_as(deserialize_as = "DefaultOnError")]
Expand Down Expand Up @@ -1722,7 +1724,7 @@ fn idle_state_update_schema(schema: &mut Schema) {
properties.insert(
"stopReason".into(),
serde_json::json!({
"description": "Why foreground work stopped. The value selects one of this type's variants, which may add fields of their own.\n\nOptional. Omitted or `null` both mean the agent is not reporting a stop reason; a malformed value is treated the same way.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/v2/prompt-lifecycle#stop-reasons)",
"description": "Why foreground work stopped. The value selects one of this type's variants, which may add fields of their own.\n\nOptional. Omitted and `null` are equivalent and mean the agent is not reporting a stop reason; a malformed value is treated the same way.\n\nSee protocol docs: [Stop Reasons](https://agentclientprotocol.com/protocol/v2/prompt-lifecycle#stop-reasons)",
"type": ["string", "null"],
"x-deserialize-default-on-error": true
}),
Expand Down Expand Up @@ -2475,6 +2477,8 @@ pub struct Command {
/// Human-readable description of what the command does.
pub description: String,
/// Input for the command if required
///
/// Omitted and `null` are equivalent and mean the command takes no input.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -2684,15 +2688,15 @@ pub struct RequestPermissionRequest {
/// Optional human-readable explanation of why permission is needed.
///
/// This text is specific to the permission prompt and does not update any
/// subject's displayed content. Omitted or `null` both mean no separate
/// subject's displayed content. Omitted and `null` are equivalent and mean no separate
/// permission description was provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub description: Option<String>,
/// Optional structured context about the operation requiring permission.
///
/// Omitted or `null` both mean no structured subject was provided.
/// Omitted and `null` are equivalent and mean no structured subject was provided.
#[serde(default)]
pub subject: Option<RequestPermissionSubject>,
/// Available permission options for the user to choose from.
Expand Down Expand Up @@ -3337,7 +3341,7 @@ pub struct ClientCapabilities {
/// Determines which authentication method types the agent may include
/// in its `InitializeResponse`.
///
/// Optional. Omitted or `null` both mean the client does not advertise any
/// Optional. Omitted and `null` are equivalent and mean the client does not advertise any
/// authentication-method extensions.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
Expand All @@ -3346,7 +3350,7 @@ pub struct ClientCapabilities {
/// Elicitation capabilities supported by the client.
/// Determines which elicitation modes the agent may use.
///
/// Optional. Omitted or `null` both mean the client does not advertise
/// Optional. Omitted and `null` are equivalent and mean the client does not advertise
/// elicitation support.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
Expand Down Expand Up @@ -3415,7 +3419,7 @@ impl ClientCapabilities {
pub struct ClientAuthCapabilities {
/// Whether the client supports `terminal` authentication methods.
///
/// Optional. Omitted or `null` both mean the client does not advertise support.
/// Optional. Omitted and `null` are equivalent and mean the client does not advertise support.
/// The client should supply `{}` only when it can reproduce the configured
/// agent invocation in an interactive terminal. Supplying `{}` means the
/// agent may include `terminal` entries in its authentication methods.
Expand Down Expand Up @@ -3444,7 +3448,7 @@ impl ClientAuthCapabilities {

/// Whether the client supports `terminal` authentication methods.
///
/// Omitted or `null` both mean the client does not advertise support.
/// Omitted and `null` are equivalent and mean the client does not advertise support.
/// The client should supply `{}` only when it can reproduce the configured
/// agent invocation in an interactive terminal. Supplying `{}` means the
/// agent may include `AuthMethod::Terminal` entries in its authentication
Expand Down
38 changes: 38 additions & 0 deletions agent-client-protocol-schema/src/v2/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ pub struct TextContent {
/// Text payload carried by this content block.
pub text: String,
/// Optional annotations that help clients decide how to display or route this content.
///
/// Omitted and `null` are equivalent and mean no annotations are provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -272,12 +274,16 @@ pub struct ImageContent {
/// MIME type describing the encoded media payload.
pub mime_type: MediaType,
/// URI associated with this resource or media payload.
///
/// Omitted and `null` are equivalent and mean no URI is associated with the image.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[cfg_attr(feature = "schemars", schemars(url))]
#[serde(default)]
pub uri: Option<String>,
/// Optional annotations that help clients decide how to display or route this content.
///
/// Omitted and `null` are equivalent and mean no annotations are provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -347,6 +353,8 @@ pub struct AudioContent {
/// MIME type describing the encoded media payload.
pub mime_type: MediaType,
/// Optional annotations that help clients decide how to display or route this content.
///
/// Omitted and `null` are equivalent and mean no annotations are provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -404,6 +412,8 @@ pub struct EmbeddedResource {
/// Embedded resource payload, either text or binary data.
pub resource: EmbeddedResourceResource,
/// Optional annotations that help clients decide how to display or route this content.
///
/// Omitted and `null` are equivalent and mean no annotations are provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -476,6 +486,8 @@ pub struct TextResourceContents {
#[cfg_attr(feature = "schemars", schemars(url))]
pub uri: String,
/// MIME type describing the encoded media payload.
///
/// Omitted and `null` are equivalent and mean the MIME type is not specified.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -538,6 +550,8 @@ pub struct BlobResourceContents {
#[cfg_attr(feature = "schemars", schemars(url))]
pub uri: String,
/// MIME type describing the encoded media payload.
///
/// Omitted and `null` are equivalent and mean the MIME type is not specified.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -599,31 +613,43 @@ pub struct ResourceLink {
#[cfg_attr(feature = "schemars", schemars(url))]
pub uri: String,
/// Optional display title for end-user UI.
///
/// Omitted and `null` are equivalent and mean no title is provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub title: Option<String>,
/// Optional human-readable details shown with this protocol object.
///
/// Omitted and `null` are equivalent and mean no description is provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub description: Option<String>,
/// Optional set of sized icons that the client can display in a user interface.
///
/// Omitted and `null` are equivalent and mean no icons are provided.
#[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_>>>")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true)))]
#[serde(default)]
pub icons: Option<Vec<Icon>>,
/// MIME type describing the encoded media payload.
///
/// Omitted and `null` are equivalent and mean the MIME type is not specified.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub mime_type: Option<MediaType>,
/// Optional size of the linked resource in bytes, if known.
///
/// Omitted and `null` are equivalent and mean the size is not known.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub size: Option<u64>,
/// Optional annotations that help clients decide how to display or route this content.
///
/// Omitted and `null` are equivalent and mean no annotations are provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -723,6 +749,8 @@ pub struct Icon {
#[cfg_attr(feature = "schemars", schemars(url))]
pub src: String,
/// Optional MIME type override if the source MIME type is missing or generic.
///
/// Omitted and `null` are equivalent and mean the source MIME type is used.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand All @@ -732,11 +760,15 @@ pub struct Icon {
/// `"any"` for scalable formats like SVG.
///
/// If not provided, the client should assume that the icon can be used at any size.
///
/// Omitted and `null` are equivalent and mean no sizes are specified.
#[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_>>>")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true)))]
#[serde(default)]
pub sizes: Option<Vec<String>>,
/// Optional theme this icon is designed for.
///
/// Omitted and `null` are equivalent and mean the icon is not theme-specific.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -827,18 +859,24 @@ pub enum IconTheme {
#[non_exhaustive]
pub struct Annotations {
/// Intended recipients for this content, such as the user or assistant.
///
/// Omitted and `null` are equivalent and mean no audience is specified.
#[serde_as(deserialize_as = "DefaultOnError<Option<VecSkipError<_>>>")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true, "x-deserialize-skip-invalid-items" = true)))]
#[serde(default)]
pub audience: Option<Vec<Role>>,
/// Timestamp indicating when the underlying resource was last modified.
///
/// Must be an RFC 3339 formatted string (e.g., "2025-01-12T15:00:58Z").
///
/// Omitted and `null` are equivalent and mean the modification time is not reported.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true, "format" = "date-time")))]
#[serde(default)]
pub last_modified: Option<String>,
/// Relative importance of this content when clients choose what to surface.
///
/// Omitted and `null` are equivalent and mean no priority is specified.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[cfg_attr(feature = "schemars", schemars(range(min = 0, max = 1)))]
Expand Down
6 changes: 4 additions & 2 deletions agent-client-protocol-schema/src/v2/elicitation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,7 @@ pub struct ElicitationCapabilities {
pub form: Option<ElicitationFormCapabilities>,
/// Whether the client supports URL-based elicitation.
///
/// Optional. Omitted or `null` both mean the client does not advertise support.
/// Optional. Omitted and `null` are equivalent and mean the client does not advertise support.
/// Supplying `{}` means the client supports URL-based elicitation.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
Expand Down Expand Up @@ -1335,7 +1335,7 @@ impl ElicitationCapabilities {

/// Whether the client supports URL-based elicitation.
///
/// Omitted or `null` both mean the client does not advertise support.
/// Omitted and `null` are equivalent and mean the client does not advertise support.
/// Supplying `{}` means the client supports URL-based elicitation.
#[must_use]
pub fn url(mut self, url: impl IntoOption<ElicitationUrlCapabilities>) -> Self {
Expand Down Expand Up @@ -2013,6 +2013,8 @@ impl From<OtherElicitationAction> for ElicitationAction {
#[non_exhaustive]
pub struct ElicitationAcceptAction {
/// The user-provided content, if any, as an object matching the requested schema.
///
/// Omitted and `null` are equivalent and mean no content is provided.
#[serde(default)]
pub content: Option<BTreeMap<String, ElicitationContentValue>>,
}
Expand Down
2 changes: 2 additions & 0 deletions agent-client-protocol-schema/src/v2/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub struct Error {
pub message: String,
/// Optional primitive or structured value that contains additional information about the error.
/// This may include debugging information or context-specific details.
///
/// Omitted and `null` are equivalent and mean no additional data is provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down
12 changes: 6 additions & 6 deletions agent-client-protocol-schema/src/v2/tool_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,8 @@ pub struct Diff {
pub changes: Vec<DiffChange>,
/// Renderable patch text for some or all of the structured changes.
///
/// Agents SHOULD provide patch text whenever feasible. Omitted or `null`
/// means no renderable patch text was provided.
/// Agents SHOULD provide patch text whenever feasible. Omitted and `null` are
/// equivalent and mean no renderable patch text was provided.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -728,14 +728,14 @@ pub enum DiffFileType {
pub struct DiffChange {
/// File content kind after the operation (for `delete`, of the deleted file).
///
/// Omitted or `null` means the content kind is unknown.
/// Omitted and `null` are equivalent and mean the content kind is unknown.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
pub file_type: Option<DiffFileType>,
/// MIME type of the file contents after the operation (for `delete`, of the deleted file).
///
/// Omitted or `null` means the MIME type is unknown.
/// Omitted and `null` are equivalent and mean the MIME type is unknown.
#[serde_as(deserialize_as = "DefaultOnError")]
#[cfg_attr(feature = "schemars", schemars(extend("x-deserialize-default-on-error" = true)))]
#[serde(default)]
Expand Down Expand Up @@ -803,7 +803,7 @@ impl DiffChange {

/// File content kind.
///
/// Omitted or `null` means the content kind is unknown.
/// Omitted and `null` are equivalent and mean the content kind is unknown.
#[must_use]
pub fn file_type(mut self, file_type: impl IntoOption<DiffFileType>) -> Self {
self.file_type = file_type.into_option();
Expand All @@ -812,7 +812,7 @@ impl DiffChange {

/// MIME type of the file contents.
///
/// Omitted or `null` means the MIME type is unknown.
/// Omitted and `null` are equivalent and mean the MIME type is unknown.
#[must_use]
pub fn mime_type(mut self, mime_type: impl IntoOption<MediaType>) -> Self {
self.mime_type = mime_type.into_option();
Expand Down
2 changes: 2 additions & 0 deletions docs/protocol/v2/draft/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,8 @@ See [Errors](/protocol/v2/draft/error) for the error codes ACP uses and when to

Unless explicitly defined otherwise in the schema, ACP-defined JSON object property keys use `camelCase`. String values carried by discriminator fields use `snake_case`. The JSON-RPC envelope fields (`jsonrpc`, `id`, `method`, `params`, `result`, and `error`) follow the JSON-RPC 2.0 specification.

An optional field that is omitted and the same field set to `null` are equivalent, unless the field says otherwise. Upsert updates are the exception: there an omitted field leaves the stored value unchanged and `null` clears it.

Selected enum-like fields and tagged unions can define custom or future fallbacks. For those fields, `_`-prefixed values are reserved for implementation-specific extensions, while unknown non-underscore values are reserved for future ACP variants.

## Extensibility
Expand Down
Loading
Loading