@bitfab/sdk 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-UGFTBSGS.js → chunk-5LY4XOUY.js} +6 -3
- package/dist/{chunk-UGFTBSGS.js.map → chunk-5LY4XOUY.js.map} +1 -1
- package/dist/{chunk-QJ6IFPGU.js → chunk-RBKGO5ZC.js} +6 -3
- package/dist/{chunk-QJ6IFPGU.js.map → chunk-RBKGO5ZC.js.map} +1 -1
- package/dist/{chunk-BG3A5HNC.js → chunk-TNGKCPBP.js} +10 -4
- package/dist/chunk-TNGKCPBP.js.map +1 -0
- package/dist/{chunk-BC5OYWAM.js → chunk-V4MRFSWK.js} +173 -67
- package/dist/chunk-V4MRFSWK.js.map +1 -0
- package/dist/{http-NZHGC5YF.js → http-FKD4GT55.js} +2 -2
- package/dist/{http-F5L466DI.js → http-TPVUGXYJ.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-PLACY77M.js → replay-PICGOZVG.js} +3 -3
- package/dist/replayCli.js +31 -10
- package/dist/replayCli.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BC5OYWAM.js.map +0 -1
- package/dist/chunk-BG3A5HNC.js.map +0 -1
- /package/dist/{http-F5L466DI.js.map → http-FKD4GT55.js.map} +0 -0
- /package/dist/{http-NZHGC5YF.js.map → http-TPVUGXYJ.js.map} +0 -0
- /package/dist/{replay-PLACY77M.js.map → replay-PICGOZVG.js.map} +0 -0
package/dist/node.cjs
CHANGED
|
@@ -88,7 +88,7 @@ var __version__, __packageName__;
|
|
|
88
88
|
var init_version_generated = __esm({
|
|
89
89
|
"src/version.generated.ts"() {
|
|
90
90
|
"use strict";
|
|
91
|
-
__version__ = "0.
|
|
91
|
+
__version__ = "0.43.1";
|
|
92
92
|
__packageName__ = "@bitfab/sdk";
|
|
93
93
|
}
|
|
94
94
|
});
|
|
@@ -1848,7 +1848,7 @@ var init_http = __esm({
|
|
|
1848
1848
|
* Start a replay session by fetching historical traces.
|
|
1849
1849
|
* Blocking call - creates a test run and returns lightweight item references.
|
|
1850
1850
|
*/
|
|
1851
|
-
async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
|
|
1851
|
+
async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts, includeOriginalMetadata) {
|
|
1852
1852
|
const payload = { traceFunctionKey };
|
|
1853
1853
|
if (limit !== void 0) {
|
|
1854
1854
|
payload.limit = limit;
|
|
@@ -1884,6 +1884,9 @@ var init_http = __esm({
|
|
|
1884
1884
|
if (attempts !== void 0 && attempts > 1) {
|
|
1885
1885
|
payload.attempts = attempts;
|
|
1886
1886
|
}
|
|
1887
|
+
if (includeOriginalMetadata) {
|
|
1888
|
+
payload.includeOriginalMetadata = true;
|
|
1889
|
+
}
|
|
1887
1890
|
const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
|
|
1888
1891
|
return this.request("/api/sdk/replay/start", payload, {
|
|
1889
1892
|
timeout
|
|
@@ -2497,6 +2500,9 @@ function reportReplayProgress(progress) {
|
|
|
2497
2500
|
} catch {
|
|
2498
2501
|
}
|
|
2499
2502
|
}
|
|
2503
|
+
function isPlainRecord(value) {
|
|
2504
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2505
|
+
}
|
|
2500
2506
|
function errorMessage(error) {
|
|
2501
2507
|
return error instanceof Error ? error.message : String(error);
|
|
2502
2508
|
}
|
|
@@ -2644,12 +2650,14 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
|
|
|
2644
2650
|
inputs = deserializeInputs(spanData);
|
|
2645
2651
|
originalOutput = deserializeOutput(spanData);
|
|
2646
2652
|
if (adaptInputs) {
|
|
2653
|
+
const originalMetadata = serverItem.originalMetadata;
|
|
2647
2654
|
inputs = adaptInputs(inputs, {
|
|
2648
2655
|
originalTraceId,
|
|
2649
2656
|
originalSpanId,
|
|
2650
2657
|
// Deprecated aliases for originalTraceId/originalSpanId.
|
|
2651
2658
|
sourceTraceId: originalTraceId,
|
|
2652
|
-
sourceSpanId: originalSpanId
|
|
2659
|
+
sourceSpanId: originalSpanId,
|
|
2660
|
+
metadata: isPlainRecord(originalMetadata) ? { ...originalMetadata } : {}
|
|
2653
2661
|
});
|
|
2654
2662
|
}
|
|
2655
2663
|
const hasOverrides = resolvedOverrides.length > 0;
|
|
@@ -2939,7 +2947,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
|
|
|
2939
2947
|
options?.datasetId,
|
|
2940
2948
|
options?.graderIds,
|
|
2941
2949
|
resolveDbBranchSettings(options?.dbBranch),
|
|
2942
|
-
attempts
|
|
2950
|
+
attempts,
|
|
2951
|
+
options?.adaptInputs !== void 0
|
|
2943
2952
|
);
|
|
2944
2953
|
if (serverItems.length === 0) {
|
|
2945
2954
|
try {
|
|
@@ -5300,7 +5309,8 @@ var BitfabLangGraphIntegration = class {
|
|
|
5300
5309
|
type: "function",
|
|
5301
5310
|
captureWhen: "nested",
|
|
5302
5311
|
mockOnReplay: shouldMock,
|
|
5303
|
-
finalize: finalizeToolResult
|
|
5312
|
+
finalize: finalizeToolResult,
|
|
5313
|
+
surface: "inherit"
|
|
5304
5314
|
},
|
|
5305
5315
|
async (_args) => await originalInvoke(input, ...rest)
|
|
5306
5316
|
);
|
|
@@ -5343,7 +5353,7 @@ var BitfabLangGraphIntegration = class {
|
|
|
5343
5353
|
wrapInvoke(fn) {
|
|
5344
5354
|
return this.client.withSpan(
|
|
5345
5355
|
this.traceFunctionKey,
|
|
5346
|
-
{ name: this.traceFunctionKey, type: "agent" },
|
|
5356
|
+
{ name: this.traceFunctionKey, type: "agent", surface: "inherit" },
|
|
5347
5357
|
fn
|
|
5348
5358
|
);
|
|
5349
5359
|
}
|
|
@@ -5396,7 +5406,11 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
5396
5406
|
}
|
|
5397
5407
|
return res?.finalOutput;
|
|
5398
5408
|
};
|
|
5399
|
-
const options_ = {
|
|
5409
|
+
const options_ = {
|
|
5410
|
+
type: "agent",
|
|
5411
|
+
finalize,
|
|
5412
|
+
surface: "inherit"
|
|
5413
|
+
};
|
|
5400
5414
|
const traced = this.withSpanFn(
|
|
5401
5415
|
this.traceFunctionKey,
|
|
5402
5416
|
options_,
|
|
@@ -5460,6 +5474,38 @@ _context = new WeakMap();
|
|
|
5460
5474
|
|
|
5461
5475
|
// src/client.ts
|
|
5462
5476
|
init_replayContext();
|
|
5477
|
+
|
|
5478
|
+
// src/seedContext.ts
|
|
5479
|
+
init_asyncStorage();
|
|
5480
|
+
var seedContextStorage = null;
|
|
5481
|
+
var SEED_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.seedContextStorage");
|
|
5482
|
+
var seedContextReady = asyncStorageReady.then(() => {
|
|
5483
|
+
const shared = globalThis;
|
|
5484
|
+
const existing = shared[SEED_CONTEXT_STORAGE_SYMBOL];
|
|
5485
|
+
if (existing) {
|
|
5486
|
+
seedContextStorage = existing;
|
|
5487
|
+
return;
|
|
5488
|
+
}
|
|
5489
|
+
const created = createAsyncLocalStorage();
|
|
5490
|
+
if (created) {
|
|
5491
|
+
shared[SEED_CONTEXT_STORAGE_SYMBOL] = created;
|
|
5492
|
+
seedContextStorage = created;
|
|
5493
|
+
}
|
|
5494
|
+
});
|
|
5495
|
+
function getSeedContext() {
|
|
5496
|
+
return seedContextStorage?.getStore() ?? null;
|
|
5497
|
+
}
|
|
5498
|
+
function inSeedScope() {
|
|
5499
|
+
return getSeedContext() !== null;
|
|
5500
|
+
}
|
|
5501
|
+
function runWithSeedContext(ctx, fn) {
|
|
5502
|
+
if (seedContextStorage) {
|
|
5503
|
+
return seedContextStorage.run(ctx, fn);
|
|
5504
|
+
}
|
|
5505
|
+
return fn();
|
|
5506
|
+
}
|
|
5507
|
+
|
|
5508
|
+
// src/client.ts
|
|
5463
5509
|
init_serialize();
|
|
5464
5510
|
|
|
5465
5511
|
// src/tracing.ts
|
|
@@ -5795,7 +5841,8 @@ var BitfabVercelAiHandler = class {
|
|
|
5795
5841
|
key,
|
|
5796
5842
|
{
|
|
5797
5843
|
type: "llm",
|
|
5798
|
-
finalize: (result) => summarizeGenerate(result ?? {}, label)
|
|
5844
|
+
finalize: (result) => summarizeGenerate(result ?? {}, label),
|
|
5845
|
+
surface: "inherit"
|
|
5799
5846
|
},
|
|
5800
5847
|
() => doGenerate()
|
|
5801
5848
|
);
|
|
@@ -5813,7 +5860,7 @@ var BitfabVercelAiHandler = class {
|
|
|
5813
5860
|
// The wrapped fn returns immediately with the live stream, so the span
|
|
5814
5861
|
// output cannot be read from the return value. `finalize` instead
|
|
5815
5862
|
// awaits the summary the accumulator resolves once the stream drains.
|
|
5816
|
-
{ type: "llm", finalize: () => summary },
|
|
5863
|
+
{ type: "llm", finalize: () => summary, surface: "inherit" },
|
|
5817
5864
|
async () => {
|
|
5818
5865
|
const result = await doStream();
|
|
5819
5866
|
const stream = result.stream.pipeThrough(
|
|
@@ -5830,6 +5877,18 @@ var BitfabVercelAiHandler = class {
|
|
|
5830
5877
|
|
|
5831
5878
|
// src/client.ts
|
|
5832
5879
|
init_warnOnce();
|
|
5880
|
+
var MIXED_SURFACE_REMEDY = {
|
|
5881
|
+
"opt-in": "Inside a withTrace/trace subtree, configure a discovered call with node()/withNode() instead, or trace this workflow with withSpan() only.",
|
|
5882
|
+
"opt-out": "Wrap the caller with withTrace()/trace() as well, or wrap this function with withSpan()."
|
|
5883
|
+
};
|
|
5884
|
+
function warnMixedTracingSurfaces(traceFunctionKey, entered, enclosing) {
|
|
5885
|
+
const enteredApi = entered === "opt-in" ? "withSpan()" : "withTrace()";
|
|
5886
|
+
const enclosingApi = enclosing === "opt-in" ? "withSpan()" : "withTrace()";
|
|
5887
|
+
warnOnce(
|
|
5888
|
+
`mixed-tracing-surface:${traceFunctionKey}:${entered}`,
|
|
5889
|
+
`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]}`
|
|
5890
|
+
);
|
|
5891
|
+
}
|
|
5833
5892
|
var activeTraceStates = /* @__PURE__ */ new Map();
|
|
5834
5893
|
var asyncLocalStorage = null;
|
|
5835
5894
|
var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
|
|
@@ -6193,7 +6252,13 @@ var Bitfab = class {
|
|
|
6193
6252
|
this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL;
|
|
6194
6253
|
this.timeout = config.timeout ?? 12e4;
|
|
6195
6254
|
this.envVars = config.envVars ?? {};
|
|
6196
|
-
|
|
6255
|
+
if (config.enabled !== void 0) {
|
|
6256
|
+
warnOnce(
|
|
6257
|
+
"deprecated-enabled-option",
|
|
6258
|
+
"Bitfab({ enabled }) is deprecated; pass captureEnabled instead."
|
|
6259
|
+
);
|
|
6260
|
+
}
|
|
6261
|
+
this.captureConfigured = (config.captureEnabled ?? true) && (config.enabled ?? true);
|
|
6197
6262
|
this.strict = config.strict ?? false;
|
|
6198
6263
|
this.bamlClient = config.bamlClient ?? null;
|
|
6199
6264
|
if (config.dbSnapshot) {
|
|
@@ -6229,9 +6294,6 @@ var Bitfab = class {
|
|
|
6229
6294
|
if (!descriptor || typeof descriptor.value !== "function") {
|
|
6230
6295
|
throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
6231
6296
|
}
|
|
6232
|
-
if (!this.explicitlyEnabled) {
|
|
6233
|
-
return;
|
|
6234
|
-
}
|
|
6235
6297
|
descriptor.value = this.createAutoTraceRoot(
|
|
6236
6298
|
traceFunctionKey,
|
|
6237
6299
|
String(propertyKey),
|
|
@@ -6245,9 +6307,6 @@ var Bitfab = class {
|
|
|
6245
6307
|
if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) {
|
|
6246
6308
|
throw new BitfabError("@bitfab.trace can only decorate methods");
|
|
6247
6309
|
}
|
|
6248
|
-
if (!this.explicitlyEnabled) {
|
|
6249
|
-
return method;
|
|
6250
|
-
}
|
|
6251
6310
|
return this.createAutoTraceRoot(
|
|
6252
6311
|
traceFunctionKey,
|
|
6253
6312
|
String(context.name),
|
|
@@ -6263,9 +6322,6 @@ var Bitfab = class {
|
|
|
6263
6322
|
if (!fn) {
|
|
6264
6323
|
throw new BitfabError("bitfab.withTrace requires a function");
|
|
6265
6324
|
}
|
|
6266
|
-
if (!this.explicitlyEnabled) {
|
|
6267
|
-
return fn;
|
|
6268
|
-
}
|
|
6269
6325
|
const name = fn.name !== "" ? fn.name : traceFunctionKey;
|
|
6270
6326
|
return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
|
|
6271
6327
|
}
|
|
@@ -6289,9 +6345,6 @@ var Bitfab = class {
|
|
|
6289
6345
|
if (!descriptor || typeof descriptor.value !== "function") {
|
|
6290
6346
|
throw new BitfabError("@bitfab.node can only decorate methods");
|
|
6291
6347
|
}
|
|
6292
|
-
if (!this.explicitlyEnabled) {
|
|
6293
|
-
return;
|
|
6294
|
-
}
|
|
6295
6348
|
descriptor.value = this.createAutoTraceNode(
|
|
6296
6349
|
configuration,
|
|
6297
6350
|
descriptor.value,
|
|
@@ -6304,9 +6357,6 @@ var Bitfab = class {
|
|
|
6304
6357
|
if (typeof method !== "function" || context?.kind !== "method") {
|
|
6305
6358
|
throw new BitfabError("@bitfab.node can only decorate methods");
|
|
6306
6359
|
}
|
|
6307
|
-
if (!this.explicitlyEnabled) {
|
|
6308
|
-
return method;
|
|
6309
|
-
}
|
|
6310
6360
|
return this.createAutoTraceNode(
|
|
6311
6361
|
configuration,
|
|
6312
6362
|
method,
|
|
@@ -6322,9 +6372,6 @@ var Bitfab = class {
|
|
|
6322
6372
|
throw new BitfabError("bitfab.withNode requires a function");
|
|
6323
6373
|
}
|
|
6324
6374
|
const configuration = this.resolveNodeConfiguration(options);
|
|
6325
|
-
if (!this.explicitlyEnabled) {
|
|
6326
|
-
return fn;
|
|
6327
|
-
}
|
|
6328
6375
|
const functionName = internalFunctionName ?? fn.name;
|
|
6329
6376
|
if (functionName === "") {
|
|
6330
6377
|
throw new BitfabError(
|
|
@@ -6377,9 +6424,14 @@ var Bitfab = class {
|
|
|
6377
6424
|
);
|
|
6378
6425
|
const excluded = new Set(options.exclude ?? []);
|
|
6379
6426
|
const includeWrappers = options.includeWrappers ?? false;
|
|
6427
|
+
const rootOptions = {
|
|
6428
|
+
name: options.name ?? name,
|
|
6429
|
+
type: options.type ?? "custom",
|
|
6430
|
+
surface: "opt-out"
|
|
6431
|
+
};
|
|
6380
6432
|
const tracedRoot = this.withSpan(
|
|
6381
6433
|
traceFunctionKey,
|
|
6382
|
-
|
|
6434
|
+
rootOptions,
|
|
6383
6435
|
function(...args) {
|
|
6384
6436
|
const capturePolicy = getAutoTraceCapturePolicy(self, traceFunctionKey);
|
|
6385
6437
|
self.refreshAutoTraceCapturePolicy(traceFunctionKey);
|
|
@@ -6423,6 +6475,7 @@ var Bitfab = class {
|
|
|
6423
6475
|
name: nodeConfiguration?.name ?? definition.name,
|
|
6424
6476
|
type: nodeConfiguration?.type ?? "function",
|
|
6425
6477
|
captureWhen: "nested",
|
|
6478
|
+
surface: "opt-out",
|
|
6426
6479
|
functionId: definition.id,
|
|
6427
6480
|
captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
|
|
6428
6481
|
autoTraceDefinition: definition,
|
|
@@ -6460,7 +6513,7 @@ var Bitfab = class {
|
|
|
6460
6513
|
}
|
|
6461
6514
|
);
|
|
6462
6515
|
const autoTraceRoot = function(...args) {
|
|
6463
|
-
if (!self.
|
|
6516
|
+
if (!self.shouldRecord()) {
|
|
6464
6517
|
return fn.apply(this, args);
|
|
6465
6518
|
}
|
|
6466
6519
|
return tracedRoot.apply(this, args);
|
|
@@ -6468,6 +6521,7 @@ var Bitfab = class {
|
|
|
6468
6521
|
Object.defineProperty(autoTraceRoot, "_bitfabTraceFunctionKey", {
|
|
6469
6522
|
value: traceFunctionKey
|
|
6470
6523
|
});
|
|
6524
|
+
Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
|
|
6471
6525
|
return autoTraceRoot;
|
|
6472
6526
|
}
|
|
6473
6527
|
refreshAutoTraceCapturePolicy(traceFunctionKey) {
|
|
@@ -6551,7 +6605,7 @@ var Bitfab = class {
|
|
|
6551
6605
|
"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`."
|
|
6552
6606
|
);
|
|
6553
6607
|
}
|
|
6554
|
-
if (this.
|
|
6608
|
+
if (this.captureConfigured && !this.apiKeyWarned) {
|
|
6555
6609
|
this.apiKeyWarned = true;
|
|
6556
6610
|
console.warn(
|
|
6557
6611
|
"Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing."
|
|
@@ -6559,17 +6613,21 @@ var Bitfab = class {
|
|
|
6559
6613
|
}
|
|
6560
6614
|
return void 0;
|
|
6561
6615
|
}
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6616
|
+
isCaptureEnabled() {
|
|
6617
|
+
if (!this.captureConfigured) {
|
|
6618
|
+
return false;
|
|
6619
|
+
}
|
|
6620
|
+
return this.resolveApiKey() !== void 0;
|
|
6621
|
+
}
|
|
6622
|
+
shouldRecord() {
|
|
6623
|
+
if (!this.captureConfigured && !getReplayContext() && !inSeedScope()) {
|
|
6569
6624
|
return false;
|
|
6570
6625
|
}
|
|
6571
6626
|
return this.resolveApiKey() !== void 0;
|
|
6572
6627
|
}
|
|
6628
|
+
get captureEnabled() {
|
|
6629
|
+
return this.isCaptureEnabled();
|
|
6630
|
+
}
|
|
6573
6631
|
/**
|
|
6574
6632
|
* Fetch the function with its current version and BAML prompt from the server.
|
|
6575
6633
|
*
|
|
@@ -6981,9 +7039,6 @@ var Bitfab = class {
|
|
|
6981
7039
|
* @returns A wrapped function with the same signature that creates spans for inputs and outputs
|
|
6982
7040
|
*/
|
|
6983
7041
|
withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
|
|
6984
|
-
if (!this.explicitlyEnabled) {
|
|
6985
|
-
return typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6986
|
-
}
|
|
6987
7042
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
6988
7043
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
6989
7044
|
const self = this;
|
|
@@ -6997,7 +7052,7 @@ var Bitfab = class {
|
|
|
6997
7052
|
}
|
|
6998
7053
|
})();
|
|
6999
7054
|
const wrappedFn = function(...args) {
|
|
7000
|
-
if (!self.
|
|
7055
|
+
if (!self.shouldRecord()) {
|
|
7001
7056
|
return fn.apply(this, args);
|
|
7002
7057
|
}
|
|
7003
7058
|
initializeAsyncContext();
|
|
@@ -7045,11 +7100,26 @@ var Bitfab = class {
|
|
|
7045
7100
|
const currentStack = getSpanStack();
|
|
7046
7101
|
const parentContext = currentStack[currentStack.length - 1];
|
|
7047
7102
|
const replayCtxForTraceId = parentContext ? null : getReplayContext();
|
|
7048
|
-
const
|
|
7103
|
+
const seedCtxForTraceId = parentContext ? null : getSeedContext();
|
|
7104
|
+
const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
|
|
7049
7105
|
const spanId = randomUuid();
|
|
7050
7106
|
const parentSpanId = parentContext?.spanId ?? null;
|
|
7051
7107
|
const isRootSpan = parentSpanId === null;
|
|
7052
|
-
const
|
|
7108
|
+
const requestedSurface = options.surface ?? "opt-in";
|
|
7109
|
+
const surface = requestedSurface === "inherit" ? parentContext?.surface ?? "opt-in" : requestedSurface;
|
|
7110
|
+
if (requestedSurface !== "inherit" && parentContext?.surface !== void 0 && parentContext.surface !== surface) {
|
|
7111
|
+
warnMixedTracingSurfaces(
|
|
7112
|
+
traceFunctionKey,
|
|
7113
|
+
surface,
|
|
7114
|
+
parentContext.surface
|
|
7115
|
+
);
|
|
7116
|
+
}
|
|
7117
|
+
const newContext = {
|
|
7118
|
+
traceId,
|
|
7119
|
+
spanId,
|
|
7120
|
+
contexts: [],
|
|
7121
|
+
surface
|
|
7122
|
+
};
|
|
7053
7123
|
newStack = [...currentStack, newContext];
|
|
7054
7124
|
const inputs = args;
|
|
7055
7125
|
const startedAt = nowIsoTimestamp();
|
|
@@ -7331,7 +7401,7 @@ var Bitfab = class {
|
|
|
7331
7401
|
if (registeredTraceId) {
|
|
7332
7402
|
activeTraceStates.delete(registeredTraceId);
|
|
7333
7403
|
}
|
|
7334
|
-
if (getReplayContext()) {
|
|
7404
|
+
if (getReplayContext() || inSeedScope()) {
|
|
7335
7405
|
throw setupError;
|
|
7336
7406
|
}
|
|
7337
7407
|
warnOnce(
|
|
@@ -7406,7 +7476,7 @@ var Bitfab = class {
|
|
|
7406
7476
|
return {
|
|
7407
7477
|
traceId,
|
|
7408
7478
|
addContext: (context) => {
|
|
7409
|
-
if (!this.
|
|
7479
|
+
if (!this.shouldRecord()) {
|
|
7410
7480
|
return Promise.resolve();
|
|
7411
7481
|
}
|
|
7412
7482
|
if (typeof context !== "object" || context === null) {
|
|
@@ -7417,7 +7487,7 @@ var Bitfab = class {
|
|
|
7417
7487
|
});
|
|
7418
7488
|
},
|
|
7419
7489
|
setMetadata: (metadata) => {
|
|
7420
|
-
if (!this.
|
|
7490
|
+
if (!this.shouldRecord()) {
|
|
7421
7491
|
return Promise.resolve();
|
|
7422
7492
|
}
|
|
7423
7493
|
if (typeof metadata !== "object" || metadata === null) {
|
|
@@ -7426,7 +7496,7 @@ var Bitfab = class {
|
|
|
7426
7496
|
return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata });
|
|
7427
7497
|
},
|
|
7428
7498
|
setSessionId: (sessionId) => {
|
|
7429
|
-
if (!this.
|
|
7499
|
+
if (!this.shouldRecord()) {
|
|
7430
7500
|
return Promise.resolve();
|
|
7431
7501
|
}
|
|
7432
7502
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
@@ -7435,7 +7505,7 @@ var Bitfab = class {
|
|
|
7435
7505
|
return this.httpClient.patchTrace(traceId, { setSessionId: sessionId });
|
|
7436
7506
|
},
|
|
7437
7507
|
setName: (name) => {
|
|
7438
|
-
if (!this.
|
|
7508
|
+
if (!this.shouldRecord()) {
|
|
7439
7509
|
return Promise.resolve();
|
|
7440
7510
|
}
|
|
7441
7511
|
if (typeof name !== "string" || name.length === 0) {
|
|
@@ -7671,22 +7741,13 @@ var Bitfab = class {
|
|
|
7671
7741
|
clearMockOverrides() {
|
|
7672
7742
|
this.mockOverrides.length = 0;
|
|
7673
7743
|
}
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
* rather than against a previous run.
|
|
7682
|
-
*
|
|
7683
|
-
* A seeded trace has no child spans and no database pin, so replay mocking
|
|
7684
|
-
* has nothing recorded to substitute and `dbBranch` refuses it. Pass
|
|
7685
|
-
* `mockOverride` at replay time for calls that must not run.
|
|
7686
|
-
*
|
|
7687
|
-
* @returns The trace ID, usable with `replay({ traceIds: [...] })`.
|
|
7688
|
-
*/
|
|
7689
|
-
seedTrace(traceFunctionKey, options) {
|
|
7744
|
+
seedTrace(traceFunctionKey, optionsOrFn, runOptions) {
|
|
7745
|
+
if (typeof optionsOrFn === "function") {
|
|
7746
|
+
return this.seedTraceByRunning(traceFunctionKey, optionsOrFn, runOptions);
|
|
7747
|
+
}
|
|
7748
|
+
return this.seedTraceFromCase(traceFunctionKey, optionsOrFn);
|
|
7749
|
+
}
|
|
7750
|
+
seedTraceFromCase(traceFunctionKey, options) {
|
|
7690
7751
|
const { input } = options;
|
|
7691
7752
|
const fn = options.fn?._bitfabWrappedFn ?? options.fn;
|
|
7692
7753
|
if (fn && input.length < fn.length) {
|
|
@@ -7735,6 +7796,50 @@ var Bitfab = class {
|
|
|
7735
7796
|
}
|
|
7736
7797
|
return traceId;
|
|
7737
7798
|
}
|
|
7799
|
+
async seedTraceByRunning(traceFunctionKey, fn, options) {
|
|
7800
|
+
const wrappedKey = fn._bitfabTraceFunctionKey;
|
|
7801
|
+
let target = fn;
|
|
7802
|
+
if (wrappedKey === void 0) {
|
|
7803
|
+
target = this.withSpan(
|
|
7804
|
+
traceFunctionKey,
|
|
7805
|
+
{ name: traceFunctionKey, type: "agent" },
|
|
7806
|
+
fn
|
|
7807
|
+
);
|
|
7808
|
+
} else if (wrappedKey !== traceFunctionKey) {
|
|
7809
|
+
throw new BitfabError(
|
|
7810
|
+
`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.`
|
|
7811
|
+
);
|
|
7812
|
+
}
|
|
7813
|
+
await seedContextReady;
|
|
7814
|
+
const traceId = randomUuid();
|
|
7815
|
+
activeTraceStates.set(traceId, {
|
|
7816
|
+
traceId,
|
|
7817
|
+
startedAt: nowIsoTimestamp(),
|
|
7818
|
+
contexts: [],
|
|
7819
|
+
ingestionType: "seeded",
|
|
7820
|
+
...options?.sessionId !== void 0 && { sessionId: options.sessionId },
|
|
7821
|
+
...options?.name !== void 0 && { name: options.name },
|
|
7822
|
+
...options?.metadata !== void 0 && { metadata: options.metadata }
|
|
7823
|
+
});
|
|
7824
|
+
const args = options?.args ?? [];
|
|
7825
|
+
let unrecorded = true;
|
|
7826
|
+
try {
|
|
7827
|
+
await runWithSeedContext({ traceId }, async () => target(...args));
|
|
7828
|
+
} finally {
|
|
7829
|
+
try {
|
|
7830
|
+
const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
|
|
7831
|
+
await flushTraces2(3e4);
|
|
7832
|
+
} finally {
|
|
7833
|
+
unrecorded = activeTraceStates.delete(traceId);
|
|
7834
|
+
}
|
|
7835
|
+
}
|
|
7836
|
+
if (unrecorded) {
|
|
7837
|
+
throw new BitfabError(
|
|
7838
|
+
`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.`
|
|
7839
|
+
);
|
|
7840
|
+
}
|
|
7841
|
+
return traceId;
|
|
7842
|
+
}
|
|
7738
7843
|
async replay(traceFunctionKey, fn, options) {
|
|
7739
7844
|
const wrappedKey = fn._bitfabTraceFunctionKey;
|
|
7740
7845
|
let replayFn = fn;
|
|
@@ -7995,7 +8100,7 @@ init_replay();
|
|
|
7995
8100
|
function defineReplayRegistry(registry) {
|
|
7996
8101
|
return registry;
|
|
7997
8102
|
}
|
|
7998
|
-
async function seedFromRegistry(registry, pipeline, cases) {
|
|
8103
|
+
async function seedFromRegistry(registry, pipeline, cases, options = {}) {
|
|
7999
8104
|
const registration = registry[pipeline];
|
|
8000
8105
|
if (registration === void 0) {
|
|
8001
8106
|
throw new BitfabError(
|
|
@@ -8003,6 +8108,19 @@ async function seedFromRegistry(registry, pipeline, cases) {
|
|
|
8003
8108
|
);
|
|
8004
8109
|
}
|
|
8005
8110
|
const traceFunctionKey = resolveTraceFunctionKey(registration);
|
|
8111
|
+
if (options.run === true) {
|
|
8112
|
+
const traceIds2 = [];
|
|
8113
|
+
for (const seedCase of cases) {
|
|
8114
|
+
traceIds2.push(
|
|
8115
|
+
await registration.client.seedTrace(traceFunctionKey, registration.fn, {
|
|
8116
|
+
args: seedCase.input,
|
|
8117
|
+
metadata: seedCase.metadata,
|
|
8118
|
+
sessionId: seedCase.sessionId
|
|
8119
|
+
})
|
|
8120
|
+
);
|
|
8121
|
+
}
|
|
8122
|
+
return { pipeline, traceFunctionKey, traceIds: traceIds2 };
|
|
8123
|
+
}
|
|
8006
8124
|
const traceIds = cases.map(
|
|
8007
8125
|
(seedCase) => registration.client.seedTrace(traceFunctionKey, {
|
|
8008
8126
|
input: seedCase.input,
|