@openwop/openwop 1.9.0 → 2.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.
Files changed (60) hide show
  1. package/README.md +64 -117
  2. package/dist/client.d.ts +131 -245
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +233 -440
  5. package/dist/client.js.map +1 -1
  6. package/dist/cost-attribution.d.ts +2 -2
  7. package/dist/cost-attribution.js +2 -2
  8. package/dist/envelope-directive.d.ts +1 -1
  9. package/dist/envelope-directive.js +1 -1
  10. package/dist/event-helpers.js +1 -1
  11. package/dist/event-helpers.js.map +1 -1
  12. package/dist/generated.d.ts +17 -0
  13. package/dist/generated.d.ts.map +1 -0
  14. package/dist/generated.js +311 -0
  15. package/dist/generated.js.map +1 -0
  16. package/dist/index.d.ts +16 -18
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +26 -56
  19. package/dist/index.js.map +1 -1
  20. package/dist/run-helpers.d.ts +20 -21
  21. package/dist/run-helpers.d.ts.map +1 -1
  22. package/dist/run-helpers.js +23 -72
  23. package/dist/run-helpers.js.map +1 -1
  24. package/dist/sse.d.ts +33 -15
  25. package/dist/sse.d.ts.map +1 -1
  26. package/dist/sse.js +28 -30
  27. package/dist/sse.js.map +1 -1
  28. package/dist/types.d.ts +253 -559
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js.map +1 -1
  31. package/dist/webhook-header-families.d.ts +22 -13
  32. package/dist/webhook-header-families.d.ts.map +1 -1
  33. package/dist/webhook-header-families.js +30 -27
  34. package/dist/webhook-header-families.js.map +1 -1
  35. package/dist/webhook-helpers.browser.d.ts +15 -29
  36. package/dist/webhook-helpers.browser.d.ts.map +1 -1
  37. package/dist/webhook-helpers.browser.js +16 -31
  38. package/dist/webhook-helpers.browser.js.map +1 -1
  39. package/dist/webhook-helpers.d.ts +41 -41
  40. package/dist/webhook-helpers.d.ts.map +1 -1
  41. package/dist/webhook-helpers.js +40 -47
  42. package/dist/webhook-helpers.js.map +1 -1
  43. package/package.json +6 -4
  44. package/src/client.ts +255 -454
  45. package/src/cost-attribution.ts +2 -2
  46. package/src/envelope-directive.ts +1 -1
  47. package/src/event-helpers.ts +1 -1
  48. package/src/generated.ts +322 -0
  49. package/src/index.ts +78 -110
  50. package/src/run-helpers.ts +27 -85
  51. package/src/sse.ts +63 -42
  52. package/src/types.ts +268 -603
  53. package/src/webhook-header-families.ts +41 -29
  54. package/src/webhook-helpers.browser.ts +23 -32
  55. package/src/webhook-helpers.ts +67 -53
  56. package/dist/registry-helpers.d.ts +0 -118
  57. package/dist/registry-helpers.d.ts.map +0 -1
  58. package/dist/registry-helpers.js +0 -82
  59. package/dist/registry-helpers.js.map +0 -1
  60. package/src/registry-helpers.ts +0 -173
package/src/types.ts CHANGED
@@ -11,6 +11,8 @@
11
11
  * rather than relying on the SDK to refuse unknown values.
12
12
  */
13
13
 
14
+ import type { CapabilityFamilyKey, ErrorCode } from './generated.js';
15
+
14
16
  /** Run statuses per `RunSnapshot.status` in OpenAPI. */
15
17
  export type RunStatus =
16
18
  | 'pending'
@@ -27,176 +29,6 @@ export type RunStatus =
27
29
  | 'cancelling'
28
30
  | 'cancelled';
29
31
 
30
- export interface Capabilities {
31
- protocolVersion: string;
32
- supportedEnvelopes: readonly string[];
33
- schemaVersions: Record<string, number>;
34
- limits: {
35
- clarificationRounds: number;
36
- schemaRounds: number;
37
- envelopesPerTurn: number;
38
- maxNodeExecutions?: number;
39
- /** RFC 0058. Engine-side wall-clock ceiling per run (ms); upper bound for `RunConfigurable.runTimeoutMs`. */
40
- maxRunDurationMs?: number;
41
- /** RFC 0058. Engine-side agent-loop iteration ceiling; upper bound for `RunConfigurable.maxLoopIterations`. */
42
- maxLoopIterations?: number;
43
- /** RFC 0094 §H. Maximum REST request body size (bytes) the host
44
- * accepts. Hosts that advertise it MUST enforce it. */
45
- maxRequestBodyBytes?: number;
46
- };
47
- /** RFC 0094 §H. gRPC transport advertisement per `grpc-transport.md`
48
- * §"Capability advertisement". Absent ⇒ the host exposes no gRPC
49
- * transport. A host that exposes the gRPC surface advertises this
50
- * block AND includes `'grpc'` in `supportedTransports`. REST + SSE
51
- * remain exposed regardless. */
52
- grpc?: {
53
- /** Toggle — `true` when the gRPC surface is live. */
54
- supported: boolean;
55
- /** Full URI: `grpc://` (cleartext, intra-trusted-network only) OR
56
- * `grpcs://` (TLS). Hosts SHOULD require TLS in production. */
57
- endpoint?: string;
58
- /** Canonical service name. v1 hosts MUST use `openwop.v1.Engine`. */
59
- service: 'openwop.v1.Engine';
60
- /** TLS posture. Production hosts MUST set `'required'`. */
61
- tls: 'required' | 'optional' | 'disabled';
62
- };
63
- /** RFC 0101. Multi-party group-conversation advertisement. Absent ⇒ the
64
- * host does not support N agents co-participating in one shared
65
- * transcript (the single user + single driving agent shape of RFC 0005
66
- * remains). When `supported: true`, the host honors the additive
67
- * `participants: AgentRef[]` roster on `conversation.opened` and the
68
- * conditionally-required per-turn `speakerId` on `role: 'agent'`
69
- * conversation turns — advertising `supported: true` without enforcing
70
- * both is a dishonest claim (`OPENWOP_REQUIRE_BEHAVIOR=true` fails it). */
71
- multiPartyConversation?: {
72
- /** Toggle — `true` when the host supports multi-party conversations. */
73
- supported: boolean;
74
- /** Upper bound on `participants[]` size the host accepts. Absent ⇒
75
- * host-defined / unbounded. */
76
- maxParticipants?: number;
77
- };
78
- /** RFC 0100. Host exposes itself as an A2A (Agent2Agent) agent. `supported`
79
- * alone ⇒ the synchronous `message/send` → poll `tasks/get` round-trip
80
- * (`a2a-integration.md`). The optional flags gate the RFC 0100 async/durable
81
- * additions. Absent ⇒ no A2A advertisement. */
82
- a2a?: {
83
- /** Host exposes itself as an A2A agent. */
84
- supported: boolean;
85
- /** A2A 0.3 well-known agent card URL (`/.well-known/agent-card.json`). */
86
- agentCardUrl: string;
87
- /** `message/stream` + `tasks/resubscribe` (RFC 0100 §3 resubscribe re-attach). */
88
- streaming?: boolean;
89
- /** A2A push-notification config (RFC 0100 §4); a caller-supplied
90
- * `pushConfig.url` is SSRF-validated (`a2a-push-egress-ssrf`). */
91
- pushNotifications?: boolean;
92
- /** RFC 0100 §2. Host persists the projected `A2ATaskState` per backing run;
93
- * `tasks/get` returns live state after disconnect. Absent/false ⇒
94
- * synchronous round-trip only. */
95
- durableTasks?: boolean;
96
- };
97
- /** RFC 0109. Host stamps the optional non-secret `agent.model`
98
- * (`{ provider, model }`) on `role:'agent'` conversation turns, recording
99
- * which model produced the turn (read verbatim on `:fork`). Absent ⇒ no
100
- * provenance; the host omits `agent.model`. */
101
- conversationTurnModelProvenance?: {
102
- /** Toggle — `true` when the host stamps `agent.model`. */
103
- supported: boolean;
104
- };
105
- /** RFC 0110. Host emits the ephemeral `channel.presence` RunEvent (online +
106
- * per-member typing) for `type:'channel'` conversations. Presence is live
107
- * state — the host never persists it to the replayable event log and it
108
- * never affects replay / `:fork`. Membership-gated (default-deny, CTI-1).
109
- * Absent ⇒ no presence. */
110
- channelPresence?: {
111
- /** Toggle — `true` when the host emits `channel.presence`. */
112
- supported: boolean;
113
- };
114
- /** Capability advertisement for the host AI-proxy (`aiProviders` in
115
- * `capabilities.md`). Absent ⇒ the host advertises no AI-proxy surface.
116
- * Carries BYOK policy plus the RFC 0105/0106/0108 self-hosted / speech /
117
- * real-time-voice flags. The wire object MAY carry additional fields
118
- * (`input`, `authModes`, `maxInlineMediaBytes`) not modeled here. */
119
- aiProviders?: AIProvidersCapability;
120
- /** RFC 0104. Portable HITL approver-routing advertisement. When
121
- * `approverRouting.supported`, the host honors the OPTIONAL, ADVISORY
122
- * `approverGroupRefs` / `approverRoleRefs` / `audience` fields on the
123
- * `kind:'approval'` interrupt payload (the SDK carries the interrupt
124
- * payload opaquely as `data`, so those advisory fields ride that opaque
125
- * object), resolves the advertised `refKinds` against its own RBAC, and
126
- * ENFORCES eligibility at resolve time. Absent ⇒ the host ignores them. */
127
- interrupt?: {
128
- approverRouting?: {
129
- /** Host honors the RFC 0104 approver-routing fields. */
130
- supported: boolean;
131
- /** Ref kinds the host actually resolves: `'group'` ⇒ honors
132
- * `approverGroupRefs`, `'role'` ⇒ honors `approverRoleRefs`. Absent ⇒
133
- * advisory-only passthrough (the host resolves neither). */
134
- refKinds?: readonly ('group' | 'role')[];
135
- /** Host honors the `audience` notification-targeting override.
136
- * Absent/`false` ⇒ the host notifies the resolved eligible union. */
137
- audience?: boolean;
138
- };
139
- };
140
- /** RFC 0007 + RFC 0118. Top-level `core.dispatch` capability descriptors
141
- * (`capabilities.md` §`dispatch`). This is the discovery surface for
142
- * parallel sub-workflow fan-out/join. NOTE: distinct from the legacy
143
- * boolean {@link AgentsCapability.dispatch} — `dispatch.supported` here
144
- * carries the SAME "host implements the `core.dispatch` Core typeId"
145
- * meaning, exposed top-level per `capabilities.md` (the corpus advertises
146
- * it both nested under `agents` and at the doc root; absent ⇒ the host
147
- * advertises no top-level dispatch descriptors). Read-only. */
148
- dispatch?: DispatchCapability;
149
- /** RFC 0117 (amended by RFC 0119). Host loads SIGNED, SANDBOXED front-end
150
- * plugin packs (`kind:"frontend-plugin"`) in an origin/execution-isolated
151
- * sandbox and talks to them over the closed `ui-plugin/1` host-RPC boundary
152
- * (`capabilities.md` §`uiPlugins`). This is the DISCOVERY surface only — the
153
- * `ui-plugin/1` RPC envelope + the `frontend-plugin` manifest are a
154
- * renderer/registry concern the SDK does not model (as with the RFC 0102
155
- * A2UI `surface` and RFC 0071 pack manifests). Absent ⇒ the host loads no
156
- * plugin packs (graceful degradation to RFC 0071 host rendering). Read-only. */
157
- uiPlugins?: UiPluginsCapability;
158
- /** RFC 0113. Agent-memory capability descriptors. `injectionBudget` advertises
159
- * that the host honors `MemoryListOptions.tokenBudget` (a token-bounded
160
- * prefix of the ranked, SR-1-redacted, single-tenant entry list). Absent ⇒
161
- * a supplied `tokenBudget` is ignored (today's `limit`/`tag` behavior).
162
- * Read-only; the wire `memory` block MAY carry other descriptors not modeled
163
- * here (e.g. `search`). */
164
- memory?: {
165
- injectionBudget?: {
166
- /** Host honors `MemoryListOptions.tokenBudget` (RFC 0113). */
167
- supported: boolean;
168
- /** Unit `tokenBudget` is denominated in. `chars` counts UTF-8/Unicode
169
- * characters of the entry `content` (tokenizer-free). */
170
- tokenCounter?: 'o200k_base' | 'cl100k_base' | 'chars' | 'host-defined';
171
- };
172
- };
173
- /** RFC 0115. Conditional-GET + Content-Encoding negotiation on run reads
174
- * (`GET /v1/runs/{runId}`). Absent ⇒ the host returns today's `200` +
175
- * identity body. Distinct from the file-egress `fileHandling.transport`
176
- * (ftp/sftp/ssh) sub-capability — this advertises HTTP-layer poll economy
177
- * on the run-read REST surface. Read-only. */
178
- restTransport?: {
179
- /** Host emits a strong, event-log-sequence-derived `ETag` on
180
- * `GET /v1/runs/{runId}` and honors `If-None-Match` with a `304 Not
181
- * Modified` (empty body) when the validator matches the current state. */
182
- conditionalRunGet?: boolean;
183
- /** Content-Encoding values the host will negotiate on run reads. `gzip`
184
- * is the baseline; `br`/`zstd` are optional — the host advertises only
185
- * the subset it can serve. For each advertised value the decoded body is
186
- * byte-identical to the identity body. */
187
- contentEncodings?: readonly ('gzip' | 'br' | 'zstd')[];
188
- };
189
- extensions?: Record<string, unknown>;
190
- // Network-handshake superset (all `(future)` fields per capabilities.md)
191
- implementation?: { name?: string; version?: string; vendor?: string };
192
- engineVersion?: number;
193
- eventLogSchemaVersion?: number;
194
- supportedTransports?: readonly ('rest' | 'mcp' | 'a2a' | 'grpc')[];
195
- configurable?: Record<string, unknown>;
196
- observability?: Record<string, unknown>;
197
- minClientVersion?: string;
198
- }
199
-
200
32
  /**
201
33
  * The `kind` discriminator on a `cap.breached` event payload
202
34
  * (`run-event-payloads.schema.json#capBreached`). The four engine kinds, the
@@ -221,7 +53,7 @@ export type CapBreachedKind =
221
53
  * does not advertise `capabilities.compensation` omits the field; an
222
54
  * advertising host carries it on every snapshot, `none` when idle. The
223
55
  * value is the deterministic fold of the `compensation.*` events defined in
224
- * `spec/v1/compensation.md §"Run rollup: compensationStatus"`.
56
+ * `spec/v2/core/compensation.md §"Run rollup: compensationStatus"`.
225
57
  */
226
58
  export type CompensationStatus =
227
59
  | 'none'
@@ -232,10 +64,22 @@ export type CompensationStatus =
232
64
  | 'failed'
233
65
  | 'manual';
234
66
 
67
+ /** `RunSnapshot.owner` — closed; `subject` REQUIRED (identity.md). */
68
+ export interface RunOwner {
69
+ tenant: string;
70
+ workspace?: string;
71
+ subject: string;
72
+ }
73
+
74
+ /** `schemas/v2/run-snapshot.schema.json` — the fold of the event log through the run projection (runs.md §Snapshot). */
235
75
  export interface RunSnapshot {
236
76
  runId: string;
237
77
  workflowId: string;
238
78
  status: RunStatus;
79
+ owner: RunOwner;
80
+ /** The era key, integer ≥ 2; a v2 host stamps `3` on every run it creates. */
81
+ eventLogSchemaVersion: number;
82
+ engineVersion?: number;
239
83
  /** RFC 0151 §D. Present iff the host advertises `capabilities.compensation`.
240
84
  * See {@link CompensationStatus}. */
241
85
  compensationStatus?: CompensationStatus;
@@ -245,7 +89,25 @@ export interface RunSnapshot {
245
89
  nodeStates?: Record<string, unknown>;
246
90
  variables?: Record<string, unknown>;
247
91
  channels?: Record<string, unknown>;
248
- error?: { code?: string; message?: string };
92
+ /** `{ code, message, details? }` on terminal `failed`. */
93
+ error?: { code: string; message: string; details?: Record<string, unknown> };
94
+ /** The persisted `RunOptions` (runs.md §Run options). */
95
+ configurable?: RunConfigurable;
96
+ tags?: readonly string[];
97
+ metadata?: Record<string, unknown>;
98
+ agent?: AgentRef;
99
+ /** MUST NOT change for the run's lifetime. */
100
+ runOrchestrator?: AgentRef;
101
+ metrics?: {
102
+ openwopCost?: {
103
+ usd?: number;
104
+ tokens?: { input?: number; output?: number };
105
+ model?: string;
106
+ provider?: string;
107
+ duration_ms?: number;
108
+ };
109
+ [key: string]: unknown;
110
+ };
249
111
  /** Linkage back to the parent run when this run was spawned via
250
112
  * `core.subWorkflow`. Per `interrupt-profiles.md §openwop-interrupt-
251
113
  * cascade-cancel`: child runs preserve `parentRunId` + `parentNodeId`
@@ -254,7 +116,7 @@ export interface RunSnapshot {
254
116
  parentNodeId?: string;
255
117
  /** Surfaced for `waiting-*` runs per `interrupt.md §"Signed-token
256
118
  * callback"`. Carries the open interrupt's metadata so clients can
257
- * resolve via `POST /v1/interrupts/{token}` without consulting a
119
+ * resolve via `POST /interrupts/{token}` without consulting a
258
120
  * separate endpoint. Hosts MAY omit `data` to keep payloads small;
259
121
  * the token + callbackUrl are the load-bearing fields. */
260
122
  interrupt?: {
@@ -267,32 +129,48 @@ export interface RunSnapshot {
267
129
  }
268
130
 
269
131
  /**
270
- * Per-run parameter overlay carried in `RunOptions.configurable`. Reserved
271
- * keys are typed; unknown keys are passed through verbatim. See
272
- * `run-options.md`.
132
+ * `schemas/v2/configurable.schema.json` closed, nested and versioned (RFC
133
+ * 0171 §D.1; runs.md §Run options). `version` is REQUIRED and is `1`. An
134
+ * unknown root key, an unknown key inside a section, or a dotted key is
135
+ * rejected with `400 validation_error`; vendor keys live under
136
+ * `extensions.<org>`.
273
137
  */
274
138
  export interface RunConfigurable {
275
- /** Override the per-run node-execution ceiling. Clamped server-side. */
276
- recursionLimit?: number;
277
- /** RFC 0058. Wall-clock run deadline (ms from `run.started`); clamped to
278
- * `Capabilities.limits.maxRunDurationMs`. Breach → `cap.breached
279
- * { kind: 'run-duration' }` + `run_timeout`. */
280
- runTimeoutMs?: number;
281
- /** RFC 0058. Agent-loop iteration ceiling (one per orchestrator turn);
282
- * clamped to `Capabilities.limits.maxLoopIterations`. Breach →
283
- * `cap.breached { kind: 'loop-iterations' }` + `loop_limit_exceeded`.
284
- * Ignored unless the host advertises `capabilities.agents.loop.supported`. */
285
- maxLoopIterations?: number;
286
- /** Override AI model for nodes that consume `ctx.config.configurable.model`. */
287
- model?: string;
288
- /** Override AI temperature (server SHOULD enforce 0..2). */
289
- temperature?: number;
290
- /** Override AI max-tokens cap. */
291
- maxTokens?: number;
292
- /** Per-prompt-ID variant override map. */
293
- promptOverrides?: Record<string, string>;
294
- /** Implementation-specific extensions; passed through verbatim. */
295
- [key: string]: unknown;
139
+ version: 1;
140
+ run?: {
141
+ /** Clamped to `limits.maxNodeExecutions`. */
142
+ recursionLimit?: number;
143
+ /** Resolves to `min(runTimeoutMs, limits.maxRunDurationMs)`; breach → `run_timeout`. */
144
+ runTimeoutMs?: number;
145
+ /** Resolves against `limits.maxLoopIterations`; breach `loop_limit_exceeded`. */
146
+ maxLoopIterations?: number;
147
+ /** The `low-confidence` interrupt threshold. */
148
+ escalationThreshold?: number;
149
+ };
150
+ ai?: {
151
+ /** MUST be in `aiProviders.supported`, else `400 validation_error`. */
152
+ provider?: string;
153
+ model?: string;
154
+ /** 0..2 */
155
+ temperature?: number;
156
+ maxTokens?: number;
157
+ /** References a provider in `aiProviders.byok`; never carries key material. */
158
+ credentialRef?: string;
159
+ promptOverrides?: Record<string, string>;
160
+ /** Test-keys-only; `403 mock_provider_forbidden` on a production credential. */
161
+ mockProvider?: string;
162
+ reasoningVerbosity?: 'none' | 'summary' | 'full';
163
+ /** The `envelope.refusal` ceiling (events.md E5). */
164
+ maxRefusals?: number;
165
+ };
166
+ distillation?: {
167
+ /** Resolves to `min(tokenBudget, memory.distillation.maxTokenBudget)`. */
168
+ tokenBudget?: number;
169
+ };
170
+ /** `schemas/v2/budget-policy.schema.json`. */
171
+ budget?: Record<string, unknown>;
172
+ /** A vendor key lives under its registered org and nowhere else. */
173
+ extensions?: Record<string, Record<string, unknown>>;
296
174
  }
297
175
 
298
176
  export interface CreateRunRequest {
@@ -305,6 +183,9 @@ export interface CreateRunRequest {
305
183
  inputs?: Record<string, unknown>;
306
184
  tenantId?: string;
307
185
  scopeId?: string;
186
+ /** `schemas/v2/residency.schema.json`; an unadvertised `region` → `422 residency_unavailable`. */
187
+ residency?: { region?: string; [key: string]: unknown };
188
+ /** The signed-token callback (interrupt.md). */
308
189
  callbackUrl?: string;
309
190
  configurable?: RunConfigurable;
310
191
  tags?: readonly string[];
@@ -333,35 +214,6 @@ export interface CancelRunResponse {
333
214
  status: 'cancelled' | 'cancelling';
334
215
  }
335
216
 
336
- /**
337
- * Portable JSON diagnostic export for a single run per
338
- * `spec/v1/debug-bundle.md` + `schemas/debug-bundle.schema.json`.
339
- *
340
- * Hosts MAY omit non-required fields. Consumers MUST treat masked /
341
- * omitted / hashed values as the spec-canonical content per the host's
342
- * advertised `redactionMode` — they are NOT placeholders for missing
343
- * data.
344
- */
345
- export interface DebugBundle {
346
- bundleVersion: string;
347
- generatedAt: string;
348
- host: { name?: string; version?: string; vendor?: string };
349
- run: Record<string, unknown>;
350
- events: ReadonlyArray<Record<string, unknown>>;
351
- redactionApplied: boolean;
352
- /** Reflects the host's `capabilities.compliance.defaultMode`. */
353
- redactionMode: 'mask' | 'omit' | 'hash' | 'passthrough';
354
- /** True when the bundle hit the host's size cap; pair with `truncatedReason`. */
355
- truncated?: boolean;
356
- truncatedReason?: string;
357
- [key: string]: unknown;
358
- }
359
-
360
- export interface DebugBundleOptions {
361
- /** Optional host-extension query parameter to lower the size cap for testing. Spec-canonical hosts SHOULD prefer `host.<vendor>.<query>` namespacing; this is the SQLite-reference convention. */
362
- maxEvents?: number;
363
- }
364
-
365
217
  export interface RegisterWebhookRequest {
366
218
  /** Receiver URL the host will POST signed deliveries to. */
367
219
  url: string;
@@ -407,7 +259,7 @@ export interface ResumeRunResponse {
407
259
  resumedAt?: string;
408
260
  }
409
261
 
410
- // rest-endpoints.md §"POST /v1/runs:bulk-cancel" (closes R1).
262
+ // rest-endpoints.md §"POST /runs:bulk-cancel" (closes R1).
411
263
  export interface BulkCancelRunsRequest {
412
264
  runIds: readonly string[];
413
265
  reason?: string;
@@ -491,28 +343,8 @@ export interface CreateAnnotationRequest {
491
343
  note?: string;
492
344
  }
493
345
 
494
- /** RFC 0059 versioned, tenant·workspace-scoped ground-truth file
495
- * (`workspace-file.schema.json`). The `list` endpoint returns this shape
496
- * minus `content` (metadata only). */
497
- export interface WorkspaceFile {
498
- path: string;
499
- content: string;
500
- contentType?: string;
501
- version: number;
502
- etag?: string;
503
- updatedAt: string;
504
- }
505
-
506
- /** RFC 0059 request body for `putWorkspaceFile` (`workspace-file-create.schema.json`).
507
- * `path` is URL-bound; the host assigns `version`/`etag`/`updatedAt`.
508
- * Optimistic concurrency is expressed via the `If-Match` header, not the body. */
509
- export interface PutWorkspaceFileRequest {
510
- content: string;
511
- contentType?: string;
512
- }
513
-
514
346
  /**
515
- * Response from `GET /v1/runs/{runId}/ancestry` — RFC 0040 §C cross-host
347
+ * Response from `GET /runs/{runId}/ancestry` — RFC 0040 §C cross-host
516
348
  * composition parent. `parent: null` for top-level runs (not dispatched
517
349
  * from any other run); otherwise `parent.wellKnownUrl` is set when the
518
350
  * parent is on a different host so callers can walk the chain.
@@ -532,7 +364,7 @@ export interface RunAncestryResponse {
532
364
  };
533
365
  }
534
366
 
535
- /** RFC 0054 — response from `GET /v1/runs/{runId}:diff?against={otherRunId}`.
367
+ /** RFC 0054 — response from `GET /runs/{runId}:diff?against={otherRunId}`.
536
368
  * Mirror of `run-diff-response.schema.json`. Deterministic, replay-aware
537
369
  * structured diff of two runs' event sequences + terminal states. */
538
370
  export interface RunDiffEventDiff {
@@ -596,9 +428,16 @@ export interface ResolveInterruptByTokenResponse {
596
428
  [key: string]: unknown;
597
429
  }
598
430
 
431
+ /** `GET /runs/{runId}/events/poll` response (events.md §Poll) — closed. */
599
432
  export interface PollEventsResponse {
433
+ runId: string;
600
434
  events: readonly RunEventDoc[];
601
- isComplete: boolean;
435
+ /** The highest sequence in the log at the time of the response; `-1` when the log is empty. */
436
+ lastSequence: number;
437
+ /** The snapshot status. */
438
+ status: RunStatus;
439
+ /** Whether the run is terminal. */
440
+ isTerminal: boolean;
602
441
  }
603
442
 
604
443
  /** Mirror of `run-event.schema.json` — top-level shape only. */
@@ -609,109 +448,184 @@ export interface RunEventDoc {
609
448
  type: string; // RunEventType — string-typed for forward compat
610
449
  payload: unknown;
611
450
  timestamp: string;
451
+ /** The one ordering field: integer ≥ 0, first event `0`, strictly increasing per run. */
612
452
  sequence: number;
613
- schemaVersion?: number;
614
- engineVersion?: string;
453
+ /** Per-event schema version, integer ≥ 1 (RFC 0172 §B axis 5). */
454
+ schemaVersion: number;
455
+ /** Integer ≥ 0 everywhere (RFC 0172 §B axis 3). */
456
+ engineVersion?: number;
615
457
  causationId?: string;
616
458
  }
617
459
 
460
+ /**
461
+ * A vendor error code: `<org>.<name>` with the org registered in
462
+ * `spec/v2/declaration.json`; `openwop.` is reserved (errors.md). The template
463
+ * literal keeps `ErrorEnvelope.error` open to registered vendor codes while
464
+ * every protocol code is a member of the generated {@link ErrorCode} union.
465
+ */
466
+ export type VendorErrorCode = `${string}.${string}`;
467
+
468
+ /** `{ error, message, details? }` and nothing else (errors.md §The envelope). */
618
469
  export interface ErrorEnvelope {
619
- error: string;
470
+ error: ErrorCode | VendorErrorCode;
620
471
  message: string;
621
472
  details?: Record<string, unknown>;
622
473
  }
623
474
 
624
475
  export type StreamMode = 'values' | 'updates' | 'messages' | 'debug';
625
476
 
626
- // ─── BYOK / AI providers (Phase H.1 + H.1″) ─────────────────────────────
477
+ // ─── Discovery: the closed v2 root (capabilities.md; RFC 0169, 0172, 0176) ──
627
478
 
628
- /**
629
- * AI policy mode advertised by the host per `capabilities.md`
630
- * §`aiProviders.policies`. Hosts MAY advertise a subset; clients MUST
631
- * tolerate any subset.
632
- *
633
- * - `disabled` — provider MUST NOT be used at all
634
- * - `optional` — no restriction (default)
635
- * - `required` — provider call MUST carry a `credentialRef`
636
- * - `restricted` — model MUST match the policy's `allowedModels`
637
- */
638
- export type AIPolicyMode = 'disabled' | 'optional' | 'required' | 'restricted';
479
+ /** Maturity of a capability record. */
480
+ export type CapabilityStatus = 'stable' | 'experimental' | 'deprecated';
481
+
482
+ /** The five wire-legal witness classes (RFC 0168 §B); `unwitnessable` never appears on the wire. */
483
+ export type WitnessClass =
484
+ | 'witnessable-unaided'
485
+ | 'witnessable-gated'
486
+ | 'seam-gated'
487
+ | 'claims-check'
488
+ | 'negative-existence';
639
489
 
640
490
  /**
641
- * Closed-set deny reason returned in `provider_policy_denied.details.reason`
642
- * per spec §"Wire-format error".
491
+ * One capability record (RFC 0169 §A). `status`, `since` and `witness` are
492
+ * REQUIRED; `until` is REQUIRED when `status` is `experimental` or
493
+ * `deprecated` and MUST NOT be present when `stable`. `supported` does not
494
+ * exist — presence of the record is the claim. The remaining members are the
495
+ * family's facets (`spec/v2/facets/<key>.schema.json` where hand-decided).
643
496
  */
644
- export type AIPolicyDenyReason =
645
- | 'provider_disabled'
646
- | 'byok_required'
647
- | 'byok_required_but_unresolved'
648
- | 'model_not_allowed';
497
+ export interface CapabilityRecord {
498
+ status: CapabilityStatus;
499
+ /** `<major>.<minor>` */
500
+ since: string;
501
+ /** `<major>.<minor>` or `YYYY-MM-DD` */
502
+ until?: string;
503
+ witness: WitnessClass;
504
+ [facet: string]: unknown;
505
+ }
506
+
507
+ /** A version-axis grammar: `<major>.<minor>` with no leading zero (RFC 0149 §C). */
508
+ export type ProtocolVersion = `${number}.${number}`;
649
509
 
650
510
  /**
651
- * Capability advertisement payload mirroring spec §`aiProviders` +
652
- * §`aiProviders.policies`. Optional sub-fields are absent on hosts
653
- * that don't enforce per-provider policies.
511
+ * The closed v2 discovery root (`schemas/v2/capabilities.schema.json`,
512
+ * `additionalProperties: false`). Every key is one of the generated
513
+ * {@link CapabilityMetadataKey}s, a family key ({@link CapabilityFamilyKey})
514
+ * carrying a {@link CapabilityRecord}, or `extensions`. `protocolVersions`
515
+ * and `preferredVersion` are REQUIRED (versioning.md §1.1).
654
516
  */
655
- export interface AIProvidersCapability {
656
- /** Provider ids the host's AI-proxy can route to. Optional per
657
- * `capabilities.schema.json` (the `aiProviders` block has no required
658
- * fields); a host advertising the block normally lists them. */
659
- supported?: readonly string[];
660
- /** Subset of `supported` for which BYOK is permitted. */
661
- byok?: readonly string[];
662
- /** Optional 4-mode policy enforcement advertisement. */
663
- policies?: {
664
- modes: readonly AIPolicyMode[];
665
- scopes?: readonly string[];
666
- errorCode?: string;
667
- };
668
- /** RFC 0108. Subset of `supported` whose entries are operator-/tenant-
669
- * configured OpenAI-compatible endpoints (Ollama / vLLM / LM Studio / any
670
- * `/v1/chat/completions`-compatible server), as opposed to a host-managed
671
- * connection to a known public vendor. Each entry also appears in
672
- * `supported` and MAY also appear in `byok`. The id is an OPAQUE label that
673
- * MUST NOT encode the endpoint's network location (RFC 0108 §A.3), and a
674
- * client MUST NOT infer model capabilities from it (§B) — the authoritative
675
- * sources are `modelCapabilities.advertised[]` and `aiProviders.input`. */
676
- selfHosted?: readonly string[];
677
- /** RFC 0105. Present (value MUST be `'supported'`) ⇒ the host exposes speech
678
- * synthesis via the host-side `ctx.callSpeechSynthesizer`. Absent ⇒ no TTS
679
- * (a call is rejected with `speech_synthesis_unsupported`). */
680
- speechSynthesis?: 'supported';
681
- /** RFC 0106. Optional real-time voice profile. Absent ⇒ no live voice. The
682
- * sub-flags gate streaming STT / chunked TTS and turn-taking; the host
683
- * enforces that `turnDetection`/`bargeIn` require `transcription`. */
684
- realtimeVoice?: {
685
- /** Present (`'streaming'`) ⇒ host exposes streaming `ctx.callTranscriber`. */
686
- transcription?: 'streaming';
687
- /** Present (`'streaming'`) ⇒ `ctx.callSpeechSynthesizer` honors `stream:true`.
688
- * Requires `aiProviders.speechSynthesis: 'supported'`. */
689
- synthesis?: 'streaming';
690
- /** Endpointing sophistication; requires `transcription`. */
691
- turnDetection?: 'vad' | 'semantic';
692
- /** Present (`'supported'`) ⇒ host emits `voice.barge_in`/`voice.cancelled`
693
- * on overlapping speech; requires `transcription`. */
694
- bargeIn?: 'supported';
695
- };
696
- /** RFC 0116. Provider-scoped advert that the host honors the AI-envelope
697
- * `generate` request's optional `cachePrefixId` (a tenant-namespaced,
698
- * secret-free label) as a routing hint into the routed provider's
699
- * server-side context cache. Absent the host ignores `cachePrefixId`
700
- * (no error). The cache MUST be keyed by `(resolved tenant, cachePrefixId)`
701
- * (SECURITY invariant `prompt-prefix-cache-cross-tenant-isolation`) and a
702
- * hit/miss MUST NOT change the recorded envelope or
703
- * `provider.usage.inputTokens`/`outputTokens` (replay-invariant). NOT a
704
- * universal claim — `providers` scopes it per routed provider. */
705
- promptPrefixCache?: {
706
- /** Whether the host honors `cachePrefixId`. */
707
- supported: boolean;
708
- /** Subset of `supported` for which `cachePrefixId` is honored (prefix
709
- * caching is provider-specific, e.g. Anthropic ephemeral). A request
710
- * whose routed provider is not listed has `cachePrefixId` ignored. */
711
- providers?: readonly string[];
517
+ export type Capabilities = {
518
+ /** Every `<major>.<minor>` this host serves. */
519
+ protocolVersions: readonly ProtocolVersion[];
520
+ /** The header-less default; MUST be a member of `protocolVersions[]`. */
521
+ preferredVersion: ProtocolVersion;
522
+ /** Kept as `preferredVersion`'s twin for v1 readers through the overlap. */
523
+ protocolVersion?: ProtocolVersion;
524
+ /** RFC 0172 row C5.8 — a host MAY refuse a client below it with `426 client_version_unsupported`. */
525
+ minClientVersion?: string;
526
+ /** Integer everywhere (RFC 0172 §B axis 3). */
527
+ engineVersion?: number;
528
+ /** The era key; a v2 host writes `3`. */
529
+ eventLogSchemaVersion?: number;
530
+ implementation?: { name?: string; version?: string; vendor?: string };
531
+ /** `extensions.<org>.<name>` vendor and host extension records; the org's own shape. */
532
+ extensions?: Record<`${string}.${string}`, Record<string, unknown>>;
533
+ configurable?: Record<string, unknown>;
534
+ observability?: Record<string, unknown>;
535
+ runtimeCapabilities?: Record<string, unknown>;
536
+ testing?: Record<string, unknown>;
537
+ conformance?: Record<string, unknown>;
538
+ fixtures?: Record<string, unknown>;
539
+ compliance?: Record<string, unknown>;
540
+ discovery?: Record<string, unknown>;
541
+ } & {
542
+ readonly [K in CapabilityFamilyKey]?: CapabilityRecord;
543
+ };
544
+
545
+ // ─── RFC 0173 compensation, effect ledger, effect seams ─────────────────
546
+
547
+ /** `GET /runs/{runId}/compensation` (`schemas/v2/compensation-projection.schema.json`). */
548
+ export interface CompensationProjection {
549
+ runId: string;
550
+ status: 'none' | 'pending' | 'running' | 'completed' | 'partial' | 'failed' | 'manual-intervention';
551
+ plan: readonly {
552
+ nodeId: string;
553
+ order: number;
554
+ /** `schemas/v2/compensation-policy.schema.json` */
555
+ policy?: Record<string, unknown>;
556
+ irreversibleEffect?: boolean;
557
+ }[];
558
+ attempts: readonly {
559
+ nodeId: string;
560
+ attempt: number;
561
+ outcome: 'succeeded' | 'failed' | 'skipped' | 'manual';
562
+ at: string;
563
+ reason?: string;
564
+ }[];
565
+ }
566
+
567
+ /** `GET /runs/{runId}/effects` (`schemas/v2/effect-ledger-projection.schema.json`). */
568
+ export interface EffectLedgerProjection {
569
+ runId: string;
570
+ effects: readonly {
571
+ effectId: string;
572
+ nodeId: string;
573
+ attempt: number;
574
+ invocationId?: string;
575
+ keying: 'business-identity' | 'activity-recipe';
576
+ /** Redaction-safe provider-side identity; never credential material. */
577
+ providerKey?: string;
578
+ state: 'claimed' | 'completed' | 'released' | 'escaped';
579
+ at: string;
580
+ }[];
581
+ }
582
+
583
+ /** `GET /host/effect-seams` (`schemas/v2/effect-seam-manifest.schema.json`). */
584
+ export interface EffectSeamManifest {
585
+ manifestVersion: '1';
586
+ host: {
587
+ name: string;
588
+ build: { kind: 'image-digest' | 'commit' | 'artifact-sha256'; id: string };
712
589
  };
590
+ seams: readonly {
591
+ /** The outbound effect path, host-named (e.g. `http.fetch`). */
592
+ seam: string;
593
+ kind: 'http' | 'queue' | 'storage' | 'provider-sdk' | 'webhook-fanout';
594
+ guarded: true;
595
+ guardedBy: string;
596
+ branchReFires?: boolean;
597
+ note?: string;
598
+ }[];
599
+ }
600
+
601
+ // ─── Host events channel (`/host/events`; events.md §Host events) ─────────
602
+
603
+ /** `heartbeat.evaluated` (`schemas/v2/heartbeat-evaluated.schema.json`). */
604
+ export interface HeartbeatEvaluatedPayload {
605
+ heartbeatId: string;
606
+ status: 'ok' | 'timeout' | 'error';
607
+ changed: boolean;
608
+ [key: string]: unknown;
609
+ }
610
+
611
+ /** `heartbeat.stateChanged` (`schemas/v2/heartbeat-state-changed.schema.json`). */
612
+ export interface HeartbeatStateChangedPayload {
613
+ heartbeatId: string;
614
+ from: Record<string, unknown>;
615
+ to: Record<string, unknown>;
616
+ [key: string]: unknown;
617
+ }
618
+
619
+ /** One frame of the `hostEvents` channel — content-free of run data. */
620
+ export interface HostEventDoc {
621
+ type: string;
622
+ payload: unknown;
623
+ timestamp?: string;
624
+ [key: string]: unknown;
713
625
  }
714
626
 
627
+ // ─── AI run overlay ─────────────────────────────────────────────────────
628
+
715
629
  /**
716
630
  * Opaque host-issued reference to a stored secret. Sent via
717
631
  * `RunOptions.configurable.ai.credentialRef`; the host resolves
@@ -734,20 +648,6 @@ export interface AIRunOverlay {
734
648
 
735
649
  // ─── MCP client (Phase H.2) ─────────────────────────────────────────────
736
650
 
737
- /**
738
- * Capability advertisement for hosts that operate an MCP client.
739
- * Mirrors `examples/hosts/postgres/src/mcp-client.ts` reference shape.
740
- * `trustBoundary: "untrusted"` is REQUIRED per
741
- * threat-model-prompt-injection.md §"UNTRUSTED marker": tool output is
742
- * adversarial-tolerant and downstream LLM nodes treat it as user data.
743
- */
744
- export interface McpClientCapability {
745
- supported: true;
746
- transports: readonly string[];
747
- defaultTimeoutMs?: number;
748
- trustBoundary: 'untrusted';
749
- }
750
-
751
651
  /** Wire shape of the `core.mcp.toolCall` node config. */
752
652
  export interface McpToolCallNodeConfig {
753
653
  serverId: string;
@@ -769,16 +669,6 @@ export interface McpInvokedSummary {
769
669
 
770
670
  // ─── HTTP client (Phase H.3) ────────────────────────────────────────────
771
671
 
772
- /** Capability advertisement for hosts that implement `core.http.request`. */
773
- export interface HttpClientCapability {
774
- supported: true;
775
- methods: readonly ('GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD')[];
776
- defaultTimeoutMs?: number;
777
- maxResponseBodyBytes: number;
778
- ssrfGuard: boolean;
779
- redirectPolicy?: 'follow' | 'reject';
780
- }
781
-
782
672
  /** Wire shape of the `core.http.request` node config. */
783
673
  export interface HttpRequestNodeConfig {
784
674
  url: string;
@@ -822,13 +712,6 @@ export interface MemoryListOptions {
822
712
  query?: string;
823
713
  }
824
714
 
825
- /** Capability advertisement shape per capabilities.md §`memory`. */
826
- export interface MemoryCapability {
827
- supported: true;
828
- maxEntrySizeBytes: number;
829
- ttlSupported: boolean;
830
- }
831
-
832
715
  // ─── Reasoning + agent events (Phase I.2) ───────────────────────────────
833
716
 
834
717
  /** Mirror of `schemas/agent-ref.schema.json`. */
@@ -842,109 +725,6 @@ export interface AgentRef {
842
725
  /** Reasoning verbosity per capabilities.md §`agents.reasoning`. */
843
726
  export type ReasoningVerbosity = 'off' | 'summary' | 'full';
844
727
 
845
- /** Capability advertisement shape per capabilities.md §`agents` (Phase 1-6). */
846
- export interface AgentsCapability {
847
- supported: true;
848
- profile?: string;
849
- modelClasses?: readonly ('reasoning' | 'tool-using' | 'chat')[];
850
- orchestratorPattern?: string;
851
- memoryBackends?: readonly string[];
852
- orchestrator?: boolean;
853
- /** Phase 6. Host implements the `core.dispatch` Core typeId. The RFC 0118
854
- * fan-out/join descriptors live on the top-level {@link Capabilities.dispatch}
855
- * object (`capabilities.md` §`dispatch`), NOT here. */
856
- dispatch?: boolean;
857
- reasoning?: {
858
- verbosity: ReasoningVerbosity;
859
- tokenLimit?: number;
860
- /** RFC 0024. When `true`, host MAY emit `agent.reasoning.delta`
861
- * events incrementally while a reasoning block is still open,
862
- * in addition to the final `agent.reasoned`. Consumers that
863
- * only read `agent.reasoned` remain correct (the closing event
864
- * is authoritative). */
865
- streaming?: boolean;
866
- };
867
- }
868
-
869
- /**
870
- * RFC 0007 + RFC 0118 — the top-level `core.dispatch` capability descriptors
871
- * (`capabilities.md` §`dispatch`), exposed as {@link Capabilities.dispatch}.
872
- * The discovery surface for parallel sub-workflow fan-out and join: an author
873
- * reads `joinModes` / `onChildFailureModes` / `fanOutPolicies` to detect partial
874
- * support before pinning a `core.dispatch` node's `fanOutPolicy` / `joinPolicy`.
875
- * All fields OPTIONAL + read-only; absent descriptors carry the documented
876
- * conservative defaults (a host that omits `joinModes` implements no parallel
877
- * join; one that omits `onChildFailureModes` accepts only `'collect'`). The SDK
878
- * does NOT model the authoring-side `DispatchConfig` (`fanOutPolicy` /
879
- * `joinPolicy` / `maxConcurrency`) — that is a workflow-node-definition shape,
880
- * out of this client SDK's read-only scope.
881
- */
882
- export interface DispatchCapability {
883
- /** Host implements the `core.dispatch` Core typeId (the top-level mirror of
884
- * the legacy {@link AgentsCapability.dispatch} boolean). */
885
- supported?: boolean;
886
- /** RFC 0007 + RFC 0118. Host honors `nextWorkerIds.length > 1`; since RFC 0118
887
- * ALSO the gate for accepting `fanOutPolicy: 'parallel'` at registration. A
888
- * host advertising `false` rejects a node pinning `'parallel'`. */
889
- fanOutSupported?: boolean;
890
- /** RFC 0118. The `fanOutPolicy` values the host accepts. Absent ⇒ treat as
891
- * `['sequential', 'reject']` (parallel unsupported). */
892
- fanOutPolicies?: readonly ('sequential' | 'reject' | 'parallel')[];
893
- /** RFC 0118. The `joinPolicy.mode` values the host implements for
894
- * `fanOutPolicy: 'parallel'`. Absent ⇒ the host implements no parallel join. */
895
- joinModes?: readonly ('wait-all' | 'quorum' | 'first' | 'race')[];
896
- /** RFC 0118. The `joinPolicy.onChildFailure` error-aggregation values the host
897
- * accepts (orthogonal to {@link joinModes}). Absent ⇒ `['collect']` only — a
898
- * host that omits this MUST reject a node pinning `'fail-fast'` / `'absorb'`. */
899
- onChildFailureModes?: readonly ('collect' | 'fail-fast' | 'absorb')[];
900
- /** RFC 0118. The host's hard concurrency/breadth ceiling for a parallel
901
- * fan-out. Effective concurrency is `min(config.maxConcurrency ?? ∞,
902
- * maxFanOut ?? ∞)`. Absent ⇒ unbounded (treat as "unknown, may be capped"). */
903
- maxFanOut?: number;
904
- }
905
-
906
- /**
907
- * RFC 0117 (`Active`; amended by RFC 0119) — the `uiPlugins` capability
908
- * advertisement (`capabilities.md` §`uiPlugins`), exposed as
909
- * {@link Capabilities.uiPlugins}. The host loads `kind:"frontend-plugin"` packs
910
- * in an origin/execution-isolated sandbox (mechanism per {@link isolation}) and
911
- * serves the closed `ui-plugin/1` host-RPC boundary. All fields but `supported`
912
- * are OPTIONAL + read-only; a client reads them to decide whether (and which
913
- * surfaces / RPC methods) a plugin can target before install. The SDK models
914
- * only this discovery block — NOT the `ui-plugin/1` RPC envelope or the
915
- * `frontend-plugin` manifest (a renderer/registry concern, out of client scope).
916
- */
917
- export interface UiPluginsCapability {
918
- /** Host loads `kind:"frontend-plugin"` packs in an isolated sandbox and
919
- * serves the `ui-plugin/1` host-RPC boundary. `false`/absent ⇒ the host
920
- * rejects such packs at registration and renders no plugin surface. */
921
- supported: boolean;
922
- /** RFC 0117 (amended by RFC 0119). The categorical isolation MECHANISM the
923
- * host enforces for plugin bytes. The five named values plus a vendor
924
- * `x-host-<host>-<key>` form (per `host-extensions.md`) — the open string
925
- * admits the vendor form without discarding autocomplete for the known set.
926
- * ALL values denote the SAME mandatory isolation property (no host execution
927
- * context / DOM / origin-storage / credential access, deny-egress, RPC-only);
928
- * the field names the mechanism, never relaxes the property. Absent ⇒
929
- * `'cross-origin-iframe'` (the default). */
930
- isolation?:
931
- | 'cross-origin-iframe'
932
- | 'wasm'
933
- | 'process'
934
- | 'container'
935
- | 'vm'
936
- | (string & {});
937
- /** RFC 0117. Plugin surfaces this host renders. A pack surface not in this
938
- * set is installable-but-inert (graceful degradation). */
939
- surfaces?: readonly ('artifact-viewer' | 'route' | 'settings-panel')[];
940
- /** RFC 0117. The `ui-plugin/1` host-RPC methods this host honors. A plugin
941
- * call to a method not in this set is rejected with `method_not_allowed`
942
- * (SECURITY invariant `frontend-plugin-rpc-allowlist`). */
943
- hostApi?: readonly ('artifact.read' | 'artifact.write' | 'host.toast' | 'host.navigate')[];
944
- /** RFC 0117. Per-plugin entry-bundle byte ceiling the host will load. */
945
- maxEntryBytes?: number;
946
- }
947
-
948
728
  // ─── agent.* event payloads (RFC 0002 §B + RFC 0024) ────────────────────
949
729
  //
950
730
  // Mirror of `schemas/run-event-payloads.schema.json#$defs.agent*`. Field
@@ -1148,7 +928,7 @@ export interface VoiceCancelledPayload {
1148
928
  /** `channel.presence` (RFC 0110). EPHEMERAL online + typing presence for a
1149
929
  * `type:'channel'` conversation. Observable on the LIVE run-event stream
1150
930
  * only — the host MUST NOT persist it to the replayable event log, so it is
1151
- * ABSENT on replay / `POST /v1/runs/{runId}:fork`. Membership-gated: every
931
+ * ABSENT on replay / `POST /runs/{runId}:fork`. Membership-gated: every
1152
932
  * ref is a current participant (opaque RFC 0041 subject refs, non-PII). */
1153
933
  export interface ChannelPresencePayload {
1154
934
  conversationId: string;
@@ -1208,7 +988,7 @@ export interface DispatchJoinPayload {
1208
988
  * in-window orchestrator-loop transcript turns with a host-produced summary to
1209
989
  * honor `multiAgent.executionModel.contextBudget.transcriptTokenBudget`.
1210
990
  * CONTENT-FREE: the summary text never rides the wire — `summaryRef` is an
1211
- * artifactId resolved via `GET /v1/runs/{runId}/artifacts/{artifactId}`. The
991
+ * artifactId resolved via `GET /runs/{runId}/artifacts/{artifactId}`. The
1212
992
  * summary is nondeterministic host output governed like an RFC 0041 envelope:
1213
993
  * on `:fork mode:replay` the host MUST reuse this recorded `summaryRef` and
1214
994
  * MUST NOT re-summarize. `replacedTurns` lists the event ids the summary stands
@@ -1237,36 +1017,8 @@ export interface TypedRunEvent<T> extends RunEventDoc {
1237
1017
  payload: T;
1238
1018
  }
1239
1019
 
1240
- // ─── Auth profile claims (Phase I.5 + I.6) ──────────────────────────────
1241
-
1242
- /** Profile identifiers per auth-profiles.md. */
1243
- export type AuthProfileClaim =
1244
- | 'openwop-audit-log-integrity'
1245
- | 'openwop-auth-api-key-rotation'
1246
- | 'openwop-auth-oauth2-client-credentials'
1247
- | 'openwop-auth-oidc-user-bearer'
1248
- | 'openwop-auth-mtls'
1249
- | 'openwop-discovery-auth-scoped'
1250
- | 'openwop-interrupt-quorum'
1251
- | 'openwop-interrupt-auth-required'
1252
- | 'openwop-interrupt-external-event'
1253
- | 'openwop-interrupt-cascade-cancel'
1254
- | 'openwop-production';
1255
-
1256
- /** Rotation advertisement shape per auth-profiles.md §"openwop-auth-api-key-rotation". */
1257
- export interface AuthRotationCapability {
1258
- supported: true;
1259
- minGraceSeconds: number;
1260
- }
1261
-
1262
- /** Auth-scoped discovery advertisement per RFC 0011 §A. */
1263
- export interface DiscoveryAuthScopedCapability {
1264
- supported: true;
1265
- mode: 'same-endpoint';
1266
- }
1267
-
1268
1020
  // ---------------------------------------------------------------------------
1269
- // AI Envelope (DRAFT v1.x — `spec/v1/ai-envelope.md`)
1021
+ // AI Envelope (`spec/v2/core/events.md` §AI envelopes)
1270
1022
  //
1271
1023
  // Inbound LLM-emission envelope. Distinct from `RunEventDoc` (outbound event
1272
1024
  // log) and `ErrorEnvelope` (host HTTP error response). Top-level shape is
@@ -1297,7 +1049,7 @@ export interface PartialInfo {
1297
1049
  total: number;
1298
1050
  }
1299
1051
 
1300
- /** Canonical inbound LLM-emission wire shape per `spec/v1/ai-envelope.md`. */
1052
+ /** Canonical inbound LLM-emission wire shape per `spec/v2/core/ai-envelope.md`. */
1301
1053
  export interface AIEnvelope<TPayload = unknown> {
1302
1054
  /** Discriminator for payload shape, kind routing, and Envelope Contract gate. */
1303
1055
  type: string;
@@ -1346,11 +1098,6 @@ export interface ValidationDetail {
1346
1098
  /** Optional capability advertisement. Default when absent: 'warn'. */
1347
1099
  export type EnvelopeStrictness = 'warn' | 'strict';
1348
1100
 
1349
- /** Optional capability advertisement per `ai-envelope.md` §"Capability handshake integration". */
1350
- export interface EnvelopeContractsCapability {
1351
- advertised: boolean;
1352
- }
1353
-
1354
1101
  // Universal-kind payloads. Per-kind schemas at `schemas/envelopes/<kind>.schema.json`.
1355
1102
 
1356
1103
  /** Payload of the universal `clarification.request` envelope kind. */
@@ -1439,7 +1186,7 @@ export interface A2uiSurfacePatchOp {
1439
1186
  /**
1440
1187
  * RFC 0114 — a HOST-SIDE TRANSPORT frame carrying an RFC 6902 delta over a
1441
1188
  * recorded `ui.a2ui-surface` envelope ({@link A2UISurfacePayload}). Delivered
1442
- * ONLY over the run event stream (`GET /v1/runs/{runId}/events`) to a subscriber
1189
+ * ONLY over the run event stream (`GET /runs/{runId}/events`) to a subscriber
1443
1190
  * that negotiated `?a2uiDelta=1`; every other consumer (the event-log read,
1444
1191
  * replay, `:fork`, any non-negotiating subscriber) receives the materialized
1445
1192
  * FULL surface. This is NOT a recorded-envelope shape — the recorded
@@ -1462,7 +1209,7 @@ export interface A2uiSurfaceDeltaFrame {
1462
1209
  patch: A2uiSurfacePatchOp[];
1463
1210
  }
1464
1211
 
1465
- // ── RFC 0027 + RFC 0028 — Prompt library (spec/v1/prompts.md) ──
1212
+ // ── RFC 0027 + RFC 0028 — Prompt library (spec/v2/core/prompts.md) ──
1466
1213
 
1467
1214
  /**
1468
1215
  * Role a PromptTemplate plays when composed into an LLM call. Shared enum
@@ -1488,7 +1235,7 @@ export interface PromptVariable {
1488
1235
 
1489
1236
  /**
1490
1237
  * Named, versioned, variable-bound prompt body. Per
1491
- * `schemas/prompt-template.schema.json` + spec/v1/prompts.md §PromptTemplate.
1238
+ * `schemas/prompt-template.schema.json` + spec/v2/core/prompts.md §PromptTemplate.
1492
1239
  *
1493
1240
  * `meta.packName` + `meta.packVersion` are required when `meta.source: "pack"`
1494
1241
  * (RFC 0028 §C); a JSON-Schema `if/then` conditional enforces this at the
@@ -1633,8 +1380,8 @@ function extractTraceId(traceparent: string): string | undefined {
1633
1380
  }
1634
1381
 
1635
1382
  /**
1636
- * One installed manifest agent, as projected by `GET /v1/agents` /
1637
- * `GET /v1/agents/{agentId}` (RFC 0072 §A). Read-only — never carries the
1383
+ * One installed manifest agent, as projected by `GET /agents` /
1384
+ * `GET /agents/{agentId}` (RFC 0072 §A). Read-only — never carries the
1638
1385
  * system-prompt body, resolved handoff schemas, or credential material (SR-1).
1639
1386
  */
1640
1387
  export interface AgentInventoryEntry {
@@ -1653,7 +1400,7 @@ export interface AgentInventoryEntry {
1653
1400
  degraded?: string[];
1654
1401
  }
1655
1402
 
1656
- /** Response body for `GET /v1/agents` (RFC 0072 §A). */
1403
+ /** Response body for `GET /agents` (RFC 0072 §A). */
1657
1404
  export interface AgentInventoryResponse {
1658
1405
  agents: AgentInventoryEntry[];
1659
1406
  total: number;
@@ -1674,7 +1421,7 @@ export interface AgentRosterEntry {
1674
1421
  description?: string;
1675
1422
  }
1676
1423
 
1677
- /** Response for `GET /v1/agents/roster` (RFC 0086 §B). */
1424
+ /** Response for `GET /agents/roster` (RFC 0086 §B). */
1678
1425
  export interface AgentRosterResponse {
1679
1426
  roster: AgentRosterEntry[];
1680
1427
  total: number;
@@ -1704,7 +1451,7 @@ export interface AgentOrgChart {
1704
1451
  members: OrgChartMember[];
1705
1452
  }
1706
1453
 
1707
- /** Response for `GET /v1/agents/org-chart/{departmentId}` (RFC 0087 §D) — the
1454
+ /** Response for `GET /agents/org-chart/{departmentId}` (RFC 0087 §D) — the
1708
1455
  * department subtree + the responsibility roll-up (union of member portfolios). */
1709
1456
  export interface OrgChartResponsibilityView {
1710
1457
  department: OrgChartDepartment;
@@ -1716,94 +1463,12 @@ export interface OrgChartResponsibilityView {
1716
1463
  * Backs the workflow-engine sample app's Agents tab. Pack-installed
1717
1464
  * agents come through `AgentInventoryEntry` above (RFC 0072 §A
1718
1465
  * normative inventory). The types below mirror the sample-host
1719
- * `POST /v1/host/sample/agents` create surface — they're scoped to
1466
+ * `POST /host/sample/agents` create surface — they're scoped to
1720
1467
  * the sample-extension and may evolve independently of the
1721
1468
  * normative agent surface. Future RFC promotion would migrate these
1722
1469
  * to the normative wire shape.
1723
1470
  */
1724
1471
 
1725
- /** Body for `POST /v1/host/sample/agents`. The server synthesises
1726
- * the agentId as `user.<tenantId>.<persona-slug>`. */
1727
- export interface CreateUserAgentRequest {
1728
- /** Short name; becomes the `@`-mention slug and chat panel label.
1729
- * Required, ≤64 chars. */
1730
- persona: string;
1731
- /** Longer display name; defaults to the persona when omitted. */
1732
- label?: string;
1733
- description?: string;
1734
- /** One of: `chat`, `reasoning`, `coding`, `extraction`. */
1735
- modelClass: string;
1736
- /** Inline system prompt body; ≤16 000 chars. The sample-host stores
1737
- * it directly (no pack-file ref). */
1738
- systemPrompt: string;
1739
- /** Capability ids the agent is allowed to call; ≤32 entries. */
1740
- toolAllowlist?: string[];
1741
- memoryShape?: {
1742
- scratchpad?: boolean;
1743
- conversation?: boolean;
1744
- longTerm?: boolean;
1745
- };
1746
- /** 0.0-1.0; decisions below this are surfaced as low-confidence. */
1747
- confidenceThreshold?: number;
1748
- }
1749
-
1750
- /** Response body for `POST /v1/host/sample/agents` — shaped to
1751
- * match `AgentInventoryEntry` minus normative-only fields, so a
1752
- * follow-up `GET /v1/agents` returns a row of the same shape. */
1753
- export interface UserAgentRecord {
1754
- agentId: string;
1755
- persona: string;
1756
- label: string;
1757
- description?: string;
1758
- modelClass: string;
1759
- packName: string;
1760
- packVersion: string;
1761
- toolAllowlist: string[];
1762
- memoryShape: {
1763
- scratchpad: boolean;
1764
- conversation: boolean;
1765
- longTerm: boolean;
1766
- };
1767
- confidenceThreshold?: number;
1768
- hasHandoffSchemas: false;
1769
- }
1770
-
1771
- /** One installable agent-pack summary from the sample host's local
1772
- * registry mirror (`GET /v1/host/sample/registry/agent-packs`). */
1773
- export interface AgentPackSummary {
1774
- /** Pack name, e.g. `core.openwop.agents.code-reviewer`. */
1775
- name: string;
1776
- version: string;
1777
- description?: string;
1778
- /** Personas declared by the pack's `agents[]` (per RFC 0003). */
1779
- personas: string[];
1780
- /** True when at least one of the pack's agents is registered in
1781
- * this host's in-process AgentRegistry. */
1782
- installed: boolean;
1783
- }
1784
-
1785
- export interface AgentPackRegistryResponse {
1786
- packs: AgentPackSummary[];
1787
- total: number;
1788
- }
1789
-
1790
- export interface InstallAgentPackRequest {
1791
- /** Must start with `core.openwop.agents.` — the sample's install
1792
- * route filters to that namespace. */
1793
- name: string;
1794
- /** Defaults to `1.0.0` when omitted. */
1795
- version?: string;
1796
- }
1797
-
1798
- export interface InstallAgentPackResponse {
1799
- name: string;
1800
- version: string;
1801
- /** True when the pack was newly installed; false when it was
1802
- * already present in the registry. */
1803
- installed: boolean;
1804
- alreadyInstalled: boolean;
1805
- }
1806
-
1807
1472
  // ── RFC 0081 — Agent evaluation (eval-summary.schema.json) ─────────────
1808
1473
 
1809
1474
  /** Abstract model class (RFC 0002 / RFC 0003 manifest vocabulary). */
@@ -1871,7 +1536,7 @@ export type DeploymentState =
1871
1536
 
1872
1537
  /**
1873
1538
  * RFC 0078 §B — a portable tool descriptor as projected onto the host's
1874
- * `GET /v1/tools` catalog. Source-agnostic (node-pack / workflow / mcp /
1539
+ * `GET /tools` catalog. Source-agnostic (node-pack / workflow / mcp /
1875
1540
  * connector / host-extension); `safetyTier`, `egress`, and `approval` let a
1876
1541
  * caller reason about a tool's blast radius before invoking it.
1877
1542
  */
@@ -1893,8 +1558,8 @@ export interface ToolDescriptor {
1893
1558
 
1894
1559
  /**
1895
1560
  * RFC 0112 — a compact, model-facing projection of `ToolDescriptor`, returned by
1896
- * `GET /v1/tools?view=compact` (envelope `{ tools: CompactToolDescriptor[] }`) +
1897
- * `GET /v1/tools/{toolId}?view=compact` when the host advertises
1561
+ * `GET /tools?view=compact` (envelope `{ tools: CompactToolDescriptor[] }`) +
1562
+ * `GET /tools/{toolId}?view=compact` when the host advertises
1898
1563
  * `capabilities.toolCatalog.compactView`. The heavy descriptor fields
1899
1564
  * (`outputSchema`/`auth`/`egress`/`approval`/`replayPolicy`/`costHint`/`latencyHint`)
1900
1565
  * are dropped, and any `inputSchema` is bounded to the compact structural subset
@@ -1941,7 +1606,7 @@ export interface AgentDeploymentTransition {
1941
1606
  reason?: string;
1942
1607
  }
1943
1608
 
1944
- // ── RFC 0103 Localized content surface (spec/v1/localized-content.md) ──
1609
+ // ── RFC 0103 Localized content surface (spec/v2/core/localized-content.md) ──
1945
1610
  // Mirror schemas/localized-content-*.schema.json. Host-defined structured
1946
1611
  // content (`data`, `localizations`, `seo`) is kept open per the schemas
1947
1612
  // (additionalProperties: true) — it is the host's content model, not a
@@ -1977,7 +1642,7 @@ export interface LocalizedContentSection {
1977
1642
  order: number;
1978
1643
  }
1979
1644
 
1980
- /** Public delivery response for `GET /v1/content/pages/{slug}` — the negotiated
1645
+ /** Public delivery response for `GET /content/pages/{slug}` — the negotiated
1981
1646
  * locale's resolved page + sections (the RFC 0103 `resolveSection` merge is
1982
1647
  * applied host-side: exact → language-family → base). */
1983
1648
  export interface LocalizedContentPageResponse {
@@ -1998,7 +1663,7 @@ export interface LocalizedContentLanguageSettings {
1998
1663
  autoTranslateOnPublish: boolean;
1999
1664
  }
2000
1665
 
2001
- /** Request body for `PUT /v1/content/pages/{pageId}/sections/{sectionId}`. */
1666
+ /** Request body for `PUT /content/pages/{pageId}/sections/{sectionId}`. */
2002
1667
  export interface PutContentSectionRequest {
2003
1668
  /** Target locale; the baseLocale upserts `data`, else `localizations[locale]`. */
2004
1669
  locale: string;
@@ -2006,9 +1671,9 @@ export interface PutContentSectionRequest {
2006
1671
  data: Record<string, unknown>;
2007
1672
  }
2008
1673
 
2009
- // ── RFC 0099 Trigger subscription registration (spec/v1/trigger-bridge.md §F) ──
1674
+ // ── RFC 0099 Trigger subscription registration (spec/v2/core/trigger-bridge.md §F) ──
2010
1675
 
2011
- /** Registration body for `POST /v1/trigger-subscriptions`
1676
+ /** Registration body for `POST /trigger-subscriptions`
2012
1677
  * (`schemas/trigger-subscription-registration.schema.json`). */
2013
1678
  export interface TriggerSubscriptionRegistration {
2014
1679
  /** External event source descriptor (host-defined: webhook / email / form …). */
@@ -2025,7 +1690,7 @@ export interface TriggerSubscriptionRegistration {
2025
1690
  * registration fields the host echoes back. */
2026
1691
  export type TriggerSubscription = Record<string, unknown>;
2027
1692
 
2028
- /** `201` response for `POST /v1/trigger-subscriptions`. `binding` carries the
1693
+ /** `201` response for `POST /trigger-subscriptions`. `binding` carries the
2029
1694
  * source-specific wiring the caller needs (e.g. `{ ingestUrl,
2030
1695
  * secretFingerprint }` for webhook); the secret is returned ONCE at creation
2031
1696
  * (SR-1) — persist it, it is not retrievable again. */