Skip to content

Commit 7375612

Browse files
committed
docs(rfds): address PR feedback on multi-client session attach
Add three features requested by reviewers: - `after_message` history policy with `afterMessageId` for delta sync on reconnect, so clients only replay messages since their last known position (references Message ID RFD / PR agentclientprotocol#536) - `turn_complete` session update broadcast so secondary clients know when the agent finishes a turn - `prompt_received` session update echo so all clients see prompts sent by other controllers Also updates proxy responsibilities, implementation plan, related RFDs list, and revision history.
1 parent 239c369 commit 7375612

1 file changed

Lines changed: 83 additions & 2 deletions

File tree

docs/rfds/multi-client-session-attach.mdx

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This proposal builds on and intersects with several existing draft RFDs:
3232
- **[Agent Extensions via ACP Proxies](./proxy-chains)** The proxy/multiplexer architecture pattern is central to the recommended implementation approach for multi-client sessions
3333
- **[Session List](./session-list)** Discovering existing sessions (prerequisite for attach)
3434
- **[Resuming of existing sessions](./session-resume)** (`session/resume`) Sequential handoff between clients
35+
- **[Message ID](./message-id)** Stable message identifiers enabling `after_message` history replay and correlation of `turn_complete`/`prompt_received` notifications
3536
- **Session Info Update** Real-time metadata propagation (draft)
3637
- **Session Fork** Branching sessions (related but distinct fork creates a copy, attach shares the original) (draft)
3738

@@ -91,8 +92,31 @@ The `historyPolicy` parameter controls what history is replayed on attach:
9192
- `"full"` (default) Replay the complete conversation history, matching the behaviour of `session/load`. Best for IDE and desktop clients.
9293
- `"pending_only"` Replay only events that require action (e.g., pending `request_permission` prompts). Best for notification clients.
9394
- `"none"` No history replay; receive only future `session/update` events. Best for lightweight observer or logging clients.
95+
- `"after_message"` Replay history starting after the message identified by `afterMessageId`. Best for reconnecting clients that already have partial history and only need the delta. Requires the [Message ID RFD](./message-id) to be adopted.
9496

95-
The response follows standard ACP patterns, returning session metadata. When `historyPolicy` is `"none"`, the `history` field is omitted. When `"pending_only"`, only items with `"status": "pending"` are included:
97+
When using `"after_message"`, the client includes an `afterMessageId` field:
98+
99+
```json
100+
{
101+
"jsonrpc": "2.0",
102+
"id": 5,
103+
"method": "session/attach",
104+
"params": {
105+
"sessionId": "sess_abc123def456",
106+
"role": "controller",
107+
"historyPolicy": "after_message",
108+
"afterMessageId": "ea87d0e7-beb8-484a-a404-94a30b78a5a8",
109+
"clientInfo": {
110+
"name": "notification-dashboard",
111+
"version": "1.0.0"
112+
}
113+
}
114+
}
115+
```
116+
117+
If the proxy does not recognise the provided `afterMessageId` (e.g., the message has been evicted from its buffer), it SHOULD fall back to `"full"` replay and indicate this in the response via the `historyPolicy` field.
118+
119+
The response follows standard ACP patterns, returning session metadata. When `historyPolicy` is `"none"`, the `history` field is omitted. When `"pending_only"`, only items with `"status": "pending"` are included. When `"after_message"`, only events after the specified message are included:
96120

97121
```json
98122
{
@@ -188,6 +212,59 @@ When an agent emits `request_permission`, it is broadcast to **all connected con
188212
}
189213
```
190214

215+
### Turn completion notification
216+
217+
When a controller sends a `session/prompt` and the agent finishes processing that turn, the proxy broadcasts a `turn_complete` notification to all connected clients. This is essential for multiplexed clients without it, secondary clients have no reliable way to know when the agent has finished responding and is ready for the next prompt.
218+
219+
```json
220+
{
221+
"jsonrpc": "2.0",
222+
"method": "session/update",
223+
"params": {
224+
"sessionId": "sess_abc123def456",
225+
"update": {
226+
"type": "turn_complete",
227+
"stopReason": "end_turn",
228+
"messageId": "ea87d0e7-beb8-484a-a404-94a30b78a5a8"
229+
}
230+
}
231+
}
232+
```
233+
234+
The `stopReason` field mirrors the `stopReason` from the `session/prompt` response (e.g., `"end_turn"`, `"max_tokens"`). The optional `messageId` field references the final agent message of the turn (requires the [Message ID RFD](./message-id)).
235+
236+
Note: The primary client (the one that sent the prompt) already receives this signal via the `session/prompt` response. The `turn_complete` notification is for all *other* connected clients that only see `session/update` events.
237+
238+
### Prompt echoing
239+
240+
When a controller sends a `session/prompt`, the proxy echoes that prompt to all **other** connected clients via a `prompt_received` session update. Without this, secondary clients would see the agent's response stream without knowing what question or instruction triggered it.
241+
242+
```json
243+
{
244+
"jsonrpc": "2.0",
245+
"method": "session/update",
246+
"params": {
247+
"sessionId": "sess_abc123def456",
248+
"update": {
249+
"type": "prompt_received",
250+
"messageId": "4c12d49b-729c-4086-bfed-5b82e9a53400",
251+
"prompt": [
252+
{
253+
"type": "text",
254+
"text": "Add authentication to the API"
255+
}
256+
],
257+
"sentBy": {
258+
"name": "Claude Code",
259+
"version": "1.0.0"
260+
}
261+
}
262+
}
263+
}
264+
```
265+
266+
The prompt is echoed *before* the agent begins streaming its response, so clients can display the user message in the correct position in the conversation. The `sentBy` field identifies which client sent the prompt, and the optional `messageId` allows clients to correlate the prompt with subsequent response chunks (requires the [Message ID RFD](./message-id)).
267+
191268
### Transport considerations
192269

193270
The current stdio transport is inherently single-client. Multi-client attach requires a **network-capable transport**. We propose this works over:
@@ -212,7 +289,10 @@ The proxy:
212289
- Fans out `session/update` notifications to all connected clients
213290
- Broadcasts `request_permission` to all controllers
214291
- Routes the first response back to the agent
292+
- Echoes `session/prompt` from one controller to all other clients as `prompt_received`
293+
- Broadcasts `turn_complete` to all non-prompting clients when a turn finishes
215294
- Tracks client roles and connection state
295+
- Buffers message history for `after_message` replay on reconnect
216296

217297
This means existing agents work **unchanged** the proxy handles all multi-client logic. This approach aligns perfectly with the proxy-chains architecture, where proxies sit between clients and agents to extend functionality without modifying the core agent implementation.
218298

@@ -285,7 +365,7 @@ With multi-client session attach:
285365
1. Add `session/attach` and `session/detach` methods to schema.json
286366
2. Define `attach` capability in `sessionCapabilities` with a `roles` field
287367
3. Define client roles (controller/observer) and their semantics
288-
4. Specify `permission_resolved` and `client_disconnected` session update variants
368+
4. Specify `permission_resolved`, `client_disconnected`, `turn_complete`, and `prompt_received` session update variants
289369
5. Document interaction with existing `session/load` and `session/resume`
290370

291371
### Phase 2: Reference proxy implementation
@@ -411,4 +491,5 @@ The typical flow for a dashboard client would be:
411491

412492
## Revision history
413493

494+
- **2026-02-24**: Added `after_message` history policy with `afterMessageId` for delta sync on reconnect; added `turn_complete` notification for secondary clients; added `prompt_received` echoing so all clients see prompts sent by other controllers
414495
- **2026-02-18**: Initial proposal

0 commit comments

Comments
 (0)