@hue-run/sdk 0.23.0 → 0.23.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 +10 -10
- package/README.md +3 -3
- package/dist/client.js +86 -57
- 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.23.
|
|
45
|
+
not a completed integration. TypeScript uses `@hue-run/sdk@0.23.1`, `@opentelemetry/api@1.9.1` and
|
|
46
46
|
`@opentelemetry/context-async-hooks@2.11.0`; Python setup uses its separately tested package pin.
|
|
47
47
|
Content capture requires an ordinary account-managed key and a later explicit application decision.
|
|
48
48
|
|
|
@@ -381,8 +381,8 @@ and Hue never receives or stores them. The command is part of the `hue` executab
|
|
|
381
381
|
# LANGFUSE_PUBLIC_KEY=pk-lf-...
|
|
382
382
|
# LANGFUSE_SECRET_KEY=sk-lf-...
|
|
383
383
|
# LANGFUSE_BASE_URL=https://cloud.langfuse.com
|
|
384
|
-
npx -y @hue-run/sdk@0.23.
|
|
385
|
-
npx -y @hue-run/sdk@0.23.
|
|
384
|
+
npx -y @hue-run/sdk@0.23.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
385
|
+
npx -y @hue-run/sdk@0.23.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --media
|
|
386
386
|
```
|
|
387
387
|
|
|
388
388
|
`LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` come from the environment or `--env-path`
|
|
@@ -892,7 +892,7 @@ node packages/sdk-typescript/scripts/verify-package.mjs --artifacts-dir .artifac
|
|
|
892
892
|
# Set project to an existing supported fixture; use the same directory on resume.
|
|
893
893
|
project=/absolute/path/to/supported-fixture
|
|
894
894
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
895
|
-
--archive .artifacts/typescript/hue-run-sdk-0.23.
|
|
895
|
+
--archive .artifacts/typescript/hue-run-sdk-0.23.1.tgz \
|
|
896
896
|
--origin https://STAGING_ORIGIN \
|
|
897
897
|
--project "$project" --command setup \
|
|
898
898
|
--evidence .context/setup-staging-before-claim.json
|
|
@@ -903,7 +903,7 @@ the private local handoff and finish the real browser claim, then reconcile the
|
|
|
903
903
|
|
|
904
904
|
```sh
|
|
905
905
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
906
|
-
--archive .artifacts/typescript/hue-run-sdk-0.23.
|
|
906
|
+
--archive .artifacts/typescript/hue-run-sdk-0.23.1.tgz \
|
|
907
907
|
--origin https://STAGING_ORIGIN \
|
|
908
908
|
--project "$project" --command claim \
|
|
909
909
|
--evidence .context/setup-staging-after-claim.json
|
|
@@ -945,10 +945,10 @@ otherwise. Never hand the agent Hue-native tools (`context.tools`, `context.mcp`
|
|
|
945
945
|
production agent lacks. Pin the SDK, so the agent's repository gains no dependency:
|
|
946
946
|
|
|
947
947
|
```sh
|
|
948
|
-
npx -y @hue-run/sdk@0.23.
|
|
949
|
-
npx -y @hue-run/sdk@0.23.
|
|
950
|
-
npx -y @hue-run/sdk@0.23.
|
|
951
|
-
npx -y @hue-run/sdk@0.23.
|
|
948
|
+
npx -y @hue-run/sdk@0.23.1 eval --case "Refund an eligible charge" --command "node agent.js"
|
|
949
|
+
npx -y @hue-run/sdk@0.23.1 eval --case https://app.hue.run/projects/demo/scenarios/<id> --command "python agent.py" --timeout 120 --baseline <run id>
|
|
950
|
+
npx -y @hue-run/sdk@0.23.1 eval --set "Billing regressions" --scorer-version <id> --command "node agent.js" --save-version
|
|
951
|
+
npx -y @hue-run/sdk@0.23.1 eval --worker --command "node agent.js" --agent-key support-agent --revision <new-agent-revision>
|
|
952
952
|
```
|
|
953
953
|
|
|
954
954
|
One invocation creates one run holding every selected case; it prints the run URL
|
|
@@ -986,7 +986,7 @@ export default function runMyAgent(inputs: JsonValue, context: SimulationTargetC
|
|
|
986
986
|
```
|
|
987
987
|
|
|
988
988
|
```sh
|
|
989
|
-
npx -y @hue-run/sdk@0.23.
|
|
989
|
+
npx -y @hue-run/sdk@0.23.1 eval --case "Refund an eligible charge" ./hue-agent.ts --content
|
|
990
990
|
```
|
|
991
991
|
|
|
992
992
|
`--scenario` remains an alias for `--case` for existing scripts. Pass one selection flag.
|
package/README.md
CHANGED
|
@@ -552,8 +552,8 @@ the Langfuse project's own keys (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, a
|
|
|
552
552
|
`HUE_API_KEY`:
|
|
553
553
|
|
|
554
554
|
```sh
|
|
555
|
-
npx -y @hue-run/sdk@0.23.
|
|
556
|
-
npx -y @hue-run/sdk@0.23.
|
|
555
|
+
npx -y @hue-run/sdk@0.23.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
556
|
+
npx -y @hue-run/sdk@0.23.1 import langfuse --env-path .env.langfuse --from 2026-01-01 --media
|
|
557
557
|
```
|
|
558
558
|
|
|
559
559
|
- It reads Langfuse Cloud and self-hosted v4 through the Observations API v2, and self-hosted v3
|
|
@@ -1325,7 +1325,7 @@ existing-provider flush callbacks and recovery. Local/CI runners remain availabl
|
|
|
1325
1325
|
|
|
1326
1326
|
## Serving safely
|
|
1327
1327
|
|
|
1328
|
-
Use `createHueSafe(options)` for best-effort startup. Invalid initialization returns a disabled client that keeps your `onExportIssue` hook and records
|
|
1328
|
+
Use `createHueSafe(options)` for best-effort startup. Invalid initialization returns a disabled client that keeps your `onExportIssue` hook and records a fixed initialization-failure diagnostic without inspecting or exposing the original error. Pass `enabled: false` to disable Hue without a key or a `captureContent` choice; disabled helpers still execute the application callback, and `inject()` keeps propagating the application's own trace context. `flushSafe({ timeoutMillis: 1000 })` and `shutdownSafe({ timeoutMillis: 1000 })` return `{ ok, timedOut, report }` without rejecting. Strict initialization, connection checks and `flush()` remain available for diagnostics; do not gate application readiness or responses on them.
|
|
1329
1329
|
|
|
1330
1330
|
Capture/serialization/redaction/provider failures omit unsafe telemetry, record failures, and preserve the original business result/error. Async diagnostic rejections are contained; diagnostics are rate-limited. The default `maxQueueBytes` is 8 MiB across traces/logs including in-flight work, alongside the existing record cap. `pendingBytes` is a current queue gauge; `droppedSpans`, `droppedLogs` and `instrumentationFailures` are cumulative failure counters; `uploadedValues` and `uploadFallbacks` count completed uploads and upload fallbacks for whole attributes, eligible binary or large text media, and opt-in `recordFile` uploads. Whole-attribute fallbacks refused at export keep a prefix; media fallbacks keep a digest; helper upload fallbacks keep the file event; a value whose upload failed after export keeps its entry as well. This is a telemetry budget, not a total process memory ceiling. A timeout bounds the caller and does not cancel a borrowed provider. Never retry the business operation to recover telemetry. See [production setup](https://docs.hue.run/sdks/typescript#production-setup).
|
|
1331
1331
|
|
package/dist/client.js
CHANGED
|
@@ -370,6 +370,8 @@ export class HueClient {
|
|
|
370
370
|
* provider and surface as `hue.mcp.provider` / `hue.mcp.surface`.
|
|
371
371
|
*/
|
|
372
372
|
async tool(name, input, execute, options = {}) {
|
|
373
|
+
if (!this.enabled || this.closed)
|
|
374
|
+
return this.withSpan("execute_tool", () => execute());
|
|
373
375
|
const attributes = {
|
|
374
376
|
"gen_ai.operation.name": "execute_tool",
|
|
375
377
|
"gen_ai.tool.name": name,
|
|
@@ -380,22 +382,25 @@ export class HueClient {
|
|
|
380
382
|
// A blank or non-string label is omitted and counted; the tool call itself still runs.
|
|
381
383
|
if (isLabel(value))
|
|
382
384
|
attributes[key] = value;
|
|
383
|
-
else
|
|
385
|
+
else
|
|
384
386
|
this.instrumentationFailed();
|
|
385
387
|
};
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
388
|
+
let spanOptions = { attributes };
|
|
389
|
+
try {
|
|
390
|
+
stamp("gen_ai.tool.call.id", options.callId);
|
|
391
|
+
stamp("mcp.server.name", options.mcp?.name);
|
|
392
|
+
stamp("mcp.server.version", options.mcp?.version);
|
|
393
|
+
stamp("hue.mcp.provider", options.mcp?.provider);
|
|
394
|
+
stamp("hue.mcp.surface", options.mcp?.surface);
|
|
395
|
+
if (this.captureContent && options.endpoint !== undefined)
|
|
396
|
+
Object.assign(attributes, toolEndpointAttributes(options.endpoint));
|
|
397
|
+
spanOptions = {
|
|
398
|
+
attributes,
|
|
399
|
+
...(options.parentContext ? { parentContext: options.parentContext } : {}),
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
this.instrumentationFailed();
|
|
399
404
|
}
|
|
400
405
|
return this.withSpan(`execute_tool ${name}`, async ({ span }) => {
|
|
401
406
|
this.setContent(span, "gen_ai.tool.call.arguments", input);
|
|
@@ -403,10 +408,7 @@ export class HueClient {
|
|
|
403
408
|
if (result !== undefined)
|
|
404
409
|
this.setContent(span, "gen_ai.tool.call.result", result);
|
|
405
410
|
return result;
|
|
406
|
-
},
|
|
407
|
-
attributes,
|
|
408
|
-
...(options.parentContext ? { parentContext: options.parentContext } : {}),
|
|
409
|
-
});
|
|
411
|
+
}, spanOptions);
|
|
410
412
|
}
|
|
411
413
|
/**
|
|
412
414
|
* Runs `callback` as a sub-agent: inside an `invoke_agent {name}` span carrying
|
|
@@ -420,11 +422,27 @@ export class HueClient {
|
|
|
420
422
|
* in `withSpan`. A blank or non-string name is recorded as `unknown` and counted.
|
|
421
423
|
*/
|
|
422
424
|
async subagent(name, callback, options = {}) {
|
|
425
|
+
if (!this.enabled || this.closed)
|
|
426
|
+
return this.withSpan("invoke_agent", callback);
|
|
423
427
|
let agent = name;
|
|
424
428
|
if (!isLabel(name)) {
|
|
425
429
|
agent = "unknown";
|
|
426
|
-
|
|
427
|
-
|
|
430
|
+
this.instrumentationFailed();
|
|
431
|
+
}
|
|
432
|
+
let spanOptions = {};
|
|
433
|
+
try {
|
|
434
|
+
spanOptions = {
|
|
435
|
+
...options,
|
|
436
|
+
attributes: {
|
|
437
|
+
...options.attributes,
|
|
438
|
+
"gen_ai.operation.name": "invoke_agent",
|
|
439
|
+
"gen_ai.agent.name": agent,
|
|
440
|
+
"hue.agent.role": "subagent",
|
|
441
|
+
},
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
this.instrumentationFailed();
|
|
428
446
|
}
|
|
429
447
|
return this.withSpan(`invoke_agent ${agent}`, async (span) => {
|
|
430
448
|
let outputSet = false;
|
|
@@ -438,15 +456,7 @@ export class HueClient {
|
|
|
438
456
|
if (result !== undefined && !outputSet)
|
|
439
457
|
span.setOutput(result);
|
|
440
458
|
return result;
|
|
441
|
-
},
|
|
442
|
-
...options,
|
|
443
|
-
attributes: {
|
|
444
|
-
...options.attributes,
|
|
445
|
-
"gen_ai.operation.name": "invoke_agent",
|
|
446
|
-
"gen_ai.agent.name": agent,
|
|
447
|
-
"hue.agent.role": "subagent",
|
|
448
|
-
},
|
|
449
|
-
});
|
|
459
|
+
}, spanOptions);
|
|
450
460
|
}
|
|
451
461
|
/**
|
|
452
462
|
* Runs `callback` inside a GenAI client span for one direct provider call, named
|
|
@@ -458,24 +468,44 @@ export class HueClient {
|
|
|
458
468
|
* recorded as `gen_ai.system_instructions` and `gen_ai.tool.definitions`, content like `input`.
|
|
459
469
|
*/
|
|
460
470
|
async model(model, callback, options) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
471
|
+
if (!this.enabled || this.closed)
|
|
472
|
+
return this.withSpan("model", callback);
|
|
473
|
+
let prepared = { provider: "unknown" };
|
|
474
|
+
try {
|
|
475
|
+
prepared = {
|
|
476
|
+
operation: options?.operation,
|
|
477
|
+
provider: options?.provider,
|
|
478
|
+
name: options?.name,
|
|
479
|
+
sessionId: options?.sessionId,
|
|
480
|
+
userId: options?.userId,
|
|
481
|
+
workspaceId: options?.workspaceId,
|
|
482
|
+
parentContext: options?.parentContext,
|
|
483
|
+
...(this.captureContent
|
|
484
|
+
? {
|
|
485
|
+
input: options?.input,
|
|
486
|
+
systemInstructions: options?.systemInstructions,
|
|
487
|
+
tools: options?.tools,
|
|
488
|
+
}
|
|
489
|
+
: {}),
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
this.instrumentationFailed();
|
|
494
|
+
}
|
|
464
495
|
const label = (value, fallback) => {
|
|
465
496
|
if (isLabel(value))
|
|
466
497
|
return value;
|
|
467
|
-
|
|
468
|
-
this.instrumentationFailed();
|
|
498
|
+
this.instrumentationFailed();
|
|
469
499
|
return fallback;
|
|
470
500
|
};
|
|
471
501
|
const requestModel = label(model, "unknown");
|
|
472
|
-
const operation = label(
|
|
473
|
-
const provider = label(
|
|
474
|
-
const name =
|
|
502
|
+
const operation = label(prepared.operation ?? "chat", "chat");
|
|
503
|
+
const provider = label(prepared.provider, "unknown");
|
|
504
|
+
const name = prepared.name === undefined
|
|
475
505
|
? `${operation} ${requestModel}`
|
|
476
|
-
: label(
|
|
506
|
+
: label(prepared.name, `${operation} ${requestModel}`);
|
|
477
507
|
const metadata = { operation, provider, requestModel };
|
|
478
|
-
const { sessionId, userId, workspaceId, parentContext, input, systemInstructions, tools
|
|
508
|
+
const { sessionId, userId, workspaceId, parentContext, input, systemInstructions, tools } = prepared;
|
|
479
509
|
return this.withSpan(name, (span) => {
|
|
480
510
|
const handle = {
|
|
481
511
|
...span,
|
|
@@ -507,22 +537,22 @@ export class HueClient {
|
|
|
507
537
|
setUsage(span, usage) {
|
|
508
538
|
if (!this.enabled || this.closed)
|
|
509
539
|
return;
|
|
510
|
-
|
|
511
|
-
[
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
540
|
+
try {
|
|
541
|
+
for (const [key, value] of [
|
|
542
|
+
["gen_ai.usage.input_tokens", usage?.inputTokens],
|
|
543
|
+
["gen_ai.usage.output_tokens", usage?.outputTokens],
|
|
544
|
+
]) {
|
|
545
|
+
if (value === undefined)
|
|
546
|
+
continue;
|
|
547
|
+
if (!Number.isInteger(value) || value < 0) {
|
|
548
|
+
this.instrumentationFailed();
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
521
551
|
span.setAttribute(key, value);
|
|
522
552
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
553
|
+
}
|
|
554
|
+
catch {
|
|
555
|
+
this.instrumentationFailed();
|
|
526
556
|
}
|
|
527
557
|
}
|
|
528
558
|
/**
|
|
@@ -1275,11 +1305,10 @@ export function createHueSafe(options) {
|
|
|
1275
1305
|
try {
|
|
1276
1306
|
return new HueClient(options);
|
|
1277
1307
|
}
|
|
1278
|
-
catch
|
|
1279
|
-
//
|
|
1308
|
+
catch {
|
|
1309
|
+
// Provider errors can contain credentials or expose throwing message accessors.
|
|
1280
1310
|
const disabled = new HueClient({ enabled: false, onExportIssue: issueCallback(options) });
|
|
1281
|
-
|
|
1282
|
-
disabled.transport.instrumentationFailure("traces", `Hue is disabled: ${reason.slice(0, 256)}`);
|
|
1311
|
+
disabled.transport.instrumentationFailure("traces", "Hue is disabled: initialization failed");
|
|
1283
1312
|
return disabled;
|
|
1284
1313
|
}
|
|
1285
1314
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Package version shared by the instrumentation scope and the export User-Agent. */
|
|
2
|
-
export declare const sdkVersion = "0.23.
|
|
2
|
+
export declare const sdkVersion = "0.23.1";
|
|
3
3
|
/** OTLP dependency version sent in the export User-Agent. */
|
|
4
4
|
export declare const otlpExporterVersion = "0.223.0";
|
package/dist/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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.23.
|
|
3
|
+
export const sdkVersion = "0.23.1";
|
|
4
4
|
/** OTLP dependency version sent in the export User-Agent. */
|
|
5
5
|
export const otlpExporterVersion = "0.223.0";
|