Skip to content

Commit 92e0061

Browse files
authored
feat(schema): Stabilize optional message IDs (#1372)
1 parent 3cc4e29 commit 92e0061

17 files changed

Lines changed: 176 additions & 73 deletions

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ unstable = [
2929
"unstable_plan_operations",
3030
"unstable_session_fork",
3131
"unstable_end_turn_token_usage",
32-
"unstable_message_id",
3332
"unstable_boolean_config",
3433
]
3534
# Protocol v2 is intentionally NOT part of the `unstable` umbrella.
@@ -46,7 +45,6 @@ unstable_nes = []
4645
unstable_plan_operations = []
4746
unstable_session_fork = []
4847
unstable_end_turn_token_usage = []
49-
unstable_message_id = []
5048
unstable_boolean_config = []
5149

5250
# Emit `tracing::warn!` events when `VecSkipError` drops a malformed list

docs/docs.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@
209209
},
210210
{
211211
"group": "Preview",
212-
"pages": ["rfds/rust-sdk-v1", "rfds/message-id"]
212+
"pages": ["rfds/rust-sdk-v1"]
213213
},
214214
{
215215
"group": "Completed",
@@ -218,6 +218,7 @@
218218
"rfds/session-config-options",
219219
"rfds/session-list",
220220
"rfds/session-usage",
221+
"rfds/message-id",
221222
"rfds/session-delete",
222223
"rfds/session-info-update",
223224
"rfds/meta-propagation",

docs/protocol/v1/draft/schema.mdx

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,11 +3501,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d
35013501
A single item of content
35023502
</ResponseField>
35033503
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
3504-
**UNSTABLE**
3505-
3506-
This capability is not part of the spec yet, and may be removed or changed at any point.
3507-
3508-
A unique identifier for the message this chunk belongs to.
3504+
A unique identifier for the message this chunk belongs to.
35093505

35103506
All chunks belonging to the same message share the same `messageId`.
35113507
A change in `messageId` indicates a new message has started.
@@ -7143,11 +7139,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d
71437139
A single item of content
71447140
</ResponseField>
71457141
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
7146-
**UNSTABLE**
7147-
7148-
This capability is not part of the spec yet, and may be removed or changed at any point.
7149-
7150-
A unique identifier for the message this chunk belongs to.
7142+
A unique identifier for the message this chunk belongs to.
71517143

71527144
All chunks belonging to the same message share the same `messageId`.
71537145
A change in `messageId` indicates a new message has started.
@@ -7177,11 +7169,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d
71777169
A single item of content
71787170
</ResponseField>
71797171
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
7180-
**UNSTABLE**
7181-
7182-
This capability is not part of the spec yet, and may be removed or changed at any point.
7183-
7184-
A unique identifier for the message this chunk belongs to.
7172+
A unique identifier for the message this chunk belongs to.
71857173

71867174
All chunks belonging to the same message share the same `messageId`.
71877175
A change in `messageId` indicates a new message has started.
@@ -7211,11 +7199,7 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/d
72117199
A single item of content
72127200
</ResponseField>
72137201
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
7214-
**UNSTABLE**
7215-
7216-
This capability is not part of the spec yet, and may be removed or changed at any point.
7217-
7218-
A unique identifier for the message this chunk belongs to.
7202+
A unique identifier for the message this chunk belongs to.
72197203

72207204
All chunks belonging to the same message share the same `messageId`.
72217205
A change in `messageId` indicates a new message has started.

docs/protocol/v1/prompt-turn.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ The Agent then reports text responses from the model:
154154
"sessionId": "sess_abc123def456",
155155
"update": {
156156
"sessionUpdate": "agent_message_chunk",
157+
"messageId": "msg_agent_c42b9",
157158
"content": {
158159
"type": "text",
159160
"text": "I'll analyze your code for potential issues. Let me examine it..."
@@ -163,6 +164,10 @@ The Agent then reports text responses from the model:
163164
}
164165
```
165166

167+
#### Message IDs
168+
169+
The Agent **MAY** include an opaque, unique `messageId` on message chunks. Chunks with the same `messageId` belong to the same message; a changed `messageId` indicates a new message.
170+
166171
If the model requested tool calls, these are also reported immediately:
167172

168173
```json

docs/protocol/v1/schema.mdx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,13 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
19071907
<ResponseField name="content" type={<a href="#contentblock">ContentBlock</a>} required>
19081908
A single item of content
19091909
</ResponseField>
1910+
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
1911+
A unique identifier for the message this chunk belongs to.
1912+
1913+
All chunks belonging to the same message share the same `messageId`.
1914+
A change in `messageId` indicates a new message has started.
1915+
1916+
</ResponseField>
19101917

19111918
## <span class="font-mono">Cost</span>
19121919

@@ -2512,6 +2519,12 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
25122519
Human-readable name identifying this MCP server.
25132520
</ResponseField>
25142521

2522+
## <span class="font-mono">MessageId</span>
2523+
2524+
Unique identifier for a message within a session.
2525+
2526+
**Type:** `string`
2527+
25152528
## <span class="font-mono">PermissionOption</span>
25162529

25172530
An option presented to the user when requesting permission.
@@ -3335,6 +3348,13 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
33353348
</ResponseField>
33363349
<ResponseField name="content" type={<a href="#contentblock">ContentBlock</a>} required>
33373350
A single item of content
3351+
</ResponseField>
3352+
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
3353+
A unique identifier for the message this chunk belongs to.
3354+
3355+
All chunks belonging to the same message share the same `messageId`.
3356+
A change in `messageId` indicates a new message has started.
3357+
33383358
</ResponseField>
33393359
<ResponseField name="sessionUpdate" type={"string"} required>
33403360
The discriminator value. Must be `"user_message_chunk"`.
@@ -3358,6 +3378,13 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
33583378
</ResponseField>
33593379
<ResponseField name="content" type={<a href="#contentblock">ContentBlock</a>} required>
33603380
A single item of content
3381+
</ResponseField>
3382+
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
3383+
A unique identifier for the message this chunk belongs to.
3384+
3385+
All chunks belonging to the same message share the same `messageId`.
3386+
A change in `messageId` indicates a new message has started.
3387+
33613388
</ResponseField>
33623389
<ResponseField name="sessionUpdate" type={"string"} required>
33633390
The discriminator value. Must be `"agent_message_chunk"`.
@@ -3381,6 +3408,13 @@ See protocol docs: [Extensibility](https://agentclientprotocol.com/protocol/v1/e
33813408
</ResponseField>
33823409
<ResponseField name="content" type={<a href="#contentblock">ContentBlock</a>} required>
33833410
A single item of content
3411+
</ResponseField>
3412+
<ResponseField name="messageId" type={<><span><a href="#messageid">MessageId</a></span><span> | null</span></>} >
3413+
A unique identifier for the message this chunk belongs to.
3414+
3415+
All chunks belonging to the same message share the same `messageId`.
3416+
A change in `messageId` indicates a new message has started.
3417+
33843418
</ResponseField>
33853419
<ResponseField name="sessionUpdate" type={"string"} required>
33863420
The discriminator value. Must be `"agent_thought_chunk"`.

docs/protocol/v1/session-setup.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ For example, a user message from the conversation history:
143143
"sessionId": "sess_789xyz",
144144
"update": {
145145
"sessionUpdate": "user_message_chunk",
146+
"messageId": "msg_user_8f7a1",
146147
"content": {
147148
"type": "text",
148149
"text": "What's the capital of France?"
@@ -162,6 +163,7 @@ Followed by the agent's response:
162163
"sessionId": "sess_789xyz",
163164
"update": {
164165
"sessionUpdate": "agent_message_chunk",
166+
"messageId": "msg_agent_c42b9",
165167
"content": {
166168
"type": "text",
167169
"text": "The capital of France is Paris."
@@ -171,6 +173,8 @@ Followed by the agent's response:
171173
}
172174
```
173175

176+
If the Agent provides message IDs during replay, each `messageId` is an opaque, unique identifier for the replayed message.
177+
174178
When **all** the conversation entries have been streamed to the Client, the Agent **MUST** respond to the original `session/load` request.
175179

176180
```json

docs/protocol/v2/prompt-turn.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ The Agent then reports text responses from the model:
158158
"sessionId": "sess_abc123def456",
159159
"update": {
160160
"sessionUpdate": "agent_message_chunk",
161+
"messageId": "msg_agent_c42b9",
161162
"content": {
162163
"type": "text",
163164
"text": "I'll analyze your code for potential issues. Let me examine it..."
@@ -167,6 +168,10 @@ The Agent then reports text responses from the model:
167168
}
168169
```
169170

171+
#### Message IDs
172+
173+
The Agent **MUST** include an opaque `messageId` on message chunks. Chunks with the same `messageId` belong to the same message; a changed `messageId` indicates a new message.
174+
170175
If the model requested tool calls, these are also reported immediately:
171176

172177
```json

docs/protocol/v2/session-setup.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ For example, a user message from the conversation history:
147147
"sessionId": "sess_789xyz",
148148
"update": {
149149
"sessionUpdate": "user_message_chunk",
150+
"messageId": "msg_user_8f7a1",
150151
"content": {
151152
"type": "text",
152153
"text": "What's the capital of France?"
@@ -166,6 +167,7 @@ Followed by the agent's response:
166167
"sessionId": "sess_789xyz",
167168
"update": {
168169
"sessionUpdate": "agent_message_chunk",
170+
"messageId": "msg_agent_c42b9",
169171
"content": {
170172
"type": "text",
171173
"text": "The capital of France is Paris."
@@ -175,6 +177,8 @@ Followed by the agent's response:
175177
}
176178
```
177179

180+
During replay, the Agent **MUST** include an opaque, unique `messageId` for each replayed message.
181+
178182
When **all** the conversation entries have been streamed to the Client, the Agent **MUST** respond to the original `session/load` request.
179183

180184
```json

docs/rfds/message-id.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ Add a `messageId` field to `AgentMessageChunk`, `UserMessageChunk`, and `AgentTh
7070

7171
### Proposed Structure
7272

73-
The `session/prompt` response does not include a message ID. In v1, there won't be a message ID for user-submitted messages. In v2, the agent will replay the message and attach the appropriate message ID to the user message.
73+
The `session/prompt` request and response do not include a message ID. Clients do not create protocol message IDs. If the Agent emits the accepted user message through `session/update`, it generates and attaches the appropriate message ID to that user message.
7474

7575
If the Agent sends `user_message_chunk` updates (e.g., during `session/load`), it uses the user message ID:
7676

@@ -282,6 +282,7 @@ Future RFDs may propose extending `messageId` to other update types if use cases
282282

283283
## Revision history
284284

285+
- **2026-06-05**: Moved to Completed and stabilized optional v1 `messageId` in the stable protocol artifacts
285286
- **2026-06-03**: Moved the v1 portion of the RFD to Preview while v2-specific behavior remains part of the v2 draft work
286287
- **2026-06-03**: Moved the RFD out of the v2 Draft group while keeping v2-specific behavior; added a dedicated `MessageId` type, and made v2 require message IDs on streamed message chunks while v1 keeps optional message IDs for compatibility
287288
- **2026-06-02**: Updated the proposal so message IDs are Agent-generated only, removed client-provided prompt IDs and prompt response acknowledgments, and removed the UUID requirement in favor of opaque strings

docs/rfds/updates.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ rss: true
66

77
This page tracks lifecycle changes for ACP Requests for Dialog. For broader ACP announcements, see [Updates](/updates).
88

9+
<Update label="June 5, 2026" tags={["Completed"]}>
10+
## Message ID RFD moves to Completed
11+
12+
The RFD for adding agent-generated `messageId` fields to streamed message chunks has been stabilized and is now part of the protocol. In v1, message IDs are optional on message chunks for compatibility; in v2, they are required. Please review the [documentation](/protocol/v1/prompt-turn#message-ids) for more information.
13+
14+
</Update>
15+
916
<Update label="June 5, 2026" tags={["Completed"]}>
1017
## Session Context Size and Cost RFD moves to Completed
1118

0 commit comments

Comments
 (0)