@openwop/openwop-conformance 1.0.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/LICENSE +201 -0
- package/README.md +241 -0
- package/api/asyncapi.yaml +481 -0
- package/api/openapi.yaml +830 -0
- package/api/redocly.yaml +8 -0
- package/coverage.md +80 -0
- package/dist/cli.js +161 -0
- package/fixtures/conformance-a2a-task-roundtrip.json +27 -0
- package/fixtures/conformance-agent-identity.json +27 -0
- package/fixtures/conformance-agent-low-confidence.json +29 -0
- package/fixtures/conformance-agent-memory-cross-tenant.json +28 -0
- package/fixtures/conformance-agent-memory-redaction.json +32 -0
- package/fixtures/conformance-agent-memory-roundtrip.json +32 -0
- package/fixtures/conformance-agent-memory-ttl.json +31 -0
- package/fixtures/conformance-agent-pack-export.json +26 -0
- package/fixtures/conformance-agent-pack-install.json +26 -0
- package/fixtures/conformance-agent-pack-provenance.json +31 -0
- package/fixtures/conformance-agent-reasoning.json +29 -0
- package/fixtures/conformance-approval.json +27 -0
- package/fixtures/conformance-cancellable.json +33 -0
- package/fixtures/conformance-cap-breach.json +27 -0
- package/fixtures/conformance-capability-missing.json +23 -0
- package/fixtures/conformance-channel-ttl.json +60 -0
- package/fixtures/conformance-clarification.json +30 -0
- package/fixtures/conformance-conversation-capability-negotiation.json +23 -0
- package/fixtures/conformance-conversation-lifecycle.json +32 -0
- package/fixtures/conformance-conversation-replay.json +33 -0
- package/fixtures/conformance-conversation-vs-clarification.json +26 -0
- package/fixtures/conformance-delay.json +33 -0
- package/fixtures/conformance-dispatch-loop.json +38 -0
- package/fixtures/conformance-failure.json +23 -0
- package/fixtures/conformance-idempotent.json +30 -0
- package/fixtures/conformance-identity.json +32 -0
- package/fixtures/conformance-interrupt-auth-required.json +28 -0
- package/fixtures/conformance-interrupt-external-event.json +33 -0
- package/fixtures/conformance-interrupt-parent-child-cancel-child.json +27 -0
- package/fixtures/conformance-interrupt-parent-child-cancel.json +26 -0
- package/fixtures/conformance-interrupt-quorum.json +30 -0
- package/fixtures/conformance-mcp-tool-roundtrip.json +32 -0
- package/fixtures/conformance-message-reducer.json +31 -0
- package/fixtures/conformance-multi-node.json +21 -0
- package/fixtures/conformance-noop.json +23 -0
- package/fixtures/conformance-orchestrator-dispatch.json +47 -0
- package/fixtures/conformance-orchestrator-low-confidence.json +41 -0
- package/fixtures/conformance-orchestrator-terminate.json +44 -0
- package/fixtures/conformance-stream-text.json +26 -0
- package/fixtures/conformance-subworkflow-child.json +21 -0
- package/fixtures/conformance-subworkflow-parent.json +49 -0
- package/fixtures/conformance-version-fold.json +23 -0
- package/fixtures/conformance-wasm-pack-roundtrip.json +25 -0
- package/fixtures/pack-manifests/pack-private-example.json +26 -0
- package/fixtures.md +404 -0
- package/package.json +48 -0
- package/schemas/README.md +75 -0
- package/schemas/agent-manifest.schema.json +107 -0
- package/schemas/agent-ref.schema.json +53 -0
- package/schemas/capabilities.schema.json +287 -0
- package/schemas/channel-written-payload.schema.json +55 -0
- package/schemas/conversation-event.schema.json +120 -0
- package/schemas/conversation-turn.schema.json +72 -0
- package/schemas/debug-bundle.schema.json +196 -0
- package/schemas/dispatch-config.schema.json +46 -0
- package/schemas/error-envelope.schema.json +25 -0
- package/schemas/memory-entry.schema.json +36 -0
- package/schemas/memory-list-options.schema.json +21 -0
- package/schemas/node-pack-manifest.schema.json +235 -0
- package/schemas/orchestrator-decision.schema.json +60 -0
- package/schemas/run-event-payloads.schema.json +663 -0
- package/schemas/run-event.schema.json +116 -0
- package/schemas/run-options.schema.json +81 -0
- package/schemas/run-orchestrator-decided-event.schema.json +20 -0
- package/schemas/run-snapshot.schema.json +121 -0
- package/schemas/suspend-request.schema.json +182 -0
- package/schemas/workflow-definition.schema.json +430 -0
- package/src/cli.ts +187 -0
- package/src/lib/a2a-fake-peer.ts +233 -0
- package/src/lib/canaries.ts +186 -0
- package/src/lib/driver.ts +96 -0
- package/src/lib/env.ts +49 -0
- package/src/lib/fixtures.ts +93 -0
- package/src/lib/mcp-fake-server.ts +185 -0
- package/src/lib/multi-agent-capabilities.ts +155 -0
- package/src/lib/multiProcess.ts +141 -0
- package/src/lib/otel-collector.ts +312 -0
- package/src/lib/paths.ts +198 -0
- package/src/lib/polling.ts +81 -0
- package/src/lib/profiles.ts +258 -0
- package/src/lib/sse.ts +172 -0
- package/src/scenarios/a2a-task-roundtrip.test.ts +149 -0
- package/src/scenarios/agentConfidenceEscalation.test.ts +61 -0
- package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +54 -0
- package/src/scenarios/agentMemoryRedactionContract.test.ts +46 -0
- package/src/scenarios/agentMemoryRoundTrip.test.ts +52 -0
- package/src/scenarios/agentMemoryTtlExpiry.test.ts +47 -0
- package/src/scenarios/agentMessageReducer.test.ts +57 -0
- package/src/scenarios/agentMetadata.test.ts +56 -0
- package/src/scenarios/agentPackExport.test.ts +45 -0
- package/src/scenarios/agentPackInstall.test.ts +50 -0
- package/src/scenarios/agentPackProvenance.test.ts +53 -0
- package/src/scenarios/agentReasoningEvents.test.ts +72 -0
- package/src/scenarios/append-ordering.test.ts +91 -0
- package/src/scenarios/approval-payload.test.ts +120 -0
- package/src/scenarios/audit-log-integrity.test.ts +106 -0
- package/src/scenarios/auth.test.ts +55 -0
- package/src/scenarios/byok-roundtrip.test.ts +166 -0
- package/src/scenarios/cancellation.test.ts +68 -0
- package/src/scenarios/cap-breach.test.ts +149 -0
- package/src/scenarios/channel-ttl.test.ts +70 -0
- package/src/scenarios/configurable-schema.test.ts +76 -0
- package/src/scenarios/conversationCapabilityNegotiation.test.ts +39 -0
- package/src/scenarios/conversationLifecycle.test.ts +64 -0
- package/src/scenarios/conversationReplayDeterminism.test.ts +52 -0
- package/src/scenarios/conversationVsLegacySuspend.test.ts +46 -0
- package/src/scenarios/cost-attribution.test.ts +207 -0
- package/src/scenarios/debugBundle.test.ts +222 -0
- package/src/scenarios/discovery.test.ts +147 -0
- package/src/scenarios/dispatchLoop.test.ts +52 -0
- package/src/scenarios/errors.test.ts +144 -0
- package/src/scenarios/eventOrdering.test.ts +144 -0
- package/src/scenarios/failure-path.test.ts +46 -0
- package/src/scenarios/fixtures-gating.test.ts +137 -0
- package/src/scenarios/fixtures-valid.test.ts +140 -0
- package/src/scenarios/highConcurrency.test.ts +263 -0
- package/src/scenarios/idempotency.test.ts +83 -0
- package/src/scenarios/idempotencyRetry.test.ts +130 -0
- package/src/scenarios/identity-passthrough.test.ts +54 -0
- package/src/scenarios/interrupt-approval.test.ts +97 -0
- package/src/scenarios/interrupt-auth-required-resume.test.ts +88 -0
- package/src/scenarios/interrupt-clarification.test.ts +45 -0
- package/src/scenarios/interrupt-external-event-correlation.test.ts +113 -0
- package/src/scenarios/interrupt-parent-child-cascade.test.ts +102 -0
- package/src/scenarios/interrupt-quorum-resolution.test.ts +97 -0
- package/src/scenarios/interruptRace.test.ts +176 -0
- package/src/scenarios/maliciousManifest.test.ts +154 -0
- package/src/scenarios/mcp-discoverability.test.ts +129 -0
- package/src/scenarios/mcp-tool-roundtrip.test.ts +149 -0
- package/src/scenarios/multi-node-ordering.test.ts +60 -0
- package/src/scenarios/multi-region-idempotency.test.ts +52 -0
- package/src/scenarios/orchestratorConservativePath.test.ts +63 -0
- package/src/scenarios/orchestratorDispatch.test.ts +66 -0
- package/src/scenarios/orchestratorTermination.test.ts +54 -0
- package/src/scenarios/otel-emission.test.ts +113 -0
- package/src/scenarios/otel-trace-propagation.test.ts +90 -0
- package/src/scenarios/pack-registry-publish.test.ts +93 -0
- package/src/scenarios/pack-registry.test.ts +328 -0
- package/src/scenarios/pause-resume.test.ts +109 -0
- package/src/scenarios/policies.test.ts +162 -0
- package/src/scenarios/profileDerivation.test.ts +335 -0
- package/src/scenarios/providerPolicyEnforcement.test.ts +132 -0
- package/src/scenarios/rate-limit-envelope.test.ts +97 -0
- package/src/scenarios/redaction.test.ts +254 -0
- package/src/scenarios/redactionAdversarial.test.ts +162 -0
- package/src/scenarios/replay-fork-arbitrary.test.ts +347 -0
- package/src/scenarios/replay-fork.test.ts +216 -0
- package/src/scenarios/replayDeterminism.test.ts +171 -0
- package/src/scenarios/route-coverage.test.ts +129 -0
- package/src/scenarios/runs-lifecycle.test.ts +65 -0
- package/src/scenarios/runtime-capabilities.test.ts +118 -0
- package/src/scenarios/spec-corpus-validity.test.ts +1257 -0
- package/src/scenarios/staleClaim.test.ts +223 -0
- package/src/scenarios/stream-modes-buffer.test.ts +148 -0
- package/src/scenarios/stream-modes-mixed.test.ts +149 -0
- package/src/scenarios/stream-modes.test.ts +139 -0
- package/src/scenarios/streamReconnect.test.ts +162 -0
- package/src/scenarios/subworkflow.test.ts +126 -0
- package/src/scenarios/version-negotiation.test.ts +157 -0
- package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +47 -0
- package/src/scenarios/wasm-pack-invoke-completed.test.ts +69 -0
- package/src/scenarios/wasm-pack-invoke-suspended.test.ts +74 -0
- package/src/scenarios/wasm-pack-load.test.ts +75 -0
- package/src/scenarios/wasm-pack-memory-cap.test.ts +43 -0
- package/src/scenarios/wasm-pack-replay-determinism.test.ts +61 -0
- package/src/scenarios/webhook-sig-algorithm.test.ts +61 -0
- package/src/setup.ts +173 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
asyncapi: 3.1.0
|
|
2
|
+
|
|
3
|
+
info:
|
|
4
|
+
title: Workflow Orchestration Protocol (openwop) SSE Event Stream
|
|
5
|
+
version: "1.0"
|
|
6
|
+
externalDocs:
|
|
7
|
+
description: openwop spec v1 corpus
|
|
8
|
+
url: https://openwop.dev/spec/v1/
|
|
9
|
+
description: |
|
|
10
|
+
Canonical AsyncAPI 3.0 specification for the openwop server's
|
|
11
|
+
Server-Sent Events surface. Formalizes `stream-modes.md`
|
|
12
|
+
and references the run-event JSON Schema via `$ref` so external SDK
|
|
13
|
+
authors can codegen typed consumers without re-reading the prose.
|
|
14
|
+
|
|
15
|
+
Four canonical stream modes are exposed via the `streamMode` query
|
|
16
|
+
parameter on a single endpoint (`GET /v1/runs/{runId}/events`):
|
|
17
|
+
|
|
18
|
+
- `updates` — minimal state-change deltas (default; lowest bandwidth)
|
|
19
|
+
- `values` — full `state.snapshot` after every transition
|
|
20
|
+
- `messages` — LLM token chunks for chat-style UIs
|
|
21
|
+
- `debug` — full event firehose including internal events
|
|
22
|
+
|
|
23
|
+
Each mode is modeled as a separate AsyncAPI channel because the
|
|
24
|
+
payload union differs per mode. The underlying transport (HTTPS SSE)
|
|
25
|
+
is shared; only the filter + synthesis layer differs.
|
|
26
|
+
|
|
27
|
+
See `stream-modes.md` for the complete event-to-mode mapping table.
|
|
28
|
+
contact:
|
|
29
|
+
name: openwop spec working group
|
|
30
|
+
url: https://openwop.dev/spec/v1/
|
|
31
|
+
license:
|
|
32
|
+
name: Apache-2.0
|
|
33
|
+
|
|
34
|
+
defaultContentType: text/event-stream
|
|
35
|
+
|
|
36
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
+
# SERVERS
|
|
38
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
39
|
+
servers:
|
|
40
|
+
production:
|
|
41
|
+
host: '{host}'
|
|
42
|
+
pathname: /v1
|
|
43
|
+
protocol: https
|
|
44
|
+
description: openwop-compliant server
|
|
45
|
+
variables:
|
|
46
|
+
host:
|
|
47
|
+
default: api.example.com
|
|
48
|
+
description: Replace with your server's hostname.
|
|
49
|
+
security:
|
|
50
|
+
- $ref: '#/components/securitySchemes/ApiKeyAuth'
|
|
51
|
+
|
|
52
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
+
# CHANNELS — one per streamMode (filter contract differs)
|
|
54
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
+
channels:
|
|
56
|
+
|
|
57
|
+
runEventsUpdates:
|
|
58
|
+
address: /runs/{runId}/events
|
|
59
|
+
title: SSE — updates mode (default)
|
|
60
|
+
summary: Minimal state-change deltas for UI/CLI consumers.
|
|
61
|
+
description: |
|
|
62
|
+
Default consumption mode. Emits an SSE event for each terminal
|
|
63
|
+
node transition, suspension transition, run transition, and
|
|
64
|
+
artifact production. Payloads are deltas (the change since the
|
|
65
|
+
last event), NOT full snapshots.
|
|
66
|
+
|
|
67
|
+
Termination: server closes the connection on a terminal run
|
|
68
|
+
event (`run.completed`, `run.failed`, `run.cancelled`).
|
|
69
|
+
|
|
70
|
+
Selected via `?streamMode=updates` (or by omitting the query
|
|
71
|
+
parameter — `updates` is the default per `stream-modes.md`).
|
|
72
|
+
parameters:
|
|
73
|
+
runId:
|
|
74
|
+
$ref: '#/components/parameters/RunId'
|
|
75
|
+
messages:
|
|
76
|
+
runStarted: { $ref: '#/components/messages/RunStarted' }
|
|
77
|
+
runCompleted: { $ref: '#/components/messages/RunCompleted' }
|
|
78
|
+
runFailed: { $ref: '#/components/messages/RunFailed' }
|
|
79
|
+
runCancelled: { $ref: '#/components/messages/RunCancelled' }
|
|
80
|
+
runPaused: { $ref: '#/components/messages/RunPaused' }
|
|
81
|
+
runResumed: { $ref: '#/components/messages/RunResumed' }
|
|
82
|
+
nodeCompleted: { $ref: '#/components/messages/NodeCompleted' }
|
|
83
|
+
nodeFailed: { $ref: '#/components/messages/NodeFailed' }
|
|
84
|
+
nodeSkipped: { $ref: '#/components/messages/NodeSkipped' }
|
|
85
|
+
nodeSuspended: { $ref: '#/components/messages/NodeSuspended' }
|
|
86
|
+
approvalRequested: { $ref: '#/components/messages/ApprovalRequested' }
|
|
87
|
+
approvalReceived: { $ref: '#/components/messages/ApprovalReceived' }
|
|
88
|
+
clarificationRequested: { $ref: '#/components/messages/ClarificationRequested' }
|
|
89
|
+
clarificationResolved: { $ref: '#/components/messages/ClarificationResolved' }
|
|
90
|
+
interruptRequested: { $ref: '#/components/messages/InterruptRequested' }
|
|
91
|
+
interruptResolved: { $ref: '#/components/messages/InterruptResolved' }
|
|
92
|
+
artifactCreated: { $ref: '#/components/messages/ArtifactCreated' }
|
|
93
|
+
|
|
94
|
+
runEventsValues:
|
|
95
|
+
address: /runs/{runId}/events
|
|
96
|
+
title: SSE — values mode
|
|
97
|
+
summary: Full state snapshots after every transition.
|
|
98
|
+
description: |
|
|
99
|
+
Higher-bandwidth mode for consumers that don't maintain their
|
|
100
|
+
own state machine. Emits a synthesized `state.snapshot` event
|
|
101
|
+
after each `updates`-tier transition. Payload is the complete
|
|
102
|
+
`ProjectedRunState` (status, nodeStates, variables,
|
|
103
|
+
currentNodeId, channels).
|
|
104
|
+
|
|
105
|
+
On resumption (`Last-Event-ID` header), the server MUST emit a
|
|
106
|
+
fresh `state.snapshot` first so the resuming client gets a
|
|
107
|
+
baseline before continuing with subsequent snapshots.
|
|
108
|
+
|
|
109
|
+
Selected via `?streamMode=values`.
|
|
110
|
+
parameters:
|
|
111
|
+
runId:
|
|
112
|
+
$ref: '#/components/parameters/RunId'
|
|
113
|
+
messages:
|
|
114
|
+
stateSnapshot: { $ref: '#/components/messages/StateSnapshot' }
|
|
115
|
+
|
|
116
|
+
runEventsMessages:
|
|
117
|
+
address: /runs/{runId}/events
|
|
118
|
+
title: SSE — messages mode
|
|
119
|
+
summary: LLM token chunks for chat-style UIs.
|
|
120
|
+
description: |
|
|
121
|
+
Per-token chunks from any AI node currently streaming
|
|
122
|
+
(`core.ai.callPrompt`, `core.ai.generateFromPrompt`, etc).
|
|
123
|
+
Other event types are filtered out — consumers wanting state
|
|
124
|
+
transitions should pair this with a separate `updates` stream.
|
|
125
|
+
|
|
126
|
+
If no AI nodes execute during the run, the stream is empty
|
|
127
|
+
until termination.
|
|
128
|
+
|
|
129
|
+
Selected via `?streamMode=messages`.
|
|
130
|
+
parameters:
|
|
131
|
+
runId:
|
|
132
|
+
$ref: '#/components/parameters/RunId'
|
|
133
|
+
messages:
|
|
134
|
+
aiMessageChunk: { $ref: '#/components/messages/AiMessageChunk' }
|
|
135
|
+
|
|
136
|
+
runEventsDebug:
|
|
137
|
+
address: /runs/{runId}/events
|
|
138
|
+
title: SSE — debug mode
|
|
139
|
+
summary: Full event firehose including internal events.
|
|
140
|
+
description: |
|
|
141
|
+
Every `RunEventDoc` from the durable event log, including
|
|
142
|
+
events filtered out of `updates`: `log.appended`,
|
|
143
|
+
`variable.changed`, `version.pinned`, `lease.*`,
|
|
144
|
+
`node.retried`, internal projection writes, and any
|
|
145
|
+
vendor-extension events.
|
|
146
|
+
|
|
147
|
+
Highest bandwidth. Used by replay tools, debuggers, and
|
|
148
|
+
conformance tests.
|
|
149
|
+
|
|
150
|
+
Selected via `?streamMode=debug`.
|
|
151
|
+
parameters:
|
|
152
|
+
runId:
|
|
153
|
+
$ref: '#/components/parameters/RunId'
|
|
154
|
+
messages:
|
|
155
|
+
anyRunEvent: { $ref: '#/components/messages/AnyRunEvent' }
|
|
156
|
+
|
|
157
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
158
|
+
# OPERATIONS — consumer-side (receive)
|
|
159
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
160
|
+
operations:
|
|
161
|
+
|
|
162
|
+
subscribeUpdates:
|
|
163
|
+
action: receive
|
|
164
|
+
channel:
|
|
165
|
+
$ref: '#/channels/runEventsUpdates'
|
|
166
|
+
title: Subscribe to updates stream
|
|
167
|
+
summary: Receive minimal state-change events for a run.
|
|
168
|
+
description: |
|
|
169
|
+
Long-lived SSE subscription. Connection auto-closes on
|
|
170
|
+
terminal run event. Honor the `Last-Event-ID` request header
|
|
171
|
+
for resumption — server begins streaming from the sequence
|
|
172
|
+
AFTER the supplied ID and MUST NOT re-emit the resumption
|
|
173
|
+
point itself.
|
|
174
|
+
bindings:
|
|
175
|
+
http:
|
|
176
|
+
method: GET
|
|
177
|
+
query:
|
|
178
|
+
type: object
|
|
179
|
+
properties:
|
|
180
|
+
streamMode:
|
|
181
|
+
type: string
|
|
182
|
+
enum: [updates]
|
|
183
|
+
default: updates
|
|
184
|
+
|
|
185
|
+
subscribeValues:
|
|
186
|
+
action: receive
|
|
187
|
+
channel:
|
|
188
|
+
$ref: '#/channels/runEventsValues'
|
|
189
|
+
title: Subscribe to values stream
|
|
190
|
+
summary: Receive full state snapshots after every transition.
|
|
191
|
+
bindings:
|
|
192
|
+
http:
|
|
193
|
+
method: GET
|
|
194
|
+
query:
|
|
195
|
+
type: object
|
|
196
|
+
required: [streamMode]
|
|
197
|
+
properties:
|
|
198
|
+
streamMode:
|
|
199
|
+
type: string
|
|
200
|
+
enum: [values]
|
|
201
|
+
|
|
202
|
+
subscribeMessages:
|
|
203
|
+
action: receive
|
|
204
|
+
channel:
|
|
205
|
+
$ref: '#/channels/runEventsMessages'
|
|
206
|
+
title: Subscribe to messages stream
|
|
207
|
+
summary: Receive per-token AI chunks.
|
|
208
|
+
bindings:
|
|
209
|
+
http:
|
|
210
|
+
method: GET
|
|
211
|
+
query:
|
|
212
|
+
type: object
|
|
213
|
+
required: [streamMode]
|
|
214
|
+
properties:
|
|
215
|
+
streamMode:
|
|
216
|
+
type: string
|
|
217
|
+
enum: [messages]
|
|
218
|
+
|
|
219
|
+
subscribeDebug:
|
|
220
|
+
action: receive
|
|
221
|
+
channel:
|
|
222
|
+
$ref: '#/channels/runEventsDebug'
|
|
223
|
+
title: Subscribe to debug stream
|
|
224
|
+
summary: Receive every engine event including internal/log/lease.
|
|
225
|
+
bindings:
|
|
226
|
+
http:
|
|
227
|
+
method: GET
|
|
228
|
+
query:
|
|
229
|
+
type: object
|
|
230
|
+
required: [streamMode]
|
|
231
|
+
properties:
|
|
232
|
+
streamMode:
|
|
233
|
+
type: string
|
|
234
|
+
enum: [debug]
|
|
235
|
+
|
|
236
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
237
|
+
# COMPONENTS
|
|
238
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
239
|
+
components:
|
|
240
|
+
|
|
241
|
+
securitySchemes:
|
|
242
|
+
ApiKeyAuth:
|
|
243
|
+
type: httpApiKey
|
|
244
|
+
in: header
|
|
245
|
+
name: Authorization
|
|
246
|
+
description: |
|
|
247
|
+
Bearer-style API key. Format implementation-defined; reference
|
|
248
|
+
impl uses `hk_`/`hk_test_` prefixes. Required scopes:
|
|
249
|
+
`runs:read` to subscribe. See `auth.md`.
|
|
250
|
+
|
|
251
|
+
parameters:
|
|
252
|
+
RunId:
|
|
253
|
+
description: The run to subscribe to. Format opaque; clients MUST treat as a string.
|
|
254
|
+
|
|
255
|
+
# ── Messages ─────────────────────────────────────────────────────────────
|
|
256
|
+
# All `updates`/`debug`-mode messages share the canonical RunEventDoc shape
|
|
257
|
+
# (run-event.schema.json). Each named message below pins the `type` field
|
|
258
|
+
# to a specific RunEventType discriminator so codegens can emit narrowed
|
|
259
|
+
# consumer handlers.
|
|
260
|
+
|
|
261
|
+
messages:
|
|
262
|
+
|
|
263
|
+
# ── Run-lifecycle ────────────────────────────────────────────────────
|
|
264
|
+
RunStarted:
|
|
265
|
+
name: run.started
|
|
266
|
+
title: Run started
|
|
267
|
+
summary: A new run was registered and execution began.
|
|
268
|
+
contentType: application/json
|
|
269
|
+
payload:
|
|
270
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
271
|
+
|
|
272
|
+
RunCompleted:
|
|
273
|
+
name: run.completed
|
|
274
|
+
title: Run completed (terminal)
|
|
275
|
+
summary: Run reached terminal success state. SSE connection closes after this event.
|
|
276
|
+
contentType: application/json
|
|
277
|
+
payload:
|
|
278
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
279
|
+
|
|
280
|
+
RunFailed:
|
|
281
|
+
name: run.failed
|
|
282
|
+
title: Run failed (terminal)
|
|
283
|
+
summary: Run reached terminal failure state. SSE connection closes after this event.
|
|
284
|
+
contentType: application/json
|
|
285
|
+
payload:
|
|
286
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
287
|
+
|
|
288
|
+
RunCancelled:
|
|
289
|
+
name: run.cancelled
|
|
290
|
+
title: Run cancelled (terminal)
|
|
291
|
+
summary: Run was cancelled by user or admin. SSE connection closes after this event.
|
|
292
|
+
contentType: application/json
|
|
293
|
+
payload:
|
|
294
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
295
|
+
|
|
296
|
+
RunPaused:
|
|
297
|
+
name: run.paused
|
|
298
|
+
title: Run paused
|
|
299
|
+
summary: Run paused (e.g., capability limit reached, manual pause).
|
|
300
|
+
contentType: application/json
|
|
301
|
+
payload:
|
|
302
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
303
|
+
|
|
304
|
+
RunResumed:
|
|
305
|
+
name: run.resumed
|
|
306
|
+
title: Run resumed
|
|
307
|
+
summary: Run resumed from pause/suspend.
|
|
308
|
+
contentType: application/json
|
|
309
|
+
payload:
|
|
310
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
311
|
+
|
|
312
|
+
# ── Node-lifecycle ───────────────────────────────────────────────────
|
|
313
|
+
NodeCompleted:
|
|
314
|
+
name: node.completed
|
|
315
|
+
title: Node completed successfully
|
|
316
|
+
contentType: application/json
|
|
317
|
+
payload:
|
|
318
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
319
|
+
|
|
320
|
+
NodeFailed:
|
|
321
|
+
name: node.failed
|
|
322
|
+
title: Node failed
|
|
323
|
+
contentType: application/json
|
|
324
|
+
payload:
|
|
325
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
326
|
+
|
|
327
|
+
NodeSkipped:
|
|
328
|
+
name: node.skipped
|
|
329
|
+
title: Node skipped due to edge condition
|
|
330
|
+
contentType: application/json
|
|
331
|
+
payload:
|
|
332
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
333
|
+
|
|
334
|
+
NodeSuspended:
|
|
335
|
+
name: node.suspended
|
|
336
|
+
title: Node suspended (HITL or external-event wait)
|
|
337
|
+
contentType: application/json
|
|
338
|
+
payload:
|
|
339
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
340
|
+
|
|
341
|
+
# ── HITL ─────────────────────────────────────────────────────────────
|
|
342
|
+
ApprovalRequested:
|
|
343
|
+
name: approval.requested
|
|
344
|
+
title: Approval requested
|
|
345
|
+
summary: Engine emitted an approval interrupt awaiting user resolution.
|
|
346
|
+
contentType: application/json
|
|
347
|
+
payload:
|
|
348
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
349
|
+
|
|
350
|
+
ApprovalReceived:
|
|
351
|
+
name: approval.received
|
|
352
|
+
title: Approval received
|
|
353
|
+
summary: User resolved an approval interrupt (accept/reject/refine/edit).
|
|
354
|
+
contentType: application/json
|
|
355
|
+
payload:
|
|
356
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
357
|
+
|
|
358
|
+
ClarificationRequested:
|
|
359
|
+
name: clarification.requested
|
|
360
|
+
title: Clarification requested
|
|
361
|
+
contentType: application/json
|
|
362
|
+
payload:
|
|
363
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
364
|
+
|
|
365
|
+
ClarificationResolved:
|
|
366
|
+
name: clarification.resolved
|
|
367
|
+
title: Clarification resolved
|
|
368
|
+
contentType: application/json
|
|
369
|
+
payload:
|
|
370
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
371
|
+
|
|
372
|
+
InterruptRequested:
|
|
373
|
+
name: interrupt.requested
|
|
374
|
+
title: Interrupt requested (canonical HITL primitive)
|
|
375
|
+
summary: |
|
|
376
|
+
The discriminated-union form of approval/clarification/external-event/custom.
|
|
377
|
+
Servers emitting `interrupt.requested` SHOULD also emit the legacy
|
|
378
|
+
kind-specific event (`approval.requested` etc) for backward compat
|
|
379
|
+
until consumers migrate.
|
|
380
|
+
contentType: application/json
|
|
381
|
+
payload:
|
|
382
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
383
|
+
|
|
384
|
+
InterruptResolved:
|
|
385
|
+
name: interrupt.resolved
|
|
386
|
+
title: Interrupt resolved
|
|
387
|
+
contentType: application/json
|
|
388
|
+
payload:
|
|
389
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
390
|
+
|
|
391
|
+
# ── Artifacts ────────────────────────────────────────────────────────
|
|
392
|
+
ArtifactCreated:
|
|
393
|
+
name: artifact.created
|
|
394
|
+
title: Artifact produced by a node
|
|
395
|
+
summary: A typed artifact (PRD, plan, theme, etc) was created and registered.
|
|
396
|
+
contentType: application/json
|
|
397
|
+
payload:
|
|
398
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
399
|
+
|
|
400
|
+
# ── Synthesized for `values` mode ────────────────────────────────────
|
|
401
|
+
StateSnapshot:
|
|
402
|
+
name: state.snapshot
|
|
403
|
+
title: Full projected run state
|
|
404
|
+
summary: |
|
|
405
|
+
Synthesized event emitted by the server in `values` mode after
|
|
406
|
+
each `updates`-tier transition. NOT a member of the canonical
|
|
407
|
+
`RunEventType` enum — this is a per-mode synthetic.
|
|
408
|
+
contentType: application/json
|
|
409
|
+
payload:
|
|
410
|
+
$ref: '#/components/schemas/StateSnapshotPayload'
|
|
411
|
+
|
|
412
|
+
# ── Synthesized for `messages` mode ──────────────────────────────────
|
|
413
|
+
AiMessageChunk:
|
|
414
|
+
name: ai.message.chunk
|
|
415
|
+
title: AI token chunk
|
|
416
|
+
summary: Per-token streaming chunk from a `core.ai.*` node.
|
|
417
|
+
contentType: application/json
|
|
418
|
+
payload:
|
|
419
|
+
$ref: '#/components/schemas/AiMessageChunkPayload'
|
|
420
|
+
|
|
421
|
+
# ── Catch-all for `debug` mode ───────────────────────────────────────
|
|
422
|
+
AnyRunEvent:
|
|
423
|
+
name: any
|
|
424
|
+
title: Any RunEventDoc
|
|
425
|
+
summary: |
|
|
426
|
+
Type-erased handler for `debug` mode — discriminate on the
|
|
427
|
+
`type` field per the `RunEventType` enum in the run-event
|
|
428
|
+
JSON Schema. Includes events filtered out of `updates`:
|
|
429
|
+
`log.appended`, `variable.changed`, `version.pinned`,
|
|
430
|
+
`lease.*`, `node.retried`, `replay.diverged`, etc.
|
|
431
|
+
contentType: application/json
|
|
432
|
+
payload:
|
|
433
|
+
$ref: '#/components/schemas/RunEventDoc'
|
|
434
|
+
|
|
435
|
+
# ── Schemas ────────────────────────────────────────────────────────────
|
|
436
|
+
schemas:
|
|
437
|
+
|
|
438
|
+
# The canonical persisted-event shape. Defined externally so the same
|
|
439
|
+
# contract is shared with REST event-poll responses (rest-endpoints.md
|
|
440
|
+
# `GET /v1/runs/{runId}/events/poll`) and offline replay tools.
|
|
441
|
+
RunEventDoc:
|
|
442
|
+
$ref: '../schemas/run-event.schema.json'
|
|
443
|
+
|
|
444
|
+
StateSnapshotPayload:
|
|
445
|
+
# S1 closure (2026-04-27): reuse the canonical RunSnapshot
|
|
446
|
+
# projection shape verbatim. Same type returned by
|
|
447
|
+
# `GET /v1/runs/{runId}` — consumers can swap polling for
|
|
448
|
+
# values-mode SSE without re-modeling state.
|
|
449
|
+
$ref: '../schemas/run-snapshot.schema.json'
|
|
450
|
+
|
|
451
|
+
AiMessageChunkPayload:
|
|
452
|
+
# S2 closure (2026-04-27): tiered metadata. Bare {nodeId, runId,
|
|
453
|
+
# chunk, isLast} is the minimum compliant payload; `meta`
|
|
454
|
+
# adds Tier 1 typed slots (finishReason / logprobs / toolCalls /
|
|
455
|
+
# model / usage) and a Tier 2 provider-pass-through escape hatch.
|
|
456
|
+
# Schema definition lives at run-event-payloads.schema.json#$defs.outputChunk
|
|
457
|
+
# — referenced here verbatim so the SSE consumer + run-event log
|
|
458
|
+
# share a single shape contract.
|
|
459
|
+
type: object
|
|
460
|
+
required: [nodeId, runId, chunk, isLast]
|
|
461
|
+
properties:
|
|
462
|
+
nodeId: { type: string }
|
|
463
|
+
runId: { type: string }
|
|
464
|
+
chunk:
|
|
465
|
+
type: string
|
|
466
|
+
description: The new token(s) since the previous chunk.
|
|
467
|
+
isLast:
|
|
468
|
+
type: boolean
|
|
469
|
+
description: True for the final chunk of a given AI node call.
|
|
470
|
+
meta:
|
|
471
|
+
type: object
|
|
472
|
+
description: |
|
|
473
|
+
Tiered metadata. Tier 1: typed slots — `finishReason`
|
|
474
|
+
("stop"|"length"|"tool_calls"|"content_filter"), `logprobs`,
|
|
475
|
+
`toolCalls`, `model`, `usage` ({promptTokens,
|
|
476
|
+
completionTokens, totalTokens}). Tier 2: provider-pass-through
|
|
477
|
+
via `provider` + `providerExtensions`. Consumers SHOULD prefer
|
|
478
|
+
Tier 1; Tier 2 is the escape hatch for fields the spec hasn't
|
|
479
|
+
typed yet. See run-event-payloads.schema.json#$defs._chunkMeta
|
|
480
|
+
for the full definition + per-field constraints.
|
|
481
|
+
additionalProperties: true
|