Skip to content

Commit 539d159

Browse files
authored
docs(rfd): Session Config Options to Preview stage (#378)
* docs(rfd): Session Config Options to Preview stage With several implementations in place, it feels like this is ready for preview. I added this in Zed + Codex ACP, and the JetBrains folks have this in their Kotlin SDK. So let's move this to preview stage for final feedback! * Allow for custom categories
1 parent c917792 commit 539d159

File tree

7 files changed

+374
-15
lines changed

7 files changed

+374
-15
lines changed

docs/docs.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"hidden": true,
8181
"pages": [
8282
"protocol/draft/cancellation",
83+
"protocol/draft/session-config-options",
8384
"protocol/draft/schema"
8485
]
8586
}
@@ -105,7 +106,6 @@
105106
"group": "Draft",
106107
"pages": [
107108
"rfds/session-list",
108-
"rfds/session-config-options",
109109
"rfds/session-fork",
110110
"rfds/request-cancellation",
111111
"rfds/session-resume",
@@ -119,7 +119,7 @@
119119
"rfds/auth-methods"
120120
]
121121
},
122-
{ "group": "Preview", "pages": [] },
122+
{ "group": "Preview", "pages": ["rfds/session-config-options"] },
123123
{ "group": "Completed", "pages": ["rfds/introduce-rfd-process"] }
124124
]
125125
},

docs/protocol/draft/schema.mdx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3043,7 +3043,10 @@ Semantic category for a session configuration option.
30433043
This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
30443044
session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
30453045
placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
3046-
categories gracefully (treat as `Other`).
3046+
categories gracefully.
3047+
3048+
Category names beginning with `_` are free for custom use, like other ACP extension methods.
3049+
Category names that do not begin with `_` are reserved for the ACP spec.
30473050

30483051
**Type:** Union
30493052

@@ -3059,7 +3062,7 @@ categories gracefully (treat as `Other`).
30593062
Thought/reasoning level selector.
30603063
</ResponseField>
30613064

3062-
<ResponseField name="other" type="string">
3065+
<ResponseField name="string" type="string">
30633066
Unknown / uncategorized selector.
30643067
</ResponseField>
30653068

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
title: "Session Config Options"
3+
description: "Flexible configuration selectors for agent sessions"
4+
---
5+
6+
Agents can provide an arbitrary list of configuration options for a session, allowing Clients to offer users customizable selectors for things like models, modes, reasoning levels, and more.
7+
8+
<Info>
9+
Session Config Options are the preferred way to expose session-level
10+
configuration. If an Agent provides `configOptions`, Clients **SHOULD** use
11+
them instead of the deprecated [`modes`](../session-modes) field.
12+
</Info>
13+
14+
## Initial State
15+
16+
During [Session Setup](../session-setup) the Agent **MAY** return a list of configuration options and their current values:
17+
18+
```json
19+
{
20+
"jsonrpc": "2.0",
21+
"id": 1,
22+
"result": {
23+
"sessionId": "sess_abc123def456",
24+
"configOptions": [
25+
{
26+
"id": "mode",
27+
"name": "Session Mode",
28+
"description": "Controls how the agent requests permission",
29+
"category": "mode",
30+
"type": "select",
31+
"currentValue": "ask",
32+
"options": [
33+
{
34+
"value": "ask",
35+
"name": "Ask",
36+
"description": "Request permission before making any changes"
37+
},
38+
{
39+
"value": "code",
40+
"name": "Code",
41+
"description": "Write and modify code with full tool access"
42+
}
43+
]
44+
},
45+
{
46+
"id": "model",
47+
"name": "Model",
48+
"category": "model",
49+
"type": "select",
50+
"currentValue": "model-1",
51+
"options": [
52+
{
53+
"value": "model-1",
54+
"name": "Model 1",
55+
"description": "The fastest model"
56+
},
57+
{
58+
"value": "model-2",
59+
"name": "Model 2",
60+
"description": "The most powerful model"
61+
}
62+
]
63+
}
64+
]
65+
}
66+
}
67+
```
68+
69+
<ResponseField name="configOptions" type="ConfigOption[]">
70+
The list of configuration options available for this session. The order of
71+
this array represents the Agent's preferred priority. Clients **SHOULD**
72+
respect this ordering when displaying options.
73+
</ResponseField>
74+
75+
### ConfigOption
76+
77+
<ResponseField name="id" type="string" required>
78+
Unique identifier for this configuration option. Used when setting values.
79+
</ResponseField>
80+
81+
<ResponseField name="name" type="string" required>
82+
Human-readable label for the option
83+
</ResponseField>
84+
85+
<ResponseField name="description" type="string">
86+
Optional description providing more details about what this option controls
87+
</ResponseField>
88+
89+
<ResponseField name="category" type="ConfigOptionCategory">
90+
Optional [semantic category](#option-categories) to help Clients provide
91+
consistent UX
92+
</ResponseField>
93+
94+
<ResponseField name="type" type="ConfigOptionType" required>
95+
The type of input control. Currently only `select` is supported.
96+
</ResponseField>
97+
98+
<ResponseField name="currentValue" type="string" required>
99+
The currently selected value for this option
100+
</ResponseField>
101+
102+
<ResponseField name="options" type="ConfigOptionValue[]" required>
103+
The available values for this option
104+
</ResponseField>
105+
106+
### ConfigOptionValue
107+
108+
<ResponseField name="value" type="string" required>
109+
The value identifier used when setting this option
110+
</ResponseField>
111+
112+
<ResponseField name="name" type="string" required>
113+
Human-readable name to display
114+
</ResponseField>
115+
116+
<ResponseField name="description" type="string">
117+
Optional description of what this value does
118+
</ResponseField>
119+
120+
## Option Categories
121+
122+
Each config option **MAY** include a `category` field. Categories are semantic metadata intended to help Clients provide consistent UX, such as attaching keyboard shortcuts, choosing icons, or deciding placement.
123+
124+
<Warning>
125+
Categories are for UX purposes only and **MUST NOT** be required for
126+
correctness. Clients **MUST** handle missing or unknown categories gracefully.
127+
</Warning>
128+
129+
Category names beginning with `_` are free for custom use (e.g., `_my_custom_category`). Category names that do not begin with `_` are reserved for the ACP spec.
130+
131+
| Category | Description |
132+
| --------------- | -------------------------------- |
133+
| `mode` | Session mode selector |
134+
| `model` | Model selector |
135+
| `thought_level` | Thought/reasoning level selector |
136+
137+
When multiple options share the same category, Clients **SHOULD** use the array ordering to resolve ties, preferring earlier options in the list for prominent placement or keyboard shortcuts.
138+
139+
## Option Ordering
140+
141+
The order of the `configOptions` array is significant. Agents **SHOULD** place higher-priority options first in the list.
142+
143+
Clients **SHOULD**:
144+
145+
- Display options in the order provided by the Agent
146+
- Use ordering to resolve ties when multiple options share the same category
147+
- If displaying a limited number of options, prefer those at the beginning of the list
148+
149+
## Default Values and Graceful Degradation
150+
151+
Agents **MUST** always provide a default value for every configuration option. This ensures the Agent can operate correctly even if:
152+
153+
- The Client doesn't support configuration options
154+
- The Client chooses not to display certain options
155+
- The Client receives an option type it doesn't recognize
156+
157+
If a Client receives an option with an unrecognized `type`, it **SHOULD** ignore that option. The Agent will continue using its default value.
158+
159+
## Setting a Config Option
160+
161+
The current value of a config option can be changed at any point during a session, whether the Agent is idle or generating a response.
162+
163+
### From the Client
164+
165+
Clients can change a config option value by calling the `session/set_config_option` method:
166+
167+
```json
168+
{
169+
"jsonrpc": "2.0",
170+
"id": 2,
171+
"method": "session/set_config_option",
172+
"params": {
173+
"sessionId": "sess_abc123def456",
174+
"configId": "mode",
175+
"value": "code"
176+
}
177+
}
178+
```
179+
180+
<ParamField path="sessionId" type="SessionId" required>
181+
The ID of the session
182+
</ParamField>
183+
184+
<ParamField path="configId" type="string" required>
185+
The `id` of the configuration option to change
186+
</ParamField>
187+
188+
<ParamField path="value" type="string" required>
189+
The new value to set. Must be one of the values listed in the option's
190+
`options` array.
191+
</ParamField>
192+
193+
The Agent **MUST** respond with the complete list of all configuration options and their current values:
194+
195+
```json
196+
{
197+
"jsonrpc": "2.0",
198+
"id": 2,
199+
"result": {
200+
"configOptions": [
201+
{
202+
"id": "mode",
203+
"name": "Session Mode",
204+
"type": "select",
205+
"currentValue": "code",
206+
"options": [...]
207+
},
208+
{
209+
"id": "model",
210+
"name": "Model",
211+
"type": "select",
212+
"currentValue": "model-1",
213+
"options": [...]
214+
}
215+
]
216+
}
217+
}
218+
```
219+
220+
<Note>
221+
The response always contains the **complete** configuration state. This allows
222+
Agents to reflect dependent changes. For example, if changing the model
223+
affects available reasoning options, or if an option's available values change
224+
based on another selection.
225+
</Note>
226+
227+
### From the Agent
228+
229+
The Agent can also change configuration options and notify the Client by sending a `config_options_update` session notification:
230+
231+
```json
232+
{
233+
"jsonrpc": "2.0",
234+
"method": "session/update",
235+
"params": {
236+
"sessionId": "sess_abc123def456",
237+
"update": {
238+
"sessionUpdate": "config_options_update",
239+
"configOptions": [
240+
{
241+
"id": "mode",
242+
"name": "Session Mode",
243+
"type": "select",
244+
"currentValue": "code",
245+
"options": [...]
246+
},
247+
{
248+
"id": "model",
249+
"name": "Model",
250+
"type": "select",
251+
"currentValue": "model-2",
252+
"options": [...]
253+
}
254+
]
255+
}
256+
}
257+
}
258+
```
259+
260+
This notification also contains the complete configuration state. Common reasons an Agent might update configuration options include:
261+
262+
- Switching modes after completing a planning phase
263+
- Falling back to a different model due to rate limits or errors
264+
- Adjusting available options based on context discovered during execution
265+
266+
## Relationship to Session Modes
267+
268+
Session Config Options supersede the older [Session Modes](../session-modes) API. However, during the transition period, Agents that provide mode-like configuration **SHOULD** send both:
269+
270+
- `configOptions` with a `category: "mode"` option for Clients that support config options
271+
- `modes` for Clients that only support the older API
272+
273+
If an Agent provides both `configOptions` and `modes` in the session response:
274+
275+
- Clients that support config options **SHOULD** use `configOptions` exclusively and ignore `modes`
276+
- Clients that don't support config options **SHOULD** fall back to `modes`
277+
- Agents **SHOULD** keep both in sync to ensure consistent behavior regardless of which field the Client uses
278+
279+
<Card icon="toggle-on" horizontal href="../session-modes">
280+
Learn about the deprecated Session Modes API
281+
</Card>

docs/rfds/session-config-options.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,16 @@ Each top-level config option MAY include an optional `category` field. This is i
109109

110110
In addition to `category`, Clients SHOULD use the ordering of the `configOptions` array as provided by the Agent as the primary way to establish priority and resolve ties. For example, if multiple options share the same `category`, a Client can prefer the first matching option in the list when assigning keyboard shortcuts or deciding which options to surface most prominently.
111111

112-
`category` is semantic metadata and MUST NOT be required for correctness. Clients MUST handle missing or unknown categories gracefully (treat as `other`).
112+
`category` is semantic metadata and MUST NOT be required for correctness. Clients MUST handle missing or unknown categories gracefully.
113+
114+
Category names beginning with `_` are free for custom use. Category names that do not begin with `_` are reserved for the ACP spec.
113115

114116
Proposed enum:
115117

116118
- `mode` - Session mode selector
117119
- `model` - Model selector
118120
- `thought_level` - Thought/reasoning level selector
119-
- `other` - Unknown / uncategorized selector
121+
- Any string beginning with `_` - Custom category (e.g., `_my_custom_category`)
120122

121123
When we introduce this, we could also allow for grouped options, in case there are logical sub-headers and groupings for the options in an individual selector.
122124

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"format:check": "prettier --check . && cargo fmt -- --check",
2929
"spellcheck": "./scripts/spellcheck.sh",
3030
"spellcheck:fix": "./scripts/spellcheck.sh --write-changes",
31-
"check": "cargo clippy --all-features && npm run format:check && npm run spellcheck && cargo test",
31+
"check": "cargo clippy --all-features && npm run format:check && npm run spellcheck && cargo test --all-features",
3232
"docs": "cd docs && npx mint dev"
3333
},
3434
"devDependencies": {

schema/schema.unstable.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,8 +2548,7 @@
25482548
"type": "object"
25492549
},
25502550
"SessionConfigOptionCategory": {
2551-
"description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSemantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully (treat as `Other`).",
2552-
"oneOf": [
2551+
"anyOf": [
25532552
{
25542553
"const": "mode",
25552554
"description": "Session mode selector.",
@@ -2566,11 +2565,11 @@
25662565
"type": "string"
25672566
},
25682567
{
2569-
"const": "other",
25702568
"description": "Unknown / uncategorized selector.",
25712569
"type": "string"
25722570
}
2573-
]
2571+
],
2572+
"description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nSemantic category for a session configuration option.\n\nThis is intended to help Clients distinguish broadly common selectors (e.g. model selector vs\nsession mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,\nplacement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown\ncategories gracefully.\n\nCategory names beginning with `_` are free for custom use, like other ACP extension methods.\nCategory names that do not begin with `_` are reserved for the ACP spec."
25742573
},
25752574
"SessionConfigSelect": {
25762575
"description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nA single-value selector (dropdown) session configuration option payload.",

0 commit comments

Comments
 (0)