@hue-run/sdk 0.2.0 for TypeScript only. They build on the local evaluation runner: each invocation creates a fresh experiment, one isolated world per case and a resumable checkpoint directory. For signatures and types, see the simulation and environment sections of the reference.
Install
Importing@hue-run/sdk/evals needs the optional zod peer (4.6.5 or later). Install it with the SDK:
HUE_API_KEY to a project service key with Read and write access. The evaluation client and the environment client must use the same Hue origin.
What a simulated world is
An environment is a versioned, immutable definition of a world: its initial state, organized as collections of entities with JSON fields, and a closed catalog of actions. Each action maps to one deterministic semantic implemented by Hue’s environment kernel, such ashue.collection.get@1, hue.gmail.create_draft@1 or hue.slack.read_channel@1, and declares flat parameters of type string, number, boolean or string[]. Publishing a definition creates an environment version with a content digest. A stable definition reuses its matching version; a changed definition publishes a new one.
A run instantiates one version into one fresh isolated world with a virtual clock, a step budget of at most 500 actions, a lease and a journal. Every action becomes a journal step that records the validated arguments, the world’s observation, the normalized state effects and the state digest after the step. Repeating an invocation identity replays the recorded result instead of acting twice. Sealing the run as completed or abandoned freezes the journal and final state as evidence.
An observation with status: "error" is a recorded world answer, for example a guard that refused a mutation. It is not a transport exception.
Run a scenario like a test
runSimulation() is the one-shot developer path. It calls your existing callback directly, so IDE breakpoints and cooperative cancellation work. It does not register a worker, poll for jobs, host your laptop or require an inbound tunnel.
run_created event carries the experiment URL as soon as the experiment exists, so you can inspect progress while the agent runs.
Repeat the command after an edit for a fresh attempt and world. An interrupted invocation resumes through the private checkpoint directory instead of starting again. Use one directory per scenario and add it to .gitignore.
Repository-authored scenarios
A repository scenario keeps the world definition, cases and scorers next to the agent code.runSimulation() publishes them through the same validated environment, dataset, scorer and experiment APIs as scenarios authored in Hue. Stable slugs reuse matching immutable content digests; changed definitions, cases or scorers publish new versions. Hue does not synchronize files back from its UI, and the helper refuses an unrelated mutable dataset draft instead of overwriting it.
ScorerDefinition union: exact match, includes, JSON Schema, local code, manual and model-judge definitions. A LocalScorer from defineLocalScorer publishes its pinned definition and binds the callback in the same step. runSimulation() applies the same identity-affecting defaults as Hue before resolving versions and rejects unknown or server-only kinds; in particular, document_verifier is not part of this SDK contract and is rejected rather than published with a guessed digest.
A scenario needs at least one case and one scorer, and case keys must be unique. Definition defaults are applied before the digest is computed: required: true on parameters, an identity observation projection, empty guards, a not_found error and handwritten provenance. Writing the defaults out does not create a new version.
What the callback receives
target(inputs, context) is invoked exactly once per attempt. The context contains:
Configuration alone does not redirect real provider calls; give
tools or mcp to the agent’s actual tool boundary. The MCP token is delivered only to the callback and is never written to checkpoints or progress events.
The local tools are bounded. Each callable accepts only the flat parameters its action declares and rejects unknown arguments; array parameters carry item and length limits. Every call is one journal step against the world’s maxSteps budget (1–500, set per invocation), and each result reports stepsRemaining. Each call becomes an execute_tool span under the case span, so the trace and the journal describe the same actions.
Evidence and scoring
The run URL joins the task, the trace, the world’s effects and final state, the target outcome and the scorer results. Target failures and cancellations seal the world asabandoned; scorer errors remain separate from target errors.
Local scoring resolves the sealed world before calling a scorer. A local-code scorer receives context.environment: the sealed run, its initialState and finalState as { collections } objects, and the complete ordered journal in steps. The SDK checks that the journal is complete, ordered and ends at the sealed state digest, and it limits the evidence to 8 MiB without truncating history. When environment evidence is present, a local-code scorer runs even if the target returned no output.
If the sealed evidence cannot be read, local-code results record an EnvironmentEvidenceUnavailable error instead of scoring on incomplete data; built-in scorers still score the saved output. Historical rescoring with rescore({ ..., environmentEvidence: "required" }) reads the same sealed evidence through the execution, so a stored simulation can be rescored without running the agent again. Manual and hosted judge scorer pins stay pending for their owning workflows.
Cancellation and uncertainty
Cancellation is cooperative. Passsignal to runSimulation() and forward context.signal into the provider or agent call. A cancelled attempt is recorded with execution state cancelled and its world is sealed as abandoned.
If the agent may have run without a saved outcome, resume fails explicitly with UncertainExecutionError and never calls it again. If Hue cannot confirm whether the world sealed, or a preflight response is lost after a decision may have been committed, the execution stays uncertain and TargetOutcomeUncertainError names the execution; a resume neither reacquires credentials nor invokes the callback again. Inspect the execution and its side effects before authorizing a new attempt. Removing the checkpoint directory or its lock is not permission to run the target again.
Running a changed scenario while an unfinished simulation is checkpointed in the same directory fails. Recover or finish that simulation first, or use another directory.
Pinned provider-profile preflight
An experiment whose configuration carries an immutableattemptBaselineV2 can require the local process to describe the agent configuration it is about to run. Supply actualAgentManifest, the exact ordered requestedProviders and an mcpSurface selected from that request. Hue compares the agent, prompt, model, tools, approvals, orchestration, MCP catalogs and native-helper configuration before the callback or model runs. Missing evidence stays explicitly missing; it is never treated as a match.
On a ready decision, context.connectionBundle contains the selected provider surfaces with attempt-scoped endpoints and bearers, and context.mcp remains the projection of the selected MCP surface. Endpoints, bearers, expiry and credential generation stay in callback memory: the runner does not write them to checkpoints or progress events, and it never mutates process.env. A durable environment_incomplete decision skips both the callback and scoring; the attempt_prepared progress event carries its stable finding codes. If a ready response or the world seal cannot be confirmed, the checkpoint stays uncertain and a resume neither reacquires credentials nor invokes the callback again.
This is currently a control-plane contract. Hue can issue provider endpoints, but a provider data-plane facade call has not yet been proven by the released integration. The generic Hue MCP capability remains the runnable hosted-tool path; do not read preparation or local-tool tests as evidence of a hosted Gmail or Slack MCP call.
Direct environment tools
For lower-level use, publish a definition, create a run and bind its generated catalog yourself:createRun, act, finishRun, recordCoverageGap) retry transient failures with stable invocation and idempotency identities. Registry writes (createEnvironment, publishVersion) do not retry automatically, because identity creation and publication have no request key. HueEnvironmentError carries the HTTP status when Hue answered and never includes response text or credentials.
Coverage gaps
A provider adapter can record a known valid provider request that the environment cannot implement withclient.recordCoverageGap(run.id, { idempotencyKey, provider, operation, code, args, description }). Use a durable UUID idempotency key and repeat the identical request to recover a lost acknowledgement. This is a runner or adapter control operation, not an agent tool. args must be a JSON object of at most 16,000 encoded bytes.
Hue preserves the first report, marks the run validity: "environment_incomplete" and refuses new actions while still replaying already-recorded invocation receipts. coverageGap retains the request and reporting provenance. An absent gap means not_assessed; it does not establish provider parity.
Local scoring and historical rescoring skip incomplete evidence before calling a scorer, even when the target returned no output or failed; the skipped result’s explanation is Environment incomplete: provider behavior is not implemented. Unsupported caller syntax and real provider errors are not automatically coverage gaps; the adapter must identify a known missing provider behavior. When the callback throws, runSimulation() checks the authoritative world: a durably recorded gap finishes the attempt as environment-incomplete rather than as a target error, while a gap or seal that cannot be confirmed stays uncertain and never causes the agent to be replayed.
Current limits
runSimulation()is TypeScript-only. Like the other local runners, it needs POSIX filesystem semantics for its checkpoint directory; use WSL2 or a Linux runner on Windows.- Definitions use
schemaVersion: 1, flat parameters and the fixed catalog of kernel semantics listed underSemanticEntryin the reference. Identity is the only observation projection. - A world records at most 500 actions and its lease is at most 86,400 seconds. A published definition may contain up to 240 KB; evidence validation accepts worlds of at most 64 collections and 2,000 entities and evidence of at most 8 MiB; coverage-gap arguments are limited to 16,000 bytes; API responses to 4 MiB and request bodies to 1 MiB.
- The hosted MCP connection exposes Hue’s bounded native actions. It is not general Gmail or Slack HTTP parity and does not proxy arbitrary provider traffic.
- Forking, in-place reset and arbitrary-step diffs are outside this interface.
document_verifierscorers cannot be published from a repository scenario.