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/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.42.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_ = { type: "agent", finalize };
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
- this.explicitlyEnabled = config.enabled ?? true;
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
- { name: options.name ?? name, type: options.type ?? "custom" },
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.isTracingEnabled()) {
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.explicitlyEnabled && !this.apiKeyWarned) {
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
- * Whether tracing should run, decided lazily at call time (not frozen at
6573
- * construction). An explicit `enabled: false` short-circuits without ever
6574
- * touching the key.
6575
- */
6576
- isTracingEnabled() {
6577
- if (!this.explicitlyEnabled) {
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.isTracingEnabled()) {
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 traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? randomUuid();
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 newContext = { traceId, spanId, contexts: [] };
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.isTracingEnabled()) {
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.isTracingEnabled()) {
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.isTracingEnabled()) {
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.isTracingEnabled()) {
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
- * Write a replayable trace from a case, without running anything.
7685
- *
7686
- * Use this to turn a corpus you already hold (a Braintrust dataset, a
7687
- * spreadsheet, hand-written cases) into traces that {@link replay} can
7688
- * select. The recorded root span carries `input` as its input and `expected`
7689
- * as its output, so replay reports each item against the value you expected
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,