@eigenpal/cli 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/cli.js +2618 -1637
- package/dist/skill/SKILL.md +111 -15
- package/dist/skill/examples/hello-world/evaluators.yaml +3 -1
- package/dist/skill/reference/cli/agents.md +23 -23
- package/dist/skill/reference/cli/runs.md +15 -15
- package/dist/skill/reference/debugging.md +4 -3
- package/dist/skill/reference/evaluators.md +86 -14
- package/dist/skill/reference/step-types.md +17 -7
- package/package.json +1 -1
package/dist/skill/SKILL.md
CHANGED
|
@@ -14,6 +14,48 @@ metadata:
|
|
|
14
14
|
Use long command names in generated commands and documentation. Short aliases may
|
|
15
15
|
appear in user examples, but do not prefer them.
|
|
16
16
|
|
|
17
|
+
## Non-interactive / agent terminals (read first)
|
|
18
|
+
|
|
19
|
+
**Never run a CLI command that opens a confirmation or picker without checking
|
|
20
|
+
`--help` first.** Agent terminals, CI, and piped shells are usually non-TTY — an
|
|
21
|
+
interactive prompt will hang indefinitely.
|
|
22
|
+
|
|
23
|
+
Rules:
|
|
24
|
+
|
|
25
|
+
- **`--yes`** — skip confirmations and pickers when a deterministic default exists,
|
|
26
|
+
or acknowledge a destructive action in scripts. Required for most cancel/delete/replace
|
|
27
|
+
flows in non-TTY.
|
|
28
|
+
- **`--force`** — only where documented: overwrite user-edited skill files on reinstall
|
|
29
|
+
(`skill install --force`). Do not use as a generic “yes to everything”.
|
|
30
|
+
- **Provide explicit inputs** instead of prompts: `--file`, `--template`, `--tools`,
|
|
31
|
+
`--stdin` / `--value-file`, `--base-url`, profile name for `auth use <name>`,
|
|
32
|
+
`EIGENPAL_API_KEY` instead of `auth login` in CI.
|
|
33
|
+
|
|
34
|
+
Commands that can prompt or block (always inspect `--help` for the exact flag):
|
|
35
|
+
|
|
36
|
+
| Area | Command | Non-interactive bypass |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| Init | `init [name]` | `--template <name>` and/or `--yes` (default template: blank) |
|
|
39
|
+
| Auth | `auth login` | Do not run non-interactively; set `EIGENPAL_API_KEY` and optionally `EIGENPAL_BASE_URL` |
|
|
40
|
+
| Auth | `auth use` | positional profile name |
|
|
41
|
+
| Skill | `skill install` | `--tools claude,cursor` and/or `--yes`; `--force` to overwrite edits |
|
|
42
|
+
| Skill | `skill uninstall` | tool ids, `--all`, or `--target` + `--yes` |
|
|
43
|
+
| Workflow | `workflow push` | `--file workflow.yaml` (TTY-only path picker otherwise) |
|
|
44
|
+
| Workflow | `workflow dataset push --mode replace` | `--yes` |
|
|
45
|
+
| Workflow | `workflow dataset example delete` | `--yes` |
|
|
46
|
+
| Workflow | `workflow experiment cancel` | `--yes` |
|
|
47
|
+
| Workflow | `workflow templates delete` | `--yes` |
|
|
48
|
+
| Agents | `agents dataset push --mode replace` | `--yes` |
|
|
49
|
+
| Agents | `agents experiment cancel` | `--yes` |
|
|
50
|
+
| Agents | `agents session stop` | `--yes` |
|
|
51
|
+
| Agents | `agents secrets set` | `--stdin` or `--value-file` |
|
|
52
|
+
| Runs | `runs cancel` | `--yes` |
|
|
53
|
+
| Runs | `runs reviews clear` | `--yes` |
|
|
54
|
+
| Runs | `runs expected delete` | `--yes` |
|
|
55
|
+
|
|
56
|
+
If a command fails with “requires --yes when run non-interactively”, re-run with
|
|
57
|
+
`--yes` only when the action is intentional — never to blindly retry.
|
|
58
|
+
|
|
17
59
|
## Choose A Command
|
|
18
60
|
|
|
19
61
|
- `eigenpal workflow` manages YAML workflow definitions, datasets, evaluators,
|
|
@@ -30,15 +72,28 @@ appear in user examples, but do not prefer them.
|
|
|
30
72
|
- `eigenpal runs` inspects, watches, compares, reruns, cancels, and downloads
|
|
31
73
|
artifacts for workflow or agent runs.
|
|
32
74
|
|
|
75
|
+
## Authenticate And Select A Workspace
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
eigenpal auth login
|
|
79
|
+
eigenpal status --json
|
|
80
|
+
eigenpal auth list
|
|
81
|
+
eigenpal auth use <profile>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
For CI, set `EIGENPAL_API_KEY` and optionally `EIGENPAL_BASE_URL` instead of
|
|
85
|
+
running the interactive login.
|
|
86
|
+
|
|
33
87
|
Use stable ids in scripts:
|
|
34
88
|
|
|
35
89
|
- Workflow id: `wf_...`
|
|
36
90
|
- Template id: `tmpl_...`
|
|
37
91
|
- Template revision id: `tmpr_...`
|
|
38
|
-
- Workflow execution id: `
|
|
92
|
+
- Workflow execution id: `exec_...`
|
|
39
93
|
- Agent execution id: `aex_...`
|
|
40
94
|
- Experiment batch id: `evb_...`
|
|
41
|
-
-
|
|
95
|
+
- Workflow dataset example id: `evx_...`
|
|
96
|
+
- Agent dataset example id: `aeg_...`
|
|
42
97
|
|
|
43
98
|
## Workflow Loop
|
|
44
99
|
|
|
@@ -48,9 +103,11 @@ eigenpal init workflow invoices --template pdf-extraction
|
|
|
48
103
|
cd invoices
|
|
49
104
|
$EDITOR workflow.yaml
|
|
50
105
|
|
|
51
|
-
# Inspect step schemas before editing config.
|
|
106
|
+
# Inspect step and evaluator schemas before editing config.
|
|
52
107
|
eigenpal workflow step-type list --search extract
|
|
53
|
-
eigenpal workflow step-type get ai.extract
|
|
108
|
+
eigenpal workflow step-type get ai.extract | jq '.configSchema.properties'
|
|
109
|
+
eigenpal workflow evaluator-type list
|
|
110
|
+
eigenpal workflow evaluator-type get exact-diff | jq '.configSchema'
|
|
54
111
|
|
|
55
112
|
# Validate and push.
|
|
56
113
|
eigenpal workflow validate ./workflow.yaml
|
|
@@ -61,7 +118,10 @@ eigenpal workflow validate ./workflow.yaml
|
|
|
61
118
|
# workflow project unless you pass --allow-external-templates.
|
|
62
119
|
eigenpal workflow validate ./workflow.yaml --online
|
|
63
120
|
eigenpal models list --json
|
|
64
|
-
|
|
121
|
+
# First push creates a new wf_…; capture the id from --json output.
|
|
122
|
+
eigenpal workflow push --file workflow.yaml --json | jq '.id'
|
|
123
|
+
# Later pushes must pass --workflow-id to update in place (omit it only on first create).
|
|
124
|
+
eigenpal workflow push --file workflow.yaml --workflow-id wf_…
|
|
65
125
|
|
|
66
126
|
# Run with ad-hoc input and read the output (use this for API-triggered workflows).
|
|
67
127
|
# `--wait --json` polls to completion and prints the run with top-level `output`.
|
|
@@ -125,6 +185,8 @@ Key rules:
|
|
|
125
185
|
# Clone source and create a branch.
|
|
126
186
|
eigenpal agents clone --out ./source
|
|
127
187
|
cd ./source
|
|
188
|
+
# Use `agents save` to validate, commit, and push source. For other Git ops, use
|
|
189
|
+
# `eigenpal git -- <git-args>` (not bare `git` — the passthrough wires credentials).
|
|
128
190
|
eigenpal git -- switch -c <short-task-branch>
|
|
129
191
|
|
|
130
192
|
# Inspect source state.
|
|
@@ -175,15 +237,34 @@ DOCX/XLSX templates for **runtime agents** live in Git source, not in the
|
|
|
175
237
|
workspace Templates table. YAML workflows use workspace templates via
|
|
176
238
|
`transform.template` and `tmpl_...` instead — see `reference/step-types.md`.
|
|
177
239
|
|
|
178
|
-
Workspace DOCX/XLSX templates for YAML workflows:
|
|
240
|
+
Workspace DOCX/XLSX templates for YAML workflows (`tmpl_…` / `tmpr_…`):
|
|
179
241
|
|
|
180
242
|
```bash
|
|
243
|
+
# Upload a new template (returns tmpl_… + tmpr_… with --json).
|
|
181
244
|
eigenpal workflow templates upload ./templates/roster.xlsx --json
|
|
245
|
+
|
|
246
|
+
# List and inspect server templates.
|
|
247
|
+
eigenpal workflow templates list --json
|
|
248
|
+
eigenpal workflow templates get tmpl_…
|
|
249
|
+
eigenpal workflow templates get tmpl_… --json | jq '.currentRevision.id'
|
|
250
|
+
|
|
251
|
+
# Download current bytes (--out required).
|
|
252
|
+
eigenpal workflow templates download tmpl_… --out ./templates/roster.xlsx
|
|
253
|
+
|
|
254
|
+
# Replace with a new local file (creates a new tmpr_… revision).
|
|
255
|
+
eigenpal workflow templates replace tmpl_… ./templates/roster-v2.xlsx --json
|
|
256
|
+
|
|
257
|
+
# Delete the tmpl_… pointer (--yes required outside a TTY).
|
|
258
|
+
eigenpal workflow templates delete tmpl_… --yes
|
|
259
|
+
|
|
260
|
+
# Smoke-fill locally (no server) or from a tmpl_… id (downloads bytes, fills locally).
|
|
182
261
|
eigenpal workflow templates smoke ./templates/roster.xlsx --data ./fixture.json --out ./filled.xlsx
|
|
262
|
+
eigenpal workflow templates smoke tmpl_… --data ./fixture.json --out ./filled.xlsx
|
|
263
|
+
|
|
183
264
|
# YAML may keep a source path; push uploads and sends tmpl_ + tmpr_ ids.
|
|
184
265
|
# template: ./templates/roster.xlsx
|
|
185
266
|
eigenpal workflow validate ./workflow.yaml --online
|
|
186
|
-
eigenpal workflow push --file workflow.yaml
|
|
267
|
+
eigenpal workflow push --file workflow.yaml --workflow-id wf_…
|
|
187
268
|
```
|
|
188
269
|
|
|
189
270
|
**Local template** (one agent):
|
|
@@ -269,10 +350,10 @@ Agent examples are runtime data, not Git source. `agents save` does not persist
|
|
|
269
350
|
them.
|
|
270
351
|
|
|
271
352
|
```bash
|
|
272
|
-
eigenpal agents dataset validate
|
|
273
|
-
eigenpal agents dataset push agents.<slug> --file
|
|
353
|
+
eigenpal agents dataset validate ./dataset --agent-dir agents/<slug>
|
|
354
|
+
eigenpal agents dataset push agents.<slug> --file ./dataset
|
|
274
355
|
eigenpal agents dataset list agents.<slug>
|
|
275
|
-
eigenpal agents dataset pull agents.<slug> --out ./dataset
|
|
356
|
+
eigenpal agents dataset pull agents.<slug> --out ./dataset.zip
|
|
276
357
|
```
|
|
277
358
|
|
|
278
359
|
Expected outputs should include stable fields only. Omit timestamps, random IDs,
|
|
@@ -301,16 +382,18 @@ Use `--version original` only to reproduce the previous resolved version.
|
|
|
301
382
|
```bash
|
|
302
383
|
eigenpal runs reviews update <agent-execution-id> \
|
|
303
384
|
--status open \
|
|
304
|
-
--verdict
|
|
385
|
+
--verdict incorrect \
|
|
305
386
|
--note "Expected the filing date to be extracted."
|
|
306
387
|
eigenpal runs reviews close <agent-execution-id> \
|
|
307
388
|
--note "Fixed and verified."
|
|
308
389
|
eigenpal runs reviews clear <agent-execution-id> --yes
|
|
309
390
|
|
|
310
|
-
eigenpal runs
|
|
311
|
-
eigenpal runs
|
|
312
|
-
eigenpal runs
|
|
313
|
-
eigenpal runs
|
|
391
|
+
eigenpal runs expected list <agent-execution-id>
|
|
392
|
+
eigenpal runs expected upload <agent-execution-id> expected.json --name expected.json
|
|
393
|
+
eigenpal runs expected copy-output <agent-execution-id> result.json --name expected.json
|
|
394
|
+
eigenpal runs expected pull <agent-execution-id> --out expected/
|
|
395
|
+
eigenpal runs expected rename <agent-execution-id> old.json new.json
|
|
396
|
+
eigenpal runs expected delete <agent-execution-id> old.json --yes
|
|
314
397
|
```
|
|
315
398
|
|
|
316
399
|
## Output
|
|
@@ -336,12 +419,25 @@ Status messages go to stderr. Pipeable data goes to stdout.
|
|
|
336
419
|
|
|
337
420
|
Use generated references for exact flags and defaults:
|
|
338
421
|
|
|
422
|
+
CLI command references:
|
|
423
|
+
|
|
339
424
|
- [`reference/cli/workflow.md`](reference/cli/workflow.md)
|
|
340
425
|
- [`reference/cli/agents.md`](reference/cli/agents.md)
|
|
341
426
|
- [`reference/cli/runs.md`](reference/cli/runs.md)
|
|
427
|
+
- [`reference/cli/run.md`](reference/cli/run.md)
|
|
428
|
+
- [`reference/cli/rerun.md`](reference/cli/rerun.md)
|
|
342
429
|
- [`reference/cli/auth.md`](reference/cli/auth.md)
|
|
430
|
+
- [`reference/cli/init.md`](reference/cli/init.md)
|
|
431
|
+
- [`reference/cli/models.md`](reference/cli/models.md)
|
|
432
|
+
- [`reference/cli/skill.md`](reference/cli/skill.md)
|
|
433
|
+
- [`reference/cli/status.md`](reference/cli/status.md)
|
|
434
|
+
- [`reference/cli/surface.md`](reference/cli/surface.md)
|
|
435
|
+
|
|
436
|
+
Workflow and eval references:
|
|
437
|
+
|
|
343
438
|
- [`reference/workflow-yaml.md`](reference/workflow-yaml.md)
|
|
344
439
|
- [`reference/step-types.md`](reference/step-types.md)
|
|
440
|
+
- [`reference/step-exec.md`](reference/step-exec.md)
|
|
345
441
|
- [`reference/dataset-format.md`](reference/dataset-format.md)
|
|
346
442
|
- [`reference/evaluators.md`](reference/evaluators.md)
|
|
347
443
|
- [`reference/debugging.md`](reference/debugging.md)
|
|
@@ -519,12 +519,12 @@ Encrypt and set a secret value in secrets.enc.yaml.
|
|
|
519
519
|
|
|
520
520
|
### Options
|
|
521
521
|
|
|
522
|
-
| Flag | Required | Default | Description
|
|
523
|
-
| ---------------------- | -------- | ------- |
|
|
524
|
-
| `--dir <dir>` | no | | Directory to inspect
|
|
525
|
-
| `--stdin` | no | | Read the secret value from stdin
|
|
526
|
-
| `--value-file <path>` | no | | Read the secret value from a file
|
|
527
|
-
| `--description <text>` | no | | Secret description
|
|
522
|
+
| Flag | Required | Default | Description |
|
|
523
|
+
| ---------------------- | -------- | ------- | ------------------------------------------------------------------- |
|
|
524
|
+
| `--dir <dir>` | no | | Directory to inspect |
|
|
525
|
+
| `--stdin` | no | | Read the secret value from stdin (required in CI / agent terminals) |
|
|
526
|
+
| `--value-file <path>` | no | | Read the secret value from a file |
|
|
527
|
+
| `--description <text>` | no | | Secret description |
|
|
528
528
|
|
|
529
529
|
### `eigenpal agents secrets|secret unset [options] <name>`
|
|
530
530
|
|
|
@@ -607,13 +607,13 @@ Upload dataset examples from a local dataset directory or zip archive.
|
|
|
607
607
|
|
|
608
608
|
### Options
|
|
609
609
|
|
|
610
|
-
| Flag | Required | Default | Description
|
|
611
|
-
| -------------------------- | -------- | ---------- |
|
|
612
|
-
| `--base-url <url>` | no | | Server base URL
|
|
613
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
614
|
-
| `--file <path>` | yes | | Dataset directory or .zip archive
|
|
615
|
-
| `--mode <append\|replace>` | no | `"append"` | Upload mode
|
|
616
|
-
| `--yes` | no | |
|
|
610
|
+
| Flag | Required | Default | Description |
|
|
611
|
+
| -------------------------- | -------- | ---------- | ---------------------------------------------------------------------------------- |
|
|
612
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
613
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
614
|
+
| `--file <path>` | yes | | Dataset directory or .zip archive |
|
|
615
|
+
| `--mode <append\|replace>` | no | `"append"` | Upload mode |
|
|
616
|
+
| `--yes` | no | | Skip typed-slug confirmation for --mode replace (required in CI / agent terminals) |
|
|
617
617
|
|
|
618
618
|
### `eigenpal agents dataset pull [options] <agent-id-or-slug>`
|
|
619
619
|
|
|
@@ -763,11 +763,11 @@ Cancel every active execution in an experiment.
|
|
|
763
763
|
|
|
764
764
|
### Options
|
|
765
765
|
|
|
766
|
-
| Flag | Required | Default | Description
|
|
767
|
-
| ------------------ | -------- | ------- |
|
|
768
|
-
| `--base-url <url>` | no | | Server base URL
|
|
769
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
770
|
-
| `--yes` | no | |
|
|
766
|
+
| Flag | Required | Default | Description |
|
|
767
|
+
| ------------------ | -------- | ------- | ------------------------------------------------------------------ |
|
|
768
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
769
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
770
|
+
| `--yes` | no | | Skip confirmation (required in CI / agent terminals without a TTY) |
|
|
771
771
|
|
|
772
772
|
### `eigenpal agents session list|ls [options] <agent-id-or-slug>`
|
|
773
773
|
|
|
@@ -854,11 +854,11 @@ Stop a builder session.
|
|
|
854
854
|
|
|
855
855
|
### Options
|
|
856
856
|
|
|
857
|
-
| Flag | Required | Default | Description
|
|
858
|
-
| ------------------ | -------- | ------- |
|
|
859
|
-
| `--base-url <url>` | no | | Server base URL
|
|
860
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
861
|
-
| `--yes` | no | |
|
|
857
|
+
| Flag | Required | Default | Description |
|
|
858
|
+
| ------------------ | -------- | ------- | ------------------------------------------------------------------ |
|
|
859
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
860
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
861
|
+
| `--yes` | no | | Skip confirmation (required in CI / agent terminals without a TTY) |
|
|
862
862
|
|
|
863
863
|
### `eigenpal agents env pull [options] [target]`
|
|
864
864
|
|
|
@@ -270,11 +270,11 @@ Cancel a run.
|
|
|
270
270
|
|
|
271
271
|
### Options
|
|
272
272
|
|
|
273
|
-
| Flag | Required | Default | Description
|
|
274
|
-
| ------------------ | -------- | ------- |
|
|
275
|
-
| `--base-url <url>` | no | | Server base URL
|
|
276
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
277
|
-
| `--yes` | no | |
|
|
273
|
+
| Flag | Required | Default | Description |
|
|
274
|
+
| ------------------ | -------- | ------- | ------------------------------------------------------------------ |
|
|
275
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
276
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
277
|
+
| `--yes` | no | | Skip confirmation (required in CI / agent terminals without a TTY) |
|
|
278
278
|
|
|
279
279
|
### `eigenpal runs artifacts|artifact list|ls [options] <run-id>`
|
|
280
280
|
|
|
@@ -393,11 +393,11 @@ Delete review metadata, corrected JSON, and corrected files for a run.
|
|
|
393
393
|
|
|
394
394
|
### Options
|
|
395
395
|
|
|
396
|
-
| Flag | Required | Default | Description
|
|
397
|
-
| ------------------ | -------- | ------- |
|
|
398
|
-
| `--base-url <url>` | no | | Server base URL
|
|
399
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
400
|
-
| `--yes` | no | |
|
|
396
|
+
| Flag | Required | Default | Description |
|
|
397
|
+
| ------------------ | -------- | ------- | ----------------------------------------------------------------------------- |
|
|
398
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
399
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
400
|
+
| `--yes` | no | | Skip typed-slug confirmation (required in CI / agent terminals without a TTY) |
|
|
401
401
|
|
|
402
402
|
### `eigenpal runs expected list|ls [options] <run-id>`
|
|
403
403
|
|
|
@@ -503,8 +503,8 @@ Delete an expected artifact.
|
|
|
503
503
|
|
|
504
504
|
### Options
|
|
505
505
|
|
|
506
|
-
| Flag | Required | Default | Description
|
|
507
|
-
| ------------------ | -------- | ------- |
|
|
508
|
-
| `--base-url <url>` | no | | Server base URL
|
|
509
|
-
| `--json` | no | | Output the raw server response as JSON
|
|
510
|
-
| `--yes` | no | |
|
|
506
|
+
| Flag | Required | Default | Description |
|
|
507
|
+
| ------------------ | -------- | ------- | ----------------------------------------------------------------------------- |
|
|
508
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
509
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
510
|
+
| `--yes` | no | | Skip typed-slug confirmation (required in CI / agent terminals without a TTY) |
|
|
@@ -16,9 +16,10 @@ eigenpal run workflows.<workflow-id> --example <example-name>
|
|
|
16
16
|
|
|
17
17
|
`<workflow-id>` is either a `wf_…` id or a slug (the YAML's `name:`
|
|
18
18
|
field). The workflow must be pushed (`eigenpal workflow push`) before
|
|
19
|
-
`eigenpal run` works — only saved workflows execute.
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
`eigenpal run` works — only saved workflows execute. Without `--wait`,
|
|
20
|
+
the command enqueues the run and exits after printing the run id — it
|
|
21
|
+
does not stream step progress. Add `--wait` to poll until a terminal
|
|
22
|
+
status, or use `runs watch <exec-id>` for a live step-by-step view.
|
|
22
23
|
|
|
23
24
|
If the workflow is server-stable and the failure is on a real
|
|
24
25
|
historical execution, skip the rerun and pull the recorded execution
|
|
@@ -56,19 +56,75 @@ finance) who never see the YAML or the judge prompt. Write it for them:
|
|
|
56
56
|
|
|
57
57
|
### `exact-diff` — JSON deep-diff against `expected.json`
|
|
58
58
|
|
|
59
|
+
Author comparison with a per-field `rules` map. Each key is a path into the
|
|
60
|
+
workflow output (the `.data` object). Use `$` to target the full output.
|
|
61
|
+
An ancestor rule covers its whole subtree; more specific descendants override
|
|
62
|
+
inherited settings. `{}` selects a path with inherited platform defaults.
|
|
63
|
+
|
|
59
64
|
```yaml
|
|
60
65
|
- name: invoice-fields
|
|
61
66
|
type: exact-diff
|
|
62
67
|
config:
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
rules:
|
|
69
|
+
invoiceNumber: {}
|
|
70
|
+
total:
|
|
71
|
+
numericTolerance: 0.01
|
|
72
|
+
lineItems:
|
|
73
|
+
order: unordered
|
|
74
|
+
items: exactly
|
|
75
|
+
matchBy: sku
|
|
76
|
+
lineItems[]:
|
|
77
|
+
allowExtraFields: false
|
|
78
|
+
lineItems[].unitPrice:
|
|
79
|
+
numericTolerance: 0.01
|
|
65
80
|
```
|
|
66
81
|
|
|
67
|
-
- `
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
is
|
|
82
|
+
- `rules` — map of path → comparison settings. Only listed paths (and their
|
|
83
|
+
descendants, unless a descendant adds its own rule) are scored. Omit a path
|
|
84
|
+
to ignore it, or set `$: {}` to compare the entire output with defaults.
|
|
85
|
+
- `numericTolerance` — maximum absolute difference between expected and actual
|
|
86
|
+
numeric values at this path. Use `0` for exact integers; `0.01` is typical
|
|
87
|
+
for currency. When omitted, numeric comparison keeps the historical relative
|
|
88
|
+
epsilon.
|
|
89
|
+
- `order: unordered` — on an array path, match items by value instead of
|
|
90
|
+
position. Matches always use distinct item slots; whether missing expected
|
|
91
|
+
items fail is controlled independently by `items`.
|
|
92
|
+
- `matchBy` — optional identity for unordered arrays of objects. Requires
|
|
93
|
+
`order: unordered` on the same rule. Set on the array path (`lineItems`),
|
|
94
|
+
not the item path (`lineItems[]`). A relative field (`sku`) or unique
|
|
95
|
+
fields (`[country, sku]`) inside each item. Expected and actual objects are
|
|
96
|
+
paired by exact identity first, then the paired objects are compared with
|
|
97
|
+
inherited nested rules, so a matching SKU with the wrong amount reports
|
|
98
|
+
`lineItems[i].amount` instead of "no matching item". Applies only at the
|
|
99
|
+
array path where it is set and is not inherited. Identity type and value
|
|
100
|
+
must both match: numeric `10` differs from string `'10'`; no coercion or
|
|
101
|
+
numeric tolerance. With `items: at-least`, extra actual items may omit or
|
|
102
|
+
duplicate identities; with `at-most`, missing expected identities are
|
|
103
|
+
allowed but every actual item being checked needs a unique valid identity;
|
|
104
|
+
`exactly` validates both sides. Omit `matchBy` to keep structural matching,
|
|
105
|
+
which still allows legitimate duplicate objects.
|
|
106
|
+
- `items: at-least` — require every expected item while allowing additional
|
|
107
|
+
actual items (the default). Use `at-most` to permit a subset of expected
|
|
108
|
+
items but reject unexpected actual items, or `exactly` to permit neither.
|
|
109
|
+
- `order` is independent. Ordered arrays use positional prefix matching:
|
|
110
|
+
`at-least` requires expected to match actual from index 0 (trailing actual
|
|
111
|
+
extras only); `at-most` requires actual to match expected from index 0
|
|
112
|
+
(trailing expected extras only); `exactly` is equal-length positional.
|
|
113
|
+
`unordered` ignores positions. Set `order`, `items`, and `matchBy` on
|
|
114
|
+
`lineItems`, not `lineItems[]`.
|
|
115
|
+
- `allowExtraFields: false` — on an object path (often `someArray[]`), reject
|
|
116
|
+
object keys present in actual but absent from expected.
|
|
117
|
+
|
|
118
|
+
Path syntax: `lineItems` targets the array; `lineItems[]` targets each element;
|
|
119
|
+
`lineItems[].unitPrice` targets a field inside every element. Nested unordered
|
|
120
|
+
lists use paths such as `groups[].members` with `order: unordered` on that path.
|
|
121
|
+
|
|
122
|
+
Extract steps may attach `_grounding` metadata under output fields. Exact-diff
|
|
123
|
+
strips that metadata before comparison, so you do not need a rule to exclude it.
|
|
124
|
+
|
|
125
|
+
Configs authored before per-field rules used other top-level `exact-diff`
|
|
126
|
+
options. Those configs keep working unchanged. Do not mix legacy options with
|
|
127
|
+
`rules` in the same evaluator; validation rejects mixed configs.
|
|
72
128
|
|
|
73
129
|
`exact-diff` branches on the example's expected shape: success-expected
|
|
74
130
|
examples (`expected.json`) are diffed against the workflow's actual output, and
|
|
@@ -120,15 +176,16 @@ one of the keys in `labels`; the harness then looks up the score.
|
|
|
120
176
|
config:
|
|
121
177
|
passThreshold: 1.0
|
|
122
178
|
function: |
|
|
123
|
-
type
|
|
179
|
+
type WorkflowData = {
|
|
124
180
|
totalAmount: number;
|
|
125
181
|
};
|
|
182
|
+
type WorkflowOutput = { data: WorkflowData };
|
|
126
183
|
type Expected = WorkflowOutput;
|
|
127
184
|
type Actual = WorkflowOutput;
|
|
128
185
|
|
|
129
186
|
function scoreScript(expected: WorkflowOutput, actual: WorkflowOutput): number {
|
|
130
|
-
const a = actual.totalAmount ?? 0;
|
|
131
|
-
const e = expected.totalAmount ?? 0;
|
|
187
|
+
const a = actual.data.totalAmount ?? 0;
|
|
188
|
+
const e = expected.data.totalAmount ?? 0;
|
|
132
189
|
return Math.abs(a - e) <= 0.01 ? 1 : 0;
|
|
133
190
|
}
|
|
134
191
|
```
|
|
@@ -142,6 +199,9 @@ enforced at parse time. The dashboard seeds new evaluators with a
|
|
|
142
199
|
declaration, plus `Expected` / `Actual` aliases for compatibility. Plain
|
|
143
200
|
`unknown` works too if you do not want a typed signature.
|
|
144
201
|
|
|
202
|
+
Both arguments are envelopes. Read workflow fields from `expected.data` and
|
|
203
|
+
`actual.data`; the actual envelope may also include `files`.
|
|
204
|
+
|
|
145
205
|
The signature shape is **locked**:
|
|
146
206
|
|
|
147
207
|
- Function name MUST be `scoreScript`.
|
|
@@ -263,10 +323,22 @@ _Generated from `EvalConfigYamlSchema` in `@eigenpal/types/src/eval/evaluator-co
|
|
|
263
323
|
|
|
264
324
|
| Field | Type | Required | Default | Description |
|
|
265
325
|
| --- | --- | --- | --- | --- |
|
|
266
|
-
| `
|
|
267
|
-
| `
|
|
326
|
+
| `rules` | record<string, object> | no | | Per-path comparison rules. Keys select compared paths (`$` = full output). More-specific keys inherit then override parent rules. `{}` selects a path using inherited platform defaults. Do not mix with legacy `paths`, `unorderedPaths`, `numericTolerance`, or `allowExtraFields`. |
|
|
327
|
+
| `numericTolerance` | number | no | | Legacy global numeric tolerance (absolute). When omitted, comparison uses historical relative epsilon. Prefer `rules.<path>.numericTolerance`. Accepted only when `rules` is omitted. |
|
|
328
|
+
| `allowExtraFields` | boolean | no | | Legacy global extra-field/extra-item flag. Prefer `rules.<path>.allowExtraFields` and `rules.<path>.items`. `true` normalizes to object extras allowed and array `items: at-least`; `false` normalizes to object extras rejected and array `items: exactly`. Accepted only when `rules` is omitted. |
|
|
268
329
|
| `passThreshold` | number | no | | Legacy per-evaluator pass threshold. Pass/fail now uses the single workflow-level pass threshold; this is read only to preserve the run gate of configs authored before the single-threshold model. |
|
|
269
|
-
| `paths` | array<string> | no | |
|
|
330
|
+
| `paths` | array<string> | no | | Legacy scoped paths. Prefer selecting those paths as `rules` keys. Syntax: `header.id`, `lineItems[].total`, `lineItems[0].sku`. |
|
|
331
|
+
| `unorderedPaths` | array<string> | no | | Legacy unordered array paths. Prefer `rules.<path>.order: unordered`. Name the array field itself (`subjects`, not `subjects[]`). |
|
|
332
|
+
|
|
333
|
+
#### Per-path `rules` fields
|
|
334
|
+
|
|
335
|
+
| Field | Type | Required | Default | Description |
|
|
336
|
+
| --- | --- | --- | --- | --- |
|
|
337
|
+
| `order` | `"ordered"` \| `"unordered"` | no | | Array matching mode at this path. Independent of `items`. Set on the array path (`lineItems`), not the item path (`lineItems[]`). `unordered` matches distinct items in any order. Arrays stay ordered when omitted. Unordered matching is limited to 1000 items, 1000000 candidate pairs, and 2000000 recursive operations per comparison. |
|
|
338
|
+
| `items` | `"at-least"` \| `"at-most"` \| `"exactly"` | no | | How expected and actual array items relate. Set on the array path (`lineItems`), not the item path (`lineItems[]`). Independent of `order`. Ordered arrays use positional prefix matching: `at-least` (default) requires expected to match actual from index 0 and allows trailing actual extras; `at-most` requires actual to match expected from index 0 and allows trailing expected extras; `exactly` is equal-cardinality positional comparison. Unordered arrays match distinct items in any order: `at-least` requires every expected item and allows extra actual items (including extras with missing or duplicate identities); `at-most` requires every actual item and allows missing expected items (every actual item being checked needs a valid unique identity); `exactly` is a bijection (both sides need valid unique identities). |
|
|
339
|
+
| `matchBy` | string \| array<string> | no | | Identity fields for unordered arrays of objects. Requires `order: unordered` on the same rule. Set on the array path (`lineItems`), not the item path (`lineItems[]`). A relative path (`sku`) or unique paths (`[country, sku]`) inside each item. Pairs expected and actual objects by exact identity, then diffs the paired objects with inherited nested rules. Identity type and value must both match: numeric `10` differs from string `'10'`; no coercion or numeric tolerance. Omitted = structural matching. Applies only at the array path where it is set and is not inherited by descendants. Nested object fields are allowed; array indexes, commas, and wildcards are not. Empty or comma-only values are rejected; composite paths must be unique. |
|
|
340
|
+
| `allowExtraFields` | boolean | no | | When false, extra actual keys at this object fail the diff. When omitted, extra keys are allowed. Applies only to objects. |
|
|
341
|
+
| `numericTolerance` | number | no | | Maximum absolute difference for numeric leaves at or under this path. Omitted = inherit, then historical relative epsilon. Explicit `0` is exact. |
|
|
270
342
|
|
|
271
343
|
|
|
272
344
|
### `llm-judge` — LLM-as-judge scoring
|
|
@@ -285,7 +357,7 @@ _Generated from `EvalConfigYamlSchema` in `@eigenpal/types/src/eval/evaluator-co
|
|
|
285
357
|
|
|
286
358
|
| Field | Type | Required | Default | Description |
|
|
287
359
|
| --- | --- | --- | --- | --- |
|
|
288
|
-
| `function` | string | yes | | Full TypeScript source for optional `type` aliases plus `function scoreScript(expected, actual): number { ... }`. Receives `expected` (the example's expected
|
|
360
|
+
| `function` | string | yes | | Full TypeScript source for optional `type` aliases plus `function scoreScript(expected, actual): number { ... }`. Receives `expected` (the example's expected-output envelope (`{ data: ... }`)) and `actual` (the workflow result envelope (`{ data: ..., files?: ... }`)), returns a number in [0, 1] (the `: number` annotation is required). The `: number` return-type annotation is required and enforced at parse time. Throws are caught and scored as 0. |
|
|
289
361
|
| `timeoutMs` | integer | no | `5000` | Maximum wall-clock time the script can run before it is killed and the run is marked failed. |
|
|
290
362
|
| `memoryLimitMb` | integer | no | `10` | Maximum memory the sandbox may allocate. Increase if the script processes large arrays or strings. |
|
|
291
363
|
| `passThreshold` | number | no | | Legacy per-evaluator pass threshold. Pass/fail now uses the single workflow-level pass threshold; this is read only to preserve the run gate of configs authored before the single-threshold model. |
|
|
@@ -431,7 +431,7 @@ Extract text from documents (PDF, DOCX, images) using native extraction, OCR, or
|
|
|
431
431
|
| `imageQuality` | integer | no | `85` | JPEG quality for rendered PDF page images sent to VLM parsing. Higher values reduce compression artifacts at larger payload sizes. |
|
|
432
432
|
| `prompt` | string | no | | Custom extraction prompt |
|
|
433
433
|
| `languages` | array<string> | no | | OCR language hints |
|
|
434
|
-
| `outputFormat` | `"plain"` \| `"markdown"` \| `"djot"` \| `"html"` | no | `"markdown"` | Format for extracted text. `markdown` (default) keeps structure
|
|
434
|
+
| `outputFormat` | `"plain"` \| `"markdown"` \| `"djot"` \| `"html"` \| `"layout"` | no | `"markdown"` | Format for extracted text. `markdown` (default) keeps structure; `plain` is unstyled text; `djot`/`html` preserve more markup. `layout` is native-PDF spatial text with column gaps preserved as spaces. It requires `parseMode: native` or `parseMode: native-or-ocr` and a PDF — omitted parseMode and `nativeText: true` are not enough. Native mode is layout-only and fail-closed. `native-or-ocr` keeps layout text on accepted native pages and uses OCR markdown on suspect or empty pages, so the document can mix fixed-width layout and markdown. Extractor failure never falls back to another parser. Office, plaintext, and images fail. OCR/vision cannot request `layout`. |
|
|
435
435
|
| `nativeText` | boolean | no | `false` | Extract native/embedded text from PDFs without OCR/VLM. Faster and uses no credits. Falls back to OCR/VLM if the PDF has no embedded text. |
|
|
436
436
|
| `describeFigures` | boolean | no | | Opt-in (default off). After text extraction, detect which pages contain figures with an in-worker layout model, then caption those pages with a vision model and append `<figure>description</figure>` to their text — so image-only pages (property photos, signatures, charts) become findable by text-based steps like ai.split. Note: the layout scan runs over all pages, and the caption step and its vision calls are billed. Skipped for plaintext. |
|
|
437
437
|
| `figureInstructions` | string | no | | Custom instruction for the figure-description pass, e.g. "Describe each figure; label a handwritten signature as `<figure>signature</figure>` and a stamp as `<figure>stamp</figure>`; for property photos note the room or exterior shown." Applied only when describeFigures runs. |
|
|
@@ -740,9 +740,9 @@ Embed OCR text layer into scanned PDFs/images to make them searchable
|
|
|
740
740
|
| `wordCount` | number | yes | | Number of words embedded |
|
|
741
741
|
| `text` | string | yes | | Extracted text from the document |
|
|
742
742
|
|
|
743
|
-
#### `transform.xlsx-to-json` —
|
|
743
|
+
#### `transform.xlsx-to-json` — Spreadsheet to JSON
|
|
744
744
|
|
|
745
|
-
Convert XLSX spreadsheet to JSON array of row objects
|
|
745
|
+
Convert an XLS or XLSX spreadsheet to a JSON array of row objects. Supports headerless files, named or positional columns, displayed text, and a single rectangular range.
|
|
746
746
|
|
|
747
747
|
**Durable retry:** Transforms, including those that write files, are not durably retried.
|
|
748
748
|
|
|
@@ -751,16 +751,26 @@ Convert XLSX spreadsheet to JSON array of row objects for use in scripts or down
|
|
|
751
751
|
| Field | Type | Required | Default | Description |
|
|
752
752
|
| --- | --- | --- | --- | --- |
|
|
753
753
|
| `input` | string | yes | | File input - template expression e.g. {{input.document}} resolving to a scoped $file artifact at runtime |
|
|
754
|
-
| `sheet` | integer \| string | no | | Sheet to read: 0-based index or sheet name. Omit for first sheet. |
|
|
755
|
-
| `outputCsv` | boolean | no | `false` | If true, also write CSV to storage and include fileId
|
|
754
|
+
| `sheet` | integer \| string | no | | Sheet to read: 0-based index or exact sheet name. Omit for the first sheet. |
|
|
755
|
+
| `outputCsv` | boolean | no | `false` | If true, also write CSV to storage and include fileId. Zero-config uses the historical full-sheet SheetJS CSV. When columns, range, headerRow, valueMode, blankCells, or blankRows are set, CSV matches that projection. |
|
|
756
|
+
| `includeMetadata` | boolean | no | `false` | If true, include sheet metadata and diagnostics in the step output. Omit to keep output as rows (and fileId when outputCsv is true). Warnings are still logged when this is false. |
|
|
756
757
|
| `outputFilename` | string | no | | Output CSV filename when outputCsv is true - supports LiquidJS e.g. {{filename}}.csv |
|
|
758
|
+
| `headerRow` | `false` \| integer | no | | Header row: a positive 1-based Excel row, or false to keep the first effective row as data. Omit to use the first effective row as the header. When range is set and this is omitted, the first range row is the header. |
|
|
759
|
+
| `columns` | array<object> | no | | Ordered output columns. Each item needs a key and exactly one source: index (0-based absolute column) or header (exact displayed header text). Named header sources require a header row. Omit to keep every column in the effective range. |
|
|
760
|
+
| `valueMode` | `"raw"` \| `"displayed"` | no | `"raw"` | raw (default) returns typed cached cell values. displayed returns formatted cell text (dates, leading zeros, punctuation, diacritics, embedded newlines). Formulas are never calculated. |
|
|
761
|
+
| `range` | string | no | | Optional rectangular A1 range without a sheet qualifier, e.g. A1:D20. Disjoint ranges are rejected. |
|
|
762
|
+
| `blankCells` | `"empty-string"` \| `"null"` \| `"omit"` | no | `"empty-string"` | How truly empty cells appear in each row object. Default empty-string. 0, false, and a formula that cached an empty string are not empty cells. |
|
|
763
|
+
| `blankRows` | `"skip"` \| `"keep"` | no | `"skip"` | skip (default) drops rows whose projected columns are all truly empty. keep retains them. Detection uses projected columns only. |
|
|
764
|
+
| `limits` | object | no | | Optional workload caps that can only lower the server defaults. Omitted fields use the server defaults. |
|
|
757
765
|
|
|
758
766
|
**Output:** `object`
|
|
759
767
|
|
|
760
768
|
| Field | Type | Required | Default | Description |
|
|
761
769
|
| --- | --- | --- | --- | --- |
|
|
762
|
-
| `rows` | array<record<string, unknown>> | yes | | Array of row objects (first row = headers as keys) |
|
|
770
|
+
| `rows` | array<record<string, unknown>> | yes | | Array of row objects (first row = headers as keys unless headerRow is false) |
|
|
763
771
|
| `fileId` | string | no | | File ID of stored CSV when outputCsv is true |
|
|
772
|
+
| `sheet` | object | no | | Selected sheet metadata after projection. Present only when includeMetadata is true. |
|
|
773
|
+
| `diagnostics` | array<object> | no | | Non-fatal warnings collected while reading the sheet. Present only when includeMetadata is true. Warnings are still logged when metadata is omitted. |
|
|
764
774
|
|
|
765
775
|
#### `transform.json-to-xlsx` — JSON to XLSX
|
|
766
776
|
|
|
@@ -899,7 +909,7 @@ Execute another workflow and return its output
|
|
|
899
909
|
|
|
900
910
|
**Output:** `record<string, unknown>`
|
|
901
911
|
|
|
902
|
-
> When wait is true, the invoked workflow's declared output fields are flattened to the top level alongside a `files` array — reference them as {{ steps.<invoke>.output.<field> }} (there is no `.data` or `.result` wrapper). When wait is false, execution metadata.
|
|
912
|
+
> When wait is true, the invoked workflow's declared output fields are flattened to the top level alongside a `files` array — reference them as {{ steps.<invoke>.output.<field> }} (there is no `.data` or `.result` wrapper). When wait is false, execution metadata. CLI authors can run `eigenpal workflow schema <workflow-id>` to inspect resolved fields; Studio builder agents can call `get_workflow_output_schema`.
|
|
903
913
|
|
|
904
914
|
#### `action.website-reader` — Website Reader
|
|
905
915
|
|