@hue-run/sdk 0.20.1 → 0.20.3
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 +102 -10
- package/ENVIRONMENTS.md +1 -1
- package/EVALUATIONS.md +3 -1
- package/README.md +30 -2
- package/dist/cli/eval.js +90 -34
- package/dist/cli/traces-import-convert.d.ts +262 -0
- package/dist/cli/traces-import-convert.js +1779 -0
- package/dist/cli/traces-import-prepare.d.ts +64 -0
- package/dist/cli/traces-import-prepare.js +443 -0
- package/dist/cli/traces-import-upload.d.ts +129 -0
- package/dist/cli/traces-import-upload.js +838 -0
- package/dist/cli/traces-import-zip.d.ts +52 -0
- package/dist/cli/traces-import-zip.js +278 -0
- package/dist/cli/traces-import.d.ts +18 -0
- package/dist/cli/traces-import.js +231 -0
- package/dist/evals/runner.d.ts +5 -2
- package/dist/evals/runner.js +31 -5
- package/dist/evals/simulation.d.ts +4 -0
- package/dist/evals/simulation.js +24 -26
- package/dist/setup/cli.js +7 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/world/world.d.ts +3 -2
- package/dist/world/world.js +4 -2
- package/package.json +1 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The conversions behind `hue traces import prepare`: a source file is recognized by its content
|
|
3
|
+
* (an OTLP/JSON trace export, a complete Langfuse observation export or a text ATIF export),
|
|
4
|
+
* each trace becomes OTLP/JSON entries, one span each, that keep the recorded ids, hierarchy,
|
|
5
|
+
* timestamps, content, errors and usage, and the entries are packed into deterministic gzip
|
|
6
|
+
* batches. Nothing here depends on where a file sat or what it was called: a renamed or repacked
|
|
7
|
+
* bundle converts to byte-identical batches, so the manifest's digests name the same import.
|
|
8
|
+
*/
|
|
9
|
+
export declare const traceImportFormats: readonly ["otlp_json", "langfuse_observations", "atif"];
|
|
10
|
+
export type TraceImportFormat = (typeof traceImportFormats)[number];
|
|
11
|
+
export declare const traceImportOrigins: readonly ["production", "evaluation", "simulation", "unknown"];
|
|
12
|
+
export type TraceImportOrigin = (typeof traceImportOrigins)[number];
|
|
13
|
+
/** The bounds the import routes hold a manifest to. */
|
|
14
|
+
export declare const traceImportLimits: {
|
|
15
|
+
readonly traces: 10000;
|
|
16
|
+
readonly batchesPerTrace: 64;
|
|
17
|
+
readonly blobsPerTrace: 1000;
|
|
18
|
+
readonly spansPerTrace: 100000;
|
|
19
|
+
readonly manifestBytes: number;
|
|
20
|
+
readonly batchBytes: number;
|
|
21
|
+
readonly blobBytes: 1000000000;
|
|
22
|
+
};
|
|
23
|
+
/** One batch, decoded, and on the wire: well inside the receiver's request bounds. */
|
|
24
|
+
export declare const MAX_BATCH_DECODED_BYTES: number;
|
|
25
|
+
export declare const MAX_BATCH_WIRE_BYTES: number;
|
|
26
|
+
/** The largest value a record keeps inline; a longer text is stored apart from its span. */
|
|
27
|
+
export declare const MAX_INLINE_VALUE_BYTES: number;
|
|
28
|
+
export declare const SOURCE_RECORD = "hue.import.source_record";
|
|
29
|
+
export declare const SOURCE_ENVELOPE = "hue.import.source_envelope";
|
|
30
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
31
|
+
[key: string]: JsonValue;
|
|
32
|
+
};
|
|
33
|
+
export interface OtlpValue {
|
|
34
|
+
stringValue?: string;
|
|
35
|
+
boolValue?: boolean;
|
|
36
|
+
intValue?: string;
|
|
37
|
+
doubleValue?: number;
|
|
38
|
+
arrayValue?: {
|
|
39
|
+
values: OtlpValue[];
|
|
40
|
+
};
|
|
41
|
+
kvlistValue?: {
|
|
42
|
+
values: OtlpAttribute[];
|
|
43
|
+
};
|
|
44
|
+
bytesValue?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface OtlpAttribute {
|
|
47
|
+
key: string;
|
|
48
|
+
value: OtlpValue;
|
|
49
|
+
}
|
|
50
|
+
export type ImportSpan = {
|
|
51
|
+
traceId: string;
|
|
52
|
+
spanId: string;
|
|
53
|
+
parentSpanId?: string;
|
|
54
|
+
name: string;
|
|
55
|
+
kind: number;
|
|
56
|
+
startTimeUnixNano: string;
|
|
57
|
+
endTimeUnixNano: string;
|
|
58
|
+
attributes: OtlpAttribute[];
|
|
59
|
+
status: {
|
|
60
|
+
code: number;
|
|
61
|
+
message?: string;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/** One resource group holding one scope group holding one span: the unit the packer serializes.
|
|
65
|
+
* A converted span is an {@link ImportSpan}; an OTLP/JSON span is kept as recorded. */
|
|
66
|
+
export interface ImportEntry {
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
scopeSpans: {
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
spans: Record<string, unknown>[];
|
|
71
|
+
}[];
|
|
72
|
+
}
|
|
73
|
+
export interface TraceIdentity {
|
|
74
|
+
user?: string;
|
|
75
|
+
entity?: {
|
|
76
|
+
namespace: string;
|
|
77
|
+
id: string;
|
|
78
|
+
};
|
|
79
|
+
session?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface PreparedBlob {
|
|
82
|
+
sha256: string;
|
|
83
|
+
byteSize: number;
|
|
84
|
+
contentType: string;
|
|
85
|
+
bytes: Uint8Array;
|
|
86
|
+
}
|
|
87
|
+
export interface ConvertedTrace {
|
|
88
|
+
traceId: string;
|
|
89
|
+
format: TraceImportFormat;
|
|
90
|
+
entries: ImportEntry[];
|
|
91
|
+
blobs: PreparedBlob[];
|
|
92
|
+
identity?: TraceIdentity;
|
|
93
|
+
origin: TraceImportOrigin;
|
|
94
|
+
/** The SHA-256 of every source file that held part of the trace. */
|
|
95
|
+
sourceDigests: Set<string>;
|
|
96
|
+
remappedTraceId: boolean;
|
|
97
|
+
remappedSpans: number;
|
|
98
|
+
}
|
|
99
|
+
/** A trace, span or file that was not converted, and why. */
|
|
100
|
+
export interface Refusal {
|
|
101
|
+
traceId?: string;
|
|
102
|
+
reason: string;
|
|
103
|
+
}
|
|
104
|
+
export declare class ConversionError extends Error {
|
|
105
|
+
}
|
|
106
|
+
export declare const sha256Hex: (value: string | Uint8Array) => string;
|
|
107
|
+
/**
|
|
108
|
+
* JSON text parsed with every integer too large for a JavaScript number kept as its decimal
|
|
109
|
+
* text, so an OTLP timestamp written as a number keeps its nanoseconds. `unsafeIntegers` says
|
|
110
|
+
* whether any was found; the Langfuse and ATIF readers refuse such a file, as Hue's do.
|
|
111
|
+
*/
|
|
112
|
+
export declare function parseJsonText(text: string): {
|
|
113
|
+
value: unknown;
|
|
114
|
+
unsafeIntegers: boolean;
|
|
115
|
+
};
|
|
116
|
+
/** Refuses a source value that JavaScript or OTLP cannot retain exactly; never omits it. */
|
|
117
|
+
export declare function validateSource(value: JsonValue, depth?: number): void;
|
|
118
|
+
/** JSON.parse otherwise loses duplicate members and can round decimal argument values. */
|
|
119
|
+
export declare function validateJsonText(raw: string): void;
|
|
120
|
+
export type DetectedSource = {
|
|
121
|
+
format: "otlp_json";
|
|
122
|
+
envelopes: Record<string, unknown>[];
|
|
123
|
+
} | {
|
|
124
|
+
format: "langfuse_observations";
|
|
125
|
+
observations: Record<string, JsonValue>[];
|
|
126
|
+
envelope: Record<string, JsonValue>;
|
|
127
|
+
unsafeIntegers: boolean;
|
|
128
|
+
} | {
|
|
129
|
+
format: "atif";
|
|
130
|
+
text: string;
|
|
131
|
+
document: unknown;
|
|
132
|
+
unsafeIntegers: boolean;
|
|
133
|
+
} | {
|
|
134
|
+
format: "unsupported";
|
|
135
|
+
reason: string;
|
|
136
|
+
};
|
|
137
|
+
/** What a file holds, read from its content alone; never from its name. */
|
|
138
|
+
export declare function detectFormat(bytes: Uint8Array): DetectedSource;
|
|
139
|
+
export declare function anyValue(value: JsonValue): OtlpValue;
|
|
140
|
+
/** The large values one trace stores apart from its spans, each once by digest. */
|
|
141
|
+
export declare class BlobSink {
|
|
142
|
+
readonly blobs: Map<string, PreparedBlob>;
|
|
143
|
+
/** Stores a text whole and returns what its record keeps: the first 16 KiB and the `hue.blobs`
|
|
144
|
+
* entry; undefined when the text is over the limit of one stored value. */
|
|
145
|
+
place(key: string, text: string): {
|
|
146
|
+
prefix: string;
|
|
147
|
+
entry: string;
|
|
148
|
+
} | undefined;
|
|
149
|
+
/** The values in digest order: the manifest lists a trace's values the same whatever order its
|
|
150
|
+
* sources were read in, so renaming or repacking them keeps the manifest digest. */
|
|
151
|
+
sorted(): PreparedBlob[];
|
|
152
|
+
}
|
|
153
|
+
/** A converted span's attributes: a value over the inline limit is stored apart from the span
|
|
154
|
+
* through the trace's {@link BlobSink} and listed in `hue.blobs`, as the SDK's exporter lists
|
|
155
|
+
* the values it uploads, with the key in `hue.truncated`. */
|
|
156
|
+
export declare class AttributeList {
|
|
157
|
+
private readonly blobs;
|
|
158
|
+
readonly values: OtlpAttribute[];
|
|
159
|
+
private readonly listed;
|
|
160
|
+
private readonly truncated;
|
|
161
|
+
constructor(blobs: BlobSink);
|
|
162
|
+
add(key: string, value: JsonValue): void;
|
|
163
|
+
json(key: string, value: unknown): void;
|
|
164
|
+
finish(): OtlpAttribute[];
|
|
165
|
+
}
|
|
166
|
+
/** Gathers the spans of OTLP/JSON exports by trace, across files: an export writes a trace's
|
|
167
|
+
* spans in the requests that carried them, which need not be one file. */
|
|
168
|
+
export declare class OtlpTraceCollector {
|
|
169
|
+
private readonly traces;
|
|
170
|
+
/** Adds every span of the envelopes; the spans refused, with their reasons. */
|
|
171
|
+
add(envelopes: readonly Record<string, unknown>[], sourceDigest: string): Refusal[];
|
|
172
|
+
private addSpan;
|
|
173
|
+
/** Every trace gathered so far, spans in time order, and the traces refused whole. */
|
|
174
|
+
finish(): {
|
|
175
|
+
traces: ConvertedTrace[];
|
|
176
|
+
refused: Refusal[];
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
export declare function unixNano(value: JsonValue | undefined): string;
|
|
180
|
+
/** Gathers Langfuse observations by trace across files and converts each trace as Hue's reader
|
|
181
|
+
* converts an observation export: one span per observation, the record kept whole. */
|
|
182
|
+
export declare class LangfuseTraceCollector {
|
|
183
|
+
private readonly traces;
|
|
184
|
+
add(observations: readonly Record<string, JsonValue>[], envelope: Record<string, JsonValue>, sourceDigest: string): void;
|
|
185
|
+
finish(): {
|
|
186
|
+
traces: ConvertedTrace[];
|
|
187
|
+
refused: Refusal[];
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/** The ATIF reader's bounds: a text export of at most 4 MiB and 2,000 spans. */
|
|
191
|
+
export declare const MAX_ATIF_FILE_BYTES: number;
|
|
192
|
+
export declare const MAX_ATIF_SPANS = 2000;
|
|
193
|
+
/** Retains nanoseconds and requires an explicit timezone, valid calendar date and OTLP uint64. */
|
|
194
|
+
export declare function atifUnixNano(value: string): string;
|
|
195
|
+
/**
|
|
196
|
+
* A text ATIF v1.7 or v1.8 export as one trace: an agent span for the run, a model span per
|
|
197
|
+
* agent step with the conversation so far, a tool span per call under it, and an embedded
|
|
198
|
+
* subagent trajectory as its own agent span under the tool span of the call that spawned it.
|
|
199
|
+
* Identity is run scoped (`session_id` and `trajectory_id`), never a path. The complete original
|
|
200
|
+
* document stays on the root; each model and tool span keeps its own record. ATIF supplies step
|
|
201
|
+
* instants, not call durations: model and tool spans are zero-duration point spans.
|
|
202
|
+
*/
|
|
203
|
+
export declare function convertAtifExport(source: Extract<DetectedSource, {
|
|
204
|
+
format: "atif";
|
|
205
|
+
}>, rawBytes: number): ConvertedTrace;
|
|
206
|
+
export interface PreparedBatch {
|
|
207
|
+
sha256: string;
|
|
208
|
+
body: Uint8Array;
|
|
209
|
+
decodedBytes: number;
|
|
210
|
+
spanIds: string[];
|
|
211
|
+
}
|
|
212
|
+
/** `Math.floor(numerator / divisor)` for safe nonnegative integers, without a division: the
|
|
213
|
+
* published package's import-boundary check reads a `/` after a name as a regular expression, so
|
|
214
|
+
* the quotient is estimated from the reciprocal and corrected by whole steps, which makes it
|
|
215
|
+
* exact on every engine. */
|
|
216
|
+
export declare function integerQuotient(numerator: number, divisor: number): number;
|
|
217
|
+
/**
|
|
218
|
+
* The trace's entries packed into gzip OTLP/JSON batches in order, each at most 3 MiB decoded
|
|
219
|
+
* and 900 KiB on the wire. Packing is linear and the output depends on the entries alone, so the
|
|
220
|
+
* same trace packs to the same batches whatever bundle it came from.
|
|
221
|
+
*/
|
|
222
|
+
export declare function batchEntries(entries: readonly ImportEntry[]): PreparedBatch[];
|
|
223
|
+
export interface ManifestTrace {
|
|
224
|
+
trace_id: string;
|
|
225
|
+
span_count: number;
|
|
226
|
+
batches: {
|
|
227
|
+
sha256: string;
|
|
228
|
+
bytes: number;
|
|
229
|
+
span_count: number;
|
|
230
|
+
}[];
|
|
231
|
+
blobs: {
|
|
232
|
+
sha256: string;
|
|
233
|
+
byte_size: number;
|
|
234
|
+
content_type: string;
|
|
235
|
+
}[];
|
|
236
|
+
identity?: TraceIdentity;
|
|
237
|
+
origin: TraceImportOrigin;
|
|
238
|
+
source_digest?: string;
|
|
239
|
+
}
|
|
240
|
+
export interface TraceImportManifest {
|
|
241
|
+
version: 1;
|
|
242
|
+
source: {
|
|
243
|
+
formats: TraceImportFormat[];
|
|
244
|
+
helper: string;
|
|
245
|
+
helper_version?: string;
|
|
246
|
+
};
|
|
247
|
+
traces: ManifestTrace[];
|
|
248
|
+
}
|
|
249
|
+
export interface TraceImportTotals {
|
|
250
|
+
traces: number;
|
|
251
|
+
batches: number;
|
|
252
|
+
spans: number;
|
|
253
|
+
blobs: number;
|
|
254
|
+
bytes: number;
|
|
255
|
+
}
|
|
256
|
+
/** The totals a manifest adds up to, as Hue computes them. */
|
|
257
|
+
export declare function manifestTotals(manifest: TraceImportManifest): TraceImportTotals;
|
|
258
|
+
export declare function manifestTraceHasIdentity(trace: Pick<ManifestTrace, "identity">): boolean;
|
|
259
|
+
/** A manifest's problem, or undefined: the shape and cross-checks Hue's registration applies
|
|
260
|
+
* (every trace id once, every batch digest once, each trace's batches adding up to its span
|
|
261
|
+
* count, each trace's values distinct) so a bundle is refused here, before any upload. */
|
|
262
|
+
export declare function validateManifest(value: unknown): string | undefined;
|