Skip to content

Commit 9be55e9

Browse files
feat(unstable): Add a category to session config options (#366)
This is to allow clients to better distinguish between different types of options, for example to have a keyboard shortcut or special placement for the first of a given category. Co-authored-by: neel <[email protected]>
1 parent eaedcb4 commit 9be55e9

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

docs/protocol/draft/schema.mdx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,37 @@ Single-value selector (dropdown).
30323032
</Expandable>
30333033
</ResponseField>
30343034

3035+
## <span class="font-mono">SessionConfigOptionCategory</span>
3036+
3037+
**UNSTABLE**
3038+
3039+
This capability is not part of the spec yet, and may be removed or changed at any point.
3040+
3041+
Semantic category for a session configuration option.
3042+
3043+
This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
3044+
session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
3045+
placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
3046+
categories gracefully (treat as `Other`).
3047+
3048+
**Type:** Union
3049+
3050+
<ResponseField name="mode" type="string">
3051+
Session mode selector.
3052+
</ResponseField>
3053+
3054+
<ResponseField name="model" type="string">
3055+
Model selector.
3056+
</ResponseField>
3057+
3058+
<ResponseField name="thought_level" type="string">
3059+
Thought/reasoning level selector.
3060+
</ResponseField>
3061+
3062+
<ResponseField name="other" type="string">
3063+
Unknown / uncategorized selector.
3064+
</ResponseField>
3065+
30353066
## <span class="font-mono">SessionConfigSelect</span>
30363067

30373068
**UNSTABLE**

docs/rfds/session-config-options.mdx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Since this space is moving fast, we ideally would find a more flexible option wi
2828
2929
Instead, we can allow Agents to provide configuration options in the `session/new` response that not only provide a list of options, but also a `key` of some kind that is a unique identifier for that selector.
3030

31+
Additionally, we can optionally allow an Agent to mark each option with a semantic category so that Clients can reliably distinguish broadly common option types (e.g. model selector vs session mode selector vs thought/reasoning level), without needing to infer meaning from the option `id` or `name`. This is intended for UX only (e.g. keyboard shortcuts, icons, preferred placement), and MUST NOT be required for correctness.
32+
3133
When the Client receives or sends an update to this selector, it would require both the selector key and the key for the new value.
3234

3335
To start, we could continue offering single-value selectors (dropdowns), but allow for the Agent to decide what those are for.
@@ -61,6 +63,7 @@ Something like an `InitializeResponse` that looks like:
6163
"id": "mode", // this is the unique `key` for communication about which option is being used
6264
"name": "Session Mode", // Human-readable label for the option
6365
"description": "Optional description for the Client to display to the user."
66+
"category": "mode",
6467
"type": "select",
6568
"currentValue": "ask",
6669
"options": [
@@ -79,6 +82,7 @@ Something like an `InitializeResponse` that looks like:
7982
{
8083
"id": "models",
8184
"name": "Model",
85+
"category": "model",
8286
"type": "select",
8387
"currentValue": "ask",
8488
"options": [
@@ -99,6 +103,21 @@ Something like an `InitializeResponse` that looks like:
99103
}
100104
```
101105

106+
### Option category (optional)
107+
108+
Each top-level config option MAY include an optional `category` field. This is intended to help Clients distinguish broadly common selectors and provide a consistent UX (for example, attaching keyboard shortcuts to the first option of a given category).
109+
110+
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.
111+
112+
`category` is semantic metadata and MUST NOT be required for correctness. Clients MUST handle missing or unknown categories gracefully (treat as `other`).
113+
114+
Proposed enum:
115+
116+
- `mode` - Session mode selector
117+
- `model` - Model selector
118+
- `thought_level` - Thought/reasoning level selector
119+
- `other` - Unknown / uncategorized selector
120+
102121
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.
103122

104123
```json

schema/schema.unstable.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,6 +2508,17 @@
25082508
"description": "The _meta property is reserved by ACP to allow clients and agents to attach additional\nmetadata to their interactions. Implementations MUST NOT make assumptions about values at\nthese keys.\n\nSee protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/extensibility)",
25092509
"type": ["object", "null"]
25102510
},
2511+
"category": {
2512+
"anyOf": [
2513+
{
2514+
"$ref": "#/$defs/SessionConfigOptionCategory"
2515+
},
2516+
{
2517+
"type": "null"
2518+
}
2519+
],
2520+
"description": "Optional semantic category for this option (UX only)."
2521+
},
25112522
"description": {
25122523
"description": "Optional description for the Client to display to the user.",
25132524
"type": ["string", "null"]
@@ -2528,6 +2539,31 @@
25282539
"required": ["id", "name"],
25292540
"type": "object"
25302541
},
2542+
"SessionConfigOptionCategory": {
2543+
"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`).",
2544+
"oneOf": [
2545+
{
2546+
"const": "mode",
2547+
"description": "Session mode selector.",
2548+
"type": "string"
2549+
},
2550+
{
2551+
"const": "model",
2552+
"description": "Model selector.",
2553+
"type": "string"
2554+
},
2555+
{
2556+
"const": "thought_level",
2557+
"description": "Thought/reasoning level selector.",
2558+
"type": "string"
2559+
},
2560+
{
2561+
"const": "other",
2562+
"description": "Unknown / uncategorized selector.",
2563+
"type": "string"
2564+
}
2565+
]
2566+
},
25312567
"SessionConfigSelect": {
25322568
"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.",
25332569
"properties": {

src/agent.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,32 @@ impl SessionConfigSelect {
15571557
}
15581558
}
15591559

1560+
/// **UNSTABLE**
1561+
///
1562+
/// This capability is not part of the spec yet, and may be removed or changed at any point.
1563+
///
1564+
/// Semantic category for a session configuration option.
1565+
///
1566+
/// This is intended to help Clients distinguish broadly common selectors (e.g. model selector vs
1567+
/// session mode selector vs thought/reasoning level) for UX purposes (keyboard shortcuts, icons,
1568+
/// placement). It MUST NOT be required for correctness. Clients MUST handle missing or unknown
1569+
/// categories gracefully (treat as `Other`).
1570+
#[cfg(feature = "unstable_session_config_options")]
1571+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
1572+
#[serde(rename_all = "snake_case")]
1573+
#[non_exhaustive]
1574+
pub enum SessionConfigOptionCategory {
1575+
/// Session mode selector.
1576+
Mode,
1577+
/// Model selector.
1578+
Model,
1579+
/// Thought/reasoning level selector.
1580+
ThoughtLevel,
1581+
/// Unknown / uncategorized selector.
1582+
#[serde(other)]
1583+
Other,
1584+
}
1585+
15601586
/// **UNSTABLE**
15611587
///
15621588
/// This capability is not part of the spec yet, and may be removed or changed at any point.
@@ -1589,6 +1615,9 @@ pub struct SessionConfigOption {
15891615
/// Optional description for the Client to display to the user.
15901616
#[serde(default, skip_serializing_if = "Option::is_none")]
15911617
pub description: Option<String>,
1618+
/// Optional semantic category for this option (UX only).
1619+
#[serde(default, skip_serializing_if = "Option::is_none")]
1620+
pub category: Option<SessionConfigOptionCategory>,
15921621
/// Type-specific fields for this configuration option.
15931622
#[serde(flatten)]
15941623
pub kind: SessionConfigKind,
@@ -1613,6 +1642,7 @@ impl SessionConfigOption {
16131642
id: id.into(),
16141643
name: name.into(),
16151644
description: None,
1645+
category: None,
16161646
kind,
16171647
meta: None,
16181648
}
@@ -1638,6 +1668,12 @@ impl SessionConfigOption {
16381668
self
16391669
}
16401670

1671+
#[must_use]
1672+
pub fn category(mut self, category: impl IntoOption<SessionConfigOptionCategory>) -> Self {
1673+
self.category = category.into_option();
1674+
self
1675+
}
1676+
16411677
/// The _meta property is reserved by ACP to allow clients and agents to attach additional
16421678
/// metadata to their interactions. Implementations MUST NOT make assumptions about values at
16431679
/// these keys.

0 commit comments

Comments
 (0)