@bitfab/sdk 0.42.0 → 0.43.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/index.cjs CHANGED
@@ -42,7 +42,7 @@ var __version__, __packageName__;
42
42
  var init_version_generated = __esm({
43
43
  "src/version.generated.ts"() {
44
44
  "use strict";
45
- __version__ = "0.42.0";
45
+ __version__ = "0.43.0";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -1841,7 +1841,7 @@ var init_http = __esm({
1841
1841
  * Start a replay session by fetching historical traces.
1842
1842
  * Blocking call - creates a test run and returns lightweight item references.
1843
1843
  */
1844
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
1844
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts, includeOriginalMetadata) {
1845
1845
  const payload = { traceFunctionKey };
1846
1846
  if (limit !== void 0) {
1847
1847
  payload.limit = limit;
@@ -1877,6 +1877,9 @@ var init_http = __esm({
1877
1877
  if (attempts !== void 0 && attempts > 1) {
1878
1878
  payload.attempts = attempts;
1879
1879
  }
1880
+ if (includeOriginalMetadata) {
1881
+ payload.includeOriginalMetadata = true;
1882
+ }
1880
1883
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
1881
1884
  return this.request("/api/sdk/replay/start", payload, {
1882
1885
  timeout
@@ -2490,6 +2493,9 @@ function reportReplayProgress(progress) {
2490
2493
  } catch {
2491
2494
  }
2492
2495
  }
2496
+ function isPlainRecord(value) {
2497
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2498
+ }
2493
2499
  function errorMessage(error) {
2494
2500
  return error instanceof Error ? error.message : String(error);
2495
2501
  }
@@ -2637,12 +2643,14 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2637
2643
  inputs = deserializeInputs(spanData);
2638
2644
  originalOutput = deserializeOutput(spanData);
2639
2645
  if (adaptInputs) {
2646
+ const originalMetadata = serverItem.originalMetadata;
2640
2647
  inputs = adaptInputs(inputs, {
2641
2648
  originalTraceId,
2642
2649
  originalSpanId,
2643
2650
  // Deprecated aliases for originalTraceId/originalSpanId.
2644
2651
  sourceTraceId: originalTraceId,
2645
- sourceSpanId: originalSpanId
2652
+ sourceSpanId: originalSpanId,
2653
+ metadata: isPlainRecord(originalMetadata) ? { ...originalMetadata } : {}
2646
2654
  });
2647
2655
  }
2648
2656
  const hasOverrides = resolvedOverrides.length > 0;
@@ -2932,7 +2940,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2932
2940
  options?.datasetId,
2933
2941
  options?.graderIds,
2934
2942
  resolveDbBranchSettings(options?.dbBranch),
2935
- attempts
2943
+ attempts,
2944
+ options?.adaptInputs !== void 0
2936
2945
  );
2937
2946
  if (serverItems.length === 0) {
2938
2947
  try {
@@ -5286,7 +5295,8 @@ var BitfabLangGraphIntegration = class {
5286
5295
  type: "function",
5287
5296
  captureWhen: "nested",
5288
5297
  mockOnReplay: shouldMock,
5289
- finalize: finalizeToolResult
5298
+ finalize: finalizeToolResult,
5299
+ surface: "inherit"
5290
5300
  },
5291
5301
  async (_args) => await originalInvoke(input, ...rest)
5292
5302
  );
@@ -5329,7 +5339,7 @@ var BitfabLangGraphIntegration = class {
5329
5339
  wrapInvoke(fn) {
5330
5340
  return this.client.withSpan(
5331
5341
  this.traceFunctionKey,
5332
- { name: this.traceFunctionKey, type: "agent" },
5342
+ { name: this.traceFunctionKey, type: "agent", surface: "inherit" },
5333
5343
  fn
5334
5344
  );
5335
5345
  }
@@ -5382,7 +5392,11 @@ var BitfabOpenAIAgentHandler = class {
5382
5392
  }
5383
5393
  return res?.finalOutput;
5384
5394
  };
5385
- const options_ = { type: "agent", finalize };
5395
+ const options_ = {
5396
+ type: "agent",
5397
+ finalize,
5398
+ surface: "inherit"
5399
+ };
5386
5400
  const traced = this.withSpanFn(
5387
5401
  this.traceFunctionKey,
5388
5402
  options_,
@@ -5446,6 +5460,38 @@ _context = new WeakMap();
5446
5460
 
5447
5461
  // src/client.ts
5448
5462
  init_replayContext();
5463
+
5464
+ // src/seedContext.ts
5465
+ init_asyncStorage();
5466
+ var seedContextStorage = null;
5467
+ var SEED_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.seedContextStorage");
5468
+ var seedContextReady = asyncStorageReady.then(() => {
5469
+ const shared = globalThis;
5470
+ const existing = shared[SEED_CONTEXT_STORAGE_SYMBOL];
5471
+ if (existing) {
5472
+ seedContextStorage = existing;
5473
+ return;
5474
+ }
5475
+ const created = createAsyncLocalStorage();
5476
+ if (created) {
5477
+ shared[SEED_CONTEXT_STORAGE_SYMBOL] = created;
5478
+ seedContextStorage = created;
5479
+ }
5480
+ });
5481
+ function getSeedContext() {
5482
+ return seedContextStorage?.getStore() ?? null;
5483
+ }
5484
+ function inSeedScope() {
5485
+ return getSeedContext() !== null;
5486
+ }
5487
+ function runWithSeedContext(ctx, fn) {
5488
+ if (seedContextStorage) {
5489
+ return seedContextStorage.run(ctx, fn);
5490
+ }
5491
+ return fn();
5492
+ }
5493
+
5494
+ // src/client.ts
5449
5495
  init_serialize();
5450
5496
 
5451
5497
  // src/tracing.ts
@@ -5781,7 +5827,8 @@ var BitfabVercelAiHandler = class {
5781
5827
  key,
5782
5828
  {
5783
5829
  type: "llm",
5784
- finalize: (result) => summarizeGenerate(result ?? {}, label)
5830
+ finalize: (result) => summarizeGenerate(result ?? {}, label),
5831
+ surface: "inherit"
5785
5832
  },
5786
5833
  () => doGenerate()
5787
5834
  );
@@ -5799,7 +5846,7 @@ var BitfabVercelAiHandler = class {
5799
5846
  // The wrapped fn returns immediately with the live stream, so the span
5800
5847
  // output cannot be read from the return value. `finalize` instead
5801
5848
  // awaits the summary the accumulator resolves once the stream drains.
5802
- { type: "llm", finalize: () => summary },
5849
+ { type: "llm", finalize: () => summary, surface: "inherit" },
5803
5850
  async () => {
5804
5851
  const result = await doStream();
5805
5852
  const stream = result.stream.pipeThrough(
@@ -5816,6 +5863,18 @@ var BitfabVercelAiHandler = class {
5816
5863
 
5817
5864
  // src/client.ts
5818
5865
  init_warnOnce();
5866
+ var MIXED_SURFACE_REMEDY = {
5867
+ "opt-in": "Inside a withTrace/trace subtree, configure a discovered call with node()/withNode() instead, or trace this workflow with withSpan() only.",
5868
+ "opt-out": "Wrap the caller with withTrace()/trace() as well, or wrap this function with withSpan()."
5869
+ };
5870
+ function warnMixedTracingSurfaces(traceFunctionKey, entered, enclosing) {
5871
+ const enteredApi = entered === "opt-in" ? "withSpan()" : "withTrace()";
5872
+ const enclosingApi = enclosing === "opt-in" ? "withSpan()" : "withTrace()";
5873
+ warnOnce(
5874
+ `mixed-tracing-surface:${traceFunctionKey}:${entered}`,
5875
+ `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]}`
5876
+ );
5877
+ }
5819
5878
  var activeTraceStates = /* @__PURE__ */ new Map();
5820
5879
  var asyncLocalStorage = null;
5821
5880
  var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
@@ -6179,7 +6238,13 @@ var Bitfab = class {
6179
6238
  this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL;
6180
6239
  this.timeout = config.timeout ?? 12e4;
6181
6240
  this.envVars = config.envVars ?? {};
6182
- this.explicitlyEnabled = config.enabled ?? true;
6241
+ if (config.enabled !== void 0) {
6242
+ warnOnce(
6243
+ "deprecated-enabled-option",
6244
+ "Bitfab({ enabled }) is deprecated; pass captureEnabled instead."
6245
+ );
6246
+ }
6247
+ this.captureConfigured = (config.captureEnabled ?? true) && (config.enabled ?? true);
6183
6248
  this.strict = config.strict ?? false;
6184
6249
  this.bamlClient = config.bamlClient ?? null;
6185
6250
  if (config.dbSnapshot) {
@@ -6215,9 +6280,6 @@ var Bitfab = class {
6215
6280
  if (!descriptor || typeof descriptor.value !== "function") {
6216
6281
  throw new BitfabError("@bitfab.trace can only decorate methods");
6217
6282
  }
6218
- if (!this.explicitlyEnabled) {
6219
- return;
6220
- }
6221
6283
  descriptor.value = this.createAutoTraceRoot(
6222
6284
  traceFunctionKey,
6223
6285
  String(propertyKey),
@@ -6231,9 +6293,6 @@ var Bitfab = class {
6231
6293
  if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) {
6232
6294
  throw new BitfabError("@bitfab.trace can only decorate methods");
6233
6295
  }
6234
- if (!this.explicitlyEnabled) {
6235
- return method;
6236
- }
6237
6296
  return this.createAutoTraceRoot(
6238
6297
  traceFunctionKey,
6239
6298
  String(context.name),
@@ -6249,9 +6308,6 @@ var Bitfab = class {
6249
6308
  if (!fn) {
6250
6309
  throw new BitfabError("bitfab.withTrace requires a function");
6251
6310
  }
6252
- if (!this.explicitlyEnabled) {
6253
- return fn;
6254
- }
6255
6311
  const name = fn.name !== "" ? fn.name : traceFunctionKey;
6256
6312
  return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
6257
6313
  }
@@ -6275,9 +6331,6 @@ var Bitfab = class {
6275
6331
  if (!descriptor || typeof descriptor.value !== "function") {
6276
6332
  throw new BitfabError("@bitfab.node can only decorate methods");
6277
6333
  }
6278
- if (!this.explicitlyEnabled) {
6279
- return;
6280
- }
6281
6334
  descriptor.value = this.createAutoTraceNode(
6282
6335
  configuration,
6283
6336
  descriptor.value,
@@ -6290,9 +6343,6 @@ var Bitfab = class {
6290
6343
  if (typeof method !== "function" || context?.kind !== "method") {
6291
6344
  throw new BitfabError("@bitfab.node can only decorate methods");
6292
6345
  }
6293
- if (!this.explicitlyEnabled) {
6294
- return method;
6295
- }
6296
6346
  return this.createAutoTraceNode(
6297
6347
  configuration,
6298
6348
  method,
@@ -6308,9 +6358,6 @@ var Bitfab = class {
6308
6358
  throw new BitfabError("bitfab.withNode requires a function");
6309
6359
  }
6310
6360
  const configuration = this.resolveNodeConfiguration(options);
6311
- if (!this.explicitlyEnabled) {
6312
- return fn;
6313
- }
6314
6361
  const functionName = internalFunctionName ?? fn.name;
6315
6362
  if (functionName === "") {
6316
6363
  throw new BitfabError(
@@ -6363,9 +6410,14 @@ var Bitfab = class {
6363
6410
  );
6364
6411
  const excluded = new Set(options.exclude ?? []);
6365
6412
  const includeWrappers = options.includeWrappers ?? false;
6413
+ const rootOptions = {
6414
+ name: options.name ?? name,
6415
+ type: options.type ?? "custom",
6416
+ surface: "opt-out"
6417
+ };
6366
6418
  const tracedRoot = this.withSpan(
6367
6419
  traceFunctionKey,
6368
- { name: options.name ?? name, type: options.type ?? "custom" },
6420
+ rootOptions,
6369
6421
  function(...args) {
6370
6422
  const capturePolicy = getAutoTraceCapturePolicy(self, traceFunctionKey);
6371
6423
  self.refreshAutoTraceCapturePolicy(traceFunctionKey);
@@ -6409,6 +6461,7 @@ var Bitfab = class {
6409
6461
  name: nodeConfiguration?.name ?? definition.name,
6410
6462
  type: nodeConfiguration?.type ?? "function",
6411
6463
  captureWhen: "nested",
6464
+ surface: "opt-out",
6412
6465
  functionId: definition.id,
6413
6466
  captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
6414
6467
  autoTraceDefinition: definition,
@@ -6446,7 +6499,7 @@ var Bitfab = class {
6446
6499
  }
6447
6500
  );
6448
6501
  const autoTraceRoot = function(...args) {
6449
- if (!self.isTracingEnabled()) {
6502
+ if (!self.shouldRecord()) {
6450
6503
  return fn.apply(this, args);
6451
6504
  }
6452
6505
  return tracedRoot.apply(this, args);
@@ -6454,6 +6507,7 @@ var Bitfab = class {
6454
6507
  Object.defineProperty(autoTraceRoot, "_bitfabTraceFunctionKey", {
6455
6508
  value: traceFunctionKey
6456
6509
  });
6510
+ Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
6457
6511
  return autoTraceRoot;
6458
6512
  }
6459
6513
  refreshAutoTraceCapturePolicy(traceFunctionKey) {
@@ -6537,7 +6591,7 @@ var Bitfab = class {
6537
6591
  "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`."
6538
6592
  );
6539
6593
  }
6540
- if (this.explicitlyEnabled && !this.apiKeyWarned) {
6594
+ if (this.captureConfigured && !this.apiKeyWarned) {
6541
6595
  this.apiKeyWarned = true;
6542
6596
  console.warn(
6543
6597
  "Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing."
@@ -6545,17 +6599,21 @@ var Bitfab = class {
6545
6599
  }
6546
6600
  return void 0;
6547
6601
  }
6548
- /**
6549
- * Whether tracing should run, decided lazily at call time (not frozen at
6550
- * construction). An explicit `enabled: false` short-circuits without ever
6551
- * touching the key.
6552
- */
6553
- isTracingEnabled() {
6554
- if (!this.explicitlyEnabled) {
6602
+ isCaptureEnabled() {
6603
+ if (!this.captureConfigured) {
6604
+ return false;
6605
+ }
6606
+ return this.resolveApiKey() !== void 0;
6607
+ }
6608
+ shouldRecord() {
6609
+ if (!this.captureConfigured && !getReplayContext() && !inSeedScope()) {
6555
6610
  return false;
6556
6611
  }
6557
6612
  return this.resolveApiKey() !== void 0;
6558
6613
  }
6614
+ get captureEnabled() {
6615
+ return this.isCaptureEnabled();
6616
+ }
6559
6617
  /**
6560
6618
  * Fetch the function with its current version and BAML prompt from the server.
6561
6619
  *
@@ -6967,9 +7025,6 @@ var Bitfab = class {
6967
7025
  * @returns A wrapped function with the same signature that creates spans for inputs and outputs
6968
7026
  */
6969
7027
  withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
6970
- if (!this.explicitlyEnabled) {
6971
- return typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
6972
- }
6973
7028
  const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
6974
7029
  const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
6975
7030
  const self = this;
@@ -6983,7 +7038,7 @@ var Bitfab = class {
6983
7038
  }
6984
7039
  })();
6985
7040
  const wrappedFn = function(...args) {
6986
- if (!self.isTracingEnabled()) {
7041
+ if (!self.shouldRecord()) {
6987
7042
  return fn.apply(this, args);
6988
7043
  }
6989
7044
  initializeAsyncContext();
@@ -7031,11 +7086,26 @@ var Bitfab = class {
7031
7086
  const currentStack = getSpanStack();
7032
7087
  const parentContext = currentStack[currentStack.length - 1];
7033
7088
  const replayCtxForTraceId = parentContext ? null : getReplayContext();
7034
- const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? randomUuid();
7089
+ const seedCtxForTraceId = parentContext ? null : getSeedContext();
7090
+ const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
7035
7091
  const spanId = randomUuid();
7036
7092
  const parentSpanId = parentContext?.spanId ?? null;
7037
7093
  const isRootSpan = parentSpanId === null;
7038
- const newContext = { traceId, spanId, contexts: [] };
7094
+ const requestedSurface = options.surface ?? "opt-in";
7095
+ const surface = requestedSurface === "inherit" ? parentContext?.surface ?? "opt-in" : requestedSurface;
7096
+ if (requestedSurface !== "inherit" && parentContext?.surface !== void 0 && parentContext.surface !== surface) {
7097
+ warnMixedTracingSurfaces(
7098
+ traceFunctionKey,
7099
+ surface,
7100
+ parentContext.surface
7101
+ );
7102
+ }
7103
+ const newContext = {
7104
+ traceId,
7105
+ spanId,
7106
+ contexts: [],
7107
+ surface
7108
+ };
7039
7109
  newStack = [...currentStack, newContext];
7040
7110
  const inputs = args;
7041
7111
  const startedAt = nowIsoTimestamp();
@@ -7317,7 +7387,7 @@ var Bitfab = class {
7317
7387
  if (registeredTraceId) {
7318
7388
  activeTraceStates.delete(registeredTraceId);
7319
7389
  }
7320
- if (getReplayContext()) {
7390
+ if (getReplayContext() || inSeedScope()) {
7321
7391
  throw setupError;
7322
7392
  }
7323
7393
  warnOnce(
@@ -7392,7 +7462,7 @@ var Bitfab = class {
7392
7462
  return {
7393
7463
  traceId,
7394
7464
  addContext: (context) => {
7395
- if (!this.isTracingEnabled()) {
7465
+ if (!this.shouldRecord()) {
7396
7466
  return Promise.resolve();
7397
7467
  }
7398
7468
  if (typeof context !== "object" || context === null) {
@@ -7403,7 +7473,7 @@ var Bitfab = class {
7403
7473
  });
7404
7474
  },
7405
7475
  setMetadata: (metadata) => {
7406
- if (!this.isTracingEnabled()) {
7476
+ if (!this.shouldRecord()) {
7407
7477
  return Promise.resolve();
7408
7478
  }
7409
7479
  if (typeof metadata !== "object" || metadata === null) {
@@ -7412,7 +7482,7 @@ var Bitfab = class {
7412
7482
  return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata });
7413
7483
  },
7414
7484
  setSessionId: (sessionId) => {
7415
- if (!this.isTracingEnabled()) {
7485
+ if (!this.shouldRecord()) {
7416
7486
  return Promise.resolve();
7417
7487
  }
7418
7488
  if (typeof sessionId !== "string" || sessionId.length === 0) {
@@ -7421,7 +7491,7 @@ var Bitfab = class {
7421
7491
  return this.httpClient.patchTrace(traceId, { setSessionId: sessionId });
7422
7492
  },
7423
7493
  setName: (name) => {
7424
- if (!this.isTracingEnabled()) {
7494
+ if (!this.shouldRecord()) {
7425
7495
  return Promise.resolve();
7426
7496
  }
7427
7497
  if (typeof name !== "string" || name.length === 0) {
@@ -7657,22 +7727,13 @@ var Bitfab = class {
7657
7727
  clearMockOverrides() {
7658
7728
  this.mockOverrides.length = 0;
7659
7729
  }
7660
- /**
7661
- * Write a replayable trace from a case, without running anything.
7662
- *
7663
- * Use this to turn a corpus you already hold (a Braintrust dataset, a
7664
- * spreadsheet, hand-written cases) into traces that {@link replay} can
7665
- * select. The recorded root span carries `input` as its input and `expected`
7666
- * as its output, so replay reports each item against the value you expected
7667
- * rather than against a previous run.
7668
- *
7669
- * A seeded trace has no child spans and no database pin, so replay mocking
7670
- * has nothing recorded to substitute and `dbBranch` refuses it. Pass
7671
- * `mockOverride` at replay time for calls that must not run.
7672
- *
7673
- * @returns The trace ID, usable with `replay({ traceIds: [...] })`.
7674
- */
7675
- seedTrace(traceFunctionKey, options) {
7730
+ seedTrace(traceFunctionKey, optionsOrFn, runOptions) {
7731
+ if (typeof optionsOrFn === "function") {
7732
+ return this.seedTraceByRunning(traceFunctionKey, optionsOrFn, runOptions);
7733
+ }
7734
+ return this.seedTraceFromCase(traceFunctionKey, optionsOrFn);
7735
+ }
7736
+ seedTraceFromCase(traceFunctionKey, options) {
7676
7737
  const { input } = options;
7677
7738
  const fn = options.fn?._bitfabWrappedFn ?? options.fn;
7678
7739
  if (fn && input.length < fn.length) {
@@ -7721,6 +7782,50 @@ var Bitfab = class {
7721
7782
  }
7722
7783
  return traceId;
7723
7784
  }
7785
+ async seedTraceByRunning(traceFunctionKey, fn, options) {
7786
+ const wrappedKey = fn._bitfabTraceFunctionKey;
7787
+ let target = fn;
7788
+ if (wrappedKey === void 0) {
7789
+ target = this.withSpan(
7790
+ traceFunctionKey,
7791
+ { name: traceFunctionKey, type: "agent" },
7792
+ fn
7793
+ );
7794
+ } else if (wrappedKey !== traceFunctionKey) {
7795
+ throw new BitfabError(
7796
+ `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.`
7797
+ );
7798
+ }
7799
+ await seedContextReady;
7800
+ const traceId = randomUuid();
7801
+ activeTraceStates.set(traceId, {
7802
+ traceId,
7803
+ startedAt: nowIsoTimestamp(),
7804
+ contexts: [],
7805
+ ingestionType: "seeded",
7806
+ ...options?.sessionId !== void 0 && { sessionId: options.sessionId },
7807
+ ...options?.name !== void 0 && { name: options.name },
7808
+ ...options?.metadata !== void 0 && { metadata: options.metadata }
7809
+ });
7810
+ const args = options?.args ?? [];
7811
+ let unrecorded = true;
7812
+ try {
7813
+ await runWithSeedContext({ traceId }, async () => target(...args));
7814
+ } finally {
7815
+ try {
7816
+ const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
7817
+ await flushTraces2(3e4);
7818
+ } finally {
7819
+ unrecorded = activeTraceStates.delete(traceId);
7820
+ }
7821
+ }
7822
+ if (unrecorded) {
7823
+ throw new BitfabError(
7824
+ `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.`
7825
+ );
7826
+ }
7827
+ return traceId;
7828
+ }
7724
7829
  async replay(traceFunctionKey, fn, options) {
7725
7830
  const wrappedKey = fn._bitfabTraceFunctionKey;
7726
7831
  let replayFn = fn;
@@ -7981,7 +8086,7 @@ init_replay();
7981
8086
  function defineReplayRegistry(registry) {
7982
8087
  return registry;
7983
8088
  }
7984
- async function seedFromRegistry(registry, pipeline, cases) {
8089
+ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
7985
8090
  const registration = registry[pipeline];
7986
8091
  if (registration === void 0) {
7987
8092
  throw new BitfabError(
@@ -7989,6 +8094,19 @@ async function seedFromRegistry(registry, pipeline, cases) {
7989
8094
  );
7990
8095
  }
7991
8096
  const traceFunctionKey = resolveTraceFunctionKey(registration);
8097
+ if (options.run === true) {
8098
+ const traceIds2 = [];
8099
+ for (const seedCase of cases) {
8100
+ traceIds2.push(
8101
+ await registration.client.seedTrace(traceFunctionKey, registration.fn, {
8102
+ args: seedCase.input,
8103
+ metadata: seedCase.metadata,
8104
+ sessionId: seedCase.sessionId
8105
+ })
8106
+ );
8107
+ }
8108
+ return { pipeline, traceFunctionKey, traceIds: traceIds2 };
8109
+ }
7992
8110
  const traceIds = cases.map(
7993
8111
  (seedCase) => registration.client.seedTrace(traceFunctionKey, {
7994
8112
  input: seedCase.input,