orizu 0.3.4 → 0.3.6
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/README.md +40 -3
- package/dist/help.js +611 -0
- package/dist/index.js +458 -20
- package/dist/preview-runtime.js +857 -0
- package/dist/skill-installer.js +180 -0
- package/package.json +12 -3
- package/scripts/vendor-orizu-skill.mjs +54 -0
- package/src/help.ts +676 -0
- package/src/index.ts +568 -21
- package/src/preview-runtime.ts +976 -0
- package/src/skill-installer.ts +260 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/cli.py +16 -0
- package/vendor/orizu-gepa-python/src/orizu_gepa/optimizer.py +68 -56
- package/vendor/orizu-gepa-python/src/orizu_gepa/reflection.py +31 -6
- package/vendor/skills/orizu-cli/SKILL.md +185 -0
- package/vendor/skills/orizu-cli/agents/openai.yaml +4 -0
- package/vendor/skills/orizu-cli/references/building-apps.md +1461 -0
- package/vendor/skills/orizu-cli/references/building-judges.md +218 -0
- package/vendor/skills/orizu-cli/references/cli-reference.md +324 -0
- package/vendor/skills/orizu-cli/references/optimization-reports.md +174 -0
- package/vendor/skills/orizu-cli/references/optimization-with-gepa.md +291 -0
- package/vendor/skills/orizu-cli/references/primer.md +245 -0
- package/vendor/skills/orizu-cli/references/prompt-control-plane.md +830 -0
- package/vendor/skills/orizu-cli/scripts/test-app.mjs +492 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Building Judges And Scorers
|
|
2
|
+
|
|
3
|
+
How to turn human-labeled annotations into automated evaluators. Use this reference for authoring and validating the evaluator logic; use `prompt-control-plane.md` to push versioned prompt artifacts, runner artifacts, scorer definitions, and score runs into Orizu.
|
|
4
|
+
|
|
5
|
+
## Inputs
|
|
6
|
+
|
|
7
|
+
You should arrive here with:
|
|
8
|
+
- A labeled task export: `orizu tasks export --task <taskId> --format jsonl --out labels.jsonl`
|
|
9
|
+
- One or more **specific binary failure modes** the labels measure (e.g. `correctly_identified_issue`, `escalated_when_required`).
|
|
10
|
+
- The original dataset row each label refers to (the export includes `dataset_row_id` and the row payload).
|
|
11
|
+
|
|
12
|
+
If you have Likert or "overall quality" labels, stop and re-annotate. Judges built on Likert data are unreliable. See `primer.md` Step 2.
|
|
13
|
+
|
|
14
|
+
Terminology:
|
|
15
|
+
- A **judge** is the evaluator itself, often an LLM prompt plus runner.
|
|
16
|
+
- A **scorer** is the metric contract stored in Orizu. It names the score, directionality, mode (`row` or `set`), display format, and backing implementation.
|
|
17
|
+
- Row scorers return per-row scores and feedback. Set scorers compute aggregate metrics such as Cohen's kappa, accuracy, precision, recall, F1, or a custom reducer over row-level outputs.
|
|
18
|
+
- Use `orizu scorers exec` for scorer-level evaluation. Builtin set scorers consume subject results or dependency row-scorer results and submit one aggregate score run by default. `runners exec --scorer-version` is a low-level row-runner compatibility command.
|
|
19
|
+
|
|
20
|
+
## Choosing the judge type
|
|
21
|
+
|
|
22
|
+
| Failure mode looks like | Use |
|
|
23
|
+
|-------------------------|-------------------------------------------|
|
|
24
|
+
| Rule-shaped (keyword present, tool called, format valid, length within bounds) | **Code assertion** |
|
|
25
|
+
| Subjective / nuanced (offered the right resolution, tone matches policy, escalation was warranted) | **LLM-as-a-judge** |
|
|
26
|
+
| Path-of-life (block before user sees the response — toxicity, PII leak) | **Guardrail** (small classifier or code, runs synchronously; not covered here) |
|
|
27
|
+
|
|
28
|
+
Default to code. LLM judges cost money, time, and trust budget — earn them.
|
|
29
|
+
|
|
30
|
+
## Code assertions
|
|
31
|
+
|
|
32
|
+
A code assertion is a pure function:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
def passes(input: dict, output: dict) -> bool:
|
|
36
|
+
# Returns True if the output is acceptable for this failure mode.
|
|
37
|
+
...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Patterns that work well:**
|
|
41
|
+
- Keyword/regex match on output text
|
|
42
|
+
- Structural check on JSON output
|
|
43
|
+
- Tool-call verification (did the agent call the expected tool with valid args?)
|
|
44
|
+
- Length/format bounds (response is within N tokens, ends with a question mark, etc.)
|
|
45
|
+
- Numeric tolerance for known answers
|
|
46
|
+
|
|
47
|
+
**Example — case reference number present in support response:**
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import re
|
|
51
|
+
|
|
52
|
+
CASE_REF_RE = re.compile(r"\bCASE-\d{6}\b")
|
|
53
|
+
|
|
54
|
+
def has_case_reference(input: dict, output: dict) -> bool:
|
|
55
|
+
return bool(CASE_REF_RE.search(output["text"]))
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Run it over the labeled export and confirm it agrees with the human labels for this failure mode. If it does, you're done — code assertions don't need TPR/TNR validation when they're tautologically correct (the rule *is* the failure definition).
|
|
59
|
+
|
|
60
|
+
If your code assertion disagrees with humans on >5% of cases, your rule isn't capturing the failure mode and you probably need an LLM judge instead.
|
|
61
|
+
|
|
62
|
+
## LLM-as-a-judge
|
|
63
|
+
|
|
64
|
+
For nuanced failures, build a judge that takes `(input, output)` and returns `pass | fail`.
|
|
65
|
+
|
|
66
|
+
### Step 1: Split the labels
|
|
67
|
+
|
|
68
|
+
Split your labeled export 20 / 40 / 40:
|
|
69
|
+
|
|
70
|
+
| Set | Size | Purpose |
|
|
71
|
+
|--------|------|----------------------------------------------------|
|
|
72
|
+
| Train | ~20% | Few-shot examples in the judge prompt |
|
|
73
|
+
| Dev | ~40% | Iterate on the judge prompt; measure TPR / TNR |
|
|
74
|
+
| Test | ~40% | Final validation; touch only when you think you're done |
|
|
75
|
+
|
|
76
|
+
Random split is fine for stationary data. If labels skew (e.g. 80% pass, 20% fail), stratify so each split preserves the ratio.
|
|
77
|
+
|
|
78
|
+
### Step 2: Write the judge prompt
|
|
79
|
+
|
|
80
|
+
Structure:
|
|
81
|
+
1. **Task framing.** What's being judged. State it as a binary question.
|
|
82
|
+
2. **Failure-mode definition.** Be specific. Include positive and negative criteria.
|
|
83
|
+
3. **Few-shot examples.** Draw 4–8 from the train set. Half pass, half fail. Include short rationales.
|
|
84
|
+
4. **Output format.** Force structured output: `{"pass": true|false, "reason": "..."}`. Reason is for debugging, not scoring.
|
|
85
|
+
|
|
86
|
+
**Example skeleton:**
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
JUDGE_PROMPT = """You are evaluating a customer support agent response.
|
|
90
|
+
|
|
91
|
+
The failure mode under evaluation: **escalated_when_required**.
|
|
92
|
+
- PASS: When the customer's situation requires human escalation (refund > $500, account compromise, legal threat, distressed user), the agent escalated.
|
|
93
|
+
- FAIL: The situation required escalation and the agent did not, OR the agent escalated unnecessarily.
|
|
94
|
+
|
|
95
|
+
Respond with JSON only: {"pass": <true|false>, "reason": "<one sentence>"}.
|
|
96
|
+
|
|
97
|
+
Examples:
|
|
98
|
+
<input>{{example_1_input}}</input>
|
|
99
|
+
<output>{{example_1_output}}</output>
|
|
100
|
+
<judgment>{"pass": true, "reason": "Distressed user, agent handed off."}</judgment>
|
|
101
|
+
|
|
102
|
+
<input>{{example_2_input}}</input>
|
|
103
|
+
<output>{{example_2_output}}</output>
|
|
104
|
+
<judgment>{"pass": false, "reason": "Refund $1200, agent processed without escalation."}</judgment>
|
|
105
|
+
|
|
106
|
+
... 4–8 examples total ...
|
|
107
|
+
|
|
108
|
+
Now evaluate:
|
|
109
|
+
<input>{input}</input>
|
|
110
|
+
<output>{output}</output>
|
|
111
|
+
<judgment>"""
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Step 3: Validate on dev set
|
|
115
|
+
|
|
116
|
+
Run the judge over the dev set and compare against human labels. Compute:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
TPR = (judge says fail AND human says fail) / (human says fail)
|
|
120
|
+
TNR = (judge says pass AND human says pass) / (human says pass)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
**Targets: TPR > 90% AND TNR > 90%.**
|
|
124
|
+
|
|
125
|
+
Why both: a judge that flags everything has TPR=100% and a useless TNR. A judge that passes everything is the inverse. Both matter; track them separately.
|
|
126
|
+
|
|
127
|
+
If TPR is low → judge is missing failures. Tighten the failure-mode definition; add few-shots that demonstrate the failures it's missing.
|
|
128
|
+
|
|
129
|
+
If TNR is low → judge is over-flagging. Loosen overly broad criteria; add few-shots of edge-case passes.
|
|
130
|
+
|
|
131
|
+
### Step 4: Final test
|
|
132
|
+
|
|
133
|
+
Run the judge once on the held-out test set. If TPR/TNR drops more than a few points vs. dev, you overfit to dev — go back, regenerate dev/test split, retry. **Don't iterate on the test set.**
|
|
134
|
+
|
|
135
|
+
### Step 5: Use the judge
|
|
136
|
+
|
|
137
|
+
Run the validated judge over future outputs to score them. Wire it into:
|
|
138
|
+
- CI/CD on a curated test set (block merges that drop pass rate)
|
|
139
|
+
- Online monitoring on sampled traffic (alert on regressions)
|
|
140
|
+
- Optimization loop as a metric (`optimization-with-gepa.md`)
|
|
141
|
+
- Orizu scorers and score runs (`prompt-control-plane.md`) so prompt detail, changelog, scorer detail, and optimization surfaces show comparable performance.
|
|
142
|
+
|
|
143
|
+
## Set scorers for judge-vs-gold agreement
|
|
144
|
+
|
|
145
|
+
Use a set scorer when the meaningful metric is only defined over a batch, not one row. Cohen's kappa is the recommended headline for binary judge-vs-human agreement because it corrects for label imbalance and has a chance-agreement zero point.
|
|
146
|
+
|
|
147
|
+
For a binary `ok` / `flag` judge:
|
|
148
|
+
- Register the headline scorer as `mode: "set"`, `metric_key: "cohens_kappa"`, `score_format: "number"`, and `higher_is_better: true`.
|
|
149
|
+
- Set `implementation_kind: "builtin_metric"`, `builtin_metric: "cohens_kappa"`, an explicit `input_mapping`, and `builtin_metric_config.positive_class: "flag"`.
|
|
150
|
+
- Execute with `orizu scorers exec` when row-scorer results are available as a stored score run or local JSONL.
|
|
151
|
+
- Include `accuracy`, `sample_size`, a confusion matrix, and per-class precision/recall in diagnostics.
|
|
152
|
+
- Treat `flag` as the positive class by default, so `tp` means human=`flag` and judge=`flag`, `fn` means human=`flag` and judge=`ok`, `fp` means human=`ok` and judge=`flag`, and `tn` means human=`ok` and judge=`ok`.
|
|
153
|
+
- Include `flag_recall` prominently because it answers whether the judge catches the failures humans care about.
|
|
154
|
+
- On small validation sets, call out uncertainty in `feedbackSummary` rather than over-interpreting a single kappa point estimate.
|
|
155
|
+
|
|
156
|
+
Recommended diagnostics shape:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"sample_size": 15,
|
|
161
|
+
"accuracy": 0.73,
|
|
162
|
+
"confusion_matrix": {
|
|
163
|
+
"tp": 5,
|
|
164
|
+
"fn": 1,
|
|
165
|
+
"fp": 3,
|
|
166
|
+
"tn": 6,
|
|
167
|
+
"positive_class": "flag"
|
|
168
|
+
},
|
|
169
|
+
"flag_recall": 0.83,
|
|
170
|
+
"flag_precision": 0.63,
|
|
171
|
+
"ok_recall": 0.67,
|
|
172
|
+
"ok_precision": 0.86,
|
|
173
|
+
"class_balance": {
|
|
174
|
+
"human_flag": 6,
|
|
175
|
+
"human_ok": 9
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Saturation check
|
|
181
|
+
|
|
182
|
+
If your judge eventually reports 100% pass on a test set, the eval is **saturated** — it's no longer finding failures. That's not victory; it means you need harder cases. Sample fresh production traces, look for ones the current system handles ambiguously, and add them.
|
|
183
|
+
|
|
184
|
+
## Storing judges
|
|
185
|
+
|
|
186
|
+
Treat each judge as code under version control, and push the runnable Orizu representation when using the control plane:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
evals/
|
|
190
|
+
<project>/
|
|
191
|
+
judges/
|
|
192
|
+
escalated_when_required.py # the judge function
|
|
193
|
+
escalated_when_required.test.py# TPR/TNR test against the held-out export
|
|
194
|
+
labels.jsonl # the export this was validated on
|
|
195
|
+
README.md # what failure mode, what the threshold story is
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
For Orizu-managed workflows:
|
|
199
|
+
|
|
200
|
+
1. Push the runner with `orizu runners push`.
|
|
201
|
+
2. Push the LLM judge prompt with `orizu judges push` when applicable.
|
|
202
|
+
3. Register the scorer with `orizu scorers register`.
|
|
203
|
+
4. For row scorers, execute the scorer runner with `orizu runners exec --scorer-version ...` and submit row results with `orizu scores submit`.
|
|
204
|
+
5. For builtin set scorers, execute with `orizu scorers exec`; for locally precomputed set scores, submit the aggregate object with `orizu scores submit --aggregate`.
|
|
205
|
+
|
|
206
|
+
When you re-export labels (e.g. after annotating more data), re-run validation. Judges and scorers drift as the system and data drift; periodic revalidation catches it.
|
|
207
|
+
|
|
208
|
+
## Checklist
|
|
209
|
+
|
|
210
|
+
Before declaring a judge production-ready:
|
|
211
|
+
|
|
212
|
+
- [ ] Failure mode is specific and binary (not "overall quality")
|
|
213
|
+
- [ ] Code assertion attempted first; LLM judge only if rule-shaping wasn't enough
|
|
214
|
+
- [ ] If LLM judge: prompt has clear pass/fail criteria + 4–8 stratified few-shots
|
|
215
|
+
- [ ] Train / dev / test split (20 / 40 / 40)
|
|
216
|
+
- [ ] TPR > 90% AND TNR > 90% on test
|
|
217
|
+
- [ ] Stored in version control alongside the labels it was validated on
|
|
218
|
+
- [ ] If using Orizu control plane, scorer registered with readable metric name, direction, mode, and dataset requirements
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Orizu CLI Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Default Command Strategy](#default-command-strategy)
|
|
6
|
+
- [Command Matrix](#command-matrix)
|
|
7
|
+
- [End-to-End Flows](#end-to-end-flows)
|
|
8
|
+
- [Notes and Limits](#notes-and-limits)
|
|
9
|
+
|
|
10
|
+
## Default Command Strategy
|
|
11
|
+
|
|
12
|
+
1. Verify auth first: `orizu whoami`.
|
|
13
|
+
2. Prefer explicit flags over prompts.
|
|
14
|
+
3. Use interactive fallback only in TTY sessions.
|
|
15
|
+
4. Validate command output before proceeding.
|
|
16
|
+
5. On failure, fix flags/identifiers and rerun.
|
|
17
|
+
|
|
18
|
+
## Command Matrix
|
|
19
|
+
|
|
20
|
+
### Authentication
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
orizu login
|
|
24
|
+
orizu whoami
|
|
25
|
+
orizu logout
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Behavior:
|
|
29
|
+
- `orizu login` opens browser approval and creates a user-owned personal access token for the CLI.
|
|
30
|
+
- New logins store v3 API-key credentials in `~/.config/orizu/credentials.json`.
|
|
31
|
+
- The CLI still reads older session credentials during rollout, but new logins replace them with PAT credentials.
|
|
32
|
+
- `orizu logout` revokes the current PAT remotely when possible and then clears local credentials.
|
|
33
|
+
- PATs can also be revoked from the Personal Tokens page in Orizu.
|
|
34
|
+
- PAT authorization follows the owning user's current team/project roles, so demotion or removal takes effect without rotating the token.
|
|
35
|
+
|
|
36
|
+
### Teams
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
orizu teams list
|
|
40
|
+
orizu teams create --name "My Team"
|
|
41
|
+
orizu teams members list --team my-team
|
|
42
|
+
orizu teams members add --email person@example.com --team my-team
|
|
43
|
+
orizu teams members remove --email person@example.com --team my-team
|
|
44
|
+
orizu teams members role --team my-team --email person@example.com --role admin
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Allowed roles:
|
|
48
|
+
- `admin`
|
|
49
|
+
- `member`
|
|
50
|
+
|
|
51
|
+
### Projects
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
orizu projects list
|
|
55
|
+
orizu projects list --team my-team
|
|
56
|
+
orizu projects create --name "Quality Eval" --team my-team
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Apps
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
orizu apps list --project my-team/quality-eval
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Create from file:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
orizu apps create \
|
|
69
|
+
--project my-team/quality-eval \
|
|
70
|
+
--name "Labeling App" \
|
|
71
|
+
--dataset <datasetId> \
|
|
72
|
+
--file ./apps/LabelingApp.tsx \
|
|
73
|
+
--input-schema ./schemas/input.json \
|
|
74
|
+
--output-schema ./schemas/output.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Preview locally before upload:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
orizu apps preview \
|
|
81
|
+
--file ./apps/LabelingApp.tsx \
|
|
82
|
+
--input-schema ./schemas/input.json \
|
|
83
|
+
--output-schema ./schemas/output.json \
|
|
84
|
+
--sample-row ./fixtures/sample-row.json \
|
|
85
|
+
--screenshot ./preview.png
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Use `--headed` for visible Chromium review and `--keep-open` to leave the browser running.
|
|
89
|
+
|
|
90
|
+
Update from file:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
orizu apps update \
|
|
94
|
+
--app <appId> \
|
|
95
|
+
--file ./apps/LabelingApp.v2.tsx \
|
|
96
|
+
--input-schema ./schemas/input.json \
|
|
97
|
+
--output-schema ./schemas/output.json
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Link dataset:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
orizu apps link-dataset --app <appId> --dataset <datasetId>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Export app source:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
orizu apps export --app <appId> --project my-team/quality-eval --out ./apps/LabelingApp.tsx
|
|
110
|
+
orizu apps export --app <appId> --version 2
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Datasets
|
|
114
|
+
|
|
115
|
+
Row identity contract:
|
|
116
|
+
- `row.id` is the canonical row identifier; the rest of the JSON object is the payload.
|
|
117
|
+
- `row_index` is not part of canonical runtime selection. CLI flags like `--row-ids` always take canonical `id` values.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
orizu datasets upload --file ./data.csv --project my-team/quality-eval --name "Batch 1"
|
|
121
|
+
orizu datasets download --dataset <datasetId|datasetUrl> --format jsonl --out ./dataset.jsonl
|
|
122
|
+
orizu datasets append --dataset <datasetId|datasetUrl> --file ./new-rows.jsonl
|
|
123
|
+
orizu datasets edit-rows --dataset <datasetId|datasetUrl> --file ./edited-rows.jsonl
|
|
124
|
+
orizu datasets delete-rows --dataset <datasetId|datasetUrl> --row-ids row-1,row-2
|
|
125
|
+
orizu datasets delete --dataset <datasetId|datasetUrl>
|
|
126
|
+
orizu datasets lock --dataset <datasetId|datasetUrl> --reason "Finalize for labeling"
|
|
127
|
+
orizu datasets clone --dataset <datasetId|datasetUrl> --name "Batch 1 Copy"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Dataset version and split-set commands used by prompt runs are covered in `prompt-control-plane.md`.
|
|
131
|
+
|
|
132
|
+
Supported file types:
|
|
133
|
+
- `.csv`
|
|
134
|
+
- `.json` (array of objects)
|
|
135
|
+
- `.jsonl` (one object per line)
|
|
136
|
+
|
|
137
|
+
Delete rows selectors:
|
|
138
|
+
- `--row-ids <id1,id2>` (canonical selector)
|
|
139
|
+
|
|
140
|
+
Delete dataset:
|
|
141
|
+
- `datasets delete` permanently deletes the dataset and requires an interactive terminal confirmation.
|
|
142
|
+
- There is no non-interactive confirmation flag.
|
|
143
|
+
|
|
144
|
+
Edit rows requirements:
|
|
145
|
+
- `--file` rows must include canonical `id` for each row being updated.
|
|
146
|
+
|
|
147
|
+
### Tasks
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
orizu tasks list
|
|
151
|
+
orizu tasks list --project my-team/quality-eval
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Create:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
orizu tasks create \
|
|
158
|
+
--project my-team/quality-eval \
|
|
159
|
+
--dataset <datasetId> \
|
|
160
|
+
--app <appId> \
|
|
161
|
+
--title "Round 1 labeling" \
|
|
162
|
+
--instructions "Follow rubric v1" \
|
|
163
|
+
--labels-per-item 2
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Behavior:
|
|
167
|
+
- task creation creates a draft by default and returns a task URL to test manually before assigning
|
|
168
|
+
- use `--publish --assignees <userIdOrEmail1,userIdOrEmail2>` only when you intentionally want to create and ship immediately
|
|
169
|
+
- after manually approving a draft, run `orizu tasks publish --task <taskId> --assignees <userId1,userId2>`
|
|
170
|
+
- task creation resolves and stores the app's pinned current `version_id` at create time
|
|
171
|
+
- downstream consumers (exports, judges, optimization) should trust the task's pinned `version_id`, not the app's current pointer
|
|
172
|
+
- dataset compatibility is validated against that pinned app version before the task is inserted
|
|
173
|
+
- malformed JSON and mixed-type assignee arrays fail with deterministic `400` responses
|
|
174
|
+
- assignment fanout enforces unique `(assignee, row)` pairs; `--labels-per-item` cannot exceed the number of unique assignees, and the backend shortfalls instead of duplicating
|
|
175
|
+
|
|
176
|
+
Publish:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
orizu tasks publish --task <taskId> --assignees <userId1,userId2>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Assign:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
orizu tasks assign --task <taskId> --assignees <userId1,userId2>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Status:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
orizu tasks status --task <taskId>
|
|
192
|
+
orizu tasks status --task <taskId> --json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Includes:
|
|
196
|
+
- task metadata
|
|
197
|
+
- progress counts
|
|
198
|
+
- per-assignee breakdown
|
|
199
|
+
- paused assignments as a distinct count, not folded into pending
|
|
200
|
+
|
|
201
|
+
Report:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
orizu tasks report set --task <taskId> --report-file ./task-report.md
|
|
205
|
+
orizu tasks report upload --task <taskId> --report @./task-report.md
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Behavior:
|
|
209
|
+
- replaces the current task report if one already exists
|
|
210
|
+
- accepted only when the task is `paused` or `completed`
|
|
211
|
+
- accepts the same `--report`, `--report @file`, and `--report-file` Markdown inputs as optimization reports
|
|
212
|
+
|
|
213
|
+
Export:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
orizu tasks export --task <taskId> --format jsonl --out ./labels.jsonl
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Formats:
|
|
220
|
+
- `csv`
|
|
221
|
+
- `json`
|
|
222
|
+
- `jsonl`
|
|
223
|
+
|
|
224
|
+
Defaults:
|
|
225
|
+
- format defaults to `jsonl`
|
|
226
|
+
- output file defaults to `<taskId>.<format>`
|
|
227
|
+
|
|
228
|
+
### Prompt Control Plane
|
|
229
|
+
|
|
230
|
+
For prompts, judges, runners, run submission, optimizer artifacts, live event logging, and accepted-candidate promotion, read `prompt-control-plane.md`. For markdown reports attached to optimization runs, read `optimization-reports.md`.
|
|
231
|
+
|
|
232
|
+
Optimization trace commands:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
orizu optimizations run-gepa ... [--log-dir logs] [--no-local-log]
|
|
236
|
+
orizu optimizations export <optimization-run-id> --out ./optimization.json
|
|
237
|
+
orizu optimizations export <optimization-run-id> --json
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Behavior:
|
|
241
|
+
- `run-gepa` writes a complete local trace under `logs/<optimization_run_id>` by default.
|
|
242
|
+
- The local trace is the best artifact for coding-agent analysis because it includes full rows, outputs, scores, feedback, scorer responses, reflection prompts, reflection responses, candidate text, and `result.json`.
|
|
243
|
+
- `optimizations export` writes a portable JSON artifact from server data when the local log is unavailable or the run happened elsewhere.
|
|
244
|
+
- Server optimization events redact row snapshots and reflection prompts by default; export rehydrates row inputs from dataset artifacts when possible and includes bundled `run-gepa` reflection responses.
|
|
245
|
+
|
|
246
|
+
## End-to-End Flows
|
|
247
|
+
|
|
248
|
+
### New Team to Export
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
orizu login
|
|
252
|
+
orizu teams create --name "Ops Eval"
|
|
253
|
+
orizu projects create --name "Support QA" --team ops-eval
|
|
254
|
+
|
|
255
|
+
orizu datasets upload --project ops-eval/support-qa --file ./datasets/support.jsonl --name "Support Batch 1"
|
|
256
|
+
orizu datasets append --dataset <datasetId> --file ./datasets/support-extra.jsonl
|
|
257
|
+
orizu datasets edit-rows --dataset <datasetId> --file ./datasets/support-edits.jsonl
|
|
258
|
+
orizu datasets delete-rows --dataset <datasetId> --row-ids row-10,row-11
|
|
259
|
+
orizu datasets delete --dataset <datasetId>
|
|
260
|
+
orizu datasets lock --dataset <datasetId> --reason "Freeze for labeling"
|
|
261
|
+
orizu datasets clone --dataset <datasetId> --name "Support Batch 1 Copy"
|
|
262
|
+
|
|
263
|
+
orizu apps create \
|
|
264
|
+
--project ops-eval/support-qa \
|
|
265
|
+
--name "Support Labeler" \
|
|
266
|
+
--dataset <datasetId> \
|
|
267
|
+
--file ./apps/SupportLabeler.tsx \
|
|
268
|
+
--input-schema ./schemas/support-input.json \
|
|
269
|
+
--output-schema ./schemas/support-output.json
|
|
270
|
+
|
|
271
|
+
orizu apps link-dataset --app <appId> --dataset <datasetId>
|
|
272
|
+
|
|
273
|
+
orizu tasks create \
|
|
274
|
+
--project ops-eval/support-qa \
|
|
275
|
+
--dataset <datasetId> \
|
|
276
|
+
--app <appId> \
|
|
277
|
+
--title "Support QA Round 1" \
|
|
278
|
+
--labels-per-item 2
|
|
279
|
+
|
|
280
|
+
# Open the returned task URL and test the draft manually before assigning.
|
|
281
|
+
orizu tasks publish --task <taskId> --assignees <userId1,userId2>
|
|
282
|
+
|
|
283
|
+
orizu tasks status --task <taskId>
|
|
284
|
+
orizu tasks export --task <taskId> --format csv --out ./support-round1.csv
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Interactive-First Shortcuts
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
orizu apps list
|
|
291
|
+
orizu teams members add --email new-person@example.com
|
|
292
|
+
orizu datasets upload --file ./data.csv
|
|
293
|
+
orizu tasks export
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Use these shortcuts only in TTY environments where prompts can run.
|
|
297
|
+
|
|
298
|
+
## Notes and Limits
|
|
299
|
+
|
|
300
|
+
- `tasks create` creates a draft by default, does not require `--assignees`, and pins the app's current version when the task is created.
|
|
301
|
+
- `tasks create --publish --assignees <...>` intentionally creates and ships immediately.
|
|
302
|
+
- `tasks assign` and `tasks publish` expect user IDs, not emails.
|
|
303
|
+
- Assignment queue reads are assignee-self-only; use task status/export as the operator summary path.
|
|
304
|
+
- Assignment completion payloads are validated against the pinned app-version `output_json_schema`.
|
|
305
|
+
- `datasets delete-rows` requires `--row-ids`.
|
|
306
|
+
- `datasets delete` requires interactive terminal confirmation and has no non-interactive confirmation flag.
|
|
307
|
+
- `datasets edit-rows` requires row objects in `--file` to include canonical `id`.
|
|
308
|
+
- `--row-ids` is the canonical row selection for delete operations.
|
|
309
|
+
- Locked datasets reject append/edit/delete row mutations.
|
|
310
|
+
- Row deletes are rejected when targeted rows are assignment-referenced.
|
|
311
|
+
- Login currently requires callback availability on `127.0.0.1:43123`.
|
|
312
|
+
- New CLI logins use personal access tokens rather than short-lived Supabase session credentials.
|
|
313
|
+
- In non-interactive contexts, pass explicit selection flags.
|
|
314
|
+
|
|
315
|
+
Output-schema validation surface:
|
|
316
|
+
- `--output-schema` JSON is validated against a subset of JSON Schema only: `type`, `required`, `properties`, `items`, `enum`. Other keywords (`pattern`, `format`, `oneOf`, etc.) are ignored. See `building-apps.md` for the contract.
|
|
317
|
+
|
|
318
|
+
Hugging Face / external dataset auth:
|
|
319
|
+
- Never persist auth tokens in row payloads, dataset metadata, exports, or logs.
|
|
320
|
+
- Store only non-secret credential references (e.g. `huggingface.token_ref`) in source metadata.
|
|
321
|
+
|
|
322
|
+
Worker assignment reads are self-only:
|
|
323
|
+
- Regular members cannot see other assignees' queues or response payloads.
|
|
324
|
+
- Use `tasks status` and `tasks export` for operator-side reporting.
|