From c5bca61a73d759075c8764b70891a838ce178426 Mon Sep 17 00:00:00 2001 From: Ben Brandt Date: Mon, 6 Jul 2026 17:41:15 +0200 Subject: [PATCH] fix(schema): remove enum discriminators from invalid schemas Tooling seems to choke on anyOfs with discriminators, so removing those. --- .../src/v1/elicitation.rs | 4 - agent-client-protocol-schema/src/v2/agent.rs | 4 - agent-client-protocol-schema/src/v2/client.rs | 5 -- .../src/v2/content.rs | 1 - .../src/v2/elicitation.rs | 4 - agent-client-protocol-schema/src/v2/nes.rs | 1 - agent-client-protocol-schema/src/v2/plan.rs | 1 - .../src/v2/tool_call.rs | 2 - schema/v1/schema.unstable.json | 16 +--- schema/v2/schema.json | 63 +++----------- schema/v2/schema.unstable.json | 84 ++++--------------- 11 files changed, 29 insertions(+), 156 deletions(-) diff --git a/agent-client-protocol-schema/src/v1/elicitation.rs b/agent-client-protocol-schema/src/v1/elicitation.rs index c169940d7..608fe1322 100644 --- a/agent-client-protocol-schema/src/v1/elicitation.rs +++ b/agent-client-protocol-schema/src/v1/elicitation.rs @@ -730,7 +730,6 @@ fn other_multi_select_items_schema(schema: &mut Schema) { /// Items for a multi-select (array) property schema. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum MultiSelectItems { /// Multi-select string items with plain string values. @@ -868,7 +867,6 @@ impl MultiSelectPropertySchema { /// Multi-select enums use the `Array` variant. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum ElicitationPropertySchema { /// String property (or single-select enum when `enum`/`oneOf` is set). @@ -1517,7 +1515,6 @@ impl CreateElicitationRequest { /// The mode of elicitation, determining how user input is collected. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "mode", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "mode"}))] #[non_exhaustive] pub enum ElicitationMode { /// Form-based elicitation where the client renders a form from the provided schema. @@ -1798,7 +1795,6 @@ impl CreateElicitationResponse { /// The user's action in response to an elicitation. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "action", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "action"}))] #[non_exhaustive] pub enum ElicitationAction { /// The user accepted and provided content. diff --git a/agent-client-protocol-schema/src/v2/agent.rs b/agent-client-protocol-schema/src/v2/agent.rs index f80542219..3493b9a9f 100644 --- a/agent-client-protocol-schema/src/v2/agent.rs +++ b/agent-client-protocol-schema/src/v2/agent.rs @@ -1481,7 +1481,6 @@ impl ResumeSessionRequest { /// Replay includes the position identified by the cursor. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum ReplayFrom { /// Replay the whole conversation from its first replayable entry. @@ -2337,7 +2336,6 @@ pub enum SessionConfigOptionCategory { /// Type-specific session configuration option payload. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum SessionConfigKind { /// Single-value selector (dropdown). @@ -2539,7 +2537,6 @@ impl SessionConfigOption { /// text option would get its own variant. #[derive(Debug, Clone, Serialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum SessionConfigOptionValue { /// A [`SessionConfigValueId`] string value (`type: "id"`). @@ -2849,7 +2846,6 @@ impl SetSessionConfigOptionResponse { /// See protocol docs: [MCP Servers](https://agentclientprotocol.com/protocol/session-setup#mcp-servers) #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum McpServer { /// HTTP transport configuration diff --git a/agent-client-protocol-schema/src/v2/client.rs b/agent-client-protocol-schema/src/v2/client.rs index 5e0e16301..4743b79bd 100644 --- a/agent-client-protocol-schema/src/v2/client.rs +++ b/agent-client-protocol-schema/src/v2/client.rs @@ -95,7 +95,6 @@ impl UpdateSessionNotification { /// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-lifecycle#3-agent-reports-output) #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "sessionUpdate", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "sessionUpdate"}))] #[non_exhaustive] pub enum SessionUpdate { /// A chunk of the user's message being streamed. @@ -459,7 +458,6 @@ impl UsageUpdate { /// that the session is idle, or that progress is blocked on user action. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "state", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "state"}))] #[non_exhaustive] pub enum StateUpdate { /// The agent is actively processing work in the session. @@ -1131,7 +1129,6 @@ impl AvailableCommand { /// The input specification for a command. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum AvailableCommandInput { /// All text that was typed after the command name is provided as input. @@ -1360,7 +1357,6 @@ impl RequestPermissionRequest { /// The operation requiring permission. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum RequestPermissionSubject { /// Permission is requested before executing a tool call. @@ -1609,7 +1605,6 @@ impl RequestPermissionResponse { /// The outcome of a permission request. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "outcome", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "outcome"}))] #[non_exhaustive] pub enum RequestPermissionOutcome { /// Active session work was cancelled before the user responded. diff --git a/agent-client-protocol-schema/src/v2/content.rs b/agent-client-protocol-schema/src/v2/content.rs index 01b791fc9..9623c0576 100644 --- a/agent-client-protocol-schema/src/v2/content.rs +++ b/agent-client-protocol-schema/src/v2/content.rs @@ -35,7 +35,6 @@ use crate::{IntoOption, SkipListener}; /// See protocol docs: [Content](https://agentclientprotocol.com/protocol/content) #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum ContentBlock { /// Text content. May be plain text or formatted with Markdown. diff --git a/agent-client-protocol-schema/src/v2/elicitation.rs b/agent-client-protocol-schema/src/v2/elicitation.rs index 1feb8541f..cb396d643 100644 --- a/agent-client-protocol-schema/src/v2/elicitation.rs +++ b/agent-client-protocol-schema/src/v2/elicitation.rs @@ -730,7 +730,6 @@ fn other_multi_select_items_schema(schema: &mut Schema) { /// Items for a multi-select (array) property schema. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum MultiSelectItems { /// Multi-select string items with plain string values. @@ -871,7 +870,6 @@ impl MultiSelectPropertySchema { /// Multi-select enums use the `Array` variant. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum ElicitationPropertySchema { /// String property (or single-select enum when `enum`/`oneOf` is set). @@ -1503,7 +1501,6 @@ impl CreateElicitationRequest { /// The mode of elicitation, determining how user input is collected. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "mode", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "mode"}))] #[non_exhaustive] pub enum ElicitationMode { /// Form-based elicitation where the client renders a form from the provided schema. @@ -1763,7 +1760,6 @@ impl CreateElicitationResponse { /// The user's action in response to an elicitation. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)] #[serde(tag = "action", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "action"}))] #[non_exhaustive] pub enum ElicitationAction { /// The user accepted and provided content. diff --git a/agent-client-protocol-schema/src/v2/nes.rs b/agent-client-protocol-schema/src/v2/nes.rs index 57bc59e2d..f7849d877 100644 --- a/agent-client-protocol-schema/src/v2/nes.rs +++ b/agent-client-protocol-schema/src/v2/nes.rs @@ -2352,7 +2352,6 @@ impl SuggestNesResponse { /// A suggestion returned by the agent. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "kind", rename_all = "camelCase")] -#[schemars(extend("discriminator" = {"propertyName": "kind"}))] #[non_exhaustive] pub enum NesSuggestion { /// A text edit suggestion. diff --git a/agent-client-protocol-schema/src/v2/plan.rs b/agent-client-protocol-schema/src/v2/plan.rs index bbbe8a275..2d80a91f2 100644 --- a/agent-client-protocol-schema/src/v2/plan.rs +++ b/agent-client-protocol-schema/src/v2/plan.rs @@ -74,7 +74,6 @@ impl PlanUpdate { /// Updated content for a plan. #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum PlanUpdateContent { /// Structured plan entries. diff --git a/agent-client-protocol-schema/src/v2/tool_call.rs b/agent-client-protocol-schema/src/v2/tool_call.rs index 9a382e990..898031b7c 100644 --- a/agent-client-protocol-schema/src/v2/tool_call.rs +++ b/agent-client-protocol-schema/src/v2/tool_call.rs @@ -347,7 +347,6 @@ pub enum ToolCallStatus { /// See protocol docs: [Content](https://agentclientprotocol.com/protocol/tool-calls#content) #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "type"}))] #[non_exhaustive] pub enum ToolCallContent { /// Standard content block (text, images, resources). @@ -738,7 +737,6 @@ impl DiffChange { /// File operation for a [`DiffChange`]. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[serde(tag = "operation", rename_all = "snake_case")] -#[schemars(extend("discriminator" = {"propertyName": "operation"}))] #[non_exhaustive] pub enum DiffChangeOperation { /// A file was added. diff --git a/schema/v1/schema.unstable.json b/schema/v1/schema.unstable.json index d0d3b6964..f342755ea 100644 --- a/schema/v1/schema.unstable.json +++ b/schema/v1/schema.unstable.json @@ -1483,9 +1483,6 @@ } } ], - "discriminator": { - "propertyName": "mode" - }, "required": ["message"], "x-side": "client", "x-method": "elicitation/create" @@ -1739,10 +1736,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "StringFormat": { "description": "String format types for string properties in elicitation schemas.", @@ -2021,10 +2015,7 @@ } ] } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "StringMultiSelectItems": { "description": "String item schema for multi-select enum properties.", @@ -8255,9 +8246,6 @@ "additionalProperties": true } ], - "discriminator": { - "propertyName": "action" - }, "x-side": "client", "x-method": "elicitation/create" }, diff --git a/schema/v2/schema.json b/schema/v2/schema.json index 3c119be67..c37105a65 100644 --- a/schema/v2/schema.json +++ b/schema/v2/schema.json @@ -625,10 +625,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ToolCallUpdate": { "description": "Represents an upsert for a tool call that the language model has requested.\n\nTool calls are actions that the agent executes on behalf of the language model,\nsuch as reading files, executing code, or fetching data from external sources.\n\nOnly [`ToolCallUpdate::tool_call_id`] is required. Other fields have patch semantics:\nomitted fields leave the existing tool call value unchanged, `null` clears or\nunsets the value, and concrete values replace the previous value. For\ncollection fields, concrete arrays replace the previous collection, and both\n`null` and `[]` clear the collection. When a client receives a tool call ID it\nhas not seen before, omitted fields use client defaults.\n\nSee protocol docs: [Tool Calls](https://agentclientprotocol.com/protocol/v2/tool-calls)", @@ -872,10 +869,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ContentBlock": { "description": "Content blocks represent displayable information in the Agent Client Protocol.\n\nThey provide a structured way to handle various types of user-facing content—whether\nit's text from language models, images for analysis, or embedded resources for context.\n\nContent blocks appear in:\n- User prompts sent via `session/prompt`\n- Language model output reported through `session/update` notifications as\n message updates or streamed chunks\n- Progress updates and results from tool calls\n\nThis structure is compatible with the Model Context Protocol (MCP), enabling\nagents to seamlessly forward content from MCP tool outputs without transformation.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/v2/content)", @@ -1027,10 +1021,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "Annotations": { "description": "Optional annotations for the client. The client can use annotations to inform how objects are used or displayed", @@ -1620,10 +1611,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "operation" - } + ] }, "DiffFileType": { "description": "Kind of file content represented by a diff change.", @@ -2642,10 +2630,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "SessionConfigId": { "description": "Unique identifier for a session configuration option.", @@ -3522,10 +3507,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "sessionUpdate" - } + ] }, "MessageId": { "description": "Unique identifier for a message within a session.", @@ -3831,10 +3813,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "state" - } + ] }, "ToolCallContentChunk": { "description": "A streamed item of tool-call content.\n\nTool-call content chunks append one [`ToolCallContent`] item to the current\ncontent for the matching [`ToolCallId`]. Agents can use\n[`ToolCallUpdate::content`] when they need to replace the whole content\ncollection instead.", @@ -3939,10 +3918,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "PlanId": { "description": "Unique identifier for a plan within a session.", @@ -4161,10 +4137,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "TextCommandInput": { "description": "All text that was typed after the command name is provided as input.", @@ -4644,10 +4617,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "HttpHeader": { "description": "An HTTP header to set when making requests to the MCP server.", @@ -4909,10 +4879,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ReplayFromStart": { "description": "Inclusive replay cursor requesting replay from the start of the conversation.", @@ -5053,9 +5020,6 @@ "additionalProperties": true } ], - "discriminator": { - "propertyName": "type" - }, "x-side": "agent", "x-method": "session/set_config_option" }, @@ -5248,10 +5212,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "outcome" - } + ] }, "SelectedPermissionOutcome": { "description": "The user selected one of the provided options.", diff --git a/schema/v2/schema.unstable.json b/schema/v2/schema.unstable.json index dca3447b7..62795b002 100644 --- a/schema/v2/schema.unstable.json +++ b/schema/v2/schema.unstable.json @@ -769,10 +769,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ToolCallUpdate": { "description": "Represents an upsert for a tool call that the language model has requested.\n\nTool calls are actions that the agent executes on behalf of the language model,\nsuch as reading files, executing code, or fetching data from external sources.\n\nOnly [`ToolCallUpdate::tool_call_id`] is required. Other fields have patch semantics:\nomitted fields leave the existing tool call value unchanged, `null` clears or\nunsets the value, and concrete values replace the previous value. For\ncollection fields, concrete arrays replace the previous collection, and both\n`null` and `[]` clear the collection. When a client receives a tool call ID it\nhas not seen before, omitted fields use client defaults.\n\nSee protocol docs: [Tool Calls](https://agentclientprotocol.com/protocol/v2/draft/tool-calls)", @@ -1016,10 +1013,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ContentBlock": { "description": "Content blocks represent displayable information in the Agent Client Protocol.\n\nThey provide a structured way to handle various types of user-facing content—whether\nit's text from language models, images for analysis, or embedded resources for context.\n\nContent blocks appear in:\n- User prompts sent via `session/prompt`\n- Language model output reported through `session/update` notifications as\n message updates or streamed chunks\n- Progress updates and results from tool calls\n\nThis structure is compatible with the Model Context Protocol (MCP), enabling\nagents to seamlessly forward content from MCP tool outputs without transformation.\n\nSee protocol docs: [Content](https://agentclientprotocol.com/protocol/v2/draft/content)", @@ -1171,10 +1165,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "Annotations": { "description": "Optional annotations for the client. The client can use annotations to inform how objects are used or displayed", @@ -1764,10 +1755,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "operation" - } + ] }, "DiffFileType": { "description": "Kind of file content represented by a diff change.", @@ -2104,9 +2092,6 @@ } } ], - "discriminator": { - "propertyName": "mode" - }, "required": ["message"], "x-side": "client", "x-method": "elicitation/create" @@ -2360,10 +2345,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "StringFormat": { "description": "String format types for string properties in elicitation schemas.", @@ -2650,10 +2632,7 @@ } ] } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "StringMultiSelectItems": { "description": "String item schema for multi-select enum properties.", @@ -4643,10 +4622,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "SessionConfigId": { "description": "Unique identifier for a session configuration option.", @@ -5181,10 +5157,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "kind" - } + ] }, "NesSuggestionId": { "description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUnique identifier for an NES suggestion.", @@ -6039,10 +6012,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "sessionUpdate" - } + ] }, "MessageId": { "description": "Unique identifier for a message within a session.", @@ -6412,10 +6382,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "state" - } + ] }, "ToolCallContentChunk": { "description": "A streamed item of tool-call content.\n\nTool-call content chunks append one [`ToolCallContent`] item to the current\ncontent for the matching [`ToolCallId`]. Agents can use\n[`ToolCallUpdate::content`] when they need to replace the whole content\ncollection instead.", @@ -6552,10 +6519,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "PlanId": { "description": "Unique identifier for a plan within a session.", @@ -6846,10 +6810,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "TextCommandInput": { "description": "All text that was typed after the command name is provided as input.", @@ -7788,10 +7749,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "HttpHeader": { "description": "An HTTP header to set when making requests to the MCP server.", @@ -8102,10 +8060,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "type" - } + ] }, "ReplayFromStart": { "description": "Inclusive replay cursor requesting replay from the start of the conversation.", @@ -8246,9 +8201,6 @@ "additionalProperties": true } ], - "discriminator": { - "propertyName": "type" - }, "x-side": "agent", "x-method": "session/set_config_option" }, @@ -8983,10 +8935,7 @@ }, "additionalProperties": true } - ], - "discriminator": { - "propertyName": "outcome" - } + ] }, "SelectedPermissionOutcome": { "description": "The user selected one of the provided options.", @@ -9107,9 +9056,6 @@ "additionalProperties": true } ], - "discriminator": { - "propertyName": "action" - }, "x-side": "client", "x-method": "elicitation/create" },