bitfab 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RMQX546G.js → chunk-53G5GR7B.js} +369 -12
- package/dist/chunk-53G5GR7B.js.map +1 -0
- package/dist/chunk-QT7HWOKU.js +131 -0
- package/dist/chunk-QT7HWOKU.js.map +1 -0
- package/dist/index.cjs +414 -394
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -2
- package/dist/index.d.ts +41 -2
- package/dist/index.js +6 -6
- package/dist/node.cjs +414 -394
- 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 +5 -5
- package/dist/{replay-LNP2K3DN.js → replay-WIBKB3BK.js} +52 -17
- package/dist/replay-WIBKB3BK.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-OW2EJK7T.js +0 -470
- package/dist/chunk-OW2EJK7T.js.map +0 -1
- package/dist/chunk-RMQX546G.js.map +0 -1
- package/dist/replay-LNP2K3DN.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -39,25 +39,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
));
|
|
40
40
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
41
41
|
|
|
42
|
-
// src/version.generated.ts
|
|
43
|
-
var __version__;
|
|
44
|
-
var init_version_generated = __esm({
|
|
45
|
-
"src/version.generated.ts"() {
|
|
46
|
-
"use strict";
|
|
47
|
-
__version__ = "0.14.0";
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// src/constants.ts
|
|
52
|
-
var DEFAULT_SERVICE_URL;
|
|
53
|
-
var init_constants = __esm({
|
|
54
|
-
"src/constants.ts"() {
|
|
55
|
-
"use strict";
|
|
56
|
-
init_version_generated();
|
|
57
|
-
DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
|
|
61
42
|
// src/errors.ts
|
|
62
43
|
var BitfabError;
|
|
63
44
|
var init_errors = __esm({
|
|
@@ -73,343 +54,6 @@ var init_errors = __esm({
|
|
|
73
54
|
}
|
|
74
55
|
});
|
|
75
56
|
|
|
76
|
-
// src/http.ts
|
|
77
|
-
function awaitOnExit(promise) {
|
|
78
|
-
pendingTracePromises.add(promise);
|
|
79
|
-
void promise.finally(() => {
|
|
80
|
-
pendingTracePromises.delete(promise);
|
|
81
|
-
}).catch(() => {
|
|
82
|
-
});
|
|
83
|
-
return promise;
|
|
84
|
-
}
|
|
85
|
-
async function flushTraces(timeoutMs = 5e3) {
|
|
86
|
-
if (pendingTracePromises.size === 0) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
await Promise.race([
|
|
90
|
-
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
91
|
-
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
92
|
-
]);
|
|
93
|
-
}
|
|
94
|
-
var pendingTracePromises, HttpClient;
|
|
95
|
-
var init_http = __esm({
|
|
96
|
-
"src/http.ts"() {
|
|
97
|
-
"use strict";
|
|
98
|
-
init_constants();
|
|
99
|
-
init_errors();
|
|
100
|
-
pendingTracePromises = /* @__PURE__ */ new Set();
|
|
101
|
-
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
102
|
-
let isFlushing = false;
|
|
103
|
-
process.on("beforeExit", () => {
|
|
104
|
-
if (pendingTracePromises.size > 0 && !isFlushing) {
|
|
105
|
-
isFlushing = true;
|
|
106
|
-
Promise.allSettled(
|
|
107
|
-
Array.from(pendingTracePromises).map(
|
|
108
|
-
(p) => p.catch(() => {
|
|
109
|
-
})
|
|
110
|
-
)
|
|
111
|
-
).then(() => {
|
|
112
|
-
isFlushing = false;
|
|
113
|
-
}).catch(() => {
|
|
114
|
-
isFlushing = false;
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
HttpClient = class {
|
|
120
|
-
constructor(config) {
|
|
121
|
-
this.apiKey = config.apiKey;
|
|
122
|
-
this.serviceUrl = config.serviceUrl;
|
|
123
|
-
this.timeout = config.timeout ?? 12e4;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
127
|
-
* `options.method` to use a different verb (e.g. "PATCH").
|
|
128
|
-
*
|
|
129
|
-
* @param endpoint - The API endpoint (without base URL)
|
|
130
|
-
* @param payload - The request body
|
|
131
|
-
* @param options - Optional request options
|
|
132
|
-
* @returns The parsed JSON response
|
|
133
|
-
* @throws {BitfabError} If the request fails
|
|
134
|
-
*/
|
|
135
|
-
async request(endpoint, payload, options) {
|
|
136
|
-
const url = `${this.serviceUrl}${endpoint}`;
|
|
137
|
-
const timeout = options?.timeout ?? this.timeout;
|
|
138
|
-
const method = options?.method ?? "POST";
|
|
139
|
-
const controller = new AbortController();
|
|
140
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
141
|
-
let body;
|
|
142
|
-
let serializationError;
|
|
143
|
-
try {
|
|
144
|
-
body = JSON.stringify(payload);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
serializationError = error instanceof Error ? error.message : String(error);
|
|
147
|
-
body = JSON.stringify({
|
|
148
|
-
...Object.fromEntries(
|
|
149
|
-
Object.entries(payload).filter(
|
|
150
|
-
([, v]) => typeof v === "string" || typeof v === "number"
|
|
151
|
-
)
|
|
152
|
-
),
|
|
153
|
-
rawSpan: {},
|
|
154
|
-
errors: [
|
|
155
|
-
{ source: "sdk", step: "json_serialize", error: serializationError }
|
|
156
|
-
]
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
const response = await fetch(url, {
|
|
161
|
-
method,
|
|
162
|
-
headers: {
|
|
163
|
-
"Content-Type": "application/json",
|
|
164
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
165
|
-
},
|
|
166
|
-
body,
|
|
167
|
-
signal: controller.signal
|
|
168
|
-
});
|
|
169
|
-
if (!response.ok) {
|
|
170
|
-
const errorText = await response.text();
|
|
171
|
-
throw new BitfabError(
|
|
172
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
const result = await response.json();
|
|
176
|
-
if (result.error) {
|
|
177
|
-
if (result.url) {
|
|
178
|
-
throw new BitfabError(
|
|
179
|
-
`${result.error} Configure it at: ${this.serviceUrl}${result.url}`,
|
|
180
|
-
result.url
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
throw new BitfabError(result.error);
|
|
184
|
-
}
|
|
185
|
-
return result;
|
|
186
|
-
} catch (error) {
|
|
187
|
-
if (error instanceof BitfabError) {
|
|
188
|
-
throw error;
|
|
189
|
-
}
|
|
190
|
-
if (error instanceof Error) {
|
|
191
|
-
if (error.name === "AbortError") {
|
|
192
|
-
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
193
|
-
}
|
|
194
|
-
throw new BitfabError(error.message);
|
|
195
|
-
}
|
|
196
|
-
throw new BitfabError("Unknown error occurred");
|
|
197
|
-
} finally {
|
|
198
|
-
clearTimeout(timeoutId);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Look up a function by name.
|
|
203
|
-
* Blocks until complete - needed for function execution.
|
|
204
|
-
*/
|
|
205
|
-
async lookupFunction(name) {
|
|
206
|
-
return this.request("/api/sdk/functions/lookup", { name });
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Send an internal trace (from BAML execution).
|
|
210
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
211
|
-
*/
|
|
212
|
-
sendInternalTrace(functionId, payload) {
|
|
213
|
-
void awaitOnExit(
|
|
214
|
-
this.request(`/api/sdk/functions/${functionId}/traces`, {
|
|
215
|
-
...payload,
|
|
216
|
-
sdkVersion: __version__
|
|
217
|
-
})
|
|
218
|
-
).catch((error) => {
|
|
219
|
-
try {
|
|
220
|
-
console.error("Bitfab: Failed to create trace:", error);
|
|
221
|
-
} catch {
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Send an external span (from withSpan wrapper or OpenAI tracing).
|
|
227
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
228
|
-
* Returns the tracked promise so callers can optionally await it.
|
|
229
|
-
*/
|
|
230
|
-
sendExternalSpan(payload) {
|
|
231
|
-
return awaitOnExit(
|
|
232
|
-
this.request("/api/sdk/externalSpans", {
|
|
233
|
-
...payload,
|
|
234
|
-
sdkVersion: __version__
|
|
235
|
-
})
|
|
236
|
-
).catch((error) => {
|
|
237
|
-
try {
|
|
238
|
-
console.error("Bitfab: Failed to create external span:", error);
|
|
239
|
-
} catch {
|
|
240
|
-
}
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Send an external trace (from OpenAI tracing).
|
|
245
|
-
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
246
|
-
*/
|
|
247
|
-
sendExternalTrace(payload) {
|
|
248
|
-
void awaitOnExit(
|
|
249
|
-
this.request("/api/sdk/externalTraces", {
|
|
250
|
-
...payload,
|
|
251
|
-
sdkVersion: __version__
|
|
252
|
-
})
|
|
253
|
-
).catch((error) => {
|
|
254
|
-
try {
|
|
255
|
-
console.error("Bitfab: Failed to create external trace:", error);
|
|
256
|
-
} catch {
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Partial update of an existing external trace identified by sourceTraceId.
|
|
262
|
-
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
263
|
-
* returns a tracked promise that callers may optionally await.
|
|
264
|
-
*/
|
|
265
|
-
patchTrace(sourceTraceId, payload) {
|
|
266
|
-
const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`;
|
|
267
|
-
return awaitOnExit(
|
|
268
|
-
this.request(endpoint, payload, { method: "PATCH" })
|
|
269
|
-
).catch((error) => {
|
|
270
|
-
try {
|
|
271
|
-
console.error("Bitfab: Failed to patch trace:", error);
|
|
272
|
-
} catch {
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Start a replay session by fetching historical traces.
|
|
278
|
-
* Blocking call — creates a test run and returns lightweight item references.
|
|
279
|
-
*/
|
|
280
|
-
async startReplay(traceFunctionKey, limit, traceIds, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId) {
|
|
281
|
-
const payload = { traceFunctionKey };
|
|
282
|
-
if (limit !== void 0) {
|
|
283
|
-
payload.limit = limit;
|
|
284
|
-
}
|
|
285
|
-
if (traceIds) {
|
|
286
|
-
payload.traceIds = traceIds;
|
|
287
|
-
}
|
|
288
|
-
if (codeChangeDescription !== void 0) {
|
|
289
|
-
payload.codeChangeDescription = codeChangeDescription;
|
|
290
|
-
}
|
|
291
|
-
if (codeChangeFiles !== void 0) {
|
|
292
|
-
payload.codeChangeFiles = codeChangeFiles;
|
|
293
|
-
}
|
|
294
|
-
if (includeDbBranchLease) {
|
|
295
|
-
payload.includeDbBranchLease = true;
|
|
296
|
-
}
|
|
297
|
-
if (experimentGroupId !== void 0) {
|
|
298
|
-
payload.experimentGroupId = experimentGroupId;
|
|
299
|
-
}
|
|
300
|
-
const timeout = includeDbBranchLease ? 18e4 : 3e4;
|
|
301
|
-
return this.request("/api/sdk/replay/start", payload, {
|
|
302
|
-
timeout
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Fetch an external span by ID.
|
|
307
|
-
* Blocking GET request.
|
|
308
|
-
*/
|
|
309
|
-
async getExternalSpan(spanId) {
|
|
310
|
-
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`;
|
|
311
|
-
const controller = new AbortController();
|
|
312
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
313
|
-
try {
|
|
314
|
-
const response = await fetch(url, {
|
|
315
|
-
method: "GET",
|
|
316
|
-
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
317
|
-
signal: controller.signal
|
|
318
|
-
});
|
|
319
|
-
if (!response.ok) {
|
|
320
|
-
const errorText = await response.text();
|
|
321
|
-
throw new BitfabError(
|
|
322
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
return await response.json();
|
|
326
|
-
} catch (error) {
|
|
327
|
-
if (error instanceof BitfabError) {
|
|
328
|
-
throw error;
|
|
329
|
-
}
|
|
330
|
-
if (error instanceof Error) {
|
|
331
|
-
if (error.name === "AbortError") {
|
|
332
|
-
throw new BitfabError("Request timed out after 30000ms");
|
|
333
|
-
}
|
|
334
|
-
throw new BitfabError(error.message);
|
|
335
|
-
}
|
|
336
|
-
throw new BitfabError("Unknown error occurred");
|
|
337
|
-
} finally {
|
|
338
|
-
clearTimeout(timeoutId);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Fetch the span tree for a root span.
|
|
343
|
-
* Blocking GET request.
|
|
344
|
-
*/
|
|
345
|
-
async getSpanTree(externalSpanId) {
|
|
346
|
-
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`;
|
|
347
|
-
const controller = new AbortController();
|
|
348
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
349
|
-
try {
|
|
350
|
-
const response = await fetch(url, {
|
|
351
|
-
method: "GET",
|
|
352
|
-
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
353
|
-
signal: controller.signal
|
|
354
|
-
});
|
|
355
|
-
if (!response.ok) {
|
|
356
|
-
const errorText = await response.text();
|
|
357
|
-
throw new BitfabError(
|
|
358
|
-
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
return await response.json();
|
|
362
|
-
} catch (error) {
|
|
363
|
-
if (error instanceof BitfabError) {
|
|
364
|
-
throw error;
|
|
365
|
-
}
|
|
366
|
-
if (error instanceof Error) {
|
|
367
|
-
if (error.name === "AbortError") {
|
|
368
|
-
throw new BitfabError("Request timed out after 30000ms");
|
|
369
|
-
}
|
|
370
|
-
throw new BitfabError(error.message);
|
|
371
|
-
}
|
|
372
|
-
throw new BitfabError("Unknown error occurred");
|
|
373
|
-
} finally {
|
|
374
|
-
clearTimeout(timeoutId);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Mark a replay test run as completed.
|
|
379
|
-
* Blocking call.
|
|
380
|
-
*/
|
|
381
|
-
async completeReplay(testRunId) {
|
|
382
|
-
return this.request(
|
|
383
|
-
"/api/sdk/replay/complete",
|
|
384
|
-
{ testRunId },
|
|
385
|
-
{ timeout: 3e4 }
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Ask the server to materialize a per-trace DB branch lease from a
|
|
390
|
-
* captured `dbSnapshotRef`. Blocking — the resolver creates a Neon
|
|
391
|
-
* snapshot + preview branch and polls operations to readiness, which
|
|
392
|
-
* can take seconds.
|
|
393
|
-
*/
|
|
394
|
-
async resolveDbBranchLease(testRunId, traceId, dbSnapshotRef) {
|
|
395
|
-
return this.request(
|
|
396
|
-
"/api/sdk/replay/resolveDbBranchLease",
|
|
397
|
-
{ testRunId, traceId, dbSnapshotRef },
|
|
398
|
-
{ timeout: 9e4 }
|
|
399
|
-
);
|
|
400
|
-
}
|
|
401
|
-
/** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
|
|
402
|
-
async releaseDbBranchLease(neonBranchId) {
|
|
403
|
-
await this.request(
|
|
404
|
-
"/api/sdk/replay/releaseDbBranchLease",
|
|
405
|
-
{ neonBranchId },
|
|
406
|
-
{ timeout: 3e4 }
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
|
-
|
|
413
57
|
// src/asyncStorage.ts
|
|
414
58
|
function registerAsyncLocalStorageClass(cls) {
|
|
415
59
|
if (!AsyncLocalStorageClass) {
|
|
@@ -583,18 +227,25 @@ function buildMockTree(rootNode) {
|
|
|
583
227
|
}
|
|
584
228
|
return { spans };
|
|
585
229
|
}
|
|
586
|
-
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, environment) {
|
|
230
|
+
async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy, environment, adaptInputs) {
|
|
587
231
|
const lease = environment ? serverItem.dbBranchLease : void 0;
|
|
588
232
|
let inputs = [];
|
|
589
233
|
let originalOutput;
|
|
590
234
|
let result;
|
|
591
235
|
let error = null;
|
|
592
236
|
const replayedTraceId = crypto.randomUUID();
|
|
237
|
+
const pendingPersistence = [];
|
|
593
238
|
try {
|
|
594
239
|
const span = await httpClient.getExternalSpan(serverItem.externalSpanId);
|
|
595
240
|
const spanData = span.rawData?.span_data ?? {};
|
|
596
241
|
inputs = deserializeInputs(spanData);
|
|
597
242
|
originalOutput = deserializeOutput(spanData);
|
|
243
|
+
if (adaptInputs) {
|
|
244
|
+
inputs = adaptInputs(inputs, {
|
|
245
|
+
traceId: serverItem.traceId,
|
|
246
|
+
sourceSpanId: serverItem.externalSpanId
|
|
247
|
+
});
|
|
248
|
+
}
|
|
598
249
|
let mockTree;
|
|
599
250
|
if (mockStrategy === "all" || mockStrategy === "marked") {
|
|
600
251
|
const treeResponse = await httpClient.getSpanTree(
|
|
@@ -612,7 +263,8 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
612
263
|
mockTree,
|
|
613
264
|
callCounters: mockTree ? /* @__PURE__ */ new Map() : void 0,
|
|
614
265
|
mockStrategy,
|
|
615
|
-
dbBranchLease: lease
|
|
266
|
+
dbBranchLease: lease,
|
|
267
|
+
pendingPersistence
|
|
616
268
|
},
|
|
617
269
|
() => fn(...inputs)
|
|
618
270
|
);
|
|
@@ -620,6 +272,7 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
620
272
|
} catch (e) {
|
|
621
273
|
error = e instanceof Error ? e.message : String(e);
|
|
622
274
|
} finally {
|
|
275
|
+
await Promise.allSettled(pendingPersistence);
|
|
623
276
|
if (lease) {
|
|
624
277
|
try {
|
|
625
278
|
await httpClient.releaseDbBranchLease(lease.neonBranchId);
|
|
@@ -703,24 +356,51 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options) {
|
|
|
703
356
|
fn,
|
|
704
357
|
testRunId,
|
|
705
358
|
mockStrategy,
|
|
706
|
-
options?.environment
|
|
359
|
+
options?.environment,
|
|
360
|
+
options?.adaptInputs
|
|
707
361
|
)
|
|
708
362
|
);
|
|
709
363
|
const resultItems = await mapWithConcurrency(tasks, maxConcurrency);
|
|
710
|
-
await
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
const completeResult = await httpClient.completeReplay(testRunId);
|
|
714
|
-
serverTraceIds = completeResult.traceIds ?? {};
|
|
715
|
-
} catch (e) {
|
|
364
|
+
const completeResult = await httpClient.completeReplay(testRunId);
|
|
365
|
+
const serverTraceIds = completeResult.traceIds;
|
|
366
|
+
if (serverTraceIds === void 0) {
|
|
716
367
|
try {
|
|
717
|
-
console.
|
|
368
|
+
console.warn(
|
|
369
|
+
"Bitfab: server did not return replay trace IDs; item.traceId will be null (server upgrade required for verdict persistence)"
|
|
370
|
+
);
|
|
718
371
|
} catch {
|
|
719
372
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
373
|
+
for (const item of resultItems) {
|
|
374
|
+
item.traceId = null;
|
|
375
|
+
}
|
|
376
|
+
} else {
|
|
377
|
+
const missing = [];
|
|
378
|
+
let completedCount = 0;
|
|
379
|
+
for (const item of resultItems) {
|
|
380
|
+
if (item.traceId) {
|
|
381
|
+
const mapped = serverTraceIds[item.traceId];
|
|
382
|
+
if (item.error === null) {
|
|
383
|
+
completedCount += 1;
|
|
384
|
+
if (mapped === void 0) {
|
|
385
|
+
missing.push(item.traceId);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
item.traceId = mapped ?? null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
if (missing.length > 0) {
|
|
392
|
+
const serverCount = completeResult.traceCount !== void 0 ? ` The server persisted ${completeResult.traceCount} trace(s) for this run.` : "";
|
|
393
|
+
if (missing.length === completedCount) {
|
|
394
|
+
throw new BitfabError(
|
|
395
|
+
`Replay completed but the server has no persisted trace for any of the ${completedCount} completed item(s) (testRunId ${testRunId}).${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.`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
console.error(
|
|
400
|
+
`Bitfab: server has no persisted trace for ${missing.length} of ${completedCount} completed replay item(s) (testRunId ${testRunId}).${serverCount} Their traceId is null and verdicts cannot be persisted for them. Missing: ${missing.join(", ")}`
|
|
401
|
+
);
|
|
402
|
+
} catch {
|
|
403
|
+
}
|
|
724
404
|
}
|
|
725
405
|
}
|
|
726
406
|
return {
|
|
@@ -733,7 +413,6 @@ var init_replay = __esm({
|
|
|
733
413
|
"src/replay.ts"() {
|
|
734
414
|
"use strict";
|
|
735
415
|
init_errors();
|
|
736
|
-
init_http();
|
|
737
416
|
init_replayContext();
|
|
738
417
|
init_serialize();
|
|
739
418
|
}
|
|
@@ -758,9 +437,346 @@ __export(index_exports, {
|
|
|
758
437
|
});
|
|
759
438
|
module.exports = __toCommonJS(index_exports);
|
|
760
439
|
|
|
440
|
+
// src/version.generated.ts
|
|
441
|
+
var __version__ = "0.16.0";
|
|
442
|
+
|
|
443
|
+
// src/constants.ts
|
|
444
|
+
var DEFAULT_SERVICE_URL = "https://bitfab.ai";
|
|
445
|
+
|
|
446
|
+
// src/http.ts
|
|
447
|
+
init_errors();
|
|
448
|
+
var pendingTracePromises = /* @__PURE__ */ new Set();
|
|
449
|
+
function awaitOnExit(promise) {
|
|
450
|
+
pendingTracePromises.add(promise);
|
|
451
|
+
void promise.finally(() => {
|
|
452
|
+
pendingTracePromises.delete(promise);
|
|
453
|
+
}).catch(() => {
|
|
454
|
+
});
|
|
455
|
+
return promise;
|
|
456
|
+
}
|
|
457
|
+
async function flushTraces(timeoutMs = 5e3) {
|
|
458
|
+
if (pendingTracePromises.size === 0) {
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
await Promise.race([
|
|
462
|
+
Promise.allSettled(Array.from(pendingTracePromises)),
|
|
463
|
+
new Promise((resolve) => setTimeout(resolve, timeoutMs))
|
|
464
|
+
]);
|
|
465
|
+
}
|
|
466
|
+
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
467
|
+
let isFlushing = false;
|
|
468
|
+
process.on("beforeExit", () => {
|
|
469
|
+
if (pendingTracePromises.size > 0 && !isFlushing) {
|
|
470
|
+
isFlushing = true;
|
|
471
|
+
Promise.allSettled(
|
|
472
|
+
Array.from(pendingTracePromises).map(
|
|
473
|
+
(p) => p.catch(() => {
|
|
474
|
+
})
|
|
475
|
+
)
|
|
476
|
+
).then(() => {
|
|
477
|
+
isFlushing = false;
|
|
478
|
+
}).catch(() => {
|
|
479
|
+
isFlushing = false;
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
var HttpClient = class {
|
|
485
|
+
constructor(config) {
|
|
486
|
+
this.apiKey = config.apiKey;
|
|
487
|
+
this.serviceUrl = config.serviceUrl;
|
|
488
|
+
this.timeout = config.timeout ?? 12e4;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Make an HTTP request to the Bitfab API. Defaults to POST; pass
|
|
492
|
+
* `options.method` to use a different verb (e.g. "PATCH").
|
|
493
|
+
*
|
|
494
|
+
* @param endpoint - The API endpoint (without base URL)
|
|
495
|
+
* @param payload - The request body
|
|
496
|
+
* @param options - Optional request options
|
|
497
|
+
* @returns The parsed JSON response
|
|
498
|
+
* @throws {BitfabError} If the request fails
|
|
499
|
+
*/
|
|
500
|
+
async request(endpoint, payload, options) {
|
|
501
|
+
const url = `${this.serviceUrl}${endpoint}`;
|
|
502
|
+
const timeout = options?.timeout ?? this.timeout;
|
|
503
|
+
const method = options?.method ?? "POST";
|
|
504
|
+
const controller = new AbortController();
|
|
505
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
506
|
+
let body;
|
|
507
|
+
let serializationError;
|
|
508
|
+
try {
|
|
509
|
+
body = JSON.stringify(payload);
|
|
510
|
+
} catch (error) {
|
|
511
|
+
serializationError = error instanceof Error ? error.message : String(error);
|
|
512
|
+
body = JSON.stringify({
|
|
513
|
+
...Object.fromEntries(
|
|
514
|
+
Object.entries(payload).filter(
|
|
515
|
+
([, v]) => typeof v === "string" || typeof v === "number"
|
|
516
|
+
)
|
|
517
|
+
),
|
|
518
|
+
rawSpan: {},
|
|
519
|
+
errors: [
|
|
520
|
+
{ source: "sdk", step: "json_serialize", error: serializationError }
|
|
521
|
+
]
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
const response = await fetch(url, {
|
|
526
|
+
method,
|
|
527
|
+
headers: {
|
|
528
|
+
"Content-Type": "application/json",
|
|
529
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
530
|
+
},
|
|
531
|
+
body,
|
|
532
|
+
signal: controller.signal
|
|
533
|
+
});
|
|
534
|
+
if (!response.ok) {
|
|
535
|
+
const errorText = await response.text();
|
|
536
|
+
throw new BitfabError(
|
|
537
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
const result = await response.json();
|
|
541
|
+
if (result.error) {
|
|
542
|
+
if (result.url) {
|
|
543
|
+
throw new BitfabError(
|
|
544
|
+
`${result.error} Configure it at: ${this.serviceUrl}${result.url}`,
|
|
545
|
+
result.url
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
throw new BitfabError(result.error);
|
|
549
|
+
}
|
|
550
|
+
return result;
|
|
551
|
+
} catch (error) {
|
|
552
|
+
if (error instanceof BitfabError) {
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
555
|
+
if (error instanceof Error) {
|
|
556
|
+
if (error.name === "AbortError") {
|
|
557
|
+
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
558
|
+
}
|
|
559
|
+
throw new BitfabError(error.message);
|
|
560
|
+
}
|
|
561
|
+
throw new BitfabError("Unknown error occurred");
|
|
562
|
+
} finally {
|
|
563
|
+
clearTimeout(timeoutId);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Look up a function by name.
|
|
568
|
+
* Blocks until complete - needed for function execution.
|
|
569
|
+
*/
|
|
570
|
+
async lookupFunction(name) {
|
|
571
|
+
return this.request("/api/sdk/functions/lookup", { name });
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Send an internal trace (from BAML execution).
|
|
575
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
576
|
+
*/
|
|
577
|
+
sendInternalTrace(functionId, payload) {
|
|
578
|
+
void awaitOnExit(
|
|
579
|
+
this.request(`/api/sdk/functions/${functionId}/traces`, {
|
|
580
|
+
...payload,
|
|
581
|
+
sdkVersion: __version__
|
|
582
|
+
})
|
|
583
|
+
).catch((error) => {
|
|
584
|
+
try {
|
|
585
|
+
console.error("Bitfab: Failed to create trace:", error);
|
|
586
|
+
} catch {
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Send an external span (from withSpan wrapper or OpenAI tracing).
|
|
592
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
593
|
+
* Returns the tracked promise so callers can optionally await it.
|
|
594
|
+
*/
|
|
595
|
+
sendExternalSpan(payload) {
|
|
596
|
+
return awaitOnExit(
|
|
597
|
+
this.request("/api/sdk/externalSpans", {
|
|
598
|
+
...payload,
|
|
599
|
+
sdkVersion: __version__
|
|
600
|
+
})
|
|
601
|
+
).catch((error) => {
|
|
602
|
+
try {
|
|
603
|
+
console.error("Bitfab: Failed to create external span:", error);
|
|
604
|
+
} catch {
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Send an external trace (from OpenAI tracing).
|
|
610
|
+
* Fire-and-forget with awaitOnExit - doesn't block the caller.
|
|
611
|
+
* Returns the tracked promise so callers can optionally await it
|
|
612
|
+
* (the replay path does, so trace completions are persisted before
|
|
613
|
+
* `completeReplay` builds the trace-ID mapping).
|
|
614
|
+
*/
|
|
615
|
+
sendExternalTrace(payload) {
|
|
616
|
+
return awaitOnExit(
|
|
617
|
+
this.request("/api/sdk/externalTraces", {
|
|
618
|
+
...payload,
|
|
619
|
+
sdkVersion: __version__
|
|
620
|
+
})
|
|
621
|
+
).catch((error) => {
|
|
622
|
+
try {
|
|
623
|
+
console.error("Bitfab: Failed to create external trace:", error);
|
|
624
|
+
} catch {
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Partial update of an existing external trace identified by sourceTraceId.
|
|
630
|
+
* Used by the detached `client.getTrace(id)` handle. Fire-and-forget;
|
|
631
|
+
* returns a tracked promise that callers may optionally await.
|
|
632
|
+
*/
|
|
633
|
+
patchTrace(sourceTraceId, payload) {
|
|
634
|
+
const endpoint = `/api/sdk/externalTraces/${encodeURIComponent(sourceTraceId)}`;
|
|
635
|
+
return awaitOnExit(
|
|
636
|
+
this.request(endpoint, payload, { method: "PATCH" })
|
|
637
|
+
).catch((error) => {
|
|
638
|
+
try {
|
|
639
|
+
console.error("Bitfab: Failed to patch trace:", error);
|
|
640
|
+
} catch {
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Start a replay session by fetching historical traces.
|
|
646
|
+
* Blocking call — creates a test run and returns lightweight item references.
|
|
647
|
+
*/
|
|
648
|
+
async startReplay(traceFunctionKey, limit, traceIds, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId) {
|
|
649
|
+
const payload = { traceFunctionKey };
|
|
650
|
+
if (limit !== void 0) {
|
|
651
|
+
payload.limit = limit;
|
|
652
|
+
}
|
|
653
|
+
if (traceIds) {
|
|
654
|
+
payload.traceIds = traceIds;
|
|
655
|
+
}
|
|
656
|
+
if (codeChangeDescription !== void 0) {
|
|
657
|
+
payload.codeChangeDescription = codeChangeDescription;
|
|
658
|
+
}
|
|
659
|
+
if (codeChangeFiles !== void 0) {
|
|
660
|
+
payload.codeChangeFiles = codeChangeFiles;
|
|
661
|
+
}
|
|
662
|
+
if (includeDbBranchLease) {
|
|
663
|
+
payload.includeDbBranchLease = true;
|
|
664
|
+
}
|
|
665
|
+
if (experimentGroupId !== void 0) {
|
|
666
|
+
payload.experimentGroupId = experimentGroupId;
|
|
667
|
+
}
|
|
668
|
+
const timeout = includeDbBranchLease ? 18e4 : 3e4;
|
|
669
|
+
return this.request("/api/sdk/replay/start", payload, {
|
|
670
|
+
timeout
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Fetch an external span by ID.
|
|
675
|
+
* Blocking GET request.
|
|
676
|
+
*/
|
|
677
|
+
async getExternalSpan(spanId) {
|
|
678
|
+
const url = `${this.serviceUrl}/api/sdk/externalSpans/${spanId}`;
|
|
679
|
+
const controller = new AbortController();
|
|
680
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
681
|
+
try {
|
|
682
|
+
const response = await fetch(url, {
|
|
683
|
+
method: "GET",
|
|
684
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
685
|
+
signal: controller.signal
|
|
686
|
+
});
|
|
687
|
+
if (!response.ok) {
|
|
688
|
+
const errorText = await response.text();
|
|
689
|
+
throw new BitfabError(
|
|
690
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
return await response.json();
|
|
694
|
+
} catch (error) {
|
|
695
|
+
if (error instanceof BitfabError) {
|
|
696
|
+
throw error;
|
|
697
|
+
}
|
|
698
|
+
if (error instanceof Error) {
|
|
699
|
+
if (error.name === "AbortError") {
|
|
700
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
701
|
+
}
|
|
702
|
+
throw new BitfabError(error.message);
|
|
703
|
+
}
|
|
704
|
+
throw new BitfabError("Unknown error occurred");
|
|
705
|
+
} finally {
|
|
706
|
+
clearTimeout(timeoutId);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Fetch the span tree for a root span.
|
|
711
|
+
* Blocking GET request.
|
|
712
|
+
*/
|
|
713
|
+
async getSpanTree(externalSpanId) {
|
|
714
|
+
const url = `${this.serviceUrl}/api/sdk/replay/spanTree/${externalSpanId}`;
|
|
715
|
+
const controller = new AbortController();
|
|
716
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
717
|
+
try {
|
|
718
|
+
const response = await fetch(url, {
|
|
719
|
+
method: "GET",
|
|
720
|
+
headers: { Authorization: `Bearer ${this.apiKey}` },
|
|
721
|
+
signal: controller.signal
|
|
722
|
+
});
|
|
723
|
+
if (!response.ok) {
|
|
724
|
+
const errorText = await response.text();
|
|
725
|
+
throw new BitfabError(
|
|
726
|
+
`HTTP ${response.status}: ${errorText.slice(0, 500)}`
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
return await response.json();
|
|
730
|
+
} catch (error) {
|
|
731
|
+
if (error instanceof BitfabError) {
|
|
732
|
+
throw error;
|
|
733
|
+
}
|
|
734
|
+
if (error instanceof Error) {
|
|
735
|
+
if (error.name === "AbortError") {
|
|
736
|
+
throw new BitfabError("Request timed out after 30000ms");
|
|
737
|
+
}
|
|
738
|
+
throw new BitfabError(error.message);
|
|
739
|
+
}
|
|
740
|
+
throw new BitfabError("Unknown error occurred");
|
|
741
|
+
} finally {
|
|
742
|
+
clearTimeout(timeoutId);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Mark a replay test run as completed.
|
|
747
|
+
* Blocking call.
|
|
748
|
+
*/
|
|
749
|
+
async completeReplay(testRunId) {
|
|
750
|
+
return this.request(
|
|
751
|
+
"/api/sdk/replay/complete",
|
|
752
|
+
{ testRunId },
|
|
753
|
+
{ timeout: 3e4 }
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Ask the server to materialize a per-trace DB branch lease from a
|
|
758
|
+
* captured `dbSnapshotRef`. Blocking — the resolver creates a Neon
|
|
759
|
+
* snapshot + preview branch and polls operations to readiness, which
|
|
760
|
+
* can take seconds.
|
|
761
|
+
*/
|
|
762
|
+
async resolveDbBranchLease(testRunId, traceId, dbSnapshotRef) {
|
|
763
|
+
return this.request(
|
|
764
|
+
"/api/sdk/replay/resolveDbBranchLease",
|
|
765
|
+
{ testRunId, traceId, dbSnapshotRef },
|
|
766
|
+
{ timeout: 9e4 }
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
/** Release a previously-resolved DB branch by deleting its Neon branch. Idempotent server-side. */
|
|
770
|
+
async releaseDbBranchLease(neonBranchId) {
|
|
771
|
+
await this.request(
|
|
772
|
+
"/api/sdk/replay/releaseDbBranchLease",
|
|
773
|
+
{ neonBranchId },
|
|
774
|
+
{ timeout: 3e4 }
|
|
775
|
+
);
|
|
776
|
+
}
|
|
777
|
+
};
|
|
778
|
+
|
|
761
779
|
// src/claudeAgentSdk.ts
|
|
762
|
-
init_constants();
|
|
763
|
-
init_http();
|
|
764
780
|
function nowIso() {
|
|
765
781
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
766
782
|
}
|
|
@@ -1525,9 +1541,6 @@ async function runFunctionWithBaml(bamlSource, inputs, providers, envVars) {
|
|
|
1525
1541
|
};
|
|
1526
1542
|
}
|
|
1527
1543
|
|
|
1528
|
-
// src/client.ts
|
|
1529
|
-
init_constants();
|
|
1530
|
-
|
|
1531
1544
|
// src/dbSnapshot.ts
|
|
1532
1545
|
init_errors();
|
|
1533
1546
|
var SUPPORTED_PROVIDERS = ["neon"];
|
|
@@ -1545,12 +1558,7 @@ function buildSnapshotRef(config, sdkWallClockBeforeFn) {
|
|
|
1545
1558
|
};
|
|
1546
1559
|
}
|
|
1547
1560
|
|
|
1548
|
-
// src/client.ts
|
|
1549
|
-
init_http();
|
|
1550
|
-
|
|
1551
1561
|
// src/langgraph.ts
|
|
1552
|
-
init_constants();
|
|
1553
|
-
init_http();
|
|
1554
1562
|
var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
|
|
1555
1563
|
var LANGGRAPH_METADATA_KEYS = [
|
|
1556
1564
|
"langgraph_step",
|
|
@@ -2098,8 +2106,6 @@ var ReplayEnvironment = class {
|
|
|
2098
2106
|
init_serialize();
|
|
2099
2107
|
|
|
2100
2108
|
// src/tracing.ts
|
|
2101
|
-
init_constants();
|
|
2102
|
-
init_http();
|
|
2103
2109
|
var BitfabOpenAITracingProcessor = class {
|
|
2104
2110
|
/**
|
|
2105
2111
|
* Initialize the tracing processor.
|
|
@@ -2933,9 +2939,18 @@ var Bitfab = class {
|
|
|
2933
2939
|
spanType: options.type ?? "custom"
|
|
2934
2940
|
};
|
|
2935
2941
|
const sendSpan = async (params) => {
|
|
2942
|
+
const replayCtx = getReplayContext();
|
|
2943
|
+
const persistenceCollector = isRootSpan ? replayCtx?.pendingPersistence : void 0;
|
|
2944
|
+
let resolvePersistence;
|
|
2945
|
+
if (persistenceCollector) {
|
|
2946
|
+
persistenceCollector.push(
|
|
2947
|
+
new Promise((resolve) => {
|
|
2948
|
+
resolvePersistence = resolve;
|
|
2949
|
+
})
|
|
2950
|
+
);
|
|
2951
|
+
}
|
|
2936
2952
|
try {
|
|
2937
2953
|
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2938
|
-
const replayCtx = getReplayContext();
|
|
2939
2954
|
const spanPromise = self.sendWrapperSpan({
|
|
2940
2955
|
...baseSpanParams,
|
|
2941
2956
|
...params,
|
|
@@ -2950,13 +2965,17 @@ var Bitfab = class {
|
|
|
2950
2965
|
if (isRootSpan) {
|
|
2951
2966
|
const pending = pendingSpanPromises.get(traceId) ?? [];
|
|
2952
2967
|
pending.push(spanPromise);
|
|
2953
|
-
|
|
2954
|
-
Promise.allSettled(pending)
|
|
2955
|
-
|
|
2956
|
-
|
|
2968
|
+
if (persistenceCollector) {
|
|
2969
|
+
await Promise.allSettled(pending);
|
|
2970
|
+
} else {
|
|
2971
|
+
await Promise.race([
|
|
2972
|
+
Promise.allSettled(pending),
|
|
2973
|
+
new Promise((resolve) => setTimeout(resolve, 5e3))
|
|
2974
|
+
]);
|
|
2975
|
+
}
|
|
2957
2976
|
pendingSpanPromises.delete(traceId);
|
|
2958
2977
|
const traceState = activeTraceStates.get(traceId);
|
|
2959
|
-
self.sendTraceCompletion({
|
|
2978
|
+
const completionPromise = self.sendTraceCompletion({
|
|
2960
2979
|
traceFunctionKey,
|
|
2961
2980
|
traceId,
|
|
2962
2981
|
startedAt: traceState?.startedAt ?? startedAt,
|
|
@@ -2969,6 +2988,9 @@ var Bitfab = class {
|
|
|
2969
2988
|
dbSnapshotRef: traceState?.dbSnapshotRef
|
|
2970
2989
|
});
|
|
2971
2990
|
activeTraceStates.delete(traceId);
|
|
2991
|
+
if (persistenceCollector) {
|
|
2992
|
+
await completionPromise;
|
|
2993
|
+
}
|
|
2972
2994
|
} else {
|
|
2973
2995
|
const pending = pendingSpanPromises.get(traceId);
|
|
2974
2996
|
if (pending) {
|
|
@@ -2978,6 +3000,8 @@ var Bitfab = class {
|
|
|
2978
3000
|
}
|
|
2979
3001
|
}
|
|
2980
3002
|
} catch {
|
|
3003
|
+
} finally {
|
|
3004
|
+
resolvePersistence?.();
|
|
2981
3005
|
}
|
|
2982
3006
|
};
|
|
2983
3007
|
const replayCtxForMock = getReplayContext();
|
|
@@ -3130,7 +3154,7 @@ var Bitfab = class {
|
|
|
3130
3154
|
if (params.dbSnapshotRef) {
|
|
3131
3155
|
rawTrace.db_snapshot_ref = params.dbSnapshotRef;
|
|
3132
3156
|
}
|
|
3133
|
-
this.httpClient.sendExternalTrace({
|
|
3157
|
+
return this.httpClient.sendExternalTrace({
|
|
3134
3158
|
type: "sdk-function",
|
|
3135
3159
|
source: "typescript-sdk-function",
|
|
3136
3160
|
traceFunctionKey: params.traceFunctionKey,
|
|
@@ -3274,10 +3298,6 @@ var BitfabFunction = class {
|
|
|
3274
3298
|
);
|
|
3275
3299
|
}
|
|
3276
3300
|
};
|
|
3277
|
-
|
|
3278
|
-
// src/index.ts
|
|
3279
|
-
init_constants();
|
|
3280
|
-
init_http();
|
|
3281
3301
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3282
3302
|
0 && (module.exports = {
|
|
3283
3303
|
Bitfab,
|