@mhome/artifact-protocol 1.6.1 → 1.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 +45 -0
- package/manifest/artifact.v1.json +13 -1
- package/package.json +1 -1
- package/protocol.json +2 -1
- package/schema/artifact-delete.v1.schema.json +6 -0
- package/schema/artifact-import.v1.schema.json +4 -0
- package/schema/artifact-put.v1.schema.json +39 -1
- package/schema/artifact-resolve.v1.schema.json +154 -20
- package/schema/artifact-upload.v1.schema.json +36 -0
package/README.md
CHANGED
|
@@ -19,3 +19,48 @@ runtime concerns and are deliberately not encoded into an artifact reference.
|
|
|
19
19
|
Capability media values (`Image`, `Audio`) use `MediaReference`: exactly `{ "uri": "meow-artifact://v1/..." }`. The reference has no URL, inline bytes, MIME or creation timestamp fields. Parse and check kind and tenant/scope at capability boundaries; do not implicitly import media. Upload bytes with `PutArtifactRequest` or explicitly download finite HTTP(S) content with `ImportArtifactRequest` via `/app/artifact/put` and `/app/artifact/import`. Storage metadata and upload transports retain their MIME and byte fields. Resolve to temporary delivery URLs only at consumers. Conversation media sources retain their existing tagged artifact protocol. Video storage remains unsupported by the runtimes.
|
|
20
20
|
|
|
21
21
|
Upload/import preserves bytes. Callers perform conversion before upload. Public ingress is limited to 1 MiB; internal producers retain their own limits. The shared reference and storage contracts do not impose the public ingress limit.
|
|
22
|
+
|
|
23
|
+
### Temporary artifacts (MeowCore)
|
|
24
|
+
|
|
25
|
+
`put`, explicit HTTP `import`, and `upload/prepare` accept `temporary: true`.
|
|
26
|
+
Omitting the flag preserves durable storage. The flag is a storage request, not
|
|
27
|
+
part of the content-addressed URI: putting the same bytes in the same tenant and
|
|
28
|
+
scope reuses that content. Existing durable content is never downgraded. Put and
|
|
29
|
+
resolve responses report `temporary: true` and `expiresAtUnixMs` for temporary
|
|
30
|
+
content; durable responses omit both fields.
|
|
31
|
+
|
|
32
|
+
MeowCore retains temporary objects for ten minutes from commit or repeated put /
|
|
33
|
+
import revalidation. Ordinary reads do not renew expiration. Small objects (up to
|
|
34
|
+
1 MiB) use memory, subject to 64 MiB per runtime and 16 MiB per scope. New objects
|
|
35
|
+
over these limits use temporary disk, capped at 512 MiB per runtime and 128 MiB
|
|
36
|
+
per scope. Object limits are 4096 per runtime / 1024 per scope. Open snapshots
|
|
37
|
+
continue to count against capacity after deletion or expiry. Exhausted capacity
|
|
38
|
+
returns an availability error; unrelated live objects are not silently deleted.
|
|
39
|
+
Ingress is bounded separately. These are implementation defaults, not URI fields.
|
|
40
|
+
|
|
41
|
+
`/artifact/persist` takes `{ "uri": "meow-artifact://…" }` and returns a put
|
|
42
|
+
response after durable storage succeeds. Promotion is idempotent, preserves the
|
|
43
|
+
URI, and leaves the temporary object readable if writing fails. MeowCore's
|
|
44
|
+
existing thirty-day durable retention policy still applies. Expired or missing
|
|
45
|
+
objects cannot be promoted. Persist before saving a reference in long-lived
|
|
46
|
+
history or scheduling work beyond its expiration.
|
|
47
|
+
|
|
48
|
+
`/artifact/delete` takes the same request and returns `{}`. Deleting missing
|
|
49
|
+
content succeeds. Deletion affects all metadata aliases of that content in the
|
|
50
|
+
same scope; an opened snapshot may finish, while subsequent opens fail. Do not
|
|
51
|
+
delete after each LLM call when another caller may reuse the URI. There is no
|
|
52
|
+
separate eviction API. A signed URL is not a revocable object identity: recreating
|
|
53
|
+
the identical content may make an unexpired old URL usable again.
|
|
54
|
+
|
|
55
|
+
App Facade equivalents are `/app/artifact/persist` and `/app/artifact/delete`;
|
|
56
|
+
Wasm hosts expose `artifact_persist_async` and `artifact_delete_async`. LLM inputs
|
|
57
|
+
continue to use canonical Artifact references. Small temporary HTTP uploads and
|
|
58
|
+
native read descriptors carry bounded inline bytes without a staging file;
|
|
59
|
+
larger objects retain file-based streaming. Temporary delivery uses `no-store`,
|
|
60
|
+
and host resolve grants never outlive the reported object expiration.
|
|
61
|
+
|
|
62
|
+
Temporary state is process-owned and is lost on restart, including spilled
|
|
63
|
+
objects. The runtime removes abandoned spill directories on startup and expired
|
|
64
|
+
entries during maintenance. This contract adds no database or migration. A
|
|
65
|
+
cloud-owned artifact store needs its own implementation; a multi-instance cloud
|
|
66
|
+
service must not emulate this with an uncoordinated in-process map.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": "mhome.artifact.v1",
|
|
3
|
-
"contractVersion": "1.
|
|
3
|
+
"contractVersion": "1.8.0",
|
|
4
4
|
"uriPrefix": "meow-artifact://v1/",
|
|
5
5
|
"kinds": [
|
|
6
6
|
"image",
|
|
@@ -30,5 +30,17 @@
|
|
|
30
30
|
"import": {
|
|
31
31
|
"schema": "schema/artifact-import.v1.schema.json",
|
|
32
32
|
"schemaVersion": 1
|
|
33
|
+
},
|
|
34
|
+
"persist": {
|
|
35
|
+
"target": "/artifact/persist",
|
|
36
|
+
"requestSchema": "schema/artifact-resolve.v1.schema.json#/$defs/request",
|
|
37
|
+
"responseSchema": "schema/artifact-put.v1.schema.json#/$defs/response",
|
|
38
|
+
"schemaVersion": 1
|
|
39
|
+
},
|
|
40
|
+
"delete": {
|
|
41
|
+
"target": "/artifact/delete",
|
|
42
|
+
"requestSchema": "schema/artifact-resolve.v1.schema.json#/$defs/request",
|
|
43
|
+
"responseSchema": "schema/artifact-delete.v1.schema.json",
|
|
44
|
+
"schemaVersion": 1
|
|
33
45
|
}
|
|
34
46
|
}
|
package/package.json
CHANGED
package/protocol.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"protocol": "mhome.artifact",
|
|
3
|
-
"contractVersion": "1.
|
|
3
|
+
"contractVersion": "1.8.0",
|
|
4
4
|
"manifest": "manifest/artifact.v1.json",
|
|
5
5
|
"schemas": {
|
|
6
6
|
"artifactMetadata": "schema/artifact-metadata.v1.schema.json",
|
|
7
7
|
"artifactResolve": "schema/artifact-resolve.v1.schema.json",
|
|
8
8
|
"artifactPut": "schema/artifact-put.v1.schema.json",
|
|
9
|
+
"artifactDelete": "schema/artifact-delete.v1.schema.json",
|
|
9
10
|
"artifactImport": "schema/artifact-import.v1.schema.json",
|
|
10
11
|
"mediaReference": "schema/media-reference.v1.schema.json",
|
|
11
12
|
"artifactUpload": "schema/artifact-upload.v1.schema.json"
|
|
@@ -58,8 +58,42 @@
|
|
|
58
58
|
"type": "integer",
|
|
59
59
|
"minimum": 1,
|
|
60
60
|
"maximum": 9007199254740991
|
|
61
|
+
},
|
|
62
|
+
"temporary": {
|
|
63
|
+
"type": "boolean",
|
|
64
|
+
"default": false
|
|
65
|
+
},
|
|
66
|
+
"expiresAtUnixMs": {
|
|
67
|
+
"type": "integer",
|
|
68
|
+
"minimum": 1
|
|
61
69
|
}
|
|
62
|
-
}
|
|
70
|
+
},
|
|
71
|
+
"allOf": [
|
|
72
|
+
{
|
|
73
|
+
"if": {
|
|
74
|
+
"properties": {
|
|
75
|
+
"temporary": {
|
|
76
|
+
"const": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"required": [
|
|
80
|
+
"temporary"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
"then": {
|
|
84
|
+
"required": [
|
|
85
|
+
"expiresAtUnixMs"
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
"else": {
|
|
89
|
+
"not": {
|
|
90
|
+
"required": [
|
|
91
|
+
"expiresAtUnixMs"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
63
97
|
},
|
|
64
98
|
"request": {
|
|
65
99
|
"type": "object",
|
|
@@ -93,6 +127,10 @@
|
|
|
93
127
|
"type": "integer",
|
|
94
128
|
"minimum": 1,
|
|
95
129
|
"maximum": 9007199254740991
|
|
130
|
+
},
|
|
131
|
+
"temporary": {
|
|
132
|
+
"type": "boolean",
|
|
133
|
+
"default": false
|
|
96
134
|
}
|
|
97
135
|
}
|
|
98
136
|
},
|
|
@@ -3,54 +3,188 @@
|
|
|
3
3
|
"$id": "https://mhome.ai/schema/artifact-resolve.v1.schema.json",
|
|
4
4
|
"title": "mHome Artifact Resolve v1",
|
|
5
5
|
"oneOf": [
|
|
6
|
-
{
|
|
7
|
-
|
|
6
|
+
{
|
|
7
|
+
"$ref": "#/$defs/request"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"$ref": "#/$defs/response"
|
|
11
|
+
}
|
|
8
12
|
],
|
|
9
13
|
"$defs": {
|
|
10
14
|
"request": {
|
|
11
15
|
"type": "object",
|
|
12
16
|
"additionalProperties": false,
|
|
13
|
-
"required": [
|
|
17
|
+
"required": [
|
|
18
|
+
"uri"
|
|
19
|
+
],
|
|
14
20
|
"properties": {
|
|
15
|
-
"uri": {
|
|
21
|
+
"uri": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"pattern": "^meow-artifact://v1/",
|
|
24
|
+
"maxLength": 2048
|
|
25
|
+
}
|
|
16
26
|
}
|
|
17
27
|
},
|
|
18
28
|
"response": {
|
|
19
29
|
"type": "object",
|
|
20
30
|
"additionalProperties": false,
|
|
21
|
-
"required": [
|
|
31
|
+
"required": [
|
|
32
|
+
"uri",
|
|
33
|
+
"kind",
|
|
34
|
+
"mimeType",
|
|
35
|
+
"sizeBytes",
|
|
36
|
+
"delivery"
|
|
37
|
+
],
|
|
22
38
|
"properties": {
|
|
23
|
-
"uri": {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
39
|
+
"uri": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^meow-artifact://v1/",
|
|
42
|
+
"maxLength": 2048
|
|
43
|
+
},
|
|
44
|
+
"kind": {
|
|
45
|
+
"enum": [
|
|
46
|
+
"IMAGE",
|
|
47
|
+
"AUDIO",
|
|
48
|
+
"VIDEO",
|
|
49
|
+
"FILE"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"mimeType": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"minLength": 3,
|
|
55
|
+
"maxLength": 255
|
|
56
|
+
},
|
|
57
|
+
"sizeBytes": {
|
|
58
|
+
"type": "integer",
|
|
59
|
+
"minimum": 1,
|
|
60
|
+
"maximum": 9007199254740991
|
|
61
|
+
},
|
|
62
|
+
"width": {
|
|
63
|
+
"type": "integer",
|
|
64
|
+
"minimum": 1,
|
|
65
|
+
"maximum": 2147483647
|
|
66
|
+
},
|
|
67
|
+
"height": {
|
|
68
|
+
"type": "integer",
|
|
69
|
+
"minimum": 1,
|
|
70
|
+
"maximum": 2147483647
|
|
71
|
+
},
|
|
72
|
+
"durationMillis": {
|
|
73
|
+
"type": "integer",
|
|
74
|
+
"minimum": 1,
|
|
75
|
+
"maximum": 9007199254740991
|
|
76
|
+
},
|
|
30
77
|
"delivery": {
|
|
31
78
|
"oneOf": [
|
|
32
79
|
{
|
|
33
80
|
"type": "object",
|
|
34
81
|
"additionalProperties": false,
|
|
35
|
-
"required": [
|
|
82
|
+
"required": [
|
|
83
|
+
"type",
|
|
84
|
+
"dataUrl"
|
|
85
|
+
],
|
|
36
86
|
"properties": {
|
|
37
|
-
"type": {
|
|
38
|
-
|
|
87
|
+
"type": {
|
|
88
|
+
"const": "DATA_URL"
|
|
89
|
+
},
|
|
90
|
+
"dataUrl": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"pattern": "^data:[^;,]+;base64,.+$"
|
|
93
|
+
}
|
|
39
94
|
}
|
|
40
95
|
},
|
|
41
96
|
{
|
|
42
97
|
"type": "object",
|
|
43
98
|
"additionalProperties": false,
|
|
44
|
-
"required": [
|
|
99
|
+
"required": [
|
|
100
|
+
"type",
|
|
101
|
+
"url",
|
|
102
|
+
"expiresAtUnixMs"
|
|
103
|
+
],
|
|
45
104
|
"properties": {
|
|
46
|
-
"type": {
|
|
47
|
-
|
|
48
|
-
|
|
105
|
+
"type": {
|
|
106
|
+
"const": "SIGNED_URL"
|
|
107
|
+
},
|
|
108
|
+
"url": {
|
|
109
|
+
"type": "string",
|
|
110
|
+
"pattern": "^https?://"
|
|
111
|
+
},
|
|
112
|
+
"expiresAtUnixMs": {
|
|
113
|
+
"type": "integer",
|
|
114
|
+
"minimum": 1,
|
|
115
|
+
"maximum": 9007199254740991
|
|
116
|
+
}
|
|
49
117
|
}
|
|
50
118
|
}
|
|
51
119
|
]
|
|
120
|
+
},
|
|
121
|
+
"hostIdentity": {
|
|
122
|
+
"type": "object",
|
|
123
|
+
"additionalProperties": false,
|
|
124
|
+
"required": [
|
|
125
|
+
"hostId",
|
|
126
|
+
"publicKey"
|
|
127
|
+
],
|
|
128
|
+
"properties": {
|
|
129
|
+
"hostId": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"minLength": 1
|
|
132
|
+
},
|
|
133
|
+
"publicKey": {
|
|
134
|
+
"type": "object",
|
|
135
|
+
"additionalProperties": false,
|
|
136
|
+
"required": [
|
|
137
|
+
"x",
|
|
138
|
+
"y"
|
|
139
|
+
],
|
|
140
|
+
"properties": {
|
|
141
|
+
"x": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"pattern": "^[A-Za-z0-9_-]{43}$"
|
|
144
|
+
},
|
|
145
|
+
"y": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"pattern": "^[A-Za-z0-9_-]{43}$"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"temporary": {
|
|
154
|
+
"type": "boolean",
|
|
155
|
+
"default": false
|
|
156
|
+
},
|
|
157
|
+
"expiresAtUnixMs": {
|
|
158
|
+
"type": "integer",
|
|
159
|
+
"minimum": 1
|
|
52
160
|
}
|
|
53
|
-
}
|
|
161
|
+
},
|
|
162
|
+
"allOf": [
|
|
163
|
+
{
|
|
164
|
+
"if": {
|
|
165
|
+
"properties": {
|
|
166
|
+
"temporary": {
|
|
167
|
+
"const": true
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"required": [
|
|
171
|
+
"temporary"
|
|
172
|
+
]
|
|
173
|
+
},
|
|
174
|
+
"then": {
|
|
175
|
+
"required": [
|
|
176
|
+
"expiresAtUnixMs"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
"else": {
|
|
180
|
+
"not": {
|
|
181
|
+
"required": [
|
|
182
|
+
"expiresAtUnixMs"
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
]
|
|
54
188
|
}
|
|
55
189
|
}
|
|
56
190
|
}
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
"type": "integer",
|
|
48
48
|
"minimum": 1,
|
|
49
49
|
"maximum": 9007199254740991
|
|
50
|
+
},
|
|
51
|
+
"temporary": {
|
|
52
|
+
"type": "boolean",
|
|
53
|
+
"default": false
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
},
|
|
@@ -78,6 +82,38 @@
|
|
|
78
82
|
"type": "integer",
|
|
79
83
|
"minimum": 1,
|
|
80
84
|
"maximum": 9007199254740991
|
|
85
|
+
},
|
|
86
|
+
"hostIdentity": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"additionalProperties": false,
|
|
89
|
+
"required": [
|
|
90
|
+
"hostId",
|
|
91
|
+
"publicKey"
|
|
92
|
+
],
|
|
93
|
+
"properties": {
|
|
94
|
+
"hostId": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"minLength": 1
|
|
97
|
+
},
|
|
98
|
+
"publicKey": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"additionalProperties": false,
|
|
101
|
+
"required": [
|
|
102
|
+
"x",
|
|
103
|
+
"y"
|
|
104
|
+
],
|
|
105
|
+
"properties": {
|
|
106
|
+
"x": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"pattern": "^[A-Za-z0-9_-]{43}$"
|
|
109
|
+
},
|
|
110
|
+
"y": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"pattern": "^[A-Za-z0-9_-]{43}$"
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
81
117
|
}
|
|
82
118
|
}
|
|
83
119
|
}
|