@bitfab/sdk 0.65.7 → 0.65.9
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/cloudReplay.py +130 -3
- package/dist/baml.cjs +12 -0
- package/dist/baml.cjs.map +1 -0
- package/dist/baml.d.cts +1 -0
- package/dist/baml.d.ts +1 -0
- package/dist/baml.js +8 -0
- package/dist/baml.js.map +1 -0
- package/dist/bamlPeer-BUoZgNxZ.cjs +88 -0
- package/dist/bamlPeer-BUoZgNxZ.cjs.map +1 -0
- package/dist/bamlPeer-CIVwS68E.js +28 -0
- package/dist/bamlPeer-CIVwS68E.js.map +1 -0
- package/dist/{http-BaLzqv9W.js → http-DUDL3FGE.js} +2 -2
- package/dist/{http-BaLzqv9W.js.map → http-DUDL3FGE.js.map} +1 -1
- package/dist/http-DX-fpUSu.cjs +2306 -0
- package/dist/http-DX-fpUSu.cjs.map +1 -0
- package/dist/{index-qVS-HeqB.d.cts → index-C2b7Qyjw.d.cts} +1 -1
- package/dist/{index-qVS-HeqB.d.ts → index-C2b7Qyjw.d.ts} +1 -1
- package/dist/index.cjs +7 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/node.cjs +7 -6
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +2 -2
- package/dist/registryCommand-Di8x0YoJ.js.map +1 -1
- package/dist/{src-DgkDt32g.cjs → src-BWZx-C1S.cjs} +324 -2440
- package/dist/src-BWZx-C1S.cjs.map +1 -0
- package/dist/{src-BblbvWfU.js → src-DYCb-06l.js} +147 -52
- package/dist/src-DYCb-06l.js.map +1 -0
- package/package.json +11 -1
- package/dist/src-BblbvWfU.js.map +0 -1
- package/dist/src-DgkDt32g.cjs.map +0 -1
|
@@ -1,2222 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
get: all[name],
|
|
12
|
-
enumerable: true
|
|
13
|
-
});
|
|
14
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
-
return target;
|
|
16
|
-
};
|
|
17
|
-
var __copyProps = (to, from, except, desc) => {
|
|
18
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
-
key = keys[i];
|
|
20
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
21
|
-
get: ((k) => from[k]).bind(null, key),
|
|
22
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
return to;
|
|
26
|
-
};
|
|
27
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
28
|
-
value: mod,
|
|
29
|
-
enumerable: true
|
|
30
|
-
}) : target, mod));
|
|
31
|
-
//#endregion
|
|
32
|
-
const require_autoTrace = require("./autoTrace-CQw0qMBt.cjs");
|
|
33
|
-
let _opentelemetry_api = require("@opentelemetry/api");
|
|
34
|
-
let _opentelemetry_core = require("@opentelemetry/core");
|
|
35
|
-
let _opentelemetry_resources = require("@opentelemetry/resources");
|
|
36
|
-
let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
37
|
-
let superjson = require("superjson");
|
|
38
|
-
superjson = __toESM(superjson, 1);
|
|
39
|
-
//#region src/categories.ts
|
|
40
|
-
const CATEGORIES_PATH = "/api/sdk/categories";
|
|
41
|
-
var CategoriesClient = class {
|
|
42
|
-
constructor(httpClient) {
|
|
43
|
-
this.httpClient = httpClient;
|
|
44
|
-
}
|
|
45
|
-
async save(params) {
|
|
46
|
-
return (await this.httpClient.request(CATEGORIES_PATH, params)).category;
|
|
47
|
-
}
|
|
48
|
-
async get(id) {
|
|
49
|
-
return (await this.httpClient.get(`${CATEGORIES_PATH}/${encodeURIComponent(id)}`)).category;
|
|
50
|
-
}
|
|
51
|
-
async list() {
|
|
52
|
-
return (await this.httpClient.get(CATEGORIES_PATH)).categories;
|
|
53
|
-
}
|
|
54
|
-
async delete(id) {
|
|
55
|
-
return (await this.httpClient.request(`${CATEGORIES_PATH}/${encodeURIComponent(id)}`, {}, { method: "DELETE" })).category;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
const AssertionCategoriesClient = CategoriesClient;
|
|
59
|
-
//#endregion
|
|
60
|
-
//#region src/version.generated.ts
|
|
61
|
-
const __version__ = "0.65.7";
|
|
62
|
-
const __packageName__ = "@bitfab/sdk";
|
|
63
|
-
//#endregion
|
|
64
|
-
//#region src/constants.ts
|
|
65
|
-
const DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/traceCompletion.ts
|
|
68
|
-
var TraceCompletion = class {
|
|
69
|
-
constructor() {
|
|
70
|
-
this.traces = /* @__PURE__ */ new Map();
|
|
71
|
-
this.closed = /* @__PURE__ */ new Map();
|
|
72
|
-
}
|
|
73
|
-
state(traceId) {
|
|
74
|
-
let state = this.traces.get(traceId);
|
|
75
|
-
if (state === void 0) {
|
|
76
|
-
state = {
|
|
77
|
-
spanIds: /* @__PURE__ */ new Set(),
|
|
78
|
-
active: /* @__PURE__ */ new Set()
|
|
79
|
-
};
|
|
80
|
-
this.traces.set(traceId, state);
|
|
81
|
-
}
|
|
82
|
-
return state;
|
|
83
|
-
}
|
|
84
|
-
start(traceId, spanId) {
|
|
85
|
-
if (this.closed.has(traceId)) return;
|
|
86
|
-
const state = this.state(traceId);
|
|
87
|
-
state.spanIds.add(spanId);
|
|
88
|
-
state.active.add(spanId);
|
|
89
|
-
}
|
|
90
|
-
open(traceId) {
|
|
91
|
-
if (!this.closed.has(traceId)) this.state(traceId);
|
|
92
|
-
}
|
|
93
|
-
hold(traceId, key) {
|
|
94
|
-
this.state(traceId).active.add(key);
|
|
95
|
-
}
|
|
96
|
-
record(traceId, spanId) {
|
|
97
|
-
if (!this.closed.has(traceId)) this.state(traceId).spanIds.add(spanId);
|
|
98
|
-
}
|
|
99
|
-
end(traceId, spanId) {
|
|
100
|
-
const state = this.traces.get(traceId);
|
|
101
|
-
if (state !== void 0) {
|
|
102
|
-
state.active.delete(spanId);
|
|
103
|
-
this.drain(traceId, state);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
abort(traceId, spanId) {
|
|
107
|
-
const state = this.traces.get(traceId);
|
|
108
|
-
if (state === void 0) return;
|
|
109
|
-
state.active.delete(spanId);
|
|
110
|
-
state.spanIds.delete(spanId);
|
|
111
|
-
if (state.active.size === 0 && state.spanIds.size === 0 && state.complete === void 0) {
|
|
112
|
-
this.traces.delete(traceId);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
this.drain(traceId, state);
|
|
116
|
-
}
|
|
117
|
-
close(traceId, complete, dropped = false) {
|
|
118
|
-
const count = this.closed.get(traceId);
|
|
119
|
-
if (count !== void 0) {
|
|
120
|
-
complete(count);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const state = this.traces.get(traceId);
|
|
124
|
-
if (state === void 0) return;
|
|
125
|
-
state.complete = complete;
|
|
126
|
-
if (dropped) state.active.clear();
|
|
127
|
-
this.drain(traceId, state);
|
|
128
|
-
}
|
|
129
|
-
drain(traceId, state) {
|
|
130
|
-
if (state.active.size !== 0 || state.complete === void 0) return;
|
|
131
|
-
this.traces.delete(traceId);
|
|
132
|
-
this.closed.set(traceId, state.spanIds.size);
|
|
133
|
-
if (this.closed.size > 1024) {
|
|
134
|
-
const oldest = this.closed.keys().next().value;
|
|
135
|
-
if (oldest !== void 0) this.closed.delete(oldest);
|
|
136
|
-
}
|
|
137
|
-
state.complete(state.spanIds.size);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
//#endregion
|
|
141
|
-
//#region src/readEnv.ts
|
|
142
|
-
function readEnv$1(name) {
|
|
143
|
-
if (typeof process !== "undefined" && process.env) return process.env[name];
|
|
144
|
-
}
|
|
145
|
-
//#endregion
|
|
146
|
-
//#region src/compress.ts
|
|
147
|
-
const DISABLE_COMPRESSION_ENV = "BITFAB_DISABLE_COMPRESSION";
|
|
148
|
-
const MIN_COMPRESSED_BYTES = 8192;
|
|
149
|
-
let gzipNode;
|
|
150
|
-
(typeof process !== "undefined" && process.versions?.node ? import(
|
|
151
|
-
/* webpackIgnore: true */
|
|
152
|
-
["node", "zlib"].join(":")
|
|
153
|
-
).then(({ gzip }) => {
|
|
154
|
-
gzipNode = (data) => new Promise((resolve, reject) => {
|
|
155
|
-
gzip(data, (error, result) => {
|
|
156
|
-
if (error) reject(error);
|
|
157
|
-
else resolve(result);
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
}).catch(() => {}) : Promise.resolve()).then(() => {});
|
|
161
|
-
function toArrayBuffer(view) {
|
|
162
|
-
return view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
|
163
|
-
}
|
|
164
|
-
function compressedRequest(body, rawBytes, compressed) {
|
|
165
|
-
if (compressed.byteLength >= rawBytes) return {
|
|
166
|
-
body,
|
|
167
|
-
rawBytes,
|
|
168
|
-
wireBytes: rawBytes
|
|
169
|
-
};
|
|
170
|
-
return {
|
|
171
|
-
body: compressed instanceof Uint8Array ? toArrayBuffer(compressed) : compressed,
|
|
172
|
-
contentEncoding: "gzip",
|
|
173
|
-
rawBytes,
|
|
174
|
-
wireBytes: compressed.byteLength
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
async function gzipViaStream(bytes) {
|
|
178
|
-
const stream = new Blob([bytes]).stream().pipeThrough(new CompressionStream("gzip"));
|
|
179
|
-
return await new Response(stream).arrayBuffer();
|
|
180
|
-
}
|
|
181
|
-
function encodeRequestBody(body) {
|
|
182
|
-
if (readEnv$1(DISABLE_COMPRESSION_ENV)) {
|
|
183
|
-
const rawBytes = new TextEncoder().encode(body).byteLength;
|
|
184
|
-
return {
|
|
185
|
-
body,
|
|
186
|
-
rawBytes,
|
|
187
|
-
wireBytes: rawBytes
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
const bytes = new TextEncoder().encode(body);
|
|
191
|
-
if (bytes.byteLength < MIN_COMPRESSED_BYTES) return {
|
|
192
|
-
body,
|
|
193
|
-
rawBytes: bytes.byteLength,
|
|
194
|
-
wireBytes: bytes.byteLength
|
|
195
|
-
};
|
|
196
|
-
if (gzipNode) return gzipNode(bytes).then((compressed) => compressedRequest(body, bytes.byteLength, compressed), () => ({
|
|
197
|
-
body,
|
|
198
|
-
rawBytes: bytes.byteLength,
|
|
199
|
-
wireBytes: bytes.byteLength
|
|
200
|
-
}));
|
|
201
|
-
if (typeof CompressionStream === "undefined") return {
|
|
202
|
-
body,
|
|
203
|
-
rawBytes: bytes.byteLength,
|
|
204
|
-
wireBytes: bytes.byteLength
|
|
205
|
-
};
|
|
206
|
-
return gzipViaStream(bytes).then((compressed) => compressedRequest(body, bytes.byteLength, compressed), () => ({
|
|
207
|
-
body,
|
|
208
|
-
rawBytes: bytes.byteLength,
|
|
209
|
-
wireBytes: bytes.byteLength
|
|
210
|
-
}));
|
|
211
|
-
}
|
|
212
|
-
//#endregion
|
|
213
|
-
//#region src/errors.ts
|
|
214
|
-
var BitfabError = class extends Error {
|
|
215
|
-
constructor(message, url, status, retryAfterMs) {
|
|
216
|
-
super(message);
|
|
217
|
-
this.url = url;
|
|
218
|
-
this.status = status;
|
|
219
|
-
this.retryAfterMs = retryAfterMs;
|
|
220
|
-
this.name = "BitfabError";
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
var MixedTracingError = class extends Error {
|
|
224
|
-
constructor(message) {
|
|
225
|
-
super(message);
|
|
226
|
-
this.name = "MixedTracingError";
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
//#endregion
|
|
230
|
-
//#region src/gitCommand.ts
|
|
231
|
-
const EXIT_GRACE_MS = 500;
|
|
232
|
-
function isUnrefable(value) {
|
|
233
|
-
return typeof value === "object" && value !== null && "unref" in value && typeof value.unref === "function";
|
|
234
|
-
}
|
|
235
|
-
function unrefStream(stream) {
|
|
236
|
-
if (isUnrefable(stream)) stream.unref();
|
|
237
|
-
}
|
|
238
|
-
function terminate(child) {
|
|
239
|
-
if (child.pid && process.platform !== "win32") try {
|
|
240
|
-
process.kill(-child.pid, "SIGTERM");
|
|
241
|
-
return;
|
|
242
|
-
} catch {
|
|
243
|
-
child.kill("SIGTERM");
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
child.kill("SIGTERM");
|
|
247
|
-
}
|
|
248
|
-
async function gitRunner(options) {
|
|
249
|
-
let spawn;
|
|
250
|
-
try {
|
|
251
|
-
({spawn} = await import("child_process"));
|
|
252
|
-
} catch {
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
return (dir, args, env) => new Promise((resolve) => {
|
|
256
|
-
let child;
|
|
257
|
-
try {
|
|
258
|
-
child = spawn("git", args, {
|
|
259
|
-
cwd: dir,
|
|
260
|
-
detached: process.platform !== "win32",
|
|
261
|
-
stdio: [
|
|
262
|
-
"ignore",
|
|
263
|
-
"pipe",
|
|
264
|
-
"pipe"
|
|
265
|
-
],
|
|
266
|
-
...env ? { env: {
|
|
267
|
-
...process.env,
|
|
268
|
-
...env
|
|
269
|
-
} } : {}
|
|
270
|
-
});
|
|
271
|
-
} catch {
|
|
272
|
-
resolve(null);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const chunks = [];
|
|
276
|
-
let size = 0;
|
|
277
|
-
let overflow = false;
|
|
278
|
-
let exitCode = null;
|
|
279
|
-
let done = false;
|
|
280
|
-
const timers = [];
|
|
281
|
-
const schedule = (callback, ms) => {
|
|
282
|
-
const timer = setTimeout(callback, ms);
|
|
283
|
-
if (!options.keepProcessAlive) timer.unref();
|
|
284
|
-
timers.push(timer);
|
|
285
|
-
};
|
|
286
|
-
const finish = () => {
|
|
287
|
-
if (done) return;
|
|
288
|
-
done = true;
|
|
289
|
-
for (const timer of timers) clearTimeout(timer);
|
|
290
|
-
child.stdout?.destroy();
|
|
291
|
-
child.stderr?.destroy();
|
|
292
|
-
resolve(exitCode === 0 && !overflow ? Buffer.concat(chunks).toString("utf8") : null);
|
|
293
|
-
};
|
|
294
|
-
child.stdout?.on("data", (chunk) => {
|
|
295
|
-
size += chunk.length;
|
|
296
|
-
if (size > options.maxBuffer) {
|
|
297
|
-
overflow = true;
|
|
298
|
-
terminate(child);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
chunks.push(chunk);
|
|
302
|
-
});
|
|
303
|
-
child.stderr?.resume();
|
|
304
|
-
child.on("error", () => {
|
|
305
|
-
exitCode = null;
|
|
306
|
-
finish();
|
|
307
|
-
});
|
|
308
|
-
child.on("exit", (code) => {
|
|
309
|
-
exitCode = code;
|
|
310
|
-
schedule(finish, EXIT_GRACE_MS);
|
|
311
|
-
});
|
|
312
|
-
child.on("close", (code) => {
|
|
313
|
-
exitCode = code ?? exitCode;
|
|
314
|
-
finish();
|
|
315
|
-
});
|
|
316
|
-
schedule(() => terminate(child), options.timeoutMs);
|
|
317
|
-
if (!options.keepProcessAlive) {
|
|
318
|
-
child.unref();
|
|
319
|
-
unrefStream(child.stdout);
|
|
320
|
-
unrefStream(child.stderr);
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
}
|
|
324
|
-
//#endregion
|
|
325
|
-
//#region src/gitState.ts
|
|
326
|
-
const GIT_TIMEOUT_MS$1 = 3e4;
|
|
327
|
-
const GIT_MAX_BUFFER$1 = 1048576;
|
|
328
|
-
const DISABLE_ENV$1 = "BITFAB_DISABLE_GIT_STATE";
|
|
329
|
-
const SHA_PATTERN = /^[0-9a-f]{40}$/;
|
|
330
|
-
function sha(value) {
|
|
331
|
-
const trimmed = value?.trim();
|
|
332
|
-
return trimmed && SHA_PATTERN.test(trimmed) ? trimmed : null;
|
|
333
|
-
}
|
|
334
|
-
function text(value) {
|
|
335
|
-
const trimmed = value?.trim();
|
|
336
|
-
return trimmed ? trimmed : null;
|
|
337
|
-
}
|
|
338
|
-
function isEmptyGitState(state) {
|
|
339
|
-
return Object.values(state).every((value) => value === null);
|
|
340
|
-
}
|
|
341
|
-
async function resolveGitState(cwd) {
|
|
342
|
-
const git = await gitRunner({
|
|
343
|
-
timeoutMs: GIT_TIMEOUT_MS$1,
|
|
344
|
-
maxBuffer: GIT_MAX_BUFFER$1,
|
|
345
|
-
keepProcessAlive: true
|
|
346
|
-
});
|
|
347
|
-
if (!git) return null;
|
|
348
|
-
const run = async (args, env) => (await git(cwd, args, env))?.trim() ?? null;
|
|
349
|
-
const [refs, email, branch] = await Promise.all([
|
|
350
|
-
run([
|
|
351
|
-
"rev-parse",
|
|
352
|
-
"--show-toplevel",
|
|
353
|
-
"HEAD",
|
|
354
|
-
"HEAD^{tree}"
|
|
355
|
-
]),
|
|
356
|
-
run(["config", "user.email"]),
|
|
357
|
-
run([
|
|
358
|
-
"symbolic-ref",
|
|
359
|
-
"--short",
|
|
360
|
-
"-q",
|
|
361
|
-
"HEAD"
|
|
362
|
-
])
|
|
363
|
-
]);
|
|
364
|
-
const [root, commitSha, baseSha] = (refs ?? "").split("\n");
|
|
365
|
-
if (!root) return null;
|
|
366
|
-
const state = {
|
|
367
|
-
githubEmail: text(email),
|
|
368
|
-
branch: text(branch),
|
|
369
|
-
commitSha: sha(commitSha),
|
|
370
|
-
baseSha: sha(baseSha),
|
|
371
|
-
experimentSha: await resolveWorkingTreeSha(run, root.trim())
|
|
372
|
-
};
|
|
373
|
-
return isEmptyGitState(state) ? null : state;
|
|
374
|
-
}
|
|
375
|
-
async function resolveWorkingTreeSha(run, root) {
|
|
376
|
-
let indexPath;
|
|
377
|
-
let cleanup;
|
|
378
|
-
try {
|
|
379
|
-
const { mkdtemp, rm } = await import("fs/promises");
|
|
380
|
-
const { join } = await import("path");
|
|
381
|
-
const { tmpdir } = await import("os");
|
|
382
|
-
const dir = await mkdtemp(join(tmpdir(), "bitfab-git-"));
|
|
383
|
-
indexPath = join(dir, "index");
|
|
384
|
-
cleanup = () => rm(dir, {
|
|
385
|
-
recursive: true,
|
|
386
|
-
force: true
|
|
387
|
-
});
|
|
388
|
-
} catch {
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
try {
|
|
392
|
-
const env = { GIT_INDEX_FILE: indexPath };
|
|
393
|
-
if (await run(["read-tree", "HEAD"], env) === null) return null;
|
|
394
|
-
if (await run([
|
|
395
|
-
"add",
|
|
396
|
-
"-A",
|
|
397
|
-
"--",
|
|
398
|
-
root
|
|
399
|
-
], env) === null) return null;
|
|
400
|
-
return sha(await run(["write-tree"], env));
|
|
401
|
-
} catch {
|
|
402
|
-
return null;
|
|
403
|
-
} finally {
|
|
404
|
-
await cleanup().catch(() => {});
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
function resolvedGitState() {
|
|
408
|
-
if (typeof process === "undefined" || process.env?.[DISABLE_ENV$1]) return Promise.resolve(null);
|
|
409
|
-
let cwd;
|
|
410
|
-
try {
|
|
411
|
-
cwd = process.cwd?.() ?? ".";
|
|
412
|
-
} catch {
|
|
413
|
-
return Promise.resolve(null);
|
|
414
|
-
}
|
|
415
|
-
return resolveGitState(cwd).catch(() => null);
|
|
416
|
-
}
|
|
417
|
-
//#endregion
|
|
418
|
-
//#region src/replayContext.ts
|
|
419
|
-
let replayContextStorage = null;
|
|
420
|
-
const REPLAY_CONTEXT_STORAGE_SYMBOL = Symbol.for("bitfab.replayContextStorage");
|
|
421
|
-
const replayContextReady = require_autoTrace.asyncStorageReady.then(() => {
|
|
422
|
-
const shared = globalThis;
|
|
423
|
-
const existing = shared[REPLAY_CONTEXT_STORAGE_SYMBOL];
|
|
424
|
-
if (existing) {
|
|
425
|
-
replayContextStorage = existing;
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
const created = require_autoTrace.createAsyncLocalStorage();
|
|
429
|
-
if (created) {
|
|
430
|
-
shared[REPLAY_CONTEXT_STORAGE_SYMBOL] = created;
|
|
431
|
-
replayContextStorage = created;
|
|
432
|
-
}
|
|
433
|
-
});
|
|
434
|
-
function getReplayContext() {
|
|
435
|
-
return replayContextStorage?.getStore() ?? null;
|
|
436
|
-
}
|
|
437
|
-
function runWithReplayContext(ctx, fn) {
|
|
438
|
-
if (replayContextStorage) return replayContextStorage.run(ctx, fn);
|
|
439
|
-
return fn();
|
|
440
|
-
}
|
|
441
|
-
//#endregion
|
|
442
|
-
//#region src/payloadBudget.ts
|
|
443
|
-
const MAX_SPAN_CARRIER_BYTES = 28e5;
|
|
444
|
-
const MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES = 78e5;
|
|
445
|
-
const textEncoder = typeof TextEncoder !== "undefined" ? new TextEncoder() : null;
|
|
446
|
-
function byteLength(value) {
|
|
447
|
-
return textEncoder ? textEncoder.encode(value).length : value.length;
|
|
448
|
-
}
|
|
449
|
-
function carrierByteLength(body) {
|
|
450
|
-
return carrierBytesOf(textEncoder ? textEncoder.encode(body) : null, body);
|
|
451
|
-
}
|
|
452
|
-
function carrierBytesOf(encoded, body) {
|
|
453
|
-
if (!encoded) return body.length + 2;
|
|
454
|
-
let extra = 2;
|
|
455
|
-
for (let i = 0; i < encoded.length; i++) {
|
|
456
|
-
const byte = encoded[i];
|
|
457
|
-
if (byte === 34 || byte === 92) extra += 1;
|
|
458
|
-
else if (byte < 32) extra += byte === 8 || byte === 9 || byte === 10 || byte === 12 || byte === 13 ? 1 : 5;
|
|
459
|
-
}
|
|
460
|
-
return encoded.length + extra;
|
|
461
|
-
}
|
|
462
|
-
const MAX_BYTES_PER_UNIT = 3;
|
|
463
|
-
function fitsCarrierBudget(body, maxBytes = MAX_SPAN_CARRIER_BYTES) {
|
|
464
|
-
const units = body.length;
|
|
465
|
-
if (units * MAX_BYTES_PER_UNIT + 2 <= maxBytes) return true;
|
|
466
|
-
if (units + 2 > maxBytes) return false;
|
|
467
|
-
return carrierByteLength(body) <= maxBytes;
|
|
468
|
-
}
|
|
469
|
-
const STRUCTURAL_SPAN_KEYS = /* @__PURE__ */ new Set([
|
|
470
|
-
"name",
|
|
471
|
-
"type",
|
|
472
|
-
"function_name",
|
|
473
|
-
"error_source"
|
|
474
|
-
]);
|
|
475
|
-
function asRecord(value) {
|
|
476
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
477
|
-
}
|
|
478
|
-
function cloneTrimmable(payload) {
|
|
479
|
-
const copy = { ...payload };
|
|
480
|
-
const containers = [];
|
|
481
|
-
const spanData = asRecord(copy.span_data);
|
|
482
|
-
if (spanData) {
|
|
483
|
-
const clone = { ...spanData };
|
|
484
|
-
copy.span_data = clone;
|
|
485
|
-
containers.push(clone);
|
|
486
|
-
}
|
|
487
|
-
const rawSpan = asRecord(copy.rawSpan);
|
|
488
|
-
const rawSpanData = rawSpan && asRecord(rawSpan.span_data);
|
|
489
|
-
if (rawSpan && rawSpanData) {
|
|
490
|
-
const clone = { ...rawSpanData };
|
|
491
|
-
copy.rawSpan = {
|
|
492
|
-
...rawSpan,
|
|
493
|
-
span_data: clone
|
|
494
|
-
};
|
|
495
|
-
containers.push(clone);
|
|
496
|
-
}
|
|
497
|
-
if (containers.length === 0) containers.push(copy);
|
|
498
|
-
return {
|
|
499
|
-
copy,
|
|
500
|
-
containers
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
function collectCandidates(containers) {
|
|
504
|
-
const candidates = [];
|
|
505
|
-
for (const container of containers) for (const [key, value] of Object.entries(container)) {
|
|
506
|
-
if (STRUCTURAL_SPAN_KEYS.has(key) || value == null) continue;
|
|
507
|
-
let size;
|
|
508
|
-
try {
|
|
509
|
-
size = byteLength(JSON.stringify(value) ?? "");
|
|
510
|
-
} catch {
|
|
511
|
-
continue;
|
|
512
|
-
}
|
|
513
|
-
candidates.push({
|
|
514
|
-
container,
|
|
515
|
-
key,
|
|
516
|
-
size
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
return candidates.sort((a, b) => b.size - a.size);
|
|
520
|
-
}
|
|
521
|
-
function trimPayloadToBudget(payload, encode, maxBytes = MAX_SPAN_CARRIER_BYTES) {
|
|
522
|
-
const { copy, containers } = cloneTrimmable(payload);
|
|
523
|
-
const candidates = collectCandidates(containers);
|
|
524
|
-
if (candidates.length === 0) return;
|
|
525
|
-
const trimmed = [];
|
|
526
|
-
for (const candidate of candidates) {
|
|
527
|
-
candidate.container[candidate.key] = `<unserializable: too_large_${candidate.size}_bytes>`;
|
|
528
|
-
trimmed.push(candidate.key);
|
|
529
|
-
let body;
|
|
530
|
-
try {
|
|
531
|
-
body = encode(copy);
|
|
532
|
-
} catch {
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
if (fitsCarrierBudget(body, maxBytes)) return {
|
|
536
|
-
value: copy,
|
|
537
|
-
trimmed
|
|
538
|
-
};
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
function markPayloadTrimmed(value, trimmed, maxBytes = MAX_SPAN_CARRIER_BYTES) {
|
|
542
|
-
value.errors = [...Array.isArray(value.errors) ? value.errors : [], {
|
|
543
|
-
source: "sdk",
|
|
544
|
-
step: "payload_budget",
|
|
545
|
-
error: `trimmed oversized field(s) to fit the ${maxBytes}-byte span carrier budget: ${[...new Set(trimmed)].join(", ")}`
|
|
546
|
-
}];
|
|
547
|
-
}
|
|
548
|
-
//#endregion
|
|
549
|
-
//#region src/serializePayload.ts
|
|
550
|
-
function serializePayloadBody(payload, maxCarrierBytes = MAX_SPAN_CARRIER_BYTES) {
|
|
551
|
-
return require_autoTrace.runWithCaptureSuppressed(() => encodeWithinBudget(payload, maxCarrierBytes));
|
|
552
|
-
}
|
|
553
|
-
function encodeWithinBudget(payload, maxCarrierBytes) {
|
|
554
|
-
const encoded = encodePayloadBody(payload);
|
|
555
|
-
if (fitsCarrierBudget(encoded.body, maxCarrierBytes)) return {
|
|
556
|
-
body: encoded.body,
|
|
557
|
-
dropped: encoded.dropped
|
|
558
|
-
};
|
|
559
|
-
return applyPayloadBudget(encoded, maxCarrierBytes);
|
|
560
|
-
}
|
|
561
|
-
function applyPayloadBudget(encoded, maxCarrierBytes) {
|
|
562
|
-
const result = encoded.value ? trimPayloadToBudget(encoded.value, (value) => encodePayloadBody(value).body, maxCarrierBytes) : void 0;
|
|
563
|
-
if (!result) return {
|
|
564
|
-
body: encoded.body,
|
|
565
|
-
dropped: encoded.dropped
|
|
566
|
-
};
|
|
567
|
-
require_autoTrace.warnOnce("payload:over-budget", `a span payload exceeded the ${maxCarrierBytes}-byte carrier budget; its largest field(s) (${[...new Set(result.trimmed)].join(", ")}) were replaced with placeholders so the span still ships. The span is incomplete and may not be replayable.`);
|
|
568
|
-
markPayloadTrimmed(result.value, result.trimmed, maxCarrierBytes);
|
|
569
|
-
return {
|
|
570
|
-
body: encodePayloadBody(result.value).body,
|
|
571
|
-
dropped: encoded.dropped
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
function encodePayloadBody(payload) {
|
|
575
|
-
try {
|
|
576
|
-
return {
|
|
577
|
-
body: JSON.stringify(payload),
|
|
578
|
-
dropped: [],
|
|
579
|
-
value: payload
|
|
580
|
-
};
|
|
581
|
-
} catch {
|
|
582
|
-
const dropped = [];
|
|
583
|
-
const sanitize = (value, seen) => {
|
|
584
|
-
const t = typeof value;
|
|
585
|
-
if (value === null || t === "string" || t === "number" || t === "boolean") return value;
|
|
586
|
-
if (t === "bigint") {
|
|
587
|
-
dropped.push("BigInt");
|
|
588
|
-
return "<unserializable: BigInt>";
|
|
589
|
-
}
|
|
590
|
-
if (t === "function") {
|
|
591
|
-
const name = value.name || "Function";
|
|
592
|
-
dropped.push(name);
|
|
593
|
-
return `<unserializable: ${name}>`;
|
|
594
|
-
}
|
|
595
|
-
if (t === "symbol") {
|
|
596
|
-
dropped.push("Symbol");
|
|
597
|
-
return "<unserializable: Symbol>";
|
|
598
|
-
}
|
|
599
|
-
if (t !== "object") return;
|
|
600
|
-
const obj = value;
|
|
601
|
-
const className = obj.constructor?.name || "object";
|
|
602
|
-
if (seen.has(obj)) {
|
|
603
|
-
dropped.push(className);
|
|
604
|
-
return `<cycle: ${className}>`;
|
|
605
|
-
}
|
|
606
|
-
seen.add(obj);
|
|
607
|
-
let result;
|
|
608
|
-
if (Array.isArray(obj)) result = obj.map((item) => sanitize(item, seen));
|
|
609
|
-
else if (typeof obj.toJSON === "function") try {
|
|
610
|
-
result = sanitize(obj.toJSON(), seen);
|
|
611
|
-
} catch {
|
|
612
|
-
dropped.push(className);
|
|
613
|
-
result = `<unserializable: ${className}>`;
|
|
614
|
-
}
|
|
615
|
-
else try {
|
|
616
|
-
const out = {};
|
|
617
|
-
for (const [k, v] of Object.entries(obj)) out[k] = sanitize(v, seen);
|
|
618
|
-
result = out;
|
|
619
|
-
} catch {
|
|
620
|
-
require_autoTrace.warnOnce("payload:field-getter-threw", "a value with a throwing getter/proxy could not be serialized into a span payload; it was replaced with a placeholder. The span still ships with its other fields intact.");
|
|
621
|
-
dropped.push(className);
|
|
622
|
-
result = `<unserializable: ${className}>`;
|
|
623
|
-
}
|
|
624
|
-
seen.delete(obj);
|
|
625
|
-
return result;
|
|
626
|
-
};
|
|
627
|
-
let sanitized;
|
|
628
|
-
try {
|
|
629
|
-
sanitized = sanitize(payload, /* @__PURE__ */ new WeakSet());
|
|
630
|
-
} catch (error) {
|
|
631
|
-
const marker = { error: `payload_serialize_failed: ${error instanceof Error ? error.message : String(error)}` };
|
|
632
|
-
return {
|
|
633
|
-
body: JSON.stringify(marker),
|
|
634
|
-
dropped,
|
|
635
|
-
value: marker
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
const isRecord = typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized);
|
|
639
|
-
if (dropped.length > 0 && isRecord) {
|
|
640
|
-
const obj = sanitized;
|
|
641
|
-
obj.errors = [...Array.isArray(obj.errors) ? obj.errors : [], {
|
|
642
|
-
source: "sdk",
|
|
643
|
-
step: "json_serialize",
|
|
644
|
-
error: `stubbed non-serializable value(s): ${[...new Set(dropped)].join(", ")}`
|
|
645
|
-
}];
|
|
646
|
-
}
|
|
647
|
-
return {
|
|
648
|
-
body: JSON.stringify(sanitized),
|
|
649
|
-
dropped,
|
|
650
|
-
value: isRecord ? sanitized : void 0
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
//#endregion
|
|
655
|
-
//#region src/policyRefresh.ts
|
|
656
|
-
var PolicyRefresh = class {
|
|
657
|
-
constructor() {
|
|
658
|
-
this.refreshAfter = 0;
|
|
659
|
-
}
|
|
660
|
-
due() {
|
|
661
|
-
return this.inFlight === void 0 && Date.now() >= this.refreshAfter;
|
|
662
|
-
}
|
|
663
|
-
hold(durationMs) {
|
|
664
|
-
this.refreshAfter = Date.now() + durationMs;
|
|
665
|
-
}
|
|
666
|
-
releaseHold() {
|
|
667
|
-
this.refreshAfter = 0;
|
|
668
|
-
}
|
|
669
|
-
run(read, onLoaded, onFailed) {
|
|
670
|
-
if (!this.due()) return;
|
|
671
|
-
let request;
|
|
672
|
-
try {
|
|
673
|
-
request = read().then(onLoaded).catch(onFailed).finally(() => {
|
|
674
|
-
this.inFlight = void 0;
|
|
675
|
-
});
|
|
676
|
-
} catch (error) {
|
|
677
|
-
onFailed(error);
|
|
678
|
-
return;
|
|
679
|
-
}
|
|
680
|
-
this.inFlight = request;
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
//#endregion
|
|
684
|
-
//#region src/spanOrigin.ts
|
|
685
|
-
const SPAN_ORIGIN_NAME = "bitfab.sdk.typescript";
|
|
686
|
-
const SPAN_INSTRUMENTATIONS = [
|
|
687
|
-
"span",
|
|
688
|
-
"trace",
|
|
689
|
-
"openai-agents",
|
|
690
|
-
"langgraph",
|
|
691
|
-
"claude-agent-sdk",
|
|
692
|
-
"vercel-ai",
|
|
693
|
-
"rivet"
|
|
694
|
-
];
|
|
695
|
-
const FRAMEWORK_INSTRUMENTATION_SET = /* @__PURE__ */ new Set([
|
|
696
|
-
"openai-agents",
|
|
697
|
-
"langgraph",
|
|
698
|
-
"claude-agent-sdk",
|
|
699
|
-
"vercel-ai",
|
|
700
|
-
"rivet"
|
|
701
|
-
]);
|
|
702
|
-
function isFrameworkInstrumentation(value) {
|
|
703
|
-
return typeof value === "string" && FRAMEWORK_INSTRUMENTATION_SET.has(value);
|
|
704
|
-
}
|
|
705
|
-
function makeSpanOrigin(instrumentation) {
|
|
706
|
-
return {
|
|
707
|
-
name: SPAN_ORIGIN_NAME,
|
|
708
|
-
version: __version__,
|
|
709
|
-
instrumentation: { name: instrumentation }
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
function isRecord$4(value) {
|
|
713
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
714
|
-
}
|
|
715
|
-
function spanOriginOf(payload) {
|
|
716
|
-
const rawSpan = payload.rawSpan;
|
|
717
|
-
if (!isRecord$4(rawSpan)) return;
|
|
718
|
-
const origin = rawSpan.span_origin;
|
|
719
|
-
if (!isRecord$4(origin) || !isRecord$4(origin.instrumentation)) return;
|
|
720
|
-
const { name, version } = origin;
|
|
721
|
-
const instrumentation = origin.instrumentation.name;
|
|
722
|
-
if (typeof name !== "string" || typeof version !== "string" || typeof instrumentation !== "string" || !SPAN_INSTRUMENTATIONS.includes(instrumentation)) return;
|
|
723
|
-
return {
|
|
724
|
-
name,
|
|
725
|
-
version,
|
|
726
|
-
instrumentation: { name: instrumentation }
|
|
727
|
-
};
|
|
728
|
-
}
|
|
729
|
-
function spanInstrumentationOf(payload) {
|
|
730
|
-
return spanOriginOf(payload)?.instrumentation.name;
|
|
731
|
-
}
|
|
732
|
-
function recordedByFramework(payload) {
|
|
733
|
-
return isFrameworkInstrumentation(spanInstrumentationOf(payload));
|
|
734
|
-
}
|
|
735
|
-
//#endregion
|
|
736
|
-
//#region src/simulationPlan.ts
|
|
737
|
-
const SIMULATION_PLAN_REFRESH_MS = 6e4;
|
|
738
|
-
const SIMULATION_PLAN_RETRY_MS = 1e4;
|
|
739
|
-
const SIMULATION_PLAN_READ_TIMEOUT_MS = 5e3;
|
|
740
|
-
const SIMULATION_PLAN_MAX_HELD = 1e3;
|
|
741
|
-
const DISABLE_SIMULATION_PLAN_ENV = "BITFAB_DISABLE_SIM_PLAN";
|
|
742
|
-
const NO_API_KEY_FOR_SIMULATION_PLAN = "no API key is set";
|
|
743
|
-
const ROOT_TRACE_FUNCTION_KEY_FIELD = "rootTraceFunctionKey";
|
|
744
|
-
const DECLARED_NODE_FIELD = "declaredNode";
|
|
745
|
-
const CONTENT_OFF_KEY = "content_off_by_simulation_plan";
|
|
746
|
-
const CONTENT_KEYS = [
|
|
747
|
-
"input",
|
|
748
|
-
"input_meta",
|
|
749
|
-
"output",
|
|
750
|
-
"output_meta",
|
|
751
|
-
"replay_recording",
|
|
752
|
-
"prompt"
|
|
753
|
-
];
|
|
754
|
-
function planWaitSliceMs(timeoutMs) {
|
|
755
|
-
return Math.min(SIMULATION_PLAN_READ_TIMEOUT_MS, Math.max(timeoutMs, 0) / 2);
|
|
756
|
-
}
|
|
757
|
-
function parseSimulationPlan(body) {
|
|
758
|
-
if (typeof body !== "object" || body === null) return null;
|
|
759
|
-
const nodes = body.nodes;
|
|
760
|
-
if (!Array.isArray(nodes)) return null;
|
|
761
|
-
const contentOff = /* @__PURE__ */ new Map();
|
|
762
|
-
for (const node of nodes) {
|
|
763
|
-
if (typeof node !== "object" || node === null) continue;
|
|
764
|
-
const { traceFunctionKey, name, captureContent } = node;
|
|
765
|
-
if (typeof traceFunctionKey !== "string" || typeof name !== "string" || typeof captureContent !== "boolean") continue;
|
|
766
|
-
if (captureContent) continue;
|
|
767
|
-
const names = contentOff.get(traceFunctionKey) ?? /* @__PURE__ */ new Set();
|
|
768
|
-
names.add(name);
|
|
769
|
-
contentOff.set(traceFunctionKey, names);
|
|
770
|
-
}
|
|
771
|
-
return contentOff;
|
|
772
|
-
}
|
|
773
|
-
function traceIdOf(payload) {
|
|
774
|
-
const traceId = payload.traceId;
|
|
775
|
-
if (typeof traceId === "string") return traceId;
|
|
776
|
-
const id = payload.id;
|
|
777
|
-
return typeof id === "string" ? id : void 0;
|
|
778
|
-
}
|
|
779
|
-
function isRecord$3(value) {
|
|
780
|
-
return typeof value === "object" && value !== null;
|
|
781
|
-
}
|
|
782
|
-
function rawSpanOf(payload) {
|
|
783
|
-
return isRecord$3(payload.rawSpan) ? payload.rawSpan : void 0;
|
|
784
|
-
}
|
|
785
|
-
function spanDataOf(payload) {
|
|
786
|
-
const spanData = rawSpanOf(payload)?.span_data;
|
|
787
|
-
return isRecord$3(spanData) ? spanData : void 0;
|
|
788
|
-
}
|
|
789
|
-
function spanNameOf(payload) {
|
|
790
|
-
const name = spanDataOf(payload)?.name;
|
|
791
|
-
return typeof name === "string" ? name : void 0;
|
|
792
|
-
}
|
|
793
|
-
function stripContent(payload) {
|
|
794
|
-
const rawSpan = rawSpanOf(payload);
|
|
795
|
-
const spanData = spanDataOf(payload);
|
|
796
|
-
if (rawSpan === void 0 || spanData === void 0) return payload;
|
|
797
|
-
const kept = { ...spanData };
|
|
798
|
-
for (const key of CONTENT_KEYS) delete kept[key];
|
|
799
|
-
kept[CONTENT_OFF_KEY] = true;
|
|
800
|
-
return {
|
|
801
|
-
...payload,
|
|
802
|
-
rawSpan: {
|
|
803
|
-
...rawSpan,
|
|
804
|
-
span_data: kept
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
|
-
}
|
|
808
|
-
function simulationPlanEnvDisabled() {
|
|
809
|
-
const value = readEnv$1(DISABLE_SIMULATION_PLAN_ENV);
|
|
810
|
-
return typeof value === "string" && value.trim() !== "";
|
|
811
|
-
}
|
|
812
|
-
function missingSimulationPlanEndpoint(error) {
|
|
813
|
-
return error instanceof BitfabError && error.status === 404;
|
|
814
|
-
}
|
|
815
|
-
function isTraceRootSpan(payload) {
|
|
816
|
-
const parentId = rawSpanOf(payload)?.parent_id;
|
|
817
|
-
return parentId === void 0 || parentId === null;
|
|
818
|
-
}
|
|
819
|
-
function declaredInCode(payload) {
|
|
820
|
-
return payload[DECLARED_NODE_FIELD] === true;
|
|
821
|
-
}
|
|
822
|
-
function recordedError(payload) {
|
|
823
|
-
const error = spanDataOf(payload)?.error;
|
|
824
|
-
return error !== void 0 && error !== null;
|
|
825
|
-
}
|
|
826
|
-
var SimulationPlan = class {
|
|
827
|
-
constructor(source, enabled = true) {
|
|
828
|
-
this.source = source;
|
|
829
|
-
this.enabled = enabled;
|
|
830
|
-
this.policyRefresh = new PolicyRefresh();
|
|
831
|
-
this.firstReadOver = false;
|
|
832
|
-
this.rootWaitOver = false;
|
|
833
|
-
this.held = [];
|
|
834
|
-
this.stopped = false;
|
|
835
|
-
this.readStarted = false;
|
|
836
|
-
this.loaded = new Promise((resolve) => {
|
|
837
|
-
this.resolveLoaded = resolve;
|
|
838
|
-
});
|
|
839
|
-
this.firstReadEnded = new Promise((resolve) => {
|
|
840
|
-
this.resolveFirstReadEnded = resolve;
|
|
841
|
-
});
|
|
842
|
-
}
|
|
843
|
-
disabled() {
|
|
844
|
-
return !this.enabled || simulationPlanEnvDisabled();
|
|
845
|
-
}
|
|
846
|
-
idle() {
|
|
847
|
-
return !this.readStarted && this.source.canRead?.() === false;
|
|
848
|
-
}
|
|
849
|
-
refresh() {
|
|
850
|
-
if (this.idle()) return;
|
|
851
|
-
this.read();
|
|
852
|
-
}
|
|
853
|
-
read() {
|
|
854
|
-
if (this.stopped || this.disabled()) return;
|
|
855
|
-
this.readStarted = true;
|
|
856
|
-
this.policyRefresh.run(() => this.source.getSimulationPlan(), (body) => {
|
|
857
|
-
const parsed = parseSimulationPlan(body);
|
|
858
|
-
if (parsed === null) this.scheduleRetry("sim-plan-unreadable", "the sim plan response was not understood");
|
|
859
|
-
else this.markLoaded(parsed);
|
|
860
|
-
this.endFirstRead();
|
|
861
|
-
}, (error) => {
|
|
862
|
-
if (missingSimulationPlanEndpoint(error)) this.markLoaded(/* @__PURE__ */ new Map());
|
|
863
|
-
else this.scheduleRetry("sim-plan-unavailable", `could not read the sim plan: ${error instanceof Error ? error.message : String(error)}`);
|
|
864
|
-
this.endFirstRead();
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
markLoaded(parsed) {
|
|
868
|
-
if (this.stopped) return;
|
|
869
|
-
this.contentOffByKey = parsed;
|
|
870
|
-
this.policyRefresh.hold(SIMULATION_PLAN_REFRESH_MS);
|
|
871
|
-
this.resolveLoaded?.();
|
|
872
|
-
this.resolveLoaded = void 0;
|
|
873
|
-
}
|
|
874
|
-
scheduleRetry(warnKey, reason) {
|
|
875
|
-
if (this.stopped) return;
|
|
876
|
-
this.policyRefresh.hold(SIMULATION_PLAN_RETRY_MS);
|
|
877
|
-
if (this.contentOffByKey !== void 0) return;
|
|
878
|
-
require_autoTrace.warnOnce(warnKey, `${reason}. Until a read succeeds, spans are sent without their inputs and outputs, except each trace's root span and spans recorded by a framework integration. The read is retried on the next span after ${SIMULATION_PLAN_RETRY_MS / 1e3}s.`);
|
|
879
|
-
}
|
|
880
|
-
endFirstRead() {
|
|
881
|
-
this.endRootWait();
|
|
882
|
-
if (!this.firstReadOver) {
|
|
883
|
-
this.firstReadOver = true;
|
|
884
|
-
this.resolveFirstReadEnded?.();
|
|
885
|
-
this.resolveFirstReadEnded = void 0;
|
|
886
|
-
}
|
|
887
|
-
this.releaseHeld();
|
|
888
|
-
}
|
|
889
|
-
endRootWait() {
|
|
890
|
-
this.rootWaitOver = true;
|
|
891
|
-
if (this.rootWaitTimer !== void 0) {
|
|
892
|
-
clearTimeout(this.rootWaitTimer);
|
|
893
|
-
this.rootWaitTimer = void 0;
|
|
894
|
-
}
|
|
895
|
-
this.resolveRootWait?.();
|
|
896
|
-
this.resolveRootWait = void 0;
|
|
897
|
-
}
|
|
898
|
-
waitForFirstRead() {
|
|
899
|
-
this.refresh();
|
|
900
|
-
if (this.rootWaitOver || this.disabled() || this.idle() || !this.holdingForFirstRead()) return;
|
|
901
|
-
if (this.rootWait === void 0) {
|
|
902
|
-
this.rootWait = new Promise((resolve) => {
|
|
903
|
-
this.resolveRootWait = resolve;
|
|
904
|
-
});
|
|
905
|
-
this.rootWaitTimer = setTimeout(() => this.endRootWait(), SIMULATION_PLAN_READ_TIMEOUT_MS);
|
|
906
|
-
}
|
|
907
|
-
return this.rootWait;
|
|
908
|
-
}
|
|
909
|
-
holdingForFirstRead() {
|
|
910
|
-
return this.contentOffByKey === void 0 && !this.firstReadOver && !this.stopped;
|
|
911
|
-
}
|
|
912
|
-
unavailableNow() {
|
|
913
|
-
return !this.disabled() && this.contentOffByKey === void 0 && this.firstReadOver;
|
|
914
|
-
}
|
|
915
|
-
firstLoad() {
|
|
916
|
-
if (this.contentOffByKey !== void 0 || this.stopped || this.disabled() || this.idle()) return;
|
|
917
|
-
return this.loaded;
|
|
918
|
-
}
|
|
919
|
-
send(payload, traceFunctionKey, submit, drop) {
|
|
920
|
-
this.read();
|
|
921
|
-
if (this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
|
|
922
|
-
submit(payload);
|
|
923
|
-
return;
|
|
924
|
-
}
|
|
925
|
-
const entry = {
|
|
926
|
-
payload,
|
|
927
|
-
traceFunctionKey,
|
|
928
|
-
submit,
|
|
929
|
-
drop
|
|
930
|
-
};
|
|
931
|
-
if (this.holdingForFirstRead()) {
|
|
932
|
-
this.hold(entry);
|
|
933
|
-
return;
|
|
934
|
-
}
|
|
935
|
-
this.submitEntry(entry);
|
|
936
|
-
}
|
|
937
|
-
sendTrace(payload, submit) {
|
|
938
|
-
this.read();
|
|
939
|
-
if (this.disabled() || !this.holdingForFirstRead() || !this.holdsSpanOfTrace(traceIdOf(payload))) {
|
|
940
|
-
submit(payload);
|
|
941
|
-
return;
|
|
942
|
-
}
|
|
943
|
-
this.hold({
|
|
944
|
-
payload,
|
|
945
|
-
traceFunctionKey: void 0,
|
|
946
|
-
submit
|
|
947
|
-
});
|
|
948
|
-
}
|
|
949
|
-
holdsSpanOfTrace(traceId) {
|
|
950
|
-
if (traceId === void 0) return false;
|
|
951
|
-
return this.held.some((entry) => entry.traceFunctionKey !== void 0 && traceIdOf(entry.payload) === traceId);
|
|
952
|
-
}
|
|
953
|
-
hold(entry) {
|
|
954
|
-
this.held.push(entry);
|
|
955
|
-
let overflowed = false;
|
|
956
|
-
while (this.held.length > SIMULATION_PLAN_MAX_HELD) {
|
|
957
|
-
const oldest = this.held.shift();
|
|
958
|
-
this.submitEntry(oldest);
|
|
959
|
-
overflowed = true;
|
|
960
|
-
}
|
|
961
|
-
if (overflowed) require_autoTrace.warnOnce("sim-plan-held-overflow", `more than ${SIMULATION_PLAN_MAX_HELD} records were waiting for the sim plan, so the oldest were sent without their inputs and outputs.`);
|
|
962
|
-
}
|
|
963
|
-
payloadToSend(entry) {
|
|
964
|
-
if (entry.traceFunctionKey === void 0 || declaredInCode(entry.payload)) return entry.payload;
|
|
965
|
-
if (this.contentOffByKey !== void 0) return this.apply(entry.payload, entry.traceFunctionKey);
|
|
966
|
-
if (recordedByFramework(entry.payload) || isTraceRootSpan(entry.payload)) return entry.payload;
|
|
967
|
-
return stripContent(entry.payload);
|
|
968
|
-
}
|
|
969
|
-
submitEntry(entry) {
|
|
970
|
-
if (entry.traceFunctionKey !== void 0 && this.skipsSpan(entry.payload, entry.traceFunctionKey)) {
|
|
971
|
-
entry.drop?.();
|
|
972
|
-
return;
|
|
973
|
-
}
|
|
974
|
-
try {
|
|
975
|
-
entry.submit(this.payloadToSend(entry));
|
|
976
|
-
} catch (error) {
|
|
977
|
-
entry.drop?.();
|
|
978
|
-
require_autoTrace.warnOnce("sim-plan-held-span-dropped", `a span held for the sim plan was dropped when released: ${error instanceof Error ? error.message : String(error)}`);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
releaseHeld() {
|
|
982
|
-
const held = this.held;
|
|
983
|
-
this.held = [];
|
|
984
|
-
for (const entry of held) this.submitEntry(entry);
|
|
985
|
-
}
|
|
986
|
-
releaseHeldWithoutPlan() {
|
|
987
|
-
if (this.held.length === 0) return;
|
|
988
|
-
if (this.contentOffByKey === void 0) require_autoTrace.warnOnce("sim-plan-not-loaded-at-release", `${this.held.length} record(s) were sent without their inputs and outputs because the sim plan had not loaded`);
|
|
989
|
-
this.releaseHeld();
|
|
990
|
-
}
|
|
991
|
-
async release(timeoutMs) {
|
|
992
|
-
this.refresh();
|
|
993
|
-
if (this.held.length > 0) await this.waitForFirstReadEnd(timeoutMs);
|
|
994
|
-
this.releaseHeldWithoutPlan();
|
|
995
|
-
}
|
|
996
|
-
waitForFirstReadEnd(timeoutMs) {
|
|
997
|
-
if (this.firstReadOver) return Promise.resolve();
|
|
998
|
-
return new Promise((resolve) => {
|
|
999
|
-
const timer = setTimeout(resolve, Math.max(timeoutMs, 0));
|
|
1000
|
-
this.firstReadEnded.then(() => {
|
|
1001
|
-
clearTimeout(timer);
|
|
1002
|
-
resolve();
|
|
1003
|
-
});
|
|
1004
|
-
});
|
|
1005
|
-
}
|
|
1006
|
-
stop() {
|
|
1007
|
-
if (this.stopped) return;
|
|
1008
|
-
this.releaseHeldWithoutPlan();
|
|
1009
|
-
this.stopped = true;
|
|
1010
|
-
this.endFirstRead();
|
|
1011
|
-
}
|
|
1012
|
-
contentOff(traceFunctionKey, spanName) {
|
|
1013
|
-
return this.contentOffByKey?.get(traceFunctionKey)?.has(spanName) === true;
|
|
1014
|
-
}
|
|
1015
|
-
contentOffNow(traceFunctionKey, spanName) {
|
|
1016
|
-
return !this.stopped && !this.disabled() && this.contentOff(traceFunctionKey, spanName);
|
|
1017
|
-
}
|
|
1018
|
-
skipsSpan(payload, traceFunctionKey) {
|
|
1019
|
-
const name = spanNameOf(payload);
|
|
1020
|
-
return name !== void 0 && this.contentOff(traceFunctionKey, name) && !isTraceRootSpan(payload) && !declaredInCode(payload) && spanInstrumentationOf(payload) !== void 0 && !recordedByFramework(payload) && !recordedError(payload);
|
|
1021
|
-
}
|
|
1022
|
-
apply(payload, traceFunctionKey) {
|
|
1023
|
-
if (recordedByFramework(payload) || declaredInCode(payload)) return payload;
|
|
1024
|
-
const name = spanNameOf(payload);
|
|
1025
|
-
if (name === void 0 || !this.contentOff(traceFunctionKey, name)) return payload;
|
|
1026
|
-
return stripContent(payload);
|
|
1027
|
-
}
|
|
1028
|
-
};
|
|
1029
|
-
const activeRecords = /* @__PURE__ */ new Map();
|
|
1030
|
-
const completedRecords = /* @__PURE__ */ new Map();
|
|
1031
|
-
function findRecord(traceId) {
|
|
1032
|
-
return activeRecords.get(traceId) ?? completedRecords.get(traceId);
|
|
1033
|
-
}
|
|
1034
|
-
function recordCallerTraceMetadata(traceId, metadata) {
|
|
1035
|
-
if (typeof traceId !== "string" || traceId === "") return;
|
|
1036
|
-
if (typeof metadata !== "object" || metadata === null) return;
|
|
1037
|
-
if (Object.keys(metadata).length === 0) return;
|
|
1038
|
-
const existing = findRecord(traceId);
|
|
1039
|
-
if (existing) {
|
|
1040
|
-
Object.assign(existing.caller, metadata);
|
|
1041
|
-
return;
|
|
1042
|
-
}
|
|
1043
|
-
activeRecords.set(traceId, {
|
|
1044
|
-
caller: { ...metadata },
|
|
1045
|
-
derived: {},
|
|
1046
|
-
warnedKeys: /* @__PURE__ */ new Set()
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
function callerTraceMetadata(traceId) {
|
|
1050
|
-
const record = findRecord(traceId);
|
|
1051
|
-
if (!record || Object.keys(record.caller).length === 0) return;
|
|
1052
|
-
return { ...record.caller };
|
|
1053
|
-
}
|
|
1054
|
-
function retireTraceMetadata(traceId) {
|
|
1055
|
-
const record = activeRecords.get(traceId);
|
|
1056
|
-
if (!record) return;
|
|
1057
|
-
activeRecords.delete(traceId);
|
|
1058
|
-
completedRecords.set(traceId, record);
|
|
1059
|
-
while (completedRecords.size > 128) {
|
|
1060
|
-
const oldest = completedRecords.keys().next();
|
|
1061
|
-
if (oldest.done) return;
|
|
1062
|
-
completedRecords.delete(oldest.value);
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
function warnAboutShadowedKeys(traceId, record) {
|
|
1066
|
-
const shadowed = Object.keys(record.derived).filter((key) => key in record.caller && record.caller[key] !== record.derived[key] && !record.warnedKeys.has(key)).sort();
|
|
1067
|
-
if (shadowed.length === 0) return;
|
|
1068
|
-
for (const key of shadowed) record.warnedKeys.add(key);
|
|
1069
|
-
require_autoTrace.warn(`trace metadata key(s) ${shadowed.join(", ")} on trace ${traceId} were set both by the caller and by an integration's own trace export; the caller's value is the one kept on the trace.`);
|
|
1070
|
-
}
|
|
1071
|
-
function mergeCallerMetadataIntoTracePayload(payload) {
|
|
1072
|
-
const externalTrace = payload.externalTrace;
|
|
1073
|
-
if (typeof externalTrace !== "object" || externalTrace === null) return payload;
|
|
1074
|
-
const external = externalTrace;
|
|
1075
|
-
const traceId = typeof payload.id === "string" && payload.id !== "" ? payload.id : external.id;
|
|
1076
|
-
if (typeof traceId !== "string" || traceId === "") return payload;
|
|
1077
|
-
const record = findRecord(traceId);
|
|
1078
|
-
if (!record || Object.keys(record.caller).length === 0) return payload;
|
|
1079
|
-
const exported = external.metadata;
|
|
1080
|
-
if (typeof exported === "object" && exported !== null) Object.assign(record.derived, exported);
|
|
1081
|
-
warnAboutShadowedKeys(traceId, record);
|
|
1082
|
-
return {
|
|
1083
|
-
...payload,
|
|
1084
|
-
externalTrace: {
|
|
1085
|
-
...external,
|
|
1086
|
-
metadata: {
|
|
1087
|
-
...record.derived,
|
|
1088
|
-
...record.caller
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
};
|
|
1092
|
-
}
|
|
1093
|
-
//#endregion
|
|
1094
|
-
//#region src/transportTypes.ts
|
|
1095
|
-
var DeliveryError = class extends Error {
|
|
1096
|
-
constructor(message, options = {}) {
|
|
1097
|
-
super(message);
|
|
1098
|
-
this.name = "DeliveryError";
|
|
1099
|
-
this.retryable = options.retryable ?? false;
|
|
1100
|
-
this.oversized = options.oversized ?? false;
|
|
1101
|
-
this.retryAfterMs = options.retryAfterMs;
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
//#endregion
|
|
1105
|
-
//#region src/unrefTimer.ts
|
|
1106
|
-
function unrefTimer(timer) {
|
|
1107
|
-
const handle = timer;
|
|
1108
|
-
if (typeof handle.unref === "function") handle.unref();
|
|
1109
|
-
}
|
|
1110
|
-
//#endregion
|
|
1111
|
-
//#region src/otel.ts
|
|
1112
|
-
const OPERATION_ATTRIBUTE = "bitfab.operation";
|
|
1113
|
-
const PAYLOAD_ATTRIBUTE = "bitfab.payload";
|
|
1114
|
-
const MAX_EXPORT_REQUEST_BYTES = 3e6;
|
|
1115
|
-
const MAX_DECOMPRESSED_REQUEST_BYTES = 8e6;
|
|
1116
|
-
const MAX_REQUEST_BYTES_ENV = "BITFAB_OTEL_MAX_REQUEST_BYTES";
|
|
1117
|
-
const EXPORT_CONCURRENCY_ENV = "BITFAB_OTEL_EXPORT_CONCURRENCY";
|
|
1118
|
-
const MAX_QUEUE_SIZE = 16384;
|
|
1119
|
-
const DIRECT_MAX_EXPORT_BATCH_SIZE = 512;
|
|
1120
|
-
const DIRECT_MAX_REQUEST_BATCH_SIZE = 256;
|
|
1121
|
-
const DEFAULT_EXPORT_CONCURRENCY = 32;
|
|
1122
|
-
const MAX_EXPORT_CONCURRENCY = 64;
|
|
1123
|
-
const SCHEDULE_DELAY_MILLIS = 5e3;
|
|
1124
|
-
const EXPORT_TIMEOUT_MILLIS = 3e4;
|
|
1125
|
-
const RETRY_BASE_DELAY_MILLIS = 100;
|
|
1126
|
-
const RETRY_BACKOFF_CEILING_MILLIS = 5e3;
|
|
1127
|
-
const MAX_SEND_ATTEMPTS = 3;
|
|
1128
|
-
const DEFAULT_LIFECYCLE_TIMEOUT_MS$1 = 3e4;
|
|
1129
|
-
const liveTransports = /* @__PURE__ */ new Set();
|
|
1130
|
-
const carrierRefs = /* @__PURE__ */ new WeakMap();
|
|
1131
|
-
function readBoundedIntEnv(name, max, fallback, warnKey) {
|
|
1132
|
-
const raw = readEnv$1(name);
|
|
1133
|
-
if (raw === void 0) return fallback;
|
|
1134
|
-
const value = Number(raw);
|
|
1135
|
-
if (Number.isInteger(value) && value > 0 && value <= max) return value;
|
|
1136
|
-
require_autoTrace.warnOnce(warnKey, `${name} must be a positive integer no greater than ${max}; using ${fallback}`);
|
|
1137
|
-
return fallback;
|
|
1138
|
-
}
|
|
1139
|
-
function logError(message, error) {
|
|
1140
|
-
try {
|
|
1141
|
-
if (error === void 0) console.error(`[bitfab] ${message}`);
|
|
1142
|
-
else console.error(`[bitfab] ${message}`, error);
|
|
1143
|
-
} catch {}
|
|
1144
|
-
}
|
|
1145
|
-
function otlpValue(value) {
|
|
1146
|
-
if (typeof value === "boolean") return { boolValue: value };
|
|
1147
|
-
if (typeof value === "number") return Number.isInteger(value) ? { intValue: String(value) } : { doubleValue: value };
|
|
1148
|
-
if (typeof value === "string") return { stringValue: value };
|
|
1149
|
-
if (Array.isArray(value)) return { arrayValue: { values: value.map(otlpValue) } };
|
|
1150
|
-
return { stringValue: String(value) };
|
|
1151
|
-
}
|
|
1152
|
-
function otlpAttributes(attributes) {
|
|
1153
|
-
if (!attributes) return [];
|
|
1154
|
-
return Object.entries(attributes).filter(([, value]) => value !== void 0).map(([key, value]) => ({
|
|
1155
|
-
key,
|
|
1156
|
-
value: otlpValue(value)
|
|
1157
|
-
}));
|
|
1158
|
-
}
|
|
1159
|
-
function hrTimeToNanoString(time) {
|
|
1160
|
-
if (!time) return "0";
|
|
1161
|
-
return `${time[0]}${String(time[1]).padStart(9, "0")}`;
|
|
1162
|
-
}
|
|
1163
|
-
function spanToOtlp(span) {
|
|
1164
|
-
const spanContext = span.spanContext();
|
|
1165
|
-
const result = {
|
|
1166
|
-
traceId: spanContext.traceId,
|
|
1167
|
-
spanId: spanContext.spanId,
|
|
1168
|
-
name: span.name,
|
|
1169
|
-
kind: span.kind + 1,
|
|
1170
|
-
startTimeUnixNano: hrTimeToNanoString(span.startTime),
|
|
1171
|
-
endTimeUnixNano: hrTimeToNanoString(span.endTime),
|
|
1172
|
-
attributes: otlpAttributes(span.attributes),
|
|
1173
|
-
droppedAttributesCount: span.droppedAttributesCount,
|
|
1174
|
-
droppedEventsCount: span.droppedEventsCount,
|
|
1175
|
-
droppedLinksCount: span.droppedLinksCount,
|
|
1176
|
-
status: {
|
|
1177
|
-
code: span.status.code,
|
|
1178
|
-
...span.status.message ? { message: span.status.message } : {}
|
|
1179
|
-
},
|
|
1180
|
-
flags: spanContext.traceFlags
|
|
1181
|
-
};
|
|
1182
|
-
const parentSpanId = span.parentSpanContext?.spanId;
|
|
1183
|
-
if (parentSpanId) result.parentSpanId = parentSpanId;
|
|
1184
|
-
if (spanContext.traceState) result.traceState = spanContext.traceState.serialize();
|
|
1185
|
-
return result;
|
|
1186
|
-
}
|
|
1187
|
-
const SPAN_SEPARATOR_BYTES = 1;
|
|
1188
|
-
function encodeSpan(span) {
|
|
1189
|
-
const json = JSON.stringify(spanToOtlp(span));
|
|
1190
|
-
return {
|
|
1191
|
-
json,
|
|
1192
|
-
size: byteLength(json),
|
|
1193
|
-
ref: carrierRefs.get(span)
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
function trimEncodedSpan(span) {
|
|
1197
|
-
try {
|
|
1198
|
-
const carrier = JSON.parse(span.json);
|
|
1199
|
-
const attribute = carrier.attributes?.find((entry) => entry.key === PAYLOAD_ATTRIBUTE);
|
|
1200
|
-
const payloadBody = attribute?.value?.stringValue;
|
|
1201
|
-
if (!attribute?.value || payloadBody === void 0) return;
|
|
1202
|
-
const payload = JSON.parse(payloadBody);
|
|
1203
|
-
attribute.value.stringValue = serializePayloadBody(payload, MAX_SPAN_CARRIER_BYTES).body;
|
|
1204
|
-
const json = JSON.stringify(carrier);
|
|
1205
|
-
return {
|
|
1206
|
-
json,
|
|
1207
|
-
size: byteLength(json)
|
|
1208
|
-
};
|
|
1209
|
-
} catch {
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
async function prepareRequest(body) {
|
|
1214
|
-
const prepared = encodeRequestBody(body);
|
|
1215
|
-
return prepared instanceof Promise ? await prepared : prepared;
|
|
1216
|
-
}
|
|
1217
|
-
function requestEnvelope(first) {
|
|
1218
|
-
const scope = first.instrumentationScope;
|
|
1219
|
-
const head = `{"resourceSpans":[{"resource":${JSON.stringify({ attributes: otlpAttributes(first.resource.attributes) })},"scopeSpans":[{"scope":${JSON.stringify({
|
|
1220
|
-
name: scope.name,
|
|
1221
|
-
version: scope.version ?? ""
|
|
1222
|
-
})},"spans":[`;
|
|
1223
|
-
const tail = "]}]}]}";
|
|
1224
|
-
return {
|
|
1225
|
-
head,
|
|
1226
|
-
tail,
|
|
1227
|
-
size: byteLength(head) + byteLength(tail)
|
|
1228
|
-
};
|
|
1229
|
-
}
|
|
1230
|
-
function encodeRequest(envelope, spans) {
|
|
1231
|
-
return envelope.head + spans.map((span) => span.json).join(",") + envelope.tail;
|
|
1232
|
-
}
|
|
1233
|
-
function delay(ms) {
|
|
1234
|
-
return new Promise((resolve) => {
|
|
1235
|
-
unrefTimer(setTimeout(resolve, ms));
|
|
1236
|
-
});
|
|
1237
|
-
}
|
|
1238
|
-
async function withDeadline(work, timeoutMs) {
|
|
1239
|
-
let timer;
|
|
1240
|
-
try {
|
|
1241
|
-
return await Promise.race([work, new Promise((resolve) => {
|
|
1242
|
-
timer = setTimeout(() => resolve(false), Math.max(0, timeoutMs));
|
|
1243
|
-
unrefTimer(timer);
|
|
1244
|
-
})]);
|
|
1245
|
-
} finally {
|
|
1246
|
-
if (timer) clearTimeout(timer);
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
async function mapWithConcurrency$1(items, limit, task) {
|
|
1250
|
-
const results = new Array(items.length);
|
|
1251
|
-
let next = 0;
|
|
1252
|
-
const workers = Array.from({ length: Math.min(Math.max(limit, 1), items.length) }, async () => {
|
|
1253
|
-
while (next < items.length) {
|
|
1254
|
-
const index = next;
|
|
1255
|
-
next += 1;
|
|
1256
|
-
results[index] = await task(items[index]);
|
|
1257
|
-
}
|
|
1258
|
-
});
|
|
1259
|
-
await Promise.all(workers);
|
|
1260
|
-
return results;
|
|
1261
|
-
}
|
|
1262
|
-
function isRetryable(error) {
|
|
1263
|
-
return error instanceof DeliveryError && error.retryable;
|
|
1264
|
-
}
|
|
1265
|
-
function isOversized(error) {
|
|
1266
|
-
return error instanceof DeliveryError && error.oversized;
|
|
1267
|
-
}
|
|
1268
|
-
function retryWaitMillis(error, attempt, remainingMillis) {
|
|
1269
|
-
const requested = error instanceof DeliveryError ? error.retryAfterMs : void 0;
|
|
1270
|
-
const affordable = remainingMillis / 2;
|
|
1271
|
-
if (requested !== void 0) return requested < affordable ? requested : null;
|
|
1272
|
-
const backoff = Math.min(RETRY_BASE_DELAY_MILLIS * 2 ** attempt, RETRY_BACKOFF_CEILING_MILLIS);
|
|
1273
|
-
const jittered = backoff / 2 + Math.random() * (backoff / 2);
|
|
1274
|
-
return jittered < affordable ? jittered : null;
|
|
1275
|
-
}
|
|
1276
|
-
var BitfabSpanExporter = class {
|
|
1277
|
-
constructor(directSender, maxRequestBytes, maxRequestBatchSize, exportConcurrency, onDelivered, exportTimeoutMillis = EXPORT_TIMEOUT_MILLIS) {
|
|
1278
|
-
this.directSender = directSender;
|
|
1279
|
-
this.maxRequestBytes = maxRequestBytes;
|
|
1280
|
-
this.maxRequestBatchSize = maxRequestBatchSize;
|
|
1281
|
-
this.exportConcurrency = exportConcurrency;
|
|
1282
|
-
this.onDelivered = onDelivered;
|
|
1283
|
-
this.exportTimeoutMillis = exportTimeoutMillis;
|
|
1284
|
-
this.throttledUntil = 0;
|
|
1285
|
-
}
|
|
1286
|
-
export(spans, resultCallback) {
|
|
1287
|
-
this.exportAsync(spans).then((succeeded) => {
|
|
1288
|
-
resultCallback({ code: succeeded ? _opentelemetry_core.ExportResultCode.SUCCESS : _opentelemetry_core.ExportResultCode.FAILED });
|
|
1289
|
-
}, (error) => {
|
|
1290
|
-
resultCallback({
|
|
1291
|
-
code: _opentelemetry_core.ExportResultCode.FAILED,
|
|
1292
|
-
error
|
|
1293
|
-
});
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
async exportAsync(spans) {
|
|
1297
|
-
if (spans.length === 0) return true;
|
|
1298
|
-
let encoded;
|
|
1299
|
-
let envelope;
|
|
1300
|
-
try {
|
|
1301
|
-
encoded = spans.map(encodeSpan);
|
|
1302
|
-
envelope = requestEnvelope(spans[0]);
|
|
1303
|
-
} catch (error) {
|
|
1304
|
-
logError("failed to encode an OpenTelemetry span batch", error);
|
|
1305
|
-
return false;
|
|
1306
|
-
}
|
|
1307
|
-
return (await mapWithConcurrency$1(this.buildRequestBatches(envelope, encoded), this.exportConcurrency, (batch) => this.send(envelope, batch))).every(Boolean);
|
|
1308
|
-
}
|
|
1309
|
-
buildRequestBatches(envelope, spans) {
|
|
1310
|
-
const batches = [];
|
|
1311
|
-
let current = [];
|
|
1312
|
-
let size = envelope.size;
|
|
1313
|
-
for (const span of spans) {
|
|
1314
|
-
const addition = span.size + (current.length > 0 ? SPAN_SEPARATOR_BYTES : 0);
|
|
1315
|
-
if (current.length > 0 && (current.length >= this.maxRequestBatchSize || size + addition > this.maxRequestBytes)) {
|
|
1316
|
-
batches.push({
|
|
1317
|
-
spans: current,
|
|
1318
|
-
size
|
|
1319
|
-
});
|
|
1320
|
-
current = [];
|
|
1321
|
-
size = envelope.size;
|
|
1322
|
-
}
|
|
1323
|
-
current.push(span);
|
|
1324
|
-
size += span.size + (current.length > 1 ? SPAN_SEPARATOR_BYTES : 0);
|
|
1325
|
-
}
|
|
1326
|
-
if (current.length > 0) batches.push({
|
|
1327
|
-
spans: current,
|
|
1328
|
-
size
|
|
1329
|
-
});
|
|
1330
|
-
return batches;
|
|
1331
|
-
}
|
|
1332
|
-
async send(envelope, batch) {
|
|
1333
|
-
try {
|
|
1334
|
-
let requestSpans = batch.spans;
|
|
1335
|
-
let requestRawBytes = batch.size;
|
|
1336
|
-
let alreadyTrimmed = false;
|
|
1337
|
-
while (true) {
|
|
1338
|
-
if (requestRawBytes <= MAX_DECOMPRESSED_REQUEST_BYTES) {
|
|
1339
|
-
const prepared = await prepareRequest(encodeRequest(envelope, requestSpans));
|
|
1340
|
-
if (prepared.wireBytes <= this.maxRequestBytes) {
|
|
1341
|
-
await this.sendWithRetries(prepared);
|
|
1342
|
-
this.reportDelivered(batch.spans);
|
|
1343
|
-
return true;
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
if (batch.spans.length !== 1) {
|
|
1347
|
-
logError("an OpenTelemetry span batch exceeded the configured request-size target and could not be exported");
|
|
1348
|
-
return false;
|
|
1349
|
-
}
|
|
1350
|
-
if (alreadyTrimmed) {
|
|
1351
|
-
logError("a single OpenTelemetry span exceeded the configured request-size target after trimming");
|
|
1352
|
-
return false;
|
|
1353
|
-
}
|
|
1354
|
-
const trimmed = trimEncodedSpan(batch.spans[0]);
|
|
1355
|
-
if (!trimmed) {
|
|
1356
|
-
logError("a single OpenTelemetry span exceeded the configured request-size target and could not be trimmed");
|
|
1357
|
-
return false;
|
|
1358
|
-
}
|
|
1359
|
-
requestSpans = [trimmed];
|
|
1360
|
-
requestRawBytes = envelope.size + trimmed.size;
|
|
1361
|
-
alreadyTrimmed = true;
|
|
1362
|
-
}
|
|
1363
|
-
} catch (error) {
|
|
1364
|
-
if (isOversized(error)) {
|
|
1365
|
-
logError(batch.spans.length === 1 ? "a single OpenTelemetry span exceeded the ingestion request limit and could not be exported" : "an OpenTelemetry span batch exceeded the ingestion request limit and could not be exported");
|
|
1366
|
-
return false;
|
|
1367
|
-
}
|
|
1368
|
-
logError("failed to export an OpenTelemetry span batch", error);
|
|
1369
|
-
return false;
|
|
1370
|
-
}
|
|
1371
|
-
}
|
|
1372
|
-
recordThrottle(error) {
|
|
1373
|
-
const requested = error instanceof DeliveryError ? error.retryAfterMs : void 0;
|
|
1374
|
-
if (requested !== void 0) this.throttledUntil = Math.max(this.throttledUntil, Date.now() + requested);
|
|
1375
|
-
}
|
|
1376
|
-
async awaitThrottle(deadline) {
|
|
1377
|
-
const remaining = this.throttledUntil - Date.now();
|
|
1378
|
-
if (remaining <= 0) return;
|
|
1379
|
-
if (remaining >= (deadline - Date.now()) / 2) throw new DeliveryError(`OTLP ingestion is throttled for another ${remaining}ms, longer than the export budget`);
|
|
1380
|
-
await delay(remaining);
|
|
1381
|
-
}
|
|
1382
|
-
async sendWithRetries(request) {
|
|
1383
|
-
const deadline = Date.now() + this.exportTimeoutMillis;
|
|
1384
|
-
for (let attempt = 0; attempt < MAX_SEND_ATTEMPTS; attempt += 1) try {
|
|
1385
|
-
await this.awaitThrottle(deadline);
|
|
1386
|
-
await this.directSender(request, Math.max(0, deadline - Date.now()));
|
|
1387
|
-
return;
|
|
1388
|
-
} catch (error) {
|
|
1389
|
-
if (isOversized(error)) throw error;
|
|
1390
|
-
this.recordThrottle(error);
|
|
1391
|
-
if (attempt === 2 || !isRetryable(error)) throw error;
|
|
1392
|
-
const wait = retryWaitMillis(error, attempt, deadline - Date.now());
|
|
1393
|
-
if (wait === null) throw error;
|
|
1394
|
-
await delay(wait);
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
reportDelivered(spans) {
|
|
1398
|
-
if (this.onDelivered === void 0) return;
|
|
1399
|
-
const refs = spans.map((span) => span.ref).filter((ref) => ref !== void 0);
|
|
1400
|
-
if (refs.length === 0) return;
|
|
1401
|
-
try {
|
|
1402
|
-
this.onDelivered(refs);
|
|
1403
|
-
} catch (error) {
|
|
1404
|
-
logError("a delivery listener threw", error);
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
async shutdown() {}
|
|
1408
|
-
async forceFlush() {}
|
|
1409
|
-
};
|
|
1410
|
-
var DeliveryTrackingExporter = class {
|
|
1411
|
-
constructor(exporter) {
|
|
1412
|
-
this.exporter = exporter;
|
|
1413
|
-
this.failedExports = 0;
|
|
1414
|
-
}
|
|
1415
|
-
export(spans, resultCallback) {
|
|
1416
|
-
try {
|
|
1417
|
-
this.exporter.export(spans, (result) => {
|
|
1418
|
-
if (result.code !== _opentelemetry_core.ExportResultCode.SUCCESS) this.failedExports += 1;
|
|
1419
|
-
resultCallback(result);
|
|
1420
|
-
});
|
|
1421
|
-
} catch (error) {
|
|
1422
|
-
this.failedExports += 1;
|
|
1423
|
-
resultCallback({
|
|
1424
|
-
code: _opentelemetry_core.ExportResultCode.FAILED,
|
|
1425
|
-
error
|
|
1426
|
-
});
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
takeFailedExports() {
|
|
1430
|
-
const failed = this.failedExports;
|
|
1431
|
-
this.failedExports = 0;
|
|
1432
|
-
return failed;
|
|
1433
|
-
}
|
|
1434
|
-
shutdown() {
|
|
1435
|
-
return this.exporter.shutdown();
|
|
1436
|
-
}
|
|
1437
|
-
forceFlush() {
|
|
1438
|
-
return this.exporter.forceFlush?.() ?? Promise.resolve();
|
|
1
|
+
const require_bamlPeer = require("./bamlPeer-BUoZgNxZ.cjs");
|
|
2
|
+
const require_http = require("./http-DX-fpUSu.cjs");
|
|
3
|
+
const require_autoTrace = require("./autoTrace-CQw0qMBt.cjs");
|
|
4
|
+
let superjson = require("superjson");
|
|
5
|
+
superjson = require_bamlPeer.__toESM(superjson, 1);
|
|
6
|
+
//#region src/categories.ts
|
|
7
|
+
const CATEGORIES_PATH = "/api/sdk/categories";
|
|
8
|
+
var CategoriesClient = class {
|
|
9
|
+
constructor(httpClient) {
|
|
10
|
+
this.httpClient = httpClient;
|
|
1439
11
|
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
constructor(options) {
|
|
1443
|
-
this.closed = false;
|
|
1444
|
-
const maxRequestBytes = options.maxRequestBytes ?? MAX_EXPORT_REQUEST_BYTES;
|
|
1445
|
-
const maxRequestBatchSize = options.maxRequestBatchSize ?? DIRECT_MAX_REQUEST_BATCH_SIZE;
|
|
1446
|
-
if (maxRequestBatchSize <= 0) throw new BitfabError("maxRequestBatchSize must be a positive integer");
|
|
1447
|
-
this.deliveryTracker = new DeliveryTrackingExporter(new BitfabSpanExporter(options.directSender, maxRequestBytes, maxRequestBatchSize, options.exportConcurrency ?? DEFAULT_EXPORT_CONCURRENCY, options.onDelivered, options.exportTimeoutMillis ?? EXPORT_TIMEOUT_MILLIS));
|
|
1448
|
-
this.processor = new _opentelemetry_sdk_trace_base.BatchSpanProcessor(this.deliveryTracker, {
|
|
1449
|
-
maxQueueSize: options.maxQueueSize ?? MAX_QUEUE_SIZE,
|
|
1450
|
-
maxExportBatchSize: options.maxExportBatchSize ?? DIRECT_MAX_EXPORT_BATCH_SIZE,
|
|
1451
|
-
scheduledDelayMillis: SCHEDULE_DELAY_MILLIS,
|
|
1452
|
-
exportTimeoutMillis: options.exportTimeoutMillis ?? EXPORT_TIMEOUT_MILLIS
|
|
1453
|
-
});
|
|
1454
|
-
this.provider = new _opentelemetry_sdk_trace_base.BasicTracerProvider({
|
|
1455
|
-
sampler: new _opentelemetry_sdk_trace_base.AlwaysOnSampler(),
|
|
1456
|
-
resource: (0, _opentelemetry_resources.resourceFromAttributes)({
|
|
1457
|
-
"service.name": "bitfab-typescript-sdk",
|
|
1458
|
-
"service.version": __version__
|
|
1459
|
-
}),
|
|
1460
|
-
spanLimits: {
|
|
1461
|
-
attributeCountLimit: 2,
|
|
1462
|
-
attributeValueLengthLimit: Number.POSITIVE_INFINITY
|
|
1463
|
-
},
|
|
1464
|
-
spanProcessors: [this.processor]
|
|
1465
|
-
});
|
|
1466
|
-
this.tracer = this.provider.getTracer("bitfab", __version__);
|
|
1467
|
-
liveTransports.add(this);
|
|
12
|
+
async save(params) {
|
|
13
|
+
return (await this.httpClient.request(CATEGORIES_PATH, params)).category;
|
|
1468
14
|
}
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
require_autoTrace.warnOnce("otel-submit-after-shutdown", "OpenTelemetry transport is shut down; dropping spans");
|
|
1472
|
-
return;
|
|
1473
|
-
}
|
|
1474
|
-
try {
|
|
1475
|
-
const { body, dropped } = serializePayloadBody(payload, MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES);
|
|
1476
|
-
if (dropped.length > 0) require_autoTrace.warnOnce("otel-carrier-payload-stubbed", `a span payload held non-serializable value(s) (${[...new Set(dropped)].join(", ")}); they were stubbed so the span still ships, but the trace may be incomplete or not replayable.`);
|
|
1477
|
-
const span = this.tracer.startSpan(meta.name ?? `bitfab.${operation}`, {
|
|
1478
|
-
attributes: {
|
|
1479
|
-
[OPERATION_ATTRIBUTE]: operation,
|
|
1480
|
-
[PAYLOAD_ATTRIBUTE]: body
|
|
1481
|
-
},
|
|
1482
|
-
startTime: meta.startTime
|
|
1483
|
-
});
|
|
1484
|
-
if (meta.ref !== void 0) carrierRefs.set(span, meta.ref);
|
|
1485
|
-
if (meta.errored === true) span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
|
|
1486
|
-
endSpan(span, meta.endTime);
|
|
1487
|
-
} catch (error) {
|
|
1488
|
-
logError("failed to queue an OpenTelemetry span", error);
|
|
1489
|
-
}
|
|
15
|
+
async get(id) {
|
|
16
|
+
return (await this.httpClient.get(`${CATEGORIES_PATH}/${encodeURIComponent(id)}`)).category;
|
|
1490
17
|
}
|
|
1491
|
-
async
|
|
1492
|
-
|
|
1493
|
-
this.pendingFlush = pending.catch(() => false);
|
|
1494
|
-
return withDeadline(pending, timeoutMs);
|
|
18
|
+
async list() {
|
|
19
|
+
return (await this.httpClient.get(CATEGORIES_PATH)).categories;
|
|
1495
20
|
}
|
|
1496
|
-
async
|
|
1497
|
-
|
|
1498
|
-
await this.processor.forceFlush();
|
|
1499
|
-
} catch (error) {
|
|
1500
|
-
logError("failed to flush OpenTelemetry spans", error);
|
|
1501
|
-
this.deliveryTracker.takeFailedExports();
|
|
1502
|
-
return false;
|
|
1503
|
-
}
|
|
1504
|
-
return this.deliveryTracker.takeFailedExports() === 0;
|
|
1505
|
-
}
|
|
1506
|
-
async shutdown(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS$1) {
|
|
1507
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1508
|
-
this.closed = true;
|
|
1509
|
-
const flushed = await this.flush(Math.max(0, deadline - Date.now()));
|
|
1510
|
-
liveTransports.delete(this);
|
|
1511
|
-
const shutdownCompleted = await withDeadline(this.provider.shutdown().then(() => true).catch((error) => {
|
|
1512
|
-
logError("failed to shut down the OpenTelemetry transport", error);
|
|
1513
|
-
return false;
|
|
1514
|
-
}), Math.max(0, deadline - Date.now()));
|
|
1515
|
-
return flushed && shutdownCompleted;
|
|
21
|
+
async delete(id) {
|
|
22
|
+
return (await this.httpClient.request(`${CATEGORIES_PATH}/${encodeURIComponent(id)}`, {}, { method: "DELETE" })).category;
|
|
1516
23
|
}
|
|
1517
24
|
};
|
|
1518
|
-
|
|
1519
|
-
span.end(endTime);
|
|
1520
|
-
}
|
|
1521
|
-
function createOtelTransport(options) {
|
|
1522
|
-
return new OtelBatchTransport({
|
|
1523
|
-
...options,
|
|
1524
|
-
exportConcurrency: readBoundedIntEnv(EXPORT_CONCURRENCY_ENV, MAX_EXPORT_CONCURRENCY, DEFAULT_EXPORT_CONCURRENCY, "otel-export-concurrency-invalid"),
|
|
1525
|
-
maxRequestBytes: readBoundedIntEnv(MAX_REQUEST_BYTES_ENV, MAX_EXPORT_REQUEST_BYTES, MAX_EXPORT_REQUEST_BYTES, "otel-max-request-bytes-invalid")
|
|
1526
|
-
});
|
|
1527
|
-
}
|
|
1528
|
-
async function forEachLiveTransport(timeoutMs, run) {
|
|
1529
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1530
|
-
let succeeded = true;
|
|
1531
|
-
for (const transport of [...liveTransports]) succeeded = await run(transport, Math.max(0, deadline - Date.now())) && succeeded;
|
|
1532
|
-
return succeeded;
|
|
1533
|
-
}
|
|
1534
|
-
function flushOtelTransports(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS$1) {
|
|
1535
|
-
return forEachLiveTransport(timeoutMs, (transport, remaining) => transport.flush(remaining));
|
|
1536
|
-
}
|
|
1537
|
-
function shutdownOtelTransports(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS$1) {
|
|
1538
|
-
return forEachLiveTransport(timeoutMs, (transport, remaining) => transport.shutdown(remaining));
|
|
1539
|
-
}
|
|
1540
|
-
//#endregion
|
|
1541
|
-
//#region src/transport.ts
|
|
1542
|
-
function createTraceTransport(options) {
|
|
1543
|
-
return createOtelTransport(options);
|
|
1544
|
-
}
|
|
1545
|
-
function flushTraceTransports(timeoutMs) {
|
|
1546
|
-
return flushOtelTransports(timeoutMs);
|
|
1547
|
-
}
|
|
1548
|
-
function shutdownTraceTransports(timeoutMs) {
|
|
1549
|
-
return shutdownOtelTransports(timeoutMs);
|
|
1550
|
-
}
|
|
25
|
+
const AssertionCategoriesClient = CategoriesClient;
|
|
1551
26
|
//#endregion
|
|
1552
|
-
//#region src/
|
|
1553
|
-
|
|
1554
|
-
BitfabError: () => BitfabError,
|
|
1555
|
-
HttpClient: () => HttpClient,
|
|
1556
|
-
SPAN_TYPES: () => SPAN_TYPES,
|
|
1557
|
-
awaitOnExit: () => awaitOnExit,
|
|
1558
|
-
awaitPendingRequests: () => awaitPendingRequests,
|
|
1559
|
-
experimentIdWireFields: () => experimentIdWireFields,
|
|
1560
|
-
flushTraces: () => flushTraces,
|
|
1561
|
-
parseRetryAfterMs: () => parseRetryAfterMs,
|
|
1562
|
-
serializePayloadBody: () => serializePayloadBody
|
|
1563
|
-
});
|
|
1564
|
-
const REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS = 3e5;
|
|
1565
|
-
const REPLAY_COMPLETE_REQUEST_TIMEOUT_MS = 12e4;
|
|
1566
|
-
const REPLAY_INTERRUPT_REQUEST_TIMEOUT_MS = 5e3;
|
|
1567
|
-
const REPLAY_HEARTBEAT_REQUEST_TIMEOUT_MS = 5e3;
|
|
1568
|
-
const OTLP_TRACES_ENDPOINT = "/api/sdk/otel/v1/traces";
|
|
1569
|
-
const RETRYABLE_STATUSES = /* @__PURE__ */ new Set([
|
|
1570
|
-
429,
|
|
1571
|
-
500,
|
|
1572
|
-
502,
|
|
1573
|
-
503,
|
|
1574
|
-
504
|
|
1575
|
-
]);
|
|
1576
|
-
const EXIT_FLUSH_TIMEOUT_MS = 5e3;
|
|
1577
|
-
const DEFAULT_LIFECYCLE_TIMEOUT_MS = 3e4;
|
|
1578
|
-
const pendingTracePromises = /* @__PURE__ */ new Set();
|
|
1579
|
-
const liveHttpClients = /* @__PURE__ */ new Set();
|
|
1580
|
-
async function releaseHeldExternalSpans(timeoutMs) {
|
|
1581
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1582
|
-
let released = true;
|
|
1583
|
-
for (const client of [...liveHttpClients]) released = await client.releaseHeldExternalSpans?.(Math.max(0, deadline - Date.now())) !== false && released;
|
|
1584
|
-
return released;
|
|
1585
|
-
}
|
|
1586
|
-
function stopSimulationPlans() {
|
|
1587
|
-
for (const client of [...liveHttpClients]) client.stopSimulationPlan?.();
|
|
1588
|
-
}
|
|
1589
|
-
function awaitOnExit(promise) {
|
|
1590
|
-
pendingTracePromises.add(promise);
|
|
1591
|
-
promise.finally(() => {
|
|
1592
|
-
pendingTracePromises.delete(promise);
|
|
1593
|
-
}).catch(() => {});
|
|
1594
|
-
return promise;
|
|
1595
|
-
}
|
|
1596
|
-
async function flushTraces(timeoutMs = 5e3) {
|
|
1597
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1598
|
-
const released = await releaseHeldExternalSpans(planWaitSliceMs(timeoutMs));
|
|
1599
|
-
const requestsFlushed = await awaitPendingRequests(Math.max(0, deadline - Date.now()));
|
|
1600
|
-
const releasedAfterDeferred = await releaseHeldExternalSpans(0);
|
|
1601
|
-
const transportsFlushed = await flushTraceTransports(Math.max(0, deadline - Date.now()));
|
|
1602
|
-
return released && releasedAfterDeferred && requestsFlushed && transportsFlushed;
|
|
1603
|
-
}
|
|
1604
|
-
async function awaitPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS) {
|
|
1605
|
-
await replayContextReady.catch(() => {});
|
|
1606
|
-
return waitForPromises(Array.from(pendingTracePromises), timeoutMs);
|
|
1607
|
-
}
|
|
1608
|
-
async function waitForPromises(promises, timeoutMs) {
|
|
1609
|
-
if (promises.length === 0) return true;
|
|
1610
|
-
let timer;
|
|
1611
|
-
try {
|
|
1612
|
-
return await Promise.race([Promise.allSettled(promises).then(() => true), new Promise((resolve) => {
|
|
1613
|
-
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
1614
|
-
unrefTimer(timer);
|
|
1615
|
-
})]);
|
|
1616
|
-
} finally {
|
|
1617
|
-
if (timer) clearTimeout(timer);
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
1621
|
-
let isFlushing = false;
|
|
1622
|
-
process.on("beforeExit", () => {
|
|
1623
|
-
if (isFlushing) return;
|
|
1624
|
-
isFlushing = true;
|
|
1625
|
-
const planWaitMs = SIMULATION_PLAN_READ_TIMEOUT_MS;
|
|
1626
|
-
const stopFlushing = () => {
|
|
1627
|
-
isFlushing = false;
|
|
1628
|
-
};
|
|
1629
|
-
const deadline = setTimeout(stopFlushing, 1e4);
|
|
1630
|
-
unrefTimer(deadline);
|
|
1631
|
-
releaseHeldExternalSpans(planWaitMs).catch(() => {}).then(() => {
|
|
1632
|
-
stopSimulationPlans();
|
|
1633
|
-
}).then(() => Promise.allSettled([...Array.from(pendingTracePromises).map((p) => p.catch(() => {})), shutdownTraceTransports(EXIT_FLUSH_TIMEOUT_MS).catch(() => false)])).then(() => {
|
|
1634
|
-
clearTimeout(deadline);
|
|
1635
|
-
stopFlushing();
|
|
1636
|
-
});
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1639
|
-
const SPAN_TYPES = [
|
|
1640
|
-
"llm",
|
|
1641
|
-
"agent",
|
|
1642
|
-
"function",
|
|
1643
|
-
"guardrail",
|
|
1644
|
-
"handoff",
|
|
1645
|
-
"custom"
|
|
1646
|
-
];
|
|
1647
|
-
function readHeader(response, name) {
|
|
1648
|
-
try {
|
|
1649
|
-
return response.headers?.get(name) ?? null;
|
|
1650
|
-
} catch {
|
|
1651
|
-
return null;
|
|
1652
|
-
}
|
|
1653
|
-
}
|
|
1654
|
-
function parseRetryAfterMs(header) {
|
|
1655
|
-
const value = header?.trim();
|
|
1656
|
-
if (!value) return;
|
|
1657
|
-
const seconds = Number(value);
|
|
1658
|
-
if (Number.isFinite(seconds)) return seconds >= 0 ? seconds * 1e3 : void 0;
|
|
1659
|
-
const at = Date.parse(value);
|
|
1660
|
-
if (Number.isNaN(at)) return;
|
|
1661
|
-
return Math.max(0, at - Date.now());
|
|
1662
|
-
}
|
|
1663
|
-
function carrierMeta(operation, payload, ref) {
|
|
1664
|
-
return {
|
|
1665
|
-
ref,
|
|
1666
|
-
name: carrierName(operation, payload),
|
|
1667
|
-
startTime: payloadTimestamp(payload, "started_at"),
|
|
1668
|
-
endTime: payloadTimestamp(payload, "ended_at"),
|
|
1669
|
-
errored: payloadHasError(payload)
|
|
1670
|
-
};
|
|
1671
|
-
}
|
|
1672
|
-
function carrierName(operation, payload) {
|
|
1673
|
-
if (operation === "external_span") {
|
|
1674
|
-
const spanData = asPayloadRecord(asPayloadRecord(payload.rawSpan)?.span_data);
|
|
1675
|
-
if (typeof spanData?.name === "string") return spanData.name;
|
|
1676
|
-
}
|
|
1677
|
-
if (typeof payload.traceFunctionKey === "string") return payload.traceFunctionKey;
|
|
1678
|
-
return `bitfab.${operation}`;
|
|
1679
|
-
}
|
|
1680
|
-
function payloadTimestamp(payload, field) {
|
|
1681
|
-
const rawSpan = asPayloadRecord(payload.rawSpan);
|
|
1682
|
-
const rawTrace = asPayloadRecord(payload.externalTrace) ?? asPayloadRecord(payload.rawTrace);
|
|
1683
|
-
const raw = rawSpan?.[field] ?? rawTrace?.[field];
|
|
1684
|
-
if (typeof raw !== "string") return;
|
|
1685
|
-
const parsed = Date.parse(raw);
|
|
1686
|
-
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
1687
|
-
}
|
|
1688
|
-
function payloadHasError(payload) {
|
|
1689
|
-
if (asPayloadRecord(asPayloadRecord(payload.rawSpan)?.span_data)?.error != null) return true;
|
|
1690
|
-
const errors = payload.errors;
|
|
1691
|
-
return Array.isArray(errors) ? errors.length > 0 : Boolean(errors);
|
|
1692
|
-
}
|
|
1693
|
-
function asPayloadRecord(value) {
|
|
1694
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
1695
|
-
}
|
|
1696
|
-
function carrierRef(payload) {
|
|
1697
|
-
const traceId = sourceTraceIdOf(payload);
|
|
1698
|
-
if (traceId === void 0) return;
|
|
1699
|
-
const rawSpan = payload.rawSpan;
|
|
1700
|
-
if (rawSpan === void 0) return { traceId };
|
|
1701
|
-
const spanId = rawSpan?.id;
|
|
1702
|
-
return {
|
|
1703
|
-
traceId,
|
|
1704
|
-
spanId: typeof spanId === "string" ? spanId : `submission-${++carrierSeq}`
|
|
1705
|
-
};
|
|
1706
|
-
}
|
|
1707
|
-
function sourceTraceIdOf(payload) {
|
|
1708
|
-
if (typeof payload.sourceTraceId === "string") return payload.sourceTraceId;
|
|
1709
|
-
const id = (payload.externalTrace ?? payload.rawTrace)?.id;
|
|
1710
|
-
return typeof id === "string" ? id : void 0;
|
|
1711
|
-
}
|
|
1712
|
-
let carrierSeq = 0;
|
|
1713
|
-
function describeError(error) {
|
|
1714
|
-
return error instanceof Error ? error.message : String(error);
|
|
1715
|
-
}
|
|
1716
|
-
function warnDroppedExternalSpan(error) {
|
|
1717
|
-
require_autoTrace.warnOnce("external-span-dropped", `a span was dropped because the send step failed: ${describeError(error)}`);
|
|
1718
|
-
}
|
|
1719
|
-
function warnDroppedExternalTrace(error) {
|
|
1720
|
-
require_autoTrace.warnOnce("external-trace-dropped", `a trace was dropped because the send step failed: ${describeError(error)}`);
|
|
1721
|
-
}
|
|
1722
|
-
var HttpClient = class {
|
|
1723
|
-
constructor(config) {
|
|
1724
|
-
this.traceDeliveries = /* @__PURE__ */ new Map();
|
|
1725
|
-
this.deferredWork = /* @__PURE__ */ new Set();
|
|
1726
|
-
this.traceCompletion = new TraceCompletion();
|
|
1727
|
-
this.closed = false;
|
|
1728
|
-
this.apiKey = config.apiKey;
|
|
1729
|
-
this.serviceUrl = config.serviceUrl;
|
|
1730
|
-
this.timeout = config.timeout ?? 12e4;
|
|
1731
|
-
liveHttpClients.add(this);
|
|
1732
|
-
}
|
|
1733
|
-
resolveApiKey() {
|
|
1734
|
-
return typeof this.apiKey === "function" ? this.apiKey() : this.apiKey;
|
|
1735
|
-
}
|
|
1736
|
-
hasApiKey() {
|
|
1737
|
-
try {
|
|
1738
|
-
const apiKey = this.resolveApiKey();
|
|
1739
|
-
return apiKey !== void 0 && apiKey.trim() !== "";
|
|
1740
|
-
} catch {
|
|
1741
|
-
return false;
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
getTraceTransport() {
|
|
1745
|
-
if (this.closed) {
|
|
1746
|
-
require_autoTrace.warnOnce("http-client-closed", "the Bitfab client is closed; dropping spans");
|
|
1747
|
-
return;
|
|
1748
|
-
}
|
|
1749
|
-
if (!this.traceTransport) this.traceTransport = createTraceTransport({
|
|
1750
|
-
directSender: (request, timeoutMs) => this.deliverCarriers(request, timeoutMs),
|
|
1751
|
-
onDelivered: (refs) => this.recordDeliveredCarriers(refs)
|
|
1752
|
-
});
|
|
1753
|
-
return this.traceTransport;
|
|
1754
|
-
}
|
|
1755
|
-
async deliverCarriers(request, timeoutMs) {
|
|
1756
|
-
let response;
|
|
1757
|
-
try {
|
|
1758
|
-
response = await this.sendPrepared(OTLP_TRACES_ENDPOINT, request, { timeout: timeoutMs });
|
|
1759
|
-
} catch (error) {
|
|
1760
|
-
const status = error instanceof BitfabError ? error.status : void 0;
|
|
1761
|
-
if (status === void 0) throw new DeliveryError(`OTLP ingestion failed: ${String(error)}`, { retryable: true });
|
|
1762
|
-
throw new DeliveryError(`OTLP ingestion failed with HTTP ${status}`, {
|
|
1763
|
-
retryable: RETRYABLE_STATUSES.has(status),
|
|
1764
|
-
oversized: status === 413,
|
|
1765
|
-
...error instanceof BitfabError && error.retryAfterMs !== void 0 ? { retryAfterMs: error.retryAfterMs } : {}
|
|
1766
|
-
});
|
|
1767
|
-
}
|
|
1768
|
-
const serverTraceIds = asPayloadRecord(response?.traceIds);
|
|
1769
|
-
if (serverTraceIds !== void 0) this.recordServerTraceIds(serverTraceIds);
|
|
1770
|
-
const partialSuccess = asPayloadRecord(response?.partialSuccess);
|
|
1771
|
-
const rejected = partialSuccess?.rejectedSpans;
|
|
1772
|
-
if (rejected !== void 0 && rejected !== "0" && rejected !== 0) throw new DeliveryError(`OTLP ingestion rejected ${rejected} span(s): ${partialSuccess?.errorMessage ?? "no reason provided"}`);
|
|
1773
|
-
}
|
|
1774
|
-
trackTraceDeliveries(traceIds) {
|
|
1775
|
-
for (const traceId of traceIds) if (!this.traceDeliveries.has(traceId)) this.traceDeliveries.set(traceId, {
|
|
1776
|
-
submittedSpanIds: /* @__PURE__ */ new Set(),
|
|
1777
|
-
ackedSpanIds: /* @__PURE__ */ new Set(),
|
|
1778
|
-
closed: false,
|
|
1779
|
-
closingAcked: false
|
|
1780
|
-
});
|
|
1781
|
-
}
|
|
1782
|
-
peekServerTraceId(traceId) {
|
|
1783
|
-
return this.traceDeliveries.get(traceId)?.serverTraceId;
|
|
1784
|
-
}
|
|
1785
|
-
hasClosedDeliveries(traceIds) {
|
|
1786
|
-
return traceIds.some((traceId) => this.traceDeliveries.get(traceId)?.closed);
|
|
1787
|
-
}
|
|
1788
|
-
takeTraceDeliveries(traceIds) {
|
|
1789
|
-
const reports = {};
|
|
1790
|
-
for (const traceId of traceIds) {
|
|
1791
|
-
const delivery = this.traceDeliveries.get(traceId);
|
|
1792
|
-
if (delivery === void 0) continue;
|
|
1793
|
-
this.traceDeliveries.delete(traceId);
|
|
1794
|
-
reports[traceId] = {
|
|
1795
|
-
spanCount: delivery.submittedSpanIds.size,
|
|
1796
|
-
closed: delivery.closed,
|
|
1797
|
-
delivered: delivery.closingAcked && [...delivery.submittedSpanIds].every((spanId) => delivery.ackedSpanIds.has(spanId)),
|
|
1798
|
-
serverTraceId: delivery.serverTraceId
|
|
1799
|
-
};
|
|
1800
|
-
}
|
|
1801
|
-
return reports;
|
|
1802
|
-
}
|
|
1803
|
-
recordedMeta(operation, payload, ref) {
|
|
1804
|
-
this.recordSubmittedCarrier(ref);
|
|
1805
|
-
return carrierMeta(operation, payload, ref);
|
|
1806
|
-
}
|
|
1807
|
-
recordSubmittedCarrier(ref) {
|
|
1808
|
-
if (ref === void 0) return;
|
|
1809
|
-
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
1810
|
-
if (delivery === void 0) return;
|
|
1811
|
-
if (ref.spanId === void 0) delivery.closed = true;
|
|
1812
|
-
else delivery.submittedSpanIds.add(ref.spanId);
|
|
1813
|
-
}
|
|
1814
|
-
recordServerTraceIds(map) {
|
|
1815
|
-
for (const [sourceTraceId, serverTraceId] of Object.entries(map)) {
|
|
1816
|
-
if (typeof serverTraceId !== "string") continue;
|
|
1817
|
-
const delivery = this.traceDeliveries.get(sourceTraceId);
|
|
1818
|
-
if (delivery === void 0) continue;
|
|
1819
|
-
delivery.serverTraceId = serverTraceId;
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
recordDeliveredCarriers(refs) {
|
|
1823
|
-
for (const ref of refs) {
|
|
1824
|
-
const delivery = this.traceDeliveries.get(ref.traceId);
|
|
1825
|
-
if (delivery === void 0) continue;
|
|
1826
|
-
if (ref.spanId === void 0) delivery.closingAcked = true;
|
|
1827
|
-
else delivery.ackedSpanIds.add(ref.spanId);
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
trackDeferred(promise) {
|
|
1831
|
-
this.deferredWork.add(promise);
|
|
1832
|
-
promise.finally(() => this.deferredWork.delete(promise)).catch(() => {});
|
|
1833
|
-
return awaitOnExit(promise);
|
|
1834
|
-
}
|
|
1835
|
-
async settleDeferredWork(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS) {
|
|
1836
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1837
|
-
const released = await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
|
|
1838
|
-
await replayContextReady.catch(() => {});
|
|
1839
|
-
const settled = await waitForPromises(Array.from(this.deferredWork), Math.max(0, deadline - Date.now()));
|
|
1840
|
-
const releasedAfterDeferred = await this.releaseHeldExternalSpans?.(0);
|
|
1841
|
-
return released !== false && releasedAfterDeferred !== false && settled;
|
|
1842
|
-
}
|
|
1843
|
-
async waitForPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS) {
|
|
1844
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1845
|
-
const settled = await this.settleDeferredWork(Math.max(0, deadline - Date.now()));
|
|
1846
|
-
const flushed = await this.traceTransport?.flush(Math.max(0, deadline - Date.now())) ?? true;
|
|
1847
|
-
return settled && flushed;
|
|
1848
|
-
}
|
|
1849
|
-
close(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS) {
|
|
1850
|
-
if (this.closing) return this.closing;
|
|
1851
|
-
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1852
|
-
this.closing = (async () => {
|
|
1853
|
-
liveHttpClients.delete(this);
|
|
1854
|
-
const settled = await this.settleDeferredWork(Math.max(0, deadline - Date.now()));
|
|
1855
|
-
this.stopSimulationPlan?.();
|
|
1856
|
-
this.closed = true;
|
|
1857
|
-
this.externalSpanTransform = void 0;
|
|
1858
|
-
this.externalTraceTransform = void 0;
|
|
1859
|
-
this.releaseHeldExternalSpans = void 0;
|
|
1860
|
-
this.stopSimulationPlan = void 0;
|
|
1861
|
-
const transport = this.traceTransport;
|
|
1862
|
-
this.traceTransport = void 0;
|
|
1863
|
-
const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
|
|
1864
|
-
return settled && shutdownOk;
|
|
1865
|
-
})();
|
|
1866
|
-
return this.closing;
|
|
1867
|
-
}
|
|
1868
|
-
async request(endpoint, payload, options) {
|
|
1869
|
-
const { body, dropped } = serializePayloadBody(payload);
|
|
1870
|
-
if (dropped.length > 0) try {
|
|
1871
|
-
console.warn(`Bitfab: request body to ${endpoint} held ${dropped.length} non-serializable value(s) (${[...new Set(dropped)].join(", ")}); they were stubbed so the span still sends, but the trace may be incomplete or not replayable. Capture a JSON-safe projection of this input to make it replayable.`);
|
|
1872
|
-
} catch {}
|
|
1873
|
-
return this.sendEncoded(endpoint, body, options);
|
|
1874
|
-
}
|
|
1875
|
-
async sendEncoded(endpoint, body, options) {
|
|
1876
|
-
const prepared = encodeRequestBody(body);
|
|
1877
|
-
const encoded = prepared instanceof Promise ? await prepared : prepared;
|
|
1878
|
-
return this.sendPrepared(endpoint, encoded, options);
|
|
1879
|
-
}
|
|
1880
|
-
async sendPrepared(endpoint, encoded, options) {
|
|
1881
|
-
const url = `${this.serviceUrl}${endpoint}`;
|
|
1882
|
-
const timeout = options?.timeout ?? this.timeout;
|
|
1883
|
-
const method = options?.method ?? "POST";
|
|
1884
|
-
const controller = new AbortController();
|
|
1885
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1886
|
-
const headers = {
|
|
1887
|
-
"Content-Type": "application/json",
|
|
1888
|
-
Authorization: `Bearer ${this.resolveApiKey() ?? ""}`
|
|
1889
|
-
};
|
|
1890
|
-
if (encoded.contentEncoding) headers["Content-Encoding"] = encoded.contentEncoding;
|
|
1891
|
-
try {
|
|
1892
|
-
const response = await fetch(url, {
|
|
1893
|
-
method,
|
|
1894
|
-
headers,
|
|
1895
|
-
body: encoded.body,
|
|
1896
|
-
signal: controller.signal
|
|
1897
|
-
});
|
|
1898
|
-
if (!response.ok) {
|
|
1899
|
-
const errorText = await response.text();
|
|
1900
|
-
throw new BitfabError(`HTTP ${response.status}: ${errorText.slice(0, 500)}`, void 0, response.status, parseRetryAfterMs(readHeader(response, "retry-after")));
|
|
1901
|
-
}
|
|
1902
|
-
const result = await response.json();
|
|
1903
|
-
if (result.error) {
|
|
1904
|
-
if (result.url) throw new BitfabError(`${result.error} Configure it at: ${this.serviceUrl}${result.url}`, result.url);
|
|
1905
|
-
throw new BitfabError(result.error);
|
|
1906
|
-
}
|
|
1907
|
-
return result;
|
|
1908
|
-
} catch (error) {
|
|
1909
|
-
if (error instanceof BitfabError) throw error;
|
|
1910
|
-
if (error instanceof Error) {
|
|
1911
|
-
if (error.name === "AbortError") throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
1912
|
-
throw new BitfabError(error.message);
|
|
1913
|
-
}
|
|
1914
|
-
throw new BitfabError("Unknown error occurred");
|
|
1915
|
-
} finally {
|
|
1916
|
-
clearTimeout(timeoutId);
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
async lookupFunction(name) {
|
|
1920
|
-
return this.request("/api/sdk/functions/lookup", { name });
|
|
1921
|
-
}
|
|
1922
|
-
async getSimulationPlan() {
|
|
1923
|
-
if (!this.hasApiKey()) throw new BitfabError(NO_API_KEY_FOR_SIMULATION_PLAN);
|
|
1924
|
-
return this.get("/api/sdk/sim-plan", SIMULATION_PLAN_READ_TIMEOUT_MS);
|
|
1925
|
-
}
|
|
1926
|
-
async getTraceSpan(traceId, lookup) {
|
|
1927
|
-
const searchParams = new URLSearchParams();
|
|
1928
|
-
if (lookup.id !== void 0) searchParams.set("id", lookup.id);
|
|
1929
|
-
else {
|
|
1930
|
-
if (lookup.name !== void 0) searchParams.set("name", lookup.name);
|
|
1931
|
-
if (lookup.type !== void 0) searchParams.set("type", lookup.type);
|
|
1932
|
-
searchParams.set("occurrence", String(lookup.occurrence ?? "last"));
|
|
1933
|
-
}
|
|
1934
|
-
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}/span?${searchParams.toString()}`;
|
|
1935
|
-
return (await this.get(endpoint)).span;
|
|
1936
|
-
}
|
|
1937
|
-
async getSpan(spanId) {
|
|
1938
|
-
return (await this.get(`/api/sdk/spans/${encodeURIComponent(spanId)}`)).span;
|
|
1939
|
-
}
|
|
1940
|
-
async get(endpoint, timeoutMs, extraHeaders) {
|
|
1941
|
-
const url = `${this.serviceUrl}${endpoint}`;
|
|
1942
|
-
const timeout = timeoutMs ?? this.timeout;
|
|
1943
|
-
const controller = new AbortController();
|
|
1944
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1945
|
-
try {
|
|
1946
|
-
const response = await fetch(url, {
|
|
1947
|
-
method: "GET",
|
|
1948
|
-
headers: {
|
|
1949
|
-
Authorization: `Bearer ${this.resolveApiKey() ?? ""}`,
|
|
1950
|
-
...extraHeaders
|
|
1951
|
-
},
|
|
1952
|
-
signal: controller.signal
|
|
1953
|
-
});
|
|
1954
|
-
if (!response.ok) {
|
|
1955
|
-
const errorText = await response.text();
|
|
1956
|
-
throw new BitfabError(`HTTP ${response.status}: ${errorText.slice(0, 500)}`, void 0, response.status, parseRetryAfterMs(readHeader(response, "retry-after")));
|
|
1957
|
-
}
|
|
1958
|
-
return await response.json();
|
|
1959
|
-
} catch (error) {
|
|
1960
|
-
if (error instanceof BitfabError) throw error;
|
|
1961
|
-
if (error instanceof Error) {
|
|
1962
|
-
if (error.name === "AbortError") throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
1963
|
-
throw new BitfabError(error.message);
|
|
1964
|
-
}
|
|
1965
|
-
throw new BitfabError("Unknown error occurred");
|
|
1966
|
-
} finally {
|
|
1967
|
-
clearTimeout(timeoutId);
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
|
-
sendInternalTrace(functionId, payload) {
|
|
1971
|
-
const body = {
|
|
1972
|
-
...payload,
|
|
1973
|
-
functionId,
|
|
1974
|
-
sdkPackage: __packageName__,
|
|
1975
|
-
sdkVersion: __version__
|
|
1976
|
-
};
|
|
1977
|
-
this.getTraceTransport()?.submit("internal_trace", body, carrierMeta("internal_trace", body, void 0));
|
|
1978
|
-
}
|
|
1979
|
-
sendExternalSpan(payload) {
|
|
1980
|
-
const ref = carrierRef(payload);
|
|
1981
|
-
if (ref?.spanId !== void 0) this.traceCompletion.record(ref.traceId, ref.spanId);
|
|
1982
|
-
const drop = () => {
|
|
1983
|
-
if (ref?.spanId !== void 0) this.traceCompletion.abort(ref.traceId, ref.spanId);
|
|
1984
|
-
};
|
|
1985
|
-
const gate = this.externalSpanTransform;
|
|
1986
|
-
if (gate === void 0) {
|
|
1987
|
-
this.submitExternalSpan(payload);
|
|
1988
|
-
return;
|
|
1989
|
-
}
|
|
1990
|
-
try {
|
|
1991
|
-
gate(payload, (ready) => this.submitExternalSpan(ready), drop);
|
|
1992
|
-
} catch (error) {
|
|
1993
|
-
drop();
|
|
1994
|
-
warnDroppedExternalSpan(error);
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
submitExternalSpan(payload) {
|
|
1998
|
-
const body = {
|
|
1999
|
-
...payload,
|
|
2000
|
-
sdkVersion: __version__
|
|
2001
|
-
};
|
|
2002
|
-
delete body[ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
2003
|
-
delete body[DECLARED_NODE_FIELD];
|
|
2004
|
-
this.getTraceTransport()?.submit("external_span", body, this.recordedMeta("external_span", payload, carrierRef(payload)));
|
|
2005
|
-
}
|
|
2006
|
-
sendExternalTrace(rawPayload) {
|
|
2007
|
-
const payload = mergeCallerMetadataIntoTracePayload(rawPayload);
|
|
2008
|
-
const traceId = sourceTraceIdOf(payload);
|
|
2009
|
-
if (payload.completed === true && traceId !== void 0) {
|
|
2010
|
-
this.traceCompletion.close(traceId, (expectedSpanCount) => this.sendCountedExternalTrace({
|
|
2011
|
-
...payload,
|
|
2012
|
-
expectedSpanCount
|
|
2013
|
-
}), payload.dropped === true);
|
|
2014
|
-
return;
|
|
2015
|
-
}
|
|
2016
|
-
if (traceId !== void 0) this.traceCompletion.open(traceId);
|
|
2017
|
-
this.sendCountedExternalTrace(payload);
|
|
2018
|
-
}
|
|
2019
|
-
sendCountedExternalTrace(payload) {
|
|
2020
|
-
try {
|
|
2021
|
-
const gate = this.externalTraceTransform;
|
|
2022
|
-
if (gate === void 0) this.submitExternalTrace(payload);
|
|
2023
|
-
else gate(payload, (ready) => this.submitExternalTrace(ready));
|
|
2024
|
-
} catch (error) {
|
|
2025
|
-
warnDroppedExternalTrace(error);
|
|
2026
|
-
}
|
|
2027
|
-
}
|
|
2028
|
-
submitExternalTrace(payload) {
|
|
2029
|
-
this.getTraceTransport()?.submit("external_trace", {
|
|
2030
|
-
...payload,
|
|
2031
|
-
sdkPackage: __packageName__,
|
|
2032
|
-
sdkVersion: __version__
|
|
2033
|
-
}, this.recordedMeta("external_trace", payload, payload.completed === true ? carrierRef(payload) : void 0));
|
|
2034
|
-
}
|
|
2035
|
-
async patchTrace(traceId, payload) {
|
|
2036
|
-
const endpoint = `/api/sdk/traces/${encodeURIComponent(traceId)}`;
|
|
2037
|
-
await this.request(endpoint, payload, { method: "PATCH" });
|
|
2038
|
-
}
|
|
2039
|
-
async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetIds, graderIds, dbBranchSettings, attempts, includeOriginalMetadata, onlyWithAssertions, skipAssertionJudging, experimentalSelectiveReplay, notes, metadata, dryRun, experimentGroupName, invocation) {
|
|
2040
|
-
const payload = { traceFunctionKey };
|
|
2041
|
-
if (experimentalSelectiveReplay !== void 0) payload.experimentalSelectiveReplay = experimentalSelectiveReplay;
|
|
2042
|
-
if (limit !== void 0) payload.limit = limit;
|
|
2043
|
-
if (traceIds) payload.traceIds = traceIds;
|
|
2044
|
-
if (name !== void 0) payload.name = name;
|
|
2045
|
-
if (notes !== void 0) payload.notes = notes;
|
|
2046
|
-
if (metadata !== void 0) payload.metadata = metadata;
|
|
2047
|
-
if (codeChangeDescription !== void 0) payload.codeChangeDescription = codeChangeDescription;
|
|
2048
|
-
if (codeChangeFiles !== void 0) payload.codeChangeFiles = codeChangeFiles;
|
|
2049
|
-
if (includeDbBranchLease) {
|
|
2050
|
-
payload.includeDbBranchLease = true;
|
|
2051
|
-
payload.lazyDbBranchLease = true;
|
|
2052
|
-
}
|
|
2053
|
-
if (experimentGroupId !== void 0) payload.experimentGroupId = experimentGroupId;
|
|
2054
|
-
if (experimentGroupName !== void 0) payload.experimentGroupName = experimentGroupName;
|
|
2055
|
-
if (datasetIds !== void 0) {
|
|
2056
|
-
if (datasetIds.length === 1) payload.datasetId = datasetIds[0];
|
|
2057
|
-
else payload.datasetIds = datasetIds;
|
|
2058
|
-
}
|
|
2059
|
-
if (graderIds !== void 0) payload.graderIds = graderIds;
|
|
2060
|
-
if (dbBranchSettings !== void 0) payload.dbBranchSettings = dbBranchSettings;
|
|
2061
|
-
if (attempts !== void 0 && attempts > 1) payload.attempts = attempts;
|
|
2062
|
-
if (includeOriginalMetadata) payload.includeOriginalMetadata = true;
|
|
2063
|
-
if (onlyWithAssertions) payload.onlyWithAssertions = true;
|
|
2064
|
-
if (skipAssertionJudging !== true) payload.judgeAssertions = true;
|
|
2065
|
-
if (dryRun) payload.dryRun = true;
|
|
2066
|
-
if (invocation !== void 0) payload.invocation = invocation;
|
|
2067
|
-
const git = await resolvedGitState();
|
|
2068
|
-
if (git && !isEmptyGitState(git)) payload.git = git;
|
|
2069
|
-
const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
|
|
2070
|
-
const response = await this.request("/api/sdk/replay/start", payload, { timeout });
|
|
2071
|
-
const { testRunId, testRunUrl, ...rest } = response;
|
|
2072
|
-
const experimentId = response.experimentId ?? testRunId;
|
|
2073
|
-
const experimentUrl = response.experimentUrl ?? testRunUrl;
|
|
2074
|
-
if (dryRun && response.experimentId === null) return {
|
|
2075
|
-
...rest,
|
|
2076
|
-
experimentId: null,
|
|
2077
|
-
experimentUrl: null
|
|
2078
|
-
};
|
|
2079
|
-
if (experimentId === void 0 || experimentId === null || experimentUrl === void 0 || experimentUrl === null) throw new BitfabError("Replay start response is missing the experiment ID or URL.");
|
|
2080
|
-
return {
|
|
2081
|
-
...rest,
|
|
2082
|
-
experimentId,
|
|
2083
|
-
experimentUrl
|
|
2084
|
-
};
|
|
2085
|
-
}
|
|
2086
|
-
async resumeReplay(experimentId, traceFunctionKey, codeChangeFiles, force) {
|
|
2087
|
-
const payload = {
|
|
2088
|
-
experimentId,
|
|
2089
|
-
traceFunctionKey,
|
|
2090
|
-
lazyDbBranchLease: true
|
|
2091
|
-
};
|
|
2092
|
-
if (force === true) payload.force = true;
|
|
2093
|
-
if (codeChangeFiles !== void 0) payload.codeChangeFiles = codeChangeFiles;
|
|
2094
|
-
const git = await resolvedGitState();
|
|
2095
|
-
if (git && !isEmptyGitState(git)) payload.git = git;
|
|
2096
|
-
const response = await this.request("/api/sdk/replay/resume", payload, { timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS });
|
|
2097
|
-
const { testRunId, testRunUrl, ...rest } = response;
|
|
2098
|
-
const resumedExperimentId = response.experimentId ?? testRunId;
|
|
2099
|
-
const experimentUrl = response.experimentUrl ?? testRunUrl;
|
|
2100
|
-
if (resumedExperimentId === void 0 || experimentUrl === void 0) throw new BitfabError("Replay resume response is missing the experiment ID or URL.");
|
|
2101
|
-
return {
|
|
2102
|
-
...rest,
|
|
2103
|
-
experimentId: resumedExperimentId,
|
|
2104
|
-
experimentUrl,
|
|
2105
|
-
work: rest.work ?? [],
|
|
2106
|
-
finished: rest.finished ?? [],
|
|
2107
|
-
skippedOriginalTraceIds: rest.skippedOriginalTraceIds ?? [],
|
|
2108
|
-
includeDbBranchLease: rest.includeDbBranchLease ?? false,
|
|
2109
|
-
dbBranchSettings: rest.dbBranchSettings ?? null
|
|
2110
|
-
};
|
|
2111
|
-
}
|
|
2112
|
-
async getExternalSpan(spanId, options) {
|
|
2113
|
-
const query = options?.view === "replay" ? "?view=replay" : "";
|
|
2114
|
-
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}${query}`;
|
|
2115
|
-
const controller = new AbortController();
|
|
2116
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
2117
|
-
try {
|
|
2118
|
-
const response = await fetch(url, {
|
|
2119
|
-
method: "GET",
|
|
2120
|
-
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
2121
|
-
signal: controller.signal
|
|
2122
|
-
});
|
|
2123
|
-
if (!response.ok) {
|
|
2124
|
-
const errorText = await response.text();
|
|
2125
|
-
throw new BitfabError(`HTTP ${response.status}: ${errorText.slice(0, 500)}`);
|
|
2126
|
-
}
|
|
2127
|
-
return await response.json();
|
|
2128
|
-
} catch (error) {
|
|
2129
|
-
if (error instanceof BitfabError) throw error;
|
|
2130
|
-
if (error instanceof Error) {
|
|
2131
|
-
if (error.name === "AbortError") throw new BitfabError("Request timed out after 30000ms");
|
|
2132
|
-
throw new BitfabError(error.message);
|
|
2133
|
-
}
|
|
2134
|
-
throw new BitfabError("Unknown error occurred");
|
|
2135
|
-
} finally {
|
|
2136
|
-
clearTimeout(timeoutId);
|
|
2137
|
-
}
|
|
2138
|
-
}
|
|
2139
|
-
async getSpanTree(externalSpanId, options) {
|
|
2140
|
-
const searchParams = new URLSearchParams();
|
|
2141
|
-
if (options?.includeOutputs === false) searchParams.set("includeOutputs", "false");
|
|
2142
|
-
if (options?.includeRootOutput === false) searchParams.set("includeRootOutput", "false");
|
|
2143
|
-
const encodedQuery = searchParams.toString();
|
|
2144
|
-
const query = encodedQuery ? `?${encodedQuery}` : "";
|
|
2145
|
-
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}${query}`;
|
|
2146
|
-
const controller = new AbortController();
|
|
2147
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
2148
|
-
try {
|
|
2149
|
-
const response = await fetch(url, {
|
|
2150
|
-
method: "GET",
|
|
2151
|
-
headers: { Authorization: `Bearer ${this.resolveApiKey() ?? ""}` },
|
|
2152
|
-
signal: controller.signal
|
|
2153
|
-
});
|
|
2154
|
-
if (!response.ok) {
|
|
2155
|
-
const errorText = await response.text();
|
|
2156
|
-
throw new BitfabError(`HTTP ${response.status}: ${errorText.slice(0, 500)}`);
|
|
2157
|
-
}
|
|
2158
|
-
return await response.json();
|
|
2159
|
-
} catch (error) {
|
|
2160
|
-
if (error instanceof BitfabError) throw error;
|
|
2161
|
-
if (error instanceof Error) {
|
|
2162
|
-
if (error.name === "AbortError") throw new BitfabError("Request timed out after 30000ms");
|
|
2163
|
-
throw new BitfabError(error.message);
|
|
2164
|
-
}
|
|
2165
|
-
throw new BitfabError("Unknown error occurred");
|
|
2166
|
-
} finally {
|
|
2167
|
-
clearTimeout(timeoutId);
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
async getReplayStatus(experimentId, expectedSpanCounts) {
|
|
2171
|
-
return this.request("/api/sdk/replay/status", {
|
|
2172
|
-
...experimentIdWireFields(experimentId),
|
|
2173
|
-
expectedSpanCounts
|
|
2174
|
-
}, { timeout: 3e4 });
|
|
2175
|
-
}
|
|
2176
|
-
async completeReplay(experimentId) {
|
|
2177
|
-
return this.request("/api/sdk/replay/complete", experimentIdWireFields(experimentId), { timeout: REPLAY_COMPLETE_REQUEST_TIMEOUT_MS });
|
|
2178
|
-
}
|
|
2179
|
-
async interruptReplay(experimentId) {
|
|
2180
|
-
try {
|
|
2181
|
-
await this.request("/api/sdk/replay/interrupt", experimentIdWireFields(experimentId), { timeout: REPLAY_INTERRUPT_REQUEST_TIMEOUT_MS });
|
|
2182
|
-
return true;
|
|
2183
|
-
} catch {
|
|
2184
|
-
return false;
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
async heartbeatReplay(experimentId) {
|
|
2188
|
-
try {
|
|
2189
|
-
await this.request("/api/sdk/replay/heartbeat", experimentIdWireFields(experimentId), { timeout: REPLAY_HEARTBEAT_REQUEST_TIMEOUT_MS });
|
|
2190
|
-
} catch {}
|
|
2191
|
-
}
|
|
2192
|
-
async getReseedSource(traceId) {
|
|
2193
|
-
return this.get(`/api/sdk/traces/${encodeURIComponent(traceId)}/reseedSource`);
|
|
2194
|
-
}
|
|
2195
|
-
async reseedTrace(traceId, runTraceId) {
|
|
2196
|
-
return this.request(`/api/sdk/traces/${encodeURIComponent(traceId)}/reseed`, { runTraceId }, { timeout: 3e4 });
|
|
2197
|
-
}
|
|
2198
|
-
async resolveDbBranchLease(experimentId, traceId, dbBranchSettings, attempt) {
|
|
2199
|
-
return this.request("/api/sdk/replay/resolveDbBranchLease", {
|
|
2200
|
-
...experimentIdWireFields(experimentId),
|
|
2201
|
-
traceId,
|
|
2202
|
-
dbBranchSettings,
|
|
2203
|
-
...attempt !== void 0 && attempt > 0 ? { attempt } : {}
|
|
2204
|
-
}, { timeout: REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS });
|
|
2205
|
-
}
|
|
2206
|
-
async releaseDbBranchLease(neonBranchId) {
|
|
2207
|
-
await this.request("/api/sdk/replay/releaseDbBranchLease", { neonBranchId }, { timeout: 3e4 });
|
|
2208
|
-
}
|
|
2209
|
-
};
|
|
2210
|
-
function experimentIdWireFields(experimentId) {
|
|
2211
|
-
return {
|
|
2212
|
-
experimentId,
|
|
2213
|
-
testRunId: experimentId
|
|
2214
|
-
};
|
|
2215
|
-
}
|
|
27
|
+
//#region src/constants.ts
|
|
28
|
+
const DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
2216
29
|
//#endregion
|
|
2217
30
|
//#region src/serialize.ts
|
|
2218
|
-
const MAX_SERIALIZED_BYTES = MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES;
|
|
2219
|
-
const MAX_FRAMEWORK_SERIALIZED_BYTES = MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES;
|
|
31
|
+
const MAX_SERIALIZED_BYTES = require_http.MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES;
|
|
32
|
+
const MAX_FRAMEWORK_SERIALIZED_BYTES = require_http.MAX_COMPRESSIBLE_SPAN_CARRIER_BYTES;
|
|
2220
33
|
function describeValue(value) {
|
|
2221
34
|
try {
|
|
2222
35
|
const ctorName = value?.constructor?.name;
|
|
@@ -2450,7 +263,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
2450
263
|
this.activeSubagentSpans = /* @__PURE__ */ new Map();
|
|
2451
264
|
this.hasRootInput = false;
|
|
2452
265
|
this.ownsHttpClient = config._httpClient === void 0;
|
|
2453
|
-
this.httpClient = config._httpClient ?? new HttpClient({
|
|
266
|
+
this.httpClient = config._httpClient ?? new require_http.HttpClient({
|
|
2454
267
|
apiKey: config.apiKey,
|
|
2455
268
|
serviceUrl: config.serviceUrl ?? "https://bitfab.ai",
|
|
2456
269
|
timeout: config.timeout ?? 1e4
|
|
@@ -2543,7 +356,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
2543
356
|
trace_id: spanInfo.traceId,
|
|
2544
357
|
started_at: spanInfo.startedAt,
|
|
2545
358
|
ended_at: spanInfo.endedAt ?? nowIso$1(),
|
|
2546
|
-
span_origin: makeSpanOrigin("claude-agent-sdk"),
|
|
359
|
+
span_origin: require_http.makeSpanOrigin("claude-agent-sdk"),
|
|
2547
360
|
span_data: spanData
|
|
2548
361
|
};
|
|
2549
362
|
if (spanInfo.parentId !== null) rawSpan.parent_id = spanInfo.parentId;
|
|
@@ -2805,25 +618,11 @@ var BitfabClaudeAgentHandler = class {
|
|
|
2805
618
|
}
|
|
2806
619
|
};
|
|
2807
620
|
//#endregion
|
|
2808
|
-
//#region src/optionalPeer.ts
|
|
2809
|
-
function importOptionalPeer(specifierParts) {
|
|
2810
|
-
return import(
|
|
2811
|
-
/* webpackIgnore: true */
|
|
2812
|
-
/* @vite-ignore */
|
|
2813
|
-
specifierParts.join("/")
|
|
2814
|
-
);
|
|
2815
|
-
}
|
|
2816
|
-
//#endregion
|
|
2817
621
|
//#region src/baml.ts
|
|
2818
|
-
let cachedBaml = null;
|
|
2819
622
|
async function loadBaml() {
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
return cachedBaml;
|
|
2824
|
-
} catch {
|
|
2825
|
-
throw new Error("@boundaryml/baml is required for Bitfab.call(). Install it with: npm install @boundaryml/baml");
|
|
2826
|
-
}
|
|
623
|
+
const baml = await require_bamlPeer.loadBamlModule();
|
|
624
|
+
if (!baml) throw new Error("@boundaryml/baml is required for Bitfab.call(). Install it with: npm install @boundaryml/baml. If it is installed and your app is bundled (Next.js with Turbopack, for example), add `import \"@bitfab/sdk/baml\"` once in your server code.");
|
|
625
|
+
return baml;
|
|
2827
626
|
}
|
|
2828
627
|
function capitalize(str) {
|
|
2829
628
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
@@ -3021,10 +820,10 @@ async function runFunctionWithBaml(bamlSource, inputs, providers, envVars) {
|
|
|
3021
820
|
//#region src/bitfabIds.ts
|
|
3022
821
|
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
3023
822
|
function validateTraceId(traceId) {
|
|
3024
|
-
if (typeof traceId !== "string" || !UUID_PATTERN.test(traceId)) throw new BitfabError("traceId must be a valid Bitfab trace ID");
|
|
823
|
+
if (typeof traceId !== "string" || !UUID_PATTERN.test(traceId)) throw new require_http.BitfabError("traceId must be a valid Bitfab trace ID");
|
|
3025
824
|
}
|
|
3026
825
|
function validateSpanId(id) {
|
|
3027
|
-
if (typeof id !== "string" || !UUID_PATTERN.test(id)) throw new BitfabError("id must be a valid Bitfab span ID");
|
|
826
|
+
if (typeof id !== "string" || !UUID_PATTERN.test(id)) throw new require_http.BitfabError("id must be a valid Bitfab span ID");
|
|
3028
827
|
}
|
|
3029
828
|
const SURFACE_API = {
|
|
3030
829
|
"opt-in": "withSpan()",
|
|
@@ -3040,7 +839,8 @@ function resolveSurface(requested, parentSurface) {
|
|
|
3040
839
|
return requested;
|
|
3041
840
|
}
|
|
3042
841
|
function mixedTracingError(enteredApi, entered, enclosing, traceFunctionKey) {
|
|
3043
|
-
|
|
842
|
+
const subject = traceFunctionKey === void 0 ? "" : ` for "${traceFunctionKey}"`;
|
|
843
|
+
return new require_http.MixedTracingError(`opt-in and opt-out tracing can't be mixed in one call stack: ${enteredApi} (${entered})${subject} was entered inside a ${SURFACE_API[enclosing]} call (${enclosing}). ${MIXED_SURFACE_REMEDY[entered]}`);
|
|
3044
844
|
}
|
|
3045
845
|
function assertSurfacesCompatible(requested, resolved, parentSurface, traceFunctionKey) {
|
|
3046
846
|
if (requested === "inherit" || requested === "neutral") return;
|
|
@@ -3178,7 +978,7 @@ function resolveCommitRefFromEnv(env) {
|
|
|
3178
978
|
};
|
|
3179
979
|
}
|
|
3180
980
|
async function resolveCommitRefFromGit(cwd) {
|
|
3181
|
-
const git = await gitRunner({
|
|
981
|
+
const git = await require_http.gitRunner({
|
|
3182
982
|
timeoutMs: GIT_TIMEOUT_MS,
|
|
3183
983
|
maxBuffer: GIT_MAX_BUFFER,
|
|
3184
984
|
keepProcessAlive: false
|
|
@@ -3229,11 +1029,11 @@ let gitStarted = false;
|
|
|
3229
1029
|
Promise.resolve();
|
|
3230
1030
|
function startCommitRefResolution() {
|
|
3231
1031
|
if (resolved || gitStarted) return;
|
|
3232
|
-
if (read(readEnv
|
|
1032
|
+
if (read(require_http.readEnv, DISABLE_ENV) !== null) {
|
|
3233
1033
|
resolved = true;
|
|
3234
1034
|
return;
|
|
3235
1035
|
}
|
|
3236
|
-
const fromEnv = resolveCommitRefFromEnv(readEnv
|
|
1036
|
+
const fromEnv = resolveCommitRefFromEnv(require_http.readEnv);
|
|
3237
1037
|
if (fromEnv) {
|
|
3238
1038
|
ref = fromEnv;
|
|
3239
1039
|
resolved = true;
|
|
@@ -3321,7 +1121,7 @@ var DatasetsClient = class {
|
|
|
3321
1121
|
}));
|
|
3322
1122
|
}
|
|
3323
1123
|
async update(datasetId, params) {
|
|
3324
|
-
if (params.name === void 0 && params.description === void 0 && params.golden === void 0) throw new BitfabError("Provide name, description, and/or golden to update.");
|
|
1124
|
+
if (params.name === void 0 && params.description === void 0 && params.golden === void 0) throw new require_http.BitfabError("Provide name, description, and/or golden to update.");
|
|
3325
1125
|
return normalizeDataset((await this.httpClient.request(datasetPath(datasetId), {
|
|
3326
1126
|
...params.name === void 0 ? {} : { name: params.name },
|
|
3327
1127
|
...params.description === void 0 ? {} : { description: params.description },
|
|
@@ -3391,7 +1191,7 @@ var DatasetsClient = class {
|
|
|
3391
1191
|
//#region src/dbSnapshot.ts
|
|
3392
1192
|
const SUPPORTED_PROVIDERS = ["neon"];
|
|
3393
1193
|
function validateDbSnapshotConfig(config) {
|
|
3394
|
-
if (!SUPPORTED_PROVIDERS.includes(config.provider)) throw new BitfabError(`dbSnapshot.provider "${config.provider}" is not supported. Supported providers: ${SUPPORTED_PROVIDERS.join(", ")}.`);
|
|
1194
|
+
if (!SUPPORTED_PROVIDERS.includes(config.provider)) throw new require_http.BitfabError(`dbSnapshot.provider "${config.provider}" is not supported. Supported providers: ${SUPPORTED_PROVIDERS.join(", ")}.`);
|
|
3395
1195
|
}
|
|
3396
1196
|
function buildSnapshotRef(config, sdkWallClockBeforeFn) {
|
|
3397
1197
|
return {
|
|
@@ -3449,7 +1249,7 @@ var GradersClient = class {
|
|
|
3449
1249
|
async getLabels(params) {
|
|
3450
1250
|
const hasTraceIds = params.traceIds !== void 0 && params.traceIds.length > 0;
|
|
3451
1251
|
const hasGraderId = params.graderId !== void 0;
|
|
3452
|
-
if (!hasTraceIds && !hasGraderId) throw new BitfabError("Pass traceIds, graderId, or both: there is nothing to read otherwise.");
|
|
1252
|
+
if (!hasTraceIds && !hasGraderId) throw new require_http.BitfabError("Pass traceIds, graderId, or both: there is nothing to read otherwise.");
|
|
3453
1253
|
const query = new URLSearchParams();
|
|
3454
1254
|
if (params.traceIds !== void 0 && params.traceIds.length > 0) query.set("traceIds", params.traceIds.join(","));
|
|
3455
1255
|
if (params.graderId !== void 0) query.set("graderId", params.graderId);
|
|
@@ -3470,11 +1270,17 @@ const LABELS_PATH = "/api/sdk/traces/labels";
|
|
|
3470
1270
|
const HUMAN_LABELS_PATH = "/api/sdk/traces/labels/human";
|
|
3471
1271
|
function assertEveryVerdictNamesAnAssertion(updates) {
|
|
3472
1272
|
const unscoped = updates.filter((update) => !("archive" in update && update.archive === true) && (typeof update.assertionId !== "string" || update.assertionId === ""));
|
|
3473
|
-
if (unscoped.length > 0)
|
|
1273
|
+
if (unscoped.length > 0) {
|
|
1274
|
+
const targets = unscoped.map((update) => update.traceId ?? update.originalTraceId);
|
|
1275
|
+
throw new require_http.BitfabError(`Agent verdicts must name an assertion: ${targets.join(", ")}. Pass the assertionId of the assertion each verdict scores to labels.save, saveAll, skip, and abstain. Only archive may omit it, to clear an old whole-trace verdict.`);
|
|
1276
|
+
}
|
|
3474
1277
|
}
|
|
3475
1278
|
function assertEveryHumanVerdictNamesAnAssertion(updates) {
|
|
3476
1279
|
const unscoped = updates.filter((update) => typeof update.assertionId !== "string" || update.assertionId === "");
|
|
3477
|
-
if (unscoped.length > 0)
|
|
1280
|
+
if (unscoped.length > 0) {
|
|
1281
|
+
const targets = unscoped.map((update) => update.traceId);
|
|
1282
|
+
throw new require_http.BitfabError(`Human verdicts must name an assertion: ${targets.join(", ")}. Pass the assertionId of the assertion each verdict scores to labels.saveHuman and saveHumanAll.`);
|
|
1283
|
+
}
|
|
3478
1284
|
}
|
|
3479
1285
|
function labelEvidencePath(traceId, assertionId) {
|
|
3480
1286
|
return `/api/sdk/traces/${encodeURIComponent(traceId)}/assertions/${encodeURIComponent(assertionId)}/evidence`;
|
|
@@ -3491,7 +1297,7 @@ var LabelsClient = class {
|
|
|
3491
1297
|
assertEveryVerdictNamesAnAssertion(updates);
|
|
3492
1298
|
return (await this.httpClient.request(LABELS_PATH, {
|
|
3493
1299
|
labels: updates,
|
|
3494
|
-
...experimentId === void 0 ? {} : experimentIdWireFields(experimentId)
|
|
1300
|
+
...experimentId === void 0 ? {} : require_http.experimentIdWireFields(experimentId)
|
|
3495
1301
|
})).labels;
|
|
3496
1302
|
}
|
|
3497
1303
|
async skip(target, experimentId) {
|
|
@@ -3711,7 +1517,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
3711
1517
|
this.runToSpan = /* @__PURE__ */ new Map();
|
|
3712
1518
|
this.invocations = /* @__PURE__ */ new Map();
|
|
3713
1519
|
this.ownsHttpClient = config._httpClient === void 0;
|
|
3714
|
-
this.httpClient = config._httpClient ?? new HttpClient({
|
|
1520
|
+
this.httpClient = config._httpClient ?? new require_http.HttpClient({
|
|
3715
1521
|
apiKey: config.apiKey,
|
|
3716
1522
|
serviceUrl: config.serviceUrl ?? "https://bitfab.ai",
|
|
3717
1523
|
timeout: config.timeout ?? 1e4
|
|
@@ -3812,7 +1618,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
3812
1618
|
trace_id: spanInfo.traceId,
|
|
3813
1619
|
started_at: spanInfo.startedAt,
|
|
3814
1620
|
ended_at: spanInfo.endedAt ?? nowIso(),
|
|
3815
|
-
span_origin: makeSpanOrigin("langgraph"),
|
|
1621
|
+
span_origin: require_http.makeSpanOrigin("langgraph"),
|
|
3816
1622
|
span_data: spanData
|
|
3817
1623
|
};
|
|
3818
1624
|
if (spanInfo.parentId !== null) rawSpan.parent_id = spanInfo.parentId;
|
|
@@ -4014,20 +1820,20 @@ function isEncodedToolResult(value) {
|
|
|
4014
1820
|
}
|
|
4015
1821
|
async function loadLangChainCore() {
|
|
4016
1822
|
try {
|
|
4017
|
-
return await importOptionalPeer([
|
|
1823
|
+
return await require_bamlPeer.importOptionalPeer([
|
|
4018
1824
|
"@langchain",
|
|
4019
1825
|
"core",
|
|
4020
1826
|
"messages"
|
|
4021
1827
|
]);
|
|
4022
1828
|
} catch {
|
|
4023
|
-
throw new BitfabError("LangGraph tool replay requires @langchain/core. Install @langchain/langgraph before using getLangGraphIntegration().", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
1829
|
+
throw new require_http.BitfabError("LangGraph tool replay requires @langchain/core. Install @langchain/langgraph before using getLangGraphIntegration().", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
4024
1830
|
}
|
|
4025
1831
|
}
|
|
4026
1832
|
async function loadLangGraph() {
|
|
4027
1833
|
try {
|
|
4028
|
-
return await importOptionalPeer(["@langchain", "langgraph"]);
|
|
1834
|
+
return await require_bamlPeer.importOptionalPeer(["@langchain", "langgraph"]);
|
|
4029
1835
|
} catch {
|
|
4030
|
-
throw new BitfabError("Replaying a LangGraph Command requires @langchain/langgraph.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
1836
|
+
throw new require_http.BitfabError("Replaying a LangGraph Command requires @langchain/langgraph.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
4031
1837
|
}
|
|
4032
1838
|
}
|
|
4033
1839
|
async function reviveNested(value, toolCallId) {
|
|
@@ -4080,7 +1886,7 @@ var BitfabLangGraphIntegration = class {
|
|
|
4080
1886
|
}
|
|
4081
1887
|
wrapTool(tool) {
|
|
4082
1888
|
const toolName = tool.name;
|
|
4083
|
-
if (typeof toolName !== "string" || toolName.length === 0) throw new BitfabError("LangGraph replayable tools must have a name.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
1889
|
+
if (typeof toolName !== "string" || toolName.length === 0) throw new require_http.BitfabError("LangGraph replayable tools must have a name.", "https://docs.bitfab.ai/frameworks/langgraph");
|
|
4084
1890
|
const mockToolsOnReplay = this.mockToolsOnReplay;
|
|
4085
1891
|
const shouldMock = typeof mockToolsOnReplay === "boolean" ? mockToolsOnReplay : mockToolsOnReplay.includes(toolName);
|
|
4086
1892
|
const originalInvoke = tool.invoke.bind(tool);
|
|
@@ -4105,7 +1911,7 @@ var BitfabLangGraphIntegration = class {
|
|
|
4105
1911
|
} });
|
|
4106
1912
|
}
|
|
4107
1913
|
assertReplayToolResultExists(toolName, shouldMock) {
|
|
4108
|
-
const replayContext = getReplayContext();
|
|
1914
|
+
const replayContext = require_http.getReplayContext();
|
|
4109
1915
|
if (!replayContext?.mockTree) return;
|
|
4110
1916
|
const counterKey = `${this.traceFunctionKey}:${toolName}`;
|
|
4111
1917
|
const callIndex = replayContext.callCounters?.get(counterKey) ?? 0;
|
|
@@ -4117,7 +1923,7 @@ var BitfabLangGraphIntegration = class {
|
|
|
4117
1923
|
originalSpanId: mockSpan?.sourceSpanId
|
|
4118
1924
|
}));
|
|
4119
1925
|
const expectsRecordedOutput = replayContext.mockStrategy === "all" || replayContext.mockStrategy === "marked" && shouldMock;
|
|
4120
|
-
if (hasMatchingOverride !== true && expectsRecordedOutput && !mockSpan) throw new BitfabError(`No recorded LangGraph tool result for "${toolName}" at call ${callIndex + 1}; refusing to execute the live tool during replay.`, "https://docs.bitfab.ai/frameworks/langgraph");
|
|
1926
|
+
if (hasMatchingOverride !== true && expectsRecordedOutput && !mockSpan) throw new require_http.BitfabError(`No recorded LangGraph tool result for "${toolName}" at call ${callIndex + 1}; refusing to execute the live tool during replay.`, "https://docs.bitfab.ai/frameworks/langgraph");
|
|
4121
1927
|
}
|
|
4122
1928
|
wrapInvoke(fn) {
|
|
4123
1929
|
return this.client.withSpan(this.traceFunctionKey, {
|
|
@@ -4159,7 +1965,7 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
4159
1965
|
this.getActiveSpanContext = config.getActiveSpanContext;
|
|
4160
1966
|
}
|
|
4161
1967
|
async wrapRun(agent, input, options) {
|
|
4162
|
-
const { run } = await importOptionalPeer(["@openai", "agents"]);
|
|
1968
|
+
const { run } = await require_bamlPeer.importOptionalPeer(["@openai", "agents"]);
|
|
4163
1969
|
if (this.getActiveSpanContext?.() != null) return run(agent, input, options);
|
|
4164
1970
|
const isStreaming = options?.stream === true;
|
|
4165
1971
|
const finalize = async (result) => {
|
|
@@ -4254,6 +2060,7 @@ var OrganizationMembersClient = class {
|
|
|
4254
2060
|
const MAX_FILES = 60;
|
|
4255
2061
|
const MAX_FILE_BYTES = 5e5;
|
|
4256
2062
|
const MAX_TOTAL_BYTES = 2e6;
|
|
2063
|
+
const MAX_BRANCH_WALK = 1e3;
|
|
4257
2064
|
const NUL = String.fromCharCode(0);
|
|
4258
2065
|
async function resolveAutoCodeChange(label) {
|
|
4259
2066
|
if (typeof process === "undefined") return null;
|
|
@@ -4286,7 +2093,7 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
4286
2093
|
} catch {
|
|
4287
2094
|
return null;
|
|
4288
2095
|
}
|
|
4289
|
-
const git = await gitRunner({
|
|
2096
|
+
const git = await require_http.gitRunner({
|
|
4290
2097
|
timeoutMs: 3e4,
|
|
4291
2098
|
maxBuffer: 67108864,
|
|
4292
2099
|
keepProcessAlive: true
|
|
@@ -4295,8 +2102,17 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
4295
2102
|
try {
|
|
4296
2103
|
const root = (await git(cwd, ["rev-parse", "--show-toplevel"]))?.trim();
|
|
4297
2104
|
if (!root) return null;
|
|
4298
|
-
|
|
2105
|
+
let resolved = await resolveBase(git, root);
|
|
4299
2106
|
if (!resolved) return null;
|
|
2107
|
+
let entries = await listChanges(git, root, resolved.base);
|
|
2108
|
+
if (entries.length === 0 && resolved.base === "HEAD") {
|
|
2109
|
+
const branchPoint = await resolveBranchPoint(git, root);
|
|
2110
|
+
if (branchPoint) {
|
|
2111
|
+
resolved = branchPoint;
|
|
2112
|
+
entries = await listChanges(git, root, branchPoint.base);
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
if (entries.length === 0) return null;
|
|
4300
2116
|
const { base, against } = resolved;
|
|
4301
2117
|
const blobBytes = async (ref, path) => {
|
|
4302
2118
|
const out = await git(root, [
|
|
@@ -4316,29 +2132,6 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
4316
2132
|
return 0;
|
|
4317
2133
|
}
|
|
4318
2134
|
};
|
|
4319
|
-
const tracked = await git(root, [
|
|
4320
|
-
"diff",
|
|
4321
|
-
"--name-status",
|
|
4322
|
-
"--find-renames",
|
|
4323
|
-
"-z",
|
|
4324
|
-
base,
|
|
4325
|
-
"--",
|
|
4326
|
-
":!.bitfab"
|
|
4327
|
-
]);
|
|
4328
|
-
const untracked = await git(root, [
|
|
4329
|
-
"ls-files",
|
|
4330
|
-
"--others",
|
|
4331
|
-
"--exclude-standard",
|
|
4332
|
-
"-z",
|
|
4333
|
-
"--",
|
|
4334
|
-
":!.bitfab"
|
|
4335
|
-
]);
|
|
4336
|
-
const entries = [...parseNameStatusZ(tracked ?? ""), ...(untracked ?? "").split(NUL).filter((p) => p.length > 0).map((path) => ({
|
|
4337
|
-
status: "A",
|
|
4338
|
-
beforePath: path,
|
|
4339
|
-
path
|
|
4340
|
-
}))];
|
|
4341
|
-
if (entries.length === 0) return null;
|
|
4342
2135
|
const files = [];
|
|
4343
2136
|
let totalBytes = 0;
|
|
4344
2137
|
for (const { status, beforePath, path } of entries) {
|
|
@@ -4374,6 +2167,129 @@ async function captureCodeChangeFromGit(cwd, label) {
|
|
|
4374
2167
|
return null;
|
|
4375
2168
|
}
|
|
4376
2169
|
}
|
|
2170
|
+
async function listChanges(git, root, base) {
|
|
2171
|
+
const tracked = await git(root, [
|
|
2172
|
+
"diff",
|
|
2173
|
+
"--name-status",
|
|
2174
|
+
"--find-renames",
|
|
2175
|
+
"-z",
|
|
2176
|
+
base,
|
|
2177
|
+
"--",
|
|
2178
|
+
":!.bitfab"
|
|
2179
|
+
]);
|
|
2180
|
+
const untracked = await git(root, [
|
|
2181
|
+
"ls-files",
|
|
2182
|
+
"--others",
|
|
2183
|
+
"--exclude-standard",
|
|
2184
|
+
"-z",
|
|
2185
|
+
"--",
|
|
2186
|
+
":!.bitfab"
|
|
2187
|
+
]);
|
|
2188
|
+
return [...parseNameStatusZ(tracked ?? ""), ...(untracked ?? "").split(NUL).filter((p) => p.length > 0).map((path) => ({
|
|
2189
|
+
status: "A",
|
|
2190
|
+
beforePath: path,
|
|
2191
|
+
path
|
|
2192
|
+
}))];
|
|
2193
|
+
}
|
|
2194
|
+
async function defaultBranchCandidates(git, root) {
|
|
2195
|
+
const originHead = (await git(root, [
|
|
2196
|
+
"rev-parse",
|
|
2197
|
+
"--abbrev-ref",
|
|
2198
|
+
"origin/HEAD"
|
|
2199
|
+
]))?.trim();
|
|
2200
|
+
const candidates = [
|
|
2201
|
+
originHead && originHead !== "origin/HEAD" ? originHead : null,
|
|
2202
|
+
"origin/main",
|
|
2203
|
+
"origin/master",
|
|
2204
|
+
"main",
|
|
2205
|
+
"master"
|
|
2206
|
+
].filter((ref) => !!ref);
|
|
2207
|
+
return [...new Set(candidates)];
|
|
2208
|
+
}
|
|
2209
|
+
async function resolveDefaultBranch(git, root) {
|
|
2210
|
+
for (const ref of await defaultBranchCandidates(git, root)) if (await refExists(git, root, ref)) return ref;
|
|
2211
|
+
return null;
|
|
2212
|
+
}
|
|
2213
|
+
async function currentBranchRefs(git, root) {
|
|
2214
|
+
const branch = (await git(root, [
|
|
2215
|
+
"symbolic-ref",
|
|
2216
|
+
"--short",
|
|
2217
|
+
"-q",
|
|
2218
|
+
"HEAD"
|
|
2219
|
+
]))?.trim();
|
|
2220
|
+
const refs = /* @__PURE__ */ new Set();
|
|
2221
|
+
if (branch) {
|
|
2222
|
+
refs.add(`refs/heads/${branch}`);
|
|
2223
|
+
const remotes = (await git(root, ["remote"]))?.split(/\s+/) ?? [];
|
|
2224
|
+
for (const remote of remotes.filter((r) => r.length > 0)) refs.add(`refs/remotes/${remote}/${branch}`);
|
|
2225
|
+
}
|
|
2226
|
+
return refs;
|
|
2227
|
+
}
|
|
2228
|
+
async function ownBranchRefs(git, root) {
|
|
2229
|
+
const upstream = (await git(root, [
|
|
2230
|
+
"rev-parse",
|
|
2231
|
+
"--symbolic-full-name",
|
|
2232
|
+
"@{upstream}"
|
|
2233
|
+
]))?.trim();
|
|
2234
|
+
const own = await currentBranchRefs(git, root);
|
|
2235
|
+
if (upstream) own.add(upstream);
|
|
2236
|
+
return own;
|
|
2237
|
+
}
|
|
2238
|
+
async function isOnDefaultBranch(git, root, defaultBranch) {
|
|
2239
|
+
const fullName = (await git(root, [
|
|
2240
|
+
"rev-parse",
|
|
2241
|
+
"--symbolic-full-name",
|
|
2242
|
+
defaultBranch
|
|
2243
|
+
]))?.trim();
|
|
2244
|
+
return !!fullName && (await currentBranchRefs(git, root)).has(fullName);
|
|
2245
|
+
}
|
|
2246
|
+
async function branchTips(git, root) {
|
|
2247
|
+
const own = await ownBranchRefs(git, root);
|
|
2248
|
+
const listing = await git(root, [
|
|
2249
|
+
"for-each-ref",
|
|
2250
|
+
"--format=%(objectname) %(refname)",
|
|
2251
|
+
"refs/heads",
|
|
2252
|
+
"refs/remotes"
|
|
2253
|
+
]);
|
|
2254
|
+
const tips = /* @__PURE__ */ new Map();
|
|
2255
|
+
for (const line of (listing ?? "").split("\n")) {
|
|
2256
|
+
const [sha, ref] = line.trim().split(" ");
|
|
2257
|
+
if (!ref || own.has(ref) || ref.endsWith("/HEAD") || tips.has(sha)) continue;
|
|
2258
|
+
tips.set(sha, ref.replace(/^refs\/(heads|remotes)\//, ""));
|
|
2259
|
+
}
|
|
2260
|
+
return tips;
|
|
2261
|
+
}
|
|
2262
|
+
async function resolveBranchPoint(git, root) {
|
|
2263
|
+
const head = (await git(root, ["rev-parse", "HEAD"]))?.trim();
|
|
2264
|
+
if (!head) return null;
|
|
2265
|
+
const defaultBranch = await resolveDefaultBranch(git, root);
|
|
2266
|
+
if (defaultBranch && await isOnDefaultBranch(git, root, defaultBranch)) return null;
|
|
2267
|
+
const defaultBase = defaultBranch ? (await git(root, [
|
|
2268
|
+
"merge-base",
|
|
2269
|
+
"HEAD",
|
|
2270
|
+
defaultBranch
|
|
2271
|
+
]))?.trim() : void 0;
|
|
2272
|
+
const walk = [
|
|
2273
|
+
"rev-list",
|
|
2274
|
+
"--first-parent",
|
|
2275
|
+
`--max-count=${MAX_BRANCH_WALK}`,
|
|
2276
|
+
"HEAD",
|
|
2277
|
+
...defaultBase ? [`^${defaultBase}`] : []
|
|
2278
|
+
];
|
|
2279
|
+
const tips = await branchTips(git, root);
|
|
2280
|
+
const history = (await git(root, walk) ?? "").split(/\s+/).filter(Boolean);
|
|
2281
|
+
for (const sha of history.slice(1)) {
|
|
2282
|
+
const name = tips.get(sha);
|
|
2283
|
+
if (name) return {
|
|
2284
|
+
base: sha,
|
|
2285
|
+
against: `vs ${name}`
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
return defaultBase && defaultBase !== head ? {
|
|
2289
|
+
base: defaultBase,
|
|
2290
|
+
against: `vs ${defaultBranch}`
|
|
2291
|
+
} : null;
|
|
2292
|
+
}
|
|
4377
2293
|
async function resolveBase(git, root) {
|
|
4378
2294
|
const forced = process.env?.BITFAB_CODE_CHANGE_BASE;
|
|
4379
2295
|
if (forced && await refExists(git, root, forced)) {
|
|
@@ -4481,7 +2397,7 @@ function startReplayHeartbeat(send) {
|
|
|
4481
2397
|
inFlight = void 0;
|
|
4482
2398
|
});
|
|
4483
2399
|
}, REPLAY_HEARTBEAT_INTERVAL_MS);
|
|
4484
|
-
unrefTimer(timer);
|
|
2400
|
+
require_http.unrefTimer(timer);
|
|
4485
2401
|
return { stop: async () => {
|
|
4486
2402
|
stopped = true;
|
|
4487
2403
|
clearInterval(timer);
|
|
@@ -4580,9 +2496,9 @@ const OPTION_FLAG_NAMES = {
|
|
|
4580
2496
|
datasetIds: "dataset-ids"
|
|
4581
2497
|
};
|
|
4582
2498
|
function replayEnvironment() {
|
|
4583
|
-
if (readEnv
|
|
4584
|
-
if (CI_TRUE_VALUES.has((readEnv
|
|
4585
|
-
if (CI_PRESENCE_ENV_VARS.some((name) => (readEnv
|
|
2499
|
+
if (require_http.readEnv(REPLAY_EXECUTION_TARGET_ENV) === HOSTED_EXECUTION_TARGET) return "cloud_replay";
|
|
2500
|
+
if (CI_TRUE_VALUES.has((require_http.readEnv(CI_ENV) ?? "").toLowerCase())) return "ci";
|
|
2501
|
+
if (CI_PRESENCE_ENV_VARS.some((name) => (require_http.readEnv(name) ?? "") !== "")) return "ci";
|
|
4586
2502
|
return "local";
|
|
4587
2503
|
}
|
|
4588
2504
|
function flagScalar(value) {
|
|
@@ -4621,7 +2537,7 @@ function buildReplayInvocation(entries = []) {
|
|
|
4621
2537
|
flags: invocationFlags(entries),
|
|
4622
2538
|
sdk: {
|
|
4623
2539
|
language: "typescript",
|
|
4624
|
-
version: __version__
|
|
2540
|
+
version: require_http.__version__
|
|
4625
2541
|
},
|
|
4626
2542
|
environment: replayEnvironment()
|
|
4627
2543
|
};
|
|
@@ -4671,7 +2587,7 @@ function jsonFingerprint(value) {
|
|
|
4671
2587
|
//#region src/selectiveReplayRuntime.ts
|
|
4672
2588
|
function validateSelectiveReplayOptions(options) {
|
|
4673
2589
|
const validNodes = (nodes) => Array.isArray(nodes) && nodes.length <= 100 && nodes.every((node) => typeof node?.traceFunctionKey === "string" && node.traceFunctionKey.length > 0 && node.traceFunctionKey.length <= 500 && typeof node.spanName === "string" && node.spanName.length > 0 && node.spanName.length <= 500);
|
|
4674
|
-
if (!options || !validNodes(options.mustRun) || options.mustRun.length === 0 || Object.keys(options).some((key) => key !== "mustRun")) throw new BitfabError("experimentalSelectiveReplay accepts only 1–100 mustRun with traceFunctionKey and spanName. Declare replayReusable on eligible spans, not reusableNodes in the replay request.");
|
|
2590
|
+
if (!options || !validNodes(options.mustRun) || options.mustRun.length === 0 || Object.keys(options).some((key) => key !== "mustRun")) throw new require_http.BitfabError("experimentalSelectiveReplay accepts only 1–100 mustRun with traceFunctionKey and spanName. Declare replayReusable on eligible spans, not reusableNodes in the replay request.");
|
|
4675
2591
|
}
|
|
4676
2592
|
function policyKey(options) {
|
|
4677
2593
|
return JSON.stringify(options.mustRun.map(replayNodeKey).sort());
|
|
@@ -4693,12 +2609,12 @@ var SelectiveReplayRuntime = class {
|
|
|
4693
2609
|
this.observedNames = /* @__PURE__ */ new Map();
|
|
4694
2610
|
this.unresolvedAssertions = [];
|
|
4695
2611
|
validateSelectiveReplayOptions(options);
|
|
4696
|
-
if (plan?.version !== 4 || !Array.isArray(plan.nodes) || plan.nodes.length === 0 || plan.nodes.length > 500 || !Array.isArray(plan.unresolvedMustRun) || !Array.isArray(plan.assertions) || !plan.options) throw new BitfabError("Server did not return a compatible selective replay plan. Update the server or disable experimentalSelectiveReplay.");
|
|
2612
|
+
if (plan?.version !== 4 || !Array.isArray(plan.nodes) || plan.nodes.length === 0 || plan.nodes.length > 500 || !Array.isArray(plan.unresolvedMustRun) || !Array.isArray(plan.assertions) || !plan.options) throw new require_http.BitfabError("Server did not return a compatible selective replay plan. Update the server or disable experimentalSelectiveReplay.");
|
|
4697
2613
|
validateSelectiveReplayOptions(plan.options);
|
|
4698
|
-
if (policyKey(plan.options) !== policyKey(options)) throw new BitfabError("Selective replay plan does not match the requested mustRun nodes.");
|
|
2614
|
+
if (policyKey(plan.options) !== policyKey(options)) throw new require_http.BitfabError("Selective replay plan does not match the requested mustRun nodes.");
|
|
4699
2615
|
this.required = new Set(options.mustRun.map(replayNodeKey));
|
|
4700
2616
|
for (const node of plan.nodes) {
|
|
4701
|
-
if (typeof node.id !== "string" || this.nodes.has(node.id) || typeof node.traceFunctionKey !== "string" || typeof node.spanName !== "string" || typeof node.mustRun !== "boolean" || typeof node.reusable !== "boolean") throw new BitfabError("Invalid selective replay node.");
|
|
2617
|
+
if (typeof node.id !== "string" || this.nodes.has(node.id) || typeof node.traceFunctionKey !== "string" || typeof node.spanName !== "string" || typeof node.mustRun !== "boolean" || typeof node.reusable !== "boolean") throw new require_http.BitfabError("Invalid selective replay node.");
|
|
4702
2618
|
this.nodes.set(node.id, node);
|
|
4703
2619
|
if (node.recording !== void 0) this.recordings.set(node.id, {
|
|
4704
2620
|
input: node.recording.kwargs === void 0 ? jsonFingerprint(node.recording.input) : void 0,
|
|
@@ -4711,16 +2627,16 @@ var SelectiveReplayRuntime = class {
|
|
|
4711
2627
|
}
|
|
4712
2628
|
}
|
|
4713
2629
|
const root = this.nodes.get(plan.rootId);
|
|
4714
|
-
if (!root || root.parentId !== null || !root.mustRun) throw new BitfabError("Selective replay requires a live recorded root.");
|
|
2630
|
+
if (!root || root.parentId !== null || !root.mustRun) throw new require_http.BitfabError("Selective replay requires a live recorded root.");
|
|
4715
2631
|
const assertionIds = /* @__PURE__ */ new Set();
|
|
4716
2632
|
let wholeTrace = false;
|
|
4717
2633
|
for (const assertion of plan.assertions) {
|
|
4718
2634
|
const target = assertion?.target;
|
|
4719
|
-
if (typeof assertion?.id !== "string" || assertion.id.length === 0 || assertionIds.has(assertion.id) || target !== null && (typeof target !== "object" || target.kind !== "output" && target.kind !== "span")) throw new BitfabError("Invalid selective replay assertion requirements.");
|
|
2635
|
+
if (typeof assertion?.id !== "string" || assertion.id.length === 0 || assertionIds.has(assertion.id) || target !== null && (typeof target !== "object" || target.kind !== "output" && target.kind !== "span")) throw new require_http.BitfabError("Invalid selective replay assertion requirements.");
|
|
4720
2636
|
assertionIds.add(assertion.id);
|
|
4721
2637
|
if (target === null) wholeTrace = true;
|
|
4722
2638
|
else if (target.kind === "span") {
|
|
4723
|
-
if (typeof target.name !== "string" || target.name.length === 0 || target.occurrence !== void 0 && target.occurrence !== "first" && target.occurrence !== "last" && !(Number.isInteger(target.occurrence) && typeof target.occurrence === "number" && target.occurrence >= 0)) throw new BitfabError("Invalid selective replay assertion target.");
|
|
2639
|
+
if (typeof target.name !== "string" || target.name.length === 0 || target.occurrence !== void 0 && target.occurrence !== "first" && target.occurrence !== "last" && !(Number.isInteger(target.occurrence) && typeof target.occurrence === "number" && target.occurrence >= 0)) throw new require_http.BitfabError("Invalid selective replay assertion target.");
|
|
4724
2640
|
this.assertionNames.add(target.name);
|
|
4725
2641
|
if (plan.nodes.filter((node) => node.spanName === target.name).length <= (typeof target.occurrence === "number" ? target.occurrence : 0)) this.unresolvedAssertions.push(assertion.id);
|
|
4726
2642
|
}
|
|
@@ -4728,7 +2644,7 @@ var SelectiveReplayRuntime = class {
|
|
|
4728
2644
|
this.fullTraceForAssertions = wholeTrace || this.unresolvedAssertions.length > 0;
|
|
4729
2645
|
const recordedKeys = new Set(plan.nodes.map(replayNodeKey));
|
|
4730
2646
|
const unresolved = options.mustRun.filter((node) => !recordedKeys.has(replayNodeKey(node)));
|
|
4731
|
-
if (JSON.stringify(unresolved.map(replayNodeKey).sort()) !== JSON.stringify(plan.unresolvedMustRun.map(replayNodeKey).sort())) throw new BitfabError("Selective replay plan has incomplete mustRun coverage.");
|
|
2647
|
+
if (JSON.stringify(unresolved.map(replayNodeKey).sort()) !== JSON.stringify(plan.unresolvedMustRun.map(replayNodeKey).sort())) throw new require_http.BitfabError("Selective replay plan has incomplete mustRun coverage.");
|
|
4732
2648
|
for (const node of plan.nodes) {
|
|
4733
2649
|
const ancestors = /* @__PURE__ */ new Set([node.id]);
|
|
4734
2650
|
let requiredByManifest = this.required.has(replayNodeKey(node));
|
|
@@ -4736,14 +2652,14 @@ var SelectiveReplayRuntime = class {
|
|
|
4736
2652
|
let parentId = node.parentId;
|
|
4737
2653
|
while (parentId !== null) {
|
|
4738
2654
|
const parent = this.nodes.get(parentId);
|
|
4739
|
-
if (!parent || ancestors.has(parentId) || node.mustRun && !parent.mustRun) throw new BitfabError("Invalid selective replay ancestry.");
|
|
2655
|
+
if (!parent || ancestors.has(parentId) || node.mustRun && !parent.mustRun) throw new require_http.BitfabError("Invalid selective replay ancestry.");
|
|
4740
2656
|
ancestors.add(parentId);
|
|
4741
2657
|
requiredByManifest || (requiredByManifest = this.required.has(replayNodeKey(parent)));
|
|
4742
2658
|
requiredForAssertion || (requiredForAssertion = this.assertionNames.has(parent.spanName));
|
|
4743
2659
|
parentId = parent.parentId;
|
|
4744
2660
|
}
|
|
4745
|
-
if (!ancestors.has(plan.rootId) || (requiredByManifest || unresolved.length > 0) && !node.mustRun) throw new BitfabError("Selective replay plan could hide required code.");
|
|
4746
|
-
if (requiredForAssertion && !node.mustRun) throw new BitfabError("Selective replay plan could hide assertion evidence.");
|
|
2661
|
+
if (!ancestors.has(plan.rootId) || (requiredByManifest || unresolved.length > 0) && !node.mustRun) throw new require_http.BitfabError("Selective replay plan could hide required code.");
|
|
2662
|
+
if (requiredForAssertion && !node.mustRun) throw new require_http.BitfabError("Selective replay plan could hide assertion evidence.");
|
|
4747
2663
|
}
|
|
4748
2664
|
}
|
|
4749
2665
|
enter(params) {
|
|
@@ -4789,7 +2705,7 @@ var SelectiveReplayRuntime = class {
|
|
|
4789
2705
|
};
|
|
4790
2706
|
if (params.safetyMock && (mustRun || !reusable)) {
|
|
4791
2707
|
decision("blocked", `safety-conflict:${reason}`);
|
|
4792
|
-
this.failure = new BitfabError(`Selective replay cannot execute or safely reuse safety-mocked node ${params.spanName} (${reason}).`);
|
|
2708
|
+
this.failure = new require_http.BitfabError(`Selective replay cannot execute or safely reuse safety-mocked node ${params.spanName} (${reason}).`);
|
|
4793
2709
|
throw this.failure;
|
|
4794
2710
|
}
|
|
4795
2711
|
if (!mustRun && reusable && (params.safetyMock || node?.reusable === true && params.reuseAllowed)) {
|
|
@@ -4820,7 +2736,7 @@ var SelectiveReplayRuntime = class {
|
|
|
4820
2736
|
};
|
|
4821
2737
|
//#endregion
|
|
4822
2738
|
//#region src/replay.ts
|
|
4823
|
-
var replay_exports = /* @__PURE__ */ __exportAll({
|
|
2739
|
+
var replay_exports = /* @__PURE__ */ require_bamlPeer.__exportAll({
|
|
4824
2740
|
BITFAB_PROGRESS_PREFIX: () => BITFAB_PROGRESS_PREFIX,
|
|
4825
2741
|
DbBranchReplayError: () => DbBranchReplayError,
|
|
4826
2742
|
JUDGE_ASSERTIONS_DEPRECATION_WARNING: () => JUDGE_ASSERTIONS_DEPRECATION_WARNING,
|
|
@@ -4854,15 +2770,15 @@ const RESUME_CONFLICTING_OPTIONS = [
|
|
|
4854
2770
|
];
|
|
4855
2771
|
const CARRIED_OVER_ERROR = "This item errored in an earlier run of this experiment, before it was resumed.";
|
|
4856
2772
|
function validateResume(resume, options) {
|
|
4857
|
-
if (resume.trim().length === 0) throw new BitfabError("resume must be the ID of the experiment to resume.");
|
|
2773
|
+
if (resume.trim().length === 0) throw new require_http.BitfabError("resume must be the ID of the experiment to resume.");
|
|
4858
2774
|
const conflicting = RESUME_CONFLICTING_OPTIONS.filter((name) => options[name] !== void 0 && options[name] !== false);
|
|
4859
|
-
if (conflicting.length > 0) throw new BitfabError(`resume continues experiment ${resume} with the traces, attempts, and graders it started with, so it cannot be combined with ${conflicting.join(", ")}. Drop those options, or start a new replay without resume.`);
|
|
2775
|
+
if (conflicting.length > 0) throw new require_http.BitfabError(`resume continues experiment ${resume} with the traces, attempts, and graders it started with, so it cannot be combined with ${conflicting.join(", ")}. Drop those options, or start a new replay without resume.`);
|
|
4860
2776
|
}
|
|
4861
2777
|
async function resumeReplaySession(httpClient, experimentId, traceFunctionKey, codeChangeFiles, force, requestedDbBranch) {
|
|
4862
2778
|
const response = await httpClient.resumeReplay(experimentId, traceFunctionKey, codeChangeFiles, force);
|
|
4863
2779
|
const work = response.work.map(({ itemIndex, attempt }) => {
|
|
4864
2780
|
const serverItem = response.items[itemIndex];
|
|
4865
|
-
if (serverItem === void 0) throw new BitfabError(`Replay resume for experiment ${response.experimentId} named item ${itemIndex}, but the server returned only ${response.items.length} item(s).`);
|
|
2781
|
+
if (serverItem === void 0) throw new require_http.BitfabError(`Replay resume for experiment ${response.experimentId} named item ${itemIndex}, but the server returned only ${response.items.length} item(s).`);
|
|
4866
2782
|
return {
|
|
4867
2783
|
serverItem,
|
|
4868
2784
|
attempt
|
|
@@ -4911,14 +2827,14 @@ function carriedOverReplayItem(finished) {
|
|
|
4911
2827
|
}
|
|
4912
2828
|
function resolveAttempts(attempts) {
|
|
4913
2829
|
if (attempts === void 0) return 1;
|
|
4914
|
-
if (!Number.isInteger(attempts) || attempts < 1 || attempts > MAX_REPLAY_ATTEMPTS) throw new BitfabError(`attempts must be an integer from 1 to ${MAX_REPLAY_ATTEMPTS} (got ${attempts}).`);
|
|
2830
|
+
if (!Number.isInteger(attempts) || attempts < 1 || attempts > MAX_REPLAY_ATTEMPTS) throw new require_http.BitfabError(`attempts must be an integer from 1 to ${MAX_REPLAY_ATTEMPTS} (got ${attempts}).`);
|
|
4915
2831
|
return attempts;
|
|
4916
2832
|
}
|
|
4917
2833
|
function resolveDatasetIds(options) {
|
|
4918
|
-
if (options?.datasetId !== void 0 && options?.datasetIds !== void 0) throw new BitfabError("datasetId and datasetIds are the same selector: pass one dataset through datasetId, or several through datasetIds.");
|
|
2834
|
+
if (options?.datasetId !== void 0 && options?.datasetIds !== void 0) throw new require_http.BitfabError("datasetId and datasetIds are the same selector: pass one dataset through datasetId, or several through datasetIds.");
|
|
4919
2835
|
if (options?.datasetId !== void 0) return [options.datasetId];
|
|
4920
2836
|
if (options?.datasetIds === void 0) return;
|
|
4921
|
-
if (options.datasetIds.length === 0) throw new BitfabError("datasetIds must contain at least one dataset ID.");
|
|
2837
|
+
if (options.datasetIds.length === 0) throw new require_http.BitfabError("datasetIds must contain at least one dataset ID.");
|
|
4922
2838
|
return [...new Set(options.datasetIds)];
|
|
4923
2839
|
}
|
|
4924
2840
|
function dbBranchEnabled(dbBranch) {
|
|
@@ -4982,7 +2898,7 @@ function reportReplayProgress(progress) {
|
|
|
4982
2898
|
stderr.write(`${BITFAB_PROGRESS_PREFIX}${JSON.stringify(progress, replayJsonReplacer)}\n`);
|
|
4983
2899
|
} catch {}
|
|
4984
2900
|
}
|
|
4985
|
-
var ReplayError = class extends BitfabError {
|
|
2901
|
+
var ReplayError = class extends require_http.BitfabError {
|
|
4986
2902
|
constructor(message, items, experimentId, experimentUrl, cause) {
|
|
4987
2903
|
super(message, experimentUrl);
|
|
4988
2904
|
this.items = items;
|
|
@@ -4994,7 +2910,7 @@ var ReplayError = class extends BitfabError {
|
|
|
4994
2910
|
this.testRunUrl = experimentUrl;
|
|
4995
2911
|
}
|
|
4996
2912
|
};
|
|
4997
|
-
var DbBranchReplayError = class extends BitfabError {
|
|
2913
|
+
var DbBranchReplayError = class extends require_http.BitfabError {
|
|
4998
2914
|
constructor(code, message, originalTraceId, cause) {
|
|
4999
2915
|
super(message);
|
|
5000
2916
|
this.code = code;
|
|
@@ -5115,7 +3031,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
|
|
|
5115
3031
|
}
|
|
5116
3032
|
if (leaseError) throw new DbBranchReplayError(leaseError.code, leaseError.message, originalTraceId);
|
|
5117
3033
|
if (selectiveOptions !== void 0) {
|
|
5118
|
-
if (serverItem.selectiveReplayPlan === void 0) throw new BitfabError("Server did not return a selective replay plan. Update the server or disable experimentalSelectiveReplay.");
|
|
3034
|
+
if (serverItem.selectiveReplayPlan === void 0) throw new require_http.BitfabError("Server did not return a selective replay plan. Update the server or disable experimentalSelectiveReplay.");
|
|
5119
3035
|
selectiveReplay = new SelectiveReplayRuntime(serverItem.selectiveReplayPlan, selectiveOptions);
|
|
5120
3036
|
}
|
|
5121
3037
|
const span = await httpClient.getExternalSpan(originalSpanId, { view: "replay" });
|
|
@@ -5142,7 +3058,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
|
|
|
5142
3058
|
includeOutputs,
|
|
5143
3059
|
includeRootOutput: false
|
|
5144
3060
|
});
|
|
5145
|
-
if (!treeResponse.root) throw new BitfabError(`Replay mock strategy "${mockStrategy}"${hasOverrides ? " with overrides" : ""} requires a span tree root for original span ${originalSpanId}.`);
|
|
3061
|
+
if (!treeResponse.root) throw new require_http.BitfabError(`Replay mock strategy "${mockStrategy}"${hasOverrides ? " with overrides" : ""} requires a span tree root for original span ${originalSpanId}.`);
|
|
5146
3062
|
mockTree = buildMockTree(treeResponse.root);
|
|
5147
3063
|
} catch (error) {
|
|
5148
3064
|
if (mockStrategy !== "marked" || hasOverrides) throw error;
|
|
@@ -5182,7 +3098,7 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
|
|
|
5182
3098
|
};
|
|
5183
3099
|
try {
|
|
5184
3100
|
replayStarted = performance.now();
|
|
5185
|
-
const maybePromise = runWithReplayContext({
|
|
3101
|
+
const maybePromise = require_http.runWithReplayContext({
|
|
5186
3102
|
experimentId,
|
|
5187
3103
|
traceId: replayedTraceId,
|
|
5188
3104
|
inputSourceSpanId: span.id,
|
|
@@ -5250,13 +3166,13 @@ async function processItem(httpClient, serverItem, fn, experimentId, mockStrateg
|
|
|
5250
3166
|
async function waitForReplayPersistence(httpClient, experimentId, replayedTraceIds, replayLabels = {}, warn = console.warn) {
|
|
5251
3167
|
if (!await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS)) {
|
|
5252
3168
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
5253
|
-
throw new BitfabError(`Replay could not settle deferred span work before the deadline, so the expected span counts are incomplete (experiment ${experimentId}).`);
|
|
3169
|
+
throw new require_http.BitfabError(`Replay could not settle deferred span work before the deadline, so the expected span counts are incomplete (experiment ${experimentId}).`);
|
|
5254
3170
|
}
|
|
5255
3171
|
if (!httpClient.hasClosedDeliveries(replayedTraceIds)) {
|
|
5256
3172
|
httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
5257
3173
|
return {};
|
|
5258
3174
|
}
|
|
5259
|
-
const flushed = await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
3175
|
+
const flushed = await require_http.flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
5260
3176
|
const deliveries = httpClient.takeTraceDeliveries(replayedTraceIds);
|
|
5261
3177
|
const expectedSpanCounts = {};
|
|
5262
3178
|
const readBackTraceIds = {};
|
|
@@ -5312,15 +3228,15 @@ function warnJudgeAssertionsDeprecated(write = console.warn) {
|
|
|
5312
3228
|
async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, registeredOverrides = []) {
|
|
5313
3229
|
if (options?.judgeAssertions !== void 0) warnJudgeAssertionsDeprecated();
|
|
5314
3230
|
if (options?.resume !== void 0) validateResume(options.resume, options);
|
|
5315
|
-
else if (options?.force === true) throw new BitfabError("force only applies when resuming an experiment. Pass it together with resume.");
|
|
5316
|
-
if (options?.experimentGroupName !== void 0 && options.experimentGroupId === void 0) throw new BitfabError("experimentGroupName only applies with experimentGroupId. Pass it together with experimentGroupId.");
|
|
3231
|
+
else if (options?.force === true) throw new require_http.BitfabError("force only applies when resuming an experiment. Pass it together with resume.");
|
|
3232
|
+
if (options?.experimentGroupName !== void 0 && options.experimentGroupId === void 0) throw new require_http.BitfabError("experimentGroupName only applies with experimentGroupId. Pass it together with experimentGroupId.");
|
|
5317
3233
|
if (options?.experimentalSelectiveReplay !== void 0) {
|
|
5318
3234
|
validateSelectiveReplayOptions(options.experimentalSelectiveReplay);
|
|
5319
|
-
if ((options.mock ?? "marked") !== "marked" || normalizeMockOverrides(options.mockOverride).length > 0 || registeredOverrides.length > 0) throw new BitfabError("experimentalSelectiveReplay requires mock: 'marked' and cannot be combined with mock overrides.");
|
|
3235
|
+
if ((options.mock ?? "marked") !== "marked" || normalizeMockOverrides(options.mockOverride).length > 0 || registeredOverrides.length > 0) throw new require_http.BitfabError("experimentalSelectiveReplay requires mock: 'marked' and cannot be combined with mock overrides.");
|
|
5320
3236
|
}
|
|
5321
3237
|
if (options?.traceIds !== void 0) {
|
|
5322
|
-
if (options.traceIds.length === 0) throw new BitfabError("traceIds must contain at least one trace ID.");
|
|
5323
|
-
if (options.traceIds.length > 100) throw new BitfabError(`traceIds supports at most 100 trace IDs per replay (got ${options.traceIds.length}).`);
|
|
3238
|
+
if (options.traceIds.length === 0) throw new require_http.BitfabError("traceIds must contain at least one trace ID.");
|
|
3239
|
+
if (options.traceIds.length > 100) throw new require_http.BitfabError(`traceIds supports at most 100 trace IDs per replay (got ${options.traceIds.length}).`);
|
|
5324
3240
|
}
|
|
5325
3241
|
const datasetIds = resolveDatasetIds(options);
|
|
5326
3242
|
if (options?.limit !== void 0 && options?.traceIds !== void 0) try {
|
|
@@ -5328,8 +3244,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
5328
3244
|
} catch {}
|
|
5329
3245
|
const requestedAttempts = resolveAttempts(options?.attempts);
|
|
5330
3246
|
const maxConcurrency = options?.maxConcurrency ?? 10;
|
|
5331
|
-
if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1) throw new BitfabError(`maxConcurrency must be a positive integer (got ${maxConcurrency}).`);
|
|
5332
|
-
await replayContextReady;
|
|
3247
|
+
if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1) throw new require_http.BitfabError(`maxConcurrency must be a positive integer (got ${maxConcurrency}).`);
|
|
3248
|
+
await require_http.replayContextReady;
|
|
5333
3249
|
let codeChangeDescription = options?.codeChangeDescription;
|
|
5334
3250
|
let codeChangeFiles = options?.codeChangeFiles;
|
|
5335
3251
|
if (codeChangeFiles === void 0) {
|
|
@@ -5387,7 +3303,7 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
5387
3303
|
}
|
|
5388
3304
|
function throwIfInterrupted(interrupted, items, experimentId, experimentUrl) {
|
|
5389
3305
|
if (!interrupted()) return;
|
|
5390
|
-
const cause = new BitfabError(`Experiment ${experimentId} was interrupted, so it was not completed or graded. Resume it by passing { resume: "${experimentId}" } to replay, or with bitfab-replay --resume ${experimentId}.`, experimentUrl);
|
|
3306
|
+
const cause = new require_http.BitfabError(`Experiment ${experimentId} was interrupted, so it was not completed or graded. Resume it by passing { resume: "${experimentId}" } to replay, or with bitfab-replay --resume ${experimentId}.`, experimentUrl);
|
|
5391
3307
|
throw new ReplayError(cause.message, items, experimentId, experimentUrl, cause);
|
|
5392
3308
|
}
|
|
5393
3309
|
async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxConcurrency, stopInterruptingOnSignal, markCompleteReturned, interrupted, options, registeredOverrides) {
|
|
@@ -5420,7 +3336,7 @@ async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxC
|
|
|
5420
3336
|
while (flushPending) {
|
|
5421
3337
|
flushPending = false;
|
|
5422
3338
|
await httpClient.settleDeferredWork(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
5423
|
-
await flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
3339
|
+
await require_http.flushTraces(REPLAY_PERSISTENCE_TIMEOUT_MS);
|
|
5424
3340
|
}
|
|
5425
3341
|
} finally {
|
|
5426
3342
|
flushInFlight = null;
|
|
@@ -5545,7 +3461,7 @@ async function runReplaySession(httpClient, fn, session, fullExperimentUrl, maxC
|
|
|
5545
3461
|
}
|
|
5546
3462
|
if (completedCount > 0 && missing.length === completedCount) {
|
|
5547
3463
|
const serverCount = completeResult.traceCount !== void 0 ? ` The server persisted ${completeResult.traceCount} trace(s) for this run.` : "";
|
|
5548
|
-
const cause = new BitfabError(`Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (experiment ${experimentId}).${serverCount} Trace uploads were awaited, so either the uploads failed (check for "Bitfab: Failed to create" errors above) or the replayed function is not wrapped with withSpan.`);
|
|
3464
|
+
const cause = new require_http.BitfabError(`Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (experiment ${experimentId}).${serverCount} Trace uploads were awaited, so either the uploads failed (check for "Bitfab: Failed to create" errors above) or the replayed function is not wrapped with withSpan.`);
|
|
5549
3465
|
throw new ReplayError(cause.message, resultItems, experimentId, fullExperimentUrl, cause);
|
|
5550
3466
|
}
|
|
5551
3467
|
if (missing.length > 0) try {
|
|
@@ -5826,7 +3742,7 @@ function snapshotContext(context) {
|
|
|
5826
3742
|
return snapshot;
|
|
5827
3743
|
}
|
|
5828
3744
|
function unavailableCapability(path) {
|
|
5829
|
-
return new BitfabError(`Rivet context capability "${path}" is unavailable during replay. Add first-class support for that public context path before replaying code that uses it.`, RIVET_DOCS_URL);
|
|
3745
|
+
return new require_http.BitfabError(`Rivet context capability "${path}" is unavailable during replay. Add first-class support for that public context path before replaying code that uses it.`, RIVET_DOCS_URL);
|
|
5830
3746
|
}
|
|
5831
3747
|
function effectNode(traceFunctionKey, effect, mockSpanId) {
|
|
5832
3748
|
return {
|
|
@@ -5851,15 +3767,15 @@ function replayEffectStatus(replay, traceFunctionKey, effect, marked) {
|
|
|
5851
3767
|
function assertReplayEffectAvailable(replay, traceFunctionKey, effect, marked) {
|
|
5852
3768
|
if (!replay) return;
|
|
5853
3769
|
const status = replayEffectStatus(replay, traceFunctionKey, effect, marked);
|
|
5854
|
-
if (!status.willMock) throw new BitfabError(`Rivet effect "${effect}" has no live actor context during replay. Add "${effect}" to mockOnReplay or provide a replay override.`, RIVET_DOCS_URL);
|
|
5855
|
-
if (!status.hasRecordedSpan && !status.hasOverride) throw new BitfabError(`No recorded Rivet effect "${effect}" exists at call ${status.callIndex + 1}; the live effect was not executed.`, RIVET_DOCS_URL);
|
|
3770
|
+
if (!status.willMock) throw new require_http.BitfabError(`Rivet effect "${effect}" has no live actor context during replay. Add "${effect}" to mockOnReplay or provide a replay override.`, RIVET_DOCS_URL);
|
|
3771
|
+
if (!status.hasRecordedSpan && !status.hasOverride) throw new require_http.BitfabError(`No recorded Rivet effect "${effect}" exists at call ${status.callIndex + 1}; the live effect was not executed.`, RIVET_DOCS_URL);
|
|
5856
3772
|
}
|
|
5857
3773
|
function fixtureName(traceFunctionKey) {
|
|
5858
3774
|
return `rivet:${traceFunctionKey}`;
|
|
5859
3775
|
}
|
|
5860
3776
|
function snapshotFromReplay(traceFunctionKey, replay) {
|
|
5861
3777
|
const fixture = replay.integrationFixtures?.get(fixtureName(traceFunctionKey));
|
|
5862
|
-
if (!isRecord(fixture)) throw new BitfabError(`Trace "${traceFunctionKey}" has no Rivet context fixture. Capture a fresh trace with the Rivet integration before replaying it.`, RIVET_DOCS_URL);
|
|
3778
|
+
if (!isRecord(fixture)) throw new require_http.BitfabError(`Trace "${traceFunctionKey}" has no Rivet context fixture. Capture a fresh trace with the Rivet integration before replaying it.`, RIVET_DOCS_URL);
|
|
5863
3779
|
return fixture;
|
|
5864
3780
|
}
|
|
5865
3781
|
var BitfabRivetIntegration = class {
|
|
@@ -5870,7 +3786,7 @@ var BitfabRivetIntegration = class {
|
|
|
5870
3786
|
this.markedEffects = new Set(options.mockOnReplay ?? []);
|
|
5871
3787
|
}
|
|
5872
3788
|
withContext(context, fn) {
|
|
5873
|
-
if (!isRecord(context)) throw new BitfabError("Rivet withContext requires a context object");
|
|
3789
|
+
if (!isRecord(context)) throw new require_http.BitfabError("Rivet withContext requires a context object");
|
|
5874
3790
|
return runWithRivetContext({
|
|
5875
3791
|
context,
|
|
5876
3792
|
fixtureContext: createIntegrationFixtureContext(fixtureName(this.traceFunctionKey), snapshotContext(context)),
|
|
@@ -5884,7 +3800,7 @@ var BitfabRivetIntegration = class {
|
|
|
5884
3800
|
};
|
|
5885
3801
|
}
|
|
5886
3802
|
getContext() {
|
|
5887
|
-
const replay = getReplayContext();
|
|
3803
|
+
const replay = require_http.getReplayContext();
|
|
5888
3804
|
if (replay) {
|
|
5889
3805
|
const existing = this.replayProxies.get(replay);
|
|
5890
3806
|
if (existing) return existing;
|
|
@@ -5893,13 +3809,13 @@ var BitfabRivetIntegration = class {
|
|
|
5893
3809
|
return proxy;
|
|
5894
3810
|
}
|
|
5895
3811
|
const binding = getRivetContextBinding();
|
|
5896
|
-
if (!binding) throw new BitfabError("No Rivet context is bound. Call rivet.bind(handler) or rivet.withContext(context, callback) at the Rivet boundary.", RIVET_DOCS_URL);
|
|
3812
|
+
if (!binding) throw new require_http.BitfabError("No Rivet context is bound. Call rivet.bind(handler) or rivet.withContext(context, callback) at the Rivet boundary.", RIVET_DOCS_URL);
|
|
5897
3813
|
this.runtime.recordRootFixture(binding.fixtureContext, binding.recordedRoots);
|
|
5898
3814
|
if (!binding.proxy) binding.proxy = this.createContextProxy(binding.context, binding);
|
|
5899
3815
|
return binding.proxy;
|
|
5900
3816
|
}
|
|
5901
3817
|
createContextProxy(target, binding) {
|
|
5902
|
-
const replay = getReplayContext();
|
|
3818
|
+
const replay = require_http.getReplayContext();
|
|
5903
3819
|
const dbProxy = this.createDbProxy(binding, replay);
|
|
5904
3820
|
const groupProxies = /* @__PURE__ */ new Map();
|
|
5905
3821
|
for (const group of Object.keys(RIVET_GROUP_EFFECT_METHODS)) if (group !== "db") groupProxies.set(group, this.createGroupProxy(group, binding, replay));
|
|
@@ -5963,7 +3879,7 @@ var BitfabRivetIntegration = class {
|
|
|
5963
3879
|
createEffect(effect, targetProvider, methodName, replay) {
|
|
5964
3880
|
const marked = this.markedEffects.has(effect);
|
|
5965
3881
|
const invoke = (...args) => {
|
|
5966
|
-
assertReplayEffectAvailable(getReplayContext(), this.traceFunctionKey, effect, marked);
|
|
3882
|
+
assertReplayEffectAvailable(require_http.getReplayContext(), this.traceFunctionKey, effect, marked);
|
|
5967
3883
|
const target = targetProvider();
|
|
5968
3884
|
const method = target ? readProperty(target, methodName) : void 0;
|
|
5969
3885
|
if (typeof method !== "function") throw unavailableCapability(effect);
|
|
@@ -5981,7 +3897,7 @@ var BitfabRivetIntegration = class {
|
|
|
5981
3897
|
}
|
|
5982
3898
|
createTransaction(binding, replay) {
|
|
5983
3899
|
return async (callback, options) => {
|
|
5984
|
-
if (typeof callback !== "function") throw new BitfabError("Rivet db.transaction requires a callback");
|
|
3900
|
+
if (typeof callback !== "function") throw new require_http.BitfabError("Rivet db.transaction requires a callback");
|
|
5985
3901
|
if (replay) return await callback(this.createMethodProxy(() => void 0, "db.transaction", ["execute"], replay));
|
|
5986
3902
|
const context = binding?.context;
|
|
5987
3903
|
const db = context ? readProperty(context, "db") : void 0;
|
|
@@ -6202,7 +4118,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
6202
4118
|
this.startedSpans = /* @__PURE__ */ new Map();
|
|
6203
4119
|
this.endedTraces = /* @__PURE__ */ new Set();
|
|
6204
4120
|
this.ownsHttpClient = config._httpClient === void 0;
|
|
6205
|
-
this.httpClient = config._httpClient ?? new HttpClient({
|
|
4121
|
+
this.httpClient = config._httpClient ?? new require_http.HttpClient({
|
|
6206
4122
|
apiKey: config.apiKey,
|
|
6207
4123
|
serviceUrl: config.serviceUrl ?? "https://bitfab.ai",
|
|
6208
4124
|
timeout: config.timeout ?? 1e4
|
|
@@ -6348,7 +4264,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
6348
4264
|
}
|
|
6349
4265
|
}
|
|
6350
4266
|
buildSpanPayload(serializedSpan, errors) {
|
|
6351
|
-
serializedSpan.span_origin = makeSpanOrigin("openai-agents");
|
|
4267
|
+
serializedSpan.span_origin = require_http.makeSpanOrigin("openai-agents");
|
|
6352
4268
|
const payload = {
|
|
6353
4269
|
id: randomUuid(),
|
|
6354
4270
|
type: "openai",
|
|
@@ -6550,7 +4466,7 @@ function markTracedFunction(target, traceFunctionKey, original) {
|
|
|
6550
4466
|
}
|
|
6551
4467
|
function resolveSpanExperimentId(options) {
|
|
6552
4468
|
const { experimentId, testRunId } = options;
|
|
6553
|
-
if (experimentId !== void 0 && testRunId !== void 0 && experimentId !== testRunId) throw new BitfabError(`experimentId ("${experimentId}") and its deprecated alias testRunId ("${testRunId}") were both passed with different values. Pass only experimentId.`);
|
|
4469
|
+
if (experimentId !== void 0 && testRunId !== void 0 && experimentId !== testRunId) throw new require_http.BitfabError(`experimentId ("${experimentId}") and its deprecated alias testRunId ("${testRunId}") were both passed with different values. Pass only experimentId.`);
|
|
6554
4470
|
return experimentId ?? testRunId;
|
|
6555
4471
|
}
|
|
6556
4472
|
const TRUNCATION_LIMIT_ORDER = ["max_depth", "max_captured_subtree_spans"];
|
|
@@ -6566,7 +4482,7 @@ function rootTraceFunctionKeyOfTrace(traceId, fallback) {
|
|
|
6566
4482
|
return activeTraceStates.get(traceId)?.traceFunctionKey ?? fallback;
|
|
6567
4483
|
}
|
|
6568
4484
|
function rootTraceFunctionKeyOf(payload) {
|
|
6569
|
-
const captured = payload[ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
4485
|
+
const captured = payload[require_http.ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
6570
4486
|
if (typeof captured === "string") return captured;
|
|
6571
4487
|
const traceId = payload.traceId;
|
|
6572
4488
|
const live = typeof traceId === "string" ? activeTraceStates.get(traceId)?.traceFunctionKey : void 0;
|
|
@@ -6676,13 +4592,10 @@ function wrapAsyncGenerator(source, spanStack, sendSpan) {
|
|
|
6676
4592
|
let cachedCollectorClass;
|
|
6677
4593
|
async function loadCollectorClass() {
|
|
6678
4594
|
if (cachedCollectorClass !== void 0) return cachedCollectorClass;
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
cachedCollectorClass = null;
|
|
6684
|
-
return null;
|
|
6685
|
-
}
|
|
4595
|
+
const baml = await require_bamlPeer.loadBamlModule();
|
|
4596
|
+
if (!baml) return null;
|
|
4597
|
+
cachedCollectorClass = baml.Collector;
|
|
4598
|
+
return cachedCollectorClass;
|
|
6686
4599
|
}
|
|
6687
4600
|
function extractPromptFromCollector(collector) {
|
|
6688
4601
|
try {
|
|
@@ -6732,7 +4645,7 @@ function extractContextFromCollector(collector) {
|
|
|
6732
4645
|
}
|
|
6733
4646
|
}
|
|
6734
4647
|
function isSpanType(value) {
|
|
6735
|
-
return SPAN_TYPES.some((spanType) => spanType === value);
|
|
4648
|
+
return require_http.SPAN_TYPES.some((spanType) => spanType === value);
|
|
6736
4649
|
}
|
|
6737
4650
|
const noOpSpan = {
|
|
6738
4651
|
id: "",
|
|
@@ -6769,7 +4682,7 @@ function getCurrentSpan() {
|
|
|
6769
4682
|
};
|
|
6770
4683
|
}
|
|
6771
4684
|
function getCurrentReplayBranch() {
|
|
6772
|
-
const ctx = getReplayContext();
|
|
4685
|
+
const ctx = require_http.getReplayContext();
|
|
6773
4686
|
if (!ctx?.dbBranchLease) return null;
|
|
6774
4687
|
const traceId = ctx.sourceBitfabTraceId ?? ctx.inputSourceTraceId;
|
|
6775
4688
|
if (!traceId) return null;
|
|
@@ -6808,7 +4721,7 @@ function getCurrentTrace() {
|
|
|
6808
4721
|
setMetadata(metadata) {
|
|
6809
4722
|
try {
|
|
6810
4723
|
if (typeof metadata !== "object" || metadata === null) return;
|
|
6811
|
-
recordCallerTraceMetadata(traceId, metadata);
|
|
4724
|
+
require_http.recordCallerTraceMetadata(traceId, metadata);
|
|
6812
4725
|
} catch {}
|
|
6813
4726
|
},
|
|
6814
4727
|
addContext(context) {
|
|
@@ -6885,12 +4798,12 @@ var Bitfab = class {
|
|
|
6885
4798
|
if (config.dbSnapshot) validateDbSnapshotConfig(config.dbSnapshot);
|
|
6886
4799
|
this.dbSnapshot = config.dbSnapshot;
|
|
6887
4800
|
startCommitRefResolution();
|
|
6888
|
-
this.httpClient = new HttpClient({
|
|
4801
|
+
this.httpClient = new require_http.HttpClient({
|
|
6889
4802
|
apiKey: () => this.resolveApiKey(),
|
|
6890
4803
|
serviceUrl: this.serviceUrl,
|
|
6891
4804
|
timeout: this.timeout
|
|
6892
4805
|
});
|
|
6893
|
-
this.simulationPlan = new SimulationPlan({
|
|
4806
|
+
this.simulationPlan = new require_http.SimulationPlan({
|
|
6894
4807
|
getSimulationPlan: () => this.httpClient.getSimulationPlan(),
|
|
6895
4808
|
canRead: () => this.canReadSimulationPlan()
|
|
6896
4809
|
}, config.simulationPlan ?? true);
|
|
@@ -6914,13 +4827,13 @@ var Bitfab = class {
|
|
|
6914
4827
|
if (args.length === 3) {
|
|
6915
4828
|
const propertyKey = args[1];
|
|
6916
4829
|
const descriptor = args[2];
|
|
6917
|
-
if (!descriptor || typeof descriptor.value !== "function") throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
4830
|
+
if (!descriptor || typeof descriptor.value !== "function") throw new require_http.BitfabError("@bitfab.trace can only decorate methods");
|
|
6918
4831
|
descriptor.value = this.createAutoTraceRoot(traceFunctionKey, String(propertyKey), options, descriptor.value);
|
|
6919
4832
|
return;
|
|
6920
4833
|
}
|
|
6921
4834
|
const method = args[0];
|
|
6922
4835
|
const context = args[1];
|
|
6923
|
-
if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
4836
|
+
if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) throw new require_http.BitfabError("@bitfab.trace can only decorate methods");
|
|
6924
4837
|
return this.createAutoTraceRoot(traceFunctionKey, String(context.name), options, method);
|
|
6925
4838
|
};
|
|
6926
4839
|
return decorator;
|
|
@@ -6928,7 +4841,7 @@ var Bitfab = class {
|
|
|
6928
4841
|
withTrace(traceFunctionKey, optionsOrFn, maybeFn) {
|
|
6929
4842
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
6930
4843
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6931
|
-
if (!fn) throw new BitfabError("bitfab.withTrace requires a function");
|
|
4844
|
+
if (!fn) throw new require_http.BitfabError("bitfab.withTrace requires a function");
|
|
6932
4845
|
const name = fn.name !== "" ? fn.name : traceFunctionKey;
|
|
6933
4846
|
return this.createAutoTraceRoot(traceFunctionKey, name, options, fn, AUTO_TRACE_NODE_FUNCTION_NAMES.get(fn) ?? fn.name.replace(/^bound /, ""));
|
|
6934
4847
|
}
|
|
@@ -6937,13 +4850,13 @@ var Bitfab = class {
|
|
|
6937
4850
|
const decorator = (...args) => {
|
|
6938
4851
|
if (args.length === 3) {
|
|
6939
4852
|
const descriptor = args[2];
|
|
6940
|
-
if (!descriptor || typeof descriptor.value !== "function") throw new BitfabError("@bitfab.node can only decorate methods");
|
|
4853
|
+
if (!descriptor || typeof descriptor.value !== "function") throw new require_http.BitfabError("@bitfab.node can only decorate methods");
|
|
6941
4854
|
descriptor.value = this.createAutoTraceNode(configuration, descriptor.value, String(args[1]));
|
|
6942
4855
|
return;
|
|
6943
4856
|
}
|
|
6944
4857
|
const method = args[0];
|
|
6945
4858
|
const context = args[1];
|
|
6946
|
-
if (typeof method !== "function" || context?.kind !== "method") throw new BitfabError("@bitfab.node can only decorate methods");
|
|
4859
|
+
if (typeof method !== "function" || context?.kind !== "method") throw new require_http.BitfabError("@bitfab.node can only decorate methods");
|
|
6947
4860
|
return this.createAutoTraceNode(configuration, method, String(context.name));
|
|
6948
4861
|
};
|
|
6949
4862
|
return decorator;
|
|
@@ -6951,15 +4864,15 @@ var Bitfab = class {
|
|
|
6951
4864
|
withNode(optionsOrFn, maybeFn, internalFunctionName) {
|
|
6952
4865
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
6953
4866
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6954
|
-
if (!fn) throw new BitfabError("bitfab.withNode requires a function");
|
|
4867
|
+
if (!fn) throw new require_http.BitfabError("bitfab.withNode requires a function");
|
|
6955
4868
|
const configuration = this.resolveNodeConfiguration(options);
|
|
6956
4869
|
const functionName = internalFunctionName ?? fn.name;
|
|
6957
|
-
if (functionName === "") throw new BitfabError("bitfab.withNode requires a named function so the subtree transform can bind its configuration to the correct call.");
|
|
4870
|
+
if (functionName === "") throw new require_http.BitfabError("bitfab.withNode requires a named function so the subtree transform can bind its configuration to the correct call.");
|
|
6958
4871
|
return this.createAutoTraceNode(configuration, fn, functionName);
|
|
6959
4872
|
}
|
|
6960
4873
|
resolveNodeConfiguration(options) {
|
|
6961
4874
|
const capture = options.capture ?? true;
|
|
6962
|
-
if (!capture && options.mockOnReplay === true) throw new BitfabError("bitfab.node({ capture: false }) cannot use mockOnReplay: true because an uncaptured node has no recorded output.");
|
|
4875
|
+
if (!capture && options.mockOnReplay === true) throw new require_http.BitfabError("bitfab.node({ capture: false }) cannot use mockOnReplay: true because an uncaptured node has no recorded output.");
|
|
6963
4876
|
const experimentId = resolveSpanExperimentId(options);
|
|
6964
4877
|
return {
|
|
6965
4878
|
capture,
|
|
@@ -7103,7 +5016,7 @@ var Bitfab = class {
|
|
|
7103
5016
|
if (firstPlanRead !== void 0) return firstPlanRead.then(() => tracedRoot.apply(this, args));
|
|
7104
5017
|
return tracedRoot.apply(this, args);
|
|
7105
5018
|
}
|
|
7106
|
-
const link = getReplayContext() || inSeedScope() ? void 0 : { traceFunctionKey };
|
|
5019
|
+
const link = require_http.getReplayContext() || inSeedScope() ? void 0 : { traceFunctionKey };
|
|
7107
5020
|
const rootName = rootNameFor(this);
|
|
7108
5021
|
const spanDetails = { contexts: [] };
|
|
7109
5022
|
return require_autoTrace.invokeThroughAutoTraceEntries(enclosing, (entry, next) => entry.context.invokeNestedRoot(rootName, name, args, next, entry, link, spanDetails), () => {
|
|
@@ -7146,7 +5059,7 @@ var Bitfab = class {
|
|
|
7146
5059
|
resolveApiKey() {
|
|
7147
5060
|
const key = this.findApiKey(true);
|
|
7148
5061
|
if (key) return key;
|
|
7149
|
-
if (this.strict) throw new BitfabError("Bitfab: no API key resolved. Set BITFAB_API_KEY or pass apiKey to new Bitfab(). If a script loads env with dotenv, load it before the module that constructs the client is imported (e.g. `node --env-file=.env script.ts`), or pass `apiKey: () => process.env.BITFAB_API_KEY`.");
|
|
5062
|
+
if (this.strict) throw new require_http.BitfabError("Bitfab: no API key resolved. Set BITFAB_API_KEY or pass apiKey to new Bitfab(). If a script loads env with dotenv, load it before the module that constructs the client is imported (e.g. `node --env-file=.env script.ts`), or pass `apiKey: () => process.env.BITFAB_API_KEY`.");
|
|
7150
5063
|
if (this.isCaptureConfigured() && !this.apiKeyWarned) {
|
|
7151
5064
|
this.apiKeyWarned = true;
|
|
7152
5065
|
console.warn("Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing.");
|
|
@@ -7162,11 +5075,11 @@ var Bitfab = class {
|
|
|
7162
5075
|
return this.resolveApiKey() !== void 0;
|
|
7163
5076
|
}
|
|
7164
5077
|
shouldRecord() {
|
|
7165
|
-
if (!this.isCaptureConfigured() && !getReplayContext() && !inSeedScope()) return false;
|
|
5078
|
+
if (!this.isCaptureConfigured() && !require_http.getReplayContext() && !inSeedScope()) return false;
|
|
7166
5079
|
return this.resolveApiKey() !== void 0;
|
|
7167
5080
|
}
|
|
7168
5081
|
canReadSimulationPlan() {
|
|
7169
|
-
return ((this.captureConfiguredInCode ?? this.captureConfiguredFromEnv ?? readBooleanEnv(CAPTURE_ENABLED_ENV) ?? true) || getReplayContext() !== null || inSeedScope()) && this.findApiKey(true) !== void 0;
|
|
5082
|
+
return ((this.captureConfiguredInCode ?? this.captureConfiguredFromEnv ?? readBooleanEnv(CAPTURE_ENABLED_ENV) ?? true) || require_http.getReplayContext() !== null || inSeedScope()) && this.findApiKey(true) !== void 0;
|
|
7170
5083
|
}
|
|
7171
5084
|
prepareFrameworkIntegration() {
|
|
7172
5085
|
if (this.isCaptureConfigured() && this.strict) this.resolveApiKey();
|
|
@@ -7176,8 +5089,8 @@ var Bitfab = class {
|
|
|
7176
5089
|
}
|
|
7177
5090
|
async fetchFunctionVersion(methodName) {
|
|
7178
5091
|
const result = await this.httpClient.lookupFunction(methodName);
|
|
7179
|
-
if (result.id === null) throw new BitfabError(`Function "${methodName}" not found. Create it at: ${this.serviceUrl}/functions`, "/functions");
|
|
7180
|
-
if (!result.prompt) throw new BitfabError(`Function "${methodName}" has no prompt configured. Add one at: ${this.serviceUrl}/functions/${result.id}`, `/functions/${result.id}`);
|
|
5092
|
+
if (result.id === null) throw new require_http.BitfabError(`Function "${methodName}" not found. Create it at: ${this.serviceUrl}/functions`, "/functions");
|
|
5093
|
+
if (!result.prompt) throw new require_http.BitfabError(`Function "${methodName}" has no prompt configured. Add one at: ${this.serviceUrl}/functions/${result.id}`, `/functions/${result.id}`);
|
|
7181
5094
|
return result;
|
|
7182
5095
|
}
|
|
7183
5096
|
async call(methodName, inputs = {}) {
|
|
@@ -7200,9 +5113,9 @@ var Bitfab = class {
|
|
|
7200
5113
|
});
|
|
7201
5114
|
return executionResult.result;
|
|
7202
5115
|
} catch (error) {
|
|
7203
|
-
if (error instanceof BitfabError) throw error;
|
|
7204
|
-
if (error instanceof Error) throw new BitfabError(error.message);
|
|
7205
|
-
throw new BitfabError("Unknown error occurred during local execution");
|
|
5116
|
+
if (error instanceof require_http.BitfabError) throw error;
|
|
5117
|
+
if (error instanceof Error) throw new require_http.BitfabError(error.message);
|
|
5118
|
+
throw new require_http.BitfabError("Unknown error occurred during local execution");
|
|
7206
5119
|
}
|
|
7207
5120
|
}
|
|
7208
5121
|
getOpenAiTracingProcessor() {
|
|
@@ -7318,14 +5231,15 @@ var Bitfab = class {
|
|
|
7318
5231
|
bamlClient = this.bamlClient;
|
|
7319
5232
|
method = methodOrClient;
|
|
7320
5233
|
options = maybeMethodOrOptions;
|
|
7321
|
-
if (!bamlClient) throw new BitfabError("bamlClient is required for wrapBAML. Pass it in the constructor or as the first argument.");
|
|
5234
|
+
if (!bamlClient) throw new require_http.BitfabError("bamlClient is required for wrapBAML. Pass it in the constructor or as the first argument.");
|
|
7322
5235
|
}
|
|
7323
5236
|
const methodName = method.name;
|
|
7324
|
-
if (!methodName) throw new BitfabError("wrapBAML requires a named function (e.g., b.ClassifyText).");
|
|
5237
|
+
if (!methodName) throw new require_http.BitfabError("wrapBAML requires a named function (e.g., b.ClassifyText).");
|
|
7325
5238
|
loadCollectorClass();
|
|
7326
5239
|
const wrappedFn = async (...args) => {
|
|
7327
5240
|
const CollectorClass = await loadCollectorClass();
|
|
7328
5241
|
if (!CollectorClass) {
|
|
5242
|
+
require_autoTrace.warnOnce("wrapBAML-collector-unavailable", `@boundaryml/baml could not be loaded, so "${methodName}" and every other wrapBAML call run untraced: no prompt, model, or token usage is recorded and onCollector is not called. If @boundaryml/baml is installed and your app is bundled (Next.js with Turbopack, for example), add \`import "@bitfab/sdk/baml"\` once in your server code.`);
|
|
7329
5243
|
wrappedFn.collector = null;
|
|
7330
5244
|
return await bamlClient[methodName](...args);
|
|
7331
5245
|
}
|
|
@@ -7335,7 +5249,7 @@ var Bitfab = class {
|
|
|
7335
5249
|
try {
|
|
7336
5250
|
trackedClient = bamlClient.withOptions({ collector });
|
|
7337
5251
|
const method = trackedClient[methodName];
|
|
7338
|
-
if (typeof method !== "function") throw new BitfabError("bamlClient.withOptions did not return the wrapped method");
|
|
5252
|
+
if (typeof method !== "function") throw new require_http.BitfabError("bamlClient.withOptions did not return the wrapped method");
|
|
7339
5253
|
trackedMethod = method;
|
|
7340
5254
|
} catch {
|
|
7341
5255
|
require_autoTrace.warnOnce(`wrapBAML-setup:${methodName}`, `BAML tracing setup failed for "${methodName}" (incompatible bamlClient or BAML version); calling it untraced. The call still runs; no span is recorded.`);
|
|
@@ -7392,7 +5306,7 @@ var Bitfab = class {
|
|
|
7392
5306
|
try {
|
|
7393
5307
|
hasParent = getSpanStack().length > 0;
|
|
7394
5308
|
} catch (setupError) {
|
|
7395
|
-
if (getReplayContext()) throw setupError;
|
|
5309
|
+
if (require_http.getReplayContext()) throw setupError;
|
|
7396
5310
|
require_autoTrace.warnOnce(`withSpan-setup:${traceFunctionKey}`, `tracing setup failed for "${traceFunctionKey}"; running it untraced. The function still runs and returns normally; no span is recorded.`);
|
|
7397
5311
|
return fn.apply(this, args);
|
|
7398
5312
|
}
|
|
@@ -7405,7 +5319,7 @@ var Bitfab = class {
|
|
|
7405
5319
|
try {
|
|
7406
5320
|
const currentStack = getSpanStack();
|
|
7407
5321
|
const parentContext = currentStack[currentStack.length - 1];
|
|
7408
|
-
const replayCtxForTraceId = parentContext ? null : getReplayContext();
|
|
5322
|
+
const replayCtxForTraceId = parentContext ? null : require_http.getReplayContext();
|
|
7409
5323
|
const seedCtxForTraceId = parentContext ? null : getSeedContext();
|
|
7410
5324
|
const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
|
|
7411
5325
|
const spanId = randomUuid();
|
|
@@ -7436,7 +5350,7 @@ var Bitfab = class {
|
|
|
7436
5350
|
newStack = [...currentStack, newContext];
|
|
7437
5351
|
const inputs = args;
|
|
7438
5352
|
const startedAt = nowIsoTimestamp();
|
|
7439
|
-
const replayCtxAtStart = getReplayContext();
|
|
5353
|
+
const replayCtxAtStart = require_http.getReplayContext();
|
|
7440
5354
|
const experimentId = replayCtxAtStart?.experimentId ?? optionExperimentId;
|
|
7441
5355
|
if (isRootSpan && !activeTraceStates.has(traceId)) {
|
|
7442
5356
|
const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
|
|
@@ -7481,7 +5395,7 @@ var Bitfab = class {
|
|
|
7481
5395
|
enclosingTrace: options.enclosingTrace
|
|
7482
5396
|
};
|
|
7483
5397
|
const sendSpan = async (params) => {
|
|
7484
|
-
const replayCtx = getReplayContext();
|
|
5398
|
+
const replayCtx = require_http.getReplayContext();
|
|
7485
5399
|
try {
|
|
7486
5400
|
const endedAt = nowIsoTimestamp();
|
|
7487
5401
|
if (!(activeTraceStates.get(traceId)?.dropped === true)) self.sendWrapperSpan({
|
|
@@ -7496,7 +5410,7 @@ var Bitfab = class {
|
|
|
7496
5410
|
if (isRootSpan) {
|
|
7497
5411
|
const traceState = activeTraceStates.get(traceId);
|
|
7498
5412
|
const truncated = truncationMetadata(traceState?.truncation);
|
|
7499
|
-
if (truncated !== void 0) recordCallerTraceMetadata(traceId, truncated);
|
|
5413
|
+
if (truncated !== void 0) require_http.recordCallerTraceMetadata(traceId, truncated);
|
|
7500
5414
|
self.sendTraceCompletion({
|
|
7501
5415
|
traceFunctionKey,
|
|
7502
5416
|
traceId,
|
|
@@ -7504,7 +5418,7 @@ var Bitfab = class {
|
|
|
7504
5418
|
endedAt,
|
|
7505
5419
|
sessionId: traceState?.sessionId,
|
|
7506
5420
|
name: traceState?.name,
|
|
7507
|
-
metadata: callerTraceMetadata(traceId),
|
|
5421
|
+
metadata: require_http.callerTraceMetadata(traceId),
|
|
7508
5422
|
contexts: traceState?.contexts ?? [],
|
|
7509
5423
|
experimentId: traceState?.experimentId,
|
|
7510
5424
|
inputSourceTraceId: traceState?.inputSourceTraceId,
|
|
@@ -7522,7 +5436,7 @@ var Bitfab = class {
|
|
|
7522
5436
|
} }
|
|
7523
5437
|
});
|
|
7524
5438
|
activeTraceStates.delete(traceId);
|
|
7525
|
-
retireTraceMetadata(traceId);
|
|
5439
|
+
require_http.retireTraceMetadata(traceId);
|
|
7526
5440
|
}
|
|
7527
5441
|
} catch {} finally {
|
|
7528
5442
|
self.httpClient.traceCompletion.end(traceId, spanId);
|
|
@@ -7568,7 +5482,7 @@ var Bitfab = class {
|
|
|
7568
5482
|
recordSpan(result);
|
|
7569
5483
|
return result;
|
|
7570
5484
|
};
|
|
7571
|
-
const replayCtxForMock = getReplayContext();
|
|
5485
|
+
const replayCtxForMock = require_http.getReplayContext();
|
|
7572
5486
|
if (replayCtxForMock?.selectiveReplay) {
|
|
7573
5487
|
const decision = replayCtxForMock.selectiveReplay.enter({
|
|
7574
5488
|
traceFunctionKey,
|
|
@@ -7608,7 +5522,7 @@ var Bitfab = class {
|
|
|
7608
5522
|
return output;
|
|
7609
5523
|
};
|
|
7610
5524
|
const emitMockAsync = (pending, mockSource) => {
|
|
7611
|
-
if (!fnReturnsPromise) throw new BitfabError(`Cannot mock synchronous span "${traceFunctionKey}" with an asynchronously-resolved value (lazy recorded-output fetch or an async value function). Make the wrapped function async, or use mock: "all" so recorded outputs are fetched eagerly.`);
|
|
5525
|
+
if (!fnReturnsPromise) throw new require_http.BitfabError(`Cannot mock synchronous span "${traceFunctionKey}" with an asynchronously-resolved value (lazy recorded-output fetch or an async value function). Make the wrapped function async, or use mock: "all" so recorded outputs are fetched eagerly.`);
|
|
7612
5526
|
return (async () => {
|
|
7613
5527
|
const output = await resolveMockOrAbort(() => pending);
|
|
7614
5528
|
sendSpan({
|
|
@@ -7622,7 +5536,7 @@ var Bitfab = class {
|
|
|
7622
5536
|
};
|
|
7623
5537
|
const resolveRecordedOutput = () => {
|
|
7624
5538
|
if (!(mockSpan?.output !== void 0 || mockSpan?.outputMeta !== void 0) && replayCtxForMock.fetchSpanOutput && mockSpan?.externalSpanId) return replayCtxForMock.fetchSpanOutput(mockSpan.externalSpanId);
|
|
7625
|
-
if (!mockSpan) return Promise.reject(new BitfabError(`No recorded span to source output for "${traceFunctionKey}".`));
|
|
5539
|
+
if (!mockSpan) return Promise.reject(new require_http.BitfabError(`No recorded span to source output for "${traceFunctionKey}".`));
|
|
7626
5540
|
let output = mockSpan.output;
|
|
7627
5541
|
if (mockSpan.outputMeta !== void 0 && mockSpan.outputMeta !== null) output = deserializeValue({
|
|
7628
5542
|
json: mockSpan.output,
|
|
@@ -7662,7 +5576,7 @@ var Bitfab = class {
|
|
|
7662
5576
|
};
|
|
7663
5577
|
const resolution = resolveOverrideFrom(0);
|
|
7664
5578
|
if (resolution instanceof Promise) {
|
|
7665
|
-
if (!fnReturnsPromise) throw new BitfabError(`Cannot resolve an asynchronous mock override for synchronous span "${traceFunctionKey}". Make the wrapped function async or return NO_MOCK_OVERRIDE synchronously.`);
|
|
5579
|
+
if (!fnReturnsPromise) throw new require_http.BitfabError(`Cannot resolve an asynchronous mock override for synchronous span "${traceFunctionKey}". Make the wrapped function async or return NO_MOCK_OVERRIDE synchronously.`);
|
|
7666
5580
|
return runWithSpanStack(newStack, async () => {
|
|
7667
5581
|
const resolved = await resolveMockOrAbort(() => resolution);
|
|
7668
5582
|
if (resolved.matched) {
|
|
@@ -7674,7 +5588,7 @@ var Bitfab = class {
|
|
|
7674
5588
|
});
|
|
7675
5589
|
return resolved.output;
|
|
7676
5590
|
}
|
|
7677
|
-
if (shouldMockWithBaseStrategy && !mockSpan) throw new BitfabError(`Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`);
|
|
5591
|
+
if (shouldMockWithBaseStrategy && !mockSpan) throw new require_http.BitfabError(`Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`);
|
|
7678
5592
|
if (shouldMockWithBaseStrategy) {
|
|
7679
5593
|
const output = await resolveMockOrAbort(() => resolveBaseOutput());
|
|
7680
5594
|
sendSpan({
|
|
@@ -7690,7 +5604,7 @@ var Bitfab = class {
|
|
|
7690
5604
|
}
|
|
7691
5605
|
if (resolution.matched) return emitMock(resolution.output, "override");
|
|
7692
5606
|
}
|
|
7693
|
-
if (shouldMockWithBaseStrategy && !mockSpan) throw new BitfabError(`Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`);
|
|
5607
|
+
if (shouldMockWithBaseStrategy && !mockSpan) throw new require_http.BitfabError(`Replay selected span "${traceFunctionKey}:${baseSpanParams.spanName}" for mocking, but recorded occurrence ${callIndex + 1} is unavailable. The real span was not executed.`);
|
|
7694
5608
|
if (shouldMockWithBaseStrategy) {
|
|
7695
5609
|
const recorded = resolveBaseOutput();
|
|
7696
5610
|
if (recorded instanceof Promise) return emitMockAsync(recorded, "recorded");
|
|
@@ -7701,10 +5615,10 @@ var Bitfab = class {
|
|
|
7701
5615
|
if (startedSpan) self.httpClient.traceCompletion.abort(startedSpan.traceId, startedSpan.spanId);
|
|
7702
5616
|
if (registeredTraceId) {
|
|
7703
5617
|
activeTraceStates.delete(registeredTraceId);
|
|
7704
|
-
retireTraceMetadata(registeredTraceId);
|
|
5618
|
+
require_http.retireTraceMetadata(registeredTraceId);
|
|
7705
5619
|
}
|
|
7706
|
-
if (setupError instanceof MixedTracingError) throw setupError;
|
|
7707
|
-
if (getReplayContext() || inSeedScope()) throw setupError;
|
|
5620
|
+
if (setupError instanceof require_http.MixedTracingError) throw setupError;
|
|
5621
|
+
if (require_http.getReplayContext() || inSeedScope()) throw setupError;
|
|
7708
5622
|
require_autoTrace.warnOnce(`withSpan-setup:${traceFunctionKey}`, `tracing setup failed for "${traceFunctionKey}"; running it untraced. The function still runs and returns normally; no span is recorded.`);
|
|
7709
5623
|
return fn.apply(this, args);
|
|
7710
5624
|
}
|
|
@@ -7714,7 +5628,7 @@ var Bitfab = class {
|
|
|
7714
5628
|
}
|
|
7715
5629
|
span(traceFunctionKey, options = {}) {
|
|
7716
5630
|
return (originalMethod, context) => {
|
|
7717
|
-
if (context.kind !== "method") throw new BitfabError(`Bitfab span decorators can only decorate methods; ${String(context.name)} is a ${context.kind}`);
|
|
5631
|
+
if (context.kind !== "method") throw new require_http.BitfabError(`Bitfab span decorators can only decorate methods; ${String(context.name)} is a ${context.kind}`);
|
|
7718
5632
|
return this.withSpan(traceFunctionKey, options, originalMethod);
|
|
7719
5633
|
};
|
|
7720
5634
|
}
|
|
@@ -7743,18 +5657,18 @@ var Bitfab = class {
|
|
|
7743
5657
|
async getTraceSpan(traceId, lookup) {
|
|
7744
5658
|
validateTraceId(traceId);
|
|
7745
5659
|
const hasId = lookup.id !== void 0;
|
|
7746
|
-
if (hasId === (lookup.name !== void 0 || lookup.type !== void 0)) throw new BitfabError("Provide id, or name and/or type");
|
|
5660
|
+
if (hasId === (lookup.name !== void 0 || lookup.type !== void 0)) throw new require_http.BitfabError("Provide id, or name and/or type");
|
|
7747
5661
|
if (hasId) validateSpanId(lookup.id);
|
|
7748
5662
|
else {
|
|
7749
|
-
if (lookup.name !== void 0 && lookup.name.length === 0) throw new BitfabError("name must be a non-empty string");
|
|
7750
|
-
if (lookup.type !== void 0 && !isSpanType(lookup.type)) throw new BitfabError(`type must be one of ${SPAN_TYPES.join(", ")}`);
|
|
5663
|
+
if (lookup.name !== void 0 && lookup.name.length === 0) throw new require_http.BitfabError("name must be a non-empty string");
|
|
5664
|
+
if (lookup.type !== void 0 && !isSpanType(lookup.type)) throw new require_http.BitfabError(`type must be one of ${require_http.SPAN_TYPES.join(", ")}`);
|
|
7751
5665
|
const occurrence = lookup.occurrence ?? "last";
|
|
7752
|
-
if (occurrence !== "first" && occurrence !== "last" && (!Number.isInteger(occurrence) || occurrence < 0)) throw new BitfabError("occurrence must be \"first\", \"last\", or a non-negative integer");
|
|
5666
|
+
if (occurrence !== "first" && occurrence !== "last" && (!Number.isInteger(occurrence) || occurrence < 0)) throw new require_http.BitfabError("occurrence must be \"first\", \"last\", or a non-negative integer");
|
|
7753
5667
|
}
|
|
7754
5668
|
return this.httpClient.getTraceSpan(traceId, lookup);
|
|
7755
5669
|
}
|
|
7756
5670
|
async getSpan(spanId) {
|
|
7757
|
-
if (typeof spanId !== "string" || spanId.trim().length === 0) throw new BitfabError("spanId must be a non-empty string");
|
|
5671
|
+
if (typeof spanId !== "string" || spanId.trim().length === 0) throw new require_http.BitfabError("spanId must be a non-empty string");
|
|
7758
5672
|
return this.httpClient.getSpan(spanId);
|
|
7759
5673
|
}
|
|
7760
5674
|
getFunction(traceFunctionKey) {
|
|
@@ -7796,11 +5710,11 @@ var Bitfab = class {
|
|
|
7796
5710
|
completed: true,
|
|
7797
5711
|
...params.dropped && { dropped: true },
|
|
7798
5712
|
...params.sessionId && { sessionId: params.sessionId },
|
|
7799
|
-
...params.experimentId !== void 0 && experimentIdWireFields(params.experimentId)
|
|
5713
|
+
...params.experimentId !== void 0 && require_http.experimentIdWireFields(params.experimentId)
|
|
7800
5714
|
});
|
|
7801
5715
|
}
|
|
7802
5716
|
sendsSpanOnCompletion(context) {
|
|
7803
|
-
return context.isRoot || context.declaredNode || isFrameworkInstrumentation(context.instrumentation) || !this.simulationPlan.contentOffNow(context.rootTraceFunctionKey, context.spanName);
|
|
5717
|
+
return context.isRoot || context.declaredNode || require_http.isFrameworkInstrumentation(context.instrumentation) || !this.simulationPlan.contentOffNow(context.rootTraceFunctionKey, context.spanName);
|
|
7804
5718
|
}
|
|
7805
5719
|
nearestCapturedAncestorSpanIdOf(stack) {
|
|
7806
5720
|
for (let index = stack.length - 1; index >= 0; index -= 1) {
|
|
@@ -7810,7 +5724,7 @@ var Bitfab = class {
|
|
|
7810
5724
|
return null;
|
|
7811
5725
|
}
|
|
7812
5726
|
contentOffBySimulationPlan(params) {
|
|
7813
|
-
if (params.rootTraceFunctionKey === void 0 || isFrameworkInstrumentation(params.instrumentation)) return false;
|
|
5727
|
+
if (params.rootTraceFunctionKey === void 0 || require_http.isFrameworkInstrumentation(params.instrumentation)) return false;
|
|
7814
5728
|
return this.simulationPlan.contentOffNow(params.rootTraceFunctionKey, params.spanName) || params.parentSpanId !== null && this.simulationPlan.unavailableNow();
|
|
7815
5729
|
}
|
|
7816
5730
|
sendWrapperSpan(params) {
|
|
@@ -7823,7 +5737,7 @@ var Bitfab = class {
|
|
|
7823
5737
|
trace_id: params.traceId,
|
|
7824
5738
|
started_at: params.startedAt,
|
|
7825
5739
|
ended_at: params.endedAt,
|
|
7826
|
-
span_origin: makeSpanOrigin(params.instrumentation),
|
|
5740
|
+
span_origin: require_http.makeSpanOrigin(params.instrumentation),
|
|
7827
5741
|
span_data: {
|
|
7828
5742
|
name: params.spanName,
|
|
7829
5743
|
...params.replayReusable !== void 0 && { replay_reusable: params.replayReusable },
|
|
@@ -7878,7 +5792,7 @@ var Bitfab = class {
|
|
|
7878
5792
|
...params.rootTraceFunctionKey !== void 0 && { ["rootTraceFunctionKey"]: params.rootTraceFunctionKey },
|
|
7879
5793
|
...params.declaredNode === true && { ["declaredNode"]: true },
|
|
7880
5794
|
rawSpan: externalSpan,
|
|
7881
|
-
...params.experimentId !== void 0 && experimentIdWireFields(params.experimentId),
|
|
5795
|
+
...params.experimentId !== void 0 && require_http.experimentIdWireFields(params.experimentId),
|
|
7882
5796
|
...params.mocked && { mocked: true },
|
|
7883
5797
|
...params.mockTarget && { mockTarget: params.mockTarget },
|
|
7884
5798
|
...params.mockSource && { mockSource: params.mockSource }
|
|
@@ -7888,7 +5802,7 @@ var Bitfab = class {
|
|
|
7888
5802
|
let override;
|
|
7889
5803
|
if (typeof overrideOrResolverOrMatch === "string") {
|
|
7890
5804
|
const keyedOverride = values[0];
|
|
7891
|
-
if (values.length !== 1 || keyedOverride === void 0) throw new BitfabError("registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override.");
|
|
5805
|
+
if (values.length !== 1 || keyedOverride === void 0) throw new require_http.BitfabError("registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override.");
|
|
7892
5806
|
if (typeof keyedOverride === "function") override = {
|
|
7893
5807
|
match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch,
|
|
7894
5808
|
value: keyedOverride
|
|
@@ -7897,7 +5811,7 @@ var Bitfab = class {
|
|
|
7897
5811
|
match: (node) => node.traceFunctionKey === overrideOrResolverOrMatch && keyedOverride.match(node),
|
|
7898
5812
|
value: keyedOverride.value
|
|
7899
5813
|
};
|
|
7900
|
-
else throw new BitfabError("registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override.");
|
|
5814
|
+
else throw new require_http.BitfabError("registerMockOverride(traceFunctionKey, override) requires a resolver function or { match, value } override.");
|
|
7901
5815
|
} else if (typeof overrideOrResolverOrMatch !== "function") override = overrideOrResolverOrMatch;
|
|
7902
5816
|
else if (values.length === 0) override = {
|
|
7903
5817
|
match: () => true,
|
|
@@ -7919,10 +5833,10 @@ var Bitfab = class {
|
|
|
7919
5833
|
seedTraceFromCase(traceFunctionKey, options) {
|
|
7920
5834
|
const { input } = options;
|
|
7921
5835
|
const fn = options.fn?._bitfabWrappedFn ?? options.fn;
|
|
7922
|
-
if (fn && input.length < fn.length) throw new BitfabError(`Seeded case supplies ${input.length} argument(s) but ${fn.name === "" ? "the function" : fn.name} requires ${fn.length}. Fix the case, or omit fn to seed it anyway.`);
|
|
5836
|
+
if (fn && input.length < fn.length) throw new require_http.BitfabError(`Seeded case supplies ${input.length} argument(s) but ${fn.name === "" ? "the function" : fn.name} requires ${fn.length}. Fix the case, or omit fn to seed it anyway.`);
|
|
7923
5837
|
const traceId = randomUuid();
|
|
7924
5838
|
const startedAt = nowIsoTimestamp();
|
|
7925
|
-
if (options.metadata !== void 0) recordCallerTraceMetadata(traceId, options.metadata);
|
|
5839
|
+
if (options.metadata !== void 0) require_http.recordCallerTraceMetadata(traceId, options.metadata);
|
|
7926
5840
|
activeTraceStates.set(traceId, {
|
|
7927
5841
|
traceId,
|
|
7928
5842
|
traceFunctionKey,
|
|
@@ -7955,13 +5869,13 @@ var Bitfab = class {
|
|
|
7955
5869
|
endedAt: startedAt,
|
|
7956
5870
|
sessionId: options.sessionId,
|
|
7957
5871
|
name: options.name,
|
|
7958
|
-
metadata: callerTraceMetadata(traceId),
|
|
5872
|
+
metadata: require_http.callerTraceMetadata(traceId),
|
|
7959
5873
|
contexts: [],
|
|
7960
5874
|
ingestionType: "seeded"
|
|
7961
5875
|
});
|
|
7962
5876
|
} finally {
|
|
7963
5877
|
activeTraceStates.delete(traceId);
|
|
7964
|
-
retireTraceMetadata(traceId);
|
|
5878
|
+
require_http.retireTraceMetadata(traceId);
|
|
7965
5879
|
}
|
|
7966
5880
|
return traceId;
|
|
7967
5881
|
}
|
|
@@ -7975,10 +5889,10 @@ var Bitfab = class {
|
|
|
7975
5889
|
surface: "neutral"
|
|
7976
5890
|
};
|
|
7977
5891
|
target = this.withSpan(traceFunctionKey, seedRootOptions, fn);
|
|
7978
|
-
} else if (wrappedKey !== traceFunctionKey) throw new BitfabError(`Function is wrapped with trace function key '${wrappedKey}' but seedTrace was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to seed it under the explicit key.`);
|
|
5892
|
+
} else if (wrappedKey !== traceFunctionKey) throw new require_http.BitfabError(`Function is wrapped with trace function key '${wrappedKey}' but seedTrace was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to seed it under the explicit key.`);
|
|
7979
5893
|
await seedContextReady;
|
|
7980
5894
|
const traceId = randomUuid();
|
|
7981
|
-
if (options?.metadata !== void 0) recordCallerTraceMetadata(traceId, options.metadata);
|
|
5895
|
+
if (options?.metadata !== void 0) require_http.recordCallerTraceMetadata(traceId, options.metadata);
|
|
7982
5896
|
activeTraceStates.set(traceId, {
|
|
7983
5897
|
traceId,
|
|
7984
5898
|
traceFunctionKey,
|
|
@@ -7994,19 +5908,19 @@ var Bitfab = class {
|
|
|
7994
5908
|
await runWithSeedContext({ traceId }, async () => target(...args));
|
|
7995
5909
|
} finally {
|
|
7996
5910
|
try {
|
|
7997
|
-
const { flushTraces } = await Promise.resolve().then(() => http_exports);
|
|
5911
|
+
const { flushTraces } = await Promise.resolve().then(() => require("./http-DX-fpUSu.cjs")).then((n) => n.http_exports);
|
|
7998
5912
|
await flushTraces(3e4);
|
|
7999
5913
|
} finally {
|
|
8000
5914
|
unrecorded = activeTraceStates.delete(traceId);
|
|
8001
|
-
retireTraceMetadata(traceId);
|
|
5915
|
+
require_http.retireTraceMetadata(traceId);
|
|
8002
5916
|
}
|
|
8003
5917
|
}
|
|
8004
|
-
if (unrecorded) throw new BitfabError(`seedTrace recorded nothing for '${traceFunctionKey}': the call finished without a root span. Check that an API key resolves (BITFAB_API_KEY or apiKey), and that fn is a regular or async function rather than a generator.`);
|
|
5918
|
+
if (unrecorded) throw new require_http.BitfabError(`seedTrace recorded nothing for '${traceFunctionKey}': the call finished without a root span. Check that an API key resolves (BITFAB_API_KEY or apiKey), and that fn is a regular or async function rather than a generator.`);
|
|
8005
5919
|
return traceId;
|
|
8006
5920
|
}
|
|
8007
5921
|
async reseedTrace(traceFunctionKey, fn, options) {
|
|
8008
5922
|
const source = await this.httpClient.getReseedSource(options.traceId);
|
|
8009
|
-
if (source.traceFunctionKey !== traceFunctionKey) throw new BitfabError(`Trace ${options.traceId} belongs to '${source.traceFunctionKey}', not '${traceFunctionKey}'.`);
|
|
5923
|
+
if (source.traceFunctionKey !== traceFunctionKey) throw new require_http.BitfabError(`Trace ${options.traceId} belongs to '${source.traceFunctionKey}', not '${traceFunctionKey}'.`);
|
|
8010
5924
|
const args = deserializeInputs({
|
|
8011
5925
|
input: source.input,
|
|
8012
5926
|
input_meta: source.inputMeta
|
|
@@ -8033,7 +5947,7 @@ var Bitfab = class {
|
|
|
8033
5947
|
surface: "neutral"
|
|
8034
5948
|
};
|
|
8035
5949
|
replayFn = this.withSpan(traceFunctionKey, replayRootOptions, fn);
|
|
8036
|
-
} else if (wrappedKey !== traceFunctionKey) throw new BitfabError(`Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`);
|
|
5950
|
+
} else if (wrappedKey !== traceFunctionKey) throw new require_http.BitfabError(`Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`);
|
|
8037
5951
|
const { replay: doReplay } = await Promise.resolve().then(() => replay_exports);
|
|
8038
5952
|
return doReplay(this.httpClient, this.serviceUrl, traceFunctionKey, replayFn, options, this.mockOverrides);
|
|
8039
5953
|
}
|
|
@@ -8053,7 +5967,7 @@ var BitfabFunction = class {
|
|
|
8053
5967
|
}
|
|
8054
5968
|
withTrace(optionsOrFn, maybeFn) {
|
|
8055
5969
|
if (typeof optionsOrFn === "function") return this.client.withTrace(this.traceFunctionKey, optionsOrFn);
|
|
8056
|
-
if (!maybeFn) throw new BitfabError("BitfabFunction.withTrace requires a function");
|
|
5970
|
+
if (!maybeFn) throw new require_http.BitfabError("BitfabFunction.withTrace requires a function");
|
|
8057
5971
|
return this.client.withTrace(this.traceFunctionKey, optionsOrFn, maybeFn);
|
|
8058
5972
|
}
|
|
8059
5973
|
trace(options = {}) {
|
|
@@ -8141,14 +6055,14 @@ const REGISTRATION_FIELDS = /* @__PURE__ */ new Set([
|
|
|
8141
6055
|
]);
|
|
8142
6056
|
function validateReplayRegistry(registry) {
|
|
8143
6057
|
for (const [pipeline, registration] of Object.entries(registry)) {
|
|
8144
|
-
if (typeof registration !== "object" || registration === null) throw new BitfabError(`Replay registry entry '${pipeline}' must be an object with client and fn.`);
|
|
6058
|
+
if (typeof registration !== "object" || registration === null) throw new require_http.BitfabError(`Replay registry entry '${pipeline}' must be an object with client and fn.`);
|
|
8145
6059
|
const unknownFields = Object.keys(registration).filter((field) => !REGISTRATION_FIELDS.has(field));
|
|
8146
6060
|
if (unknownFields.length > 0) require_autoTrace.warnOnce(`replay-registry-unknown-fields:${pipeline}:${unknownFields.join(",")}`, `Replay registry entry '${pipeline}' has unknown field(s): ${unknownFields.join(", ")}. They are ignored. An entry takes client, fn, traceFunctionKey, options, and optionsFactory. Put replay options such as adaptInputs, mock, and mockOverride inside options. A later SDK release will reject unknown fields.`);
|
|
8147
6061
|
}
|
|
8148
6062
|
}
|
|
8149
6063
|
async function reseedFromRegistry(registry, pipeline, traceIds) {
|
|
8150
6064
|
const registration = registry[pipeline];
|
|
8151
|
-
if (registration === void 0) throw new BitfabError(`Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`);
|
|
6065
|
+
if (registration === void 0) throw new require_http.BitfabError(`Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`);
|
|
8152
6066
|
const traceFunctionKey = resolveTraceFunctionKey(registration);
|
|
8153
6067
|
const reseeded = [];
|
|
8154
6068
|
for (const traceId of traceIds) reseeded.push(await registration.client.reseedTrace(traceFunctionKey, registration.fn, { traceId }));
|
|
@@ -8160,7 +6074,7 @@ async function reseedFromRegistry(registry, pipeline, traceIds) {
|
|
|
8160
6074
|
}
|
|
8161
6075
|
async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
8162
6076
|
const registration = registry[pipeline];
|
|
8163
|
-
if (registration === void 0) throw new BitfabError(`Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`);
|
|
6077
|
+
if (registration === void 0) throw new require_http.BitfabError(`Unknown pipeline '${pipeline}'. Registered: ${Object.keys(registry).join(", ")}`);
|
|
8164
6078
|
const traceFunctionKey = resolveTraceFunctionKey(registration);
|
|
8165
6079
|
if (options.run === true) {
|
|
8166
6080
|
const traceIds = [];
|
|
@@ -8182,7 +6096,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
|
8182
6096
|
metadata: seedCase.metadata,
|
|
8183
6097
|
sessionId: seedCase.sessionId
|
|
8184
6098
|
}));
|
|
8185
|
-
const { flushTraces } = await Promise.resolve().then(() => http_exports);
|
|
6099
|
+
const { flushTraces } = await Promise.resolve().then(() => require("./http-DX-fpUSu.cjs")).then((n) => n.http_exports);
|
|
8186
6100
|
await flushTraces(3e4);
|
|
8187
6101
|
return {
|
|
8188
6102
|
pipeline,
|
|
@@ -8193,7 +6107,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
|
8193
6107
|
function resolveTraceFunctionKey(registration) {
|
|
8194
6108
|
const wrappedKey = registration.fn._bitfabTraceFunctionKey;
|
|
8195
6109
|
const key = registration.traceFunctionKey ?? wrappedKey;
|
|
8196
|
-
if (key === void 0) throw new BitfabError("Replay registry entry uses a plain function. Set traceFunctionKey to the key its production handler records.");
|
|
6110
|
+
if (key === void 0) throw new require_http.BitfabError("Replay registry entry uses a plain function. Set traceFunctionKey to the key its production handler records.");
|
|
8197
6111
|
return key;
|
|
8198
6112
|
}
|
|
8199
6113
|
//#endregion
|
|
@@ -8233,12 +6147,6 @@ Object.defineProperty(exports, "BitfabClaudeAgentHandler", {
|
|
|
8233
6147
|
return BitfabClaudeAgentHandler;
|
|
8234
6148
|
}
|
|
8235
6149
|
});
|
|
8236
|
-
Object.defineProperty(exports, "BitfabError", {
|
|
8237
|
-
enumerable: true,
|
|
8238
|
-
get: function() {
|
|
8239
|
-
return BitfabError;
|
|
8240
|
-
}
|
|
8241
|
-
});
|
|
8242
6150
|
Object.defineProperty(exports, "BitfabFunction", {
|
|
8243
6151
|
enumerable: true,
|
|
8244
6152
|
get: function() {
|
|
@@ -8329,24 +6237,12 @@ Object.defineProperty(exports, "GradersClient", {
|
|
|
8329
6237
|
return GradersClient;
|
|
8330
6238
|
}
|
|
8331
6239
|
});
|
|
8332
|
-
Object.defineProperty(exports, "HttpClient", {
|
|
8333
|
-
enumerable: true,
|
|
8334
|
-
get: function() {
|
|
8335
|
-
return HttpClient;
|
|
8336
|
-
}
|
|
8337
|
-
});
|
|
8338
6240
|
Object.defineProperty(exports, "LabelsClient", {
|
|
8339
6241
|
enumerable: true,
|
|
8340
6242
|
get: function() {
|
|
8341
6243
|
return LabelsClient;
|
|
8342
6244
|
}
|
|
8343
6245
|
});
|
|
8344
|
-
Object.defineProperty(exports, "MixedTracingError", {
|
|
8345
|
-
enumerable: true,
|
|
8346
|
-
get: function() {
|
|
8347
|
-
return MixedTracingError;
|
|
8348
|
-
}
|
|
8349
|
-
});
|
|
8350
6246
|
Object.defineProperty(exports, "NO_MOCK_OVERRIDE", {
|
|
8351
6247
|
enumerable: true,
|
|
8352
6248
|
get: function() {
|
|
@@ -8383,12 +6279,6 @@ Object.defineProperty(exports, "TracesClient", {
|
|
|
8383
6279
|
return TracesClient;
|
|
8384
6280
|
}
|
|
8385
6281
|
});
|
|
8386
|
-
Object.defineProperty(exports, "__version__", {
|
|
8387
|
-
enumerable: true,
|
|
8388
|
-
get: function() {
|
|
8389
|
-
return __version__;
|
|
8390
|
-
}
|
|
8391
|
-
});
|
|
8392
6282
|
Object.defineProperty(exports, "defineReplayRegistry", {
|
|
8393
6283
|
enumerable: true,
|
|
8394
6284
|
get: function() {
|
|
@@ -8401,12 +6291,6 @@ Object.defineProperty(exports, "finalizers", {
|
|
|
8401
6291
|
return finalizers;
|
|
8402
6292
|
}
|
|
8403
6293
|
});
|
|
8404
|
-
Object.defineProperty(exports, "flushTraces", {
|
|
8405
|
-
enumerable: true,
|
|
8406
|
-
get: function() {
|
|
8407
|
-
return flushTraces;
|
|
8408
|
-
}
|
|
8409
|
-
});
|
|
8410
6294
|
Object.defineProperty(exports, "getCurrentReplayBranch", {
|
|
8411
6295
|
enumerable: true,
|
|
8412
6296
|
get: function() {
|
|
@@ -8450,4 +6334,4 @@ Object.defineProperty(exports, "serializeReplayResult", {
|
|
|
8450
6334
|
}
|
|
8451
6335
|
});
|
|
8452
6336
|
|
|
8453
|
-
//# sourceMappingURL=src-
|
|
6337
|
+
//# sourceMappingURL=src-BWZx-C1S.cjs.map
|