@mhome/conversation-protocol 3.7.0 → 3.8.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # mhome-conversation-api
2
2
 
3
- Typed, transport-neutral DTOs and canonical surface identities for the mHome conversation API.
3
+ Typed, transport-neutral DTOs and canonical surface identities for the MeowLink conversation API.
4
4
 
5
5
  This crate owns wire targets, request and response bodies, user-visible message content, and
6
6
  conversation events. `ConversationSurface` is a canonical value object whose string form is the
@@ -80,3 +80,30 @@ Final replies, failures, cancellations, queue state, and actionable user
80
80
  confirmations remain durable. Snapshot deltas keep their existing contiguous
81
81
  version/recovery rules. Agent checkpoints and billing are independent of live
82
82
  presentation delivery.
83
+
84
+ ## Waiting queue operations
85
+
86
+ `/chat/queue/update` replaces the complete content of one waiting request. Its
87
+ request ID, original admission fingerprint, author, and frozen execution settings
88
+ remain unchanged. Concurrent edits use the last successful server commit; client
89
+ clocks are irrelevant. Claiming the request for execution and editing it share the
90
+ same transactional boundary, so an edit cannot succeed after execution begins.
91
+
92
+ `/chat/queue/reorder` moves `requestId` before `beforeRequestId`; a null anchor
93
+ moves it to the tail. The server applies the move to its current queue, preserving
94
+ new arrivals and unrelated moves. A missing request or anchor is a conflict; a
95
+ client must never replace the whole queue from its stale local list.
96
+
97
+ Both operations require an `operationId`, scoped to the surface and request ID.
98
+ An exact retry returns `already_applied` and the original operation's queue version,
99
+ without replaying its changes. Reusing it with another payload is a conflict.
100
+ Command responses still carry a fresh authoritative control projection; clients
101
+ apply control versions monotonically rather than treating a mutation receipt as
102
+ a queue snapshot. Events and command responses use the same control versions.
103
+
104
+ Cancellation, including archive cleanup, retains a durable terminal admission
105
+ receipt independently of transcript retention. `/chat/request/status` reads that
106
+ receipt by request ID, returning null admission for an unknown request. It recovers
107
+ missed `admission.changed` events without reenqueuing or guessing from an empty
108
+ queue. Retry of the original submission still checks its original content, even
109
+ when the queued execution content was later edited.
@@ -3,7 +3,8 @@
3
3
  "direction": "request",
4
4
  "body": {
5
5
  "threadId": "thread-2",
6
- "expectedQueueVersion": 3,
7
- "orderedRequestIds": ["request-2", "request-1"]
6
+ "requestId": "request-2",
7
+ "operationId": "move-1",
8
+ "beforeRequestId": "request-1"
8
9
  }
9
10
  }
@@ -3,8 +3,10 @@
3
3
  "direction": "response",
4
4
  "body": {
5
5
  "receipt": {
6
+ "operationId": "move-1",
7
+ "requestId": "request-2",
6
8
  "queueVersion": 4,
7
- "items": []
9
+ "disposition": "applied"
8
10
  },
9
11
  "control": {
10
12
  "surfaceId": "cs1:cp:dXNlcg",
@@ -0,0 +1,17 @@
1
+ {
2
+ "target": "/chat/queue/update",
3
+ "direction": "request",
4
+ "body": {
5
+ "threadId": "thread-2",
6
+ "requestId": "request-2",
7
+ "operationId": "edit-1",
8
+ "content": {
9
+ "parts": [
10
+ {
11
+ "type": "text",
12
+ "text": "Updated instruction"
13
+ }
14
+ ]
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "target": "/chat/queue/update",
3
+ "direction": "response",
4
+ "body": {
5
+ "receipt": {
6
+ "operationId": "edit-1",
7
+ "requestId": "request-2",
8
+ "queueVersion": 4,
9
+ "disposition": "applied"
10
+ },
11
+ "control": {
12
+ "surfaceId": "cs1:cp:dXNlcg",
13
+ "version": "00000000000000000001:00000000000000000001",
14
+ "activeThread": {
15
+ "threadId": "thread-2",
16
+ "title": "New conversation",
17
+ "state": "active",
18
+ "createdAt": "2026-08-22T00:00:00Z",
19
+ "updatedAt": "2026-08-22T00:00:00Z",
20
+ "archivedAt": null,
21
+ "purgeAfter": null
22
+ },
23
+ "activeRun": null,
24
+ "pendingInteraction": null,
25
+ "queue": {
26
+ "queueVersion": 0,
27
+ "items": []
28
+ },
29
+ "historyVersion": 0
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "target": "/chat/request/status",
3
+ "direction": "request",
4
+ "body": {
5
+ "requestId": "request-2"
6
+ }
7
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "target": "/chat/request/status",
3
+ "direction": "response",
4
+ "body": {
5
+ "requestId": "request-2",
6
+ "admission": {
7
+ "state": "cancelled",
8
+ "admissionVersion": 2,
9
+ "reason": "cancelled",
10
+ "threadId": "thread-2",
11
+ "queueVersion": 5
12
+ }
13
+ }
14
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.conversation.targets.v1",
3
- "contractVersion": "3.7.0",
3
+ "contractVersion": "3.8.0",
4
4
  "requestTargets": [
5
5
  "/chat/control/get",
6
6
  "/chat/thread/list",
@@ -14,7 +14,9 @@
14
14
  "/chat/interaction/answer",
15
15
  "/chat/queue/reorder",
16
16
  "/chat/request/cancel",
17
- "/chat/interaction/submit"
17
+ "/chat/interaction/submit",
18
+ "/chat/queue/update",
19
+ "/chat/request/status"
18
20
  ],
19
21
  "eventTargets": [
20
22
  "/chat/event",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/conversation-protocol",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
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.7.0",
3
+ "contractVersion": "3.8.0",
4
4
  "manifest": "manifest/targets.v1.json",
5
5
  "schemas": {
6
6
  "frame": "schema/conversation-frame.v2.schema.json",
@@ -1575,6 +1575,15 @@
1575
1575
  },
1576
1576
  {
1577
1577
  "$ref": "#/$defs/catalogCommandResponse"
1578
+ },
1579
+ {
1580
+ "$ref": "#/$defs/updateRequest"
1581
+ },
1582
+ {
1583
+ "$ref": "#/$defs/statusRequest"
1584
+ },
1585
+ {
1586
+ "$ref": "#/$defs/statusResponse"
1578
1587
  }
1579
1588
  ]
1580
1589
  },
@@ -1917,23 +1926,29 @@
1917
1926
  "additionalProperties": false,
1918
1927
  "required": [
1919
1928
  "threadId",
1920
- "expectedQueueVersion",
1921
- "orderedRequestIds"
1929
+ "requestId",
1930
+ "operationId",
1931
+ "beforeRequestId"
1922
1932
  ],
1923
1933
  "properties": {
1924
1934
  "threadId": {
1925
1935
  "$ref": "#/$defs/id"
1926
1936
  },
1927
- "expectedQueueVersion": {
1928
- "type": "integer",
1929
- "minimum": 0
1937
+ "requestId": {
1938
+ "$ref": "#/$defs/id"
1930
1939
  },
1931
- "orderedRequestIds": {
1932
- "type": "array",
1933
- "uniqueItems": true,
1934
- "items": {
1935
- "$ref": "#/$defs/id"
1936
- }
1940
+ "operationId": {
1941
+ "$ref": "#/$defs/id"
1942
+ },
1943
+ "beforeRequestId": {
1944
+ "oneOf": [
1945
+ {
1946
+ "$ref": "#/$defs/id"
1947
+ },
1948
+ {
1949
+ "type": "null"
1950
+ }
1951
+ ]
1937
1952
  }
1938
1953
  }
1939
1954
  }
@@ -2217,7 +2232,10 @@
2217
2232
  ],
2218
2233
  "properties": {
2219
2234
  "target": {
2220
- "const": "/chat/queue/reorder"
2235
+ "enum": [
2236
+ "/chat/queue/reorder",
2237
+ "/chat/queue/update"
2238
+ ]
2221
2239
  },
2222
2240
  "direction": {
2223
2241
  "const": "response"
@@ -2231,7 +2249,7 @@
2231
2249
  ],
2232
2250
  "properties": {
2233
2251
  "receipt": {
2234
- "$ref": "#/$defs/queue"
2252
+ "$ref": "#/$defs/queueMutationReceipt"
2235
2253
  },
2236
2254
  "control": {
2237
2255
  "oneOf": [
@@ -2856,6 +2874,144 @@
2856
2874
  }
2857
2875
  }
2858
2876
  ]
2877
+ },
2878
+ "updateRequest": {
2879
+ "type": "object",
2880
+ "additionalProperties": false,
2881
+ "required": [
2882
+ "target",
2883
+ "direction",
2884
+ "body"
2885
+ ],
2886
+ "properties": {
2887
+ "target": {
2888
+ "const": "/chat/queue/update"
2889
+ },
2890
+ "direction": {
2891
+ "const": "request"
2892
+ },
2893
+ "body": {
2894
+ "type": "object",
2895
+ "additionalProperties": false,
2896
+ "required": [
2897
+ "threadId",
2898
+ "requestId",
2899
+ "operationId",
2900
+ "content"
2901
+ ],
2902
+ "properties": {
2903
+ "threadId": {
2904
+ "$ref": "#/$defs/id"
2905
+ },
2906
+ "requestId": {
2907
+ "$ref": "#/$defs/id"
2908
+ },
2909
+ "operationId": {
2910
+ "$ref": "#/$defs/id"
2911
+ },
2912
+ "content": {
2913
+ "$ref": "#/$defs/content"
2914
+ }
2915
+ }
2916
+ }
2917
+ }
2918
+ },
2919
+ "queueMutationReceipt": {
2920
+ "type": "object",
2921
+ "additionalProperties": false,
2922
+ "required": [
2923
+ "operationId",
2924
+ "requestId",
2925
+ "queueVersion",
2926
+ "disposition"
2927
+ ],
2928
+ "properties": {
2929
+ "operationId": {
2930
+ "$ref": "#/$defs/id"
2931
+ },
2932
+ "requestId": {
2933
+ "$ref": "#/$defs/id"
2934
+ },
2935
+ "queueVersion": {
2936
+ "type": "integer",
2937
+ "minimum": 0
2938
+ },
2939
+ "disposition": {
2940
+ "enum": [
2941
+ "applied",
2942
+ "already_applied"
2943
+ ]
2944
+ }
2945
+ }
2946
+ },
2947
+ "statusRequest": {
2948
+ "type": "object",
2949
+ "additionalProperties": false,
2950
+ "required": [
2951
+ "target",
2952
+ "direction",
2953
+ "body"
2954
+ ],
2955
+ "properties": {
2956
+ "target": {
2957
+ "const": "/chat/request/status"
2958
+ },
2959
+ "direction": {
2960
+ "const": "request"
2961
+ },
2962
+ "body": {
2963
+ "type": "object",
2964
+ "additionalProperties": false,
2965
+ "required": [
2966
+ "requestId"
2967
+ ],
2968
+ "properties": {
2969
+ "requestId": {
2970
+ "$ref": "#/$defs/id"
2971
+ }
2972
+ }
2973
+ }
2974
+ }
2975
+ },
2976
+ "statusResponse": {
2977
+ "type": "object",
2978
+ "additionalProperties": false,
2979
+ "required": [
2980
+ "target",
2981
+ "direction",
2982
+ "body"
2983
+ ],
2984
+ "properties": {
2985
+ "target": {
2986
+ "const": "/chat/request/status"
2987
+ },
2988
+ "direction": {
2989
+ "const": "response"
2990
+ },
2991
+ "body": {
2992
+ "type": "object",
2993
+ "additionalProperties": false,
2994
+ "required": [
2995
+ "requestId",
2996
+ "admission"
2997
+ ],
2998
+ "properties": {
2999
+ "requestId": {
3000
+ "$ref": "#/$defs/id"
3001
+ },
3002
+ "admission": {
3003
+ "oneOf": [
3004
+ {
3005
+ "$ref": "#/$defs/requestAdmission"
3006
+ },
3007
+ {
3008
+ "type": "null"
3009
+ }
3010
+ ]
3011
+ }
3012
+ }
3013
+ }
3014
+ }
2859
3015
  }
2860
3016
  }
2861
3017
  }