@hue-run/sdk 0.7.0 → 0.8.1
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 +27 -14
- package/ENVIRONMENTS.md +63 -1
- package/README.md +121 -5
- package/dist/ai-sdk.d.ts +3 -3
- package/dist/ai-sdk.js +3 -3
- package/dist/cli/env-file.d.ts +22 -0
- package/dist/cli/env-file.js +21 -0
- package/dist/cli/eval.js +100 -30
- package/dist/cli/login.d.ts +1 -1
- package/dist/cli/login.js +9 -4
- package/dist/client.d.ts +31 -3
- package/dist/client.js +199 -7
- package/dist/config.d.ts +2 -0
- package/dist/config.js +2 -0
- package/dist/environment/client.d.ts +16 -2
- package/dist/environment/client.js +46 -3
- package/dist/environment/tools.d.ts +2 -2
- package/dist/environment/tools.js +2 -2
- package/dist/environment/types.d.ts +134 -4
- package/dist/environment/world.d.ts +50 -0
- package/dist/environment/world.js +105 -0
- package/dist/environment.d.ts +2 -0
- package/dist/environment.js +1 -0
- package/dist/evals/environment-target.d.ts +53 -2
- package/dist/evals/environment-target.js +114 -10
- package/dist/evals/local-worker.d.ts +12 -5
- package/dist/evals/local-worker.js +13 -5
- package/dist/evals/runner.d.ts +1 -1
- package/dist/evals/runner.js +2 -2
- package/dist/evals/simulation.d.ts +14 -5
- package/dist/evals/simulation.js +26 -8
- package/dist/experimental-telemetry.d.ts +3 -2
- package/dist/experimental-telemetry.js +3 -2
- package/dist/inline-files.d.ts +10 -0
- package/dist/inline-files.js +86 -0
- package/dist/privacy.js +54 -5
- package/dist/provider-tools.d.ts +39 -0
- package/dist/provider-tools.js +222 -0
- package/dist/tool-definitions.d.ts +20 -0
- package/dist/tool-definitions.js +274 -0
- package/dist/transport.js +4 -2
- package/dist/types.d.ts +76 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/cli/eval.js
CHANGED
|
@@ -6,6 +6,7 @@ import { parseArgs } from "node:util";
|
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import { createHue } from "../client.js";
|
|
8
8
|
import { createEnvironmentClient } from "../environment/client.js";
|
|
9
|
+
import { agentEnvironment, stripHueControlPlaneCredentials, writeMcpConfig, } from "../environment/world.js";
|
|
9
10
|
import { EvaluationClient, HueApiError } from "../evals/client.js";
|
|
10
11
|
import { TargetResult } from "../evals/types.js";
|
|
11
12
|
import { CheckpointStore } from "../evals/checkpoint.js";
|
|
@@ -16,6 +17,7 @@ import { matchByName, parseScenarioSelector, resolveEvalSetPins, resolveScenario
|
|
|
16
17
|
import { collectDirectOutputs, stageDirectCase } from "./eval-direct.js";
|
|
17
18
|
import { runSimulation, } from "../evals/simulation.js";
|
|
18
19
|
import { collectExperimentVerdicts, compareVerdicts, metricPassed, } from "../evals/verdicts.js";
|
|
20
|
+
import { envFileArgument, envFileOptions } from "./env-file.js";
|
|
19
21
|
const USAGE = `Usage: hue eval [adapter-file] [options]
|
|
20
22
|
|
|
21
23
|
Run a local agent against a published case or eval set, then print Hue's verdicts.
|
|
@@ -32,9 +34,15 @@ Selection (exactly one, not used with --worker):
|
|
|
32
34
|
|
|
33
35
|
Agent (exactly one):
|
|
34
36
|
<adapter-file> Module exporting default or runMyAgent(inputs, context)
|
|
35
|
-
--command "<shell command>" Simulation: spawned per case with
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
--command "<shell command>" Simulation: spawned per case with the world's environment
|
|
38
|
+
(HUE_WORLD_ID, HUE_WORLD_TOKEN, one HUE_SIM_<SURFACE>_URL per
|
|
39
|
+
provider mirror, HUE_MCP_CONFIG, plus HUE_MCP_URL, HUE_MCP_TOKEN
|
|
40
|
+
and HUE_MCP_EXPIRES_AT for the first MCP mirror), HUE_EXECUTION_ID,
|
|
41
|
+
HUE_ENVIRONMENT_RUN_ID, HUE_CASE_ID and HUE_CASE_KEY set;
|
|
42
|
+
{"inputs","config"} on stdin. HUE_API_KEY and other Hue
|
|
43
|
+
control-plane credentials are removed from the child.
|
|
44
|
+
--allow-hue-credentials Keep HUE_API_KEY and other Hue control-plane credentials in
|
|
45
|
+
the --command child (off by default)
|
|
38
46
|
Direct: spawned in a private case directory with HUE_CASE_DIR,
|
|
39
47
|
HUE_CASE_INPUTS, HUE_CASE_OUTPUT_DIR, HUE_CASE_ID, HUE_CASE_KEY
|
|
40
48
|
and HUE_EXECUTION_ID set; files/<role>/ hold the pinned inputs
|
|
@@ -49,17 +57,18 @@ Modes:
|
|
|
49
57
|
|
|
50
58
|
Connection:
|
|
51
59
|
--env-file <path> Load a dotenv file (HUE_API_KEY, HUE_BASE_URL) first
|
|
60
|
+
--env-path <path> Same as --env-file
|
|
52
61
|
--origin <url> Hue origin (default: HUE_BASE_URL or https://app.hue.run)
|
|
53
62
|
|
|
54
63
|
Output and limits:
|
|
55
|
-
--name <run name> Run name (default: <
|
|
64
|
+
--name <run name> Run name (default: <agent key> @ <revision>, hashes shortened)
|
|
56
65
|
--baseline <experiment id|url> Compare verdicts with a previous experiment
|
|
57
66
|
--json Print one JSON document on stdout; progress goes to stderr
|
|
58
67
|
--content Capture telemetry content; one-shot also persists
|
|
59
68
|
outputs/explanations (--worker always persists them)
|
|
60
69
|
--save-version Freeze an unsaved eval-set version before running
|
|
61
70
|
--checkpoint-dir <path> Private checkpoint directory (default: .hue/eval/<agent-key>)
|
|
62
|
-
--concurrency <n> Cases in flight, 1-
|
|
71
|
+
--concurrency <n> Cases in flight, 1-64 (default: 1)
|
|
63
72
|
--timeout <seconds> Per-case --command timeout (default: 600)
|
|
64
73
|
--wait <seconds> Verdict wait after the run finishes (default: 300)
|
|
65
74
|
-h, --help Show this help
|
|
@@ -92,12 +101,13 @@ function parse(argv) {
|
|
|
92
101
|
"scorer-version": { type: "string", multiple: true },
|
|
93
102
|
mode: { type: "string" },
|
|
94
103
|
command: { type: "string" },
|
|
104
|
+
"allow-hue-credentials": { type: "boolean", default: false },
|
|
95
105
|
worker: { type: "boolean", default: false },
|
|
96
106
|
"max-runs": { type: "string" },
|
|
97
107
|
"agent-key": { type: "string" },
|
|
98
108
|
"agent-name": { type: "string" },
|
|
99
109
|
revision: { type: "string" },
|
|
100
|
-
|
|
110
|
+
...envFileOptions,
|
|
101
111
|
origin: { type: "string" },
|
|
102
112
|
name: { type: "string" },
|
|
103
113
|
baseline: { type: "string" },
|
|
@@ -164,6 +174,12 @@ function derivedAgentKey(adapterFile, command) {
|
|
|
164
174
|
"";
|
|
165
175
|
return slug(basename(script, extname(script)));
|
|
166
176
|
}
|
|
177
|
+
function defaultRunName(agent) {
|
|
178
|
+
const revision = /^[0-9a-f]{12,64}$/i.test(agent.revision)
|
|
179
|
+
? agent.revision.slice(0, 7)
|
|
180
|
+
: agent.revision;
|
|
181
|
+
return `${agent.key} @ ${revision}`;
|
|
182
|
+
}
|
|
167
183
|
function gitRevision() {
|
|
168
184
|
try {
|
|
169
185
|
const value = execFileSync("git", ["rev-parse", "--short=12", "HEAD"], {
|
|
@@ -296,29 +312,65 @@ function parseAnswer(text) {
|
|
|
296
312
|
return text;
|
|
297
313
|
}
|
|
298
314
|
}
|
|
299
|
-
/**
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Runs the shell command once per case. The world token and mirror URLs travel only through the
|
|
317
|
+
* child's environment and an owner-only MCP configuration file that is removed after the run;
|
|
318
|
+
* Hue control-plane credentials (`HUE_API_KEY`, `HUE_MCP_KEY`, any `hue_sk_` value) stay with
|
|
319
|
+
* the CLI unless `--allow-hue-credentials` is passed. A world created while the gateway is off
|
|
320
|
+
* still gets the `hue_sim_` capability under the same `HUE_MCP_*` names.
|
|
321
|
+
*/
|
|
322
|
+
/** The parent environment an agent child starts from: without Hue control-plane credentials
|
|
323
|
+
* unless `--allow-hue-credentials` was passed. */
|
|
324
|
+
function parentEnvironment(allowHueCredentials) {
|
|
325
|
+
return allowHueCredentials
|
|
326
|
+
? Object.fromEntries(Object.entries(process.env).filter((entry) => entry[1] !== undefined))
|
|
327
|
+
: stripHueControlPlaneCredentials(process.env);
|
|
328
|
+
}
|
|
329
|
+
function commandAdapter(command, timeoutSeconds, options) {
|
|
330
|
+
return async (inputs, context) => {
|
|
331
|
+
const parent = parentEnvironment(options.allowHueCredentials);
|
|
332
|
+
const identity = {
|
|
307
333
|
HUE_EXECUTION_ID: context.executionId,
|
|
308
334
|
HUE_ENVIRONMENT_RUN_ID: context.environmentRunId,
|
|
309
335
|
HUE_CASE_ID: context.item.id,
|
|
310
336
|
HUE_CASE_KEY: context.item.externalKey,
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
337
|
+
};
|
|
338
|
+
const configFile = context.world ? await writeMcpConfig(context.world) : undefined;
|
|
339
|
+
try {
|
|
340
|
+
const env = context.world
|
|
341
|
+
? {
|
|
342
|
+
...agentEnvironment(context.world, { parent, includeHueCredentials: true }),
|
|
343
|
+
...identity,
|
|
344
|
+
HUE_MCP_CONFIG: configFile.path,
|
|
345
|
+
}
|
|
346
|
+
: {
|
|
347
|
+
...parent,
|
|
348
|
+
...(context.mcp
|
|
349
|
+
? {
|
|
350
|
+
HUE_MCP_URL: context.mcp.url,
|
|
351
|
+
HUE_MCP_TOKEN: context.mcp.token,
|
|
352
|
+
HUE_MCP_EXPIRES_AT: context.mcp.expiresAt,
|
|
353
|
+
}
|
|
354
|
+
: {}),
|
|
355
|
+
...identity,
|
|
356
|
+
};
|
|
357
|
+
return parseAnswer(await spawnAgentCommand(command, {
|
|
358
|
+
env,
|
|
359
|
+
stdin: JSON.stringify({ inputs, config: context.config }),
|
|
360
|
+
timeoutSeconds,
|
|
361
|
+
...(context.signal ? { signal: context.signal } : {}),
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
finally {
|
|
365
|
+
await configFile?.dispose();
|
|
366
|
+
}
|
|
367
|
+
};
|
|
316
368
|
}
|
|
317
369
|
/**
|
|
318
370
|
* Direct cases: the command works in a private case directory and writes its documents to
|
|
319
371
|
* `output/`. Its stdout is only used as the JSON output when it wrote no result or summary file.
|
|
320
372
|
*/
|
|
321
|
-
function directCommandAdapter(command, timeoutSeconds) {
|
|
373
|
+
function directCommandAdapter(command, timeoutSeconds, options) {
|
|
322
374
|
return async (inputs, context) => {
|
|
323
375
|
const layout = await stageDirectCase(context.outputDirectory, {
|
|
324
376
|
inputs,
|
|
@@ -330,7 +382,7 @@ function directCommandAdapter(command, timeoutSeconds) {
|
|
|
330
382
|
const stdout = await spawnAgentCommand(command, {
|
|
331
383
|
cwd: layout.caseDirectory,
|
|
332
384
|
env: {
|
|
333
|
-
...
|
|
385
|
+
...parentEnvironment(options.allowHueCredentials),
|
|
334
386
|
HUE_CASE_DIR: layout.caseDirectory,
|
|
335
387
|
HUE_CASE_INPUTS: layout.inputsPath,
|
|
336
388
|
HUE_CASE_OUTPUT_DIR: layout.outputDirectory,
|
|
@@ -636,7 +688,7 @@ function parseBaseline(value) {
|
|
|
636
688
|
}
|
|
637
689
|
async function runOnce(values, connection, agents, agent, hue, output, signal) {
|
|
638
690
|
const client = new EvaluationClient(connection);
|
|
639
|
-
const concurrency = integer("concurrency", values.concurrency, 1, 1,
|
|
691
|
+
const concurrency = integer("concurrency", values.concurrency, 1, 1, 64);
|
|
640
692
|
const baselineId = parseBaseline(values.baseline);
|
|
641
693
|
const mode = parseMode(values.mode);
|
|
642
694
|
const pins = await resolveSelection(client, values);
|
|
@@ -648,7 +700,7 @@ async function runOnce(values, connection, agents, agent, hue, output, signal) {
|
|
|
648
700
|
const frozen = await client.freezeDatasetVersion(pins.datasetVersionId, pins.revision);
|
|
649
701
|
output.log(`Saved "${pins.name}" version ${frozen.version}.`);
|
|
650
702
|
}
|
|
651
|
-
const runName = values.name ??
|
|
703
|
+
const runName = values.name ?? defaultRunName(agent);
|
|
652
704
|
const project = await client.checkConnection();
|
|
653
705
|
if (await detectDirect(client, pins, mode))
|
|
654
706
|
return runDirect({
|
|
@@ -683,6 +735,10 @@ async function runOnce(values, connection, agents, agent, hue, output, signal) {
|
|
|
683
735
|
persistResultContent: values.content,
|
|
684
736
|
traceEvidence: { mode: "required" },
|
|
685
737
|
concurrency,
|
|
738
|
+
agentRevision: agent.revision,
|
|
739
|
+
// The CLI adapts to whatever the deployment serves; the library warning is for code that
|
|
740
|
+
// still reads the legacy capability itself.
|
|
741
|
+
deprecationWarnings: false,
|
|
686
742
|
signal,
|
|
687
743
|
target: agents.simulation,
|
|
688
744
|
async onProgress(event) {
|
|
@@ -820,7 +876,7 @@ async function runWorker(values, connection, adapter, agent, hue, output, signal
|
|
|
820
876
|
const client = new ObservedClient(connection);
|
|
821
877
|
const environmentClient = createEnvironmentClient(connection);
|
|
822
878
|
const wait = integer("wait", values.wait, 300, 0, 86_400);
|
|
823
|
-
const concurrency = integer("concurrency", values.concurrency, 1, 1,
|
|
879
|
+
const concurrency = integer("concurrency", values.concurrency, 1, 1, 64);
|
|
824
880
|
const maxRuns = values["max-runs"] === undefined
|
|
825
881
|
? undefined
|
|
826
882
|
: integer("max-runs", values["max-runs"], 1, 1, 1_000_000);
|
|
@@ -847,6 +903,7 @@ async function runWorker(values, connection, adapter, agent, hue, output, signal
|
|
|
847
903
|
},
|
|
848
904
|
scorers: [],
|
|
849
905
|
concurrency,
|
|
906
|
+
deprecationWarnings: false,
|
|
850
907
|
signal,
|
|
851
908
|
...(maxRuns === undefined ? {} : { maxRuns }),
|
|
852
909
|
target(inputs, tools, context) {
|
|
@@ -857,7 +914,8 @@ async function runWorker(values, connection, adapter, agent, hue, output, signal
|
|
|
857
914
|
executionId: context.executionId,
|
|
858
915
|
environmentRunId: context.environmentRunId,
|
|
859
916
|
tools,
|
|
860
|
-
|
|
917
|
+
...(context.world ? { world: context.world } : {}),
|
|
918
|
+
...(context.mcp ? { mcp: context.mcp } : {}),
|
|
861
919
|
...(context.connectionBundle ? { connectionBundle: context.connectionBundle } : {}),
|
|
862
920
|
signal,
|
|
863
921
|
});
|
|
@@ -926,12 +984,19 @@ export async function runEvalCommand(argv) {
|
|
|
926
984
|
throw new UsageError("--worker takes no selection; Hue chooses the run to execute");
|
|
927
985
|
if (!values.worker && selections !== 1)
|
|
928
986
|
throw new UsageError("Pass exactly one of --case, --set or --dataset-version");
|
|
929
|
-
|
|
987
|
+
let envFile;
|
|
988
|
+
try {
|
|
989
|
+
envFile = envFileArgument(values, process.cwd());
|
|
990
|
+
}
|
|
991
|
+
catch (error) {
|
|
992
|
+
throw new UsageError(error.message);
|
|
993
|
+
}
|
|
994
|
+
if (envFile) {
|
|
930
995
|
try {
|
|
931
|
-
process.loadEnvFile(resolve(
|
|
996
|
+
process.loadEnvFile(resolve(envFile));
|
|
932
997
|
}
|
|
933
998
|
catch (error) {
|
|
934
|
-
throw new UsageError(`Unable to load ${
|
|
999
|
+
throw new UsageError(`Unable to load ${envFile}: ${error instanceof Error ? error.message : String(error)}`);
|
|
935
1000
|
}
|
|
936
1001
|
}
|
|
937
1002
|
const apiKey = process.env.HUE_API_KEY?.trim();
|
|
@@ -959,8 +1024,13 @@ export async function runEvalCommand(argv) {
|
|
|
959
1024
|
throw new Error("The adapter returned generated files for a simulated-world case");
|
|
960
1025
|
return answer;
|
|
961
1026
|
}
|
|
962
|
-
: commandAdapter(values.command, timeout
|
|
963
|
-
|
|
1027
|
+
: commandAdapter(values.command, timeout, {
|
|
1028
|
+
allowHueCredentials: values["allow-hue-credentials"],
|
|
1029
|
+
}),
|
|
1030
|
+
direct: loaded ??
|
|
1031
|
+
directCommandAdapter(values.command, timeout, {
|
|
1032
|
+
allowHueCredentials: values["allow-hue-credentials"],
|
|
1033
|
+
}),
|
|
964
1034
|
};
|
|
965
1035
|
hue = createHue({ apiKey, baseUrl, serviceName: key, captureContent: values.content });
|
|
966
1036
|
return values.worker
|
package/dist/cli/login.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface LoginCommandIo {
|
|
|
14
14
|
fetch?: typeof fetch;
|
|
15
15
|
openBrowser?: (url: string) => Promise<boolean>;
|
|
16
16
|
}
|
|
17
|
-
export declare const LOGIN_USAGE = "Usage: hue login [--origin URL] [--env-
|
|
17
|
+
export declare const LOGIN_USAGE = "Usage: hue login [--origin URL] [--env-path PATH] [--keys evaluations|coding-agent|both]\n [--no-browser] [--force] [--gitignore]\n\nStore the key you created in Hue in a private env file. By default one \"Read and write\" key serves\nboth evaluations (HUE_API_KEY) and your coding agent (HUE_MCP_KEY); it is validated against Hue\nbefore it is stored, and key values are never printed.\n\nOptions:\n --origin URL Hue origin (default https://app.hue.run)\n --env-path PATH Env file to write (default .env.hue in the current directory); it is\n created when missing. --env-file also works, but Node itself exits\n before this command runs when that file does not exist yet\n --keys KIND evaluations (HUE_API_KEY), coding-agent (HUE_MCP_KEY) or both from one key\n (default both)\n --no-browser Do not open the key settings page in a browser\n --force Replace an existing different value in the env file\n --gitignore Add the env file to .gitignore when a git repository does not ignore it\n -h, --help Show this help";
|
|
18
18
|
/** Hue MCP endpoint that pairs with an application origin. */
|
|
19
19
|
export declare function mcpUrlForOrigin(origin: string): string;
|
|
20
20
|
/** Normalizes a Hue origin: HTTPS, or HTTP for loopback only; no credentials, path, query or hash. */
|
package/dist/cli/login.js
CHANGED
|
@@ -7,6 +7,7 @@ import { createInterface } from "node:readline";
|
|
|
7
7
|
import { Writable } from "node:stream";
|
|
8
8
|
import { parseArgs } from "node:util";
|
|
9
9
|
import { isLoopbackHost } from "../config.js";
|
|
10
|
+
import { envFileArgument, envFileOptions } from "./env-file.js";
|
|
10
11
|
const DEFAULT_ORIGIN = "https://app.hue.run";
|
|
11
12
|
const DEFAULT_ENV_FILE = ".env.hue";
|
|
12
13
|
/** Settings section that lists and creates project service keys. */
|
|
@@ -27,7 +28,7 @@ const KEY_KINDS = {
|
|
|
27
28
|
};
|
|
28
29
|
/** Settings preset that authorizes both evaluations and the coding agent's MCP reads and writes. */
|
|
29
30
|
const KEY_PRESET = "Read and write";
|
|
30
|
-
export const LOGIN_USAGE = `Usage: hue login [--origin URL] [--env-
|
|
31
|
+
export const LOGIN_USAGE = `Usage: hue login [--origin URL] [--env-path PATH] [--keys evaluations|coding-agent|both]
|
|
31
32
|
[--no-browser] [--force] [--gitignore]
|
|
32
33
|
|
|
33
34
|
Store the key you created in Hue in a private env file. By default one "Read and write" key serves
|
|
@@ -36,7 +37,9 @@ before it is stored, and key values are never printed.
|
|
|
36
37
|
|
|
37
38
|
Options:
|
|
38
39
|
--origin URL Hue origin (default ${DEFAULT_ORIGIN})
|
|
39
|
-
--env-
|
|
40
|
+
--env-path PATH Env file to write (default ${DEFAULT_ENV_FILE} in the current directory); it is
|
|
41
|
+
created when missing. --env-file also works, but Node itself exits
|
|
42
|
+
before this command runs when that file does not exist yet
|
|
40
43
|
--keys KIND evaluations (HUE_API_KEY), coding-agent (HUE_MCP_KEY) or both from one key
|
|
41
44
|
(default both)
|
|
42
45
|
--no-browser Do not open the key settings page in a browser
|
|
@@ -558,7 +561,7 @@ function parseLoginArguments(argv) {
|
|
|
558
561
|
strict: true,
|
|
559
562
|
options: {
|
|
560
563
|
origin: { type: "string" },
|
|
561
|
-
|
|
564
|
+
...envFileOptions,
|
|
562
565
|
keys: { type: "string" },
|
|
563
566
|
"no-browser": { type: "boolean", default: false },
|
|
564
567
|
force: { type: "boolean", default: false },
|
|
@@ -591,8 +594,10 @@ export async function runLoginCommand(argv, io = {}) {
|
|
|
591
594
|
return code;
|
|
592
595
|
};
|
|
593
596
|
let parsed;
|
|
597
|
+
let envFileOption;
|
|
594
598
|
try {
|
|
595
599
|
parsed = parseLoginArguments(argv);
|
|
600
|
+
envFileOption = envFileArgument(parsed.values, cwd);
|
|
596
601
|
}
|
|
597
602
|
catch (error) {
|
|
598
603
|
return fail(`${error.message}\n\n${LOGIN_USAGE}`, 2);
|
|
@@ -615,7 +620,7 @@ export async function runLoginCommand(argv, io = {}) {
|
|
|
615
620
|
if (!origin)
|
|
616
621
|
return fail("--origin must be an HTTPS origin such as https://app.hue.run (plain HTTP is accepted for loopback test servers only).", 2);
|
|
617
622
|
const mcpUrl = mcpUrlForOrigin(origin);
|
|
618
|
-
const envPath = resolve(cwd,
|
|
623
|
+
const envPath = resolve(cwd, envFileOption ?? DEFAULT_ENV_FILE);
|
|
619
624
|
const envDisplay = displayPath(cwd, envPath);
|
|
620
625
|
let envFile;
|
|
621
626
|
try {
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Context, type Span, type Tracer } from "@opentelemetry/api";
|
|
2
2
|
import { HueTransport } from "./transport.js";
|
|
3
|
-
import type { ExportReport, FlushableLoggerProvider, FlushableTracerProvider, HueOptions, HueSpan, ModelOptions, ProjectConnection, SpanOptions, ToolOptions, VerifyTraceOptions, TraceVerification, SafeLifecycleOptions, SafeLifecycleResult } from "./types.js";
|
|
3
|
+
import type { ExportReport, FileRecord, FlushableLoggerProvider, FlushableTracerProvider, HueOptions, HueSpan, ModelOptions, ProjectConnection, SpanOptions, ProviderToolCallOptions, ToolOptions, VerifyTraceOptions, TraceVerification, SafeLifecycleOptions, SafeLifecycleResult } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Attach mode: the application owns its OpenTelemetry providers and passes the transport whose
|
|
6
6
|
* processors it attached to them. The client flushes these providers but never shuts them down.
|
|
@@ -75,7 +75,8 @@ export declare class HueClient {
|
|
|
75
75
|
* `options.callId` is recorded as `gen_ai.tool.call.id`, like the Python `call_id=` keyword.
|
|
76
76
|
* `options.mcp` records the MCP `initialize` `serverInfo` as `mcp.server.name` /
|
|
77
77
|
* `mcp.server.version` so a generic tool name can be attributed to the server that
|
|
78
|
-
* handled it. Pass `client.getServerVersion()`.
|
|
78
|
+
* handled it. Pass `client.getServerVersion()`. `mcp.provider` / `mcp.surface` record the Hue
|
|
79
|
+
* provider and surface as `hue.mcp.provider` / `hue.mcp.surface`.
|
|
79
80
|
*/
|
|
80
81
|
tool<T>(name: string, input: unknown, execute: () => Promise<T> | T, options?: ToolOptions): Promise<T>;
|
|
81
82
|
/**
|
|
@@ -84,7 +85,8 @@ export declare class HueClient {
|
|
|
84
85
|
* `gen_ai.request.model` and `gen_ai.provider.name`. The argument order matches `withSpan`. The
|
|
85
86
|
* handle's `setInput`/`setOutput` record `gen_ai.input.messages` / `gen_ai.output.messages`,
|
|
86
87
|
* which should use the GenAI semantic-convention message shape; `recordMessages` inside the
|
|
87
|
-
* callback inherits the request metadata.
|
|
88
|
+
* callback inherits the request metadata. `options.systemInstructions` and `options.tools` are
|
|
89
|
+
* recorded as `gen_ai.system_instructions` and `gen_ai.tool.definitions`, content like `input`.
|
|
88
90
|
*/
|
|
89
91
|
model<T>(model: string, callback: (span: HueSpan) => Promise<T> | T, options: ModelOptions): Promise<T>;
|
|
90
92
|
private setUsage;
|
|
@@ -113,6 +115,8 @@ export declare class HueClient {
|
|
|
113
115
|
input?: unknown;
|
|
114
116
|
/** Output messages, ideally in the GenAI semantic-convention shape; any JSON-encodable value. */
|
|
115
117
|
output?: unknown;
|
|
118
|
+
/** System instructions sent separately from the messages, as `gen_ai.system_instructions`. */
|
|
119
|
+
systemInstructions?: unknown;
|
|
116
120
|
/** `gen_ai.operation.name` for the record; defaults to the enclosing `model()` span's value. */
|
|
117
121
|
operation?: string;
|
|
118
122
|
/** `gen_ai.provider.name` for the record; defaults to the enclosing `model()` span's value. */
|
|
@@ -120,6 +124,30 @@ export declare class HueClient {
|
|
|
120
124
|
/** `gen_ai.request.model` for the record; defaults to the enclosing `model()` span's value. */
|
|
121
125
|
model?: string;
|
|
122
126
|
}, explicitContext?: Context): void;
|
|
127
|
+
/**
|
|
128
|
+
* Records the tools a model provider executed itself while producing `response`, which no
|
|
129
|
+
* `hue.tool()` call saw: OpenAI Responses `mcp_call`, `web_search_call`, `file_search_call` and
|
|
130
|
+
* `code_interpreter_call` items, and Anthropic Messages `mcp_tool_use` / `server_tool_use`
|
|
131
|
+
* blocks with their result blocks. Each becomes an `execute_tool {name}` child span of the active
|
|
132
|
+
* (or given) context with `gen_ai.tool.type` `extension` and `gen_ai.tool.call.id`; MCP calls add
|
|
133
|
+
* `mcp.server.name` (the provider's label, or the `servers` entry for it). Arguments and results
|
|
134
|
+
* follow `captureContent`; a failed call carries `error.type` and ERROR status. An OpenAI
|
|
135
|
+
* `mcp_list_tools` item becomes a `tools/list` child span carrying that server's tools as
|
|
136
|
+
* `gen_ai.tool.definitions`. Call it inside `hue.model()` so the spans nest under the model call
|
|
137
|
+
* and `provider` defaults to its provider; pass `request` to record each server's host as
|
|
138
|
+
* `server.address`. The spans have no duration of their own: the provider ran the tools inside
|
|
139
|
+
* the model request. Unreadable items are skipped and counted; nothing is thrown.
|
|
140
|
+
*/
|
|
141
|
+
recordProviderToolCalls(response: unknown, options?: ProviderToolCallOptions): void;
|
|
142
|
+
/**
|
|
143
|
+
* Adds a `hue.file` event to the active (or given) span for a file the work read, received or
|
|
144
|
+
* produced: `hue.file.sha256`, `hue.file.role`, `hue.file.media_type`, `hue.file.size` when known
|
|
145
|
+
* and, when `captureContent` is true, `hue.file.name`. `data` is hashed and measured locally and
|
|
146
|
+
* never exported. The event is metadata, so it is recorded in both capture modes. An invalid
|
|
147
|
+
* record, or one without an active span, is omitted and counted, never thrown; an invalid name
|
|
148
|
+
* alone is omitted and counted while the rest is recorded.
|
|
149
|
+
*/
|
|
150
|
+
recordFile(file: FileRecord, explicitContext?: Context): void;
|
|
123
151
|
private setContent;
|
|
124
152
|
/**
|
|
125
153
|
* Confirms the key and origin by reading the current project; a setup and CI diagnostic, not a
|