@hue-run/sdk 0.4.1 → 0.5.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/CLI.md +194 -6
- package/ENVIRONMENTS.md +30 -9
- package/EVALUATIONS.md +125 -4
- package/README.md +27 -2
- package/dist/cli/eval-direct.d.ts +47 -0
- package/dist/cli/eval-direct.js +171 -0
- package/dist/cli/eval.d.ts +28 -0
- package/dist/cli/eval.js +985 -0
- package/dist/cli/login.d.ts +32 -0
- package/dist/cli/login.js +712 -0
- package/dist/cli/mcp.d.ts +76 -0
- package/dist/cli/mcp.js +466 -0
- package/dist/evals/client.d.ts +30 -1
- package/dist/evals/client.js +138 -1
- package/dist/evals/files.d.ts +50 -0
- package/dist/evals/files.js +223 -0
- package/dist/evals/local-worker.d.ts +49 -4
- package/dist/evals/local-worker.js +63 -12
- package/dist/evals/runner.d.ts +30 -10
- package/dist/evals/runner.js +216 -68
- package/dist/evals/scenarios.d.ts +79 -0
- package/dist/evals/scenarios.js +169 -0
- package/dist/evals/scorers.d.ts +13 -0
- package/dist/evals/scorers.js +21 -3
- package/dist/evals/simulation.d.ts +23 -4
- package/dist/evals/simulation.js +70 -24
- package/dist/evals/types.d.ts +174 -1
- package/dist/evals/types.js +17 -1
- package/dist/evals/verdicts.d.ts +161 -0
- package/dist/evals/verdicts.js +192 -0
- package/dist/evals.d.ts +10 -4
- package/dist/evals.js +5 -1
- package/dist/setup/cli.js +13 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CLI.md
CHANGED
|
@@ -42,8 +42,8 @@ project manifest are refused because managers can update ancestor locks; Python
|
|
|
42
42
|
The generated `hue.setup.mjs` or `hue_setup.py` always selects `captureContent: false` /
|
|
43
43
|
`capture_content=False`. For a supported application, setup installs the dependency and adds the
|
|
44
44
|
managed import and middleware registration to the existing entrypoint; an unreferenced helper is
|
|
45
|
-
not a completed integration. TypeScript uses `@hue-run/sdk@0.
|
|
46
|
-
`@opentelemetry/context-async-hooks@2.11.0`; Python uses `hue-run==0.2.2`.
|
|
45
|
+
not a completed integration. TypeScript uses `@hue-run/sdk@0.5.0`, `@opentelemetry/api@1.9.1` and
|
|
46
|
+
`@opentelemetry/context-async-hooks@2.11.0`; Python uses published `hue-run==0.2.2`.
|
|
47
47
|
Content capture requires an ordinary account-managed key and a later explicit application decision.
|
|
48
48
|
|
|
49
49
|
The generated bootstrap supplies standard active SERVER-span context across asynchronous/streaming
|
|
@@ -79,7 +79,7 @@ events, checkpoints or receipts. Ordinary app starts have no handshake and retai
|
|
|
79
79
|
listener behavior. This prevents accidental requests to an unrelated listener, not access by
|
|
80
80
|
malicious code running as the same local user.
|
|
81
81
|
|
|
82
|
-
Setup creates no
|
|
82
|
+
Setup creates no simulation, Hue Run, evaluation, source capture, worker or remote execution. Package
|
|
83
83
|
manager lifecycle scripts are disabled. The supported existing application entrypoint is executed
|
|
84
84
|
directly with fixed argv solely for its bounded local HTTP verification; no shell command is accepted.
|
|
85
85
|
|
|
@@ -111,6 +111,8 @@ hue claim --restart # explicit owner recovery; requires an interactive loc
|
|
|
111
111
|
hue setup --agent # noninteractive version-2 JSONL events
|
|
112
112
|
hue setup --format human # explicit append-only terminal rendering
|
|
113
113
|
hue setup --origin http://127.0.0.1:PORT # isolated loopback tests only
|
|
114
|
+
hue login # validate keys created in Hue and store them in ./.env.hue
|
|
115
|
+
hue mcp install --client claude-code # write the Hue MCP configuration for a coding agent
|
|
114
116
|
```
|
|
115
117
|
|
|
116
118
|
Hosted setup accepts HTTPS origins only. HTTP is accepted solely for `localhost`, `127.0.0.1` and
|
|
@@ -138,6 +140,60 @@ uses the observed predecessor for compare-and-swap. A conflict refreshes status
|
|
|
138
140
|
At most 32 distinct handoff IDs exist per installation; `SETUP_HANDOFF_LIMIT` is terminal. Replacing a
|
|
139
141
|
handoff does not create a trial, reset quota or rerun business work.
|
|
140
142
|
|
|
143
|
+
## Sign in and store keys
|
|
144
|
+
|
|
145
|
+
`hue login` stores keys that a person creates in Hue; it never mints one, because setup
|
|
146
|
+
credentials are deliberately isolated from ordinary project keys. It prints the key settings page
|
|
147
|
+
(`<origin>/settings/integrations`, opened in a browser only when a terminal is attached and
|
|
148
|
+
`--no-browser` is absent), then reads each requested key from stdin without echo. A
|
|
149
|
+
**Tracing and evaluations** key is validated with `GET /api/v1/projects/current` and stored as
|
|
150
|
+
`HUE_API_KEY` with `HUE_BASE_URL`; a **Coding agent (read + evaluations)** key is validated with an
|
|
151
|
+
MCP `tools/list` request and stored as `HUE_MCP_KEY` with `HUE_MCP_URL`. A rejected key (`401` or
|
|
152
|
+
`403`) exits `1` and stores nothing for that key.
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
hue login # both keys into ./.env.hue
|
|
156
|
+
hue login --keys coding-agent --gitignore # only HUE_MCP_KEY; add .env.hue to .gitignore
|
|
157
|
+
hue login --origin https://staging.hue.run --env-file .env.staging
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The env file is written with mode `0600` through a temporary file and an atomic rename. Other
|
|
161
|
+
lines are preserved; a symlink or a non-regular file is refused; an existing different value is
|
|
162
|
+
replaced only with `--force`. Empty values, whitespace and URLs are refused before any request.
|
|
163
|
+
The MCP endpoint is `https://mcp.hue.run/mcp` for `https://app.hue.run`,
|
|
164
|
+
`https://mcp.staging.hue.run/mcp` for `https://staging.hue.run` and `<origin>/api/mcp` otherwise;
|
|
165
|
+
plain HTTP origins are accepted for loopback test servers only. Output names variables and lengths
|
|
166
|
+
(`Stored HUE_API_KEY (NN chars)`), never values. When git does not ignore the env file, the command
|
|
167
|
+
warns; `--gitignore` appends the file name to the `.gitignore` next to it. Exit codes: `0` stored,
|
|
168
|
+
`1` failed, `2` usage error, `130` interrupted.
|
|
169
|
+
|
|
170
|
+
## Install the MCP for your coding agent
|
|
171
|
+
|
|
172
|
+
`hue mcp install --client <name>` writes, runs or prints the configuration for Hue's MCP server.
|
|
173
|
+
Every shape matches the snippet Hue shows in Settings: server name `hue`, the endpoint (default
|
|
174
|
+
`https://mcp.hue.run/mcp`; `--url https://mcp.staging.hue.run/mcp` for staging) and a reference to
|
|
175
|
+
the `HUE_MCP_KEY` environment variable. A key value is never written.
|
|
176
|
+
|
|
177
|
+
| Client | Result |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| `claude-code` | Merges `mcpServers.hue` into `./.mcp.json`. `--scope user` runs `claude mcp add --transport http --scope user hue URL --header 'Authorization: Bearer ${HUE_MCP_KEY}'` when `claude` is on `PATH`, otherwise prints it. |
|
|
180
|
+
| `cursor` | Merges `mcpServers.hue` into `./.cursor/mcp.json` with `${env:HUE_MCP_KEY}`. |
|
|
181
|
+
| `codex` | Runs `codex mcp add hue --url URL --bearer-token-env-var HUE_MCP_KEY`, or prints the `[mcp_servers.hue]` TOML block for `~/.codex/config.toml`. |
|
|
182
|
+
| `vscode` | Merges `servers.hue` and the `hue-mcp-key` password input into `./.vscode/mcp.json`. |
|
|
183
|
+
| `windsurf` | Prints the `serverUrl` snippet for `~/.codeium/windsurf/mcp_config.json`; nothing is written to the home directory. |
|
|
184
|
+
| `gemini` | Runs `gemini mcp add --transport http hue URL -H 'Authorization: Bearer $HUE_MCP_KEY'`, or prints it. |
|
|
185
|
+
|
|
186
|
+
JSON files are parsed and merged: other servers, inputs and top-level fields are kept, only the
|
|
187
|
+
`hue` entry is replaced, and invalid JSON (including comments) is refused together with the snippet
|
|
188
|
+
to add by hand. Files are written with mode `0644` through a temporary file and an atomic rename;
|
|
189
|
+
symlinks are refused. `--dry-run` prints the resulting file content or command without writing or
|
|
190
|
+
running; `--print` prints only the snippet. Client CLIs run without a shell, so the
|
|
191
|
+
`${HUE_MCP_KEY}` and `$HUE_MCP_KEY` references reach them literally; the printed commands use
|
|
192
|
+
single quotes for the same reason. After installation the command reminds you to export
|
|
193
|
+
`HUE_MCP_KEY` in the shell that starts the client (VS Code prompts for the key instead) and prints
|
|
194
|
+
the verification prompt: `Use the Hue MCP: call get_project_context, then show my 5 most recent
|
|
195
|
+
error traces with links.` Exit codes: `0` done or printed, `1` failed, `2` usage error.
|
|
196
|
+
|
|
141
197
|
## Local state and conflicts
|
|
142
198
|
|
|
143
199
|
Before its first network write, setup creates a lowercase UUIDv4 and a 32-byte random installation
|
|
@@ -172,7 +228,7 @@ capability `setup_telemetry_write`.
|
|
|
172
228
|
Normal project credentials and unknown token shapes are refused in setup responses and private
|
|
173
229
|
managed state. These credentials authorize metadata-only OTLP at `/api/v1/otlp/v1/traces` and exact
|
|
174
230
|
content-free receipt verification at `/api/v1/setup/traces/{traceId}/receipt`. They do not authorize
|
|
175
|
-
generic project, receipt, evaluation, log or browsing APIs. Python `0.2.2` can export with the setup
|
|
231
|
+
generic project, receipt, evaluation, log or browsing APIs. Published Python `0.2.2` can export with the setup
|
|
176
232
|
credential; the CLI verifies the dedicated setup receipt instead of Python's generic receipt helper.
|
|
177
233
|
|
|
178
234
|
Each command uses bounded timeouts and retries. Provisioning records at most five attempts per local
|
|
@@ -241,7 +297,7 @@ node packages/sdk-typescript/scripts/verify-package.mjs --artifacts-dir .artifac
|
|
|
241
297
|
# Set project to an existing supported fixture; use the same directory on resume.
|
|
242
298
|
project=/absolute/path/to/supported-fixture
|
|
243
299
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
244
|
-
--archive .artifacts/typescript/hue-run-sdk-0.
|
|
300
|
+
--archive .artifacts/typescript/hue-run-sdk-0.5.0.tgz \
|
|
245
301
|
--origin https://STAGING_ORIGIN \
|
|
246
302
|
--project "$project" --command setup \
|
|
247
303
|
--evidence .context/setup-staging-before-claim.json
|
|
@@ -252,7 +308,7 @@ the private local handoff and finish the real browser claim, then reconcile the
|
|
|
252
308
|
|
|
253
309
|
```sh
|
|
254
310
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
255
|
-
--archive .artifacts/typescript/hue-run-sdk-0.
|
|
311
|
+
--archive .artifacts/typescript/hue-run-sdk-0.5.0.tgz \
|
|
256
312
|
--origin https://STAGING_ORIGIN \
|
|
257
313
|
--project "$project" --command claim \
|
|
258
314
|
--evidence .context/setup-staging-after-claim.json
|
|
@@ -273,3 +329,135 @@ only the private local file and produces no secret-bearing screenshots, traces,
|
|
|
273
329
|
Publication under a candidate dist-tag, registry acceptance, production activation, promotion of
|
|
274
330
|
the same version to `latest`, and clean-project literal `@latest` smoke remain separate gates; see
|
|
275
331
|
[RELEASING.md](../../RELEASING.md).
|
|
332
|
+
|
|
333
|
+
## Evaluate an agent against a Scenario
|
|
334
|
+
|
|
335
|
+
`hue eval` runs a developer's local agent against a published Hue Scenario or a saved eval set
|
|
336
|
+
and prints Hue's verdicts. It is the command-line form of `runSimulation()` (one-shot) and
|
|
337
|
+
`runLocalAgent()` (worker): the agent, its prompts and its provider credentials stay in the local
|
|
338
|
+
process, Hue creates one isolated simulated world per case, and Hue-owned outcome checks grade
|
|
339
|
+
the sealed world. Hue never executes the agent. `HUE_API_KEY` must be a **Tracing and
|
|
340
|
+
evaluations** project key (a **Tracing only** key cannot read Scenarios or create experiments);
|
|
341
|
+
the CLI never prints it. The optional `zod` peer of `@hue-run/sdk/evals` must be installed.
|
|
342
|
+
|
|
343
|
+
Write an adapter module that hands the case inputs and the world's tools or MCP connection to
|
|
344
|
+
the real agent. The module exports `default` or `runMyAgent`; `context` is the SDK's
|
|
345
|
+
`SimulationTargetContext` (`tools`, `mcp`, `config`, `item`, `executionId`, `environmentRunId`,
|
|
346
|
+
`signal`):
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
// hue-agent.ts: erasable TypeScript only; Node.js 24 and Bun strip the types natively.
|
|
350
|
+
import type { JsonValue, SimulationTargetContext } from "@hue-run/sdk/evals";
|
|
351
|
+
import { runAgent } from "./src/agent.js"; // The application's existing entry point.
|
|
352
|
+
|
|
353
|
+
export default function runMyAgent(inputs: JsonValue, context: SimulationTargetContext) {
|
|
354
|
+
// Hand context.tools or context.mcp to the agent's real tool boundary; configuration alone
|
|
355
|
+
// does not redirect provider calls. Pass context.signal for cooperative cancellation.
|
|
356
|
+
const { config, tools, mcp, signal } = context;
|
|
357
|
+
return runAgent({ inputs, config, tools, mcp, signal });
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
```sh
|
|
362
|
+
hue eval --scenario "Refund an eligible charge" ./hue-agent.ts --env-file .env.hue
|
|
363
|
+
hue eval --scenario https://app.hue.run/projects/demo/scenarios/<id> ./hue-agent.ts --baseline <experiment id>
|
|
364
|
+
hue eval --set "Billing regressions" --scorer-version <id> ./hue-agent.ts --save-version
|
|
365
|
+
hue eval --scenario "Refund an eligible charge" --command "python agent.py" --timeout 120 --content
|
|
366
|
+
hue eval --worker ./hue-agent.ts --agent-key support-agent --env-file .env.hue
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The one-shot mode resolves the selection (`--scenario` by name, ID or URL; `--set` by name, ID or
|
|
370
|
+
URL with explicit `--scorer-version` pins; or `--dataset-version` with `--scorer-version`),
|
|
371
|
+
creates a fresh experiment from those immutable pins named `<scenario> · <agent key> · <revision>`
|
|
372
|
+
(`--name` overrides), prints `Run: <url>` and `Experiment: <id>` as soon as the experiment exists,
|
|
373
|
+
one line per case event (world created, agent started, world sealed), then
|
|
374
|
+
`Waiting for Hue checks...` and a table with one row per case: boolean metrics as `PASS`/`FAIL`,
|
|
375
|
+
numbers as values, text and category metrics as-is, an overall result per case and a pass count.
|
|
376
|
+
Failing cases print the scorer explanation. `--baseline <experiment id|url>` adds improvement,
|
|
377
|
+
regression and unchanged counts with per-case deltas. `--json` prints one JSON document
|
|
378
|
+
(`experimentId`, `runId`, `runUrl`, `complete`, `cases`, `totals`, optional `baseline`) on stdout
|
|
379
|
+
and sends progress to stderr. `--wait <seconds>` (default 300) bounds the verdict wait because
|
|
380
|
+
Hue-owned `world_outcome` checks are graded after the world seals. An experiment always covers
|
|
381
|
+
every case of the saved version; there is no case subset.
|
|
382
|
+
|
|
383
|
+
`--command "<shell command>"` spawns the command once per case with `HUE_MCP_URL`,
|
|
384
|
+
`HUE_MCP_TOKEN`, `HUE_MCP_EXPIRES_AT`, `HUE_EXECUTION_ID`, `HUE_ENVIRONMENT_RUN_ID`, `HUE_CASE_ID`
|
|
385
|
+
and `HUE_CASE_KEY` in its environment and `{"inputs": ..., "config": ...}` on stdin. Its stdout is
|
|
386
|
+
the answer (JSON when it parses, otherwise trimmed text; empty means no output); a non-zero exit
|
|
387
|
+
or the per-case `--timeout` (default 600 seconds) is a target failure. The scoped MCP token is
|
|
388
|
+
never logged. The agent key defaults to the slug of the command's script name.
|
|
389
|
+
|
|
390
|
+
`--worker` registers the adapter through `runLocalAgent()` with key `--agent-key` (default: the
|
|
391
|
+
adapter filename slug), name `--agent-name` (default: the key), revision `--revision` (default:
|
|
392
|
+
`AGENT_REVISION`, then the Git `HEAD` short hash, then `dev`) and capability `environment:v1`,
|
|
393
|
+
prints the registration and each claimed run with its URL, executes runs launched from Hue until
|
|
394
|
+
Ctrl+C or `--max-runs <n>`, and prints the verdict table after each run. Selection flags do not
|
|
395
|
+
apply; Hue chooses the pinned experiment. The worker exits 0 when it stops normally.
|
|
396
|
+
|
|
397
|
+
A Scenario or eval set whose dataset version is not saved cannot back an experiment: the command
|
|
398
|
+
exits 1 and asks for **Save eval-set version** in Hue or `--save-version`, which freezes that
|
|
399
|
+
version at its current revision. Connection settings are `HUE_API_KEY` and `HUE_BASE_URL`
|
|
400
|
+
(default `https://app.hue.run`), loaded from `--env-file <path>` first when given; `--origin`
|
|
401
|
+
overrides the origin. Telemetry content capture stays off unless `--content` is passed; in
|
|
402
|
+
one-shot mode it also decides whether case outputs, error messages and explanations are persisted
|
|
403
|
+
to Hue. `--worker` always persists them, because a run launched from Hue is read on its run page:
|
|
404
|
+
that is `runLocalAgent()`'s contract and `--content` does not change it. Trace evidence is required
|
|
405
|
+
for every case.
|
|
406
|
+
Resumable checkpoints live in `.hue/eval/<agent-key>/<project id>/` (a `.gitignore` is written
|
|
407
|
+
inside `.hue/eval/`); `--checkpoint-dir` overrides the root. Rerunning the same selection resumes
|
|
408
|
+
an interrupted run without invoking the agent again; a different selection is refused until the
|
|
409
|
+
unfinished one is resumed or its directory is removed.
|
|
410
|
+
|
|
411
|
+
Exit codes: `0` every case passed, `1` a case failed, errored, was skipped or Hue's checks were
|
|
412
|
+
still pending at `--wait`, `2` usage or configuration error (including a missing key), `130`
|
|
413
|
+
interrupted. On Node.js 22, load TypeScript adapters with `NODE_OPTIONS=--experimental-strip-types`;
|
|
414
|
+
non-erasable syntax (enums, parameter properties, namespaces) needs a loader such as `--import tsx`
|
|
415
|
+
on any Node.js version.
|
|
416
|
+
|
|
417
|
+
## Evaluate a document eval set
|
|
418
|
+
|
|
419
|
+
Eval sets whose cases pin no simulated world — a task plus pinned input files, answered with
|
|
420
|
+
generated documents — run as **direct** cases through `runExperiment()`. `hue eval` detects this
|
|
421
|
+
from the saved version (`--mode direct|simulation` overrides the detection; `--scenario` is always
|
|
422
|
+
a simulation). `--set` accepts the eval set's slug, name, ID or URL; `--set-version <n>` pins a
|
|
423
|
+
saved version other than the latest; `--scorer <slug|name|id>` pins an evaluator at its newest
|
|
424
|
+
published version, beside or instead of explicit `--scorer-version` IDs.
|
|
425
|
+
|
|
426
|
+
```sh
|
|
427
|
+
hue eval --set gia-d1-citation --scorer gia-d1-citation \
|
|
428
|
+
--command "pnpm --filter @august/frontend run hue:gia-agent" \
|
|
429
|
+
--revision prompt-v10 --wait 1800 --json --env-file .env.hue
|
|
430
|
+
hue eval --set gia-d1-citation --set-version 1 --scorer gia-d1-citation ./hue-agent.ts --baseline <experiment id>
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
For each case the command is spawned once **inside a private case directory** with
|
|
434
|
+
`HUE_CASE_DIR`, `HUE_CASE_INPUTS`, `HUE_CASE_OUTPUT_DIR`, `HUE_CASE_ID`, `HUE_CASE_KEY` and
|
|
435
|
+
`HUE_EXECUTION_ID` in its environment (`{"inputs","config"}` is also written to stdin):
|
|
436
|
+
|
|
437
|
+
```text
|
|
438
|
+
<case dir>/inputs.json the case inputs (for example {"query": "...", "tipo_diligencia": "Virtual"})
|
|
439
|
+
<case dir>/case.json id, external key, execution id, run config, staged file list
|
|
440
|
+
<case dir>/files/<role>/<name> verified copies of the agent-visible pinned files
|
|
441
|
+
<case dir>/output/ write the generated documents here
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
Every regular file the command leaves under `output/` is uploaded as a generated document
|
|
445
|
+
(accepted: `.pdf .docx .pptx .xlsx .json .txt .csv .png .jpg .jpeg .webp`; another extension or an
|
|
446
|
+
empty file is the case's error). Optional helpers: `manifest.json` (`{"primary": "<filename>",
|
|
447
|
+
"output": <json>}`) names the primary document and the JSON output; `result.json` is the JSON
|
|
448
|
+
output; `summary.txt` or `summary.md` is recorded as `{"summary": "..."}`. When none is written,
|
|
449
|
+
the command's stdout is the output (JSON when it parses). A single generated file is the primary
|
|
450
|
+
document by default. Model and provider credentials stay in the command's own environment; the
|
|
451
|
+
scoped case files are copies under `--checkpoint-dir` (default `.hue/eval/<agent-key>/<project>/direct/<experiment>`).
|
|
452
|
+
|
|
453
|
+
An adapter file works too: it is called with `(inputs, context)` where `context.mode` is
|
|
454
|
+
`"direct"` and `context` carries `config`, `item`, `executionId`, `files` (agent-visible pinned
|
|
455
|
+
files on disk), `outputDirectory` and `signal`. Return a JSON value, or `withFiles(output, files)`
|
|
456
|
+
from `@hue-run/sdk/evals` to attach generated documents.
|
|
457
|
+
|
|
458
|
+
Code evaluators pinned to the run are **not** executed on your machine: the CLI leaves them
|
|
459
|
+
deferred (`deferUnboundLocalScorers`) and Hue's grading executor scores the uploaded documents;
|
|
460
|
+
evaluator-only pinned files such as a legal corpus are never downloaded. `Waiting for Hue
|
|
461
|
+
checks...` then covers that grading, so size `--wait` to the evaluator's runtime. The
|
|
462
|
+
`--json` document gains `"mode": "direct"` and `"deferredScorerVersionIds"`. Exit codes, `--baseline`
|
|
463
|
+
and checkpoints behave as for Scenarios.
|
package/ENVIRONMENTS.md
CHANGED
|
@@ -10,7 +10,7 @@ Your agent runs in your process while a disposable simulated world runs in Hue.
|
|
|
10
10
|
authoritative and records an ordered journal; Hue does not execute your agent code or provider
|
|
11
11
|
credentials.
|
|
12
12
|
|
|
13
|
-
## Run a
|
|
13
|
+
## Run a definition like a test
|
|
14
14
|
|
|
15
15
|
`runSimulation` is the one-shot developer path. It calls your existing callback directly, so
|
|
16
16
|
IDE breakpoints and cooperative cancellation work. It does not register a worker, poll for jobs,
|
|
@@ -29,8 +29,8 @@ try {
|
|
|
29
29
|
client: createEvaluationClient(connection),
|
|
30
30
|
environmentClient: createEnvironmentClient(connection),
|
|
31
31
|
hue,
|
|
32
|
-
checkpointDirectory: ".hue-checkpoints/refund-
|
|
33
|
-
|
|
32
|
+
checkpointDirectory: ".hue-checkpoints/refund-definition",
|
|
33
|
+
definition: { kind: "experiment", experimentId: process.env.HUE_EXPERIMENT_ID! },
|
|
34
34
|
persistResultContent: true,
|
|
35
35
|
traceEvidence: { mode: "required" },
|
|
36
36
|
target: (inputs, { tools, mcp, config, signal }) =>
|
|
@@ -60,6 +60,27 @@ identifies the same world for adapter control operations such as
|
|
|
60
60
|
`environmentClient.recordCoverageGap`; it is not a credential. The MCP token is delivered only
|
|
61
61
|
to the callback and is never written to checkpoints.
|
|
62
62
|
|
|
63
|
+
### Published pins and verdicts
|
|
64
|
+
|
|
65
|
+
`scenario: { kind: "pins", datasetVersionId, scorerVersionIds, config?, name? }` runs already
|
|
66
|
+
published immutable pins, such as a Scenario's frozen case and Hue-owned outcome checks or a saved
|
|
67
|
+
eval set with explicitly chosen scorer versions. `resolveScenarioPins(client, selector)` reads
|
|
68
|
+
those pins from a Scenario ID, its Hue URL or its name (`listScenarios` and `getScenario` expose
|
|
69
|
+
the underlying reads; a Tracing and evaluations key is required), and `resolveEvalSetPins`
|
|
70
|
+
resolves an eval set to its latest saved version. `runSimulation` creates the experiment directly
|
|
71
|
+
(`name` defaults to the dataset name, `config` to `{}`) and binds the pins and configuration into
|
|
72
|
+
the checkpoint identity, so resuming with different pins is refused like the other kinds.
|
|
73
|
+
Hue-executed pins such as `world_outcome` need no local callback; pass `localScorers` only for
|
|
74
|
+
bound `local_code` pins.
|
|
75
|
+
|
|
76
|
+
Hue grades `world_outcome` pins after the world seals, so the runner's report precedes the
|
|
77
|
+
verdicts. `waitForResults(client, { runId, scorerVersionIds, subjectIds, timeoutMillis })` polls
|
|
78
|
+
until every item has a terminal result for every pin or the budget elapses (`complete: false`);
|
|
79
|
+
`summarizeVerdicts` turns results into per-case rows with `passed` and totals; `compareVerdicts`
|
|
80
|
+
diffs two summaries by case key; and `collectExperimentVerdicts` combines those reads for one
|
|
81
|
+
experiment. The `hue eval` command uses the same path; see
|
|
82
|
+
[Evaluate an agent against a Scenario](CLI.md#evaluate-an-agent-against-a-scenario).
|
|
83
|
+
|
|
63
84
|
### Pinned provider-profile preflight
|
|
64
85
|
|
|
65
86
|
An experiment with an immutable `attemptBaselineV2` can require the local process to describe
|
|
@@ -84,10 +105,10 @@ facade acceptance remains a post-publication Fern integration gate. No public SD
|
|
|
84
105
|
official Gmail service, and passing these tests is not evidence of universal Gmail or Slack
|
|
85
106
|
parity. A matching Hue deployment and verified provider profile remain required.
|
|
86
107
|
|
|
87
|
-
## Repository-authored
|
|
108
|
+
## Repository-authored definitions
|
|
88
109
|
|
|
89
|
-
Repository
|
|
90
|
-
experiment APIs as
|
|
110
|
+
Repository definitions publish through the same validated environment, dataset, scorer and
|
|
111
|
+
experiment APIs as definitions authored in Hue. Stable slugs reuse matching immutable content
|
|
91
112
|
digests; changed definitions, tasks or scorers publish new versions. Hue does not synchronize
|
|
92
113
|
files back from its UI, and the helper refuses an unrelated mutable dataset draft instead of
|
|
93
114
|
overwriting it.
|
|
@@ -106,7 +127,7 @@ the same before comparing immutable digests, so casing-only UUID changes reuse t
|
|
|
106
127
|
version without dropping provider bindings.
|
|
107
128
|
|
|
108
129
|
```ts
|
|
109
|
-
const
|
|
130
|
+
const definition = {
|
|
110
131
|
kind: "repository" as const,
|
|
111
132
|
name: "Refund an eligible charge",
|
|
112
133
|
slug: "refund-eligible-charge",
|
|
@@ -130,8 +151,8 @@ await runSimulation({
|
|
|
130
151
|
client,
|
|
131
152
|
environmentClient,
|
|
132
153
|
hue,
|
|
133
|
-
checkpointDirectory: ".hue-checkpoints/refund-
|
|
134
|
-
|
|
154
|
+
checkpointDirectory: ".hue-checkpoints/refund-definition",
|
|
155
|
+
definition,
|
|
135
156
|
persistResultContent: false,
|
|
136
157
|
traceEvidence: { mode: "required" },
|
|
137
158
|
target: (inputs, context) => runMyExistingAgent({ inputs, ...context }),
|
package/EVALUATIONS.md
CHANGED
|
@@ -72,10 +72,20 @@ try {
|
|
|
72
72
|
|
|
73
73
|
Create another experiment with the same frozen version and different `config` to compare configurations. The runner reads the exact experiment case/version and scorer definitions; it never resolves a mutable latest version. `rescore` accepts an existing evaluation-run ID and has no target callback. Subject IDs refer to immutable saved outputs and trace evidence.
|
|
74
74
|
|
|
75
|
+
`rescore` preserves terminal scores already recorded for each item and evaluator version,
|
|
76
|
+
including built-in checks scheduled by Hue's **Grade again** flow. It computes only the missing
|
|
77
|
+
local scores and reports the existing receipts alongside the new ones. If another executor
|
|
78
|
+
finishes the same score while this one uploads, the runner accepts that exact item/version
|
|
79
|
+
receipt; an unrelated conflict still fails. To evaluate the same saved output again, create a new
|
|
80
|
+
scoring run.
|
|
81
|
+
|
|
75
82
|
For the shorter agent-against-a-hosted-world workflow, use `runSimulation`. It owns immutable
|
|
76
83
|
resolution, a fresh linked world per case, local and hosted MCP tools, finalization, sealed
|
|
77
84
|
evidence and scoring while retaining this runner's checkpoint guarantees. See
|
|
78
|
-
[Simulated environments](ENVIRONMENTS.md#run-a-
|
|
85
|
+
[Simulated environments](ENVIRONMENTS.md#run-a-definition-like-a-test).
|
|
86
|
+
|
|
87
|
+
Cases whose inputs are a task plus pinned documents, and rescoring over documents a run already
|
|
88
|
+
saved, use the same runner without a world. See [Direct cases and files](#direct-cases-and-files).
|
|
79
89
|
|
|
80
90
|
## Content and result states
|
|
81
91
|
|
|
@@ -110,7 +120,7 @@ const published = await client.publishScorerVersion(identity.id, local.definitio
|
|
|
110
120
|
// Pin published.id in the experiment and pass scorers:[local] to the runner.
|
|
111
121
|
```
|
|
112
122
|
|
|
113
|
-
A callback receives `{inputs,hasOutput,output?,hasExpected,expected?,metadata,executionState}` and returns one of:
|
|
123
|
+
A callback receives `{inputs,hasOutput,output?,hasExpected,expected?,metadata,executionState,files?}` and returns one of:
|
|
114
124
|
|
|
115
125
|
- `{state:"scored",metrics:[{name,value,passed?}],explanation?,evidence?}` (explanation or evidence required).
|
|
116
126
|
- `{state:"error",error:{type,message?}}`.
|
|
@@ -118,6 +128,13 @@ A callback receives `{inputs,hasOutput,output?,hasExpected,expected?,metadata,ex
|
|
|
118
128
|
|
|
119
129
|
All declared metrics must appear exactly once and satisfy pinned types, bounds and categories. The binding must match language, entrypoint, SHA-256 source digest and metric definitions. The digest is an authenticated caller declaration; it does not attest closures, dependency versions or actual execution. Callback source is never downloaded or evaluated. Callbacks are trusted local code; they have **no execution timeout or side-effect cancellation**. Concurrency limits active cases to 1–16 (default 1), with scorers evaluated sequentially within each case.
|
|
120
130
|
|
|
131
|
+
`files` is present only when the runner handled files for that execution: every pinned input file
|
|
132
|
+
(all roles, including the evaluator-only `org_template`) and every generated output, each with its
|
|
133
|
+
verified local `path`, `role`, `filename`, `contentType`, `byteSize`, `sha256`, `artifactId` and
|
|
134
|
+
`primary` flag. A `local_code` callback runs when generated files exist even without a JSON output;
|
|
135
|
+
built-ins keep their usual missing-output behavior. See
|
|
136
|
+
[Direct cases and files](#direct-cases-and-files).
|
|
137
|
+
|
|
121
138
|
### Hosted and manual scorer pins
|
|
122
139
|
|
|
123
140
|
Scorer deferral shipped in TypeScript `0.3.1`: the local runner executes only the three known built-in entries and bound `local_code` scorers. It leaves every other pin pending and reports its ID in `deferredScorerVersionIds`, including kinds and built-in entries introduced by a newer server. It never uploads a placeholder result that would occupy the immutable result slot, including placeholders already saved in an older SDK's checkpoint. Direct `scoreLocally()` calls reject pins that require another executor.
|
|
@@ -156,7 +173,7 @@ The runner stops scheduling more cases after an operational failure and waits fo
|
|
|
156
173
|
|
|
157
174
|
## Verification boundaries
|
|
158
175
|
|
|
159
|
-
`scripts/verify-package.mjs` installs a real packed tarball outside the monorepo and runs HTTP contract tests against a synthetic service plus actual OpenTelemetry exporters. It checks two configurations, rescoring without target invocation, absent/null output, upload resume, uncertain execution, exclusive checkpoints, source/metric contracts, content policy and terminating schema workers. It also exercises the local worker's ready, incomplete and uncertain provider-attempt control-plane paths, but does not call an issued provider facade. `scripts/verify-evaluation-api.mjs` is a separate opt-in acceptance against a real Hue receiver/API; it creates synthetic datasets/scorers/experiments in the project associated with the supplied development key.
|
|
176
|
+
`scripts/verify-package.mjs` installs a real packed tarball outside the monorepo and runs HTTP contract tests against a synthetic service plus actual OpenTelemetry exporters. It checks two configurations, rescoring without target invocation, absent/null output, upload resume, uncertain execution, exclusive checkpoints, source/metric contracts, content policy and terminating schema workers. It also exercises the local worker's ready, incomplete and uncertain provider-attempt control-plane paths, but does not call an issued provider facade. `scripts/verify-file-cases.mjs` runs against the same installed consumer: pinned input download and verification, artifact publication of a generated document, file-aware local scoring during the run and again on a later rescore, and a declared file the target could not deliver recorded as the target's own error. `scripts/verify-evaluation-api.mjs` is a separate opt-in acceptance against a real Hue receiver/API; it creates synthetic datasets/scorers/experiments in the project associated with the supplied development key.
|
|
160
177
|
|
|
161
178
|
## Outbound local agent worker
|
|
162
179
|
|
|
@@ -168,7 +185,9 @@ establish hosted provider availability.
|
|
|
168
185
|
`runLocalAgent` registers one fixed application callback and polls for queued runs. Hue selects
|
|
169
186
|
the registered key/revision; it does not send executable code or shell commands. Keep the
|
|
170
187
|
checkpoint directory private and durable. The worker persists result content and requires
|
|
171
|
-
acknowledged trace
|
|
188
|
+
acknowledged trace evidence; a case pinned to a world also requires sealed environment evidence.
|
|
189
|
+
A case without a world runs through `directTarget` instead, described in
|
|
190
|
+
[Direct cases and files](#direct-cases-and-files).
|
|
172
191
|
|
|
173
192
|
```ts
|
|
174
193
|
import { createHue } from "@hue-run/sdk";
|
|
@@ -218,3 +237,105 @@ the worker reports `attention` and stops; operator investigation is required. Su
|
|
|
218
237
|
automatically reclaimed, and presenting the same uncertain checkpoint again cannot replay the
|
|
219
238
|
candidate. Public package acceptance proves this lifecycle against local fixtures; exact
|
|
220
239
|
installed-registry-package to hosted-facade acceptance remains a post-publication Fern gate.
|
|
240
|
+
|
|
241
|
+
## Direct cases and files
|
|
242
|
+
|
|
243
|
+
Cases without a simulated world — document workflows whose inputs are a task plus pinned files —
|
|
244
|
+
run on the same runner under the same checkpoint rules. This is unreleased and ships in the next
|
|
245
|
+
`@hue-run/sdk` release. It requires a Hue deployment that serves case `inputFiles` on experiment
|
|
246
|
+
items, subject `files`, and the artifact reservation, upload, completion and download APIs. The
|
|
247
|
+
Python SDK has no equivalent.
|
|
248
|
+
|
|
249
|
+
On the outbound worker, supply `directTarget` beside or instead of `target`. Supplying
|
|
250
|
+
`directTarget` registers the `direct:v1` capability and supplying `target` registers
|
|
251
|
+
`environment:v1` (both strings are exported as `localAgentCapabilities`). Declare the file
|
|
252
|
+
capabilities the agent accepts and returns — `input:docx`, `input:pdf`, `output:docx` and so on — so
|
|
253
|
+
Hue matches them against each case's `hue.requiredCapabilities` metadata and offers only matching
|
|
254
|
+
cases. `registeredCapabilities` refuses a registration that names a capability without its callback.
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import { basename } from "node:path";
|
|
258
|
+
import { createEnvironmentClient } from "@hue-run/sdk/environment";
|
|
259
|
+
import { createEvaluationClient, runLocalAgent, withFiles } from "@hue-run/sdk/evals";
|
|
260
|
+
import { runMyAgent } from "./document-agent.js"; // Your existing application entry point.
|
|
261
|
+
import { letterGrader } from "./letter-grader.js"; // A defineLocalScorer binding.
|
|
262
|
+
|
|
263
|
+
await runLocalAgent({
|
|
264
|
+
client: createEvaluationClient(connection),
|
|
265
|
+
environmentClient: createEnvironmentClient(connection),
|
|
266
|
+
hue,
|
|
267
|
+
checkpointDirectory: ".hue-checkpoints/document-worker",
|
|
268
|
+
agent: {
|
|
269
|
+
key: "letter-agent",
|
|
270
|
+
name: "Letter agent",
|
|
271
|
+
revision: process.env.GIT_COMMIT!,
|
|
272
|
+
capabilities: ["input:docx", "input:pdf", "output:docx"], // direct:v1 is added for directTarget
|
|
273
|
+
},
|
|
274
|
+
scorers: [letterGrader], // Its callback reads context.files.
|
|
275
|
+
directTarget: async (inputs, { config, files, outputDirectory }) => {
|
|
276
|
+
// `files` are verified copies of the case's agent-visible input files on disk.
|
|
277
|
+
const { summary, documents } = await runMyAgent({ inputs, config, files, outputDirectory });
|
|
278
|
+
return withFiles(
|
|
279
|
+
{ summary },
|
|
280
|
+
documents.map((path, index) => ({
|
|
281
|
+
path,
|
|
282
|
+
filename: basename(path),
|
|
283
|
+
contentType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
284
|
+
primary: index === 0,
|
|
285
|
+
})),
|
|
286
|
+
);
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
The direct callback receives cloned inputs and an allowlisted context of `config`,
|
|
292
|
+
`item: {id, externalKey}`, `executionId`, `trace: {traceId,spanId}`, `files` and `outputDirectory`,
|
|
293
|
+
plus the worker's `signal` when one was supplied. Expected outcomes and case metadata stay with
|
|
294
|
+
grading, as they do for world cases.
|
|
295
|
+
|
|
296
|
+
Before an execution exists, `runExperiment` downloads every pinned input file named by the frozen
|
|
297
|
+
case's `inputFiles` and verifies byte count and SHA-256. A download failure is an SDK failure and
|
|
298
|
+
consumes no execution slot; a file already saved with the pinned identity is reused instead of
|
|
299
|
+
downloaded again. The target sees only the agent-visible roles — `source`, `attached_template`,
|
|
300
|
+
`attached_reference` and `original` — as `context.files`; evaluator-only
|
|
301
|
+
`org_template` and `evaluator_reference` files (an organization's template, a legal corpus, an
|
|
302
|
+
answer key) reach scorers but not the agent, and are not even downloaded when no bound code
|
|
303
|
+
evaluator runs in this process. Verified copies live under `filesDirectory` (default
|
|
304
|
+
`<checkpointDirectory>/files`, created mode 0700), and each case gets its own private
|
|
305
|
+
`context.outputDirectory` to write into.
|
|
306
|
+
|
|
307
|
+
Return generated documents by wrapping the output in `withFiles(output, files)`. Each entry names a
|
|
308
|
+
`path` or in-memory `bytes`, a `filename`, a Hue-accepted `contentType` and at most one `primary`.
|
|
309
|
+
The runner copies them next to its checkpoint, publishes them through the artifact reservation,
|
|
310
|
+
upload and verified completion APIs with stable per-execution keys, and completes the execution with
|
|
311
|
+
`artifactIds` and `primaryArtifactId`, so the subject's frozen manifest holds inputs and outputs
|
|
312
|
+
together. Generated files are always uploaded regardless of `persistResultContent`: they are the
|
|
313
|
+
execution's evidence. A declared file that cannot be read, exceeds 25 MiB, repeats a filename or has
|
|
314
|
+
an unsupported content type is saved as the target's error (`TargetError`), not as an uncertain
|
|
315
|
+
execution. A crash after the target finished resumes from the staged files without invoking the
|
|
316
|
+
target again; if result content is not persisted, the JSON output cannot be reconstructed and the
|
|
317
|
+
case is reported as uncertain.
|
|
318
|
+
|
|
319
|
+
`rescore` downloads a subject's frozen `files` — the pinned inputs and the generated outputs, with
|
|
320
|
+
`role: "output"` for the documents a run produced — so a code evaluator can grade saved documents
|
|
321
|
+
without invoking an agent. Local scorers receive them as `context.files` exactly as they do during
|
|
322
|
+
an experiment.
|
|
323
|
+
|
|
324
|
+
`runExperiment` and `rescore` accept `environmentEvidence: "required" | "when_pinned"`. A connected
|
|
325
|
+
worker that supplies `directTarget` uses `when_pinned`: direct cases never contact the environment
|
|
326
|
+
evidence endpoint, while cases pinned to a world still require sealed evidence. Use the same policy
|
|
327
|
+
for file-only regrading, and keep `required` for a generic target that attaches a world
|
|
328
|
+
independently of the case pin.
|
|
329
|
+
|
|
330
|
+
### Grading on Hue's side
|
|
331
|
+
|
|
332
|
+
By default a pinned `local_code` version without a matching local scorer refuses the run: nobody
|
|
333
|
+
would produce its result. `deferUnboundLocalScorers: true` changes that for both `runExperiment`
|
|
334
|
+
and `rescore`: unbound code-evaluator pins are reported in `deferredScorerVersionIds` and left to
|
|
335
|
+
the executor that owns their source, typically a grading worker Hue operates with its own provider
|
|
336
|
+
credentials. The customer's process then runs only the agent and uploads its documents; nothing
|
|
337
|
+
grader-related is installed there and evaluator-only files never reach it. The grading worker
|
|
338
|
+
calls `rescore` on the same run with the evaluator bound and the same option, so pins belonging to
|
|
339
|
+
other evaluators are left alone rather than refused. `EvaluationClient.listEvaluationRuns` pages
|
|
340
|
+
the project's runs so such a worker can find the ones that still owe it results. `hue eval` uses
|
|
341
|
+
this mode for eval sets whose cases pin no simulated world.
|
package/README.md
CHANGED
|
@@ -74,9 +74,15 @@ preflight checks availability and presents the published [privacy notice](https:
|
|
|
74
74
|
and [security information](https://trust.hue.run/) before telemetry. Anonymous trials last 24 hours
|
|
75
75
|
and are limited to 100 traces, 1,000 spans and 2 MiB. A private owner-only browser handoff supports
|
|
76
76
|
account linkage; the original request evidence is retained and business work is never replayed on
|
|
77
|
-
claim. Setup never enables content capture or creates a
|
|
77
|
+
claim. Setup never enables content capture or creates a simulation, Hue Run, evaluation, source capture
|
|
78
78
|
or remote execution. See the [setup CLI contract](./CLI.md) for the supported shapes and release gates.
|
|
79
79
|
|
|
80
|
+
For an existing account, `hue login` validates keys created in Hue Settings and stores them in
|
|
81
|
+
`.env.hue` without printing them, and `hue mcp install --client claude-code` (or `cursor`, `codex`,
|
|
82
|
+
`vscode`, `windsurf`, `gemini`) writes the Hue MCP configuration that references `HUE_MCP_KEY`. See
|
|
83
|
+
[Sign in and store keys](./CLI.md#sign-in-and-store-keys) and
|
|
84
|
+
[Install the MCP for your coding agent](./CLI.md#install-the-mcp-for-your-coding-agent).
|
|
85
|
+
|
|
80
86
|
`checkConnection()` rejects with `HueConnectionError`: its fixed message is safe to log, `status`
|
|
81
87
|
carries the HTTP status when Hue answered, and `cause` carries the underlying network, timeout or
|
|
82
88
|
parsing error. `serviceVersion` and `resourceAttributes` (for example
|
|
@@ -423,13 +429,32 @@ an uncertain preparation. See the
|
|
|
423
429
|
an issued facade endpoint or the official Gmail service, and do not claim universal provider
|
|
424
430
|
parity.
|
|
425
431
|
|
|
432
|
+
An unreleased `directTarget` callback extends the same worker to cases without a world: the runner
|
|
433
|
+
verifies the case's pinned input files, hands them to the agent, and uploads the documents it
|
|
434
|
+
returns as verified Hue artifacts for scoring. See
|
|
435
|
+
[direct cases and files](EVALUATIONS.md#direct-cases-and-files).
|
|
436
|
+
|
|
426
437
|
Scorer deferral shipped in TypeScript `0.3.1`. Only built-ins
|
|
427
438
|
and bound `local_code` callbacks run here; other pins remain pending for their authorized executor.
|
|
428
439
|
See [scorer execution](EVALUATIONS.md#hosted-and-manual-scorer-pins).
|
|
429
440
|
|
|
430
441
|
The published [setup CLI](CLI.md) is a resumable local inspection core; the unreleased `0.4.0`
|
|
431
442
|
candidate adds the bounded application onboarding flow described above. Existing customers connect
|
|
432
|
-
their agents with `runLocalAgent()`; setup does not register workers or launch
|
|
443
|
+
their agents with `runLocalAgent()`; setup does not register workers or launch simulations.
|
|
444
|
+
|
|
445
|
+
### Command-line evaluation
|
|
446
|
+
|
|
447
|
+
The unreleased `hue eval` command wraps `runSimulation()` and `runLocalAgent()` for an adapter
|
|
448
|
+
file or a shell command: `hue eval --scenario "<name>" ./hue-agent.ts` creates a fresh experiment
|
|
449
|
+
from a published Scenario's immutable pins, runs the agent in one isolated world per case, waits
|
|
450
|
+
for Hue's outcome checks and prints the run URL and per-case PASS/FAIL verdicts with an exit code;
|
|
451
|
+
`--worker` registers the same adapter for runs launched from Hue. It needs a Tracing and
|
|
452
|
+
evaluations key in `HUE_API_KEY` (never printed) and keeps content capture off unless `--content`
|
|
453
|
+
is passed. See [Evaluate an agent against a Scenario](CLI.md#evaluate-an-agent-against-a-scenario).
|
|
454
|
+
Eval sets whose cases pin files instead of a world run as direct cases through `runExperiment()`:
|
|
455
|
+
`hue eval --set <slug> --scorer <slug> --command "…"` hands the agent each case's pinned files in a
|
|
456
|
+
private directory, uploads the documents it writes and waits for Hue's grading executor to score
|
|
457
|
+
them. See [Evaluate a document eval set](CLI.md#evaluate-a-document-eval-set).
|
|
433
458
|
|
|
434
459
|
## Managed targets
|
|
435
460
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { LocalFile, TargetResult } from "../evals/types.js";
|
|
2
|
+
import type { JsonValue } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Direct (file) cases for `hue eval`: a case is a task plus pinned input files, and the agent's
|
|
5
|
+
* answer is one or more generated documents. The agent command receives a private case directory
|
|
6
|
+
* instead of stdin/stdout JSON, the same layout Hue's document workers use:
|
|
7
|
+
*
|
|
8
|
+
* <case dir>/inputs.json the case inputs
|
|
9
|
+
* <case dir>/case.json id, external key, run config and the staged file list
|
|
10
|
+
* <case dir>/files/<role>/<name> verified copies of the agent-visible pinned files
|
|
11
|
+
* <case dir>/output/ where the command writes what it produced
|
|
12
|
+
*
|
|
13
|
+
* Everything under `output/` becomes the execution's generated files. Optional helpers there:
|
|
14
|
+
* `manifest.json` (`{ "primary": "<filename>", "output": <json> }`), `result.json` (the JSON
|
|
15
|
+
* output) and `summary.txt` / `summary.md` (recorded as `{ "summary": "…" }`).
|
|
16
|
+
*/
|
|
17
|
+
export declare const directCaseEnvironment: readonly ["HUE_CASE_DIR", "HUE_CASE_INPUTS", "HUE_CASE_OUTPUT_DIR", "HUE_CASE_ID", "HUE_CASE_KEY", "HUE_EXECUTION_ID"];
|
|
18
|
+
/** Generated-file extensions Hue accepts and the content type recorded for each. */
|
|
19
|
+
export declare const outputExtensions: Readonly<Record<string, string>>;
|
|
20
|
+
export interface DirectCaseLayout {
|
|
21
|
+
caseDirectory: string;
|
|
22
|
+
inputsPath: string;
|
|
23
|
+
outputDirectory: string;
|
|
24
|
+
files: {
|
|
25
|
+
role: string;
|
|
26
|
+
filename: string;
|
|
27
|
+
path: string;
|
|
28
|
+
}[];
|
|
29
|
+
}
|
|
30
|
+
/** Writes the case directory: inputs, descriptor, verified file copies and an empty output folder. */
|
|
31
|
+
export declare function stageDirectCase(root: string, input: {
|
|
32
|
+
inputs: JsonValue;
|
|
33
|
+
config: JsonValue;
|
|
34
|
+
item: {
|
|
35
|
+
id: string;
|
|
36
|
+
externalKey: string;
|
|
37
|
+
};
|
|
38
|
+
executionId: string;
|
|
39
|
+
files: LocalFile[];
|
|
40
|
+
}): Promise<DirectCaseLayout>;
|
|
41
|
+
/**
|
|
42
|
+
* Turns the output folder into the target's result. Every regular file, in subdirectories too,
|
|
43
|
+
* becomes a generated file; an unsupported extension is the agent's error rather than a silently
|
|
44
|
+
* dropped document. `fallbackOutput` (for example the command's stdout) is used when no JSON
|
|
45
|
+
* output or summary file was written.
|
|
46
|
+
*/
|
|
47
|
+
export declare function collectDirectOutputs(outputDirectory: string, fallbackOutput?: JsonValue): Promise<TargetResult>;
|