@hue-run/sdk 0.5.1 → 0.6.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 +14 -12
- package/ENVIRONMENTS.md +1 -1
- package/EVALUATIONS.md +19 -0
- package/README.md +3 -3
- package/dist/cli/eval.js +11 -8
- package/dist/cli/login.js +1 -1
- package/dist/evals/client.d.ts +98 -1
- package/dist/evals/client.js +195 -0
- package/dist/evals/types.d.ts +77 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CLI.md
CHANGED
|
@@ -42,7 +42,7 @@ 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.
|
|
45
|
+
not a completed integration. TypeScript uses `@hue-run/sdk@0.6.0`, `@opentelemetry/api@1.9.1` and
|
|
46
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
|
|
|
@@ -300,7 +300,7 @@ node packages/sdk-typescript/scripts/verify-package.mjs --artifacts-dir .artifac
|
|
|
300
300
|
# Set project to an existing supported fixture; use the same directory on resume.
|
|
301
301
|
project=/absolute/path/to/supported-fixture
|
|
302
302
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
303
|
-
--archive .artifacts/typescript/hue-run-sdk-0.
|
|
303
|
+
--archive .artifacts/typescript/hue-run-sdk-0.6.0.tgz \
|
|
304
304
|
--origin https://STAGING_ORIGIN \
|
|
305
305
|
--project "$project" --command setup \
|
|
306
306
|
--evidence .context/setup-staging-before-claim.json
|
|
@@ -311,7 +311,7 @@ the private local handoff and finish the real browser claim, then reconcile the
|
|
|
311
311
|
|
|
312
312
|
```sh
|
|
313
313
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
314
|
-
--archive .artifacts/typescript/hue-run-sdk-0.
|
|
314
|
+
--archive .artifacts/typescript/hue-run-sdk-0.6.0.tgz \
|
|
315
315
|
--origin https://STAGING_ORIGIN \
|
|
316
316
|
--project "$project" --command claim \
|
|
317
317
|
--evidence .context/setup-staging-after-claim.json
|
|
@@ -333,14 +333,14 @@ Publication under a candidate dist-tag, registry acceptance, production activati
|
|
|
333
333
|
the same version to `latest`, and clean-project literal `@latest` smoke remain separate gates; see
|
|
334
334
|
[RELEASING.md](../../RELEASING.md).
|
|
335
335
|
|
|
336
|
-
## Evaluate an agent against a
|
|
336
|
+
## Evaluate an agent against a case
|
|
337
337
|
|
|
338
|
-
`hue eval` runs a developer's local agent against a published Hue
|
|
338
|
+
`hue eval` runs a developer's local agent against a published Hue case or a saved eval set
|
|
339
339
|
and prints Hue's verdicts. It is the command-line form of `runSimulation()` (one-shot) and
|
|
340
340
|
`runLocalAgent()` (worker): the agent, its prompts and its provider credentials stay in the local
|
|
341
341
|
process, Hue creates one isolated simulated world per case, and Hue-owned outcome checks grade
|
|
342
342
|
the sealed world. Hue never executes the agent. `HUE_API_KEY` must be a **Read and
|
|
343
|
-
write** project key (a **Read** or **Tracing only** key cannot read
|
|
343
|
+
write** project key (a **Read** or **Tracing only** key cannot read cases or create runs);
|
|
344
344
|
the CLI never prints it. The optional `zod` peer of `@hue-run/sdk/evals` must be installed.
|
|
345
345
|
|
|
346
346
|
Write an adapter module that hands the case inputs and the world's tools or MCP connection to
|
|
@@ -362,16 +362,18 @@ export default function runMyAgent(inputs: JsonValue, context: SimulationTargetC
|
|
|
362
362
|
```
|
|
363
363
|
|
|
364
364
|
```sh
|
|
365
|
-
hue eval --
|
|
366
|
-
hue eval --
|
|
365
|
+
hue eval --case "Refund an eligible charge" ./hue-agent.ts --env-file .env.hue
|
|
366
|
+
hue eval --case https://app.hue.run/projects/demo/scenarios/<id> ./hue-agent.ts --baseline <run id>
|
|
367
367
|
hue eval --set "Billing regressions" --scorer-version <id> ./hue-agent.ts --save-version
|
|
368
|
-
hue eval --
|
|
368
|
+
hue eval --case "Refund an eligible charge" --command "python agent.py" --timeout 120 --content
|
|
369
369
|
hue eval --worker ./hue-agent.ts --agent-key support-agent --env-file .env.hue
|
|
370
370
|
```
|
|
371
371
|
|
|
372
|
-
|
|
372
|
+
`--scenario` remains an alias for `--case` for existing scripts. Pass one selection flag.
|
|
373
|
+
|
|
374
|
+
The one-shot mode resolves the selection (`--case` by name, ID or URL; `--set` by name, ID or
|
|
373
375
|
URL with explicit `--scorer-version` pins; or `--dataset-version` with `--scorer-version`),
|
|
374
|
-
creates a fresh
|
|
376
|
+
creates a fresh run from those immutable pins named `<case> · <agent key> · <revision>`
|
|
375
377
|
(`--name` overrides), prints `Run: <url>` and `Experiment: <id>` as soon as the experiment exists,
|
|
376
378
|
one line per case event (world created, agent started, world sealed), then
|
|
377
379
|
`Waiting for Hue checks...` and a table with one row per case: boolean metrics as `PASS`/`FAIL`,
|
|
@@ -421,7 +423,7 @@ on any Node.js version.
|
|
|
421
423
|
|
|
422
424
|
Eval sets whose cases pin no simulated world — a task plus pinned input files, answered with
|
|
423
425
|
generated documents — run as **direct** cases through `runExperiment()`. `hue eval` detects this
|
|
424
|
-
from the saved version (`--mode direct|simulation` overrides the detection; `--
|
|
426
|
+
from the saved version (`--mode direct|simulation` overrides the detection; `--case` is always
|
|
425
427
|
a simulation). `--set` accepts the eval set's slug, name, ID or URL; `--set-version <n>` pins a
|
|
426
428
|
saved version other than the latest; `--scorer <slug|name|id>` pins an evaluator at its newest
|
|
427
429
|
published version, beside or instead of explicit `--scorer-version` IDs.
|
package/ENVIRONMENTS.md
CHANGED
|
@@ -79,7 +79,7 @@ until every item has a terminal result for every pin or the budget elapses (`com
|
|
|
79
79
|
`summarizeVerdicts` turns results into per-case rows with `passed` and totals; `compareVerdicts`
|
|
80
80
|
diffs two summaries by case key; and `collectExperimentVerdicts` combines those reads for one
|
|
81
81
|
experiment. The `hue eval` command uses the same path; see
|
|
82
|
-
[Evaluate an agent against a
|
|
82
|
+
[Evaluate an agent against a case](CLI.md#evaluate-an-agent-against-a-case).
|
|
83
83
|
|
|
84
84
|
### Pinned provider-profile preflight
|
|
85
85
|
|
package/EVALUATIONS.md
CHANGED
|
@@ -70,6 +70,25 @@ try {
|
|
|
70
70
|
}
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
For new registry code, use `createEvalSet`, `getEvalSet`, `listEvalSets`,
|
|
74
|
+
`createEvalSetVersion`, `getEvalSetVersion`, `listEvalSetCases`, `addEvalSetCase`,
|
|
75
|
+
and `freezeEvalSetVersion`. Evaluators use `createEvaluator`, `getEvaluator`,
|
|
76
|
+
`listEvaluators`, `publishEvaluatorVersion`, and `getEvaluatorVersion`. These
|
|
77
|
+
methods return product fields such as `evalSetId` and `evalSetVersionId` alongside
|
|
78
|
+
the existing v1 fields. Evaluator versions include `evaluatorId` when the server
|
|
79
|
+
supplies their owning identity; older v1 responses may omit it. They use the existing v1 paths;
|
|
80
|
+
the earlier method names remain callable for existing integrations.
|
|
81
|
+
|
|
82
|
+
For new run and scoring code, use `createRun`, `getRun`, `listRunItems`,
|
|
83
|
+
`getRunCase`, `startRunExecution`, `getRunExecution`,
|
|
84
|
+
`completeRunExecution`, and `finishRun`. Use `createScoring`, `getScoring`,
|
|
85
|
+
`listScorings`, `listScoringItems`, `getScoringSubject`,
|
|
86
|
+
`submitScoringResults`, `listScoringResults`, and `getScoringResult` to score
|
|
87
|
+
saved subjects. `createRun` accepts `evalSetVersionId` and
|
|
88
|
+
`evaluatorVersionIds`; `createScoring` and `submitScoringResults` use evaluator
|
|
89
|
+
version IDs. A run ID and a scoring ID identify different records. The methods
|
|
90
|
+
use the existing v1 paths and leave existing runner entry points callable.
|
|
91
|
+
|
|
73
92
|
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
93
|
|
|
75
94
|
`rescore` preserves terminal scores already recorded for each item and evaluator version,
|
package/README.md
CHANGED
|
@@ -445,12 +445,12 @@ their agents with `runLocalAgent()`; setup does not register workers or launch s
|
|
|
445
445
|
### Command-line evaluation
|
|
446
446
|
|
|
447
447
|
The unreleased `hue eval` command wraps `runSimulation()` and `runLocalAgent()` for an adapter
|
|
448
|
-
file or a shell command: `hue eval --
|
|
449
|
-
from a published
|
|
448
|
+
file or a shell command: `hue eval --case "<name>" ./hue-agent.ts` creates a fresh run
|
|
449
|
+
from a published case's immutable pins, runs the agent in one isolated world per case, waits
|
|
450
450
|
for Hue's outcome checks and prints the run URL and per-case PASS/FAIL verdicts with an exit code;
|
|
451
451
|
`--worker` registers the same adapter for runs launched from Hue. It needs a Read and
|
|
452
452
|
write key in `HUE_API_KEY` (never printed) and keeps content capture off unless `--content`
|
|
453
|
-
is passed. See [Evaluate an agent against a
|
|
453
|
+
is passed. See [Evaluate an agent against a case](CLI.md#evaluate-an-agent-against-a-case).
|
|
454
454
|
Eval sets whose cases pin files instead of a world run as direct cases through `runExperiment()`:
|
|
455
455
|
`hue eval --set <slug> --scorer <slug> --command "…"` hands the agent each case's pinned files in a
|
|
456
456
|
private directory, uploads the documents it writes and waits for Hue's grading executor to score
|
package/dist/cli/eval.js
CHANGED
|
@@ -18,10 +18,11 @@ import { runSimulation, } from "../evals/simulation.js";
|
|
|
18
18
|
import { collectExperimentVerdicts, compareVerdicts, metricPassed, } from "../evals/verdicts.js";
|
|
19
19
|
const USAGE = `Usage: hue eval [adapter-file] [options]
|
|
20
20
|
|
|
21
|
-
Run a local agent against a
|
|
21
|
+
Run a local agent against a published case or eval set, then print Hue's verdicts.
|
|
22
22
|
|
|
23
23
|
Selection (exactly one, not used with --worker):
|
|
24
|
-
--
|
|
24
|
+
--case <name|id|url> Published case to run
|
|
25
|
+
--scenario <name|id|url> Legacy alias for --case
|
|
25
26
|
--set <name|id|url> Saved eval set; requires --scorer or --scorer-version
|
|
26
27
|
--set-version <n> Saved version number of the eval set (default: latest saved)
|
|
27
28
|
--dataset-version <id> Frozen dataset version; requires --scorer or --scorer-version
|
|
@@ -51,7 +52,7 @@ Connection:
|
|
|
51
52
|
--origin <url> Hue origin (default: HUE_BASE_URL or https://app.hue.run)
|
|
52
53
|
|
|
53
54
|
Output and limits:
|
|
54
|
-
--name <run name>
|
|
55
|
+
--name <run name> Run name (default: <case> · <agent key> · <revision>)
|
|
55
56
|
--baseline <experiment id|url> Compare verdicts with a previous experiment
|
|
56
57
|
--json Print one JSON document on stdout; progress goes to stderr
|
|
57
58
|
--content Capture telemetry content; one-shot also persists
|
|
@@ -82,6 +83,7 @@ function parse(argv) {
|
|
|
82
83
|
allowPositionals: true,
|
|
83
84
|
strict: true,
|
|
84
85
|
options: {
|
|
86
|
+
case: { type: "string" },
|
|
85
87
|
scenario: { type: "string" },
|
|
86
88
|
set: { type: "string" },
|
|
87
89
|
"set-version": { type: "string" },
|
|
@@ -508,15 +510,16 @@ async function resolveSelection(client, values) {
|
|
|
508
510
|
const extra = [...(values["scorer-version"] ?? [])];
|
|
509
511
|
for (const selector of values.scorer ?? [])
|
|
510
512
|
extra.push(await resolveScorerVersion(client, selector));
|
|
511
|
-
|
|
513
|
+
const caseSelector = values.case ?? values.scenario;
|
|
514
|
+
if (caseSelector) {
|
|
512
515
|
if (values["set-version"])
|
|
513
516
|
throw new UsageError("--set-version applies to --set only");
|
|
514
|
-
const pins = await resolveScenarioPins(client,
|
|
517
|
+
const pins = await resolveScenarioPins(client, caseSelector);
|
|
515
518
|
pins.scorerVersionIds = [...new Set([...pins.scorerVersionIds, ...extra])];
|
|
516
519
|
return pins;
|
|
517
520
|
}
|
|
518
521
|
if (!extra.length)
|
|
519
|
-
throw new UsageError(`${values.set ? "--set" : "--dataset-version"} needs at least one --scorer or --scorer-version; use --
|
|
522
|
+
throw new UsageError(`${values.set ? "--set" : "--dataset-version"} needs at least one --scorer or --scorer-version; use --case for published pins`);
|
|
520
523
|
if (values.set) {
|
|
521
524
|
const pins = await resolveEvalSetPins(client, values.set, { scorerVersionIds: extra });
|
|
522
525
|
if (values["set-version"] === undefined)
|
|
@@ -918,11 +921,11 @@ export async function runEvalCommand(argv) {
|
|
|
918
921
|
const adapterFile = positionals[0];
|
|
919
922
|
if ((adapterFile ? 1 : 0) + (values.command ? 1 : 0) !== 1)
|
|
920
923
|
throw new UsageError("Pass exactly one agent: an adapter file or --command");
|
|
921
|
-
const selections = [values.scenario, values.set, values["dataset-version"]].filter((value) => value !== undefined).length;
|
|
924
|
+
const selections = [values.case, values.scenario, values.set, values["dataset-version"]].filter((value) => value !== undefined).length;
|
|
922
925
|
if (values.worker && selections)
|
|
923
926
|
throw new UsageError("--worker takes no selection; Hue chooses the run to execute");
|
|
924
927
|
if (!values.worker && selections !== 1)
|
|
925
|
-
throw new UsageError("Pass exactly one of --
|
|
928
|
+
throw new UsageError("Pass exactly one of --case, --set or --dataset-version");
|
|
926
929
|
if (values["env-file"]) {
|
|
927
930
|
try {
|
|
928
931
|
process.loadEnvFile(resolve(values["env-file"]));
|
package/dist/cli/login.js
CHANGED
|
@@ -739,6 +739,6 @@ export async function runLoginCommand(argv, io = {}) {
|
|
|
739
739
|
// `hue mcp install` defaults to production; a non-default origin needs its own endpoint.
|
|
740
740
|
out(` hue mcp install --client claude-code${mcpUrl === mcpUrlForOrigin(DEFAULT_ORIGIN) ? "" : ` --url ${mcpUrl}`}`);
|
|
741
741
|
if (stored.includes("evaluations"))
|
|
742
|
-
out(` hue eval --
|
|
742
|
+
out(` hue eval --case "<name>" ./hue-agent.ts --env-file ${envDisplay}`);
|
|
743
743
|
return 0;
|
|
744
744
|
}
|
package/dist/evals/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ProjectConnection } from "../types.js";
|
|
2
2
|
import { type AttemptConnectionBundleV2, type PrepareAttemptRequestV2 } from "./attempt.js";
|
|
3
|
-
import type { ArtifactReservation, ArtifactUpload, CaseConversion, CaseConversionSummary, CaseWrite, CompleteExecution, Completion, Dataset, DatasetCase, DatasetVersion, EvaluationItem, EvaluationRun, EvaluationRunSummary, EnvironmentEvidenceSnapshot, Execution, Experiment, ExperimentCase, ExperimentItem, Identity, JsonValue, LocalAgentClaim, LocalAgentRegistration, RegisteredLocalAgent, JudgeBudget, JudgeJob, Page, PageOptions, RegistryPageOptions, Result, ResultSummary, Scorer, ScorerDefinition, ScorerVersion, SimulationMcpCapability, StartExecution, Subject, StoredResult } from "./types.js";
|
|
3
|
+
import type { ArtifactReservation, ArtifactUpload, CaseConversion, CaseConversionSummary, CaseWrite, CompleteExecution, Completion, Dataset, DatasetCase, DatasetVersion, EvalSet, EvalSetCase, EvalSetVersion, EvaluationItem, EvaluationRun, EvaluationRunSummary, EnvironmentEvidenceSnapshot, Execution, Experiment, ExperimentCase, ExperimentItem, Evaluator, EvaluatorVersion, Identity, JsonValue, LocalAgentClaim, LocalAgentRegistration, RegisteredLocalAgent, JudgeBudget, JudgeJob, Page, PageOptions, RegistryPageOptions, Result, ResultSummary, Run, RunCase, Scorer, ScorerDefinition, ScorerVersion, Scoring, ScoringResultInput, ScoringResultSummary, ScoringSubject, ScoringSummary, SimulationMcpCapability, StartExecution, Subject, StoredResult, StoredScoringResult } from "./types.js";
|
|
4
4
|
/** Connection options for {@link createEvaluationClient}. */
|
|
5
5
|
export interface EvaluationClientOptions {
|
|
6
6
|
/** Project service key sent as a Bearer token; server side only. */
|
|
@@ -71,6 +71,39 @@ export declare class EvaluationClient {
|
|
|
71
71
|
publishScorerVersion(id: string, definition: ScorerDefinition): Promise<ScorerVersion>;
|
|
72
72
|
/** Reads a published scorer version. */
|
|
73
73
|
getScorerVersion(id: string): Promise<ScorerVersion>;
|
|
74
|
+
/** Creates an eval set using the existing v1 registry path. */
|
|
75
|
+
createEvalSet(input: Identity): Promise<EvalSet>;
|
|
76
|
+
/** Reads an eval set and its versions. */
|
|
77
|
+
getEvalSet(id: string): Promise<EvalSet>;
|
|
78
|
+
/** Lists eval sets. */
|
|
79
|
+
listEvalSets(page?: RegistryPageOptions): Promise<Page<Omit<EvalSet, "versions">>>;
|
|
80
|
+
/** Creates a draft eval set version, optionally copying cases from another version. */
|
|
81
|
+
createEvalSetVersion(id: string, input?: {
|
|
82
|
+
fromVersionId?: string;
|
|
83
|
+
}): Promise<EvalSetVersion>;
|
|
84
|
+
/** Reads an eval set version. */
|
|
85
|
+
getEvalSetVersion(id: string): Promise<EvalSetVersion>;
|
|
86
|
+
/** Lists cases in an eval set version. */
|
|
87
|
+
listEvalSetCases(id: string, page?: PageOptions): Promise<Page<EvalSetCase>>;
|
|
88
|
+
/** Adds a case to a draft eval set version at its expected revision. */
|
|
89
|
+
addEvalSetCase(id: string, input: CaseWrite): Promise<{
|
|
90
|
+
/** The stored case. */
|
|
91
|
+
item: EvalSetCase;
|
|
92
|
+
/** The version with its new revision. */
|
|
93
|
+
version: EvalSetVersion;
|
|
94
|
+
}>;
|
|
95
|
+
/** Freezes a draft eval set version at its expected revision. */
|
|
96
|
+
freezeEvalSetVersion(id: string, expectedRevision: number): Promise<EvalSetVersion>;
|
|
97
|
+
/** Creates an evaluator identity. */
|
|
98
|
+
createEvaluator(input: Identity): Promise<Evaluator>;
|
|
99
|
+
/** Reads an evaluator and its published versions. */
|
|
100
|
+
getEvaluator(id: string): Promise<Evaluator>;
|
|
101
|
+
/** Lists evaluators. */
|
|
102
|
+
listEvaluators(page?: RegistryPageOptions): Promise<Page<Evaluator>>;
|
|
103
|
+
/** Publishes an immutable evaluator version. */
|
|
104
|
+
publishEvaluatorVersion(id: string, definition: ScorerDefinition): Promise<EvaluatorVersion>;
|
|
105
|
+
/** Reads a published evaluator version. */
|
|
106
|
+
getEvaluatorVersion(id: string): Promise<EvaluatorVersion>;
|
|
74
107
|
/** Creates an experiment over a frozen dataset version with pinned scorer versions and a configuration. */
|
|
75
108
|
createExperiment(input: {
|
|
76
109
|
idempotencyKey: string;
|
|
@@ -175,6 +208,70 @@ export declare class EvaluationClient {
|
|
|
175
208
|
listResults(id: string, page?: PageOptions): Promise<Page<ResultSummary>>;
|
|
176
209
|
/** Reads a full stored result. */
|
|
177
210
|
getResult(id: string): Promise<StoredResult>;
|
|
211
|
+
/** Creates a run using product request fields on the existing v1 path. */
|
|
212
|
+
createRun(input: {
|
|
213
|
+
idempotencyKey: string;
|
|
214
|
+
name: string;
|
|
215
|
+
evalSetVersionId: string;
|
|
216
|
+
evaluatorVersionIds: string[];
|
|
217
|
+
config: JsonValue;
|
|
218
|
+
}): Promise<{
|
|
219
|
+
/** Run ID. */
|
|
220
|
+
id: string;
|
|
221
|
+
/** ID of the run's scoring pass. */
|
|
222
|
+
scoringId: string;
|
|
223
|
+
/** Existing v1 field for the scoring pass ID. */
|
|
224
|
+
evaluationRunId: string;
|
|
225
|
+
}>;
|
|
226
|
+
/** Reads a run with its scoring progress. */
|
|
227
|
+
getRun(id: string): Promise<Run>;
|
|
228
|
+
/** Lists a run's cases with their latest executions. */
|
|
229
|
+
listRunItems(id: string, page?: PageOptions): Promise<Page<ExperimentItem>>;
|
|
230
|
+
/** Reads one frozen case of a run. */
|
|
231
|
+
getRunCase(id: string, caseId: string): Promise<RunCase>;
|
|
232
|
+
/** Starts or replays a target execution for a run case. */
|
|
233
|
+
startRunExecution(id: string, caseId: string, input: StartExecution): Promise<Execution>;
|
|
234
|
+
/** Reads one run execution. */
|
|
235
|
+
getRunExecution(id: string): Promise<Execution>;
|
|
236
|
+
/** Saves a run execution's outcome. */
|
|
237
|
+
completeRunExecution(id: string, input: CompleteExecution): Promise<Completion>;
|
|
238
|
+
/** Marks a run finished. */
|
|
239
|
+
finishRun(id: string, idempotencyKey: string): Promise<{
|
|
240
|
+
/** Run ID. */
|
|
241
|
+
id: string;
|
|
242
|
+
/** When the run finished. */
|
|
243
|
+
finishedAt: string;
|
|
244
|
+
}>;
|
|
245
|
+
/** Creates a standalone scoring pass over saved subjects. */
|
|
246
|
+
createScoring(input: {
|
|
247
|
+
idempotencyKey: string;
|
|
248
|
+
name: string;
|
|
249
|
+
subjectIds: string[];
|
|
250
|
+
evaluatorVersionIds: string[];
|
|
251
|
+
}): Promise<{
|
|
252
|
+
/** Scoring pass ID. */
|
|
253
|
+
id: string;
|
|
254
|
+
}>;
|
|
255
|
+
/** Reads a scoring pass and its pinned evaluators. */
|
|
256
|
+
getScoring(id: string): Promise<Scoring>;
|
|
257
|
+
/** Lists scoring passes in the project. */
|
|
258
|
+
listScorings(page?: PageOptions): Promise<Page<ScoringSummary>>;
|
|
259
|
+
/** Lists the subjects of a scoring pass. */
|
|
260
|
+
listScoringItems(id: string, page?: PageOptions): Promise<Page<EvaluationItem>>;
|
|
261
|
+
/** Reads a saved subject with product-named source fields. */
|
|
262
|
+
getScoringSubject(id: string): Promise<ScoringSubject>;
|
|
263
|
+
/** Uploads evaluator results for a scoring pass using product request fields. */
|
|
264
|
+
submitScoringResults(id: string, input: {
|
|
265
|
+
idempotencyKey: string;
|
|
266
|
+
results: ScoringResultInput[];
|
|
267
|
+
}): Promise<{
|
|
268
|
+
/** Stored result IDs, in input order. */
|
|
269
|
+
ids: string[];
|
|
270
|
+
}>;
|
|
271
|
+
/** Lists result summaries for a scoring pass. */
|
|
272
|
+
listScoringResults(id: string, page?: PageOptions): Promise<Page<ScoringResultSummary>>;
|
|
273
|
+
/** Reads a stored evaluator result. */
|
|
274
|
+
getScoringResult(id: string): Promise<StoredScoringResult>;
|
|
178
275
|
/** Dispatches hosted judge jobs for `llm_judge` pins; check {@link getJudgeBudget} first. */
|
|
179
276
|
createJudgeJobs(id: string, input: {
|
|
180
277
|
idempotencyKey: string;
|
package/dist/evals/client.js
CHANGED
|
@@ -12,6 +12,85 @@ export class HueApiError extends Error {
|
|
|
12
12
|
this.name = "HueApiError";
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
+
const registryFieldAliases = [
|
|
16
|
+
["datasetId", "evalSetId"],
|
|
17
|
+
["datasetVersionId", "evalSetVersionId"],
|
|
18
|
+
["scorerId", "evaluatorId"],
|
|
19
|
+
["scorerVersionId", "evaluatorVersionId"],
|
|
20
|
+
];
|
|
21
|
+
const registryEnvelopes = new Set(["items", "item", "versions", "version"]);
|
|
22
|
+
// Only Hue response envelopes are traversed. Case inputs, metadata, and evaluator
|
|
23
|
+
// definitions are customer JSON and must retain their original field names.
|
|
24
|
+
function productRegistryFields(value) {
|
|
25
|
+
if (Array.isArray(value))
|
|
26
|
+
return value.map((item) => productRegistryFields(item));
|
|
27
|
+
if (value === null || typeof value !== "object")
|
|
28
|
+
return value;
|
|
29
|
+
const result = { ...value };
|
|
30
|
+
for (const key of registryEnvelopes) {
|
|
31
|
+
if (Object.hasOwn(result, key))
|
|
32
|
+
result[key] = productRegistryFields(result[key]);
|
|
33
|
+
}
|
|
34
|
+
for (const [legacy, product] of registryFieldAliases) {
|
|
35
|
+
if (Object.hasOwn(result, legacy)) {
|
|
36
|
+
if (Object.hasOwn(result, product) && result[legacy] !== result[product])
|
|
37
|
+
throw new HueApiError();
|
|
38
|
+
result[product] = result[legacy];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
const runResponseAliases = [
|
|
44
|
+
["datasetId", "evalSetId"],
|
|
45
|
+
["datasetName", "evalSetName"],
|
|
46
|
+
["datasetDisplayName", "evalSetDisplayName"],
|
|
47
|
+
["datasetVersion", "evalSetVersion"],
|
|
48
|
+
["datasetVersionId", "evalSetVersionId"],
|
|
49
|
+
["datasetVersionIds", "evalSetVersionIds"],
|
|
50
|
+
["scorerId", "evaluatorId"],
|
|
51
|
+
["scorerName", "evaluatorName"],
|
|
52
|
+
["scorerVersion", "evaluatorVersion"],
|
|
53
|
+
["scorerVersionId", "evaluatorVersionId"],
|
|
54
|
+
["scorerVersionIds", "evaluatorVersionIds"],
|
|
55
|
+
["scorerVersions", "evaluatorVersions"],
|
|
56
|
+
["evaluationRunId", "scoringId"],
|
|
57
|
+
];
|
|
58
|
+
const runResponseEnvelopes = new Set([
|
|
59
|
+
"items",
|
|
60
|
+
"item",
|
|
61
|
+
"versions",
|
|
62
|
+
"version",
|
|
63
|
+
"scorerVersions",
|
|
64
|
+
"evaluatorVersions",
|
|
65
|
+
]);
|
|
66
|
+
function productRunFields(value, kind) {
|
|
67
|
+
if (Array.isArray(value))
|
|
68
|
+
return value.map((item) => productRunFields(item, kind));
|
|
69
|
+
if (value === null || typeof value !== "object")
|
|
70
|
+
return value;
|
|
71
|
+
const result = { ...value };
|
|
72
|
+
for (const key of runResponseEnvelopes) {
|
|
73
|
+
if (Object.hasOwn(result, key))
|
|
74
|
+
result[key] = productRunFields(result[key], kind);
|
|
75
|
+
}
|
|
76
|
+
for (const key of ["evaluation", "scoring"]) {
|
|
77
|
+
if (Object.hasOwn(result, key))
|
|
78
|
+
result[key] = productRunFields(result[key], "scoring");
|
|
79
|
+
}
|
|
80
|
+
const identityAlias = kind === "result" ? ["runId", "scoringId"] : ["experimentId", "runId"];
|
|
81
|
+
const aliases = [...runResponseAliases, identityAlias];
|
|
82
|
+
for (const [legacy, product] of aliases) {
|
|
83
|
+
if (Object.hasOwn(result, legacy)) {
|
|
84
|
+
if (Object.hasOwn(result, product) &&
|
|
85
|
+
JSON.stringify(result[legacy]) !== JSON.stringify(result[product]))
|
|
86
|
+
throw new HueApiError();
|
|
87
|
+
result[product] = result[legacy];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (Object.hasOwn(result, "evaluation") && !Object.hasOwn(result, "scoring"))
|
|
91
|
+
result.scoring = result.evaluation;
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
15
94
|
/**
|
|
16
95
|
* Typed client for Hue's evaluation REST API: datasets, scorers, experiments, executions, runs,
|
|
17
96
|
* results and hosted judge jobs. No implicit mutation retry: callers retain stable idempotency keys
|
|
@@ -225,6 +304,58 @@ export class EvaluationClient {
|
|
|
225
304
|
getScorerVersion(id) {
|
|
226
305
|
return this.request("GET", `/scorer-versions/${uuid(id)}`);
|
|
227
306
|
}
|
|
307
|
+
/** Creates an eval set using the existing v1 registry path. */
|
|
308
|
+
async createEvalSet(input) {
|
|
309
|
+
return productRegistryFields(await this.createDataset(input));
|
|
310
|
+
}
|
|
311
|
+
/** Reads an eval set and its versions. */
|
|
312
|
+
async getEvalSet(id) {
|
|
313
|
+
return productRegistryFields(await this.getDataset(id));
|
|
314
|
+
}
|
|
315
|
+
/** Lists eval sets. */
|
|
316
|
+
async listEvalSets(page) {
|
|
317
|
+
return productRegistryFields(await this.listDatasets(page));
|
|
318
|
+
}
|
|
319
|
+
/** Creates a draft eval set version, optionally copying cases from another version. */
|
|
320
|
+
async createEvalSetVersion(id, input = {}) {
|
|
321
|
+
return productRegistryFields(await this.createDatasetVersion(id, input));
|
|
322
|
+
}
|
|
323
|
+
/** Reads an eval set version. */
|
|
324
|
+
async getEvalSetVersion(id) {
|
|
325
|
+
return productRegistryFields(await this.getDatasetVersion(id));
|
|
326
|
+
}
|
|
327
|
+
/** Lists cases in an eval set version. */
|
|
328
|
+
async listEvalSetCases(id, page) {
|
|
329
|
+
return productRegistryFields(await this.listCases(id, page));
|
|
330
|
+
}
|
|
331
|
+
/** Adds a case to a draft eval set version at its expected revision. */
|
|
332
|
+
async addEvalSetCase(id, input) {
|
|
333
|
+
return productRegistryFields(await this.addCase(id, input));
|
|
334
|
+
}
|
|
335
|
+
/** Freezes a draft eval set version at its expected revision. */
|
|
336
|
+
async freezeEvalSetVersion(id, expectedRevision) {
|
|
337
|
+
return productRegistryFields(await this.freezeDatasetVersion(id, expectedRevision));
|
|
338
|
+
}
|
|
339
|
+
/** Creates an evaluator identity. */
|
|
340
|
+
async createEvaluator(input) {
|
|
341
|
+
return productRegistryFields(await this.createScorer(input));
|
|
342
|
+
}
|
|
343
|
+
/** Reads an evaluator and its published versions. */
|
|
344
|
+
async getEvaluator(id) {
|
|
345
|
+
return productRegistryFields(await this.getScorer(id));
|
|
346
|
+
}
|
|
347
|
+
/** Lists evaluators. */
|
|
348
|
+
async listEvaluators(page) {
|
|
349
|
+
return productRegistryFields(await this.listScorers(page));
|
|
350
|
+
}
|
|
351
|
+
/** Publishes an immutable evaluator version. */
|
|
352
|
+
async publishEvaluatorVersion(id, definition) {
|
|
353
|
+
return productRegistryFields(await this.publishScorerVersion(id, definition));
|
|
354
|
+
}
|
|
355
|
+
/** Reads a published evaluator version. */
|
|
356
|
+
async getEvaluatorVersion(id) {
|
|
357
|
+
return productRegistryFields(await this.getScorerVersion(id));
|
|
358
|
+
}
|
|
228
359
|
/** Creates an experiment over a frozen dataset version with pinned scorer versions and a configuration. */
|
|
229
360
|
createExperiment(input) {
|
|
230
361
|
return this.request("POST", "/experiments", input);
|
|
@@ -376,6 +507,70 @@ export class EvaluationClient {
|
|
|
376
507
|
getResult(id) {
|
|
377
508
|
return this.request("GET", `/evaluation-results/${uuid(id)}`);
|
|
378
509
|
}
|
|
510
|
+
/** Creates a run using product request fields on the existing v1 path. */
|
|
511
|
+
async createRun(input) {
|
|
512
|
+
return productRunFields(await this.request("POST", "/experiments", input), "run");
|
|
513
|
+
}
|
|
514
|
+
/** Reads a run with its scoring progress. */
|
|
515
|
+
async getRun(id) {
|
|
516
|
+
return productRunFields(await this.getExperiment(id), "run");
|
|
517
|
+
}
|
|
518
|
+
/** Lists a run's cases with their latest executions. */
|
|
519
|
+
async listRunItems(id, page) {
|
|
520
|
+
return productRunFields(await this.listExperimentItems(id, page), "run");
|
|
521
|
+
}
|
|
522
|
+
/** Reads one frozen case of a run. */
|
|
523
|
+
async getRunCase(id, caseId) {
|
|
524
|
+
return productRunFields(await this.getExperimentCase(id, caseId), "run");
|
|
525
|
+
}
|
|
526
|
+
/** Starts or replays a target execution for a run case. */
|
|
527
|
+
async startRunExecution(id, caseId, input) {
|
|
528
|
+
return productRunFields(await this.startExecution(id, caseId, input), "run");
|
|
529
|
+
}
|
|
530
|
+
/** Reads one run execution. */
|
|
531
|
+
async getRunExecution(id) {
|
|
532
|
+
return productRunFields(await this.getExecution(id), "run");
|
|
533
|
+
}
|
|
534
|
+
/** Saves a run execution's outcome. */
|
|
535
|
+
async completeRunExecution(id, input) {
|
|
536
|
+
return productRunFields(await this.completeExecution(id, input), "run");
|
|
537
|
+
}
|
|
538
|
+
/** Marks a run finished. */
|
|
539
|
+
async finishRun(id, idempotencyKey) {
|
|
540
|
+
return productRunFields(await this.finishExperiment(id, idempotencyKey), "run");
|
|
541
|
+
}
|
|
542
|
+
/** Creates a standalone scoring pass over saved subjects. */
|
|
543
|
+
async createScoring(input) {
|
|
544
|
+
return productRunFields(await this.request("POST", "/evaluation-runs", input), "scoring");
|
|
545
|
+
}
|
|
546
|
+
/** Reads a scoring pass and its pinned evaluators. */
|
|
547
|
+
async getScoring(id) {
|
|
548
|
+
return productRunFields(await this.getEvaluationRun(id), "scoring");
|
|
549
|
+
}
|
|
550
|
+
/** Lists scoring passes in the project. */
|
|
551
|
+
async listScorings(page) {
|
|
552
|
+
return productRunFields(await this.listEvaluationRuns(page), "scoring");
|
|
553
|
+
}
|
|
554
|
+
/** Lists the subjects of a scoring pass. */
|
|
555
|
+
async listScoringItems(id, page) {
|
|
556
|
+
return productRunFields(await this.listEvaluationItems(id, page), "scoring");
|
|
557
|
+
}
|
|
558
|
+
/** Reads a saved subject with product-named source fields. */
|
|
559
|
+
async getScoringSubject(id) {
|
|
560
|
+
return productRunFields(await this.getSubject(id), "run");
|
|
561
|
+
}
|
|
562
|
+
/** Uploads evaluator results for a scoring pass using product request fields. */
|
|
563
|
+
async submitScoringResults(id, input) {
|
|
564
|
+
return productRunFields(await this.request("POST", `/evaluation-runs/${uuid(id)}/results`, input), "result");
|
|
565
|
+
}
|
|
566
|
+
/** Lists result summaries for a scoring pass. */
|
|
567
|
+
async listScoringResults(id, page) {
|
|
568
|
+
return productRunFields(await this.listResults(id, page), "result");
|
|
569
|
+
}
|
|
570
|
+
/** Reads a stored evaluator result. */
|
|
571
|
+
async getScoringResult(id) {
|
|
572
|
+
return productRunFields(await this.getResult(id), "result");
|
|
573
|
+
}
|
|
379
574
|
/** Dispatches hosted judge jobs for `llm_judge` pins; check {@link getJudgeBudget} first. */
|
|
380
575
|
createJudgeJobs(id, input) {
|
|
381
576
|
return this.request("POST", `/evaluation-runs/${uuid(id)}/judge-jobs`, input);
|
package/dist/evals/types.d.ts
CHANGED
|
@@ -76,6 +76,21 @@ export interface DatasetCase {
|
|
|
76
76
|
/** Immutable input-file manifest identity, when files are attached. */
|
|
77
77
|
artifactManifestId?: string | null;
|
|
78
78
|
}
|
|
79
|
+
/** An eval set and its versions. Both field names remain available during v1 compatibility. */
|
|
80
|
+
export type EvalSet = Omit<Dataset, "versions"> & {
|
|
81
|
+
/** Versions of this eval set. */
|
|
82
|
+
versions: EvalSetVersion[];
|
|
83
|
+
};
|
|
84
|
+
/** A version of an eval set, with its product field name. */
|
|
85
|
+
export type EvalSetVersion = DatasetVersion & {
|
|
86
|
+
/** Owning eval set ID. */
|
|
87
|
+
evalSetId: string;
|
|
88
|
+
};
|
|
89
|
+
/** A stored case in an eval set version. */
|
|
90
|
+
export type EvalSetCase = DatasetCase & {
|
|
91
|
+
/** Eval set version containing this case. */
|
|
92
|
+
evalSetVersionId: string;
|
|
93
|
+
};
|
|
79
94
|
/** One pinned input file of a case or subject, as recorded in Hue's immutable manifest. */
|
|
80
95
|
export interface CaseFile {
|
|
81
96
|
/** Hue artifact identity of the pinned bytes. */
|
|
@@ -346,6 +361,16 @@ export interface ScorerVersion {
|
|
|
346
361
|
/** The pinned definition. */
|
|
347
362
|
definition: ScorerDefinition;
|
|
348
363
|
}
|
|
364
|
+
/** An evaluator and its published versions. */
|
|
365
|
+
export type Evaluator = Omit<Scorer, "versions"> & {
|
|
366
|
+
/** Published versions, when included in the response. */
|
|
367
|
+
versions?: EvaluatorVersion[];
|
|
368
|
+
};
|
|
369
|
+
/** An immutable published evaluator definition. */
|
|
370
|
+
export type EvaluatorVersion = ScorerVersion & {
|
|
371
|
+
/** Owning evaluator ID when the server supplies it; older v1 responses may omit it. */
|
|
372
|
+
evaluatorId?: string;
|
|
373
|
+
};
|
|
349
374
|
/** Final state of a target execution. */
|
|
350
375
|
export type TerminalState = "succeeded" | "error" | "cancelled";
|
|
351
376
|
/** One attempt to run the target for a case. */
|
|
@@ -439,6 +464,30 @@ export interface Experiment {
|
|
|
439
464
|
cancelled: number;
|
|
440
465
|
};
|
|
441
466
|
}
|
|
467
|
+
/** A run over a frozen eval set version and configuration. */
|
|
468
|
+
export type Run = Experiment & {
|
|
469
|
+
/** Frozen eval set version under test. */
|
|
470
|
+
evalSetVersionId: string;
|
|
471
|
+
/** Scoring pass created for this run. */
|
|
472
|
+
scoring: Scoring;
|
|
473
|
+
};
|
|
474
|
+
/** One frozen case in a run. */
|
|
475
|
+
export type RunCase = ExperimentCase & {
|
|
476
|
+
/** Source eval set version ID. */
|
|
477
|
+
evalSetVersionId: string;
|
|
478
|
+
};
|
|
479
|
+
/** A scoring pass over saved subjects with pinned evaluators. */
|
|
480
|
+
export type Scoring = EvaluationRun & {
|
|
481
|
+
/** Evaluator versions pinned to this scoring pass. */
|
|
482
|
+
evaluatorVersions: EvaluatorVersion[];
|
|
483
|
+
/** Linked run ID, or null for standalone scoring. */
|
|
484
|
+
runId?: string | null;
|
|
485
|
+
};
|
|
486
|
+
/** One row in the project's scoring list. */
|
|
487
|
+
export type ScoringSummary = EvaluationRunSummary & {
|
|
488
|
+
/** Linked run ID, or null for standalone scoring. */
|
|
489
|
+
runId: string | null;
|
|
490
|
+
};
|
|
442
491
|
/** A sanitized error type with an optional bounded message. */
|
|
443
492
|
export interface TypedError {
|
|
444
493
|
/** Stable error type. */
|
|
@@ -549,6 +598,13 @@ export interface Subject {
|
|
|
549
598
|
/** The target's declared primary generated artifact, or `null`. */
|
|
550
599
|
primaryArtifactId?: string | null;
|
|
551
600
|
}
|
|
601
|
+
/** An immutable saved subject with product-named source fields. */
|
|
602
|
+
export type ScoringSubject = Subject & {
|
|
603
|
+
/** Source eval set version ID. */
|
|
604
|
+
evalSetVersionId: string;
|
|
605
|
+
/** Source run ID. */
|
|
606
|
+
runId: string;
|
|
607
|
+
};
|
|
552
608
|
/** A reported metric value. */
|
|
553
609
|
export interface Metric {
|
|
554
610
|
/** Declared metric name. */
|
|
@@ -588,6 +644,27 @@ export type Result = Score & {
|
|
|
588
644
|
/** Source digest of the local scorer, for `local_code` pins. */
|
|
589
645
|
sourceDigest?: string;
|
|
590
646
|
};
|
|
647
|
+
/** A score uploaded through the product-named scoring method. */
|
|
648
|
+
export type ScoringResultInput = Score & {
|
|
649
|
+
/** Scoring item this result belongs to. */
|
|
650
|
+
evaluationItemId: string;
|
|
651
|
+
/** Evaluator version that produced the score. */
|
|
652
|
+
evaluatorVersionId: string;
|
|
653
|
+
/** Source digest for a local code evaluator. */
|
|
654
|
+
sourceDigest?: string;
|
|
655
|
+
};
|
|
656
|
+
/** A result as listed by {@link EvaluationClient.listScoringResults}. */
|
|
657
|
+
export type ScoringResultSummary = ResultSummary & {
|
|
658
|
+
/** Evaluator version that produced this result. */
|
|
659
|
+
evaluatorVersionId: string;
|
|
660
|
+
};
|
|
661
|
+
/** A full stored result from {@link EvaluationClient.getScoringResult}. */
|
|
662
|
+
export type StoredScoringResult = StoredResult & {
|
|
663
|
+
/** Scoring pass containing this result. */
|
|
664
|
+
scoringId: string;
|
|
665
|
+
/** Evaluator version that produced this result. */
|
|
666
|
+
evaluatorVersionId: string;
|
|
667
|
+
};
|
|
591
668
|
/** What a local scorer callback receives. */
|
|
592
669
|
export interface ScoreContext {
|
|
593
670
|
/** Case inputs. */
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Package version shared by the instrumentation scope and the export User-Agent. */
|
|
2
|
-
export declare const sdkVersion = "0.
|
|
2
|
+
export declare const sdkVersion = "0.6.0";
|
package/dist/version.js
CHANGED