@hue-run/sdk 0.17.0 → 0.18.0
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 +8 -8
- package/EVALUATIONS.md +53 -2
- package/README.md +262 -37
- package/dist/attachment.d.ts +82 -0
- package/dist/attachment.js +225 -0
- package/dist/blobs.d.ts +41 -3
- package/dist/blobs.js +126 -41
- package/dist/client.d.ts +18 -0
- package/dist/client.js +148 -13
- package/dist/evals/client.d.ts +14 -1
- package/dist/evals/client.js +73 -9
- package/dist/evals/files.d.ts +11 -1
- package/dist/evals/files.js +160 -20
- package/dist/evals/media.d.ts +217 -0
- package/dist/evals/media.js +907 -0
- package/dist/evals/runner.js +130 -106
- package/dist/evals/types.d.ts +48 -0
- package/dist/evals.d.ts +2 -0
- package/dist/evals.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/inline-files.d.ts +131 -8
- package/dist/inline-files.js +565 -47
- package/dist/json-edits.d.ts +24 -0
- package/dist/json-edits.js +187 -0
- package/dist/privacy.d.ts +13 -0
- package/dist/privacy.js +84 -17
- package/dist/safety.d.ts +6 -2
- package/dist/safety.js +15 -3
- package/dist/snapshot.d.ts +1 -1
- package/dist/snapshot.js +123 -29
- package/dist/transport.d.ts +7 -0
- package/dist/transport.js +285 -55
- package/dist/types.d.ts +25 -6
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading recorded media back. A trace records a large file as a digest part: the provider part
|
|
3
|
+
* with its content field removed and the file's `sha256` and `size` added, its bytes uploaded
|
|
4
|
+
* under the record's `hue.blobs`. `fetch` downloads one file by digest through a short-lived
|
|
5
|
+
* link Hue issues; `resolve` and {@link rehydrateMedia} put the bytes back into the parts of a
|
|
6
|
+
* recorded value, in the field and encoding each part's shape uses.
|
|
7
|
+
*/
|
|
8
|
+
/** Why a media read failed. */
|
|
9
|
+
export type MediaFetchErrorReason =
|
|
10
|
+
/** Hue holds no such file for the trace or snapshot: an unknown trace, another project's, or a
|
|
11
|
+
* digest none of its records list (with `spanId`, that span's record). */
|
|
12
|
+
"not_found"
|
|
13
|
+
/** The trace lists the file, but its bytes were never uploaded or have been erased. */
|
|
14
|
+
| "missing"
|
|
15
|
+
/** Hue could not read its evidence store, again after one retry; `retryAfterSeconds` says when
|
|
16
|
+
* to ask again. */
|
|
17
|
+
| "unavailable"
|
|
18
|
+
/** The key cannot read recorded content: use a Read or Read and write key, and a Read and write
|
|
19
|
+
* key for a snapshot's copy. */
|
|
20
|
+
| "forbidden"
|
|
21
|
+
/** The file is larger than `maxBytes`; nothing was downloaded. */
|
|
22
|
+
| "too_large"
|
|
23
|
+
/** The downloaded bytes do not have the requested SHA-256 or the size Hue reported. */
|
|
24
|
+
| "digest_mismatch"
|
|
25
|
+
/** A connection failure, a timeout, an unexpected status or an invalid response. */
|
|
26
|
+
| "failed";
|
|
27
|
+
/** Thrown by {@link MediaClient.fetch}. The message is fixed and never includes response text. */
|
|
28
|
+
export declare class MediaFetchError extends Error {
|
|
29
|
+
/** What failed. */
|
|
30
|
+
readonly reason: MediaFetchErrorReason;
|
|
31
|
+
/** HTTP status of the answer that failed, when there was one. */
|
|
32
|
+
readonly status?: number | undefined;
|
|
33
|
+
/** Seconds Hue asked the caller to wait, on `unavailable`, when it said. */
|
|
34
|
+
readonly retryAfterSeconds?: number | undefined;
|
|
35
|
+
constructor(
|
|
36
|
+
/** What failed. */
|
|
37
|
+
reason: MediaFetchErrorReason,
|
|
38
|
+
/** HTTP status of the answer that failed, when there was one. */
|
|
39
|
+
status?: number | undefined,
|
|
40
|
+
/** Seconds Hue asked the caller to wait, on `unavailable`, when it said. */
|
|
41
|
+
retryAfterSeconds?: number | undefined, options?: {
|
|
42
|
+
cause?: unknown;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** One recorded file, downloaded and checked against its digest. */
|
|
46
|
+
export interface MediaFile {
|
|
47
|
+
/** The file's bytes; their SHA-256 is `sha256`. */
|
|
48
|
+
bytes: Uint8Array;
|
|
49
|
+
/** Lowercase hex SHA-256 of `bytes`, as requested. */
|
|
50
|
+
sha256: string;
|
|
51
|
+
/** Byte length of `bytes`. */
|
|
52
|
+
size: number;
|
|
53
|
+
/** The media type the record lists for the file; absent for a snapshot's copy, whose type is
|
|
54
|
+
* the part's own. */
|
|
55
|
+
contentType?: string;
|
|
56
|
+
/** The recorded file name as Hue serves it; absent for a snapshot's copy. */
|
|
57
|
+
fileName?: string;
|
|
58
|
+
}
|
|
59
|
+
/** The file {@link MediaClient.fetch} reads: from a trace, or from a snapshot's pinned copy. */
|
|
60
|
+
export type MediaFetchTarget = {
|
|
61
|
+
/** Hue trace ID (UUID) or the 32-hex OpenTelemetry trace ID. */
|
|
62
|
+
traceId: string;
|
|
63
|
+
/** Lowercase hex SHA-256 the part records. */
|
|
64
|
+
sha256: string;
|
|
65
|
+
/** 16-hex OpenTelemetry span ID of the span that recorded the part. Pass it when known: Hue
|
|
66
|
+
* then reads that span's record alone instead of searching the trace. */
|
|
67
|
+
spanId?: string;
|
|
68
|
+
/** Not set when reading a live trace's file. */
|
|
69
|
+
snapshotId?: undefined;
|
|
70
|
+
} | {
|
|
71
|
+
/** Trace snapshot ID (UUID), such as the one a case converted from a trace keeps. Reading
|
|
72
|
+
* its copy needs a Read and write key. */
|
|
73
|
+
snapshotId: string;
|
|
74
|
+
/** Lowercase hex SHA-256 the part records. */
|
|
75
|
+
sha256: string;
|
|
76
|
+
/** Not set when reading a snapshot's pinned copy. */
|
|
77
|
+
traceId?: undefined;
|
|
78
|
+
/** Not set when reading a snapshot's pinned copy. */
|
|
79
|
+
spanId?: undefined;
|
|
80
|
+
};
|
|
81
|
+
/** Options for {@link MediaClient.fetch}. */
|
|
82
|
+
export interface MediaFetchOptions {
|
|
83
|
+
/** Largest file read into memory, in bytes; a larger one fails with `too_large` before any byte
|
|
84
|
+
* is downloaded. Default 64 MiB, at most 1 GB. */
|
|
85
|
+
maxBytes?: number;
|
|
86
|
+
/** Ends the request, the retry wait and the download. */
|
|
87
|
+
signal?: AbortSignal;
|
|
88
|
+
}
|
|
89
|
+
/** Where {@link MediaClient.resolve} reads the files of a recorded value from, and how it writes
|
|
90
|
+
* them. */
|
|
91
|
+
export type MediaResolveOptions = ({
|
|
92
|
+
/** Hue trace ID (UUID) or the 32-hex OpenTelemetry trace ID the value was recorded in. */
|
|
93
|
+
traceId: string;
|
|
94
|
+
/** 16-hex OpenTelemetry span ID of the span that recorded the value. */
|
|
95
|
+
spanId?: string;
|
|
96
|
+
/** Not set when resolving a live trace's files. */
|
|
97
|
+
snapshotId?: undefined;
|
|
98
|
+
} | {
|
|
99
|
+
/** Trace snapshot ID whose pinned copies hold the files; reading them needs a Read and
|
|
100
|
+
* write key. */
|
|
101
|
+
snapshotId: string;
|
|
102
|
+
/** Not set when resolving a snapshot's pinned copies. */
|
|
103
|
+
traceId?: undefined;
|
|
104
|
+
/** Not set when resolving a snapshot's pinned copies. */
|
|
105
|
+
spanId?: undefined;
|
|
106
|
+
}) & MediaWriteOptions & {
|
|
107
|
+
/** The `hue.blobs` entries of the record the value was read from, in any form Hue reads: an
|
|
108
|
+
* array of compact JSON object strings (what the SDKs write), an array of objects, or one
|
|
109
|
+
* string holding the JSON array. A part that declares no media type, read from a copy that
|
|
110
|
+
* carries none (a snapshot's), takes the type of the entry with its SHA-256 for its `data:`
|
|
111
|
+
* URL, rather than `application/octet-stream`. A part whose content field an entry names and
|
|
112
|
+
* that holds only the first 16 KiB of its file is reported as `prefix_only`. Entries that do
|
|
113
|
+
* not parse are ignored. */
|
|
114
|
+
blobs?: readonly (string | Readonly<Record<string, unknown>>)[] | string;
|
|
115
|
+
/** Files downloaded at once, 1–16. Default 4. */
|
|
116
|
+
concurrency?: number;
|
|
117
|
+
/** Largest file read, as in {@link MediaFetchOptions.maxBytes}. */
|
|
118
|
+
maxBytes?: number;
|
|
119
|
+
/** Ends every request and download. */
|
|
120
|
+
signal?: AbortSignal;
|
|
121
|
+
};
|
|
122
|
+
/** How resolved bytes are written into a part. */
|
|
123
|
+
export interface MediaWriteOptions {
|
|
124
|
+
/**
|
|
125
|
+
* `"dataUrl"` (the default) writes text: a `data:` URL where the part's field takes one (OpenAI
|
|
126
|
+
* `image_url` and `file_data`, Responses `input_image`, `input_file` and `computer_screenshot`,
|
|
127
|
+
* AI SDK `image` and `file` `data`), and bare base64 where its convention requires it (GenAI
|
|
128
|
+
* `blob` `content`, OpenAI `input_audio` and assistant `audio` `data`, Anthropic `source.data`,
|
|
129
|
+
* Gemini `inlineData.data`, Vertex `media` `data`, Bedrock `source.bytes`), so the value can be
|
|
130
|
+
* sent to the provider again. `"bytes"` writes the `Uint8Array` itself in the same field.
|
|
131
|
+
*/
|
|
132
|
+
as?: "dataUrl" | "bytes";
|
|
133
|
+
}
|
|
134
|
+
/** A part {@link MediaClient.resolve} or {@link rehydrateMedia} left unchanged. */
|
|
135
|
+
export interface MediaResolveFailure {
|
|
136
|
+
/** RFC 6901 JSON pointer of the part in the value. */
|
|
137
|
+
pointer: string;
|
|
138
|
+
/** The SHA-256 the part records, or for `prefix_only` the SHA-256 of the entry naming its
|
|
139
|
+
* content field. */
|
|
140
|
+
sha256: string;
|
|
141
|
+
/** Why its bytes were not written: as {@link MediaFetchError.reason}, `not_found` when no local
|
|
142
|
+
* file has the digest, or `prefix_only` for a part whose content field holds only the first
|
|
143
|
+
* 16 KiB of its file, as a `blobs` entry names it; {@link MediaClient.fetch} returns that file
|
|
144
|
+
* whole. */
|
|
145
|
+
reason: MediaFetchErrorReason | "prefix_only";
|
|
146
|
+
}
|
|
147
|
+
/** A recorded value with the bytes of its digest parts written back. */
|
|
148
|
+
export interface MediaResolution<T = unknown> {
|
|
149
|
+
/** A new value: the input is never changed. Each resolved part holds its bytes in its content
|
|
150
|
+
* field and no longer carries `sha256` and `size`. */
|
|
151
|
+
value: T;
|
|
152
|
+
/** Parts whose bytes were written. */
|
|
153
|
+
resolved: number;
|
|
154
|
+
/** Parts left unchanged, in reading order. */
|
|
155
|
+
failures: MediaResolveFailure[];
|
|
156
|
+
}
|
|
157
|
+
/** A local copy of a file {@link rehydrateMedia} reads by digest: a runner's verified case file
|
|
158
|
+
* (`LocalFile`, read from `path`) or bytes already in memory. */
|
|
159
|
+
export type MediaSourceFile = {
|
|
160
|
+
/** Lowercase hex SHA-256 of the file's bytes. */
|
|
161
|
+
sha256: string;
|
|
162
|
+
/** The file's media type, used when the part declares none. */
|
|
163
|
+
contentType?: string;
|
|
164
|
+
} & ({
|
|
165
|
+
/** Path of the file on this machine. */
|
|
166
|
+
path: string;
|
|
167
|
+
/** Not set when the file is given as a path. */
|
|
168
|
+
bytes?: undefined;
|
|
169
|
+
} | {
|
|
170
|
+
/** The file's bytes. */
|
|
171
|
+
bytes: Uint8Array;
|
|
172
|
+
/** Not set when the file is given as bytes. */
|
|
173
|
+
path?: undefined;
|
|
174
|
+
});
|
|
175
|
+
/** The least time a download may go without a byte before it ends: two minutes. Tests shorten it;
|
|
176
|
+
* it is not exported from the package. */
|
|
177
|
+
export declare const mediaDownload: {
|
|
178
|
+
minIdleMillis: number;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Hue's media reads, `client.media`: one recorded file by digest (`fetch`), and every digest part
|
|
182
|
+
* of a recorded value written back with its bytes (`resolve`). The project key is sent to Hue
|
|
183
|
+
* only; the file itself comes from a short-lived link fetched without it.
|
|
184
|
+
*/
|
|
185
|
+
export declare class MediaClient {
|
|
186
|
+
#private;
|
|
187
|
+
/**
|
|
188
|
+
* Downloads one recorded file and checks it against its digest: from a trace (Hue reads the
|
|
189
|
+
* span's record that lists the digest under `hue.blobs`) or from a snapshot's pinned copy. A
|
|
190
|
+
* read Hue answers as unavailable (503 or 429) is asked once more after its `Retry-After`, at
|
|
191
|
+
* most 10 seconds, and so is one that lost its connection or timed out.
|
|
192
|
+
*
|
|
193
|
+
* @throws MediaFetchError for a file Hue does not hold, a refused key, an unavailable store, a
|
|
194
|
+
* file over `maxBytes`, bytes that do not match the digest or a failed request.
|
|
195
|
+
* @throws TypeError for an invalid trace, span or snapshot ID or digest.
|
|
196
|
+
*/
|
|
197
|
+
fetch(target: MediaFetchTarget, options?: MediaFetchOptions): Promise<MediaFile>;
|
|
198
|
+
/**
|
|
199
|
+
* Writes the bytes of every digest part in `value` back into its content field, the reverse of
|
|
200
|
+
* the SDK's media capture: each distinct digest is downloaded once with {@link fetch}, at most
|
|
201
|
+
* `concurrency` at a time. Returns a new value; a part whose file cannot be read stays as it is
|
|
202
|
+
* and is reported in `failures`. Parse attributes recorded as JSON text (such as
|
|
203
|
+
* `gen_ai.input.messages`) before passing them; pass the record's `hue.blobs` as `blobs` when
|
|
204
|
+
* reading a snapshot, whose copies carry no media type.
|
|
205
|
+
*
|
|
206
|
+
* @throws TypeError for invalid identifiers or options; never for one file's failure.
|
|
207
|
+
*/
|
|
208
|
+
resolve<T>(value: T, options: MediaResolveOptions): Promise<MediaResolution<T>>;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Writes case files back into the digest parts of a case's inputs, by SHA-256: the files a runner
|
|
212
|
+
* hands a target (`context.files`) or any bytes the caller holds, so a target can send the
|
|
213
|
+
* recorded model call again with the real image, document or audio. Each file is read once and
|
|
214
|
+
* checked against its digest; a part with no matching file, or whose file does not match, stays
|
|
215
|
+
* as it is and is reported in `failures`. Returns a new value; the input is never changed.
|
|
216
|
+
*/
|
|
217
|
+
export declare function rehydrateMedia<T>(value: T, files: readonly MediaSourceFile[], options?: MediaWriteOptions): Promise<MediaResolution<T>>;
|