@eigenpal/cli 0.16.0 → 0.16.2

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.
@@ -25,7 +25,7 @@ implement at runtime. Server-side validation errors point you here.
25
25
  - `transform.*` — deterministic data transforms (set, remove, combine, split, merge,
26
26
  script, template, pdf-embed, xlsx-to-json, json-to-xlsx). WASM sandboxed where applicable.
27
27
  - `action.*` — external side effects (HTTP, invoke another workflow, website reader).
28
- - `control.*` — flow control (if, foreach, parallel, parallel_map, wait, fail).
28
+ - `control.*` — flow control (if, foreach, parallel, parallel_map, wait, human_review, fail).
29
29
 
30
30
  The full per-type catalog with field tables is auto-generated below from
31
31
  `STEP_SCHEMAS`. The high-level map above tells you which family you want;
@@ -40,6 +40,7 @@ the catalog tells you what fields it takes.
40
40
  | Pull a typed object from text | `ai.extract` with `config.schema` |
41
41
  | Pick one label from a fixed set | `ai.classify` with `config.labels` |
42
42
  | Reject bad inputs with a 4xx code | `control.fail` (often after `ai.classify`) |
43
+ | Pause for human field review | `control.human_review` (top-level only; see below) |
43
44
  | Sum / filter / regex | `transform.script` (NOT Liquid) |
44
45
  | Render a DOCX or XLSX template (YAML workflow) | `transform.template` with `tmpl_...` or `./file.xlsx` |
45
46
  | Fill a DOCX or XLSX template (runtime agent) | fill-template platform skill |
@@ -158,6 +159,70 @@ $ eigenpal workflow step-type get ai.extract | jq '.outputSchema'
158
159
  Reference user-supplied schema fields the same way:
159
160
  `{{ steps.extract.output.extracted.invoiceNumber }}`.
160
161
 
162
+ ## Human review — top-level gate only
163
+
164
+ `control.human_review` pauses the run until a reviewer confirms or corrects
165
+ selected scalar fields, then resumes with the reviewed object or array. Place
166
+ it as a **top-level sequential step** only — nested placement inside
167
+ `control.if`, `control.foreach`, `control.parallel`, `control.parallel_map`, or
168
+ `control.switch` is rejected at publish time.
169
+
170
+ Config lives in `step.with` (unlike most other `control.*` steps). Wire data
171
+ from an upstream extract or transform, choose a selection mode, and attach run
172
+ files for context:
173
+
174
+ ```yaml
175
+ - name: review-invoice
176
+ type: control.human_review
177
+ with:
178
+ data: '{{ steps.extract.output }}'
179
+ metadataFrom: ai.extract
180
+ instructions: Confirm vendor and total before posting.
181
+ selection:
182
+ mode: confidence
183
+ threshold: medium
184
+ missingConfidence: review
185
+ fields:
186
+ /vendor:
187
+ review: always
188
+ /total:
189
+ threshold: high
190
+ fieldMetadata:
191
+ /vendor:
192
+ label: Vendor name
193
+ /total:
194
+ label: Invoice total
195
+ files:
196
+ includeRunInputs: true
197
+ attachments:
198
+ - '{{ steps.render.output.files[0] }}'
199
+ ```
200
+
201
+ When `metadataFrom: ai.extract` is set and `data` is the whole extract output
202
+ (`{{ steps.<name>.output }}`), the step strips the reserved `_grounding` key,
203
+ derives categorical confidence (`low`, `medium`, `high`) per field, and reuses
204
+ the extract schema when `schema` is omitted.
205
+
206
+ **Selection:** three modes — `confidence` (review fields below threshold),
207
+ `explicit` (review matched include/exclude paths), and `all` (every scalar
208
+ leaf). Thresholds accept numeric `0`–`1` or categorical `low|medium|high`;
209
+ equality auto-approves. Per-path overrides live under `selection.fields` with
210
+ `review: always|never|skip` and optional per-field `threshold`. Prefer
211
+ `selection.fields` over the legacy `fieldMetadata.review`.
212
+
213
+ **Output:** the complete reviewed data in the same shape as `data`. Reference
214
+ downstream fields directly: `{{ steps.review-invoice.output.vendor }}`.
215
+
216
+ **Evaluations:** evaluation runs always simulate review and never pause the
217
+ run. Use `meta.json` `review` fixtures to assert routing, reasons, and
218
+ simulated reviewer edits — see `reference/dataset-format.md`. Empty selection
219
+ continues immediately without creating a task.
220
+
221
+ **Limits:** 2 MiB review JSON, 10k scalar leaves, 1 MiB metadata, 2k required
222
+ fields, 100 attachments.
223
+
224
+ Use `eigenpal workflow step-type get control.human_review` for the full schema.
225
+
161
226
  ## Control containers — nested step shape and scoping
162
227
 
163
228
  `control.parallel`, `control.parallel_map`, `control.foreach`, `control.if`,
@@ -426,9 +491,9 @@ Extract text from documents (PDF, DOCX, images) using native extraction, OCR, or
426
491
  | `parseMode` | `"ocr"` \| `"vision"` \| `"native"` \| `"native-or-ocr"` | no | | Base parser for PDF/image inputs. OCR is the default; vision uses the selected LLM. `native` extracts PDF embedded text only and never calls OCR or vision. `native-or-ocr` extracts native text, runs page-quality diagnostics, and requests OCR when pages have detectable anomalies (empty, U+FFFD, lone surrogates, forbidden controls, unassigned/noncharacter, heavy PUA). Page selection, subset egress, and billing are provider-dependent. Valid-looking wrong text and literal "?" are not flagged. Text and Office files always use local parsing. |
427
492
  | `ocrModel` | string | no | | OCR provider ID for PDF/image parsing |
428
493
  | `llmModel` | string | no | | LLM provider ID for vision-based parsing |
429
- | `llmReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
494
+ | `llmReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
430
495
  | `figureModel` | string | no | | Vision model used only for the optional figure-description pass |
431
- | `figureReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
496
+ | `figureReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
432
497
  | `maxConcurrency` | number | no | `3` | Max concurrent VLM batch requests |
433
498
  | `pagesPerBatch` | number | no | `5` | Number of page images per VLM request |
434
499
  | `pdfRenderScale` | number | no | `1` | Scale factor for rendering PDF pages before VLM parsing. Higher values produce sharper images at larger payload sizes. |
@@ -486,7 +551,7 @@ Config schema:
486
551
  "type": "string"
487
552
  },
488
553
  "llmReasoningEffort": {
489
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
554
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
490
555
  "type": "string",
491
556
  "enum": [
492
557
  "none",
@@ -503,7 +568,7 @@ Config schema:
503
568
  "type": "string"
504
569
  },
505
570
  "figureReasoningEffort": {
506
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
571
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
507
572
  "type": "string",
508
573
  "enum": [
509
574
  "none",
@@ -1390,17 +1455,17 @@ Extract structured data from text using AI with a JSON schema
1390
1455
  | `prompt` | string | no | | Custom prompt template for extraction |
1391
1456
  | `provider` | string | no | | Provider ID (e.g., "openai-gpt4o") |
1392
1457
  | `model` | string | no | | Model override |
1393
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
1458
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
1394
1459
  | `maxInputTokens` | integer | no | | Max input tokens. Truncates input text and logs a warning when exceeded. Omit for no limit. |
1395
1460
  | `grounded` | boolean | no | | Grounding is ON by default: each schema field gets a source span + confidence (high=verbatim, medium=fuzzy, low=ungrounded) under a reserved `_grounding` output key, and fields whose value cannot be located in the source are flagged for human review. Values stay the reliable schema-typed ones. The pass runs through the workspace LLM (any provider) and chunks long documents automatically. Tri-state: unset (default) = on, degrading gracefully to deterministic text alignment (`_grounding._degraded: true`) if no grounding model is available; `true` = strict, the step fails when the grounding model cannot be resolved; `false` = off, no `_grounding` key at all. |
1396
1461
  | `groundingModel` | string | no | | Provider/model for the grounding pass. Defaults to the workspace default LLM. Any configured provider works; the pass only fails the step when `grounded: true` is set explicitly and no model resolves. |
1397
- | `groundingReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
1462
+ | `groundingReasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
1398
1463
  | `groundingExamples` | array<object> | no | | Optional few-shot examples pinning grounding to verbatim source text per field. |
1399
1464
  | `reviewOn` | `"medium_or_low"` \| `"low_only"` | no | | Which grounding confidences set needsReview on a field. Default: low_only (only fields whose value could not be located in the source). Use medium_or_low to also flag approximate and derived matches. |
1400
1465
 
1401
1466
  **Output:** `record<string, unknown>`
1402
1467
 
1403
- > Extracted structured data matching the provided schema. Unless grounding is disabled (grounded: false), the output also carries a reserved `_grounding` map keyed by field name: `_grounding.<field> = { confidence: high|medium|low, needsReview, reason?, source_span: { start, end, text, alignment } | null }`, plus reserved `_degraded: true` / `_reason` markers when the grounding LLM pass could not run.
1468
+ > Extracted structured data matching the provided schema. Unless grounding is disabled (grounded: false), the output also carries a reserved `_grounding` map keyed by dotted field path: `_grounding["line_items.0.amount"] = { confidence: high|medium|low, score?, needsReview, reason?, quote?, citations?, source_span }`, plus reserved `_degraded: true` / `_reason` markers when grounding could not run the shared algorithm or the Eigenpal text pass. Lineage is never included in this JSON.
1404
1469
 
1405
1470
  ##### Complete machine-readable schemas
1406
1471
 
@@ -1456,7 +1521,7 @@ Config schema:
1456
1521
  "type": "string"
1457
1522
  },
1458
1523
  "reasoningEffort": {
1459
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
1524
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
1460
1525
  "type": "string",
1461
1526
  "enum": [
1462
1527
  "none",
@@ -1483,7 +1548,7 @@ Config schema:
1483
1548
  "type": "string"
1484
1549
  },
1485
1550
  "groundingReasoningEffort": {
1486
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
1551
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
1487
1552
  "type": "string",
1488
1553
  "enum": [
1489
1554
  "none",
@@ -1559,7 +1624,7 @@ Output schema:
1559
1624
  "type": "string"
1560
1625
  },
1561
1626
  "additionalProperties": {},
1562
- "description": "Extracted structured data matching the provided schema. Unless grounding is disabled (grounded: false), the output also carries a reserved `_grounding` map keyed by field name: `_grounding.<field> = { confidence: high|medium|low, needsReview, reason?, source_span: { start, end, text, alignment } | null }`, plus reserved `_degraded: true` / `_reason` markers when the grounding LLM pass could not run."
1627
+ "description": "Extracted structured data matching the provided schema. Unless grounding is disabled (grounded: false), the output also carries a reserved `_grounding` map keyed by dotted field path: `_grounding[\"line_items.0.amount\"] = { confidence: high|medium|low, score?, needsReview, reason?, quote?, citations?, source_span }`, plus reserved `_degraded: true` / `_reason` markers when grounding could not run the shared algorithm or the Eigenpal text pass. Lineage is never included in this JSON."
1563
1628
  }
1564
1629
  ```
1565
1630
 
@@ -1580,7 +1645,7 @@ Split a parsed document into named sections using an LLM. Consumes ai.parse outp
1580
1645
  | `sections` | array<object> | yes | | Named sections to find in the document |
1581
1646
  | `rules` | string | no | | Optional natural-language rules appended to the system prompt. E.g. "End-of-section markers like *Koniec prílohy 2* close the current section." |
1582
1647
  | `provider` | string | no | | Provider ID from eigenpal.config.yaml (e.g. "openai-gpt5.4-mini"). Falls back to the tenant default LLM provider when omitted. |
1583
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
1648
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
1584
1649
  | `windowTokenBudget` | integer | no | | Override the per-window token ceiling for this step. Defaults to env SPLIT_WINDOW_TOKEN_BUDGET or 20000. Smaller windows give sharper anchors on contract-style documents (less competing context for the LLM to mis-anchor on); bump to 50k–100k when sections routinely exceed per-window page count. |
1585
1650
 
1586
1651
  **Output:** `object`
@@ -1648,7 +1713,7 @@ Config schema:
1648
1713
  "type": "string"
1649
1714
  },
1650
1715
  "reasoningEffort": {
1651
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
1716
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
1652
1717
  "type": "string",
1653
1718
  "enum": [
1654
1719
  "none",
@@ -2052,7 +2117,7 @@ Separate a concatenated batch (one big scan) into typed document instances using
2052
2117
  | `documentTypes` | array<object> | yes | | The document-type taxonomy. The LLM tags each detected document with one of these names, or the reserved "unknown" type when none fit. |
2053
2118
  | `rules` | string | no | | Optional natural-language rules appended to the system prompt. |
2054
2119
  | `provider` | string | no | | Provider ID from eigenpal.config.yaml. Falls back to the tenant default LLM provider when omitted. |
2055
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
2120
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
2056
2121
  | `windowTokenBudget` | integer | no | | Override the per-window token ceiling. Defaults to env SPLIT_WINDOW_TOKEN_BUDGET or 20000. |
2057
2122
 
2058
2123
  **Output:** `object`
@@ -2107,7 +2172,7 @@ Config schema:
2107
2172
  "type": "string"
2108
2173
  },
2109
2174
  "reasoningEffort": {
2110
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
2175
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
2111
2176
  "type": "string",
2112
2177
  "enum": [
2113
2178
  "none",
@@ -2416,7 +2481,7 @@ Classify a document or text into one of a fixed label set using an LLM. Output e
2416
2481
  | `prompt` | string | no | | Custom classification instructions appended to the system prompt. Use to clarify edge cases or emphasize evidence the model should weigh. |
2417
2482
  | `provider` | string | no | | Provider ID from eigenpal.config.yaml (e.g. "openai-gpt4o-mini"). Falls back to the tenant default LLM provider when omitted. |
2418
2483
  | `model` | string | no | | Model override (advanced) |
2419
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
2484
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
2420
2485
  | `maxInputTokens` | integer | no | | Max input tokens. Truncates input text when exceeded. Omit for no limit. |
2421
2486
 
2422
2487
  **Output:** `object`
@@ -2476,7 +2541,7 @@ Config schema:
2476
2541
  "type": "string"
2477
2542
  },
2478
2543
  "reasoningEffort": {
2479
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
2544
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
2480
2545
  "type": "string",
2481
2546
  "enum": [
2482
2547
  "none",
@@ -2556,7 +2621,7 @@ Assign zero or more labels to each page independently (multi-label) using an LLM
2556
2621
  | `prompt` | string | no | | Extra classification guidance appended to the system prompt. |
2557
2622
  | `provider` | string | no | | Provider ID from eigenpal.config.yaml. Falls back to the tenant default. |
2558
2623
  | `model` | string | no | | Model override (advanced). |
2559
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
2624
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
2560
2625
  | `windowTokenBudget` | integer | no | | Per-window token ceiling. Pages are packed into windows under this budget; one LLM call per window. Defaults to env SPLIT_WINDOW_TOKEN_BUDGET (20000). |
2561
2626
 
2562
2627
  **Output:** `object`
@@ -2623,7 +2688,7 @@ Config schema:
2623
2688
  "type": "string"
2624
2689
  },
2625
2690
  "reasoningEffort": {
2626
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
2691
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
2627
2692
  "type": "string",
2628
2693
  "enum": [
2629
2694
  "none",
@@ -2729,7 +2794,7 @@ Inspect rendered page images with a vision model and return structured JSON matc
2729
2794
  | `prompt` | string | no | | Optional instruction refining the extraction. The schema drives it when omitted. |
2730
2795
  | `provider` | string | no | | Provider ID (must support vision). |
2731
2796
  | `model` | string | no | | Model override (must support vision). |
2732
- | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to preserve the current provider default. |
2797
+ | `reasoningEffort` | `"none"` \| `"minimal"` \| `"low"` \| `"medium"` \| `"high"` \| `"xhigh"` \| `"max"` | no | | Reasoning effort for models that support it. Omit to use the selected model's default. |
2733
2798
  | `renderScale` | number | no | | PDF render scale (1.0 = 72 DPI). Raise for small text or weak VLM OCR. Capped at 6 to avoid oversized page rasters. |
2734
2799
  | `imageQuality` | integer | no | | JPEG quality for rendered pages (default 85). |
2735
2800
  | `maxPages` | integer | no | | Chunk size: the maximum pages sent to the vision model in a single call. When the inspected range (or the whole document) is larger, it is split into chunks of this size and the per-chunk results are merged by a reduce pass. The reduce follows each field's DESCRIPTION: a boolean described as "present on any page" is OR-ed, one described as "true for every page" is AND-ed, and list fields are concatenated. The merge is most reliable for boolean/scalar claims; for schemas that AGGREGATE long lists across chunks it can still drop or reorder items, so prefer a bounded page range for large list extraction. Default 20, capped at 100. |
@@ -2882,7 +2947,7 @@ Config schema:
2882
2947
  "type": "string"
2883
2948
  },
2884
2949
  "reasoningEffort": {
2885
- "description": "Reasoning effort for models that support it. Omit to preserve the current provider default.",
2950
+ "description": "Reasoning effort for models that support it. Omit to use the selected model's default.",
2886
2951
  "type": "string",
2887
2952
  "enum": [
2888
2953
  "none",
@@ -4802,7 +4867,7 @@ Execute another workflow and return its output
4802
4867
  | `execution` | `"inline"` \| `"child"` | no | | inline: run target steps in this execution (default). child: spawn a separate run with lineage. |
4803
4868
  | `input` | record<string, unknown> | no | | Input record keyed by the invoked workflow's declared inputs |
4804
4869
  | `wait` | boolean | no | | Child mode only. Wait for the invoked workflow to complete and return its output (default: true). Set false for fire-and-forget. |
4805
- | `timeout` | number | no | | Child mode only. Max wait time in ms when waiting (default: 300000) |
4870
+ | `timeout` | number | no | | Child mode only. Max wait time in ms while the child is queued or running (default: 300000). Once the child pauses for human review, the parent pauses durably instead of using this timeout. |
4806
4871
  | `pollInterval` | number | no | | Child mode only. How often to poll status in ms when waiting (default: 1000) |
4807
4872
 
4808
4873
  **Output:** `record<string, unknown>`
@@ -4849,7 +4914,7 @@ Config schema:
4849
4914
  "type": "boolean"
4850
4915
  },
4851
4916
  "timeout": {
4852
- "description": "Child mode only. Max wait time in ms when waiting (default: 300000)",
4917
+ "description": "Child mode only. Max wait time in ms while the child is queued or running (default: 300000). Once the child pauses for human review, the parent pauses durably instead of using this timeout.",
4853
4918
  "type": "number"
4854
4919
  },
4855
4920
  "pollInterval": {
@@ -5769,6 +5834,446 @@ Output schema:
5769
5834
  ```
5770
5835
 
5771
5836
 
5837
+ #### `control.human_review` — Human Review
5838
+
5839
+ Pause the run for selective field confirmation or correction, then continue with the reviewed data.
5840
+
5841
+ **Behavior and examples:** `eigenpal docs read steps/control/human_review`
5842
+
5843
+ **Durable retry:** This control step is not retried durably.
5844
+
5845
+ **Config** (in `step.with`):
5846
+
5847
+ | Field | Type | Required | Default | Description |
5848
+ | --- | --- | --- | --- | --- |
5849
+ | `data` | string \| record<string, unknown> \| array<unknown> | yes | | Structured data or a template expression resolving to an object or array |
5850
+ | `schema` | record<string, unknown> | no | | Optional JSON Schema for validating edits and exposing downstream autocomplete. When omitted with metadataFrom: ai.extract and a direct whole-output data expression, the extract step schema is reused. |
5851
+ | `metadataFrom` | `"ai.extract"` | no | | Producer adapter. `ai.extract` derives field confidence from `_grounding` and strips that reserved key from review data. Grounding is not stripped unless this is set. |
5852
+ | `fieldMetadata` | record<string, object> | no | `{}` | RFC 6901 pointer map of producer facts (labels, confidence, display). Selection policy belongs under selection.fields; fieldMetadata.review is a legacy alias. |
5853
+ | `selection` | object | yes | | Field selection policy resolved once when the task is created |
5854
+ | `files` | object | no | `{"includeRunInputs":true,"attachments":[]}` | Run input files and optional current-run attachments for reviewers |
5855
+ | `instructions` | string | no | | Free-form guidance shown above the review workspace |
5856
+
5857
+ **Output:** `unknown`
5858
+
5859
+ > The complete reviewed data in the same object or array shape as the input.
5860
+
5861
+ ##### Complete machine-readable schemas
5862
+
5863
+ Config schema:
5864
+
5865
+ ```json
5866
+ {
5867
+ "$schema": "http://json-schema.org/draft-07/schema#",
5868
+ "type": "object",
5869
+ "properties": {
5870
+ "data": {
5871
+ "anyOf": [
5872
+ {
5873
+ "type": "string",
5874
+ "minLength": 1
5875
+ },
5876
+ {
5877
+ "type": "object",
5878
+ "propertyNames": {
5879
+ "type": "string"
5880
+ },
5881
+ "additionalProperties": {}
5882
+ },
5883
+ {
5884
+ "type": "array",
5885
+ "items": {}
5886
+ }
5887
+ ],
5888
+ "description": "Structured data or a template expression resolving to an object or array"
5889
+ },
5890
+ "schema": {
5891
+ "description": "Optional JSON Schema for validating edits and exposing downstream autocomplete. When omitted with metadataFrom: ai.extract and a direct whole-output data expression, the extract step schema is reused.",
5892
+ "type": "object",
5893
+ "propertyNames": {
5894
+ "type": "string"
5895
+ },
5896
+ "additionalProperties": {}
5897
+ },
5898
+ "metadataFrom": {
5899
+ "type": "string",
5900
+ "enum": [
5901
+ "ai.extract"
5902
+ ],
5903
+ "description": "Producer adapter. `ai.extract` derives field confidence from `_grounding` and strips that reserved key from review data. Grounding is not stripped unless this is set."
5904
+ },
5905
+ "fieldMetadata": {
5906
+ "description": "RFC 6901 pointer map of producer facts (labels, confidence, display). Selection policy belongs under selection.fields; fieldMetadata.review is a legacy alias.",
5907
+ "default": {},
5908
+ "type": "object",
5909
+ "propertyNames": {
5910
+ "type": "string"
5911
+ },
5912
+ "additionalProperties": {
5913
+ "type": "object",
5914
+ "properties": {
5915
+ "confidence": {
5916
+ "anyOf": [
5917
+ {
5918
+ "type": "number",
5919
+ "minimum": 0,
5920
+ "maximum": 1
5921
+ },
5922
+ {
5923
+ "type": "string",
5924
+ "enum": [
5925
+ "low",
5926
+ "medium",
5927
+ "high"
5928
+ ]
5929
+ },
5930
+ {
5931
+ "type": "string",
5932
+ "minLength": 1
5933
+ }
5934
+ ]
5935
+ },
5936
+ "label": {
5937
+ "type": "string",
5938
+ "maxLength": 500
5939
+ },
5940
+ "description": {
5941
+ "type": "string",
5942
+ "maxLength": 5000
5943
+ },
5944
+ "review": {
5945
+ "default": "auto",
5946
+ "type": "string",
5947
+ "enum": [
5948
+ "auto",
5949
+ "always",
5950
+ "never"
5951
+ ]
5952
+ },
5953
+ "display": {
5954
+ "type": "object",
5955
+ "propertyNames": {
5956
+ "type": "string"
5957
+ },
5958
+ "additionalProperties": {}
5959
+ }
5960
+ },
5961
+ "additionalProperties": false
5962
+ }
5963
+ },
5964
+ "selection": {
5965
+ "oneOf": [
5966
+ {
5967
+ "type": "object",
5968
+ "properties": {
5969
+ "include": {
5970
+ "description": "RFC 6901 pointers or wildcard patterns (for example `/items/*/amount`)",
5971
+ "default": [],
5972
+ "type": "array",
5973
+ "items": {
5974
+ "type": "string",
5975
+ "maxLength": 512
5976
+ }
5977
+ },
5978
+ "exclude": {
5979
+ "description": "RFC 6901 pointers removed after include expansion",
5980
+ "default": [],
5981
+ "type": "array",
5982
+ "items": {
5983
+ "type": "string",
5984
+ "maxLength": 512
5985
+ }
5986
+ },
5987
+ "fields": {
5988
+ "description": "Per-field selection policy keyed by exact pointers or wildcard patterns. Exact beats the most specific wildcard; equally specific overlapping wildcards are rejected.",
5989
+ "type": "object",
5990
+ "propertyNames": {
5991
+ "type": "string",
5992
+ "maxLength": 512
5993
+ },
5994
+ "additionalProperties": {
5995
+ "type": "object",
5996
+ "properties": {
5997
+ "review": {
5998
+ "type": "string",
5999
+ "enum": [
6000
+ "always",
6001
+ "never",
6002
+ "skip"
6003
+ ]
6004
+ },
6005
+ "threshold": {
6006
+ "anyOf": [
6007
+ {
6008
+ "type": "number",
6009
+ "minimum": 0,
6010
+ "maximum": 1
6011
+ },
6012
+ {
6013
+ "type": "string",
6014
+ "enum": [
6015
+ "low",
6016
+ "medium",
6017
+ "high"
6018
+ ]
6019
+ },
6020
+ {
6021
+ "type": "string",
6022
+ "minLength": 1
6023
+ }
6024
+ ]
6025
+ }
6026
+ },
6027
+ "additionalProperties": false
6028
+ }
6029
+ },
6030
+ "mode": {
6031
+ "type": "string",
6032
+ "const": "confidence",
6033
+ "description": "Review fields below threshold or missing confidence"
6034
+ },
6035
+ "threshold": {
6036
+ "anyOf": [
6037
+ {
6038
+ "type": "number",
6039
+ "minimum": 0,
6040
+ "maximum": 1
6041
+ },
6042
+ {
6043
+ "type": "string",
6044
+ "enum": [
6045
+ "low",
6046
+ "medium",
6047
+ "high"
6048
+ ]
6049
+ },
6050
+ {
6051
+ "type": "string",
6052
+ "minLength": 1
6053
+ }
6054
+ ],
6055
+ "description": "Fields with confidence strictly below this value require review. Equality auto-approves. Numeric 0–1 or categorical low|medium|high. Template strings are resolved at runtime."
6056
+ },
6057
+ "missingConfidence": {
6058
+ "description": "Whether unscored or type-mismatched fields require review (default review)",
6059
+ "default": "review",
6060
+ "type": "string",
6061
+ "enum": [
6062
+ "review",
6063
+ "skip"
6064
+ ]
6065
+ }
6066
+ },
6067
+ "required": [
6068
+ "mode",
6069
+ "threshold"
6070
+ ],
6071
+ "additionalProperties": false
6072
+ },
6073
+ {
6074
+ "type": "object",
6075
+ "properties": {
6076
+ "include": {
6077
+ "description": "RFC 6901 pointers or wildcard patterns (for example `/items/*/amount`)",
6078
+ "default": [],
6079
+ "type": "array",
6080
+ "items": {
6081
+ "type": "string",
6082
+ "maxLength": 512
6083
+ }
6084
+ },
6085
+ "exclude": {
6086
+ "description": "RFC 6901 pointers removed after include expansion",
6087
+ "default": [],
6088
+ "type": "array",
6089
+ "items": {
6090
+ "type": "string",
6091
+ "maxLength": 512
6092
+ }
6093
+ },
6094
+ "fields": {
6095
+ "description": "Per-field selection policy keyed by exact pointers or wildcard patterns. Exact beats the most specific wildcard; equally specific overlapping wildcards are rejected.",
6096
+ "type": "object",
6097
+ "propertyNames": {
6098
+ "type": "string",
6099
+ "maxLength": 512
6100
+ },
6101
+ "additionalProperties": {
6102
+ "type": "object",
6103
+ "properties": {
6104
+ "review": {
6105
+ "type": "string",
6106
+ "enum": [
6107
+ "always",
6108
+ "never",
6109
+ "skip"
6110
+ ]
6111
+ },
6112
+ "threshold": {
6113
+ "anyOf": [
6114
+ {
6115
+ "type": "number",
6116
+ "minimum": 0,
6117
+ "maximum": 1
6118
+ },
6119
+ {
6120
+ "type": "string",
6121
+ "enum": [
6122
+ "low",
6123
+ "medium",
6124
+ "high"
6125
+ ]
6126
+ },
6127
+ {
6128
+ "type": "string",
6129
+ "minLength": 1
6130
+ }
6131
+ ]
6132
+ }
6133
+ },
6134
+ "additionalProperties": false
6135
+ }
6136
+ },
6137
+ "mode": {
6138
+ "type": "string",
6139
+ "const": "explicit",
6140
+ "description": "Review only paths matched by include/exclude"
6141
+ }
6142
+ },
6143
+ "required": [
6144
+ "mode"
6145
+ ],
6146
+ "additionalProperties": false
6147
+ },
6148
+ {
6149
+ "type": "object",
6150
+ "properties": {
6151
+ "include": {
6152
+ "description": "RFC 6901 pointers or wildcard patterns (for example `/items/*/amount`)",
6153
+ "default": [],
6154
+ "type": "array",
6155
+ "items": {
6156
+ "type": "string",
6157
+ "maxLength": 512
6158
+ }
6159
+ },
6160
+ "exclude": {
6161
+ "description": "RFC 6901 pointers removed after include expansion",
6162
+ "default": [],
6163
+ "type": "array",
6164
+ "items": {
6165
+ "type": "string",
6166
+ "maxLength": 512
6167
+ }
6168
+ },
6169
+ "fields": {
6170
+ "description": "Per-field selection policy keyed by exact pointers or wildcard patterns. Exact beats the most specific wildcard; equally specific overlapping wildcards are rejected.",
6171
+ "type": "object",
6172
+ "propertyNames": {
6173
+ "type": "string",
6174
+ "maxLength": 512
6175
+ },
6176
+ "additionalProperties": {
6177
+ "type": "object",
6178
+ "properties": {
6179
+ "review": {
6180
+ "type": "string",
6181
+ "enum": [
6182
+ "always",
6183
+ "never",
6184
+ "skip"
6185
+ ]
6186
+ },
6187
+ "threshold": {
6188
+ "anyOf": [
6189
+ {
6190
+ "type": "number",
6191
+ "minimum": 0,
6192
+ "maximum": 1
6193
+ },
6194
+ {
6195
+ "type": "string",
6196
+ "enum": [
6197
+ "low",
6198
+ "medium",
6199
+ "high"
6200
+ ]
6201
+ },
6202
+ {
6203
+ "type": "string",
6204
+ "minLength": 1
6205
+ }
6206
+ ]
6207
+ }
6208
+ },
6209
+ "additionalProperties": false
6210
+ }
6211
+ },
6212
+ "mode": {
6213
+ "type": "string",
6214
+ "const": "all",
6215
+ "description": "Review every scalar leaf unless excluded or review: never"
6216
+ }
6217
+ },
6218
+ "required": [
6219
+ "mode"
6220
+ ],
6221
+ "additionalProperties": false
6222
+ }
6223
+ ],
6224
+ "description": "Field selection policy resolved once when the task is created"
6225
+ },
6226
+ "files": {
6227
+ "description": "Run input files and optional current-run attachments for reviewers",
6228
+ "default": {
6229
+ "includeRunInputs": true,
6230
+ "attachments": []
6231
+ },
6232
+ "type": "object",
6233
+ "properties": {
6234
+ "includeRunInputs": {
6235
+ "description": "Attach every authorized run input file to the review task",
6236
+ "default": true,
6237
+ "type": "boolean"
6238
+ },
6239
+ "attachments": {
6240
+ "description": "Additional current-run file or artifact template expressions",
6241
+ "default": [],
6242
+ "maxItems": 100,
6243
+ "type": "array",
6244
+ "items": {
6245
+ "type": "string",
6246
+ "minLength": 1
6247
+ }
6248
+ }
6249
+ },
6250
+ "additionalProperties": false
6251
+ },
6252
+ "instructions": {
6253
+ "description": "Free-form guidance shown above the review workspace",
6254
+ "type": "string",
6255
+ "maxLength": 10000
6256
+ }
6257
+ },
6258
+ "required": [
6259
+ "data",
6260
+ "selection"
6261
+ ],
6262
+ "additionalProperties": false
6263
+ }
6264
+ ```
6265
+
6266
+
6267
+ Output schema:
6268
+
6269
+ ```json
6270
+ {
6271
+ "$schema": "http://json-schema.org/draft-07/schema#",
6272
+ "description": "The complete reviewed data in the same object or array shape as the input."
6273
+ }
6274
+ ```
6275
+
6276
+
5772
6277
  #### `control.fail` — Fail
5773
6278
 
5774
6279
  Terminate the workflow with a typed status code + message. With an optional condition, only fails when the condition is truthy; otherwise always fails when reached. Pair with ai.classify or any prior step to fail fast on bad inputs.