@eigenpal/cli 0.7.2 → 0.9.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 +101 -23
- package/README.md +8 -8
- package/dist/cli.js +9300 -9059
- package/dist/skill/SKILL.md +87 -415
- package/dist/skill/reference/cli/agents.md +26 -26
- package/dist/skill/reference/cli/rerun.md +1 -1
- package/dist/skill/reference/cli/run.md +1 -1
- package/dist/skill/reference/cli/runs.md +23 -2
- package/dist/skill/reference/cli/surface.md +1 -2
- package/dist/skill/reference/cli/workflow.md +10 -10
- package/dist/skill/reference/dataset-format.md +74 -241
- package/dist/skill/reference/debugging.md +5 -5
- package/dist/skill/reference/evaluators.md +10 -10
- package/dist/skill/reference/step-exec.md +2 -2
- package/dist/skill/reference/step-types.md +7 -7
- package/dist/skill/reference/workflow-yaml.md +4 -4
- package/dist/templates/blank/README.md +4 -3
- package/dist/templates/blank/evaluators.yaml +1 -1
- package/package.json +1 -1
- package/dist/skill/reference/cli/completion.md +0 -9
- package/dist/skill/reference/cli/git.md +0 -9
- /package/dist/templates/blank/dataset/examples/sample/{expected/output.json → expected.json} +0 -0
- /package/dist/templates/blank/dataset/examples/sample/{input/arguments.json → input.json} +0 -0
- /package/dist/templates/pdf-extraction/dataset/examples/sample-invoice/{expected/output.json → expected.json} +0 -0
- /package/dist/templates/pdf-extraction/dataset/examples/sample-invoice/{input/arguments.json → input.json} +0 -0
- /package/dist/templates/text-classification/dataset/examples/negative/{expected/output.json → expected.json} +0 -0
- /package/dist/templates/text-classification/dataset/examples/negative/{input/arguments.json → input.json} +0 -0
- /package/dist/templates/text-classification/dataset/examples/positive/{expected/output.json → expected.json} +0 -0
- /package/dist/templates/text-classification/dataset/examples/positive/{input/arguments.json → input.json} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# eigenpal agents
|
|
2
2
|
|
|
3
|
-
Manage Eigenpal agents: Git source, datasets,
|
|
3
|
+
Manage Eigenpal agents: Git source, datasets, experiments, sessions, and releases.
|
|
4
4
|
|
|
5
5
|
## Contents
|
|
6
6
|
|
|
@@ -157,20 +157,20 @@ agents
|
|
|
157
157
|
| Command | Description |
|
|
158
158
|
| --------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
159
159
|
| `eigenpal agents dataset list\|ls [options] <agent-id-or-slug>` | List dataset examples for an agent. |
|
|
160
|
-
| `eigenpal agents dataset push [options] <agent-id-or-slug>` | Upload dataset examples from a local dataset directory.
|
|
161
|
-
| `eigenpal agents dataset pull [options] <agent-id-or-slug>` | Download an agent dataset
|
|
160
|
+
| `eigenpal agents dataset push [options] <agent-id-or-slug>` | Upload dataset examples from a local dataset directory or zip archive. |
|
|
161
|
+
| `eigenpal agents dataset pull [options] <agent-id-or-slug>` | Download an agent dataset as a .zip archive. |
|
|
162
162
|
| `eigenpal agents dataset validate [options] [path]` | Validate a local dataset directory against the agent input/output schemas. |
|
|
163
163
|
|
|
164
164
|
### Experiment
|
|
165
165
|
|
|
166
|
-
| Command | Description
|
|
167
|
-
| ----------------------------------------------------------------------------------- |
|
|
168
|
-
| `eigenpal agents experiment\|exp run [options] <agent-id-or-slug>` | Start an experiment over dataset examples.
|
|
169
|
-
| `eigenpal agents experiment\|exp status [options] <agent-id-or-slug> <batch-id>` | Get experiment status.
|
|
170
|
-
| `eigenpal agents experiment\|exp results [options] <agent-id-or-slug> [batch-id]` | Print experiment results as JSON or CSV.
|
|
171
|
-
| `eigenpal agents experiment\|exp list\|ls [options] <agent-id-or-slug>` | List experiments.
|
|
172
|
-
| `eigenpal agents experiment\|exp compare\|diff [options] <batch-id-a> <batch-id-b>` |
|
|
173
|
-
| `eigenpal agents experiment\|exp cancel [options] <agent-id-or-slug> <batch-id>` | Cancel every active execution in an experiment.
|
|
166
|
+
| Command | Description |
|
|
167
|
+
| ----------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
168
|
+
| `eigenpal agents experiment\|exp run [options] <agent-id-or-slug>` | Start an experiment over dataset examples. |
|
|
169
|
+
| `eigenpal agents experiment\|exp status [options] <agent-id-or-slug> <batch-id>` | Get experiment status. |
|
|
170
|
+
| `eigenpal agents experiment\|exp results [options] <agent-id-or-slug> [batch-id]` | Print experiment results as JSON or CSV. |
|
|
171
|
+
| `eigenpal agents experiment\|exp list\|ls [options] <agent-id-or-slug>` | List experiments. |
|
|
172
|
+
| `eigenpal agents experiment\|exp compare\|diff [options] <batch-id-a> <batch-id-b>` | Diff eval scores between two experiment batches. |
|
|
173
|
+
| `eigenpal agents experiment\|exp cancel [options] <agent-id-or-slug> <batch-id>` | Cancel every active execution in an experiment. |
|
|
174
174
|
|
|
175
175
|
### Session
|
|
176
176
|
|
|
@@ -572,7 +572,7 @@ List dataset examples for an agent.
|
|
|
572
572
|
|
|
573
573
|
### `eigenpal agents dataset push [options] <agent-id-or-slug>`
|
|
574
574
|
|
|
575
|
-
Upload dataset examples from a local dataset directory.
|
|
575
|
+
Upload dataset examples from a local dataset directory or zip archive.
|
|
576
576
|
|
|
577
577
|
### Arguments
|
|
578
578
|
|
|
@@ -586,13 +586,13 @@ Upload dataset examples from a local dataset directory.
|
|
|
586
586
|
| -------------------------- | -------- | ---------- | ---------------------------------------------------- |
|
|
587
587
|
| `--base-url <url>` | no | | Server base URL |
|
|
588
588
|
| `--json` | no | | Output the raw server response as JSON |
|
|
589
|
-
| `--file <path>` | yes | | Dataset directory
|
|
589
|
+
| `--file <path>` | yes | | Dataset directory or .zip archive |
|
|
590
590
|
| `--mode <append\|replace>` | no | `"append"` | Upload mode |
|
|
591
591
|
| `--yes` | no | | Confirm replace mode in non-interactive environments |
|
|
592
592
|
|
|
593
593
|
### `eigenpal agents dataset pull [options] <agent-id-or-slug>`
|
|
594
594
|
|
|
595
|
-
Download an agent dataset
|
|
595
|
+
Download an agent dataset as a .zip archive.
|
|
596
596
|
|
|
597
597
|
### Arguments
|
|
598
598
|
|
|
@@ -602,10 +602,10 @@ Download an agent dataset directory.
|
|
|
602
602
|
|
|
603
603
|
### Options
|
|
604
604
|
|
|
605
|
-
| Flag | Required | Default | Description
|
|
606
|
-
| ------------------ | -------- | ----------- |
|
|
607
|
-
| `--base-url <url>` | no | | Server base URL
|
|
608
|
-
| `--out <
|
|
605
|
+
| Flag | Required | Default | Description |
|
|
606
|
+
| ------------------ | -------- | ----------- | --------------------------------------- |
|
|
607
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
608
|
+
| `--out <path>` | no | `"dataset"` | Output .zip path (default: dataset.zip) |
|
|
609
609
|
|
|
610
610
|
### `eigenpal agents dataset validate [options] [path]`
|
|
611
611
|
|
|
@@ -663,7 +663,7 @@ Get experiment status.
|
|
|
663
663
|
| `--json` | no | | Output the raw server response as JSON |
|
|
664
664
|
| `--watch` | no | | Poll until complete |
|
|
665
665
|
| `--interval <seconds>` | no | `2` | Polling interval in seconds |
|
|
666
|
-
| `--max-wait <seconds>` | no | `1800` | Maximum wait before
|
|
666
|
+
| `--max-wait <seconds>` | no | `1800` | Maximum wait before exit code 2 |
|
|
667
667
|
| `--include <parts>` | no | | Reserved for future detailed parts |
|
|
668
668
|
|
|
669
669
|
### `eigenpal agents experiment|exp results [options] <agent-id-or-slug> [batch-id]`
|
|
@@ -707,7 +707,7 @@ List experiments.
|
|
|
707
707
|
|
|
708
708
|
### `eigenpal agents experiment|exp compare|diff [options] <batch-id-a> <batch-id-b>`
|
|
709
709
|
|
|
710
|
-
|
|
710
|
+
Diff eval scores between two experiment batches.
|
|
711
711
|
|
|
712
712
|
### Arguments
|
|
713
713
|
|
|
@@ -718,12 +718,12 @@ Compare two experiment batches.
|
|
|
718
718
|
|
|
719
719
|
### Options
|
|
720
720
|
|
|
721
|
-
| Flag
|
|
722
|
-
|
|
|
723
|
-
| `--base-url <url>`
|
|
724
|
-
| `--json`
|
|
725
|
-
| `--sort <
|
|
726
|
-
| `--regression-threshold <n>`
|
|
721
|
+
| Flag | Required | Default | Description |
|
|
722
|
+
| ------------------------------------------------------ | -------- | ------------------ | ------------------------------------------------------ |
|
|
723
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
724
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
725
|
+
| `--sort <abs-delta-desc\|delta-asc\|delta-desc\|name>` | no | `"abs-delta-desc"` | Row sort order (default: biggest movers first) |
|
|
726
|
+
| `--regression-threshold <n>` | no | `0.05` | Δ below this is flagged as a regression (default 0.05) |
|
|
727
727
|
|
|
728
728
|
### `eigenpal agents experiment|exp cancel [options] <agent-id-or-slug> <batch-id>`
|
|
729
729
|
|
|
@@ -17,4 +17,4 @@ Create a new run from a previous run's stored input snapshot.
|
|
|
17
17
|
| `--version <version>` | no | `"latest"` | Version/source ref for the new run: latest, original, or an explicit ref |
|
|
18
18
|
| `--wait` | no | | Poll until the rerun reaches a terminal status |
|
|
19
19
|
| `--interval <seconds>` | no | `2` | Polling interval in seconds |
|
|
20
|
-
| `--max-wait <seconds>` | no | `1800` | Maximum wait before
|
|
20
|
+
| `--max-wait <seconds>` | no | `1800` | Maximum wait before exit code 2 |
|
|
@@ -20,4 +20,4 @@ Start a workflow or agent run, e.g. workflows.extract-invoice.
|
|
|
20
20
|
| `--dir <dir>` | no | | Local eigenpal directory for workflow examples |
|
|
21
21
|
| `--wait` | no | | Poll until the run reaches a terminal status |
|
|
22
22
|
| `--interval <seconds>` | no | `2` | Polling interval in seconds |
|
|
23
|
-
| `--max-wait <seconds>` | no | `1800` | Maximum wait before
|
|
23
|
+
| `--max-wait <seconds>` | no | `1800` | Maximum wait before exit code 2 |
|
|
@@ -15,6 +15,7 @@ Inspect, watch, and manage workflow, agent, and eval runs.
|
|
|
15
15
|
- [`eigenpal runs get [options] <run-id>`](#eigenpal-runs-get-options-run-id)
|
|
16
16
|
- [`eigenpal runs compare|diff [options] <reference-run-id> <run-id>`](#eigenpal-runs-comparediff-options-reference-run-id-run-id)
|
|
17
17
|
- [`eigenpal runs rerun [options] <run-id>`](#eigenpal-runs-rerun-options-run-id)
|
|
18
|
+
- [`eigenpal runs promote [options] <run-id>`](#eigenpal-runs-promote-options-run-id)
|
|
18
19
|
- [`eigenpal runs trace [options] <run-id>`](#eigenpal-runs-trace-options-run-id)
|
|
19
20
|
- [`eigenpal runs watch [options] <run-id>`](#eigenpal-runs-watch-options-run-id)
|
|
20
21
|
- [`eigenpal runs cancel [options] <run-id>`](#eigenpal-runs-cancel-options-run-id)
|
|
@@ -38,6 +39,7 @@ runs
|
|
|
38
39
|
├── get <run-id>
|
|
39
40
|
├── compare|diff <reference-run-id> <run-id>
|
|
40
41
|
├── rerun <run-id>
|
|
42
|
+
├── promote <run-id>
|
|
41
43
|
├── artifacts|artifact
|
|
42
44
|
│ ├── list|ls <run-id>
|
|
43
45
|
│ └── fetch <run-id>
|
|
@@ -67,6 +69,7 @@ runs
|
|
|
67
69
|
| `eigenpal runs get [options] <run-id>` | Get one run. |
|
|
68
70
|
| `eigenpal runs compare\|diff [options] <reference-run-id> <run-id>` | Compare one run against another run. PDF/DOCX text comparison uses pdftotext/python3 and reports byte fallbacks. |
|
|
69
71
|
| `eigenpal runs rerun [options] <run-id>` | Create a new run from a previous run's stored input snapshot. |
|
|
72
|
+
| `eigenpal runs promote [options] <run-id>` | Promote a run into a dataset example on the run's automation. |
|
|
70
73
|
| `eigenpal runs trace [options] <run-id>` | Print raw trace.jsonl for a run, or write it with --out. |
|
|
71
74
|
| `eigenpal runs watch [options] <run-id>` | Watch a run until it reaches a terminal status. |
|
|
72
75
|
| `eigenpal runs cancel [options] <run-id>` | Cancel a run. |
|
|
@@ -196,7 +199,25 @@ Create a new run from a previous run's stored input snapshot.
|
|
|
196
199
|
| `--source-ref <ref>` | no | | Alias for --version |
|
|
197
200
|
| `--wait` | no | | Poll until the rerun reaches a terminal status |
|
|
198
201
|
| `--interval <seconds>` | no | `2` | Polling interval in seconds |
|
|
199
|
-
| `--max-wait <seconds>` | no | `1800` | Maximum wait before
|
|
202
|
+
| `--max-wait <seconds>` | no | `1800` | Maximum wait before exit code 2 |
|
|
203
|
+
|
|
204
|
+
### `eigenpal runs promote [options] <run-id>`
|
|
205
|
+
|
|
206
|
+
Promote a run into a dataset example on the run's automation.
|
|
207
|
+
|
|
208
|
+
### Arguments
|
|
209
|
+
|
|
210
|
+
| Name | Required | Variadic | Description |
|
|
211
|
+
| -------- | -------- | -------- | ----------- |
|
|
212
|
+
| `run-id` | yes | no | |
|
|
213
|
+
|
|
214
|
+
### Options
|
|
215
|
+
|
|
216
|
+
| Flag | Required | Default | Description |
|
|
217
|
+
| ------------------ | -------- | ------- | -------------------------------------- |
|
|
218
|
+
| `--base-url <url>` | no | | Server base URL |
|
|
219
|
+
| `--json` | no | | Output the raw server response as JSON |
|
|
220
|
+
| `--name <name>` | no | | Name for the created example |
|
|
200
221
|
|
|
201
222
|
### `eigenpal runs trace [options] <run-id>`
|
|
202
223
|
|
|
@@ -232,7 +253,7 @@ Watch a run until it reaches a terminal status.
|
|
|
232
253
|
| `--base-url <url>` | no | | Server base URL |
|
|
233
254
|
| `--json` | no | | Output the raw server response as JSON |
|
|
234
255
|
| `--interval <seconds>` | no | `2` | Polling interval in seconds |
|
|
235
|
-
| `--max-wait <seconds>` | no | `1800` | Maximum wait before
|
|
256
|
+
| `--max-wait <seconds>` | no | `1800` | Maximum wait before exit code 2 |
|
|
236
257
|
|
|
237
258
|
### `eigenpal runs cancel [options] <run-id>`
|
|
238
259
|
|
|
@@ -108,6 +108,7 @@ eigenpal
|
|
|
108
108
|
│ ├── get <run-id>
|
|
109
109
|
│ ├── compare|diff <reference-run-id> <run-id>
|
|
110
110
|
│ ├── rerun <run-id>
|
|
111
|
+
│ ├── promote <run-id>
|
|
111
112
|
│ ├── artifacts|artifact
|
|
112
113
|
│ │ ├── list|ls <run-id>
|
|
113
114
|
│ │ └── fetch <run-id>
|
|
@@ -125,8 +126,6 @@ eigenpal
|
|
|
125
126
|
│ │ └── delete <run-id> <name>
|
|
126
127
|
│ ├── watch <run-id>
|
|
127
128
|
│ └── cancel <run-id>
|
|
128
|
-
├── git [gitArgs...]
|
|
129
|
-
├── completion <shell>
|
|
130
129
|
└── skill
|
|
131
130
|
├── install
|
|
132
131
|
├── uninstall [toolIds...]
|
|
@@ -96,14 +96,14 @@ workflow
|
|
|
96
96
|
|
|
97
97
|
### Core
|
|
98
98
|
|
|
99
|
-
| Command | Description
|
|
100
|
-
| ------------------------------------------------------- |
|
|
101
|
-
| `eigenpal workflow list\|ls [options]` | List workflows the caller can read.
|
|
102
|
-
| `eigenpal workflow pull [options] <workflow-id>` | Download the YAML definition of the workflow at its current version.
|
|
103
|
-
| `eigenpal workflow push [options]` | Create or update a workflow from a YAML file.
|
|
104
|
-
| `eigenpal workflow move [options] <workflow-id>` | Move a workflow to a folder path, creating folders as needed
|
|
105
|
-
| `eigenpal workflow validate [options] [path]` | Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates
|
|
106
|
-
| `eigenpal workflow clear-local [options] [examples...]` | Delete local execution artifacts under ./dataset/examples/. Keeps the latest run per example by default.
|
|
99
|
+
| Command | Description |
|
|
100
|
+
| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
101
|
+
| `eigenpal workflow list\|ls [options]` | List workflows the caller can read. |
|
|
102
|
+
| `eigenpal workflow pull [options] <workflow-id>` | Download the YAML definition of the workflow at its current version. |
|
|
103
|
+
| `eigenpal workflow push [options]` | Create or update a workflow from a YAML file. |
|
|
104
|
+
| `eigenpal workflow move [options] <workflow-id>` | Move a workflow to a folder path, creating folders as needed |
|
|
105
|
+
| `eigenpal workflow validate [options] [path]` | Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates that workflow.yaml. For per-noun targeting use `evaluators validate` or `dataset validate`. |
|
|
106
|
+
| `eigenpal workflow clear-local [options] [examples...]` | Delete local execution artifacts under ./dataset/examples/. Keeps the latest run per example by default. |
|
|
107
107
|
|
|
108
108
|
### Evaluators
|
|
109
109
|
|
|
@@ -233,7 +233,7 @@ Move a workflow to a folder path, creating folders as needed
|
|
|
233
233
|
|
|
234
234
|
### `eigenpal workflow validate [options] [path]`
|
|
235
235
|
|
|
236
|
-
Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates
|
|
236
|
+
Local-only validation. Without [path]: runs the templated three-way check (./workflow.yaml + ./evaluators.yaml + ./dataset/). With [path] pointing at a YAML file: validates that workflow.yaml. For per-noun targeting use `evaluators validate` or `dataset validate`.
|
|
237
237
|
|
|
238
238
|
### Arguments
|
|
239
239
|
|
|
@@ -601,7 +601,7 @@ Poll until terminal, then auto-pull results — replaces `status --watch` + `res
|
|
|
601
601
|
| `--max-wait <seconds>` | no | `1800` | Hard ceiling in seconds (default 1800 = 30 min) |
|
|
602
602
|
| `--pull-on-complete <path>` | no | | Destination for the results file. Default: ./results-<batchId>.<format> |
|
|
603
603
|
| `--format <csv\|json>` | no | `"json"` | Results export format (default json) |
|
|
604
|
-
| `--no-pull` | no | | Skip auto-pulling results on terminal (
|
|
604
|
+
| `--no-pull` | no | | Skip auto-pulling results on terminal (watch only) |
|
|
605
605
|
| `--base-url <url>` | no | | Server base URL |
|
|
606
606
|
|
|
607
607
|
### `eigenpal workflow versions list|ls [options] <workflow-id>`
|
|
@@ -1,309 +1,142 @@
|
|
|
1
1
|
# Dataset folder format
|
|
2
2
|
|
|
3
|
-
A dataset is a folder of named example folders. The folder structure
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
A dataset is a folder of named example folders. The folder structure itself is
|
|
4
|
+
the manifest; there is no top-level `manifest.json`, and the import endpoint
|
|
5
|
+
rejects archives that contain one.
|
|
6
6
|
|
|
7
|
-
This is the format
|
|
8
|
-
`eigenpal workflow dataset push <workflow-id> --file dataset
|
|
9
|
-
|
|
10
|
-
`eigenpal workflow dataset example {get,create,update,delete}` (and
|
|
11
|
-
`dataset list` for a table view) — the local folder is a pre-push
|
|
12
|
-
staging area, not a synced mirror.
|
|
13
|
-
|
|
14
|
-
Dataset folders are unrelated to workflow organization folders. To place
|
|
15
|
-
the workflow itself under dashboard folders, use `workflow move --folder`;
|
|
16
|
-
dataset push/pull never changes folder placement.
|
|
7
|
+
This is the archive format for automation datasets, shared by workflows and
|
|
8
|
+
agents. `eigenpal workflow dataset push <workflow-id> --file dataset/` builds
|
|
9
|
+
this archive locally and sends it to the server.
|
|
17
10
|
|
|
18
11
|
## Required layout
|
|
19
12
|
|
|
20
|
-
```
|
|
13
|
+
```text
|
|
21
14
|
dataset/
|
|
22
15
|
└── examples/
|
|
23
16
|
├── invoice-foo/
|
|
17
|
+
│ ├── input.json REQUIRED — full run input object
|
|
24
18
|
│ ├── input/
|
|
25
|
-
│ │ ├──
|
|
26
|
-
│ │ └──
|
|
27
|
-
│
|
|
28
|
-
│ │ └── Appendix.pdf
|
|
19
|
+
│ │ ├── Contract_2026.pdf referenced by input.json
|
|
20
|
+
│ │ └── Appendix.pdf
|
|
21
|
+
│ ├── expected.json OPTIONAL — expected output or { "$error": ... }
|
|
29
22
|
│ ├── expected/
|
|
30
|
-
│ │
|
|
31
|
-
│ │ └── generated_invoice/ OPTIONAL — expected file output
|
|
32
|
-
│ │ └── Invoice.docx
|
|
23
|
+
│ │ └── Invoice.docx referenced by expected.json
|
|
33
24
|
│ └── meta.json OPTIONAL — { rowOrder?, annotation?, overrides? }
|
|
34
25
|
│
|
|
35
|
-
├── invoice-bar/
|
|
36
|
-
│ └── input/
|
|
37
|
-
│ └── arguments.json { amount: 42 }
|
|
38
|
-
│
|
|
39
26
|
└── unsupported-format/
|
|
40
|
-
├── input
|
|
41
|
-
|
|
42
|
-
└── expected/
|
|
43
|
-
└── error.json OPTIONAL — failure-expected, mutually exclusive with output.json
|
|
27
|
+
├── input.json
|
|
28
|
+
└── expected.json { "$error": { "code": 422 } }
|
|
44
29
|
```
|
|
45
30
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
in `expected/<docKey>/<file>` folders (one folder per output path).
|
|
49
|
-
`error.json` is the failure-expected counterpart (see "Failure-expected
|
|
50
|
-
examples" below) and cannot coexist with `output.json` for the same
|
|
51
|
-
example.
|
|
31
|
+
`input.json` is the source of truth for the full automation input. File values
|
|
32
|
+
are explicit references:
|
|
52
33
|
|
|
53
|
-
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"language": "en",
|
|
37
|
+
"contract": [
|
|
38
|
+
{ "$file": "input/Contract_2026.pdf" },
|
|
39
|
+
{ "$file": "input/Appendix.pdf" }
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- **`input/arguments.json`** is REQUIRED for every example, even if it's
|
|
58
|
-
just `{}`. It must be a JSON object (not array, not literal).
|
|
59
|
-
- **File-arguments** live in `input/<arg-name>/<filename>`. The
|
|
60
|
-
materialized shape on `triggerInput` is **driven by the workflow YAML's
|
|
61
|
-
`inputs[].type`**, not by the file count:
|
|
44
|
+
`expected.json` mirrors the expected automation output. Expected files use the
|
|
45
|
+
same reference shape with the `expected/` prefix.
|
|
62
46
|
|
|
63
|
-
|
|
64
|
-
| ------------------------------------------ | ------------------------- | --------------------- |
|
|
65
|
-
| `type: file` | `input/<name>/<one-file>` | `{ fileId }` |
|
|
66
|
-
| `type: array`, `items: { type: file }` | `input/<name>/<file>...` | `[{ fileId }, ...]` |
|
|
47
|
+
## Rules
|
|
67
48
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- **`expected/output.json`** is OPTIONAL. When present, it must be a
|
|
78
|
-
JSON object that mirrors your workflow's `output:` shape 1:1, no
|
|
79
|
-
envelope, no wrapper. A scalar/array at the top level is rejected
|
|
80
|
-
with `code: invalid_expected_output`. Mutually exclusive with
|
|
81
|
-
`expected/error.json` (see below).
|
|
82
|
-
- **`expected/error.json`** is OPTIONAL and marks the example as
|
|
83
|
-
failure-expected (the workflow is supposed to terminate via
|
|
84
|
-
`control.fail`). Must be a JSON object with at least one of
|
|
85
|
-
`{ code, messageContains, step }`; an empty object is rejected (it
|
|
86
|
-
would match any failure). When set, the scorer matches the example's
|
|
87
|
-
terminal `executions.error` envelope against the fields you specify
|
|
88
|
-
and ignores `expected/output.json` entirely. `code` is the HTTP-style
|
|
89
|
-
status code from `control.fail`'s `statusCode`; `messageContains` is a
|
|
90
|
-
case-sensitive substring of the failure message; `step` is the name
|
|
91
|
-
of the `control.fail` step expected to fire.
|
|
49
|
+
- Example folder names must match `[a-z0-9][a-z0-9-_]*`.
|
|
50
|
+
- Every example needs `input.json`, even if it is `{}`. It must be a JSON object.
|
|
51
|
+
- Files under `input/` must be referenced from `input.json` as
|
|
52
|
+
`{ "$file": "input/<path>" }`.
|
|
53
|
+
- Files under `expected/` must be referenced from `expected.json` as
|
|
54
|
+
`{ "$file": "expected/<path>" }`.
|
|
55
|
+
- File references cannot use `..`, absolute paths, backslashes, or null bytes.
|
|
56
|
+
- `expected.json` is optional. When present, it must be a JSON object.
|
|
57
|
+
- Failure-expected examples use `expected.json` with a single `$error` key:
|
|
92
58
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
{
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"$error": {
|
|
96
62
|
"code": 422,
|
|
97
63
|
"messageContains": "unsupported document type",
|
|
98
64
|
"step": "reject-unsupported"
|
|
99
65
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
> **Note:** the importer is idempotent and accepts both bare objects and
|
|
103
|
-
> pre-wrapped `{ data: { ... } }` forms; bare is preferred.
|
|
66
|
+
}
|
|
67
|
+
```
|
|
104
68
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// invoiceNumber: '{{ steps.extract.output.invoiceNumber }}'
|
|
109
|
-
// totalAmount: '{{ steps.extract.output.totalAmount }}'
|
|
110
|
-
//
|
|
111
|
-
// → expected/output.json
|
|
112
|
-
{
|
|
113
|
-
"invoiceNumber": "INV-001",
|
|
114
|
-
"totalAmount": 1234.56
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
- **Expected file outputs** live in `expected/<docKey>/<filename>` —
|
|
118
|
-
symmetric with `input/<argName>/<file>`. Each `<docKey>` folder is
|
|
119
|
-
uploaded and becomes an `expectedDocuments[docKey]` entry server-side
|
|
120
|
-
(single file ⇒ `{fileId}`, multiple ⇒ `[{fileId}, …]`). The judge
|
|
121
|
-
compares by file presence + content, not byte-equal.
|
|
122
|
-
- **`meta.json`** is OPTIONAL. Schema:
|
|
123
|
-
```json
|
|
124
|
-
{
|
|
125
|
-
"rowOrder": 0,
|
|
126
|
-
"annotation": "free-form notes about this example",
|
|
127
|
-
"overrides": {
|
|
128
|
-
"steps": {
|
|
129
|
-
"<stepName>": { ...stepOutputObject }
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
- `rowOrder` — sort order in the dashboard
|
|
135
|
-
- `annotation` — surfaced in the UI; useful for "why this case is
|
|
136
|
-
interesting" notes
|
|
137
|
-
- `overrides.steps.<stepName>` — short-circuits the named step,
|
|
138
|
-
returns the override as the step's output. Use for steps that
|
|
139
|
-
depend on external state (third-party APIs, private connectors) so the rest
|
|
140
|
-
of the example can still run.
|
|
141
|
-
- **Path-traversal patterns** (`..`, leading `/`, backslashes, null
|
|
142
|
-
bytes) reject the whole archive.
|
|
69
|
+
The `$error` object must contain at least one of `code`, `messageContains`, or
|
|
70
|
+
`step`. It asserts that the automation should fail with a matching typed
|
|
71
|
+
`control.fail` envelope.
|
|
143
72
|
|
|
144
|
-
## How
|
|
73
|
+
## How a row materializes
|
|
145
74
|
|
|
146
75
|
For an example with:
|
|
147
76
|
|
|
148
|
-
- `
|
|
149
|
-
- `input/
|
|
150
|
-
- `input/
|
|
151
|
-
- `expected
|
|
152
|
-
- `expected/
|
|
77
|
+
- `input.json`: `{"language":"en","contract":[{"$file":"input/Contract_2026.pdf"},{"$file":"input/Appendix.pdf"}]}`
|
|
78
|
+
- `input/Contract_2026.pdf`
|
|
79
|
+
- `input/Appendix.pdf`
|
|
80
|
+
- `expected.json`: `{"invoiceNumber":"INV-001","generatedInvoice":{"$file":"expected/Invoice.docx"}}`
|
|
81
|
+
- `expected/Invoice.docx`
|
|
153
82
|
|
|
154
|
-
The
|
|
83
|
+
The stored row keeps the same input shape. When the example runs, each `$file`
|
|
84
|
+
reference is resolved into the S3 file descriptor the worker consumes.
|
|
155
85
|
|
|
156
86
|
```json
|
|
157
|
-
// eval_examples.triggerInput
|
|
158
87
|
{
|
|
159
88
|
"language": "en",
|
|
160
89
|
"contract": [
|
|
161
|
-
{ "
|
|
162
|
-
{ "
|
|
90
|
+
{ "kind": "s3", "ref": ".../input/Contract_2026.pdf", "filename": "Contract_2026.pdf" },
|
|
91
|
+
{ "kind": "s3", "ref": ".../input/Appendix.pdf", "filename": "Appendix.pdf" }
|
|
163
92
|
]
|
|
164
93
|
}
|
|
165
|
-
|
|
166
|
-
// eval_examples.expectedOutput
|
|
167
|
-
{
|
|
168
|
-
"data": { "invoiceNumber": "INV-001" },
|
|
169
|
-
"expectedDocuments": {
|
|
170
|
-
"generated_invoice": { "fileId": "file_ghi..." }
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
94
|
```
|
|
174
95
|
|
|
175
|
-
Each file is uploaded to S3
|
|
176
|
-
filename is preserved on the `files` row and shows up in the dashboard.
|
|
177
|
-
The `expectedOutput` envelope (`{ data?, expectedDocuments?, error? }`) is
|
|
178
|
-
internal storage shape — your dataset folder stays clean (raw
|
|
179
|
-
`output.json` or `error.json`, plus per-docKey folders).
|
|
180
|
-
|
|
181
|
-
## Failure-expected examples
|
|
182
|
-
|
|
183
|
-
When a workflow uses `control.fail` to reject bad inputs, you usually
|
|
184
|
-
want to test both paths: happy-path examples carry `expected/output.json`
|
|
185
|
-
and assert the workflow completed; rejection examples carry
|
|
186
|
-
`expected/error.json` and assert the workflow failed with the right
|
|
187
|
-
status code.
|
|
188
|
-
|
|
189
|
-
```
|
|
190
|
-
examples/
|
|
191
|
-
├── valid-invoice/
|
|
192
|
-
│ ├── input/...
|
|
193
|
-
│ └── expected/output.json # success-expected
|
|
194
|
-
└── unsupported-format/
|
|
195
|
-
├── input/...
|
|
196
|
-
└── expected/error.json # failure-expected
|
|
197
|
-
# { "code": 422, "step": "reject-unsupported" }
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
The two files are mutually exclusive for the same example (an example
|
|
201
|
-
is either a success-case or a failure-case, never both). The `exact-diff`
|
|
202
|
-
evaluator branches on the envelope shape and reports a clean
|
|
203
|
-
`expectedFailureButSucceeded` or `actualWasUntypedError` reason when
|
|
204
|
-
the actual run doesn't match the expectation.
|
|
96
|
+
Each file is uploaded to S3 and the original filename is preserved.
|
|
205
97
|
|
|
206
98
|
## Validate before pushing
|
|
207
99
|
|
|
208
100
|
```bash
|
|
209
|
-
eigenpal workflow validate
|
|
101
|
+
eigenpal workflow dataset validate ./dataset
|
|
210
102
|
```
|
|
211
103
|
|
|
212
|
-
|
|
104
|
+
Example output:
|
|
213
105
|
|
|
214
|
-
```
|
|
106
|
+
```text
|
|
215
107
|
✗ dataset (./dataset) — 2 issues
|
|
216
|
-
examples/Invoice-Foo
|
|
217
|
-
examples/foo/input
|
|
108
|
+
examples/Invoice-Foo Folder name must be lowercase kebab/snake-case.
|
|
109
|
+
examples/foo/input.json:contract Referenced file does not exist: input/contract.pdf.
|
|
218
110
|
```
|
|
219
111
|
|
|
220
112
|
## Push
|
|
221
113
|
|
|
222
114
|
```bash
|
|
223
|
-
# Replace
|
|
115
|
+
# Replace wipes existing examples for the automation, uploads the folder fresh.
|
|
224
116
|
eigenpal workflow dataset push <workflow-id> --file ./dataset --mode replace
|
|
225
117
|
|
|
226
|
-
# Append
|
|
118
|
+
# Append adds to whatever is already on the server.
|
|
227
119
|
eigenpal workflow dataset push <workflow-id> --file ./dataset --mode append
|
|
228
120
|
```
|
|
229
121
|
|
|
230
|
-
The endpoint streams progress as NDJSON. The terminal `done` event
|
|
231
|
-
|
|
122
|
+
The endpoint streams progress as NDJSON. The terminal `done` event includes
|
|
123
|
+
`{ created, expectedSet, … }`:
|
|
232
124
|
|
|
233
|
-
- `created` — examples successfully persisted
|
|
234
|
-
- `expectedSet` — how many of those carried an `expected
|
|
235
|
-
|
|
236
|
-
folders — the dashboard's "Expected" tab will be blank and evals
|
|
237
|
-
will only run un-graded.
|
|
125
|
+
- `created` — examples successfully persisted.
|
|
126
|
+
- `expectedSet` — how many of those carried an `expected.json`. If
|
|
127
|
+
`expectedSet < created`, the rest run un-graded.
|
|
238
128
|
|
|
239
129
|
## Editing a dataset on the server
|
|
240
130
|
|
|
241
|
-
To inspect or round-trip what
|
|
131
|
+
To inspect or round-trip what is currently on the server:
|
|
242
132
|
|
|
243
133
|
```bash
|
|
244
134
|
eigenpal workflow dataset list <workflow-id>
|
|
245
135
|
eigenpal workflow dataset pull <workflow-id> --out current.zip
|
|
246
|
-
# (or omit --out to stream the zip to stdout for piping)
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
For bulk changes — many examples at once, schema-level rework, file
|
|
250
|
-
swaps — edit the local folder and re-push with
|
|
251
|
-
`dataset push --mode replace`.
|
|
252
|
-
|
|
253
|
-
For one-row tweaks — capturing a corrected output as the new GT,
|
|
254
|
-
deleting one bad example, adding one example to a known dataset — use
|
|
255
|
-
the per-example CRUD commands instead. They avoid the round-trip of
|
|
256
|
-
re-zipping and re-uploading the whole folder.
|
|
257
|
-
|
|
258
|
-
### Inspect one example end-to-end
|
|
259
|
-
|
|
260
|
-
```bash
|
|
261
|
-
eigenpal workflow dataset example get <workflow-id> <example-id>
|
|
262
|
-
eigenpal workflow dataset example get <workflow-id> <example-id> --json | jq '.expectedOutput'
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Pretty mode prints labelled `Inputs` / `Expected` / `Metadata` sections;
|
|
266
|
-
`--json` returns the full row (`triggerInput`, `expectedOutput`,
|
|
267
|
-
`annotation`, `rowOrder`, timestamps) for piping.
|
|
268
|
-
|
|
269
|
-
### Capture a corrected output as the new ground truth
|
|
270
|
-
|
|
271
|
-
```bash
|
|
272
|
-
# 1. Look at what the workflow actually returned for the example
|
|
273
|
-
eigenpal runs get exec_… --json | jq '.output.data' > /tmp/correct.json
|
|
274
|
-
|
|
275
|
-
# 2. Patch the example's expected output in place. PATCH semantics:
|
|
276
|
-
# every flag you omit is left alone.
|
|
277
|
-
eigenpal workflow dataset example update <workflow-id> <example-id> \
|
|
278
|
-
--expected-file /tmp/correct.json
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
`--expected-file -` reads JSON from stdin if you'd rather pipe. Pass
|
|
282
|
-
empty string to clear an annotation: `--annotation ""`.
|
|
283
|
-
|
|
284
|
-
### Add one new example
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
eigenpal workflow dataset example create <workflow-id> \
|
|
288
|
-
--name missing-required-field \
|
|
289
|
-
--input-json '{"language":"en"}' \
|
|
290
|
-
--expected-file /tmp/expected.json \
|
|
291
|
-
--annotation "edge case: required field absent from input"
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
`--input-json` / `--expected-json` accept inline JSON literals; the
|
|
295
|
-
`-file` variants read from disk (or `-` for stdin). They're mutually
|
|
296
|
-
exclusive — pass one or the other, not both.
|
|
297
|
-
|
|
298
|
-
File-arg uploads still go through `dataset push`; CRUD only handles
|
|
299
|
-
scalar args + `expected/output.json`-style outputs.
|
|
300
|
-
|
|
301
|
-
### Delete one bad example
|
|
302
|
-
|
|
303
|
-
```bash
|
|
304
|
-
eigenpal workflow dataset example delete <workflow-id> <example-id> --yes
|
|
305
136
|
```
|
|
306
137
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
`
|
|
138
|
+
For bulk changes, edit the local folder and re-push with
|
|
139
|
+
`dataset push --mode replace`. For one-row tweaks, use
|
|
140
|
+
`eigenpal workflow dataset example {get,create,update,delete}`. File uploads
|
|
141
|
+
still go through `dataset push`; CRUD only handles JSON input and
|
|
142
|
+
`expected.json`-style outputs.
|