@mhome/core-protocol 1.1.1 → 1.2.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
@@ -5,6 +5,18 @@ provider runtimes. Public `/app/*` contracts belong to
5
5
  `mhome-app-facade-api`; this crate owns internal MWS, authentication, LLM,
6
6
  Messaging normalization, Node runtime, and Storage contracts.
7
7
 
8
+ `interaction_flow` defines the serializable Core-to-Node flow definition and
9
+ handler protocol. Definitions name logical operations only; MeowCore chooses
10
+ and pins the Node instance and fixed transport routes for each session.
11
+
12
+ The Node owns the source session returned with a definition. Core closes that
13
+ session through the fixed close route after completion, cancellation, expiry,
14
+ or a failed start. Close is idempotent, and Nodes must also expire abandoned
15
+ source sessions so a Core restart cannot leak them. Execute operations are
16
+ idempotent within a source session: replaying the same `operationId` and
17
+ request returns the original result, while reusing the ID for a different
18
+ request is rejected.
19
+
8
20
  Storage separates backing-filesystem capacity from Storage-owned logical
9
21
  usage. Namespace is an internal protocol term; user-facing clients present it
10
22
  as a Folder.
@@ -0,0 +1,81 @@
1
+ {
2
+ "definitionRequest": {
3
+ "flowId": "provider.connect",
4
+ "subjectId": "onvif"
5
+ },
6
+ "definitionResponse": {
7
+ "definitionRevision": "sha256:demo",
8
+ "sourceSessionId": "source-session-1",
9
+ "definition": {
10
+ "protocolVersion": 1,
11
+ "flowId": "provider.connect",
12
+ "startStepId": "credentials",
13
+ "steps": {
14
+ "credentials": {
15
+ "id": "credentials",
16
+ "content": {
17
+ "type": "form",
18
+ "presentation": {
19
+ "renderer": "typedForm",
20
+ "title": "Connect camera provider"
21
+ },
22
+ "form": {
23
+ "fields": [
24
+ {
25
+ "var": "$host",
26
+ "valueType": "string",
27
+ "control": "text",
28
+ "required": true,
29
+ "repeat": false,
30
+ "label": "Host",
31
+ "readOnly": false
32
+ },
33
+ {
34
+ "var": "$password",
35
+ "valueType": "string",
36
+ "control": "password",
37
+ "required": true,
38
+ "repeat": false,
39
+ "label": "Password",
40
+ "readOnly": false
41
+ }
42
+ ]
43
+ },
44
+ "renderRefs": []
45
+ },
46
+ "transition": { "type": "finish" }
47
+ }
48
+ },
49
+ "resolvers": {},
50
+ "lifecycle": {
51
+ "complete": {
52
+ "operation": "provider.save",
53
+ "args": [
54
+ { "type": "ref", "valueRef": { "root": "$host" } },
55
+ { "type": "ref", "valueRef": { "root": "$password" } }
56
+ ]
57
+ }
58
+ }
59
+ }
60
+ },
61
+ "executeRequest": {
62
+ "flowId": "provider.connect",
63
+ "sourceSessionId": "source-session-1",
64
+ "definitionRevision": "sha256:demo",
65
+ "operation": "provider.save",
66
+ "operationId": "operation-1",
67
+ "args": ["192.0.2.1", "secret"]
68
+ },
69
+ "executeResponse": {
70
+ "data": { "providerConnectionId": "provider-1" }
71
+ },
72
+ "closeRequest": {
73
+ "flowId": "provider.connect",
74
+ "sourceSessionId": "source-session-1",
75
+ "operationId": "close-1",
76
+ "reason": "completed"
77
+ },
78
+ "closeResponse": {
79
+ "closed": true
80
+ }
81
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.core.v1",
3
- "contractVersion": "1.1.1",
3
+ "contractVersion": "1.2.0",
4
4
  "protocols": {
5
5
  "llm": {
6
6
  "completeTarget": "/llm/complete"
@@ -8,7 +8,11 @@
8
8
  "node": {
9
9
  "settingsChangedTarget": "/node/settings/changed",
10
10
  "statusContract": "mhome.node.status.v1",
11
- "runtimeVersion": "v1"
11
+ "runtimeVersion": "v1",
12
+ "interactionFlowSchema": "schema/interaction-flow-node.v1.schema.json",
13
+ "interactionFlowDefinitionTarget": "/{nodeType}/interaction-flow/definition",
14
+ "interactionFlowExecuteTarget": "/{nodeType}/interaction-flow/execute",
15
+ "interactionFlowCloseTarget": "/{nodeType}/interaction-flow/close"
12
16
  },
13
17
  "messaging": {
14
18
  "normalizedInboundSchema": "schema/normalized-inbound.v4.schema.json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/core-protocol",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Build-time protocol artifacts for mhome.core",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "protocol": "mhome.core",
3
- "contractVersion": "1.1.1",
3
+ "contractVersion": "1.2.0",
4
4
  "manifest": "manifest/core.v1.json",
5
5
  "schemas": {
6
6
  "normalizedInbound": "schema/normalized-inbound.v4.schema.json",
7
- "messagingCommands": "schema/messaging-commands.v1.schema.json"
7
+ "messagingCommands": "schema/messaging-commands.v1.schema.json",
8
+ "interactionFlowNode": "schema/interaction-flow-node.v1.schema.json"
8
9
  },
9
10
  "fixtures": {
10
11
  "normalizedInbound": "fixtures/normalized-inbound.conformance.json",
11
- "messagingCommands": "fixtures/messaging-commands.conformance.json"
12
+ "messagingCommands": "fixtures/messaging-commands.conformance.json",
13
+ "interactionFlowNode": "fixtures/interaction-flow-node.conformance.json"
12
14
  }
13
15
  }
@@ -0,0 +1,278 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:mhome:core-api:interaction-flow-node:v1",
4
+ "title": "MeowCore Interaction Flow Node protocol v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["definitionRequest", "definitionResponse", "executeRequest", "executeResponse", "closeRequest", "closeResponse"],
8
+ "properties": {
9
+ "definitionRequest": { "$ref": "#/$defs/definitionRequest" },
10
+ "definitionResponse": { "$ref": "#/$defs/definitionResponse" },
11
+ "executeRequest": { "$ref": "#/$defs/executeRequest" },
12
+ "executeResponse": { "$ref": "#/$defs/executeResponse" },
13
+ "closeRequest": { "$ref": "#/$defs/closeRequest" },
14
+ "closeResponse": { "$ref": "#/$defs/closeResponse" }
15
+ },
16
+ "$defs": {
17
+ "nonEmpty": { "type": "string", "minLength": 1, "maxLength": 128 },
18
+ "identifier": {
19
+ "type": "string",
20
+ "minLength": 1,
21
+ "maxLength": 128,
22
+ "pattern": "^[A-Za-z0-9_.\\/-]+$"
23
+ },
24
+ "variable": { "type": "string", "pattern": "^\\$[A-Za-z_][A-Za-z0-9_]{0,126}$" },
25
+ "valueRef": {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": ["root"],
29
+ "properties": {
30
+ "root": { "$ref": "#/$defs/variable" },
31
+ "path": {
32
+ "type": "array",
33
+ "items": { "type": "string", "pattern": "^[A-Za-z_][A-Za-z0-9_]{0,127}$" },
34
+ "maxItems": 32
35
+ }
36
+ }
37
+ },
38
+ "argument": {
39
+ "oneOf": [
40
+ {
41
+ "type": "object",
42
+ "additionalProperties": false,
43
+ "required": ["type", "value"],
44
+ "properties": { "type": { "const": "value" }, "value": true }
45
+ },
46
+ {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["type", "valueRef"],
50
+ "properties": {
51
+ "type": { "const": "ref" },
52
+ "valueRef": { "$ref": "#/$defs/valueRef" }
53
+ }
54
+ }
55
+ ]
56
+ },
57
+ "handler": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": ["operation"],
61
+ "properties": {
62
+ "operation": { "$ref": "#/$defs/identifier" },
63
+ "args": { "type": "array", "items": { "$ref": "#/$defs/argument" }, "maxItems": 128 }
64
+ }
65
+ },
66
+ "presentation": {
67
+ "type": "object",
68
+ "additionalProperties": false,
69
+ "required": ["renderer"],
70
+ "properties": {
71
+ "renderer": { "const": "typedForm" },
72
+ "title": { "type": "string", "maxLength": 1024 },
73
+ "description": { "type": "string", "maxLength": 16384 },
74
+ "content": { "type": "string", "maxLength": 65536 }
75
+ }
76
+ },
77
+ "field": {
78
+ "type": "object",
79
+ "additionalProperties": false,
80
+ "required": ["var", "valueType", "control"],
81
+ "properties": {
82
+ "var": { "$ref": "#/$defs/variable" },
83
+ "valueType": { "enum": ["string", "boolean"] },
84
+ "control": { "enum": ["text", "password", "longText", "select", "boolean"] },
85
+ "required": { "type": "boolean" },
86
+ "repeat": { "type": "boolean" },
87
+ "label": { "type": "string", "maxLength": 1024 },
88
+ "defaultValue": true,
89
+ "defaultValueRef": { "$ref": "#/$defs/valueRef" },
90
+ "options": { "type": "array", "maxItems": 1024 },
91
+ "optionsRef": { "$ref": "#/$defs/valueRef" },
92
+ "optionUnavailableText": { "type": "string", "maxLength": 4096 },
93
+ "readOnly": { "type": "boolean" },
94
+ "minRows": { "type": "integer", "minimum": 1, "maximum": 100 }
95
+ },
96
+ "allOf": [
97
+ {
98
+ "if": {
99
+ "properties": { "control": { "const": "password" } },
100
+ "required": ["control"]
101
+ },
102
+ "then": {
103
+ "not": {
104
+ "anyOf": [
105
+ { "required": ["defaultValue"] },
106
+ { "required": ["defaultValueRef"] },
107
+ {
108
+ "properties": { "readOnly": { "const": true } },
109
+ "required": ["readOnly"]
110
+ }
111
+ ]
112
+ }
113
+ }
114
+ }
115
+ ]
116
+ },
117
+ "form": {
118
+ "type": "object",
119
+ "additionalProperties": false,
120
+ "properties": {
121
+ "fields": { "type": "array", "items": { "$ref": "#/$defs/field" }, "maxItems": 64 }
122
+ }
123
+ },
124
+ "stepContent": {
125
+ "oneOf": [
126
+ {
127
+ "type": "object",
128
+ "additionalProperties": false,
129
+ "required": ["type", "presentation", "form"],
130
+ "properties": {
131
+ "type": { "const": "form" },
132
+ "presentation": { "$ref": "#/$defs/presentation" },
133
+ "form": { "$ref": "#/$defs/form" },
134
+ "renderRefs": { "type": "array", "items": { "$ref": "#/$defs/valueRef" } }
135
+ }
136
+ },
137
+ {
138
+ "type": "object",
139
+ "additionalProperties": false,
140
+ "required": ["type", "presentation", "authorizationUrlRef", "completionMode"],
141
+ "properties": {
142
+ "type": { "const": "externalAuth" },
143
+ "presentation": { "$ref": "#/$defs/presentation" },
144
+ "authorizationUrlRef": { "$ref": "#/$defs/valueRef" },
145
+ "completionMode": { "enum": ["callback", "poll"] },
146
+ "pollAfterMs": { "type": "integer", "minimum": 250, "maximum": 60000 }
147
+ }
148
+ }
149
+ ]
150
+ },
151
+ "transition": {
152
+ "oneOf": [
153
+ {
154
+ "type": "object",
155
+ "additionalProperties": false,
156
+ "required": ["type", "stepId"],
157
+ "properties": { "type": { "const": "step" }, "stepId": { "$ref": "#/$defs/identifier" } }
158
+ },
159
+ {
160
+ "type": "object",
161
+ "additionalProperties": false,
162
+ "required": ["type", "valueRef"],
163
+ "properties": { "type": { "const": "dynamic" }, "valueRef": { "$ref": "#/$defs/valueRef" } }
164
+ },
165
+ {
166
+ "type": "object",
167
+ "additionalProperties": false,
168
+ "required": ["type"],
169
+ "properties": { "type": { "const": "finish" } }
170
+ }
171
+ ]
172
+ },
173
+ "step": {
174
+ "type": "object",
175
+ "additionalProperties": false,
176
+ "required": ["id", "content", "transition"],
177
+ "properties": {
178
+ "id": { "$ref": "#/$defs/identifier" },
179
+ "content": { "$ref": "#/$defs/stepContent" },
180
+ "transition": { "$ref": "#/$defs/transition" }
181
+ }
182
+ },
183
+ "resolver": {
184
+ "type": "object",
185
+ "additionalProperties": false,
186
+ "required": ["outputVar", "handler"],
187
+ "properties": {
188
+ "outputVar": { "$ref": "#/$defs/variable" },
189
+ "handler": { "$ref": "#/$defs/handler" }
190
+ }
191
+ },
192
+ "definition": {
193
+ "type": "object",
194
+ "additionalProperties": false,
195
+ "required": ["protocolVersion", "flowId", "startStepId", "steps"],
196
+ "properties": {
197
+ "protocolVersion": { "const": 1 },
198
+ "flowId": { "$ref": "#/$defs/identifier" },
199
+ "startStepId": { "$ref": "#/$defs/identifier" },
200
+ "steps": {
201
+ "type": "object",
202
+ "minProperties": 1,
203
+ "maxProperties": 64,
204
+ "additionalProperties": { "$ref": "#/$defs/step" }
205
+ },
206
+ "resolvers": {
207
+ "type": "object",
208
+ "maxProperties": 128,
209
+ "additionalProperties": { "$ref": "#/$defs/resolver" }
210
+ },
211
+ "lifecycle": {
212
+ "type": "object",
213
+ "additionalProperties": false,
214
+ "properties": {
215
+ "complete": { "$ref": "#/$defs/handler" },
216
+ "cancel": { "$ref": "#/$defs/handler" },
217
+ "expire": { "$ref": "#/$defs/handler" }
218
+ }
219
+ }
220
+ }
221
+ },
222
+ "definitionRequest": {
223
+ "type": "object",
224
+ "additionalProperties": false,
225
+ "required": ["flowId"],
226
+ "properties": {
227
+ "flowId": { "$ref": "#/$defs/identifier" },
228
+ "subjectId": { "$ref": "#/$defs/nonEmpty" }
229
+ }
230
+ },
231
+ "definitionResponse": {
232
+ "type": "object",
233
+ "additionalProperties": false,
234
+ "required": ["definitionRevision", "sourceSessionId", "definition"],
235
+ "properties": {
236
+ "definitionRevision": { "$ref": "#/$defs/nonEmpty" },
237
+ "sourceSessionId": { "$ref": "#/$defs/nonEmpty" },
238
+ "definition": { "$ref": "#/$defs/definition" }
239
+ }
240
+ },
241
+ "executeRequest": {
242
+ "type": "object",
243
+ "additionalProperties": false,
244
+ "required": ["flowId", "sourceSessionId", "definitionRevision", "operation", "operationId"],
245
+ "properties": {
246
+ "flowId": { "$ref": "#/$defs/identifier" },
247
+ "sourceSessionId": { "$ref": "#/$defs/nonEmpty" },
248
+ "definitionRevision": { "$ref": "#/$defs/nonEmpty" },
249
+ "operation": { "$ref": "#/$defs/nonEmpty" },
250
+ "operationId": { "$ref": "#/$defs/nonEmpty" },
251
+ "args": { "type": "array", "maxItems": 128 }
252
+ }
253
+ },
254
+ "executeResponse": {
255
+ "type": "object",
256
+ "additionalProperties": true,
257
+ "required": ["data"],
258
+ "properties": { "data": true }
259
+ },
260
+ "closeRequest": {
261
+ "type": "object",
262
+ "additionalProperties": false,
263
+ "required": ["flowId", "sourceSessionId", "operationId", "reason"],
264
+ "properties": {
265
+ "flowId": { "$ref": "#/$defs/identifier" },
266
+ "sourceSessionId": { "$ref": "#/$defs/nonEmpty" },
267
+ "operationId": { "$ref": "#/$defs/nonEmpty" },
268
+ "reason": { "enum": ["completed", "cancelled", "expired", "startFailed"] }
269
+ }
270
+ },
271
+ "closeResponse": {
272
+ "type": "object",
273
+ "additionalProperties": true,
274
+ "required": ["closed"],
275
+ "properties": { "closed": { "type": "boolean" } }
276
+ }
277
+ }
278
+ }