dev.cocore.inference.dispatch
Schema Diff
+15 -1
Compatibility Analysis
Breaking Changes Detected
2 breaking changes, 4 non-breaking changes.
Breaking Changes (2)
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.inference.dispatch:input.nonce", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.inference.dispatch:input.nonce", sort: "minLength", value: "32" }
Non-Breaking Changes (4)
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.nonce" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.requireConfidential" }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.nonce", kind: "prop", name: Some("nonce") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.requireConfidential", kind: "prop", name: Some("requireConfidential") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.nonce" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.requireConfidential" }
Constraint Changes
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.inference.dispatch:input.nonce", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.inference.dispatch:input.nonce", sort: "minLength", value: "32" }
Additional Notes
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.nonce", kind: "prop", name: Some("nonce") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.requireConfidential", kind: "prop", name: Some("requireConfidential") }
1
1
{
2
2
"id": "dev.cocore.inference.dispatch",
3
3
"defs": {
4
4
"main": {
5
5
"type": "procedure",
6
6
"input": {
7
7
"schema": {
8
8
"type": "object",
9
9
"required": [
10
10
"model",
11
11
"prompt",
12
12
"maxTokensOut",
13
13
"priceCeiling"
14
14
],
15
15
"properties": {
16
16
"model": {
17
17
"type": "string",
18
18
"minLength": 1
19
19
},
20
+
"nonce": {
21
+
"type": "string",
22
+
"maxLength": 64,
23
+
"minLength": 32,
24
+
"description": "Fresh lowercase-hex freshness challenge (>=16 random bytes) supplied by the caller when `requireConfidential` is set. The provider's enclave signs (ephemeralPubKey || nonce || attestationCid) so the caller can prove the ephemeral seal key was minted for THIS request and is not replayed. Required when requireConfidential is true; ignored otherwise."
25
+
},
20
26
"prompt": {
21
27
"type": "string",
22
28
"minLength": 1
23
29
},
24
30
"maxTokensOut": {
25
31
"type": "integer",
26
32
"minimum": 1
27
33
},
28
34
"priceCeiling": {
29
35
"type": "object",
30
36
"required": [
31
37
"amount",
32
38
"currency"
33
39
],
34
40
"properties": {
35
41
"amount": {
36
42
"type": "integer",
37
43
"minimum": 0
38
44
},
39
45
"currency": {
40
46
"type": "string",
41
47
"minLength": 1
42
48
}
43
49
}
44
50
},
45
51
"targetProviderDid": {
46
52
"type": "string",
47
53
"format": "did",
48
54
"description": "Pin dispatch to a specific provider DID instead of letting the advisor route."
55
+
},
56
+
"requireConfidential": {
57
+
"type": "boolean",
58
+
"description": "Demand the `attested-confidential` tier: the chosen provider must present a verified, signing-key-bound Apple MDA chain, a known-good measured cdHash, the hardened-runtime posture, and a fresh enclave-signed ephemeral session key bound to `nonce`. If no eligible provider is available the request fails closed with `ConfidentialUnavailable` rather than silently downgrading to best-effort. Optional / additive; absent or false means best-effort."
49
59
}
50
60
}
51
61
},
52
62
"encoding": "application/json"
53
63
},
54
64
"errors": [
55
65
{
56
66
"name": "AuthRequired",
57
67
"description": "The caller is not authenticated."
58
68
},
59
69
{
60
70
"name": "InvalidRequest",
61
71
"description": "The body failed validation."
72
+
},
73
+
{
74
+
"name": "ConfidentialUnavailable",
75
+
"description": "requireConfidential was set but no provider could satisfy the attested-confidential tier (no verified+bound MDA chain, cdHash not in the known-good set, posture failed, or the ephemeral session handshake did not verify). The request was NOT downgraded; no prompt was sealed."
62
76
}
63
77
],
64
78
"output": {
65
79
"encoding": "text/event-stream",
66
80
"description": "A Server-Sent Events stream of `meta`, `chunk`, `complete`, and `error` frames (see the method description for payloads)."
67
81
},
68
-
"description": "Submit an inference request and stream the result back as Server-Sent Events. Authenticates the requester, runs the dispatch core, and emits typed SSE frames. Unlike `submit` (which returns URIs to poll), `dispatch` drives the full request and streams plaintext output chunks until completion.\n\nSSE events:\n * `meta` — { jobUri, jobCid, authUri, inputCommitment, providerDid, sessionId }\n * `chunk` — { seq, text } (plaintext, decrypted)\n * `complete` — { tokensIn, tokensOut, receiptUri, providerCredit? }\n * `error` — { reason, code }"
82
+
"description": "Submit an inference request and stream the result back as Server-Sent Events. Authenticates the requester, runs the dispatch core, and emits typed SSE frames. Unlike `submit` (which returns URIs to poll), `dispatch` drives the full request and streams plaintext output chunks until completion.\n\nConfidentiality: by default the AppView seals the prompt to the chosen provider on the caller's behalf (`best-effort` tier) — convenient, but the AppView is in the plaintext path. A caller that needs privacy FROM the provider sets `requireConfidential` and supplies a fresh `nonce`; the AppView then runs the verified, enclave-bound ephemeral handshake and either confirms an `attested-confidential` session or fails closed with the `ConfidentialUnavailable` error. For genuine end-to-end confidentiality the prompt is sealed at the client edge (SDK/browser) and the AppView forwards ciphertext only; this method's server-side seal path is always `best-effort`.\n\nSSE events:\n * `meta` — { jobUri, jobCid, authUri, inputCommitment, providerDid, sessionId, tier }\n * `sessionKey` — { ephemeralPubKey, nonce, attestationCid, signature } (only when `requireConfidential`; the enclave-signed fresh key the requester verifies before sealing)\n * `chunk` — { seq, text } (plaintext, decrypted)\n * `complete` — { tokensIn, tokensOut, receiptUri, tier, providerCredit? }\n * `error` — { reason, code }"
69
83
}
70
84
},
71
85
"$type": "com.atproto.lexicon.schema",
72
86
"lexicon": 1
73
87
}