@hue-run/sdk 0.20.6 → 0.20.7
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 -13
- package/README.md +2 -2
- package/dist/cli/traces-import-convert.d.ts +6 -3
- package/dist/cli/traces-import-convert.js +7 -4
- package/dist/cli/traces-import-prepare.d.ts +3 -0
- package/dist/cli/traces-import-prepare.js +16 -2
- package/dist/cli/traces-import-upload.js +5 -1
- 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.20.
|
|
45
|
+
not a completed integration. TypeScript uses `@hue-run/sdk@0.20.7`, `@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.20.
|
|
385
|
-
npx -y @hue-run/sdk@0.20.
|
|
384
|
+
npx -y @hue-run/sdk@0.20.7 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
385
|
+
npx -y @hue-run/sdk@0.20.7 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`
|
|
@@ -536,8 +536,9 @@ instrumentation scope `hue.import.atif`, and the run's agent span is named `invo
|
|
|
536
536
|
<agent.name>` from the export's own agent. ATIF records instants, not durations, so model and tool
|
|
537
537
|
spans are points in time, and a tool's result is kept as text with no error status of the
|
|
538
538
|
importer's making. The same trace in two files is one trace when the copies agree and a refusal
|
|
539
|
-
when they differ; a trace with more than 100,000 spans,
|
|
540
|
-
named
|
|
539
|
+
when they differ; a trace with more than 100,000 spans, 512 batches or 10,000 values is refused and
|
|
540
|
+
named, and an input of more than 25,000 traces, or whose manifest would exceed 32 MiB (4 MiB
|
|
541
|
+
compressed), is refused whole. Nothing about where a file sat or what it was called reaches a span: a renamed, reordered
|
|
541
542
|
or re-zipped copy of the bundle prepares to byte-identical batches and the same manifest digest.
|
|
542
543
|
|
|
543
544
|
The report (`--json` prints it as one object) names `manifest_digest`, `totals` (traces, batches,
|
|
@@ -553,7 +554,7 @@ no upload has started in it.
|
|
|
553
554
|
|
|
554
555
|
**Authorize.** Call `prepare_trace_import` over the Hue MCP with the report's `manifest_digest`,
|
|
555
556
|
`totals` and `source`. It answers the import id, `upload_url` and an `authorization` (`hue_it_` and
|
|
556
|
-
43 characters) valid for
|
|
557
|
+
43 characters) valid for a day. Save its answer, or the authorization alone, in a private file
|
|
557
558
|
(mode 0600; never in a transcript, a message or a shell history). The same digest in the same
|
|
558
559
|
project is the same import: calling again renews the authorization for an interrupted upload and
|
|
559
560
|
revokes the earlier one.
|
|
@@ -697,7 +698,7 @@ node packages/sdk-typescript/scripts/verify-package.mjs --artifacts-dir .artifac
|
|
|
697
698
|
# Set project to an existing supported fixture; use the same directory on resume.
|
|
698
699
|
project=/absolute/path/to/supported-fixture
|
|
699
700
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
700
|
-
--archive .artifacts/typescript/hue-run-sdk-0.20.
|
|
701
|
+
--archive .artifacts/typescript/hue-run-sdk-0.20.7.tgz \
|
|
701
702
|
--origin https://STAGING_ORIGIN \
|
|
702
703
|
--project "$project" --command setup \
|
|
703
704
|
--evidence .context/setup-staging-before-claim.json
|
|
@@ -708,7 +709,7 @@ the private local handoff and finish the real browser claim, then reconcile the
|
|
|
708
709
|
|
|
709
710
|
```sh
|
|
710
711
|
node packages/sdk-typescript/scripts/verify-setup-live.mjs \
|
|
711
|
-
--archive .artifacts/typescript/hue-run-sdk-0.20.
|
|
712
|
+
--archive .artifacts/typescript/hue-run-sdk-0.20.7.tgz \
|
|
712
713
|
--origin https://STAGING_ORIGIN \
|
|
713
714
|
--project "$project" --command claim \
|
|
714
715
|
--evidence .context/setup-staging-after-claim.json
|
|
@@ -750,10 +751,10 @@ otherwise. Never hand the agent Hue-native tools (`context.tools`, `context.mcp`
|
|
|
750
751
|
production agent lacks. Pin the SDK, so the agent's repository gains no dependency:
|
|
751
752
|
|
|
752
753
|
```sh
|
|
753
|
-
npx -y @hue-run/sdk@0.20.
|
|
754
|
-
npx -y @hue-run/sdk@0.20.
|
|
755
|
-
npx -y @hue-run/sdk@0.20.
|
|
756
|
-
npx -y @hue-run/sdk@0.20.
|
|
754
|
+
npx -y @hue-run/sdk@0.20.7 eval --case "Refund an eligible charge" --command "node agent.js"
|
|
755
|
+
npx -y @hue-run/sdk@0.20.7 eval --case https://app.hue.run/projects/demo/scenarios/<id> --command "python agent.py" --timeout 120 --baseline <run id>
|
|
756
|
+
npx -y @hue-run/sdk@0.20.7 eval --set "Billing regressions" --scorer-version <id> --command "node agent.js" --save-version
|
|
757
|
+
npx -y @hue-run/sdk@0.20.7 eval --worker --command "node agent.js" --agent-key support-agent --revision <new-agent-revision>
|
|
757
758
|
```
|
|
758
759
|
|
|
759
760
|
One invocation creates one run holding every selected case; it prints the run URL
|
|
@@ -791,7 +792,7 @@ export default function runMyAgent(inputs: JsonValue, context: SimulationTargetC
|
|
|
791
792
|
```
|
|
792
793
|
|
|
793
794
|
```sh
|
|
794
|
-
npx -y @hue-run/sdk@0.20.
|
|
795
|
+
npx -y @hue-run/sdk@0.20.7 eval --case "Refund an eligible charge" ./hue-agent.ts --content
|
|
795
796
|
```
|
|
796
797
|
|
|
797
798
|
`--scenario` remains an alias for `--case` for existing scripts. Pass one selection flag.
|
package/README.md
CHANGED
|
@@ -536,8 +536,8 @@ the Langfuse project's own keys (`LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`, a
|
|
|
536
536
|
`HUE_API_KEY`:
|
|
537
537
|
|
|
538
538
|
```sh
|
|
539
|
-
npx -y @hue-run/sdk@0.20.
|
|
540
|
-
npx -y @hue-run/sdk@0.20.
|
|
539
|
+
npx -y @hue-run/sdk@0.20.7 import langfuse --env-path .env.langfuse --from 2026-01-01 --dry-run
|
|
540
|
+
npx -y @hue-run/sdk@0.20.7 import langfuse --env-path .env.langfuse --from 2026-01-01 --media
|
|
541
541
|
```
|
|
542
542
|
|
|
543
543
|
- It reads Langfuse Cloud and self-hosted v4 through the Observations API v2, and self-hosted v3
|
|
@@ -12,11 +12,14 @@ export declare const traceImportOrigins: readonly ["production", "evaluation", "
|
|
|
12
12
|
export type TraceImportOrigin = (typeof traceImportOrigins)[number];
|
|
13
13
|
/** The bounds the import routes hold a manifest to. */
|
|
14
14
|
export declare const traceImportLimits: {
|
|
15
|
-
readonly traces:
|
|
16
|
-
readonly batchesPerTrace:
|
|
17
|
-
readonly blobsPerTrace:
|
|
15
|
+
readonly traces: 25000;
|
|
16
|
+
readonly batchesPerTrace: 512;
|
|
17
|
+
readonly blobsPerTrace: 10000;
|
|
18
18
|
readonly spansPerTrace: 100000;
|
|
19
|
+
/** The manifest decoded. */
|
|
19
20
|
readonly manifestBytes: number;
|
|
21
|
+
/** The manifest as registration takes it, gzip. */
|
|
22
|
+
readonly manifestWireBytes: number;
|
|
20
23
|
readonly batchBytes: number;
|
|
21
24
|
readonly blobBytes: 1000000000;
|
|
22
25
|
};
|
|
@@ -17,11 +17,14 @@ export const traceImportFormats = ["otlp_json", "langfuse_observations", "atif"]
|
|
|
17
17
|
export const traceImportOrigins = ["production", "evaluation", "simulation", "unknown"];
|
|
18
18
|
/** The bounds the import routes hold a manifest to. */
|
|
19
19
|
export const traceImportLimits = {
|
|
20
|
-
traces:
|
|
21
|
-
batchesPerTrace:
|
|
22
|
-
blobsPerTrace:
|
|
20
|
+
traces: 25_000,
|
|
21
|
+
batchesPerTrace: 512,
|
|
22
|
+
blobsPerTrace: 10_000,
|
|
23
23
|
spansPerTrace: 100_000,
|
|
24
|
-
|
|
24
|
+
/** The manifest decoded. */
|
|
25
|
+
manifestBytes: 32 * 1024 * 1024,
|
|
26
|
+
/** The manifest as registration takes it, gzip. */
|
|
27
|
+
manifestWireBytes: 4 * 1024 * 1024,
|
|
25
28
|
batchBytes: 4 * 1024 * 1024,
|
|
26
29
|
blobBytes: 1_000_000_000,
|
|
27
30
|
};
|
|
@@ -57,6 +57,9 @@ export declare class PrepareError extends Error {
|
|
|
57
57
|
}
|
|
58
58
|
/** The default output directory: `<input>.hue-import` beside the input. */
|
|
59
59
|
export declare function defaultOutputDirectory(input: string): string;
|
|
60
|
+
/** Why a manifest cannot be registered, or undefined: Hue reads at most 32 MiB decoded and takes
|
|
61
|
+
* at most 4 MiB on the wire, gzip as the upload sends it. Checked here, before any upload. */
|
|
62
|
+
export declare function manifestTooLarge(bytes: Uint8Array): string | undefined;
|
|
60
63
|
export interface PrepareOptions {
|
|
61
64
|
out?: string;
|
|
62
65
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { mkdir, open, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { gzipSync } from "node:zlib";
|
|
4
5
|
import { sdkVersion } from "../version.js";
|
|
5
6
|
import { batchEntries, ConversionError, convertAtifExport, detectFormat, LangfuseTraceCollector, manifestTotals, manifestTraceHasIdentity, OtlpTraceCollector, sha256Hex, traceImportFormats, traceImportLimits, validateManifest, } from "./traces-import-convert.js";
|
|
6
7
|
import { isZipSignature, ZipArchive, ZipError } from "./traces-import-zip.js";
|
|
@@ -193,6 +194,18 @@ async function prepareOutputDirectory(directory) {
|
|
|
193
194
|
await rm(path, { force: true });
|
|
194
195
|
}
|
|
195
196
|
}
|
|
197
|
+
/** Why a manifest cannot be registered, or undefined: Hue reads at most 32 MiB decoded and takes
|
|
198
|
+
* at most 4 MiB on the wire, gzip as the upload sends it. Checked here, before any upload. */
|
|
199
|
+
export function manifestTooLarge(bytes) {
|
|
200
|
+
// No division by a name: the published package's import-boundary check reads one as a regex.
|
|
201
|
+
const mebibytes = (value) => `${Math.ceil(value * 2 ** -20)} MiB`;
|
|
202
|
+
if (bytes.byteLength > traceImportLimits.manifestBytes)
|
|
203
|
+
return `The manifest is ${mebibytes(bytes.byteLength)}, over the ${mebibytes(traceImportLimits.manifestBytes)} Hue reads; prepare the input in smaller parts`;
|
|
204
|
+
const wire = gzipSync(bytes, { level: 6 }).byteLength;
|
|
205
|
+
if (wire > traceImportLimits.manifestWireBytes)
|
|
206
|
+
return `The manifest is ${mebibytes(wire)} compressed, over the ${mebibytes(traceImportLimits.manifestWireBytes)} a registration takes; prepare the input in smaller parts`;
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
196
209
|
async function writePrivate(path, bytes) {
|
|
197
210
|
const temporary = `${path}.tmp`;
|
|
198
211
|
await writeFile(temporary, bytes, { mode: 0o600, flag: "w" });
|
|
@@ -422,8 +435,9 @@ export async function prepareTraceBundle(input, options = {}) {
|
|
|
422
435
|
if (invalid)
|
|
423
436
|
throw new PrepareError(`The prepared manifest is not valid: ${invalid}`);
|
|
424
437
|
const bytes = Buffer.from(JSON.stringify(manifest), "utf8");
|
|
425
|
-
|
|
426
|
-
|
|
438
|
+
const tooLarge = manifestTooLarge(bytes);
|
|
439
|
+
if (tooLarge)
|
|
440
|
+
throw new PrepareError(tooLarge);
|
|
427
441
|
await writePrivate(join(outputDirectory, MANIFEST_FILE), bytes);
|
|
428
442
|
return {
|
|
429
443
|
manifest_digest: createHash("sha256").update(bytes).digest("hex"),
|
|
@@ -3,7 +3,7 @@ import { join } from "node:path";
|
|
|
3
3
|
import { gunzipSync, gzipSync } from "node:zlib";
|
|
4
4
|
import { sdkVersion } from "../version.js";
|
|
5
5
|
import { manifestTotals, sha256Hex, validateManifest, } from "./traces-import-convert.js";
|
|
6
|
-
import { MANIFEST_FILE, PROGRESS_FILE } from "./traces-import-prepare.js";
|
|
6
|
+
import { MANIFEST_FILE, manifestTooLarge, PROGRESS_FILE } from "./traces-import-prepare.js";
|
|
7
7
|
/**
|
|
8
8
|
* `hue traces import upload`: delivers a prepared bundle to Hue's import routes with the
|
|
9
9
|
* short-lived import authorization `prepare_trace_import` minted. The manifest's exact bytes
|
|
@@ -229,6 +229,10 @@ export async function uploadTraceBundle(options, io = {}) {
|
|
|
229
229
|
const invalid = validateManifest(manifest);
|
|
230
230
|
if (invalid)
|
|
231
231
|
throw new UploadStop(`${MANIFEST_FILE} is not valid: ${invalid}`, "bundle_invalid");
|
|
232
|
+
// A manifest registration would refuse (413) is refused here, before anything is sent.
|
|
233
|
+
const tooLarge = manifestTooLarge(manifestBytes);
|
|
234
|
+
if (tooLarge)
|
|
235
|
+
throw new UploadStop(tooLarge, "bundle_invalid");
|
|
232
236
|
const manifestDigest = sha256Hex(manifestBytes);
|
|
233
237
|
const totals = manifestTotals(manifest);
|
|
234
238
|
// Every declared file must be present before the first request: a bundle missing a batch
|
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.20.
|
|
2
|
+
export declare const sdkVersion = "0.20.7";
|
package/dist/version.js
CHANGED