diff --git a/docs/protocol/schema.mdx b/docs/protocol/schema.mdx index f289286c..d5d46aa9 100644 --- a/docs/protocol/schema.mdx +++ b/docs/protocol/schema.mdx @@ -250,6 +250,12 @@ See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol **Properties:** +AvailableCommand[]} > + **UNSTABLE** + +Commands that may be executed via `session/prompt` requests + + SessionId} required> Unique identifier for the created session. @@ -605,6 +611,50 @@ Unique identifier for an authentication method. **Type:** `string` +## AvailableCommand + +Information about a command. + +**Type:** Object + +**Properties:** + + + Human-readable description of what the command does. + + + + AvailableCommandInput + + | null + + } +> + Input for the command if required + + + Command name (e.g., "create_plan", "research_codebase"). + + +## AvailableCommandInput + +**Type:** Union + + +All text that was typed after the command name is provided as input. + + + + + A brief description of the expected input + + + + + ## BlobResourceContents Binary resource contents. diff --git a/rust/agent.rs b/rust/agent.rs index ffeda9a3..b172eb35 100644 --- a/rust/agent.rs +++ b/rust/agent.rs @@ -204,6 +204,37 @@ pub struct NewSessionResponse { /// /// Used in all subsequent requests for this conversation. pub session_id: SessionId, + /// **UNSTABLE** + /// + /// Commands that may be executed via `session/prompt` requests + #[cfg(feature = "unstable")] + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub available_commands: Vec, +} + +/// Information about a command. +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[serde(rename_all = "camelCase")] +#[cfg(feature = "unstable")] +pub struct AvailableCommand { + /// Command name (e.g., "create_plan", "research_codebase"). + pub name: String, + /// Human-readable description of what the command does. + pub description: String, + /// Input for the command if required + pub input: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] +#[serde(untagged, rename_all = "camelCase")] +#[cfg(feature = "unstable")] +pub enum AvailableCommandInput { + /// All text that was typed after the command name is provided as input. + #[schemars(rename = "UnstructuredCommandInput")] + Unstructured { + /// A brief description of the expected input + hint: String, + }, } // Load session diff --git a/schema/schema.json b/schema/schema.json index 19bc41b4..f77bef1e 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -172,6 +172,48 @@ "x-method": "authenticate", "x-side": "agent" }, + "AvailableCommand": { + "description": "Information about a command.", + "properties": { + "description": { + "description": "Human-readable description of what the command does.", + "type": "string" + }, + "input": { + "anyOf": [ + { + "$ref": "#/$defs/AvailableCommandInput" + }, + { + "type": "null" + } + ], + "description": "Input for the command if required" + }, + "name": { + "description": "Command name (e.g., \"create_plan\", \"research_codebase\").", + "type": "string" + } + }, + "required": ["name", "description"], + "type": "object" + }, + "AvailableCommandInput": { + "anyOf": [ + { + "description": "All text that was typed after the command name is provided as input.", + "properties": { + "hint": { + "description": "A brief description of the expected input", + "type": "string" + } + }, + "required": ["hint"], + "title": "UnstructuredCommandInput", + "type": "object" + } + ] + }, "BlobResourceContents": { "description": "Binary resource contents.", "properties": { @@ -723,6 +765,13 @@ "NewSessionResponse": { "description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)", "properties": { + "availableCommands": { + "description": "**UNSTABLE**\n\nCommands that may be executed via `session/prompt` requests", + "items": { + "$ref": "#/$defs/AvailableCommand" + }, + "type": "array" + }, "sessionId": { "$ref": "#/$defs/SessionId", "description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation." diff --git a/typescript/schema.ts b/typescript/schema.ts index 80c17835..1c6023f1 100644 --- a/typescript/schema.ts +++ b/typescript/schema.ts @@ -295,6 +295,7 @@ export type AgentResponse = | LoadSessionResponse | PromptResponse; export type AuthenticateResponse = null; +export type AvailableCommandInput = UnstructuredCommandInput; export type LoadSessionResponse = null; /** * All possible notifications that an agent can send to a client. @@ -815,6 +816,12 @@ export interface AuthMethod { * See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session) */ export interface NewSessionResponse { + /** + * **UNSTABLE** + * + * Commands that may be executed via `session/prompt` requests + */ + availableCommands?: AvailableCommand[]; /** * A unique identifier for a conversation session between a client and agent. * @@ -834,6 +841,32 @@ export interface NewSessionResponse { */ sessionId: string; } +/** + * Information about a command. + */ +export interface AvailableCommand { + /** + * Human-readable description of what the command does. + */ + description: string; + /** + * Input for the command if required + */ + input?: AvailableCommandInput | null; + /** + * Command name (e.g., "create_plan", "research_codebase"). + */ + name: string; +} +/** + * All text that was typed after the command name is provided as input. + */ +export interface UnstructuredCommandInput { + /** + * A brief description of the expected input + */ + hint: string; +} /** * Response from processing a user prompt. * @@ -1121,11 +1154,6 @@ export const embeddedResourceResourceSchema = z.union([ /** @internal */ export const authenticateResponseSchema = z.null(); -/** @internal */ -export const newSessionResponseSchema = z.object({ - sessionId: z.string(), -}); - /** @internal */ export const loadSessionResponseSchema = z.null(); @@ -1140,6 +1168,11 @@ export const promptResponseSchema = z.object({ ]), }); +/** @internal */ +export const unstructuredCommandInputSchema = z.object({ + hint: z.string(), +}); + /** @internal */ export const permissionOptionSchema = z.object({ kind: z.union([ @@ -1318,6 +1351,9 @@ export const promptCapabilitiesSchema = z.object({ image: z.boolean().optional(), }); +/** @internal */ +export const availableCommandInputSchema = unstructuredCommandInputSchema; + /** @internal */ export const planEntrySchema = z.object({ content: z.string(), @@ -1449,6 +1485,13 @@ export const agentCapabilitiesSchema = z.object({ promptCapabilities: promptCapabilitiesSchema.optional(), }); +/** @internal */ +export const availableCommandSchema = z.object({ + description: z.string(), + input: availableCommandInputSchema.optional().nullable(), + name: z.string(), +}); + /** @internal */ export const clientResponseSchema = z.union([ writeTextFileResponseSchema, @@ -1484,6 +1527,12 @@ export const initializeResponseSchema = z.object({ protocolVersion: z.number(), }); +/** @internal */ +export const newSessionResponseSchema = z.object({ + availableCommands: z.array(availableCommandSchema).optional(), + sessionId: z.string(), +}); + /** @internal */ export const clientRequestSchema = z.union([ writeTextFileRequestSchema,