bitfab 0.42.0 → 0.43.1
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-73EBNSFJ.js → chunk-M3WVF2H7.js} +10 -4
- package/dist/chunk-M3WVF2H7.js.map +1 -0
- package/dist/{chunk-GUKZZRAA.js → chunk-NQULKHFJ.js} +173 -67
- package/dist/chunk-NQULKHFJ.js.map +1 -0
- package/dist/{chunk-PDPMZA4Y.js → chunk-QP3ZDSMN.js} +6 -3
- package/dist/{chunk-PDPMZA4Y.js.map → chunk-QP3ZDSMN.js.map} +1 -1
- package/dist/{chunk-WB3IVBWE.js → chunk-XFEEB6DH.js} +6 -3
- package/dist/{chunk-WB3IVBWE.js.map → chunk-XFEEB6DH.js.map} +1 -1
- package/dist/{http-JU2VKSY3.js → http-QWLOMVEH.js} +2 -2
- package/dist/{http-B7QOMWQP.js → http-SV454Y6C.js} +2 -2
- package/dist/index.cjs +184 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -64
- package/dist/index.d.ts +37 -64
- package/dist/index.js +3 -3
- package/dist/node.cjs +184 -66
- 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 +3 -3
- package/dist/{replay-GLUOZHJS.js → replay-CCNUJTRI.js} +3 -3
- package/dist/replayCli.js +31 -10
- package/dist/replayCli.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-73EBNSFJ.js.map +0 -1
- package/dist/chunk-GUKZZRAA.js.map +0 -1
- /package/dist/{http-B7QOMWQP.js.map → http-QWLOMVEH.js.map} +0 -0
- /package/dist/{http-JU2VKSY3.js.map → http-SV454Y6C.js.map} +0 -0
- /package/dist/{replay-GLUOZHJS.js.map → replay-CCNUJTRI.js.map} +0 -0
package/dist/node.cjs
CHANGED
|
@@ -97,7 +97,7 @@ var __version__, __packageName__;
|
|
|
97
97
|
var init_version_generated = __esm({
|
|
98
98
|
"src/version.generated.ts"() {
|
|
99
99
|
"use strict";
|
|
100
|
-
__version__ = "0.
|
|
100
|
+
__version__ = "0.43.1";
|
|
101
101
|
__packageName__ = "bitfab";
|
|
102
102
|
}
|
|
103
103
|
});
|
|
@@ -1857,7 +1857,7 @@ var init_http = __esm({
|
|
|
1857
1857
|
* Start a replay session by fetching historical traces.
|
|
1858
1858
|
* Blocking call - creates a test run and returns lightweight item references.
|
|
1859
1859
|
*/
|
|
1860
|
-
async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
|
|
1860
|
+
async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts, includeOriginalMetadata) {
|
|
1861
1861
|
const payload = { traceFunctionKey };
|
|
1862
1862
|
if (limit !== void 0) {
|
|
1863
1863
|
payload.limit = limit;
|
|
@@ -1893,6 +1893,9 @@ var init_http = __esm({
|
|
|
1893
1893
|
if (attempts !== void 0 && attempts > 1) {
|
|
1894
1894
|
payload.attempts = attempts;
|
|
1895
1895
|
}
|
|
1896
|
+
if (includeOriginalMetadata) {
|
|
1897
|
+
payload.includeOriginalMetadata = true;
|
|
1898
|
+
}
|
|
1896
1899
|
const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
|
|
1897
1900
|
return this.request("/api/sdk/replay/start", payload, {
|
|
1898
1901
|
timeout
|
|
@@ -2506,6 +2509,9 @@ function reportReplayProgress(progress) {
|
|
|
2506
2509
|
} catch {
|
|
2507
2510
|
}
|
|
2508
2511
|
}
|
|
2512
|
+
function isPlainRecord(value) {
|
|
2513
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2514
|
+
}
|
|
2509
2515
|
function errorMessage(error) {
|
|
2510
2516
|
return error instanceof Error ? error.message : String(error);
|
|
2511
2517
|
}
|
|
@@ -2653,12 +2659,14 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
2653
2659
|
inputs = deserializeInputs(spanData);
|
|
2654
2660
|
originalOutput = deserializeOutput(spanData);
|
|
2655
2661
|
if (adaptInputs) {
|
|
2662
|
+
const originalMetadata = serverItem.originalMetadata;
|
|
2656
2663
|
inputs = adaptInputs(inputs, {
|
|
2657
2664
|
originalTraceId,
|
|
2658
2665
|
originalSpanId,
|
|
2659
2666
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
2660
2667
|
sourceTraceId: originalTraceId,
|
|
2661
|
-
sourceSpanId: originalSpanId
|
|
2668
|
+
sourceSpanId: originalSpanId,
|
|
2669
|
+
metadata: isPlainRecord(originalMetadata) ? { ...originalMetadata } : {}
|
|
2662
2670
|
});
|
|
2663
2671
|
}
|
|
2664
2672
|
const hasOverrides = resolvedOverrides.length > 0;
|
|
@@ -2948,7 +2956,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2948
2956
|
options?.datasetId,
|
|
2949
2957
|
options?.graderIds,
|
|
2950
2958
|
resolveDbBranchSettings(options?.dbBranch),
|
|
2951
|
-
attempts
|
|
2959
|
+
attempts,
|
|
2960
|
+
options?.adaptInputs !== void 0
|
|
2952
2961
|
);
|
|
2953
2962
|
if (serverItems.length === 0) {
|
|
2954
2963
|
try {
|
|
@@ -5309,7 +5318,8 @@ var BitfabLangGraphIntegration = class {
|
|
|
5309
5318
|
type: "function",
|
|
5310
5319
|
captureWhen: "nested",
|
|
5311
5320
|
mockOnReplay: shouldMock,
|
|
5312
|
-
finalize: finalizeToolResult
|
|
5321
|
+
finalize: finalizeToolResult,
|
|
5322
|
+
surface: "inherit"
|
|
5313
5323
|
},
|
|
5314
5324
|
async (_args) => await originalInvoke(input, ...rest)
|
|
5315
5325
|
);
|
|
@@ -5352,7 +5362,7 @@ var BitfabLangGraphIntegration = class {
|
|
|
5352
5362
|
wrapInvoke(fn) {
|
|
5353
5363
|
return this.client.withSpan(
|
|
5354
5364
|
this.traceFunctionKey,
|
|
5355
|
-
{ name: this.traceFunctionKey, type: "agent" },
|
|
5365
|
+
{ name: this.traceFunctionKey, type: "agent", surface: "inherit" },
|
|
5356
5366
|
fn
|
|
5357
5367
|
);
|
|
5358
5368
|
}
|
|
@@ -5405,7 +5415,11 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
5405
5415
|
}
|
|
5406
5416
|
return res?.finalOutput;
|
|
5407
5417
|
};
|
|
5408
|
-
const options_ = {
|
|
5418
|
+
const options_ = {
|
|
5419
|
+
type: "agent",
|
|
5420
|
+
finalize,
|
|
5421
|
+
surface: "inherit"
|
|
5422
|
+
};
|
|
5409
5423
|
const traced = this.withSpanFn(
|
|
5410
5424
|
this.traceFunctionKey,
|
|
5411
5425
|
options_,
|
|
@@ -5469,6 +5483,38 @@ _context = new WeakMap();
|
|
|
5469
5483
|
|
|
5470
5484
|
// src/client.ts
|
|
5471
5485
|
init_replayContext();
|
|
5486
|
+
|
|
5487
|
+
// src/seedContext.ts
|
|
5488
|
+
init_asyncStorage();
|
|
5489
|
+
var seedContextStorage = null;
|
|
5490
|
+
var SEED_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.seedContextStorage");
|
|
5491
|
+
var seedContextReady = asyncStorageReady.then(() => {
|
|
5492
|
+
const shared = globalThis;
|
|
5493
|
+
const existing = shared[SEED_CONTEXT_STORAGE_SYMBOL];
|
|
5494
|
+
if (existing) {
|
|
5495
|
+
seedContextStorage = existing;
|
|
5496
|
+
return;
|
|
5497
|
+
}
|
|
5498
|
+
const created = createAsyncLocalStorage();
|
|
5499
|
+
if (created) {
|
|
5500
|
+
shared[SEED_CONTEXT_STORAGE_SYMBOL] = created;
|
|
5501
|
+
seedContextStorage = created;
|
|
5502
|
+
}
|
|
5503
|
+
});
|
|
5504
|
+
function getSeedContext() {
|
|
5505
|
+
return seedContextStorage?.getStore() ?? null;
|
|
5506
|
+
}
|
|
5507
|
+
function inSeedScope() {
|
|
5508
|
+
return getSeedContext() !== null;
|
|
5509
|
+
}
|
|
5510
|
+
function runWithSeedContext(ctx, fn) {
|
|
5511
|
+
if (seedContextStorage) {
|
|
5512
|
+
return seedContextStorage.run(ctx, fn);
|
|
5513
|
+
}
|
|
5514
|
+
return fn();
|
|
5515
|
+
}
|
|
5516
|
+
|
|
5517
|
+
// src/client.ts
|
|
5472
5518
|
init_serialize();
|
|
5473
5519
|
|
|
5474
5520
|
// src/tracing.ts
|
|
@@ -5804,7 +5850,8 @@ var BitfabVercelAiHandler = class {
|
|
|
5804
5850
|
key,
|
|
5805
5851
|
{
|
|
5806
5852
|
type: "llm",
|
|
5807
|
-
finalize: (result) => summarizeGenerate(result ?? {}, label)
|
|
5853
|
+
finalize: (result) => summarizeGenerate(result ?? {}, label),
|
|
5854
|
+
surface: "inherit"
|
|
5808
5855
|
},
|
|
5809
5856
|
() => doGenerate()
|
|
5810
5857
|
);
|
|
@@ -5822,7 +5869,7 @@ var BitfabVercelAiHandler = class {
|
|
|
5822
5869
|
// The wrapped fn returns immediately with the live stream, so the span
|
|
5823
5870
|
// output cannot be read from the return value. `finalize` instead
|
|
5824
5871
|
// awaits the summary the accumulator resolves once the stream drains.
|
|
5825
|
-
{ type: "llm", finalize: () => summary },
|
|
5872
|
+
{ type: "llm", finalize: () => summary, surface: "inherit" },
|
|
5826
5873
|
async () => {
|
|
5827
5874
|
const result = await doStream();
|
|
5828
5875
|
const stream = result.stream.pipeThrough(
|
|
@@ -5839,6 +5886,18 @@ var BitfabVercelAiHandler = class {
|
|
|
5839
5886
|
|
|
5840
5887
|
// src/client.ts
|
|
5841
5888
|
init_warnOnce();
|
|
5889
|
+
var MIXED_SURFACE_REMEDY = {
|
|
5890
|
+
"opt-in": "Inside a withTrace/trace subtree, configure a discovered call with node()/withNode() instead, or trace this workflow with withSpan() only.",
|
|
5891
|
+
"opt-out": "Wrap the caller with withTrace()/trace() as well, or wrap this function with withSpan()."
|
|
5892
|
+
};
|
|
5893
|
+
function warnMixedTracingSurfaces(traceFunctionKey, entered, enclosing) {
|
|
5894
|
+
const enteredApi = entered === "opt-in" ? "withSpan()" : "withTrace()";
|
|
5895
|
+
const enclosingApi = enclosing === "opt-in" ? "withSpan()" : "withTrace()";
|
|
5896
|
+
warnOnce(
|
|
5897
|
+
`mixed-tracing-surface:${traceFunctionKey}:${entered}`,
|
|
5898
|
+
`opt-in and opt-out tracing are mixed in one call stack: ${enteredApi} (${entered}) for "${traceFunctionKey}" was entered inside a ${enclosingApi} call (${enclosing}). Both are recorded, and the spans nest as written. ${MIXED_SURFACE_REMEDY[entered]}`
|
|
5899
|
+
);
|
|
5900
|
+
}
|
|
5842
5901
|
var activeTraceStates = /* @__PURE__ */ new Map();
|
|
5843
5902
|
var asyncLocalStorage = null;
|
|
5844
5903
|
var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
|
|
@@ -6202,7 +6261,13 @@ var Bitfab = class {
|
|
|
6202
6261
|
this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL;
|
|
6203
6262
|
this.timeout = config.timeout ?? 12e4;
|
|
6204
6263
|
this.envVars = config.envVars ?? {};
|
|
6205
|
-
|
|
6264
|
+
if (config.enabled !== void 0) {
|
|
6265
|
+
warnOnce(
|
|
6266
|
+
"deprecated-enabled-option",
|
|
6267
|
+
"Bitfab({ enabled }) is deprecated; pass captureEnabled instead."
|
|
6268
|
+
);
|
|
6269
|
+
}
|
|
6270
|
+
this.captureConfigured = (config.captureEnabled ?? true) && (config.enabled ?? true);
|
|
6206
6271
|
this.strict = config.strict ?? false;
|
|
6207
6272
|
this.bamlClient = config.bamlClient ?? null;
|
|
6208
6273
|
if (config.dbSnapshot) {
|
|
@@ -6238,9 +6303,6 @@ var Bitfab = class {
|
|
|
6238
6303
|
if (!descriptor || typeof descriptor.value !== "function") {
|
|
6239
6304
|
throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
6240
6305
|
}
|
|
6241
|
-
if (!this.explicitlyEnabled) {
|
|
6242
|
-
return;
|
|
6243
|
-
}
|
|
6244
6306
|
descriptor.value = this.createAutoTraceRoot(
|
|
6245
6307
|
traceFunctionKey,
|
|
6246
6308
|
String(propertyKey),
|
|
@@ -6254,9 +6316,6 @@ var Bitfab = class {
|
|
|
6254
6316
|
if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) {
|
|
6255
6317
|
throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
6256
6318
|
}
|
|
6257
|
-
if (!this.explicitlyEnabled) {
|
|
6258
|
-
return method;
|
|
6259
|
-
}
|
|
6260
6319
|
return this.createAutoTraceRoot(
|
|
6261
6320
|
traceFunctionKey,
|
|
6262
6321
|
String(context.name),
|
|
@@ -6272,9 +6331,6 @@ var Bitfab = class {
|
|
|
6272
6331
|
if (!fn) {
|
|
6273
6332
|
throw new BitfabError("bitfab.withTrace requires a function");
|
|
6274
6333
|
}
|
|
6275
|
-
if (!this.explicitlyEnabled) {
|
|
6276
|
-
return fn;
|
|
6277
|
-
}
|
|
6278
6334
|
const name = fn.name !== "" ? fn.name : traceFunctionKey;
|
|
6279
6335
|
return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
|
|
6280
6336
|
}
|
|
@@ -6298,9 +6354,6 @@ var Bitfab = class {
|
|
|
6298
6354
|
if (!descriptor || typeof descriptor.value !== "function") {
|
|
6299
6355
|
throw new BitfabError("@bitfab.node can only decorate methods");
|
|
6300
6356
|
}
|
|
6301
|
-
if (!this.explicitlyEnabled) {
|
|
6302
|
-
return;
|
|
6303
|
-
}
|
|
6304
6357
|
descriptor.value = this.createAutoTraceNode(
|
|
6305
6358
|
configuration,
|
|
6306
6359
|
descriptor.value,
|
|
@@ -6313,9 +6366,6 @@ var Bitfab = class {
|
|
|
6313
6366
|
if (typeof method !== "function" || context?.kind !== "method") {
|
|
6314
6367
|
throw new BitfabError("@bitfab.node can only decorate methods");
|
|
6315
6368
|
}
|
|
6316
|
-
if (!this.explicitlyEnabled) {
|
|
6317
|
-
return method;
|
|
6318
|
-
}
|
|
6319
6369
|
return this.createAutoTraceNode(
|
|
6320
6370
|
configuration,
|
|
6321
6371
|
method,
|
|
@@ -6331,9 +6381,6 @@ var Bitfab = class {
|
|
|
6331
6381
|
throw new BitfabError("bitfab.withNode requires a function");
|
|
6332
6382
|
}
|
|
6333
6383
|
const configuration = this.resolveNodeConfiguration(options);
|
|
6334
|
-
if (!this.explicitlyEnabled) {
|
|
6335
|
-
return fn;
|
|
6336
|
-
}
|
|
6337
6384
|
const functionName = internalFunctionName ?? fn.name;
|
|
6338
6385
|
if (functionName === "") {
|
|
6339
6386
|
throw new BitfabError(
|
|
@@ -6386,9 +6433,14 @@ var Bitfab = class {
|
|
|
6386
6433
|
);
|
|
6387
6434
|
const excluded = new Set(options.exclude ?? []);
|
|
6388
6435
|
const includeWrappers = options.includeWrappers ?? false;
|
|
6436
|
+
const rootOptions = {
|
|
6437
|
+
name: options.name ?? name,
|
|
6438
|
+
type: options.type ?? "custom",
|
|
6439
|
+
surface: "opt-out"
|
|
6440
|
+
};
|
|
6389
6441
|
const tracedRoot = this.withSpan(
|
|
6390
6442
|
traceFunctionKey,
|
|
6391
|
-
|
|
6443
|
+
rootOptions,
|
|
6392
6444
|
function(...args) {
|
|
6393
6445
|
const capturePolicy = getAutoTraceCapturePolicy(self, traceFunctionKey);
|
|
6394
6446
|
self.refreshAutoTraceCapturePolicy(traceFunctionKey);
|
|
@@ -6432,6 +6484,7 @@ var Bitfab = class {
|
|
|
6432
6484
|
name: nodeConfiguration?.name ?? definition.name,
|
|
6433
6485
|
type: nodeConfiguration?.type ?? "function",
|
|
6434
6486
|
captureWhen: "nested",
|
|
6487
|
+
surface: "opt-out",
|
|
6435
6488
|
functionId: definition.id,
|
|
6436
6489
|
captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
|
|
6437
6490
|
autoTraceDefinition: definition,
|
|
@@ -6469,7 +6522,7 @@ var Bitfab = class {
|
|
|
6469
6522
|
}
|
|
6470
6523
|
);
|
|
6471
6524
|
const autoTraceRoot = function(...args) {
|
|
6472
|
-
if (!self.
|
|
6525
|
+
if (!self.shouldRecord()) {
|
|
6473
6526
|
return fn.apply(this, args);
|
|
6474
6527
|
}
|
|
6475
6528
|
return tracedRoot.apply(this, args);
|
|
@@ -6477,6 +6530,7 @@ var Bitfab = class {
|
|
|
6477
6530
|
Object.defineProperty(autoTraceRoot, "_bitfabTraceFunctionKey", {
|
|
6478
6531
|
value: traceFunctionKey
|
|
6479
6532
|
});
|
|
6533
|
+
Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
|
|
6480
6534
|
return autoTraceRoot;
|
|
6481
6535
|
}
|
|
6482
6536
|
refreshAutoTraceCapturePolicy(traceFunctionKey) {
|
|
@@ -6560,7 +6614,7 @@ var Bitfab = class {
|
|
|
6560
6614
|
"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`."
|
|
6561
6615
|
);
|
|
6562
6616
|
}
|
|
6563
|
-
if (this.
|
|
6617
|
+
if (this.captureConfigured && !this.apiKeyWarned) {
|
|
6564
6618
|
this.apiKeyWarned = true;
|
|
6565
6619
|
console.warn(
|
|
6566
6620
|
"Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing."
|
|
@@ -6568,17 +6622,21 @@ var Bitfab = class {
|
|
|
6568
6622
|
}
|
|
6569
6623
|
return void 0;
|
|
6570
6624
|
}
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6625
|
+
isCaptureEnabled() {
|
|
6626
|
+
if (!this.captureConfigured) {
|
|
6627
|
+
return false;
|
|
6628
|
+
}
|
|
6629
|
+
return this.resolveApiKey() !== void 0;
|
|
6630
|
+
}
|
|
6631
|
+
shouldRecord() {
|
|
6632
|
+
if (!this.captureConfigured && !getReplayContext() && !inSeedScope()) {
|
|
6578
6633
|
return false;
|
|
6579
6634
|
}
|
|
6580
6635
|
return this.resolveApiKey() !== void 0;
|
|
6581
6636
|
}
|
|
6637
|
+
get captureEnabled() {
|
|
6638
|
+
return this.isCaptureEnabled();
|
|
6639
|
+
}
|
|
6582
6640
|
/**
|
|
6583
6641
|
* Fetch the function with its current version and BAML prompt from the server.
|
|
6584
6642
|
*
|
|
@@ -6990,9 +7048,6 @@ var Bitfab = class {
|
|
|
6990
7048
|
* @returns A wrapped function with the same signature that creates spans for inputs and outputs
|
|
6991
7049
|
*/
|
|
6992
7050
|
withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
|
|
6993
|
-
if (!this.explicitlyEnabled) {
|
|
6994
|
-
return typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6995
|
-
}
|
|
6996
7051
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
6997
7052
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6998
7053
|
const self = this;
|
|
@@ -7006,7 +7061,7 @@ var Bitfab = class {
|
|
|
7006
7061
|
}
|
|
7007
7062
|
})();
|
|
7008
7063
|
const wrappedFn = function(...args) {
|
|
7009
|
-
if (!self.
|
|
7064
|
+
if (!self.shouldRecord()) {
|
|
7010
7065
|
return fn.apply(this, args);
|
|
7011
7066
|
}
|
|
7012
7067
|
initializeAsyncContext();
|
|
@@ -7054,11 +7109,26 @@ var Bitfab = class {
|
|
|
7054
7109
|
const currentStack = getSpanStack();
|
|
7055
7110
|
const parentContext = currentStack[currentStack.length - 1];
|
|
7056
7111
|
const replayCtxForTraceId = parentContext ? null : getReplayContext();
|
|
7057
|
-
const
|
|
7112
|
+
const seedCtxForTraceId = parentContext ? null : getSeedContext();
|
|
7113
|
+
const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
|
|
7058
7114
|
const spanId = randomUuid();
|
|
7059
7115
|
const parentSpanId = parentContext?.spanId ?? null;
|
|
7060
7116
|
const isRootSpan = parentSpanId === null;
|
|
7061
|
-
const
|
|
7117
|
+
const requestedSurface = options.surface ?? "opt-in";
|
|
7118
|
+
const surface = requestedSurface === "inherit" ? parentContext?.surface ?? "opt-in" : requestedSurface;
|
|
7119
|
+
if (requestedSurface !== "inherit" && parentContext?.surface !== void 0 && parentContext.surface !== surface) {
|
|
7120
|
+
warnMixedTracingSurfaces(
|
|
7121
|
+
traceFunctionKey,
|
|
7122
|
+
surface,
|
|
7123
|
+
parentContext.surface
|
|
7124
|
+
);
|
|
7125
|
+
}
|
|
7126
|
+
const newContext = {
|
|
7127
|
+
traceId,
|
|
7128
|
+
spanId,
|
|
7129
|
+
contexts: [],
|
|
7130
|
+
surface
|
|
7131
|
+
};
|
|
7062
7132
|
newStack = [...currentStack, newContext];
|
|
7063
7133
|
const inputs = args;
|
|
7064
7134
|
const startedAt = nowIsoTimestamp();
|
|
@@ -7340,7 +7410,7 @@ var Bitfab = class {
|
|
|
7340
7410
|
if (registeredTraceId) {
|
|
7341
7411
|
activeTraceStates.delete(registeredTraceId);
|
|
7342
7412
|
}
|
|
7343
|
-
if (getReplayContext()) {
|
|
7413
|
+
if (getReplayContext() || inSeedScope()) {
|
|
7344
7414
|
throw setupError;
|
|
7345
7415
|
}
|
|
7346
7416
|
warnOnce(
|
|
@@ -7415,7 +7485,7 @@ var Bitfab = class {
|
|
|
7415
7485
|
return {
|
|
7416
7486
|
traceId,
|
|
7417
7487
|
addContext: (context) => {
|
|
7418
|
-
if (!this.
|
|
7488
|
+
if (!this.shouldRecord()) {
|
|
7419
7489
|
return Promise.resolve();
|
|
7420
7490
|
}
|
|
7421
7491
|
if (typeof context !== "object" || context === null) {
|
|
@@ -7426,7 +7496,7 @@ var Bitfab = class {
|
|
|
7426
7496
|
});
|
|
7427
7497
|
},
|
|
7428
7498
|
setMetadata: (metadata) => {
|
|
7429
|
-
if (!this.
|
|
7499
|
+
if (!this.shouldRecord()) {
|
|
7430
7500
|
return Promise.resolve();
|
|
7431
7501
|
}
|
|
7432
7502
|
if (typeof metadata !== "object" || metadata === null) {
|
|
@@ -7435,7 +7505,7 @@ var Bitfab = class {
|
|
|
7435
7505
|
return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata });
|
|
7436
7506
|
},
|
|
7437
7507
|
setSessionId: (sessionId) => {
|
|
7438
|
-
if (!this.
|
|
7508
|
+
if (!this.shouldRecord()) {
|
|
7439
7509
|
return Promise.resolve();
|
|
7440
7510
|
}
|
|
7441
7511
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
@@ -7444,7 +7514,7 @@ var Bitfab = class {
|
|
|
7444
7514
|
return this.httpClient.patchTrace(traceId, { setSessionId: sessionId });
|
|
7445
7515
|
},
|
|
7446
7516
|
setName: (name) => {
|
|
7447
|
-
if (!this.
|
|
7517
|
+
if (!this.shouldRecord()) {
|
|
7448
7518
|
return Promise.resolve();
|
|
7449
7519
|
}
|
|
7450
7520
|
if (typeof name !== "string" || name.length === 0) {
|
|
@@ -7680,22 +7750,13 @@ var Bitfab = class {
|
|
|
7680
7750
|
clearMockOverrides() {
|
|
7681
7751
|
this.mockOverrides.length = 0;
|
|
7682
7752
|
}
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
* rather than against a previous run.
|
|
7691
|
-
*
|
|
7692
|
-
* A seeded trace has no child spans and no database pin, so replay mocking
|
|
7693
|
-
* has nothing recorded to substitute and `dbBranch` refuses it. Pass
|
|
7694
|
-
* `mockOverride` at replay time for calls that must not run.
|
|
7695
|
-
*
|
|
7696
|
-
* @returns The trace ID, usable with `replay({ traceIds: [...] })`.
|
|
7697
|
-
*/
|
|
7698
|
-
seedTrace(traceFunctionKey, options) {
|
|
7753
|
+
seedTrace(traceFunctionKey, optionsOrFn, runOptions) {
|
|
7754
|
+
if (typeof optionsOrFn === "function") {
|
|
7755
|
+
return this.seedTraceByRunning(traceFunctionKey, optionsOrFn, runOptions);
|
|
7756
|
+
}
|
|
7757
|
+
return this.seedTraceFromCase(traceFunctionKey, optionsOrFn);
|
|
7758
|
+
}
|
|
7759
|
+
seedTraceFromCase(traceFunctionKey, options) {
|
|
7699
7760
|
const { input } = options;
|
|
7700
7761
|
const fn = options.fn?._bitfabWrappedFn ?? options.fn;
|
|
7701
7762
|
if (fn && input.length < fn.length) {
|
|
@@ -7744,6 +7805,50 @@ var Bitfab = class {
|
|
|
7744
7805
|
}
|
|
7745
7806
|
return traceId;
|
|
7746
7807
|
}
|
|
7808
|
+
async seedTraceByRunning(traceFunctionKey, fn, options) {
|
|
7809
|
+
const wrappedKey = fn._bitfabTraceFunctionKey;
|
|
7810
|
+
let target = fn;
|
|
7811
|
+
if (wrappedKey === void 0) {
|
|
7812
|
+
target = this.withSpan(
|
|
7813
|
+
traceFunctionKey,
|
|
7814
|
+
{ name: traceFunctionKey, type: "agent" },
|
|
7815
|
+
fn
|
|
7816
|
+
);
|
|
7817
|
+
} else if (wrappedKey !== traceFunctionKey) {
|
|
7818
|
+
throw new BitfabError(
|
|
7819
|
+
`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.`
|
|
7820
|
+
);
|
|
7821
|
+
}
|
|
7822
|
+
await seedContextReady;
|
|
7823
|
+
const traceId = randomUuid();
|
|
7824
|
+
activeTraceStates.set(traceId, {
|
|
7825
|
+
traceId,
|
|
7826
|
+
startedAt: nowIsoTimestamp(),
|
|
7827
|
+
contexts: [],
|
|
7828
|
+
ingestionType: "seeded",
|
|
7829
|
+
...options?.sessionId !== void 0 && { sessionId: options.sessionId },
|
|
7830
|
+
...options?.name !== void 0 && { name: options.name },
|
|
7831
|
+
...options?.metadata !== void 0 && { metadata: options.metadata }
|
|
7832
|
+
});
|
|
7833
|
+
const args = options?.args ?? [];
|
|
7834
|
+
let unrecorded = true;
|
|
7835
|
+
try {
|
|
7836
|
+
await runWithSeedContext({ traceId }, async () => target(...args));
|
|
7837
|
+
} finally {
|
|
7838
|
+
try {
|
|
7839
|
+
const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
|
|
7840
|
+
await flushTraces2(3e4);
|
|
7841
|
+
} finally {
|
|
7842
|
+
unrecorded = activeTraceStates.delete(traceId);
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
if (unrecorded) {
|
|
7846
|
+
throw new BitfabError(
|
|
7847
|
+
`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.`
|
|
7848
|
+
);
|
|
7849
|
+
}
|
|
7850
|
+
return traceId;
|
|
7851
|
+
}
|
|
7747
7852
|
async replay(traceFunctionKey, fn, options) {
|
|
7748
7853
|
const wrappedKey = fn._bitfabTraceFunctionKey;
|
|
7749
7854
|
let replayFn = fn;
|
|
@@ -8004,7 +8109,7 @@ init_replay();
|
|
|
8004
8109
|
function defineReplayRegistry(registry) {
|
|
8005
8110
|
return registry;
|
|
8006
8111
|
}
|
|
8007
|
-
async function seedFromRegistry(registry, pipeline, cases) {
|
|
8112
|
+
async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
8008
8113
|
const registration = registry[pipeline];
|
|
8009
8114
|
if (registration === void 0) {
|
|
8010
8115
|
throw new BitfabError(
|
|
@@ -8012,6 +8117,19 @@ async function seedFromRegistry(registry, pipeline, cases) {
|
|
|
8012
8117
|
);
|
|
8013
8118
|
}
|
|
8014
8119
|
const traceFunctionKey = resolveTraceFunctionKey(registration);
|
|
8120
|
+
if (options.run === true) {
|
|
8121
|
+
const traceIds2 = [];
|
|
8122
|
+
for (const seedCase of cases) {
|
|
8123
|
+
traceIds2.push(
|
|
8124
|
+
await registration.client.seedTrace(traceFunctionKey, registration.fn, {
|
|
8125
|
+
args: seedCase.input,
|
|
8126
|
+
metadata: seedCase.metadata,
|
|
8127
|
+
sessionId: seedCase.sessionId
|
|
8128
|
+
})
|
|
8129
|
+
);
|
|
8130
|
+
}
|
|
8131
|
+
return { pipeline, traceFunctionKey, traceIds: traceIds2 };
|
|
8132
|
+
}
|
|
8015
8133
|
const traceIds = cases.map(
|
|
8016
8134
|
(seedCase) => registration.client.seedTrace(traceFunctionKey, {
|
|
8017
8135
|
input: seedCase.input,
|