@mhome/conversation-protocol 3.3.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +20 -0
  2. package/fixtures/control-get.request.json +5 -0
  3. package/fixtures/control-get.response.json +24 -0
  4. package/fixtures/control.event.json +28 -0
  5. package/fixtures/enqueue.response.json +25 -3
  6. package/fixtures/execution/enqueue.v1.json +30 -278
  7. package/fixtures/execution/observation.v1.json +3 -3
  8. package/fixtures/interaction-answer.response.json +25 -3
  9. package/fixtures/interaction.response.json +24 -2
  10. package/fixtures/live.event.json +4 -2
  11. package/fixtures/progress-planning.event.json +4 -2
  12. package/fixtures/progress-thinking.event.json +4 -2
  13. package/fixtures/progress-tool-scheduled.event.json +8 -2
  14. package/fixtures/progress-tool-started.event.json +5 -2
  15. package/fixtures/progress-waiting.event.json +4 -2
  16. package/fixtures/queue-reorder.response.json +24 -2
  17. package/fixtures/request-cancel-waiting.response.json +26 -4
  18. package/fixtures/request-cancel.response.json +26 -4
  19. package/fixtures/session-start.response.json +39 -9
  20. package/fixtures/system-failed.event.json +5 -2
  21. package/fixtures/thread-archive.response.json +36 -5
  22. package/fixtures/thread-create.response.json +35 -5
  23. package/fixtures/thread-load.response.json +26 -5
  24. package/fixtures/thread-rotate.response.json +45 -6
  25. package/fixtures/turn-submit-waiting.response.json +28 -6
  26. package/fixtures/turn-submit.response.json +27 -5
  27. package/manifest/targets.v1.json +2 -1
  28. package/package.json +1 -1
  29. package/protocol.json +1 -1
  30. package/schema/conversation-frame.v2.schema.json +440 -157
  31. package/schema/execution/envelope.v1.schema.json +8 -27
package/README.md CHANGED
@@ -50,3 +50,23 @@ adopted by Lion and Cloud together before deployment.
50
50
  ### Strict execution envelope decoding
51
51
 
52
52
  Execution commands, events, facade responses and their typed nested objects reject undeclared fields, including null-valued unknown fields. Opaque JSON inputs/results and model continuation payloads remain extensible; known optional null fields remain accepted. Enforcement lives on the typed DTOs as well as the wire entry point because Serde's internally tagged enum buffering bypasses an outer `serde_ignored` observer. Tagged unit variants explicitly require an empty remaining map. This restores the existing wire-v1 contract without changing its message shape or major version.
53
+
54
+ ## Disposable execution presentation
55
+
56
+ `assistant.preview`, `run.progress`, and `run.system_failed` are best-effort live
57
+ presentation. They are not replayed by `thread/load`, which has no `live` field.
58
+ Each event replaces its display slot completely; preview text never appends and
59
+ is capped by the host at 8,192 Unicode characters. Clients retain at most one
60
+ event per slot, scoped to the active request and `baseSnapshotVersion`.
61
+
62
+ `sequence` is assigned by the execution owner, may contain gaps, and only rejects
63
+ older or duplicate events in the same slot. A missing presentation event must not
64
+ trigger history resynchronization. A new snapshot generation resets ordering;
65
+ terminal or pending-interaction control clears presentation. Joining or reconnecting
66
+ starts from durable history/control and future live events, with a generic running
67
+ indicator until a new presentation arrives.
68
+
69
+ Final replies, failures, cancellations, queue state, and actionable user
70
+ confirmations remain durable. Snapshot deltas keep their existing contiguous
71
+ version/recovery rules. Agent checkpoints and billing are independent of live
72
+ presentation delivery.
@@ -0,0 +1,5 @@
1
+ {
2
+ "target": "/chat/control/get",
3
+ "direction": "request",
4
+ "body": {}
5
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "target": "/chat/control/get",
3
+ "direction": "response",
4
+ "body": {
5
+ "surfaceId": "cs1:cp:dXNlcg",
6
+ "version": "00000000000000000001:00000000000000000001",
7
+ "activeThread": {
8
+ "threadId": "thread-2",
9
+ "title": "New conversation",
10
+ "state": "active",
11
+ "createdAt": "2026-08-22T00:00:00Z",
12
+ "updatedAt": "2026-08-22T00:00:00Z",
13
+ "archivedAt": null,
14
+ "purgeAfter": null
15
+ },
16
+ "activeRun": null,
17
+ "pendingInteraction": null,
18
+ "queue": {
19
+ "queueVersion": 0,
20
+ "items": []
21
+ },
22
+ "historyVersion": 0
23
+ }
24
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "target": "/chat/event",
3
+ "direction": "event",
4
+ "body": {
5
+ "type": "control.updated",
6
+ "surfaceId": "cs1:cp:dXNlcg",
7
+ "data": {
8
+ "surfaceId": "cs1:cp:dXNlcg",
9
+ "version": "00000000000000000001:00000000000000000001",
10
+ "activeThread": {
11
+ "threadId": "thread-2",
12
+ "title": "New conversation",
13
+ "state": "active",
14
+ "createdAt": "2026-08-22T00:00:00Z",
15
+ "updatedAt": "2026-08-22T00:00:00Z",
16
+ "archivedAt": null,
17
+ "purgeAfter": null
18
+ },
19
+ "activeRun": null,
20
+ "pendingInteraction": null,
21
+ "queue": {
22
+ "queueVersion": 0,
23
+ "items": []
24
+ },
25
+ "historyVersion": 0
26
+ }
27
+ }
28
+ }
@@ -2,8 +2,30 @@
2
2
  "target": "/chat/message/enqueue",
3
3
  "direction": "response",
4
4
  "body": {
5
- "requestId": "request-1",
6
- "disposition": "queued",
7
- "queueVersion": 4
5
+ "receipt": {
6
+ "requestId": "request-1",
7
+ "disposition": "queued",
8
+ "queueVersion": 4
9
+ },
10
+ "control": {
11
+ "surfaceId": "cs1:cp:dXNlcg",
12
+ "version": "00000000000000000001:00000000000000000001",
13
+ "activeThread": {
14
+ "threadId": "thread-2",
15
+ "title": "New conversation",
16
+ "state": "active",
17
+ "createdAt": "2026-08-22T00:00:00Z",
18
+ "updatedAt": "2026-08-22T00:00:00Z",
19
+ "archivedAt": null,
20
+ "purgeAfter": null
21
+ },
22
+ "activeRun": null,
23
+ "pendingInteraction": null,
24
+ "queue": {
25
+ "queueVersion": 0,
26
+ "items": []
27
+ },
28
+ "historyVersion": 0
29
+ }
8
30
  }
9
31
  }
@@ -59,288 +59,40 @@
59
59
  "scope_integrations": "scope-integrations-1"
60
60
  },
61
61
  "llm_plan": {
62
- "routes": [
63
- {
64
- "use_case": "chat",
65
- "model_mode": "auto",
66
- "revision": "1700000000000",
67
- "route": {
68
- "backend": "openrouter",
69
- "profile": "cloud_openrouter",
70
- "model": "openai/gpt-5.4-mini",
71
- "provider_preferences": [
72
- "OpenAI"
62
+ "model_mode": "auto",
63
+ "revision": "1700000000000",
64
+ "route": {
65
+ "backend": "openrouter",
66
+ "profile": "cloud_openrouter",
67
+ "model": "openai/gpt-5.4-mini",
68
+ "provider_preferences": [
69
+ "OpenAI"
70
+ ],
71
+ "temperature": 0.5,
72
+ "context_window_tokens": 128000,
73
+ "cache_control": true,
74
+ "reasoning_effort": null,
75
+ "model_snapshot": {
76
+ "capabilities": {
77
+ "input": [
78
+ "image"
73
79
  ],
74
- "temperature": 0.5,
75
- "context_window_tokens": 128000,
76
- "cache_control": true,
77
- "reasoning_effort": null,
78
- "model_snapshot": {
79
- "capabilities": {
80
- "input": ["image"],
81
- "tool_calling": true,
82
- "structured_output": true
83
- },
84
- "generation_support": {
85
- "temperature": true,
86
- "maxTokens": true,
87
- "thinking": true,
88
- "reasoningEfforts": [
89
- "high"
90
- ],
91
- "temperatureWithReasoning": true,
92
- "temperatureMax": null,
93
- "maxOutputTokens": null
94
- }
95
- }
96
- }
97
- },
98
- {
99
- "use_case": "agent_info_merge",
100
- "model_mode": "auto",
101
- "revision": "1700000000000",
102
- "route": {
103
- "backend": "openrouter",
104
- "profile": "cloud_openrouter",
105
- "model": "openai/gpt-5.4-mini",
106
- "provider_preferences": [
107
- "OpenAI"
108
- ],
109
- "temperature": 0.5,
110
- "context_window_tokens": 128000,
111
- "cache_control": true,
112
- "reasoning_effort": null,
113
- "model_snapshot": {
114
- "capabilities": {
115
- "input": ["image"],
116
- "tool_calling": true,
117
- "structured_output": true
118
- },
119
- "generation_support": {
120
- "temperature": true,
121
- "maxTokens": true,
122
- "thinking": true,
123
- "reasoningEfforts": [
124
- "high"
125
- ],
126
- "temperatureWithReasoning": true,
127
- "temperatureMax": null,
128
- "maxOutputTokens": null
129
- }
130
- }
131
- }
132
- },
133
- {
134
- "use_case": "automation_judge",
135
- "model_mode": "auto",
136
- "revision": "1700000000000",
137
- "route": {
138
- "backend": "openrouter",
139
- "profile": "cloud_openrouter",
140
- "model": "openai/gpt-5.4-mini",
141
- "provider_preferences": [
142
- "OpenAI"
143
- ],
144
- "temperature": 0.5,
145
- "context_window_tokens": 128000,
146
- "cache_control": true,
147
- "reasoning_effort": null,
148
- "model_snapshot": {
149
- "capabilities": {
150
- "input": ["image"],
151
- "tool_calling": true,
152
- "structured_output": true
153
- },
154
- "generation_support": {
155
- "temperature": true,
156
- "maxTokens": true,
157
- "thinking": true,
158
- "reasoningEfforts": [
159
- "high"
160
- ],
161
- "temperatureWithReasoning": true,
162
- "temperatureMax": null,
163
- "maxOutputTokens": null
164
- }
165
- }
166
- }
167
- },
168
- {
169
- "use_case": "automation_diagnose",
170
- "model_mode": "auto",
171
- "revision": "1700000000000",
172
- "route": {
173
- "backend": "openrouter",
174
- "profile": "cloud_openrouter",
175
- "model": "openai/gpt-5.4-mini",
176
- "provider_preferences": [
177
- "OpenAI"
178
- ],
179
- "temperature": 0.5,
180
- "context_window_tokens": 128000,
181
- "cache_control": true,
182
- "reasoning_effort": null,
183
- "model_snapshot": {
184
- "capabilities": {
185
- "input": ["image"],
186
- "tool_calling": true,
187
- "structured_output": true
188
- },
189
- "generation_support": {
190
- "temperature": true,
191
- "maxTokens": true,
192
- "thinking": true,
193
- "reasoningEfforts": [
194
- "high"
195
- ],
196
- "temperatureWithReasoning": true,
197
- "temperatureMax": null,
198
- "maxOutputTokens": null
199
- }
200
- }
201
- }
202
- },
203
- {
204
- "use_case": "app_guide",
205
- "model_mode": "auto",
206
- "revision": "1700000000000",
207
- "route": {
208
- "backend": "openrouter",
209
- "profile": "cloud_openrouter",
210
- "model": "openai/gpt-5.4-mini",
211
- "provider_preferences": [
212
- "OpenAI"
80
+ "tool_calling": true,
81
+ "structured_output": true
82
+ },
83
+ "generation_support": {
84
+ "temperature": true,
85
+ "maxTokens": true,
86
+ "thinking": true,
87
+ "reasoningEfforts": [
88
+ "high"
213
89
  ],
214
- "temperature": 0.5,
215
- "context_window_tokens": 128000,
216
- "cache_control": true,
217
- "reasoning_effort": null,
218
- "model_snapshot": {
219
- "capabilities": {
220
- "input": ["image"],
221
- "tool_calling": true,
222
- "structured_output": true
223
- },
224
- "generation_support": {
225
- "temperature": true,
226
- "maxTokens": true,
227
- "thinking": true,
228
- "reasoningEfforts": [
229
- "high"
230
- ],
231
- "temperatureWithReasoning": true,
232
- "temperatureMax": null,
233
- "maxOutputTokens": null
234
- }
235
- }
236
- }
237
- },
238
- {
239
- "use_case": "workflow.action_operate",
240
- "model_mode": "auto",
241
- "revision": "1700000000000",
242
- "route": {
243
- "backend": "openrouter",
244
- "profile": "cloud_openrouter",
245
- "model": "openai/gpt-5.4-mini",
246
- "provider_preferences": [
247
- "OpenAI"
248
- ],
249
- "temperature": 0.5,
250
- "context_window_tokens": 128000,
251
- "cache_control": true,
252
- "reasoning_effort": null,
253
- "model_snapshot": {
254
- "capabilities": {
255
- "input": ["image"],
256
- "tool_calling": true,
257
- "structured_output": true
258
- },
259
- "generation_support": {
260
- "temperature": true,
261
- "maxTokens": true,
262
- "thinking": true,
263
- "reasoningEfforts": [
264
- "high"
265
- ],
266
- "temperatureWithReasoning": true,
267
- "temperatureMax": null,
268
- "maxOutputTokens": null
269
- }
270
- }
271
- }
272
- },
273
- {
274
- "use_case": "workflow.automation_generate",
275
- "model_mode": "auto",
276
- "revision": "1700000000000",
277
- "route": {
278
- "backend": "openrouter",
279
- "profile": "cloud_openrouter",
280
- "model": "openai/gpt-5.4-mini",
281
- "provider_preferences": [
282
- "OpenAI"
283
- ],
284
- "temperature": 0.5,
285
- "context_window_tokens": 128000,
286
- "cache_control": true,
287
- "reasoning_effort": null,
288
- "model_snapshot": {
289
- "capabilities": {
290
- "input": ["image"],
291
- "tool_calling": true,
292
- "structured_output": true
293
- },
294
- "generation_support": {
295
- "temperature": true,
296
- "maxTokens": true,
297
- "thinking": true,
298
- "reasoningEfforts": [
299
- "high"
300
- ],
301
- "temperatureWithReasoning": true,
302
- "temperatureMax": null,
303
- "maxOutputTokens": null
304
- }
305
- }
306
- }
307
- },
308
- {
309
- "use_case": "workflow.description_generate",
310
- "model_mode": "auto",
311
- "revision": "1700000000000",
312
- "route": {
313
- "backend": "openrouter",
314
- "profile": "cloud_openrouter",
315
- "model": "openai/gpt-5.4-mini",
316
- "provider_preferences": [
317
- "OpenAI"
318
- ],
319
- "temperature": 0.5,
320
- "context_window_tokens": 128000,
321
- "cache_control": true,
322
- "reasoning_effort": null,
323
- "model_snapshot": {
324
- "capabilities": {
325
- "input": ["image"],
326
- "tool_calling": true,
327
- "structured_output": true
328
- },
329
- "generation_support": {
330
- "temperature": true,
331
- "maxTokens": true,
332
- "thinking": true,
333
- "reasoningEfforts": [
334
- "high"
335
- ],
336
- "temperatureWithReasoning": true,
337
- "temperatureMax": null,
338
- "maxOutputTokens": null
339
- }
340
- }
90
+ "temperatureWithReasoning": true,
91
+ "temperatureMax": null,
92
+ "maxOutputTokens": null
341
93
  }
342
94
  }
343
- ]
95
+ }
344
96
  },
345
97
  "base_checkpoint": null,
346
98
  "abandoned_run_id": null
@@ -31,9 +31,9 @@
31
31
  },
32
32
  "observation": {
33
33
  "type": "companion_text",
34
- "content": "I will check that now.",
35
- "append": false
36
- }
34
+ "content": "I will check that now."
35
+ },
36
+ "sequence": 1
37
37
  }
38
38
  }
39
39
  }
@@ -2,8 +2,30 @@
2
2
  "target": "/chat/interaction/answer",
3
3
  "direction": "response",
4
4
  "body": {
5
- "requestId": "request-1",
6
- "threadId": "thread-3",
7
- "disposition": "accepted"
5
+ "receipt": {
6
+ "requestId": "request-1",
7
+ "threadId": "thread-3",
8
+ "disposition": "accepted"
9
+ },
10
+ "control": {
11
+ "surfaceId": "cs1:cp:dXNlcg",
12
+ "version": "00000000000000000001:00000000000000000001",
13
+ "activeThread": {
14
+ "threadId": "thread-2",
15
+ "title": "New conversation",
16
+ "state": "active",
17
+ "createdAt": "2026-08-22T00:00:00Z",
18
+ "updatedAt": "2026-08-22T00:00:00Z",
19
+ "archivedAt": null,
20
+ "purgeAfter": null
21
+ },
22
+ "activeRun": null,
23
+ "pendingInteraction": null,
24
+ "queue": {
25
+ "queueVersion": 0,
26
+ "items": []
27
+ },
28
+ "historyVersion": 0
29
+ }
8
30
  }
9
31
  }
@@ -2,7 +2,29 @@
2
2
  "target": "/chat/interaction/submit",
3
3
  "direction": "response",
4
4
  "body": {
5
- "requestId": "request-1",
6
- "disposition": "accepted"
5
+ "receipt": {
6
+ "requestId": "request-1",
7
+ "disposition": "accepted"
8
+ },
9
+ "control": {
10
+ "surfaceId": "cs1:cp:dXNlcg",
11
+ "version": "00000000000000000001:00000000000000000001",
12
+ "activeThread": {
13
+ "threadId": "thread-2",
14
+ "title": "New conversation",
15
+ "state": "active",
16
+ "createdAt": "2026-08-22T00:00:00Z",
17
+ "updatedAt": "2026-08-22T00:00:00Z",
18
+ "archivedAt": null,
19
+ "purgeAfter": null
20
+ },
21
+ "activeRun": null,
22
+ "pendingInteraction": null,
23
+ "queue": {
24
+ "queueVersion": 0,
25
+ "items": []
26
+ },
27
+ "historyVersion": 0
28
+ }
7
29
  }
8
30
  }
@@ -7,8 +7,10 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 1,
11
10
  "occurredAt": "2026-08-22T00:00:00Z",
12
- "data": { "text": "Working", "append": true }
11
+ "data": {
12
+ "text": "Working"
13
+ },
14
+ "sequence": 1
13
15
  }
14
16
  }
@@ -7,8 +7,10 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 3,
11
10
  "occurredAt": "2026-08-22T00:00:02Z",
12
- "data": { "kind": "planning" }
11
+ "data": {
12
+ "kind": "planning"
13
+ },
14
+ "sequence": 3
13
15
  }
14
16
  }
@@ -7,8 +7,10 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 2,
11
10
  "occurredAt": "2026-08-22T00:00:01Z",
12
- "data": { "kind": "thinking" }
11
+ "data": {
12
+ "kind": "thinking"
13
+ },
14
+ "sequence": 2
13
15
  }
14
16
  }
@@ -7,8 +7,14 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 5,
11
10
  "occurredAt": "2026-08-22T00:00:04Z",
12
- "data": { "kind": "tool_scheduled", "toolNames": ["search", "fetch"] }
11
+ "data": {
12
+ "kind": "tool_scheduled",
13
+ "toolNames": [
14
+ "search",
15
+ "fetch"
16
+ ]
17
+ },
18
+ "sequence": 5
13
19
  }
14
20
  }
@@ -7,8 +7,11 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 6,
11
10
  "occurredAt": "2026-08-22T00:00:05Z",
12
- "data": { "kind": "tool_started", "toolName": "search" }
11
+ "data": {
12
+ "kind": "tool_started",
13
+ "toolName": "search"
14
+ },
15
+ "sequence": 6
13
16
  }
14
17
  }
@@ -7,8 +7,10 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 4,
11
10
  "occurredAt": "2026-08-22T00:00:03Z",
12
- "data": { "kind": "waiting_external" }
11
+ "data": {
12
+ "kind": "waiting_external"
13
+ },
14
+ "sequence": 4
13
15
  }
14
16
  }
@@ -2,7 +2,29 @@
2
2
  "target": "/chat/queue/reorder",
3
3
  "direction": "response",
4
4
  "body": {
5
- "queueVersion": 4,
6
- "items": []
5
+ "receipt": {
6
+ "queueVersion": 4,
7
+ "items": []
8
+ },
9
+ "control": {
10
+ "surfaceId": "cs1:cp:dXNlcg",
11
+ "version": "00000000000000000001:00000000000000000001",
12
+ "activeThread": {
13
+ "threadId": "thread-2",
14
+ "title": "New conversation",
15
+ "state": "active",
16
+ "createdAt": "2026-08-22T00:00:00Z",
17
+ "updatedAt": "2026-08-22T00:00:00Z",
18
+ "archivedAt": null,
19
+ "purgeAfter": null
20
+ },
21
+ "activeRun": null,
22
+ "pendingInteraction": null,
23
+ "queue": {
24
+ "queueVersion": 0,
25
+ "items": []
26
+ },
27
+ "historyVersion": 0
28
+ }
7
29
  }
8
30
  }