Skip to content

Commit 2b8cbaa

Browse files
committed
Unstable support for model selection
Signed-off-by: Ben Brandt <benjamin.j.brandt@gmail.com>
1 parent 4f58953 commit 2b8cbaa

11 files changed

Lines changed: 1071 additions & 14 deletions

File tree

docs/protocol/schema.mdx

Lines changed: 236 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/ini
8888
<ResponseField name="clientCapabilities" type={<a href="#clientcapabilities">ClientCapabilities</a>} >
8989
Capabilities supported by the client.
9090

91-
- Default: `{"fs":{"readTextFile":false,"writeTextFile":false},"terminal":false}`
91+
- Default: `{"fs":{"readTextFile":false,"writeTextFile":false},"modelSelection":false,"terminal":false}`
9292

9393
</ResponseField>
9494
<ResponseField name="protocolVersion" type={<a href="#protocolversion">ProtocolVersion</a>} required>
@@ -113,7 +113,7 @@ See protocol docs: [Initialization](https://agentclientprotocol.com/protocol/ini
113113
<ResponseField name="agentCapabilities" type={<a href="#agentcapabilities">AgentCapabilities</a>} >
114114
Capabilities supported by the agent.
115115

116-
- Default: `{"loadSession":false,"mcpCapabilities":{"http":false,"sse":false},"promptCapabilities":{"audio":false,"embeddedContext":false,"image":false}}`
116+
- Default: `{"loadSession":false,"mcpCapabilities":{"http":false,"sse":false},"modelSelection":false,"promptCapabilities":{"audio":false,"embeddedContext":false,"image":false}}`
117117

118118
</ResponseField>
119119
<ResponseField name="authMethods" type={<><span><a href="#authmethod">AuthMethod</a></span><span>[]</span></>} >
@@ -130,6 +130,184 @@ The client should disconnect, if it doesn't support this version.
130130

131131
</ResponseField>
132132

133+
<a id="model-list"></a>
134+
### <span class="font-mono">model/list</span>
135+
136+
**UNSTABLE**
137+
138+
This capability is not part of the spec yet, and may be removed or changed at any point.
139+
140+
List all available models for the session.
141+
142+
#### <span class="font-mono">ModelInfo</span>
143+
144+
**UNSTABLE**
145+
146+
This capability is not part of the spec yet, and may be removed or changed at any point.
147+
148+
Information about a selectable model.
149+
150+
**Type:** Object
151+
152+
**Properties:**
153+
154+
<ResponseField name="_meta" type={"object"}>
155+
Extension point for implementations
156+
</ResponseField>
157+
<ResponseField name="modelId" type={<a href="#modelid">ModelId</a>} required>
158+
Unique identifier for the model.
159+
</ResponseField>
160+
<ResponseField name="name" type={"string"} required>
161+
Human-readable name of the model.
162+
</ResponseField>
163+
164+
#### <span class="font-mono">ModelListRequest</span>
165+
166+
**UNSTABLE**
167+
168+
This capability is not part of the spec yet, and may be removed or changed at any point.
169+
170+
Request parameters for requesting available models from the agent.
171+
This request is per-session to allow for custom settings to affect the list of available models.
172+
173+
**Type:** Object
174+
175+
**Properties:**
176+
177+
<ResponseField name="_meta" type={"object"}>
178+
Extension point for implementations
179+
</ResponseField>
180+
<ResponseField
181+
name="sessionId"
182+
type={<a href="#sessionid">SessionId</a>}
183+
required
184+
>
185+
The ID of the session to send this request to.
186+
</ResponseField>
187+
188+
#### <span class="font-mono">ModelListResponse</span>
189+
190+
**UNSTABLE**
191+
192+
This capability is not part of the spec yet, and may be removed or changed at any point.
193+
194+
Response of available models from the agent.
195+
196+
**Type:** Object
197+
198+
**Properties:**
199+
200+
<ResponseField name="_meta" type={"object"}>
201+
Extension point for implementations
202+
</ResponseField>
203+
<ResponseField
204+
name="models"
205+
type={
206+
<>
207+
<span>
208+
<a href="#modelinfo">ModelInfo</a>
209+
</span>
210+
<span>[]</span>
211+
</>
212+
}
213+
required
214+
>
215+
Models available to choose from.
216+
</ResponseField>
217+
218+
<a id="model-select"></a>
219+
### <span class="font-mono">model/select</span>
220+
221+
**UNSTABLE**
222+
223+
This capability is not part of the spec yet, and may be removed or changed at any point.
224+
225+
Select a model for a given session.
226+
227+
#### <span class="font-mono">ModelSelectRequest</span>
228+
229+
**UNSTABLE**
230+
231+
This capability is not part of the spec yet, and may be removed or changed at any point.
232+
233+
Request parameters for setting a session model.
234+
235+
**Type:** Object
236+
237+
**Properties:**
238+
239+
<ResponseField name="_meta" type={"object"}>
240+
Extension point for implementations
241+
</ResponseField>
242+
<ResponseField name="modelId" type={<a href="#modelid">ModelId</a>} required>
243+
The ID of the model to set.
244+
</ResponseField>
245+
<ResponseField
246+
name="sessionId"
247+
type={<a href="#sessionid">SessionId</a>}
248+
required
249+
>
250+
The ID of the session to set the model for.
251+
</ResponseField>
252+
253+
#### <span class="font-mono">ModelSelectResponse</span>
254+
255+
**UNSTABLE**
256+
257+
This capability is not part of the spec yet, and may be removed or changed at any point.
258+
259+
Response to `model/select` method.
260+
261+
**Type:** Object
262+
263+
**Properties:**
264+
265+
<ResponseField name="_meta" type={"object"}>
266+
Extension point for implementations
267+
</ResponseField>
268+
269+
#### <span class="font-mono">ModelSelectedRequest</span>
270+
271+
**UNSTABLE**
272+
273+
This capability is not part of the spec yet, and may be removed or changed at any point.
274+
275+
Request parameters for getting the currently selected model for a session.
276+
277+
**Type:** Object
278+
279+
**Properties:**
280+
281+
<ResponseField name="_meta" type={"object"}>
282+
Extension point for implementations
283+
</ResponseField>
284+
<ResponseField
285+
name="sessionId"
286+
type={<a href="#sessionid">SessionId</a>}
287+
required
288+
>
289+
The ID of the session to set the model for.
290+
</ResponseField>
291+
292+
#### <span class="font-mono">ModelSelectedResponse</span>
293+
294+
**UNSTABLE**
295+
296+
This capability is not part of the spec yet, and may be removed or changed at any point.
297+
298+
Response to `model/selected` method.
299+
300+
**Type:** Object
301+
302+
**Properties:**
303+
304+
<ResponseField name="_meta" type={"object"}>
305+
Extension point for implementations
306+
</ResponseField>
307+
<ResponseField name="modelId" type={<a href="#modelid">ModelId</a>} required>
308+
The ID of the model to set.
309+
</ResponseField>
310+
133311
<a id="session-cancel"></a>
134312
### <span class="font-mono">session/cancel</span>
135313

@@ -541,7 +719,7 @@ Only available if the client supports the `fs.writeTextFile` capability.
541719

542720
#### <span class="font-mono">WriteTextFileResponse</span>
543721

544-
Response to fs/write_text_file
722+
Response to `fs/write_text_file`
545723

546724
**Type:** Object
547725

@@ -986,6 +1164,16 @@ See protocol docs: [Agent Capabilities](https://agentclientprotocol.com/protocol
9861164

9871165
- Default: `{"http":false,"sse":false}`
9881166

1167+
</ResponseField>
1168+
<ResponseField name="modelSelection" type={"boolean"} >
1169+
**UNSTABLE**
1170+
1171+
This capability is not part of the spec yet, and may be removed or changed at any point.
1172+
1173+
Whether the agent supports `model/*`.
1174+
1175+
- Default: `false`
1176+
9891177
</ResponseField>
9901178
<ResponseField name="promptCapabilities" type={<a href="#promptcapabilities">PromptCapabilities</a>} >
9911179
Prompt capabilities supported by the agent.
@@ -1093,7 +1281,7 @@ Information about a command.
10931281
Input for the command if required
10941282
</ResponseField>
10951283
<ResponseField name="name" type={"string"} required>
1096-
Command name (e.g., "create_plan", "research_codebase").
1284+
Command name (e.g., `create_plan`, `research_codebase`).
10971285
</ResponseField>
10981286

10991287
## <span class="font-mono">AvailableCommandInput</span>
@@ -1151,6 +1339,16 @@ Determines which file operations the agent can request.
11511339

11521340
- Default: `{"readTextFile":false,"writeTextFile":false}`
11531341

1342+
</ResponseField>
1343+
<ResponseField name="modelSelection" type={"boolean"} >
1344+
**UNSTABLE**
1345+
1346+
This capability is not part of the spec yet, and may be removed or changed at any point.
1347+
1348+
Whether the Client supports `model/*` methods.
1349+
1350+
- Default: `false`
1351+
11541352
</ResponseField>
11551353
<ResponseField name="terminal" type={"boolean"} >
11561354
Whether the Client support all `terminal/*` methods.
@@ -1622,6 +1820,40 @@ All Agents MUST support this transport.
16221820
</Expandable>
16231821
</ResponseField>
16241822

1823+
## <span class="font-mono">ModelId</span>
1824+
1825+
**UNSTABLE**
1826+
1827+
This capability is not part of the spec yet, and may be removed or changed at any point.
1828+
1829+
A unique identifier for a model.
1830+
1831+
**Type:** `string`
1832+
1833+
## <span class="font-mono">ModelNotification</span>
1834+
1835+
**UNSTABLE**
1836+
1837+
This capability is not part of the spec yet, and may be removed or changed at any point.
1838+
1839+
Notification that the agent's model list has been updated
1840+
so that the client can requery it.
1841+
1842+
**Type:** Object
1843+
1844+
**Properties:**
1845+
1846+
<ResponseField name="_meta" type={"object"}>
1847+
Extension point for implementations
1848+
</ResponseField>
1849+
<ResponseField
1850+
name="sessionId"
1851+
type={<a href="#sessionid">SessionId</a>}
1852+
required
1853+
>
1854+
The session ID that was updated.
1855+
</ResponseField>
1856+
16251857
## <span class="font-mono">PermissionOption</span>
16261858

16271859
An option presented to the user when requesting permission.

rust/acp.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,39 @@ impl Agent for ClientSideConnection {
234234
)
235235
}
236236

237+
#[cfg(feature = "unstable")]
238+
async fn list_models(&self, args: ModelListRequest) -> Result<ModelListResponse, Error> {
239+
self.conn
240+
.request(
241+
MODEL_LIST_METHOD_NAME,
242+
Some(ClientRequest::ModelListRequest(args)),
243+
)
244+
.await
245+
}
246+
247+
#[cfg(feature = "unstable")]
248+
async fn select_model(&self, args: ModelSelectRequest) -> Result<ModelSelectResponse, Error> {
249+
self.conn
250+
.request(
251+
MODEL_SELECT_METHOD_NAME,
252+
Some(ClientRequest::ModelSelectRequest(args)),
253+
)
254+
.await
255+
}
256+
257+
#[cfg(feature = "unstable")]
258+
async fn selected_model(
259+
&self,
260+
args: ModelSelectedRequest,
261+
) -> Result<ModelSelectedResponse, Error> {
262+
self.conn
263+
.request(
264+
MODEL_SELECTED_METHOD_NAME,
265+
Some(ClientRequest::ModelSelectedRequest(args)),
266+
)
267+
.await
268+
}
269+
237270
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse, Error> {
238271
self.conn
239272
.request(
@@ -377,6 +410,10 @@ impl<T: Client> MessageHandler<ClientSide> for T {
377410
AgentNotification::SessionNotification(args) => {
378411
self.session_notification(args).await?;
379412
}
413+
#[cfg(feature = "unstable")]
414+
AgentNotification::ModelNotification(args) => {
415+
self.model_notification(args).await?;
416+
}
380417
AgentNotification::ExtNotification(args) => {
381418
self.ext_notification(args).await?;
382419
}
@@ -550,6 +587,14 @@ impl Client for AgentSideConnection {
550587
)
551588
}
552589

590+
#[cfg(feature = "unstable")]
591+
async fn model_notification(&self, args: ModelNotification) -> Result<(), Error> {
592+
self.conn.notify(
593+
MODEL_UPDATE_NOTIFICATION,
594+
Some(AgentNotification::ModelNotification(args)),
595+
)
596+
}
597+
553598
async fn ext_method(&self, args: ExtRequest) -> Result<ExtResponse, Error> {
554599
self.conn
555600
.request(
@@ -667,6 +712,21 @@ impl<T: Agent> MessageHandler<AgentSide> for T {
667712
let response = self.set_session_mode(args).await?;
668713
Ok(AgentResponse::SetSessionModeResponse(response))
669714
}
715+
#[cfg(feature = "unstable")]
716+
ClientRequest::ModelListRequest(args) => {
717+
let response = self.list_models(args).await?;
718+
Ok(AgentResponse::ModelListResponse(response))
719+
}
720+
#[cfg(feature = "unstable")]
721+
ClientRequest::ModelSelectRequest(args) => {
722+
let response = self.select_model(args).await?;
723+
Ok(AgentResponse::ModelSelectResponse(response))
724+
}
725+
#[cfg(feature = "unstable")]
726+
ClientRequest::ModelSelectedRequest(args) => {
727+
let response = self.selected_model(args).await?;
728+
Ok(AgentResponse::ModelSelectedResponse(response))
729+
}
670730
ClientRequest::ExtMethodRequest(args) => {
671731
let response = self.ext_method(args).await?;
672732
Ok(AgentResponse::ExtMethodResponse(response))

0 commit comments

Comments
 (0)