dev.cocore.inference.dispatch
Schema Diff
+87 -1
Compatibility Analysis
Breaking Changes Detected
3 breaking changes, 27 non-breaking changes.
Breaking Changes (3)
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items", src: "dev.cocore.inference.dispatch:input.tools:items", tgt: "dev.cocore.inference.dispatch:input.tools:items.type", kind: "prop", name: Some("type") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items", src: "dev.cocore.inference.dispatch:input.tools:items", tgt: "dev.cocore.inference.dispatch:input.tools:items.function", kind: "prop", name: Some("function") }
- RequiredEdgeAdded RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function", src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.name", kind: "prop", name: Some("name") }
Non-Breaking Changes (27)
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.nonce" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.name" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.schema" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.strict" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.requireConfidential" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.toolChoice" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.toolChoiceFunction" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.description" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.name" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.parameters" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.type" }
- 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.outputSchema", kind: "prop", name: Some("outputSchema") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.requireConfidential", kind: "prop", name: Some("requireConfidential") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.toolChoice", kind: "prop", name: Some("toolChoice") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.toolChoiceFunction", kind: "prop", name: Some("toolChoiceFunction") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.tools", kind: "prop", name: Some("tools") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.name", kind: "prop", name: Some("name") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.schema", kind: "prop", name: Some("schema") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.strict", kind: "prop", name: Some("strict") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.tools", tgt: "dev.cocore.inference.dispatch:input.tools:items", kind: "items", name: None }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.description", kind: "prop", name: Some("description") }
- AddedEdge AddedEdge { src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.parameters", kind: "prop", name: Some("parameters") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.nonce" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.name" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.schema" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.outputSchema.strict" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.requireConfidential" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.toolChoice" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.toolChoiceFunction" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.description" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.name" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function.parameters" }AddedVertex { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.type" }
Additional Notes
- Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items.function", src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.name", kind: "prop", name: Some("name") }
- Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items", src: "dev.cocore.inference.dispatch:input.tools:items", tgt: "dev.cocore.inference.dispatch:input.tools:items.type", kind: "prop", name: Some("type") }
- Breaking: RequiredEdgeAdded { vertex_id: "dev.cocore.inference.dispatch:input.tools:items", src: "dev.cocore.inference.dispatch:input.tools:items", tgt: "dev.cocore.inference.dispatch:input.tools:items.function", kind: "prop", name: Some("function") }
- 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.outputSchema", kind: "prop", name: Some("outputSchema") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.requireConfidential", kind: "prop", name: Some("requireConfidential") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.toolChoice", kind: "prop", name: Some("toolChoice") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.toolChoiceFunction", kind: "prop", name: Some("toolChoiceFunction") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input", tgt: "dev.cocore.inference.dispatch:input.tools", kind: "prop", name: Some("tools") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.name", kind: "prop", name: Some("name") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.schema", kind: "prop", name: Some("schema") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.outputSchema", tgt: "dev.cocore.inference.dispatch:input.outputSchema.strict", kind: "prop", name: Some("strict") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.tools", tgt: "dev.cocore.inference.dispatch:input.tools:items", kind: "items", name: None }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.description", kind: "prop", name: Some("description") }
- Non-breaking: AddedEdge { src: "dev.cocore.inference.dispatch:input.tools:items.function", tgt: "dev.cocore.inference.dispatch:input.tools:items.function.parameters", kind: "prop", name: Some("parameters") }
1
1
{
2
2
"$type": "com.atproto.lexicon.schema",
3
3
"defs": {
4
4
"main": {
5
-
"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 }",
5
+
"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 }",
6
6
"errors": [
7
7
{
8
8
"description": "The caller is not authenticated.",
9
9
"name": "AuthRequired"
10
10
},
11
11
{
12
12
"description": "The body failed validation.",
13
13
"name": "InvalidRequest"
14
+
},
15
+
{
16
+
"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.",
17
+
"name": "ConfidentialUnavailable"
14
18
}
15
19
],
16
20
"input": {
17
21
"encoding": "application/json",
18
22
"schema": {
19
23
"properties": {
20
24
"maxTokensOut": {
21
25
"minimum": 1,
22
26
"type": "integer"
23
27
},
24
28
"model": {
25
29
"minLength": 1,
26
30
"type": "string"
27
31
},
32
+
"nonce": {
33
+
"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.",
34
+
"maxLength": 64,
35
+
"minLength": 32,
36
+
"type": "string"
37
+
},
38
+
"outputSchema": {
39
+
"description": "Optional JSON Schema to constrain the model output. When present, the published job record carries this schema and the provider passes it to the inference engine as response_format guided decoding. The schema is public (not encrypted) — it describes the output shape, not the input.",
40
+
"properties": {
41
+
"name": {
42
+
"description": "Schema name (maps to OpenAI response_format.json_schema.name).",
43
+
"type": "string"
44
+
},
45
+
"schema": {
46
+
"description": "The actual JSON Schema object that constrains the model output.",
47
+
"type": "object"
48
+
},
49
+
"strict": {
50
+
"description": "Whether to enforce strict schema adherence.",
51
+
"type": "boolean"
52
+
}
53
+
},
54
+
"type": "object"
55
+
},
28
56
"priceCeiling": {
29
57
"properties": {
30
58
"amount": {
31
59
"minimum": 0,
32
60
"type": "integer"
33
61
},
34
62
"currency": {
35
63
"minLength": 1,
36
64
"type": "string"
37
65
}
38
66
},
39
67
"required": [
40
68
"amount",
41
69
"currency"
42
70
],
43
71
"type": "object"
44
72
},
45
73
"prompt": {
46
74
"minLength": 1,
47
75
"type": "string"
48
76
},
77
+
"requireConfidential": {
78
+
"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.",
79
+
"type": "boolean"
80
+
},
49
81
"targetProviderDid": {
50
82
"description": "Pin dispatch to a specific provider DID instead of letting the advisor route.",
51
83
"format": "did",
52
84
"type": "string"
85
+
},
86
+
"toolChoice": {
87
+
"description": "Optional tool choice strategy. 'auto' (default), 'none', or 'required'. Additive.",
88
+
"knownValues": [
89
+
"auto",
90
+
"none",
91
+
"required"
92
+
],
93
+
"type": "string"
94
+
},
95
+
"toolChoiceFunction": {
96
+
"description": "When toolChoice is 'required', force the model to call this specific function. Maps to OpenAI tool_choice object form. Additive.",
97
+
"maxLength": 256,
98
+
"type": "string"
99
+
},
100
+
"tools": {
101
+
"description": "Optional list of tool/function definitions the model may call. Public (not encrypted). The published job record carries this list and the provider passes it to the inference engine.",
102
+
"items": {
103
+
"properties": {
104
+
"function": {
105
+
"properties": {
106
+
"description": {
107
+
"maxLength": 4096,
108
+
"type": "string"
109
+
},
110
+
"name": {
111
+
"maxLength": 256,
112
+
"type": "string"
113
+
},
114
+
"parameters": {
115
+
"description": "JSON Schema for the function's arguments.",
116
+
"type": "object"
117
+
}
118
+
},
119
+
"required": [
120
+
"name"
121
+
],
122
+
"type": "object"
123
+
},
124
+
"type": {
125
+
"knownValues": [
126
+
"function"
127
+
],
128
+
"type": "string"
129
+
}
130
+
},
131
+
"required": [
132
+
"type",
133
+
"function"
134
+
],
135
+
"type": "object"
136
+
},
137
+
"maxLength": 128,
138
+
"type": "array"
53
139
}
54
140
},
55
141
"required": [
56
142
"model",
57
143
"prompt",
58
144
"maxTokensOut",
59
145
"priceCeiling"
60
146
],
61
147
"type": "object"
62
148
}
63
149
},
64
150
"output": {
65
151
"description": "A Server-Sent Events stream of `meta`, `chunk`, `complete`, and `error` frames (see the method description for payloads).",
66
152
"encoding": "text/event-stream"
67
153
},
68
154
"type": "procedure"
69
155
}
70
156
},
71
157
"id": "dev.cocore.inference.dispatch",
72
158
"lexicon": 1
73
159
}