Skip to content

Commit bd5906b

Browse files
authored
Merge pull request #54 from zed-industries/add-experiment-commands
Add experimental command support
2 parents 1dc5659 + 9f17b72 commit bd5906b

4 files changed

Lines changed: 184 additions & 5 deletions

File tree

docs/protocol/schema.mdx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,12 @@ See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol
250250

251251
**Properties:**
252252

253+
<ResponseField name="availableCommands" type={<><span><a href="#availablecommand">AvailableCommand</a></span><span>[]</span></>} >
254+
**UNSTABLE**
255+
256+
Commands that may be executed via `session/prompt` requests
257+
258+
</ResponseField>
253259
<ResponseField name="sessionId" type={<a href="#sessionid">SessionId</a>} required>
254260
Unique identifier for the created session.
255261

@@ -605,6 +611,50 @@ Unique identifier for an authentication method.
605611

606612
**Type:** `string`
607613

614+
## <span class="font-mono">AvailableCommand</span>
615+
616+
Information about a command.
617+
618+
**Type:** Object
619+
620+
**Properties:**
621+
622+
<ResponseField name="description" type={"string"} required>
623+
Human-readable description of what the command does.
624+
</ResponseField>
625+
<ResponseField
626+
name="input"
627+
type={
628+
<>
629+
<span>
630+
<a href="#availablecommandinput">AvailableCommandInput</a>
631+
</span>
632+
<span> | null</span>
633+
</>
634+
}
635+
>
636+
Input for the command if required
637+
</ResponseField>
638+
<ResponseField name="name" type={"string"} required>
639+
Command name (e.g., "create_plan", "research_codebase").
640+
</ResponseField>
641+
642+
## <span class="font-mono">AvailableCommandInput</span>
643+
644+
**Type:** Union
645+
646+
<ResponseField name="Object">
647+
All text that was typed after the command name is provided as input.
648+
649+
<Expandable title="Properties">
650+
651+
<ResponseField name="hint" type={"string"} required>
652+
A brief description of the expected input
653+
</ResponseField>
654+
655+
</Expandable>
656+
</ResponseField>
657+
608658
## <span class="font-mono">BlobResourceContents</span>
609659

610660
Binary resource contents.

rust/agent.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,37 @@ pub struct NewSessionResponse {
204204
///
205205
/// Used in all subsequent requests for this conversation.
206206
pub session_id: SessionId,
207+
/// **UNSTABLE**
208+
///
209+
/// Commands that may be executed via `session/prompt` requests
210+
#[cfg(feature = "unstable")]
211+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
212+
pub available_commands: Vec<AvailableCommand>,
213+
}
214+
215+
/// Information about a command.
216+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
217+
#[serde(rename_all = "camelCase")]
218+
#[cfg(feature = "unstable")]
219+
pub struct AvailableCommand {
220+
/// Command name (e.g., "create_plan", "research_codebase").
221+
pub name: String,
222+
/// Human-readable description of what the command does.
223+
pub description: String,
224+
/// Input for the command if required
225+
pub input: Option<AvailableCommandInput>,
226+
}
227+
228+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
229+
#[serde(untagged, rename_all = "camelCase")]
230+
#[cfg(feature = "unstable")]
231+
pub enum AvailableCommandInput {
232+
/// All text that was typed after the command name is provided as input.
233+
#[schemars(rename = "UnstructuredCommandInput")]
234+
Unstructured {
235+
/// A brief description of the expected input
236+
hint: String,
237+
},
207238
}
208239

209240
// Load session

schema/schema.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,48 @@
172172
"x-method": "authenticate",
173173
"x-side": "agent"
174174
},
175+
"AvailableCommand": {
176+
"description": "Information about a command.",
177+
"properties": {
178+
"description": {
179+
"description": "Human-readable description of what the command does.",
180+
"type": "string"
181+
},
182+
"input": {
183+
"anyOf": [
184+
{
185+
"$ref": "#/$defs/AvailableCommandInput"
186+
},
187+
{
188+
"type": "null"
189+
}
190+
],
191+
"description": "Input for the command if required"
192+
},
193+
"name": {
194+
"description": "Command name (e.g., \"create_plan\", \"research_codebase\").",
195+
"type": "string"
196+
}
197+
},
198+
"required": ["name", "description"],
199+
"type": "object"
200+
},
201+
"AvailableCommandInput": {
202+
"anyOf": [
203+
{
204+
"description": "All text that was typed after the command name is provided as input.",
205+
"properties": {
206+
"hint": {
207+
"description": "A brief description of the expected input",
208+
"type": "string"
209+
}
210+
},
211+
"required": ["hint"],
212+
"title": "UnstructuredCommandInput",
213+
"type": "object"
214+
}
215+
]
216+
},
175217
"BlobResourceContents": {
176218
"description": "Binary resource contents.",
177219
"properties": {
@@ -723,6 +765,13 @@
723765
"NewSessionResponse": {
724766
"description": "Response from creating a new session.\n\nSee protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)",
725767
"properties": {
768+
"availableCommands": {
769+
"description": "**UNSTABLE**\n\nCommands that may be executed via `session/prompt` requests",
770+
"items": {
771+
"$ref": "#/$defs/AvailableCommand"
772+
},
773+
"type": "array"
774+
},
726775
"sessionId": {
727776
"$ref": "#/$defs/SessionId",
728777
"description": "Unique identifier for the created session.\n\nUsed in all subsequent requests for this conversation."

typescript/schema.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ export type AgentResponse =
295295
| LoadSessionResponse
296296
| PromptResponse;
297297
export type AuthenticateResponse = null;
298+
export type AvailableCommandInput = UnstructuredCommandInput;
298299
export type LoadSessionResponse = null;
299300
/**
300301
* All possible notifications that an agent can send to a client.
@@ -815,6 +816,12 @@ export interface AuthMethod {
815816
* See protocol docs: [Creating a Session](https://agentclientprotocol.com/protocol/session-setup#creating-a-session)
816817
*/
817818
export interface NewSessionResponse {
819+
/**
820+
* **UNSTABLE**
821+
*
822+
* Commands that may be executed via `session/prompt` requests
823+
*/
824+
availableCommands?: AvailableCommand[];
818825
/**
819826
* A unique identifier for a conversation session between a client and agent.
820827
*
@@ -834,6 +841,32 @@ export interface NewSessionResponse {
834841
*/
835842
sessionId: string;
836843
}
844+
/**
845+
* Information about a command.
846+
*/
847+
export interface AvailableCommand {
848+
/**
849+
* Human-readable description of what the command does.
850+
*/
851+
description: string;
852+
/**
853+
* Input for the command if required
854+
*/
855+
input?: AvailableCommandInput | null;
856+
/**
857+
* Command name (e.g., "create_plan", "research_codebase").
858+
*/
859+
name: string;
860+
}
861+
/**
862+
* All text that was typed after the command name is provided as input.
863+
*/
864+
export interface UnstructuredCommandInput {
865+
/**
866+
* A brief description of the expected input
867+
*/
868+
hint: string;
869+
}
837870
/**
838871
* Response from processing a user prompt.
839872
*
@@ -1121,11 +1154,6 @@ export const embeddedResourceResourceSchema = z.union([
11211154
/** @internal */
11221155
export const authenticateResponseSchema = z.null();
11231156

1124-
/** @internal */
1125-
export const newSessionResponseSchema = z.object({
1126-
sessionId: z.string(),
1127-
});
1128-
11291157
/** @internal */
11301158
export const loadSessionResponseSchema = z.null();
11311159

@@ -1140,6 +1168,11 @@ export const promptResponseSchema = z.object({
11401168
]),
11411169
});
11421170

1171+
/** @internal */
1172+
export const unstructuredCommandInputSchema = z.object({
1173+
hint: z.string(),
1174+
});
1175+
11431176
/** @internal */
11441177
export const permissionOptionSchema = z.object({
11451178
kind: z.union([
@@ -1318,6 +1351,9 @@ export const promptCapabilitiesSchema = z.object({
13181351
image: z.boolean().optional(),
13191352
});
13201353

1354+
/** @internal */
1355+
export const availableCommandInputSchema = unstructuredCommandInputSchema;
1356+
13211357
/** @internal */
13221358
export const planEntrySchema = z.object({
13231359
content: z.string(),
@@ -1449,6 +1485,13 @@ export const agentCapabilitiesSchema = z.object({
14491485
promptCapabilities: promptCapabilitiesSchema.optional(),
14501486
});
14511487

1488+
/** @internal */
1489+
export const availableCommandSchema = z.object({
1490+
description: z.string(),
1491+
input: availableCommandInputSchema.optional().nullable(),
1492+
name: z.string(),
1493+
});
1494+
14521495
/** @internal */
14531496
export const clientResponseSchema = z.union([
14541497
writeTextFileResponseSchema,
@@ -1484,6 +1527,12 @@ export const initializeResponseSchema = z.object({
14841527
protocolVersion: z.number(),
14851528
});
14861529

1530+
/** @internal */
1531+
export const newSessionResponseSchema = z.object({
1532+
availableCommands: z.array(availableCommandSchema).optional(),
1533+
sessionId: z.string(),
1534+
});
1535+
14871536
/** @internal */
14881537
export const clientRequestSchema = z.union([
14891538
writeTextFileRequestSchema,

0 commit comments

Comments
 (0)