@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 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.5.1`, `@opentelemetry/api@1.9.1` and
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.5.1.tgz \
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.5.1.tgz \
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 Scenario
336
+ ## Evaluate an agent against a case
337
337
 
338
- `hue eval` runs a developer's local agent against a published Hue Scenario or a saved eval set
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 Scenarios or create experiments);
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 --scenario "Refund an eligible charge" ./hue-agent.ts --env-file .env.hue
366
- hue eval --scenario https://app.hue.run/projects/demo/scenarios/<id> ./hue-agent.ts --baseline <experiment id>
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 --scenario "Refund an eligible charge" --command "python agent.py" --timeout 120 --content
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
- The one-shot mode resolves the selection (`--scenario` by name, ID or URL; `--set` by name, ID or
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 experiment from those immutable pins named `<scenario> · <agent key> · <revision>`
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; `--scenario` is always
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 Scenario](CLI.md#evaluate-an-agent-against-a-scenario).
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 --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
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 Scenario](CLI.md#evaluate-an-agent-against-a-scenario).
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 Hue Scenario or eval set, then print Hue's verdicts.
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
- --scenario <name|id|url> Published Scenario to run
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> Experiment name (default: <scenario> · <agent key> · <revision>)
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
- if (values.scenario) {
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, values.scenario);
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 --scenario for published pins`);
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 --scenario, --set or --dataset-version");
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 --scenario "<name>" ./hue-agent.ts --env-file ${envDisplay}`);
742
+ out(` hue eval --case "<name>" ./hue-agent.ts --env-file ${envDisplay}`);
743
743
  return 0;
744
744
  }
@@ -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;
@@ -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);
@@ -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.5.1";
2
+ export declare const sdkVersion = "0.6.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Generated by scripts/write-version.mjs from package.json; do not edit by hand.
2
2
  /** Package version shared by the instrumentation scope and the export User-Agent. */
3
- export const sdkVersion = "0.5.1";
3
+ export const sdkVersion = "0.6.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hue-run/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "publishConfig": {