Skip to content

Commit bab1c4d

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 bab1c4d

File tree

1 file changed

+372
-0
lines changed

1 file changed

+372
-0
lines changed

docs/rfds/session-info-update.mdx

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

0 commit comments

Comments
 (0)