prefix-safe-json 0.0.1-alpha.3 → 0.0.1-alpha.4

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 (49) hide show
  1. package/README.md +70 -31
  2. package/dist/gate/decide.d.ts +7 -0
  3. package/dist/gate/decide.d.ts.map +1 -1
  4. package/dist/gate/decide.js +11 -0
  5. package/dist/gate/decide.js.map +1 -1
  6. package/dist/gate/gate.d.ts.map +1 -1
  7. package/dist/gate/gate.js +18 -2
  8. package/dist/gate/gate.js.map +1 -1
  9. package/dist/gate/types.d.ts +63 -1
  10. package/dist/gate/types.d.ts.map +1 -1
  11. package/dist/guard/ai-sdk.d.ts +48 -0
  12. package/dist/guard/ai-sdk.d.ts.map +1 -0
  13. package/dist/guard/ai-sdk.js +51 -0
  14. package/dist/guard/ai-sdk.js.map +1 -0
  15. package/dist/guard/provider-guard.d.ts +4 -0
  16. package/dist/guard/provider-guard.d.ts.map +1 -0
  17. package/dist/guard/provider-guard.js +38 -0
  18. package/dist/guard/provider-guard.js.map +1 -0
  19. package/dist/guard/types.d.ts +48 -0
  20. package/dist/guard/types.d.ts.map +1 -0
  21. package/dist/guard/types.js +2 -0
  22. package/dist/guard/types.js.map +1 -0
  23. package/dist/index.d.ts +9 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +8 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/lexer/scanner.d.ts +0 -2
  28. package/dist/lexer/scanner.d.ts.map +1 -1
  29. package/dist/lexer/scanner.js +3 -21
  30. package/dist/lexer/scanner.js.map +1 -1
  31. package/dist/lexer/states.d.ts +0 -4
  32. package/dist/lexer/states.d.ts.map +1 -1
  33. package/dist/lexer/states.js +0 -4
  34. package/dist/lexer/states.js.map +1 -1
  35. package/dist/parser.js +26 -53
  36. package/dist/parser.js.map +1 -1
  37. package/dist/providers/ai-sdk.d.ts +5 -1
  38. package/dist/providers/ai-sdk.d.ts.map +1 -1
  39. package/dist/providers/ai-sdk.js +21 -0
  40. package/dist/providers/ai-sdk.js.map +1 -1
  41. package/dist/providers/openai.d.ts +7 -0
  42. package/dist/providers/openai.d.ts.map +1 -1
  43. package/dist/providers/openai.js +65 -7
  44. package/dist/providers/openai.js.map +1 -1
  45. package/dist/semantic/snapshot.d.ts +11 -4
  46. package/dist/semantic/snapshot.d.ts.map +1 -1
  47. package/dist/semantic/snapshot.js +11 -9
  48. package/dist/semantic/snapshot.js.map +1 -1
  49. package/package.json +7 -3
package/README.md CHANGED
@@ -34,43 +34,74 @@ model output truncated
34
34
 
35
35
  *(Real terminal output from [`examples/anthropic-truncation-safety.mjs`](examples/anthropic-truncation-safety.mjs) — not staged. Same script CI runs on every push.)*
36
36
 
37
- ## Quick start: the execution safety gate
38
-
39
- The highest-level API answers one question per tool call — is it safe to
40
- execute right now — without requiring you to know anything about parser
41
- state, coordinator events, or JSON Pointers:
37
+ ## From stream to safe execution, in about 10 lines
42
38
 
43
39
  ```typescript
44
- import { createToolCallExecutionGate, AnthropicStreamAdapter } from "prefix-safe-json";
45
-
46
- const gate = createToolCallExecutionGate(undefined, undefined, {
47
- write_file: {
48
- type: "object",
49
- properties: { path: { type: "string" }, content: { type: "string" } },
50
- required: ["path", "content"],
40
+ import { createAiSdkExecutionGuard } from "prefix-safe-json";
41
+
42
+ const guard = createAiSdkExecutionGuard({
43
+ schemas: {
44
+ write_file: {
45
+ type: "object",
46
+ properties: { path: { type: "string" }, content: { type: "string" } },
47
+ required: ["path", "content"],
48
+ },
51
49
  },
52
50
  });
53
- const adapter = new AnthropicStreamAdapter();
54
51
 
55
- for (const rawEvent of anthropicSseEvents) {
56
- for (const normalized of adapter.push(rawEvent)) gate.push(normalized);
57
- }
52
+ for await (const part of result.fullStream) guard.push(part);
58
53
 
59
- for (const decision of gate.finish().decisions) {
60
- if (decision.action === "execute") {
61
- await tools[decision.name](decision.value);
62
- } else {
63
- console.warn(`${decision.name}: ${decision.action} (${decision.reason})`); // "retry" or "reject"
64
- }
54
+ for (const decision of guard.finish().decisions) {
55
+ if (decision.action === "execute") await tools[decision.name](decision.value);
65
56
  }
66
57
  ```
67
58
 
68
- Provider adapters exist for OpenAI, Anthropic, Gemini, OpenRouter,
69
- OpenAI-compatible endpoints, and the [Vercel AI SDK](https://ai-sdk.dev)
70
- (`ai` package — not a dependency of this library; see
71
- [`examples/ai-sdk-execution-gate.mjs`](examples/ai-sdk-execution-gate.mjs)).
72
- Full semantics, the decision table, and provider finish-reason mapping:
73
- [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md).
59
+ `createAiSdkExecutionGuard()` is a drop-in guard for the [Vercel AI
60
+ SDK](https://ai-sdk.dev)'s `fullStream` — not a dependency of this library
61
+ (no `ai` import, no runtime version lock; see
62
+ [`examples/ai-sdk-guard.mjs`](examples/ai-sdk-guard.mjs)). It's a thin
63
+ composition over the same lower-level adapter + gate API this library has
64
+ always exposed — nothing about the decision logic changes based on which one
65
+ you call.
66
+
67
+ **What the decisions mean**
68
+
69
+ Every tool call gets exactly one verdict:
70
+
71
+ - **`execute`** — complete, unfabricated, and (if a schema is registered)
72
+ schema-valid. `decision.value` is safe to pass to your tool.
73
+ - **`retry`** — nothing is wrong with what arrived; there just isn't a
74
+ trustworthy complete value yet. Continue generation.
75
+ - **`reject`** — the data itself is the problem (malformed JSON, a schema
76
+ mismatch, a resource limit, a provider error, a content-policy
77
+ termination). Retrying the same input won't help.
78
+
79
+ **Why the model's finish reason matters as much as the JSON's shape**
80
+
81
+ A tool call cut short by a token limit, a provider error, or a content
82
+ filter can still contain syntactically complete, schema-valid JSON — the
83
+ model was simply stopped before finishing the *rest* of its response, not
84
+ necessarily mid-argument. Executing on JSON shape alone means trusting data
85
+ nobody, including the model, confirmed as final. This is exactly the failure
86
+ mode independently reported and reproduced in
87
+ [vercel/ai#19063](https://github.com/vercel/ai/issues/19063): tool calls
88
+ executing regardless of an unsafe finish reason, across AI SDK v5, v6, and
89
+ v7, with fixes landing across all three release lines (v7's in `ai@7.0.70`).
90
+ `prefix-safe-json` does not patch or depend on that fix — it's a
91
+ provider-independent guard that requires positive proof a stream ended
92
+ safely before treating any tool call as final, regardless of which SDK,
93
+ provider, or framework hands it the data. See
94
+ `test/guard/ai-sdk-compatibility.test.ts` for the cross-version test
95
+ evidence.
96
+
97
+ **Supported providers**: OpenAI (legacy `function_call` and Responses API),
98
+ Anthropic, Gemini, OpenRouter, generic OpenAI-compatible endpoints, and the
99
+ Vercel AI SDK. High-level guards currently ship for the AI SDK; every
100
+ provider has a public low-level adapter (see below) that composes with
101
+ `createToolCallExecutionGate()` the same way.
102
+
103
+ Full semantics, the decision table, provider finish-reason mapping, and the
104
+ high-level guard API: [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md).
74
105
 
75
106
  ## The lower-level problem this is built on
76
107
 
@@ -197,6 +228,7 @@ for the full list, including known internal limitations.
197
228
  - Provider stream adapters for OpenAI (legacy `function_call` and Responses API), Anthropic, Gemini, OpenRouter, generic OpenAI-compatible endpoints, and the Vercel AI SDK, plus a coordinator for tracking multiple concurrent tool-call streams
198
229
  - Optional per-tool JSON Schema validation on the coordinator (see below) — a value can be structurally complete and still not match what a tool declared it needs
199
230
  - `createToolCallExecutionGate()` — a fail-closed `execute` / `retry` / `reject` decision per tool call, built on top of the coordinator (see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md))
231
+ - `createAiSdkExecutionGuard()` — a drop-in high-level guard for the Vercel AI SDK's `fullStream`, composing a provider adapter with the execution gate; every `ExecutionDecision` also carries an `evidence` object explaining why (see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md#high-level-guards))
200
232
 
201
233
  ### Not Yet Implemented
202
234
 
@@ -241,8 +273,11 @@ npm install prefix-safe-json
241
273
 
242
274
  ## Low-level API: Quick Start
243
275
 
244
- The execution gate (above) is what most consumers want. The low-level
245
- `createParser()` API it's built on is also fully public, for anyone who
276
+ The AI SDK guard (above) covers the common case. For other providers, or
277
+ when you need the adapter/gate instance directly, `createToolCallExecutionGate()`
278
+ and the provider adapters (`AnthropicStreamAdapter`, `OpenAIStreamAdapter`,
279
+ etc.) are equally public — see [`docs/EXECUTION_GATE.md`](docs/EXECUTION_GATE.md#example).
280
+ The `createParser()` API both are built on is also fully public, for anyone who
246
281
  needs direct access to parser state:
247
282
 
248
283
  ```typescript
@@ -280,10 +315,14 @@ and asserts the truncated call is never reported executable while a
280
315
  genuinely complete one is. This example runs in CI on every push, so it
281
316
  can't silently rot into a stale claim.
282
317
 
283
- For the same demonstration through the high-level execution gate and the
318
+ For the same demonstration through the low-level execution gate and the
284
319
  [Vercel AI SDK](https://ai-sdk.dev)'s `fullStream` shape instead, see
285
320
  [`examples/ai-sdk-execution-gate.mjs`](examples/ai-sdk-execution-gate.mjs)
286
321
  (`node examples/ai-sdk-execution-gate.mjs` after `pnpm run build`) — also
322
+ run in CI on every push. For the drop-in `createAiSdkExecutionGuard()` shown
323
+ at the top of this README, see
324
+ [`examples/ai-sdk-guard.mjs`](examples/ai-sdk-guard.mjs)
325
+ (`node examples/ai-sdk-guard.mjs`) — same scenarios, same guarantees, also
287
326
  run in CI on every push.
288
327
 
289
328
  ## License
@@ -9,6 +9,13 @@ export interface DecisionContext {
9
9
  * rather than per-call state.
10
10
  */
11
11
  readonly streamEndReason: StreamEndReason;
12
+ /**
13
+ * The provider's own pre-normalization reason string for the stream-end
14
+ * event, when one was given (`ProviderStreamEndEvent.providerReason`).
15
+ * Observability only, mirrored onto `DecisionEvidence.providerReason` -
16
+ * never consulted by the decision logic itself.
17
+ */
18
+ readonly streamEndProviderReason?: string;
12
19
  /**
13
20
  * The coordinator's full, unfiltered diagnostics list (`snapshot().diagnostics`).
14
21
  * `decideExecution` splits this into per-call (`internalId` matches) and
@@ -1 +1 @@
1
- {"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../src/gate/decide.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAmB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAErF,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAE1C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACxD;AAeD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,eAAe,GACnB,eAAe,GAAG,qBAAqB,CAmHzC"}
1
+ {"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../src/gate/decide.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,OAAO,EAAoB,eAAe,EAAmB,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEvG,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAE1C;;;;;OAKG;IACH,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAE1C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACxD;AAeD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,eAAe,GACnB,eAAe,GAAG,qBAAqB,CA+HzC"}
@@ -36,6 +36,16 @@ export function decideExecution(call, ctx) {
36
36
  ...globalCoordinatorDiagnostics,
37
37
  ...callCoordinatorDiagnostics,
38
38
  ];
39
+ const evidence = {
40
+ provider: call.provider,
41
+ providerReason: ctx.streamEndProviderReason,
42
+ streamEndReason: ctx.streamEndReason,
43
+ terminalConfirmed: ctx.streamEndReason !== "unknown",
44
+ structurallyComplete: call.parser.rootComplete,
45
+ parserExecutable: call.parser.executable,
46
+ schemaValid: call.schemaValid,
47
+ receivedBytes: call.parser.receivedBytes,
48
+ };
39
49
  const common = {
40
50
  internalId: call.internalId,
41
51
  toolCallId: call.toolCallId,
@@ -44,6 +54,7 @@ export function decideExecution(call, ctx) {
44
54
  stableValue: call.parser.stableValue,
45
55
  parserDiagnostics,
46
56
  coordinatorDiagnostics,
57
+ evidence,
47
58
  };
48
59
  function reject(reason) {
49
60
  return { ...common, action: "reject", executable: false, reason };
@@ -1 +1 @@
1
- {"version":3,"file":"decide.js","sourceRoot":"","sources":["../../src/gate/decide.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decide.js","sourceRoot":"","sources":["../../src/gate/decide.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate/gate.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,iBAAiB,EAEjB,cAAc,EAGf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAEL,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AA+DpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,qBAAqB,CAEvB"}
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate/gate.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,iBAAiB,EAEjB,cAAc,EAGf,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAEL,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AA+EpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACnC,aAAa,CAAC,EAAE,aAAa,EAC7B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAC3C,qBAAqB,CAEvB"}
package/dist/gate/gate.js CHANGED
@@ -14,8 +14,11 @@ class DefaultToolCallExecutionGate {
14
14
  // Mirrors the coordinator's own "first provider_stream_end (from push(),
15
15
  // or from finish()'s meta if none arrived) wins" rule - see push()/finish()
16
16
  // below and DefaultToolCallStreamCoordinator.finish()'s matching
17
- // `if (!this.isFinished)` guard.
17
+ // `if (!this.isFinished)` guard. streamEndProviderReason is captured
18
+ // alongside streamEndReason purely for DecisionEvidence.providerReason -
19
+ // it is never read by decideExecution()'s own logic.
18
20
  streamEndReason;
21
+ streamEndProviderReason;
19
22
  streamEndCaptured = false;
20
23
  constructor(limits, parserOptions, toolSchemas) {
21
24
  this.coordinator = createToolCallStreamCoordinator(limits, parserOptions, toolSchemas);
@@ -24,6 +27,7 @@ class DefaultToolCallExecutionGate {
24
27
  if (event.type === "provider_stream_end" && !this.streamEndCaptured) {
25
28
  this.streamEndCaptured = true;
26
29
  this.streamEndReason = event.reason;
30
+ this.streamEndProviderReason = event.providerReason;
27
31
  }
28
32
  return this.coordinator.push(event);
29
33
  }
@@ -35,6 +39,7 @@ class DefaultToolCallExecutionGate {
35
39
  // every in-flight call is still "collecting" regardless, so this
36
40
  // never influences whether something looks executable.
37
41
  streamEndReason: this.streamEndReason ?? "unknown",
42
+ streamEndProviderReason: this.streamEndProviderReason,
38
43
  diagnostics: snap.diagnostics,
39
44
  };
40
45
  return snap.calls.map((call) => decideExecution(call, ctx));
@@ -46,10 +51,21 @@ class DefaultToolCallExecutionGate {
46
51
  if (!this.streamEndCaptured) {
47
52
  this.streamEndCaptured = true;
48
53
  this.streamEndReason = meta?.reason ?? "unknown";
54
+ this.streamEndProviderReason = meta?.providerReason;
49
55
  }
50
56
  const result = this.coordinator.finish(meta);
51
57
  const diagnostics = this.coordinator.snapshot().diagnostics;
52
- const ctx = { streamEndReason: this.streamEndReason ?? "unknown", diagnostics };
58
+ // Unlike snapshot() above, this point is only ever reached after
59
+ // streamEndCaptured is guaranteed true (set on entry to this method, or
60
+ // already true from an earlier push()/finish() call) - and every path
61
+ // that sets streamEndCaptured sets streamEndReason to a defined value in
62
+ // the same branch, so the pre-finish "unknown" placeholder never applies
63
+ // here.
64
+ const ctx = {
65
+ streamEndReason: this.streamEndReason,
66
+ streamEndProviderReason: this.streamEndProviderReason,
67
+ diagnostics,
68
+ };
53
69
  const decisions = result.calls.map((call) => decideExecution(call, ctx));
54
70
  return { decisions, diagnostics };
55
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/gate/gate.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6DAA6D;AAC7D,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAC5E,8EAA8E;AAE9E,OAAO,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAC;AAUhF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO9C,MAAM,4BAA4B;IACf,WAAW,CAA4B;IAExD,yEAAyE;IACzE,4EAA4E;IAC5E,iEAAiE;IACjE,iCAAiC;IACzB,eAAe,CAA8B;IAC7C,iBAAiB,GAAG,KAAK,CAAC;IAElC,YACE,MAAmC,EACnC,aAA6B,EAC7B,WAA4C;QAE5C,IAAI,CAAC,WAAW,GAAG,+BAA+B,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,CAAC,KAAgC;QACnC,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACN,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG;YACV,oEAAoE;YACpE,oEAAoE;YACpE,iEAAiE;YACjE,uDAAuD;YACvD,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS;YAClD,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,CAAC,IAGN;QACC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,EAAE,MAAM,IAAI,SAAS,CAAC;QACnD,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC;QAC5D,MAAM,GAAG,GAAG,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS,EAAE,WAAW,EAAE,CAAC;QAChF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAEzE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IACpC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAmC,EACnC,aAA6B,EAC7B,WAA4C;IAE5C,OAAO,IAAI,4BAA4B,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAC9E,CAAC"}
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/gate/gate.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { JsonValue, Diagnostic } from "../types.js";
2
2
  import { CoordinatorDiagnostic, CoordinatorPushResult, ToolCallCoordinatorEvent } from "../coordinator/types.js";
3
- import { NormalizedToolStreamEvent, StreamEndReason } from "../coordinator/protocol.js";
3
+ import { NormalizedToolStreamEvent, ProviderName, StreamEndReason } from "../coordinator/protocol.js";
4
4
  /**
5
5
  * What to do with a tool call right now.
6
6
  *
@@ -19,6 +19,62 @@ export type ExecutionAction = "execute" | "retry" | "reject";
19
19
  * See `docs/EXECUTION_GATE.md` for the full decision table.
20
20
  */
21
21
  export type ExecutionReason = "complete" | "truncated" | "stream_incomplete" | "schema_invalid" | "malformed" | "resource_limit" | "provider_error" | "content_filtered" | "unknown";
22
+ /**
23
+ * Why a decision came out the way it did - observability, not a second
24
+ * decision input. Every field here is read-only, derived state already held
25
+ * elsewhere (`ToolCallState`, the stream-level `DecisionContext`); nothing
26
+ * on this object ever feeds back into `decideExecution()`'s own logic, and
27
+ * changing what it reports can never change `action`/`executable`/`reason`.
28
+ *
29
+ * Deliberately excludes anything that would require new cross-layer
30
+ * plumbing to derive reliably (e.g. a received-chunk count - the parser
31
+ * only tracks cumulative bytes, not `push()` call counts, and adding that
32
+ * tracking purely to populate a metric here was judged not worth the
33
+ * coupling for this release).
34
+ */
35
+ export interface DecisionEvidence {
36
+ /** Which provider adapter produced this call (`ToolCallState.provider`). */
37
+ readonly provider: ProviderName;
38
+ /**
39
+ * The provider's own, pre-normalization finish/stop reason string, when
40
+ * the stream-ending event carried one (e.g. `"length"`, `"max_output_tokens"`,
41
+ * `"content_filter"`). `undefined` when the stream never reported one, or
42
+ * reported one without a `providerReason` (e.g. a default `finish()` call
43
+ * with no `meta`).
44
+ */
45
+ readonly providerReason?: string;
46
+ /** The normalized, library-level stream-end reason applied to this call. */
47
+ readonly streamEndReason: StreamEndReason;
48
+ /**
49
+ * Whether a real `provider_stream_end` reason was ever observed, as
50
+ * opposed to the neutral `"unknown"` default a gate reports before any
51
+ * stream-end signal has arrived at all. `true` here does NOT mean the
52
+ * reason was safe - a confirmed `"length"` still has `terminalConfirmed:
53
+ * true` - only that the stream's end state is genuinely known rather than
54
+ * merely unclassified or never observed.
55
+ */
56
+ readonly terminalConfirmed: boolean;
57
+ /**
58
+ * Whether the parser's root JSON container actually closed
59
+ * (`ToolCallState.parser.rootComplete`) - independent of whether that
60
+ * closure was genuine or reached via a safe-close repair, and independent
61
+ * of whether the stream-end reason makes it trustworthy. A syntactically
62
+ * complete value cut short by `length` has `structurallyComplete: true`
63
+ * and `parserExecutable: false` at the same time - that combination *is*
64
+ * the scenario this library exists to catch.
65
+ */
66
+ readonly structurallyComplete: boolean;
67
+ /** `ToolCallState.parser.executable`, verbatim - the parser's own fail-closed verdict. */
68
+ readonly parserExecutable: boolean;
69
+ /**
70
+ * `ToolCallState.schemaValid`, verbatim. `undefined` when no schema was
71
+ * registered for this tool, or the call never reached a structurally
72
+ * complete outcome.
73
+ */
74
+ readonly schemaValid?: boolean;
75
+ /** Total bytes received for this call's argument stream (`ToolCallState.parser.receivedBytes`). */
76
+ readonly receivedBytes: number;
77
+ }
22
78
  interface ExecutionDecisionCommon {
23
79
  /** The coordinator's internal call identifier (see `ToolCallState.internalId`). */
24
80
  readonly internalId: string;
@@ -38,6 +94,12 @@ interface ExecutionDecisionCommon {
38
94
  readonly parserDiagnostics: readonly Diagnostic[];
39
95
  /** Coordinator-level diagnostics attributable to this call, verbatim. */
40
96
  readonly coordinatorDiagnostics: readonly CoordinatorDiagnostic[];
97
+ /**
98
+ * Why this decision came out the way it did. See `DecisionEvidence` -
99
+ * always present, purely observational, never a second source of truth
100
+ * for `action`/`executable`/`reason`.
101
+ */
102
+ readonly evidence: DecisionEvidence;
41
103
  }
42
104
  /**
43
105
  * The one and only shape a decision can have when `action === "execute"`.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gate/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAExF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,WAAW,GACX,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,SAAS,CAAC;AAEd,UAAU,uBAAuB;IAC/B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IAEjC,yFAAyF;IACzF,QAAQ,CAAC,iBAAiB,EAAE,SAAS,UAAU,EAAE,CAAC;IAElD,yEAAyE;IACzE,QAAQ,CAAC,sBAAsB,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACnE;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAgB,SAAQ,uBAAuB;IAC9D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAE1B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;CACvD;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,qBAAqB,CAAC;AAExE,MAAM,WAAW,gCAAgC;IAC/C,+DAA+D;IAC/D,QAAQ,CAAC,SAAS,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAEjD;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACxD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,KAAK,EAAE,yBAAyB,GAAG,qBAAqB,CAAC;IAE9D;;;;;OAKG;IACH,QAAQ,IAAI,SAAS,iBAAiB,EAAE,CAAC;IAEzC,sFAAsF;IACtF,WAAW,IAAI,SAAS,wBAAwB,EAAE,CAAC;IAEnD,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,eAAe,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,gCAAgC,CAAC;CACtC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gate/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { AiSdkExecutionGuard, ExecutionGuardOptions } from "./types.js";
2
+ /**
3
+ * @public (Experimental)
4
+ * Drop-in fail-closed execution guard for the Vercel AI SDK's `fullStream`.
5
+ * Composes `AiSdkStreamAdapter` with `createToolCallExecutionGate()` - same
6
+ * decision logic, same fail-closed guarantees, no new parser or coordinator.
7
+ * Does not depend on the `ai` package at runtime and does not import its
8
+ * types; `push()` accepts `unknown` and reads only the fields it needs.
9
+ *
10
+ * ```ts
11
+ * const guard = createAiSdkExecutionGuard({
12
+ * schemas: {
13
+ * write_file: {
14
+ * type: "object",
15
+ * properties: { path: { type: "string" }, content: { type: "string" } },
16
+ * required: ["path", "content"],
17
+ * },
18
+ * },
19
+ * });
20
+ *
21
+ * for await (const part of result.fullStream) {
22
+ * guard.push(part);
23
+ * }
24
+ *
25
+ * const final = guard.finish();
26
+ * for (const decision of final.decisions) {
27
+ * if (decision.action === "execute") {
28
+ * await tools[decision.name](decision.value);
29
+ * }
30
+ * }
31
+ * ```
32
+ *
33
+ * Equivalent to composing the low-level API yourself:
34
+ *
35
+ * ```ts
36
+ * const gate = createToolCallExecutionGate(undefined, undefined, schemas);
37
+ * const adapter = new AiSdkStreamAdapter();
38
+ * for await (const part of result.fullStream) {
39
+ * for (const normalized of adapter.push(part)) gate.push(normalized);
40
+ * }
41
+ * const final = gate.finish();
42
+ * ```
43
+ *
44
+ * Both APIs remain public; use this one for the common case, the low-level
45
+ * one when you need direct access to the adapter or gate instance.
46
+ */
47
+ export declare function createAiSdkExecutionGuard(options?: ExecutionGuardOptions): AiSdkExecutionGuard;
48
+ //# sourceMappingURL=ai-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.d.ts","sourceRoot":"","sources":["../../src/guard/ai-sdk.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,mBAAmB,CAE9F"}
@@ -0,0 +1,51 @@
1
+ import { AiSdkStreamAdapter } from "../providers/ai-sdk.js";
2
+ import { createProviderExecutionGuard } from "./provider-guard.js";
3
+ /**
4
+ * @public (Experimental)
5
+ * Drop-in fail-closed execution guard for the Vercel AI SDK's `fullStream`.
6
+ * Composes `AiSdkStreamAdapter` with `createToolCallExecutionGate()` - same
7
+ * decision logic, same fail-closed guarantees, no new parser or coordinator.
8
+ * Does not depend on the `ai` package at runtime and does not import its
9
+ * types; `push()` accepts `unknown` and reads only the fields it needs.
10
+ *
11
+ * ```ts
12
+ * const guard = createAiSdkExecutionGuard({
13
+ * schemas: {
14
+ * write_file: {
15
+ * type: "object",
16
+ * properties: { path: { type: "string" }, content: { type: "string" } },
17
+ * required: ["path", "content"],
18
+ * },
19
+ * },
20
+ * });
21
+ *
22
+ * for await (const part of result.fullStream) {
23
+ * guard.push(part);
24
+ * }
25
+ *
26
+ * const final = guard.finish();
27
+ * for (const decision of final.decisions) {
28
+ * if (decision.action === "execute") {
29
+ * await tools[decision.name](decision.value);
30
+ * }
31
+ * }
32
+ * ```
33
+ *
34
+ * Equivalent to composing the low-level API yourself:
35
+ *
36
+ * ```ts
37
+ * const gate = createToolCallExecutionGate(undefined, undefined, schemas);
38
+ * const adapter = new AiSdkStreamAdapter();
39
+ * for await (const part of result.fullStream) {
40
+ * for (const normalized of adapter.push(part)) gate.push(normalized);
41
+ * }
42
+ * const final = gate.finish();
43
+ * ```
44
+ *
45
+ * Both APIs remain public; use this one for the common case, the low-level
46
+ * one when you need direct access to the adapter or gate instance.
47
+ */
48
+ export function createAiSdkExecutionGuard(options) {
49
+ return createProviderExecutionGuard(new AiSdkStreamAdapter(), options);
50
+ }
51
+ //# sourceMappingURL=ai-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/guard/ai-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAA+B;IACvE,OAAO,4BAA4B,CAAC,IAAI,kBAAkB,EAAE,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { ProviderStreamAdapter } from "../providers/adapter.js";
2
+ import { ExecutionGuard, ExecutionGuardOptions } from "./types.js";
3
+ export declare function createProviderExecutionGuard<TRawEvent>(adapter: ProviderStreamAdapter<TRawEvent>, options?: ExecutionGuardOptions): ExecutionGuard<TRawEvent>;
4
+ //# sourceMappingURL=provider-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-guard.d.ts","sourceRoot":"","sources":["../../src/guard/provider-guard.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnE,wBAAgB,4BAA4B,CAAC,SAAS,EACpD,OAAO,EAAE,qBAAqB,CAAC,SAAS,CAAC,EACzC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,cAAc,CAAC,SAAS,CAAC,CA0B3B"}
@@ -0,0 +1,38 @@
1
+ // ---------------------------------------------------------------------------
2
+ // createProviderExecutionGuard — internal composition helper.
3
+ //
4
+ // Not exported from the package root in this release. Every high-level
5
+ // per-provider guard (currently only createAiSdkExecutionGuard) is this
6
+ // function applied to one ProviderStreamAdapter instance - no duplicated
7
+ // state, no duplicated decision logic, no new parser or coordinator. Kept
8
+ // internal (rather than public) until a second provider guard actually
9
+ // needs it, per the "don't expose abstraction for its own sake" scoping
10
+ // this release deliberately holds to - promoting it to a public export is a
11
+ // non-breaking addition whenever that happens.
12
+ // ---------------------------------------------------------------------------
13
+ import { createToolCallExecutionGate } from "../gate/gate.js";
14
+ export function createProviderExecutionGuard(adapter, options) {
15
+ const gate = createToolCallExecutionGate(options?.limits, options?.parserOptions, options?.schemas);
16
+ return {
17
+ push(rawEvent) {
18
+ for (const normalized of adapter.push(rawEvent)) {
19
+ gate.push(normalized);
20
+ }
21
+ },
22
+ snapshot() {
23
+ return gate.snapshot();
24
+ },
25
+ finish(meta) {
26
+ // If the provider stream already delivered its own terminal event
27
+ // through push() (the common case), the adapter is already
28
+ // `finished` and this is a no-op - meta is only consulted as a
29
+ // fail-closed backstop for a stream that ends without ever reporting
30
+ // why (see ProviderStreamAdapter.finish()'s own contract).
31
+ for (const normalized of adapter.finish(meta)) {
32
+ gate.push(normalized);
33
+ }
34
+ return gate.finish(meta);
35
+ },
36
+ };
37
+ }
38
+ //# sourceMappingURL=provider-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-guard.js","sourceRoot":"","sources":["../../src/guard/provider-guard.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,8DAA8D;AAC9D,EAAE;AACF,uEAAuE;AACvE,wEAAwE;AACxE,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,wEAAwE;AACxE,4EAA4E;AAC5E,+CAA+C;AAC/C,8EAA8E;AAE9E,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAM9D,MAAM,UAAU,4BAA4B,CAC1C,OAAyC,EACzC,OAA+B;IAE/B,MAAM,IAAI,GAAG,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAEpG,OAAO;QACL,IAAI,CAAC,QAAmB;YACtB,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAChD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;QAED,QAAQ;YACN,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,CAAC;QAED,MAAM,CAAC,IAA4D;YACjE,kEAAkE;YAClE,2DAA2D;YAC3D,+DAA+D;YAC/D,qEAAqE;YACrE,2DAA2D;YAC3D,KAAK,MAAM,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;YACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { StreamEndReason } from "../coordinator/protocol.js";
2
+ import { CoordinatorLimits, JsonSchemaLike } from "../coordinator/types.js";
3
+ import { ToolCallExecutionGateFinalResult, ExecutionDecision } from "../gate/types.js";
4
+ import { ParserOptions } from "../types.js";
5
+ /**
6
+ * High-level, provider-agnostic execution guard: composes a
7
+ * `ProviderStreamAdapter` with a `ToolCallExecutionGate` behind three
8
+ * methods. `push()`/`snapshot()`/`finish()` mirror the underlying gate's own
9
+ * shape exactly - this is a thinner call surface over the same object, not a
10
+ * parallel implementation with its own state or decision logic.
11
+ */
12
+ export interface ExecutionGuard<TRawEvent = unknown> {
13
+ /** Feed one raw provider event (e.g. one `fullStream` part) through the adapter into the gate. */
14
+ push(rawEvent: TRawEvent): void;
15
+ /**
16
+ * In-flight view of every call's current decision. As with the underlying
17
+ * gate, every decision here is `"retry"` or `"reject"` - `"execute"` is
18
+ * only ever returned from `finish()`.
19
+ */
20
+ snapshot(): readonly ExecutionDecision[];
21
+ /**
22
+ * Signals stream completion and returns the final decision for every tool
23
+ * call the stream ever produced. Safe to call even if the underlying
24
+ * provider stream already delivered its own terminal event through
25
+ * `push()` - `meta` is only used as a fallback for a stream that ends
26
+ * without ever reporting why.
27
+ */
28
+ finish(meta?: {
29
+ reason?: StreamEndReason;
30
+ providerReason?: string;
31
+ }): ToolCallExecutionGateFinalResult;
32
+ }
33
+ /** Options accepted by every high-level provider execution guard factory. */
34
+ export interface ExecutionGuardOptions {
35
+ /**
36
+ * Optional JSON Schema (draft-07) per tool name - same option
37
+ * `createToolCallExecutionGate()`/`createToolCallStreamCoordinator()`
38
+ * accept as their third constructor argument.
39
+ */
40
+ schemas?: Record<string, JsonSchemaLike>;
41
+ /** Coordinator-level limits (concurrent tool calls, tool name size, etc.). */
42
+ limits?: Partial<CoordinatorLimits>;
43
+ /** Per-call parser configuration (resource limits, repairs). */
44
+ parserOptions?: ParserOptions;
45
+ }
46
+ /** A guard specialized for the Vercel AI SDK's `fullStream` part shape. See `createAiSdkExecutionGuard`. */
47
+ export type AiSdkExecutionGuard = ExecutionGuard<unknown>;
48
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,cAAc,CAAC,SAAS,GAAG,OAAO;IACjD,kGAAkG;IAClG,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,IAAI,SAAS,iBAAiB,EAAE,CAAC;IAEzC;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,eAAe,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,gCAAgC,CAAC;CACxG;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAEzC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEpC,gEAAgE;IAChE,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,4GAA4G;AAC5G,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -21,7 +21,15 @@ export { CONTENT_FILTERED_DIAGNOSTIC_CODE } from "./coordinator/diagnostic-codes
21
21
  * See docs/EXECUTION_GATE.md.
22
22
  */
23
23
  export { createToolCallExecutionGate } from "./gate/gate.js";
24
- export type { ToolCallExecutionGate, ToolCallExecutionGateFinalResult, ExecutionDecision, ExecuteDecision, NonExecutableDecision, ExecutionAction, ExecutionReason, } from "./gate/types.js";
24
+ export type { ToolCallExecutionGate, ToolCallExecutionGateFinalResult, ExecutionDecision, ExecuteDecision, NonExecutableDecision, ExecutionAction, ExecutionReason, DecisionEvidence, } from "./gate/types.js";
25
+ /**
26
+ * @public (Experimental)
27
+ * Drop-in fail-closed execution guard for the Vercel AI SDK's `fullStream`.
28
+ * Composes `AiSdkStreamAdapter` and `createToolCallExecutionGate()` - see
29
+ * `docs/EXECUTION_GATE.md#high-level-guards`.
30
+ */
31
+ export { createAiSdkExecutionGuard } from "./guard/ai-sdk.js";
32
+ export type { ExecutionGuard, AiSdkExecutionGuard, ExecutionGuardOptions } from "./guard/types.js";
25
33
  export type { ProviderStreamAdapter } from "./providers/adapter.js";
26
34
  /**
27
35
  * @public (Experimental)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,YAAY,EAEV,qBAAqB,EACrB,aAAa,EAGb,UAAU,EACV,cAAc,EACd,WAAW,EAGX,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EAGnB,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD;;;GAGG;AACH,OAAO,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAC/E,YAAY,EACV,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AAGrF;;;;;GAKG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,YAAY,EACV,qBAAqB,EACrB,gCAAgC,EAChC,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAGzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;GAIG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,YAAY,EAEV,qBAAqB,EACrB,aAAa,EAGb,UAAU,EACV,cAAc,EACd,WAAW,EAGX,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EAGnB,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD;;;GAGG;AACH,OAAO,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAC/E,YAAY,EACV,yBAAyB,EACzB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,gCAAgC,EAAE,MAAM,mCAAmC,CAAC;AAGrF;;;;;GAKG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,YAAY,EACV,qBAAqB,EACrB,gCAAgC,EAChC,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB;;;;;GAKG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGnG,YAAY,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;GAIG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}