@mhome/conversation-protocol 3.4.0 → 3.6.1

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.
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.
@@ -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
  }
@@ -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
  }
@@ -7,8 +7,11 @@
7
7
  "threadId": "thread-1",
8
8
  "requestId": "request-1",
9
9
  "baseSnapshotVersion": 3,
10
- "offset": 7,
11
10
  "occurredAt": "2026-08-22T00:00:06Z",
12
- "data": { "code": "AGENT_UNAVAILABLE", "message": "Agent connection was lost" }
11
+ "data": {
12
+ "code": "AGENT_UNAVAILABLE",
13
+ "message": "Agent connection was lost"
14
+ },
15
+ "sequence": 7
13
16
  }
14
17
  }
@@ -2,10 +2,31 @@
2
2
  "target": "/chat/thread/load",
3
3
  "direction": "response",
4
4
  "body": {
5
- "thread": { "threadId": "thread-2", "title": "New conversation", "state": "active", "createdAt": "2026-08-22T00:00:00Z", "updatedAt": "2026-08-22T00:00:00Z", "archivedAt": null, "purgeAfter": null },
6
- "session": { "activityAtUnixMs": 0 },
7
- "sync": { "mode": "snapshot", "snapshot": { "version": 0, "messages": [], "activeRun": null, "pendingInteraction": null, "runOutcomes": [] } },
8
- "live": { "baseSnapshotVersion": 0, "lastOffset": 0, "events": [] },
9
- "queue": { "queueVersion": 0, "items": [] }
5
+ "thread": {
6
+ "threadId": "thread-2",
7
+ "title": "New conversation",
8
+ "state": "active",
9
+ "createdAt": "2026-08-22T00:00:00Z",
10
+ "updatedAt": "2026-08-22T00:00:00Z",
11
+ "archivedAt": null,
12
+ "purgeAfter": null
13
+ },
14
+ "session": {
15
+ "activityAtUnixMs": 0
16
+ },
17
+ "sync": {
18
+ "mode": "snapshot",
19
+ "snapshot": {
20
+ "version": 0,
21
+ "messages": [],
22
+ "activeRun": null,
23
+ "pendingInteraction": null,
24
+ "runOutcomes": []
25
+ }
26
+ },
27
+ "queue": {
28
+ "queueVersion": 0,
29
+ "items": []
30
+ }
10
31
  }
11
32
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.conversation.targets.v1",
3
- "contractVersion": "3.4.0",
3
+ "contractVersion": "3.6.1",
4
4
  "requestTargets": [
5
5
  "/chat/control/get",
6
6
  "/chat/thread/list",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/conversation-protocol",
3
- "version": "3.4.0",
3
+ "version": "3.6.1",
4
4
  "description": "Build-time protocol artifacts for mhome.conversation",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "protocol": "mhome.conversation",
3
- "contractVersion": "3.4.0",
3
+ "contractVersion": "3.6.1",
4
4
  "manifest": "manifest/targets.v1.json",
5
5
  "schemas": {
6
6
  "frame": "schema/conversation-frame.v2.schema.json",
@@ -842,7 +842,7 @@
842
842
  "threadId",
843
843
  "requestId",
844
844
  "baseSnapshotVersion",
845
- "offset",
845
+ "sequence",
846
846
  "occurredAt",
847
847
  "data"
848
848
  ],
@@ -863,10 +863,6 @@
863
863
  "type": "integer",
864
864
  "minimum": 0
865
865
  },
866
- "offset": {
867
- "type": "integer",
868
- "minimum": 1
869
- },
870
866
  "occurredAt": {
871
867
  "$ref": "#/$defs/time"
872
868
  },
@@ -874,17 +870,18 @@
874
870
  "type": "object",
875
871
  "additionalProperties": false,
876
872
  "required": [
877
- "text",
878
- "append"
873
+ "text"
879
874
  ],
880
875
  "properties": {
881
876
  "text": {
882
- "type": "string"
883
- },
884
- "append": {
885
- "type": "boolean"
877
+ "type": "string",
878
+ "maxLength": 8192
886
879
  }
887
880
  }
881
+ },
882
+ "sequence": {
883
+ "type": "integer",
884
+ "minimum": 1
888
885
  }
889
886
  }
890
887
  },
@@ -973,7 +970,7 @@
973
970
  "threadId",
974
971
  "requestId",
975
972
  "baseSnapshotVersion",
976
- "offset",
973
+ "sequence",
977
974
  "occurredAt",
978
975
  "data"
979
976
  ],
@@ -994,15 +991,15 @@
994
991
  "type": "integer",
995
992
  "minimum": 0
996
993
  },
997
- "offset": {
998
- "type": "integer",
999
- "minimum": 1
1000
- },
1001
994
  "occurredAt": {
1002
995
  "$ref": "#/$defs/time"
1003
996
  },
1004
997
  "data": {
1005
998
  "$ref": "#/$defs/runProgressData"
999
+ },
1000
+ "sequence": {
1001
+ "type": "integer",
1002
+ "minimum": 1
1006
1003
  }
1007
1004
  }
1008
1005
  },
@@ -1015,7 +1012,7 @@
1015
1012
  "threadId",
1016
1013
  "requestId",
1017
1014
  "baseSnapshotVersion",
1018
- "offset",
1015
+ "sequence",
1019
1016
  "occurredAt",
1020
1017
  "data"
1021
1018
  ],
@@ -1036,10 +1033,6 @@
1036
1033
  "type": "integer",
1037
1034
  "minimum": 0
1038
1035
  },
1039
- "offset": {
1040
- "type": "integer",
1041
- "minimum": 1
1042
- },
1043
1036
  "occurredAt": {
1044
1037
  "$ref": "#/$defs/time"
1045
1038
  },
@@ -1058,6 +1051,10 @@
1058
1051
  "type": "string"
1059
1052
  }
1060
1053
  }
1054
+ },
1055
+ "sequence": {
1056
+ "type": "integer",
1057
+ "minimum": 1
1061
1058
  }
1062
1059
  }
1063
1060
  },
@@ -1074,31 +1071,6 @@
1074
1071
  }
1075
1072
  ]
1076
1073
  },
1077
- "live": {
1078
- "type": "object",
1079
- "additionalProperties": false,
1080
- "required": [
1081
- "baseSnapshotVersion",
1082
- "lastOffset",
1083
- "events"
1084
- ],
1085
- "properties": {
1086
- "baseSnapshotVersion": {
1087
- "type": "integer",
1088
- "minimum": 0
1089
- },
1090
- "lastOffset": {
1091
- "type": "integer",
1092
- "minimum": 0
1093
- },
1094
- "events": {
1095
- "type": "array",
1096
- "items": {
1097
- "$ref": "#/$defs/liveEvent"
1098
- }
1099
- }
1100
- }
1101
- },
1102
1074
  "threadSession": {
1103
1075
  "type": "object",
1104
1076
  "additionalProperties": false,
@@ -1184,7 +1156,6 @@
1184
1156
  "thread",
1185
1157
  "session",
1186
1158
  "sync",
1187
- "live",
1188
1159
  "queue"
1189
1160
  ],
1190
1161
  "properties": {
@@ -1197,9 +1168,6 @@
1197
1168
  "sync": {
1198
1169
  "$ref": "#/$defs/threadSync"
1199
1170
  },
1200
- "live": {
1201
- "$ref": "#/$defs/live"
1202
- },
1203
1171
  "queue": {
1204
1172
  "$ref": "#/$defs/queue"
1205
1173
  }
@@ -2133,6 +2101,7 @@
2133
2101
  },
2134
2102
  "disposition": {
2135
2103
  "enum": [
2104
+ "scheduled",
2136
2105
  "queued",
2137
2106
  "duplicate"
2138
2107
  ]
@@ -2199,6 +2168,7 @@
2199
2168
  },
2200
2169
  "disposition": {
2201
2170
  "enum": [
2171
+ "scheduled",
2202
2172
  "queued",
2203
2173
  "duplicate",
2204
2174
  "blocked_pending_interaction"
@@ -610,19 +610,15 @@
610
610
  }
611
611
  }
612
612
  },
613
- "llm_route_binding": {
613
+ "llm_execution_plan": {
614
614
  "type": "object",
615
615
  "additionalProperties": false,
616
616
  "required": [
617
- "use_case",
618
617
  "model_mode",
619
618
  "revision",
620
619
  "route"
621
620
  ],
622
621
  "properties": {
623
- "use_case": {
624
- "$ref": "#/$defs/identifier"
625
- },
626
622
  "model_mode": {
627
623
  "$ref": "#/$defs/identifier"
628
624
  },
@@ -642,22 +638,6 @@
642
638
  }
643
639
  }
644
640
  },
645
- "llm_execution_plan": {
646
- "type": "object",
647
- "additionalProperties": false,
648
- "required": [
649
- "routes"
650
- ],
651
- "properties": {
652
- "routes": {
653
- "type": "array",
654
- "minItems": 1,
655
- "items": {
656
- "$ref": "#/$defs/llm_route_binding"
657
- }
658
- }
659
- }
660
- },
661
641
  "command_request": {
662
642
  "type": "object",
663
643
  "additionalProperties": false,
@@ -1135,8 +1115,7 @@
1135
1115
  "additionalProperties": false,
1136
1116
  "required": [
1137
1117
  "type",
1138
- "content",
1139
- "append"
1118
+ "content"
1140
1119
  ],
1141
1120
  "properties": {
1142
1121
  "type": {
@@ -1144,9 +1123,6 @@
1144
1123
  },
1145
1124
  "content": {
1146
1125
  "type": "string"
1147
- },
1148
- "append": {
1149
- "type": "boolean"
1150
1126
  }
1151
1127
  }
1152
1128
  },
@@ -1257,7 +1233,8 @@
1257
1233
  "additionalProperties": false,
1258
1234
  "required": [
1259
1235
  "context",
1260
- "observation"
1236
+ "observation",
1237
+ "sequence"
1261
1238
  ],
1262
1239
  "properties": {
1263
1240
  "context": {
@@ -1265,6 +1242,10 @@
1265
1242
  },
1266
1243
  "observation": {
1267
1244
  "$ref": "#/$defs/agent_observation"
1245
+ },
1246
+ "sequence": {
1247
+ "type": "integer",
1248
+ "minimum": 1
1268
1249
  }
1269
1250
  }
1270
1251
  },