@fayegram-ai/decision-bridge 0.1.1 → 0.1.3

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 (79) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/CONTRIBUTING.md +5 -3
  3. package/README.md +26 -10
  4. package/SECURITY.md +18 -11
  5. package/docs/README.md +19 -5
  6. package/docs/development/ARCHITECTURE.md +36 -7
  7. package/docs/development/DESIGN.md +21 -3
  8. package/docs/development/RELEASING.md +7 -3
  9. package/docs/development/REPOSITORY_LAYOUT.md +2 -0
  10. package/docs/development/TESTING.md +31 -3
  11. package/docs/guides/BROWSER.md +8 -0
  12. package/docs/guides/CLOUDFLARE_DECISIONS.md +24 -46
  13. package/docs/guides/CUSTOMIZATION.md +8 -2
  14. package/docs/guides/CUSTOM_GENERATIVE.md +5 -3
  15. package/docs/guides/CUSTOM_PROVIDERS.md +5 -3
  16. package/docs/guides/EXTRACTION.md +125 -0
  17. package/docs/guides/GETTING_STARTED.md +8 -4
  18. package/docs/guides/JEV.md +167 -0
  19. package/docs/guides/LIVE_DECISIONS.md +163 -0
  20. package/docs/guides/OPENAI_DECISIONS.md +52 -24
  21. package/docs/guides/PLATFORMS.md +3 -3
  22. package/docs/guides/SWITCHING_MODELS.md +6 -2
  23. package/docs/guides/TROUBLESHOOTING.md +25 -0
  24. package/docs/reference/CLI.md +60 -11
  25. package/docs/reference/CONFIGURATION.md +34 -6
  26. package/docs/reference/ERRORS.md +41 -12
  27. package/docs/reference/PROVIDERS.md +31 -8
  28. package/docs/reference/SDK.md +72 -26
  29. package/docs/reference/SOURCES.md +11 -0
  30. package/examples/extraction.mjs +16 -0
  31. package/examples/live-decisions.mjs +24 -0
  32. package/package.json +11 -1
  33. package/schemas/decision.config.schema.json +102 -11
  34. package/src/bridge.mjs +9 -6
  35. package/src/capabilities.mjs +34 -4
  36. package/src/cli/config-validation.mjs +13 -5
  37. package/src/cli/config.mjs +19 -4
  38. package/src/cli/decisions.mjs +8 -0
  39. package/src/cli/initialize.mjs +8 -4
  40. package/src/cli/live.mjs +63 -0
  41. package/src/cli/main.mjs +50 -16
  42. package/src/cli/provider-loader.mjs +3 -2
  43. package/src/cloudflare-decisions.d.mts +12 -5
  44. package/src/decisions.d.mts +28 -4
  45. package/src/errors.mjs +7 -1
  46. package/src/extraction/index.d.mts +66 -0
  47. package/src/extraction/index.mjs +78 -0
  48. package/src/extraction/validation.mjs +105 -0
  49. package/src/index.d.mts +42 -9
  50. package/src/index.mjs +1 -1
  51. package/src/input.mjs +21 -3
  52. package/src/jev.d.mts +16 -0
  53. package/src/live/index.d.mts +73 -0
  54. package/src/live/index.mjs +170 -0
  55. package/src/live/state.mjs +125 -0
  56. package/src/live/validation.mjs +122 -0
  57. package/src/probabilities.mjs +6 -3
  58. package/src/providers/cloudflare-images.mjs +5 -67
  59. package/src/providers/cloudflare-media.mjs +5 -10
  60. package/src/providers/cloudflare-preflight.mjs +4 -3
  61. package/src/providers/cloudflare-profile.mjs +10 -14
  62. package/src/providers/cloudflare-transport.mjs +12 -5
  63. package/src/providers/cloudflare-validation.mjs +3 -1
  64. package/src/providers/decisions-codec.mjs +10 -5
  65. package/src/providers/decisions-input.mjs +120 -0
  66. package/src/providers/decisions-validation.mjs +37 -69
  67. package/src/providers/image-header.mjs +59 -0
  68. package/src/providers/jev-images.mjs +84 -0
  69. package/src/providers/jev-preflight.mjs +62 -0
  70. package/src/providers/jev-profile.mjs +37 -0
  71. package/src/providers/jev.mjs +32 -13
  72. package/src/providers/media-binary.mjs +0 -7
  73. package/src/providers/openai-decisions.mjs +2 -1
  74. package/src/providers/openai-errors.mjs +23 -0
  75. package/src/providers/openai-profile.mjs +2 -1
  76. package/src/questions.mjs +2 -0
  77. package/src/response-transport.mjs +84 -17
  78. package/src/validation.mjs +39 -20
  79. package/src/version.mjs +1 -1
@@ -0,0 +1,163 @@
1
+ # Live Decisions
2
+
3
+ Requires **0.1.3 or later**. See [version availability](../README.md#version-availability)
4
+ and [installation](GETTING_STARTED.md#install-into-your-application).
5
+
6
+ `@fayegram-ai/decision-bridge/live` attaches Decisions handling to an existing
7
+ GPT-Live connection. Your application owns authentication, audio, connection
8
+ setup and reconnection. The controller owns Decisions commands, acknowledgements
9
+ and conservative result correlation. It does not issue additional HTTP inference.
10
+
11
+ ```javascript
12
+ import { createLiveDecisions } from '@fayegram-ai/decision-bridge/live';
13
+
14
+ const live = createLiveDecisions({ transport: {
15
+ send(event) { connection.send(JSON.stringify(event)); },
16
+ subscribe(listener) {
17
+ const message = event => listener({ kind: 'event', event: JSON.parse(event.data) });
18
+ const closed = () => listener({ kind: 'close' });
19
+ const failed = () => listener({ kind: 'error' });
20
+ connection.addEventListener('message', message);
21
+ connection.addEventListener('close', closed);
22
+ connection.addEventListener('error', failed);
23
+ return () => {
24
+ connection.removeEventListener('message', message);
25
+ connection.removeEventListener('close', closed);
26
+ connection.removeEventListener('error', failed);
27
+ };
28
+ },
29
+ } });
30
+
31
+ live.subscribe(event => {
32
+ if (event.type === 'decision') {
33
+ console.log(event.decision, event.correlation);
34
+ }
35
+ });
36
+ await live.configure({
37
+ delegation: { type: 'decisions', decisions: {
38
+ model: 'gpt-6-luna',
39
+ questions: [{ type: 'predicate', name: 'ready', instructions: 'Is the requested action fully specified?' }],
40
+ } },
41
+ });
42
+ ```
43
+
44
+ The connection must already support the required Live events and Decisions
45
+ permissions. Start the session with Decisions delegation if it will delegate to
46
+ Decisions; Live does not allow changing the delegation type after startup.
47
+ `transport.subscribe` receives a listener for `{ kind: 'event',
48
+ event }`, `{ kind: 'close' }`, and `{ kind: 'error' }` notifications and must
49
+ return an unsubscribe function. `send` may return a promise. Dispose the
50
+ controller before replacing a connection; disposal does not close the connection.
51
+
52
+ ## Commands and acknowledgements
53
+
54
+ | Method | Completion |
55
+ | --- | --- |
56
+ | `configure(configuration, options?)` | Matching `session.updated` acknowledgement |
57
+ | `createItem(item, options?)` | Matching `decision.item.created` acknowledgement |
58
+ | `deleteItem(itemId, options?)` | Matching `decision.item.deleted` acknowledgement |
59
+ | `requestDecision(options?)` | Submission receipt, not an inference-result promise |
60
+ | `appendCommentary(content, { delegationId, ...options }?)` | Submission receipt, not a speech-completion promise |
61
+ | `subscribe(observer)` | Returns an unsubscribe function |
62
+ | `dispose()` | Cancels pending waits and detaches owned listeners |
63
+
64
+ Configuration accepts Decisions `delegation` and transcript `triggers`. Each
65
+ trigger specifies `type: 'decisions'`, `event_type` as input or output transcript
66
+ delta, and `decisions: { questions }`. Trigger arrays replace the trigger list;
67
+ an empty list disables them. Omitted fields preserve server configuration.
68
+ Questions use the native predicate/choice/score representation.
69
+
70
+ Decision items are user messages containing text or embedded image parts. Live
71
+ items do not inherit the HTTP Decisions conversation, remote-image or cache
72
+ input extensions. Item creation appends evidence for later evaluations; it does
73
+ not itself request evaluation. IDs are generated uniquely for commands.
74
+
75
+ An application can execute a selected action, append its confirmed outcome with
76
+ `createItem`, wait for acknowledgement, then submit commentary. The controller
77
+ does not execute application actions. Commentary is forwarded with the explicit
78
+ delegation ID or null; any service rejection is reported as an error event.
79
+
80
+ ## Results and correlation
81
+
82
+ Completed native decisions arrive as `type: 'decision'` notifications containing
83
+ the full model, ordered answers and usage. Native refusal answers are preserved.
84
+ The controller does not fabricate partial common success from a refusal.
85
+
86
+ `correlation` contains `matched`, `stale`, source event ID/type, delegation ID,
87
+ trigger ID and a configuration generation when known. Match quality describes
88
+ available protocol evidence, not model accuracy.
89
+
90
+ - Transcript fragments are tracked in delivery order separately for input and
91
+ output. Results can arrive out of order; older/equal source results are stale.
92
+ A newer result from an observed source makes older results stale even when its
93
+ configuration cannot be matched. An unknown source or conflicting direction
94
+ cannot advance the observed order.
95
+ - Configuration becomes active after acknowledgement. Sources observed during
96
+ an in-flight or unresolved update remain unmatched.
97
+ - A rejected update preserves the last acknowledged configuration. If unresolved
98
+ update IDs are evicted from history, future sources stay unmatched for this
99
+ controller's lifetime. Attach a new controller with a known accepted snapshot
100
+ to restore correlation after losing that history.
101
+ - A known delegation or transcript source carries its question snapshot. Missing
102
+ or evicted source/configuration history remains observable and unmatched.
103
+ - Duplicate server event IDs produce `duplicate` notifications within retained
104
+ history. Delegation results consume their source snapshot; repeated results
105
+ cannot become newly matched work.
106
+ - Manual request IDs are not assumed to be echoed by completion events. A manual
107
+ submission receipt cannot be used as proof that a later result belongs to it.
108
+ - Unrelated events do not enter the Decisions state machine.
109
+
110
+ Only apply application actions when your own policy accepts the result and its
111
+ correlation. A supplied starting `configuration` asserts that the application
112
+ already knows the connection's accepted Decisions configuration.
113
+
114
+ ## Resources and failures
115
+
116
+ Defaults are a 30-second command deadline, 128 pending operations, 4096 retained
117
+ history entries per correlation map, and 8 MiB command/event budgets (configurable
118
+ through 64 MiB). These are local resource budgets, independent of server quotas.
119
+ History eviction can make late results unmatched. No service RPM/TPM enforcement,
120
+ automatic command replay or reconnect policy is introduced.
121
+
122
+ Call options accept `signal` and `timeoutMs`. Disconnect and disposal settle
123
+ pending operations. Invalid signal values fail with `CONFIGURATION_ERROR` before
124
+ dispatch. Application cleanup exceptions are isolated, including when the
125
+ connection closes synchronously during attachment.
126
+ A timed-out update may still be accepted upstream; a later
127
+ acknowledgement updates observed state without resolving an unrelated call.
128
+ Cancellation before dispatch preserves the accepted configuration. A correlated
129
+ item acknowledgement with the wrong item ID rejects that operation with
130
+ `INVALID_RESPONSE` immediately.
131
+ Observer failures emit safe `observer_error` notifications and do not repeat work.
132
+ Subscription changes during delivery apply to subsequent notifications; a
133
+ recipient is called at most once for the current notification.
134
+ Server errors are normalized without exposing their raw messages.
135
+ Malformed server events, including nested items and configuration snapshots,
136
+ report `INVALID_RESPONSE`. Unknown validation exceptions use a generic message.
137
+
138
+ ## Offline protocol tools
139
+
140
+ ```shell
141
+ decision live validate configuration.json --kind config
142
+ decision live validate command.json --kind command
143
+ decision live validate event.json --kind event
144
+ decision live replay session.jsonl
145
+ ```
146
+
147
+ Replay records are `{ "direction": "client" | "server", "event": ... }`.
148
+ The same correlation reducer processes them and emits ordered JSONL records.
149
+ No connection, audio device or credential is used. Malformed rows are reported
150
+ individually and make the final exit status nonzero.
151
+ Offline `live validate` treats malformed event files as caller input: it reports
152
+ `VALIDATION_ERROR` and exits 2. Replay retains `INVALID_RESPONSE` for malformed
153
+ server records, continues processing later records, and exits 1 if any row fails.
154
+ A replay represents one connection lifecycle. `session.closed` releases its
155
+ history; subsequent records report `CONNECTION_CLOSED` and make the exit status
156
+ nonzero. Use a separate replay for a replacement connection. Configuration
157
+ updates without event IDs are valid wire commands, but prevent trustworthy
158
+ configuration correlation for the rest of that replay. Controller-generated
159
+ commands always include unique IDs.
160
+
161
+ See the [connection adapter example](../../examples/live-decisions.mjs),
162
+ [OpenAI guide](https://developers.openai.com/api/docs/guides/decisions-voice) and
163
+ [Live protocol reference](https://developers.openai.com/api/reference/resources/live/primary-websocket).
@@ -1,5 +1,8 @@
1
1
  # OpenAI Decisions
2
2
 
3
+ Conversation/tool history, remote images and prompt caching require **0.1.3 or
4
+ later**. See [version availability](../README.md#version-availability).
5
+
3
6
  The `openai-decisions` provider implements the native `POST /v1/decisions` API.
4
7
  Its default model selector is `default`; `luna` selects the supported Luna-family
5
8
  model, and `gpt-6-luna` selects that explicit upstream ID. Decision Bridge resolves
@@ -80,8 +83,9 @@ That native choice's confidence is retained in provider metadata.
80
83
 
81
84
  ## Ordered text and images
82
85
 
83
- Provide exactly one of `state` or `input`. An existing JSON array supplied as
84
- `state` retains its original meaning. New `input` is a nonempty ordered array:
86
+ Choose exactly one of `state`, ordered `input` or `conversation`. An existing
87
+ JSON array supplied as `state` retains its original meaning. Ordered `input` is
88
+ a nonempty array:
85
89
 
86
90
  ```javascript
87
91
  const result = await bridge.evaluate({
@@ -95,9 +99,9 @@ const result = await bridge.evaluate({
95
99
  });
96
100
  ```
97
101
 
98
- Images must be nonempty inline base64 data URLs, such as
99
- `data:image/png;base64,...`. The bridge does not fetch image URLs or read files.
100
- Convert image bytes in your application. OpenAI permits at most 128 images.
102
+ Images accept inline base64 data URLs or an exclusive common `url` HTTP(S)
103
+ reference. Native images use `image_url` for either form. References are forwarded;
104
+ the bridge does not fetch URLs or read files. Image-count admission is server-owned.
101
105
  Detail accepts `low`, `high`, `auto`, `original`, or null; omission uses the service
102
106
  default. Text/image ordering is preserved.
103
107
 
@@ -105,9 +109,8 @@ The default transport request/response limits are 8 MiB each, including encoded
105
109
  images. Set `maxRequestBytes` explicitly for larger requests, up to the existing
106
110
  64 MiB ceiling. These local limits do not override service limits.
107
111
 
108
- `safetyIdentifier` is an optional per-request opaque string of at most 128
109
- Unicode characters, or null. It maps to `safety_identifier`; avoid private identity
110
- data. Character limits count Unicode code points rather than UTF-16 code units.
112
+ `safetyIdentifier` is an optional per-request opaque string or null. It maps
113
+ to `safety_identifier`; length admission remains upstream.
111
114
 
112
115
  ## Typed choices and labelled scores
113
116
 
@@ -130,35 +133,38 @@ coercion to object keys are not supported. TypeScript preserves literal unions.
130
133
  `scoreLevels` stores ordered `levels` instead of `criteria` and requires at least
131
134
  two `{ label, description? }` objects. Its answer retains the numeric score and
132
135
  index-keyed probability map, with the original level objects in the legend.
133
- OpenAI choice questions require 2–255 unique options in both common forms and
134
- native requests. Labelled scores do not inherit Jev's 10-level limit; legacy
135
- score criteria retain the 2–10-level limit. JSON snapshots and transport caps
136
- apply to all requests.
136
+ Choices require at least two distinct options for OpenAI. Service count ceilings
137
+ are not enforced locally. Both labelled and legacy scores retain ordered levels;
138
+ JSON safety and configured client wire budgets apply to all forms.
137
139
 
138
140
  ## Capabilities and preparation
139
141
 
140
142
  `bridge.getCapabilities(model?)` synchronously reports support and limits for
141
143
  ordered input, images, typed choices, labelled scores, and safety identifiers.
144
+ It also reports conversation/tool history, remote images and prompt caching.
142
145
  `bridge.validate(request)` resolves the model, snapshots/freezes the request,
143
146
  and checks capabilities without inference. Unsupported combinations fail before
144
147
  dispatch with `UNSUPPORTED_CAPABILITY`.
145
148
 
146
- Preflight also checks the encoded native field limits and the complete UTF-8 wire
149
+ Preflight also checks the encoded native structure and the complete UTF-8 wire
147
150
  body against `maxRequestBytes`. SDK array batches check every raw request before
148
151
  dispatching any entry. Prepared input is revalidated during each evaluation.
149
152
 
150
- Jev, OpenAI-compatible, OpenRouter, and Anthropic currently support the legacy
151
- common forms. Existing custom providers default to that profile; implement
153
+ Jev supports shared state and ordered text, with experimental images and boxes;
154
+ the maintained generative presets use legacy shared-state forms. Existing custom
155
+ providers default to the legacy profile; implement
152
156
  `getCapabilities(model)` and corresponding behavior to support new forms.
153
157
 
154
- Use `prepareInput(parts, context)` for ordered input and `prepareState` for state.
158
+ Use `prepareInput(parts, context)` for ordered input, `prepareState` for state,
159
+ and `prepareConversation(items, context)` for conversation history.
155
160
  A preparation extension must implement the hook for the form being used;
156
161
  incompatible extensions fail explicitly rather than being skipped. Extensions
157
- can implement both hooks. `onResult` works with either form and runs only after
162
+ can implement all three preparation hooks. `onResult` works with every form and runs only after
158
163
  success, with the existing isolated-failure policy.
159
164
 
160
165
  Legacy common requests retain `meta.schemaVersion: 1`. New input/question forms
161
- or safety identifiers use version 2.
166
+ or safety identifiers use version 2. Conversation, remote image URLs or cache
167
+ controls select version 5; see [conversation and prompt caching](#conversation-and-prompt-caching).
162
168
 
163
169
  ## Dedicated native access
164
170
 
@@ -178,11 +184,11 @@ const { decision, meta } = await provider.createDecision({
178
184
  }, { signal: controller.signal });
179
185
  ```
180
186
 
181
- An omitted model inherits the provider's configured selection. Native input accepts text or
182
- multiple user messages containing text or ordered `input_text`/`input_image`
183
- parts. Only user roles are supported. Files, external image URLs, audio, tools,
184
- and item references are rejected locally. Exported `NativeDecisionRequest` and
185
- related types describe this format.
187
+ An omitted model inherits the provider's configured selection. Native input accepts
188
+ text, role-aware messages, assistant output/refusal content and function/custom-tool
189
+ calls and outputs. Images may be embedded or remote HTTP(S) references. File IDs,
190
+ audio and item references remain unsupported. Exported native types describe the
191
+ Decisions-specific representation; tool payload strings remain verbatim.
186
192
 
187
193
  `decision` preserves native answer arrays, optional question names, probabilities,
188
194
  confidence, and full usage. `meta` has the exported `OpenAIDecisionsTransportMetadata`
@@ -239,7 +245,7 @@ OpenAI initialization stores the model selection in configuration and omits it
239
245
  from the generated request so later configuration changes apply. The default
240
246
  configuration uses `default`. Offline validation reports the selected value as
241
247
  `model` and the outgoing upstream ID as `resolvedModel`.
242
- Decisions offline validation also checks native field limits and the configured
248
+ Decisions offline validation also checks native structure and the configured
243
249
  request byte limit in both modes.
244
250
 
245
251
  The `schema` command remains a generative utility and rejects the new request
@@ -250,3 +256,25 @@ From a source checkout, the optional `npm run smoke:live -- --decisions --env-fi
250
256
  checks four bounded requests when `RUN_LIVE_TESTS=1` is explicitly set. It checks
251
257
  protocol behavior rather than prediction quality, disables retries, and prints
252
258
  only model identities and token usage. Normal verification never runs it.
259
+
260
+ ## Conversation and prompt caching
261
+
262
+ Common requests select exactly one of `state`, ordered `input` or `conversation`.
263
+ Conversation items use `NativeDecisionInputItem`: user/developer/system messages,
264
+ assistant messages with optional commentary/final_answer phase, function calls,
265
+ custom tool calls and their outputs. Tool outputs reference preceding call IDs.
266
+ System/developer content is text; assistant parts are output text or refusal.
267
+
268
+ `promptCacheKey` and `promptCacheOptions` map to native `prompt_cache_key` and
269
+ `prompt_cache_options`. Options support implicit/explicit mode and Decisions'
270
+ 30m TTL. Eligible common text/image parts accept `promptCacheBreakpoint` with
271
+ explicit mode or null; native content uses `prompt_cache_breakpoint`. The adapter
272
+ preserves breakpoints, omission and explicit nulls without selecting cache writes.
273
+
274
+ Use `prepareConversation(items, context)` to transform conversation input.
275
+ Transformations are snapshotted, frozen and revalidated before dispatch. Capability
276
+ flags are `conversation`, `toolHistory`, `remoteImages` and `promptCaching`;
277
+ existing custom providers default to false. New-feature requests use common
278
+ schema version 5; existing forms retain versions 1–4.
279
+
280
+ See [Live Decisions](LIVE_DECISIONS.md) for the separate connection lifecycle.
@@ -22,7 +22,7 @@ compatible native Node runtime. See [testing](../development/TESTING.md).
22
22
  Open PowerShell at the cloned repository or extracted source directory:
23
23
 
24
24
  ```powershell
25
- cd "C:\path\to\decision-bridge-0.1.1"
25
+ cd "C:\path\to\decision-bridge"
26
26
  node --version
27
27
  node bin/decision.mjs validate examples/request.json
28
28
  Copy-Item .env.example .env
@@ -48,7 +48,7 @@ the archive rather than reusing generated `node_modules` or executable shims.
48
48
  ## macOS / Linux
49
49
 
50
50
  ```bash
51
- cd "/path/to/decision-bridge-0.1.1"
51
+ cd "/path/to/decision-bridge"
52
52
  node --version
53
53
  node bin/decision.mjs validate examples/request.json
54
54
  cp .env.example .env
@@ -73,7 +73,7 @@ Install the package with npm from your application's directory:
73
73
  npm install @fayegram-ai/decision-bridge
74
74
  ```
75
75
 
76
- For installation from a verified local archive, see
76
+ For version requirements and installation from a verified local archive, see
77
77
  [getting started](GETTING_STARTED.md#install-into-your-application).
78
78
 
79
79
  Import from `@fayegram-ai/decision-bridge` in ESM JavaScript, or invoke the installed
@@ -1,7 +1,8 @@
1
1
  # Switching models without rewriting the application
2
2
 
3
- The bridge's request contains `questions`, either `state` or ordered `input`, and
4
- optionally `model`. Ordered input and richer question types require provider capabilities.
3
+ The bridge's request contains `questions`, exactly one of `state`, ordered `input`
4
+ or `conversation`, and optionally `model`. Ordered input, conversation/tool history,
5
+ remote images, cache controls and richer questions require provider capabilities.
5
6
  The provider translates it into that service's wire protocol and validates the
6
7
  response. Select a provider when constructing your SDK bridge.
7
8
  See [model selectors and provider defaults](../../README.md#model-selectors).
@@ -15,6 +16,9 @@ entry point. A new decision protocol uses [custom decision](CUSTOM_DECISION.md).
15
16
  The example below demonstrates the opt-in generative path; native alternatives
16
17
  follow it.
17
18
 
19
+ Clairic [extraction](EXTRACTION.md) and [Live Decisions](LIVE_DECISIONS.md) use
20
+ dedicated APIs. They cannot replace a provider in an existing `createBridge` call.
21
+
18
22
  ## SDK: same request, different provider
19
23
 
20
24
  Install the package as described in [getting started](GETTING_STARTED.md).
@@ -1,5 +1,13 @@
1
1
  # Troubleshooting
2
2
 
3
+ ## An export or command from these guides is missing
4
+
5
+ Run `npm exec -- decision-bridge --version` in the consuming project and compare
6
+ it with [version availability](../README.md#version-availability). The `/extraction`
7
+ and `/live` exports, their CLI commands, and expanded OpenAI history/cache inputs
8
+ require 0.1.3 or later. See [installation options](GETTING_STARTED.md#install-into-your-application)
9
+ to install a compatible version.
10
+
3
11
  ## The command cannot find a key
4
12
 
5
13
  General `node bin/decision.mjs ...` calls need exported environment variables or an
@@ -81,6 +89,23 @@ file output is not finalized in that case; stdout can contain a completed prefix
81
89
  Some requests may already have been sent/billed. Retrying an entire prefix can
82
90
  repeat work, so retain completed records externally when designing resumability.
83
91
 
92
+ ## Extraction or Live does not behave like bridge evaluation
93
+
94
+ For Clairic, use `CloudflareExtractionProvider` from the `/extraction` export or
95
+ the `extraction` CLI namespace with `cloudflare-extraction`. The root decision
96
+ factory and `createBridge` do not accept extraction providers. An explicit
97
+ provider from config or environment overrides the namespace default and must
98
+ match the operation. A null value, empty list or `truncated: true` can be a valid
99
+ native result; inspect it according to your application's needs.
100
+
101
+ For Live, `requestDecision` and `appendCommentary` resolve on submission. Consume
102
+ completed decisions through `subscribe`. An unmatched result indicates missing or
103
+ ambiguous source/configuration history; a stale result refers to older observed
104
+ transcript order. Neither is proof of a current request result. Disposal and
105
+ connection closure cancel pending waits. Malformed offline event validation exits
106
+ 2, while failed replay rows produce exit 1 and processing continues. See
107
+ [Live lifecycle](LIVE_DECISIONS.md#results-and-correlation).
108
+
84
109
  ## Type checks fail because tsc is missing
85
110
 
86
111
  Runtime and tests have no TypeScript dependency. Development type checks require
@@ -1,7 +1,11 @@
1
1
  # Command runner reference
2
2
 
3
- The optional command runner evaluates files using the same bridge available in
4
- the SDK. For application integration, start with the [SDK guide](../guides/GETTING_STARTED.md).
3
+ The optional command runner evaluates decision files, runs Clairic extraction,
4
+ and validates or replays Live protocol records offline. For application
5
+ integration, start with the [SDK guide](../guides/GETTING_STARTED.md).
6
+
7
+ The extraction and Live commands require **0.1.3 or later**; see
8
+ [version availability](../README.md#version-availability).
5
9
 
6
10
  After [installing the package](../guides/GETTING_STARTED.md#install-into-your-application)
7
11
  in your project, run:
@@ -17,8 +21,10 @@ it with `node bin/decision.mjs` from a source checkout. `decision` and
17
21
  `faye-decision` are equivalent aliases with the same commands and options.
18
22
  `--help` and `--version` do not access credentials or services.
19
23
 
20
- The CLI defaults to Jev. Flags override `DECISION_*` environment settings, which
21
- override an explicit config file and then built-in defaults. It constructs an
24
+ Decision commands default to Jev. The extraction namespace defaults to
25
+ `cloudflare-extraction` only when no provider was selected. Flags override
26
+ `DECISION_*` environment settings, which override an explicit config file and
27
+ then built-in defaults. It constructs an
22
28
  explicit provider for the SDK; `createBridge` itself has no implicit selection.
23
29
  Choose a supported native model from the
24
30
  [model selector inventory](../../README.md#model-selectors).
@@ -50,10 +56,24 @@ there is no CLI binding selector. Gateway settings route the selected REST reque
50
56
  | `schema [FILE\|-]` | Print the generative response schema for these questions; local only |
51
57
  | `models` | List the configured provider's models; may be paginated |
52
58
  | `batch FILE\|-` | Stream JSONL inputs and ordered JSONL result/error records |
53
-
54
- No input filename on `evaluate`, `validate`, or `schema` selects the bundled sample,
59
+ | `extraction run FILE\|-` | One native extraction; returns `{ extraction, meta }` |
60
+ | `extraction validate FILE\|-` | Offline structural and client-budget validation |
61
+ | `extraction batch FILE\|-` | Ordered extraction JSONL results and per-row errors |
62
+ | `extraction init [DIRECTORY]` | Create an extraction profile, request, schema and credential template |
63
+ | `live validate FILE\|- --kind config\|command\|event` | Offline Live structure validation |
64
+ | `live replay FILE\|-` | Offline JSONL protocol replay; no connection is opened |
65
+
66
+ Jev supports both common and `--native` requests for evaluation, validation,
67
+ initialization, and ordered batches. Experimental images/boxes require
68
+ `--jev-images`, and longer context requires `--jev-long-context` (or matching
69
+ JSON configuration). Use `--no-jev-images` and `--no-jev-long-context` to
70
+ override enabled settings. See the [Jev guide](../guides/JEV.md).
71
+
72
+ No input filename on decision `evaluate`, `validate`, or `schema` selects the bundled sample,
55
73
  not stdin. Use `-` explicitly for stdin. Empty invocation prints help. Configuration
56
74
  and credential errors do not cause fallback to another backend.
75
+ Extraction and Live file operations require an explicit filename or `-`.
76
+ Extraction rejects `--native` because its request already uses native fields.
57
77
 
58
78
  ```bash
59
79
  cat request.json | decision-bridge evaluate - --env-file .env --compact
@@ -88,14 +108,16 @@ later configuration changes to control selection.
88
108
  | --- | --- |
89
109
  | `--config FILE` | Explicit JSON configuration; never autodiscovered |
90
110
  | `--env-file FILE` | Load an explicit environment file without changing the parent shell |
91
- | `--provider NAME` | `jev`, `openai-decisions`, `cloudflare-decisions`, `custom-decision`, `custom-generative` |
111
+ | `--provider NAME` | `jev`, `openai-decisions`, `cloudflare-decisions`, `cloudflare-extraction` (extraction namespace), `custom-decision`, `custom-generative` |
92
112
  | `--preset NAME` | custom-generative preset: `openai-compatible`, `openrouter`, or `anthropic`; exclusive with module |
93
113
  | `--native` | Explicit native Decisions input/output; init/evaluate/validate/batch only |
114
+ | `--jev-images`, `--no-jev-images` | Enable/disable experimental Jev images and boxes |
115
+ | `--jev-long-context`, `--no-jev-long-context` | Enable/disable experimental Jev 262k context |
94
116
  | `--model SELECTOR` | Model selector or supported upstream ID; overrides input JSON model and configured default |
95
117
  | `--base-url URL` | Custom endpoint; requires explicit credential selection |
96
118
  | `--api-key-env NAME` | Environment variable name, never the key itself |
97
119
  | `--account-id ID` | Cloudflare REST account ID |
98
- | `--reject-if-busy`, `--no-reject-if-busy` | Explicit Cloudflare native-request override. Enabling fails local REST preflight with `UNSUPPORTED_CAPABILITY`; disabling permits ordinary inference. See the [REST limitation](../guides/CLOUDFLARE_DECISIONS.md#capacity-rejection-and-ai-gateway) |
120
+ | `--reject-if-busy`, `--no-reject-if-busy` | Override Cloudflare request/provider busy settings. Enabling fails Clef REST preflight; Clairic forwards the setting. See the [Clef REST limitation](../guides/CLOUDFLARE_DECISIONS.md#capacity-rejection-and-ai-gateway) |
99
121
  | `--gateway-id ID` | Existing Cloudflare Gateway; richer settings in config |
100
122
  | `--no-auth` | Only for a loopback OpenAI-compatible endpoint |
101
123
  | `--timeout-ms N` | HTTP and bridge deadline for each evaluation/listing |
@@ -109,6 +131,7 @@ later configuration changes to control selection.
109
131
  | `--force` | Replace existing output; valid only with `--output` |
110
132
  | `--concurrency N` | Batch in-flight limit 1–64; default 4 |
111
133
  | `--pretty`, `--compact` | JSON formatting; pretty by default; batches always JSONL |
134
+ | `--kind config\|command\|event` | Required by `live validate`; rejected by other commands |
112
135
  | `--help`, `-h`, `--version`, `-v` | Informational commands |
113
136
 
114
137
  Unknown or duplicate flags fail. Provider-inapplicable flags fail instead of being
@@ -130,6 +153,10 @@ includes `validationScope: 'provider'` for known native/preset profiles or
130
153
  `'structure'` for a custom module. Structure validation cannot verify an unknown
131
154
  module's capabilities or protocol. `schema` is an offline generative-output tool;
132
155
  it does not add generative support to a native provider.
156
+ Decision validation reports `operation: 'decision'` and `questionCount`;
157
+ extraction reports `operation: 'extraction'` and `fieldCount`. Neither authenticates
158
+ an account or claims server admission. Live validation reports its `kind` and
159
+ `validationScope: 'structure'`.
133
160
 
134
161
  A batch emits one compact record per nonblank input line:
135
162
 
@@ -172,12 +199,17 @@ delivery needs separate validation.
172
199
 
173
200
  ## I/O and resource limits
174
201
 
175
- Single JSON input: **8 MiB**. JSONL: **8 MiB per line, 64 MiB total**. Config:
202
+ Single JSON input normally uses **8 MiB**. JSONL normally uses **8 MiB per line,
203
+ 64 MiB total**. Jev defaults to **32 MiB** for a single JSON input or JSONL record,
204
+ then checks serialized requests against its configured ceiling (32 MiB by default).
205
+ An explicit larger client request budget raises the input reader budget through 64 MiB.
206
+ Config:
176
207
  **1 MiB**. Environment file: **64 KiB**. Provider request and response default to
177
208
  8 MiB each, configurable to at most 64 MiB. Cloudflare reads single JSON inputs
178
209
  and individual JSONL records within 64 MiB, then applies model-specific serialized
179
- request validation: Clef/Clef-flash default/cap 13 MiB; Omni default 36 MiB,
180
- configurable through 64 MiB. Explicit smaller ceilings remain in force. Request
210
+ request validation: Clef/Clef-flash default 13 MiB, configurable through 64 MiB; Omni default 36 MiB,
211
+ configurable through 64 MiB; Clairic defaults to 8 MiB, configurable through 64 MiB.
212
+ Explicit smaller ceilings remain in force. Request
181
213
  model overrides and mixed-model JSONL batches use each effective model's budget.
182
214
  The 64 MiB JSONL total remains. These are client limits, not a promise
183
215
  that every remote model has an equivalent context window.
@@ -211,3 +243,20 @@ Already-cancelled CLI work does not initialize a project or create an output fil
211
243
  File writers check cancellation before writes and before submitting the atomic
212
244
  commit. A commit already submitted to the operating system cannot be undone;
213
245
  cancellation does not roll back a completed write or remote inference billing.
246
+
247
+ ## Offline Live tools
248
+
249
+ Live tools load no provider configuration, environment files or credentials and
250
+ open no connection. They accept input/output and formatting flags; `--kind` is
251
+ required only for validation. Replay always emits compact JSONL.
252
+
253
+ Replay input records are `{ direction: 'client' | 'server', event }`. Each row
254
+ produces `{ line, ok, event }` or `{ line, ok: false, error }` using the same
255
+ correlation state as the SDK controller. Malformed rows remain explicit errors
256
+ and later rows are processed. A closed session ends that replay lifecycle;
257
+ subsequent protocol rows fail with `CONNECTION_CLOSED`.
258
+
259
+ Malformed event-file validation reports `VALIDATION_ERROR` and exits 2. Malformed
260
+ server replay rows retain `INVALID_RESPONSE`; any failed row makes replay exit 1.
261
+ See the [Live guide](../guides/LIVE_DECISIONS.md) for correlation guarantees and
262
+ the [extraction guide](../guides/EXTRACTION.md) for native extraction requests.
@@ -29,16 +29,17 @@ is native-only. Generative presets use `createGenerativeProvider` from the
29
29
  `@fayegram-ai/decision-bridge/config.schema.json` and in
30
30
  [schemas/decision.config.schema.json](../../schemas/decision.config.schema.json).
31
31
  It checks profile structure; runtime preflight additionally checks endpoint,
32
- credential, capability, and model-specific limits.
32
+ credential, capability, and serialized client-byte budgets.
33
33
  Cloudflare CLI configuration always selects REST. Inject a Workers AI binding
34
- through the SDK's `CloudflareDecisionsProvider` constructor instead of a JSON
35
- profile. Gateway configuration is optional for either SDK transport and for CLI REST.
34
+ through the SDK's `CloudflareDecisionsProvider` or `CloudflareExtractionProvider`
35
+ constructor instead of a JSON profile. Gateway configuration is optional for
36
+ either SDK transport and for CLI REST.
36
37
 
37
38
  | Field | Values / scope |
38
39
  | --- | --- |
39
40
  | `$schema` | Optional nonempty schema reference for editors |
40
41
  | `schemaVersion` | 1; optional, but generated profiles include it |
41
- | `provider` | `jev` default, `openai-decisions`, `cloudflare-decisions`, `custom-decision`, `custom-generative` |
42
+ | `provider` | `jev` default for decision commands, `openai-decisions`, `cloudflare-decisions`, `cloudflare-extraction` for extraction commands, `custom-decision`, `custom-generative` |
42
43
  | `preset` | `custom-generative` only: `openai-compatible`, `openrouter`, `anthropic`; mutually exclusive with module |
43
44
  | `model` | Nonempty model selector or supported upstream ID; built-in native providers have defaults; required for generative evaluation unless the request supplies it |
44
45
  | `baseURL` | HTTPS API base; loopback may use HTTP |
@@ -46,10 +47,11 @@ profile. Gateway configuration is optional for either SDK transport and for CLI
46
47
  | `noAuth` | Boolean; true only for loopback OpenAI-compatible endpoints |
47
48
  | `timeoutMs` | Positive integer up to 2,147,483,647 milliseconds |
48
49
  | `maxRetries` | Integer 0–10; OpenAI/Cloudflare default 0; Jev and generative presets default 2 |
49
- | `maxRequestBytes`, `maxResponseBytes` | Positive integer through 64 MiB; default 8 MiB. Cloudflare requests: Clef/Clef-flash default/cap 13 MiB; Omni default 36 MiB, configurable through 64 MiB |
50
+ | `maxRequestBytes`, `maxResponseBytes` | Positive integer through 64 MiB; default 8 MiB, including Clairic. Jev requests default 32 MiB. Clef/Clef-flash requests default 13 MiB; Omni 36 MiB. Explicit request budgets can select through 64 MiB for every built-in provider |
50
51
  | `accountId` | Cloudflare REST account ID; otherwise `CLOUDFLARE_ACCOUNT_ID` |
51
- | `rejectIfBusy` | Cloudflare boolean; default false, incompatible with retries. Effective true fails REST preflight with `UNSUPPORTED_CAPABILITY`; see the [binding support and REST limitation](../guides/CLOUDFLARE_DECISIONS.md#capacity-rejection-and-ai-gateway) |
52
+ | `rejectIfBusy` | Cloudflare boolean; default false, incompatible with retries. Effective true fails Clef REST preflight with `UNSUPPORTED_CAPABILITY`; Clairic forwards the setting for server acceptance/rejection. See the [Clef limitation](../guides/CLOUDFLARE_DECISIONS.md#capacity-rejection-and-ai-gateway) and [extraction options](../guides/EXTRACTION.md#images-binding-and-gateway) |
52
53
  | `gateway` | Cloudflare Gateway object; see the [Cloudflare guide](../guides/CLOUDFLARE_DECISIONS.md) |
54
+ | `dangerZone` | Jev-only `{ images?: boolean, longContext?: boolean }`; both default false; see the [Jev guide](../guides/JEV.md) |
53
55
  | `maxTokens` | Generative output budget, 1–1,048,576; default 4096 |
54
56
  | `responseFormat` | Compatible generative presets: `json_schema`, `json_object`, `text` |
55
57
  | `tokenParameter` | Compatible generative presets: `max_completion_tokens` or `max_tokens` |
@@ -58,6 +60,10 @@ profile. Gateway configuration is optional for either SDK transport and for CLI
58
60
  | `options` | Custom factory's JSON options, e.g. its own baseURL |
59
61
 
60
62
  Upper numeric limits validate client configuration, not vendor model capabilities.
63
+ Jev requests default to a 32 MiB client budget; an explicit `maxRequestBytes`
64
+ can select a budget through 64 MiB. `DECISION_JEV_IMAGES` and `DECISION_JEV_LONG_CONTEXT`
65
+ accept `true` or `false`; their CLI overrides are `--jev-images`,
66
+ `--no-jev-images`, `--jev-long-context`, and `--no-jev-long-context`.
61
67
  Cloudflare selects its byte budget from the effective request model, including
62
68
  per-call overrides. An explicit smaller `maxRequestBytes` remains the ceiling;
63
69
  selecting Omni cannot enlarge it. Omni's default is a bridge policy, not a
@@ -168,3 +174,25 @@ presets, and separate custom decision/generative modules. Use
168
174
  with `--provider-module FILE`. The module flag does not infer classification. Replace placeholder model identifiers
169
175
  with IDs returned by the intended account/server. Profiles intentionally contain
170
176
  no real key or claim that one model is available to every user.
177
+
178
+ ## Extraction and Live configuration
179
+
180
+ The `extraction` namespace supplies provider `cloudflare-extraction` only when
181
+ flags, environment and an explicit file have selected no provider. Its default
182
+ model is `clairic`; `@cf/cloudflare/clairic` is also accepted. An explicit
183
+ incompatible provider is rejected. Provider switching follows the same isolation
184
+ rules above, including transitions between Clef and Clairic. The configuration
185
+ schema stays at version 1.
186
+
187
+ OpenAI prompt-cache controls and Clairic inference settings (`include_quantiles`,
188
+ `return_state_text`) belong in request JSON. Extraction busy-mode flags override
189
+ the request's `options.rejectIfBusy`; otherwise that request value overrides the
190
+ provider setting. See [extraction](../guides/EXTRACTION.md).
191
+
192
+ Live SDK configuration is passed directly to `createLiveDecisions` with a supplied
193
+ transport. Offline `live validate` and `live replay` do not load provider profiles,
194
+ credentials or environment files. See [Live Decisions](../guides/LIVE_DECISIONS.md).
195
+
196
+ Offline validation checks structure and client resource budgets. Service quotas,
197
+ context/media admission and Gateway limits remain upstream; the SDK and CLI do
198
+ not estimate tokens or enforce RPM/TPM.