Skip to content

Commit e8d18af

Browse files
author
Sergey Ignatov
committed
Add RFD for session info update notification
- Adds session_info_update variant to SessionUpdate - Enables real-time session metadata updates (title, _meta) - Follows existing notification pattern (available_commands_update, current_mode_update) - All fields optional for partial updates - Must stay aligned with SessionInfo structure
1 parent 21a8206 commit e8d18af

File tree

1 file changed

+362
-0
lines changed

1 file changed

+362
-0
lines changed

docs/rfds/session-info-update.mdx

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
---
2+
title: "Session Info Update"
3+
---
4+
5+
- Author(s): [@ignatov](https://github.com/ignatov)
6+
- Champion: [@benbrandt](https://github.com/benbrandt)
7+
8+
## Elevator pitch
9+
10+
Add a `session_info_update` variant to the existing `SessionUpdate` notification type that allows agents to update session metadata (particularly title/name), enabling dynamic session identification in client UIs without requiring a new endpoint.
11+
12+
## Status quo
13+
14+
Currently, the ACP protocol provides session management through `session/new`, `session/load`, and `session/list` (unstable). The `session/list` endpoint returns `SessionInfo` objects that include an optional `title` field for displaying session names in client UIs.
15+
16+
However, there are several problems:
17+
18+
1. **No way to communicate title updates** - The `title` field in `SessionInfo` is static in the list response. Agents cannot dynamically update it as the session evolves.
19+
20+
2. **No mechanism for real-time metadata updates** - Unlike commands (`available_commands_update`) or modes (`current_mode_update`), there's no way for agents to:
21+
- Auto-generate titles after the first meaningful exchange
22+
- Update titles as conversation context shifts
23+
- Provide custom metadata that reflects session state
24+
25+
3. **Inconsistent with protocol patterns** - Other dynamic session properties use `session/update` notifications (commands, modes, plans), but metadata has no equivalent mechanism.
26+
27+
The current workaround is for clients to:
28+
- Maintain their own title mapping (doesn't persist or sync)
29+
- Only show static metadata from `session/list`
30+
- Have no way to receive agent-generated titles in real-time
31+
32+
## What we propose to do about it
33+
34+
Add a new `session_info_update` variant to the existing `SessionUpdate` discriminated union that allows agents to notify clients about metadata changes. This update would:
35+
36+
1. **Follow the existing `SessionUpdate` pattern**:
37+
- Uses the same notification mechanism as `available_commands_update`, `current_mode_update`, etc.
38+
- Sent via `session/update` method
39+
- Agent-initiated, no request/response needed
40+
41+
2. **Align with `SessionInfo` structure**:
42+
- Contains the same fields as `SessionInfo` from `session/list`
43+
- All fields are optional (partial updates)
44+
- Enables incremental metadata updates
45+
- **Important**: `SessionInfoUpdate` must stay aligned with `SessionInfo` - when new fields are added to `SessionInfo`, they should also be added to `SessionInfoUpdate` as optional fields
46+
47+
3. **Support common use cases**:
48+
- Agent auto-generates title after first prompt
49+
- Agent updates title as conversation context shifts
50+
- Agent provides custom metadata for client features (tags, status, etc.)
51+
- User explicitly requests title change (agent responds with update notification)
52+
53+
4. **Integrate seamlessly**:
54+
- No new capability required (uses existing `session/update` mechanism)
55+
- Compatible with `session/list` - metadata should persist and be reflected in list responses
56+
- Works during active sessions
57+
58+
### Notification Structure
59+
60+
The agent sends a `session/update` notification with `sessionUpdate: "session_info_update"`:
61+
62+
```json
63+
{
64+
"jsonrpc": "2.0",
65+
"method": "session/update",
66+
"params": {
67+
"sessionId": "sess_abc123def456",
68+
"update": {
69+
"sessionUpdate": "session_info_update",
70+
"title": "Implement user authentication",
71+
"_meta": {
72+
"tags": ["feature", "auth"],
73+
"priority": "high"
74+
}
75+
}
76+
}
77+
}
78+
```
79+
80+
### SessionInfoUpdate Type
81+
82+
The update type mirrors `SessionInfo` but with all fields optional:
83+
84+
```typescript
85+
{
86+
sessionUpdate: "session_info_update",
87+
title?: string | null, // Update or clear the title
88+
updatedAt?: string | null, // ISO 8601 timestamp (usually agent sets this)
89+
_meta?: object | null // Custom metadata (merged with existing)
90+
}
91+
```
92+
93+
**Note:** `sessionId` and `cwd` are NOT included since:
94+
- `sessionId` is already in the notification's `params`
95+
- `cwd` is immutable and set during `session/new`
96+
97+
### Examples
98+
99+
#### Update title and working directory metadata
100+
101+
After the user sends their first meaningful prompt, the agent can generate and send a title along with metadata about the working directory:
102+
103+
```json
104+
{
105+
"jsonrpc": "2.0",
106+
"method": "session/update",
107+
"params": {
108+
"sessionId": "sess_abc123def456",
109+
"update": {
110+
"sessionUpdate": "session_info_update",
111+
"title": "Debug authentication timeout",
112+
"_meta": {
113+
"projectName": "api-server",
114+
"branch": "main"
115+
}
116+
}
117+
}
118+
}
119+
```
120+
121+
#### Update title as conversation evolves
122+
123+
As the conversation shifts focus:
124+
125+
```json
126+
{
127+
"jsonrpc": "2.0",
128+
"method": "session/update",
129+
"params": {
130+
"sessionId": "sess_abc123def456",
131+
"update": {
132+
"sessionUpdate": "session_info_update",
133+
"title": "Debug authentication timeout → Add retry logic"
134+
}
135+
}
136+
}
137+
```
138+
139+
## Shiny future
140+
141+
Once this feature exists:
142+
143+
1. **Dynamic session identification** - Agents can:
144+
- Auto-generate meaningful titles from conversation content
145+
- Update titles as conversations evolve
146+
- Provide rich metadata for better organization
147+
148+
2. **Improved client UIs** - Clients can:
149+
- Show real-time title updates in session lists
150+
- Display session status, tags, or other metadata
151+
- Update UI immediately without polling `session/list`
152+
153+
3. **Consistent protocol patterns** - Session metadata updates work like other dynamic session properties (commands, modes), creating a unified model
154+
155+
4. **Bidirectional workflows** - Combined with a potential future request method:
156+
- User renames session → client sends request → agent acknowledges with `session_info_update` notification
157+
- Agent auto-generates title → sends `session_info_update` notification → client displays it
158+
159+
5. **Enhanced use cases**:
160+
- Session templates that auto-set titles and tags
161+
- Progress indicators via `_meta`
162+
- Integration with external tools via metadata
163+
- Rich session browsing and filtering
164+
165+
## Implementation details and plan
166+
167+
### Phase 1: Schema Changes
168+
169+
1. **Update `schema.unstable.json`**:
170+
- Add `SessionInfoUpdate` type definition
171+
- Add new variant to `SessionUpdate` oneOf array
172+
- Align fields with `SessionInfo` but make all optional
173+
174+
```json
175+
{
176+
"SessionInfoUpdate": {
177+
"description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUpdate to session metadata. All fields are optional to support partial updates.",
178+
"properties": {
179+
"_meta": {
180+
"description": "Extension point for implementations"
181+
},
182+
"title": {
183+
"description": "Human-readable title for the session",
184+
"type": ["string", "null"]
185+
},
186+
"updatedAt": {
187+
"description": "ISO 8601 timestamp of last activity",
188+
"type": ["string", "null"]
189+
}
190+
},
191+
"type": "object"
192+
}
193+
}
194+
```
195+
196+
Add to `SessionUpdate` oneOf:
197+
198+
```json
199+
{
200+
"allOf": [
201+
{
202+
"$ref": "#/$defs/SessionInfoUpdate"
203+
}
204+
],
205+
"description": "**UNSTABLE**\n\nThis capability is not part of the spec yet, and may be removed or changed at any point.\n\nUpdate to session metadata",
206+
"properties": {
207+
"sessionUpdate": {
208+
"const": "session_info_update",
209+
"type": "string"
210+
}
211+
},
212+
"required": ["sessionUpdate"],
213+
"type": "object"
214+
}
215+
```
216+
217+
### Phase 2: Protocol Documentation
218+
219+
2. **Create documentation** in `/docs/protocol/session-metadata.mdx`:
220+
- Explain the notification mechanism
221+
- Provide examples of common patterns
222+
- Document merge semantics for `_meta`
223+
- Clarify relationship with `session/list`
224+
225+
3. **Update existing docs**:
226+
- Reference in `/docs/protocol/session-setup.mdx`
227+
- Add to `/docs/protocol/prompt-turn.mdx` session update section
228+
229+
### Phase 3: SDK Implementation
230+
231+
4. **Implement in Rust SDK**:
232+
- Add `SessionInfoUpdate` struct
233+
- Add variant to `SessionUpdate` enum
234+
- Update notification handling in agent and client traits
235+
- Add helper methods for common patterns
236+
237+
5. **Implement in TypeScript SDK** (if applicable):
238+
- Add TypeScript types
239+
- Update notification handlers
240+
- Add helper methods
241+
242+
### Phase 4: Example Implementation
243+
244+
6. **Update example agents**:
245+
- Demonstrate auto-generating title from first prompt
246+
- Show updating metadata during session
247+
- Example of using `_meta` for custom fields
248+
249+
### Compatibility Considerations
250+
251+
- **Fully backward compatible**: This adds a new notification variant to an existing mechanism
252+
- **No breaking changes**: Existing agents and clients continue working
253+
- **Graceful degradation**: Clients that don't handle this notification simply ignore it
254+
- **No new capability needed**: Uses existing `session/update` infrastructure
255+
256+
### Design Decisions
257+
258+
**Why notification instead of request/response?**
259+
- Consistent with existing `SessionUpdate` patterns (`available_commands_update`, `current_mode_update`)
260+
- Agents initiate updates based on conversation state
261+
- Simpler than bidirectional request/response
262+
- Enables real-time updates without polling
263+
264+
**Why make all fields optional?**
265+
- Allows partial updates (only update what changed)
266+
- More efficient - don't resend unchanged data
267+
- Flexible for different use cases
268+
- Mirrors partial update patterns in other protocols
269+
270+
**Why not include `sessionId` and `cwd` in the update?**
271+
- `sessionId` is already in the notification params
272+
- `cwd` is immutable (set in `session/new`, never changes)
273+
- Keeps update focused on mutable metadata
274+
275+
**How do `_meta` updates work?**
276+
- **Merge semantics**: New `_meta` fields are merged with existing ones
277+
- To clear a specific field: `"_meta": { "fieldName": null }`
278+
- To clear all custom metadata: `"_meta": null`
279+
280+
### Security Considerations
281+
282+
- **No additional security concerns**: Uses existing session authentication
283+
- **Input validation**:
284+
- Agents should validate title length (recommend 500 chars max)
285+
- Sanitize metadata to prevent injection
286+
- Validate `_meta` structure based on agent requirements
287+
- **Resource limits**: Agents should limit update frequency and metadata size
288+
289+
## Frequently asked questions
290+
291+
### Why not create a new endpoint like `session/update-metadata`?
292+
293+
The notification pattern is more appropriate because:
294+
1. **Consistency**: Other dynamic session properties (commands, modes) use notifications
295+
2. **Agent-initiated**: Agents typically generate titles from conversation context
296+
3. **Real-time**: No request/response overhead, updates flow naturally
297+
4. **Simpler**: Reuses existing `session/update` infrastructure
298+
299+
### How does this work with `session/list`?
300+
301+
The updated metadata should persist and be reflected in subsequent `session/list` calls. The notification provides real-time updates to connected clients, while `session/list` provides the current state for discovery.
302+
303+
### Can clients trigger title updates?
304+
305+
This RFD covers agent-initiated updates. Client-initiated updates could work by:
306+
1. Client sends a prompt asking to rename session
307+
2. Agent updates its internal state
308+
3. Agent sends `session_info_update` notification
309+
4. Client receives and displays the update
310+
311+
A future RFD could add explicit request/response for this if needed.
312+
313+
### What if multiple updates are sent in quick succession?
314+
315+
Clients should apply updates incrementally in order. Each notification represents a delta, not a full replacement (except for fields explicitly set to `null`).
316+
317+
### Should `updatedAt` be automatically set by the agent?
318+
319+
Yes, typically the agent should update this timestamp when any session activity occurs, not just when metadata changes. However, including it in `session_info_update` allows agents to explicitly control it if needed.
320+
321+
### Do agents need a new capability for this?
322+
323+
No. All agents that support `session/update` notifications can send this variant. Clients that don't recognize it will ignore it (standard JSON-RPC behavior).
324+
325+
### How does this interact with `session/fork`?
326+
327+
When forking, the parent session's metadata could be copied (implementation choice). The forked session would have its own `sessionId` and could receive separate `session_info_update` notifications.
328+
329+
### What happens if title is too long?
330+
331+
This is an implementation choice. Agents MAY:
332+
- Truncate long titles
333+
- Reject updates (though this is a notification, so no error response)
334+
- Set a reasonable limit (e.g., 500 characters)
335+
336+
Clients SHOULD handle long titles gracefully (truncate in UI, show tooltip, etc.).
337+
338+
### Can `_meta` have nested objects?
339+
340+
Yes, `_meta` is an arbitrary object. Agents define its structure. The merge semantics apply recursively - nested objects are merged, not replaced entirely.
341+
342+
### What alternative approaches did you consider, and why did you settle on this one?
343+
344+
Several alternatives were considered:
345+
346+
1. **Add a new request/response endpoint (`session/update-metadata`)** - This would be inconsistent with how other dynamic session properties (commands, modes) are handled. The notification pattern is more appropriate for agent-initiated updates.
347+
348+
2. **Add title parameter to `session/new`** - Only allows setting title at creation time, doesn't support dynamic updates as the conversation evolves.
349+
350+
3. **Client-side only metadata tracking** - Doesn't work across devices, can get out of sync, and duplicates storage. This is the current workaround and has significant limitations.
351+
352+
4. **Generic `session/update` request for all properties** - Could conflict with immutable properties (sessionId, cwd) and has unclear semantics about what can be updated.
353+
354+
The proposed notification-based approach:
355+
- **Consistent** with existing protocol patterns
356+
- **Flexible** for both agent-initiated and user-initiated updates
357+
- **Simple** to implement and understand
358+
- **Extensible** via `_meta` field
359+
360+
## Revision history
361+
362+
- **2025-11-28**: Initial draft proposal

0 commit comments

Comments
 (0)