bitfab 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.
@@ -6,7 +6,7 @@ import {
6
6
  flushTraces,
7
7
  parseRetryAfterMs,
8
8
  serializePayloadBody
9
- } from "./chunk-WB3IVBWE.js";
9
+ } from "./chunk-QY7ZBVKW.js";
10
10
  export {
11
11
  BitfabError,
12
12
  HttpClient,
@@ -16,4 +16,4 @@ export {
16
16
  parseRetryAfterMs,
17
17
  serializePayloadBody
18
18
  };
19
- //# sourceMappingURL=http-JU2VKSY3.js.map
19
+ //# sourceMappingURL=http-4BIN6GTR.js.map
@@ -6,7 +6,7 @@ import {
6
6
  flushTraces,
7
7
  parseRetryAfterMs,
8
8
  serializePayloadBody
9
- } from "./chunk-PDPMZA4Y.js";
9
+ } from "./chunk-DCQR5MF4.js";
10
10
  import "./chunk-H6LZRFMN.js";
11
11
  export {
12
12
  BitfabError,
@@ -17,4 +17,4 @@ export {
17
17
  parseRetryAfterMs,
18
18
  serializePayloadBody
19
19
  };
20
- //# sourceMappingURL=http-B7QOMWQP.js.map
20
+ //# sourceMappingURL=http-MTCJ2CX2.js.map
package/dist/index.cjs CHANGED
@@ -51,7 +51,7 @@ var __version__, __packageName__;
51
51
  var init_version_generated = __esm({
52
52
  "src/version.generated.ts"() {
53
53
  "use strict";
54
- __version__ = "0.42.0";
54
+ __version__ = "0.43.0";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -1850,7 +1850,7 @@ var init_http = __esm({
1850
1850
  * Start a replay session by fetching historical traces.
1851
1851
  * Blocking call - creates a test run and returns lightweight item references.
1852
1852
  */
1853
- async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts) {
1853
+ async startReplay(traceFunctionKey, limit, traceIds, name, codeChangeDescription, codeChangeFiles, includeDbBranchLease, experimentGroupId, datasetId, graderIds, dbBranchSettings, attempts, includeOriginalMetadata) {
1854
1854
  const payload = { traceFunctionKey };
1855
1855
  if (limit !== void 0) {
1856
1856
  payload.limit = limit;
@@ -1886,6 +1886,9 @@ var init_http = __esm({
1886
1886
  if (attempts !== void 0 && attempts > 1) {
1887
1887
  payload.attempts = attempts;
1888
1888
  }
1889
+ if (includeOriginalMetadata) {
1890
+ payload.includeOriginalMetadata = true;
1891
+ }
1889
1892
  const timeout = includeDbBranchLease ? REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS : 3e4;
1890
1893
  return this.request("/api/sdk/replay/start", payload, {
1891
1894
  timeout
@@ -2499,6 +2502,9 @@ function reportReplayProgress(progress) {
2499
2502
  } catch {
2500
2503
  }
2501
2504
  }
2505
+ function isPlainRecord(value) {
2506
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2507
+ }
2502
2508
  function errorMessage(error) {
2503
2509
  return error instanceof Error ? error.message : String(error);
2504
2510
  }
@@ -2646,12 +2652,14 @@ async function processItem(httpClient, serverItem, fn, testRunId, mockStrategy,
2646
2652
  inputs = deserializeInputs(spanData);
2647
2653
  originalOutput = deserializeOutput(spanData);
2648
2654
  if (adaptInputs) {
2655
+ const originalMetadata = serverItem.originalMetadata;
2649
2656
  inputs = adaptInputs(inputs, {
2650
2657
  originalTraceId,
2651
2658
  originalSpanId,
2652
2659
  // Deprecated aliases for originalTraceId/originalSpanId.
2653
2660
  sourceTraceId: originalTraceId,
2654
- sourceSpanId: originalSpanId
2661
+ sourceSpanId: originalSpanId,
2662
+ metadata: isPlainRecord(originalMetadata) ? { ...originalMetadata } : {}
2655
2663
  });
2656
2664
  }
2657
2665
  const hasOverrides = resolvedOverrides.length > 0;
@@ -2941,7 +2949,8 @@ async function replay(httpClient, serviceUrl, traceFunctionKey, fn, options, reg
2941
2949
  options?.datasetId,
2942
2950
  options?.graderIds,
2943
2951
  resolveDbBranchSettings(options?.dbBranch),
2944
- attempts
2952
+ attempts,
2953
+ options?.adaptInputs !== void 0
2945
2954
  );
2946
2955
  if (serverItems.length === 0) {
2947
2956
  try {
@@ -5295,7 +5304,8 @@ var BitfabLangGraphIntegration = class {
5295
5304
  type: "function",
5296
5305
  captureWhen: "nested",
5297
5306
  mockOnReplay: shouldMock,
5298
- finalize: finalizeToolResult
5307
+ finalize: finalizeToolResult,
5308
+ surface: "inherit"
5299
5309
  },
5300
5310
  async (_args) => await originalInvoke(input, ...rest)
5301
5311
  );
@@ -5338,7 +5348,7 @@ var BitfabLangGraphIntegration = class {
5338
5348
  wrapInvoke(fn) {
5339
5349
  return this.client.withSpan(
5340
5350
  this.traceFunctionKey,
5341
- { name: this.traceFunctionKey, type: "agent" },
5351
+ { name: this.traceFunctionKey, type: "agent", surface: "inherit" },
5342
5352
  fn
5343
5353
  );
5344
5354
  }
@@ -5391,7 +5401,11 @@ var BitfabOpenAIAgentHandler = class {
5391
5401
  }
5392
5402
  return res?.finalOutput;
5393
5403
  };
5394
- const options_ = { type: "agent", finalize };
5404
+ const options_ = {
5405
+ type: "agent",
5406
+ finalize,
5407
+ surface: "inherit"
5408
+ };
5395
5409
  const traced = this.withSpanFn(
5396
5410
  this.traceFunctionKey,
5397
5411
  options_,
@@ -5455,6 +5469,38 @@ _context = new WeakMap();
5455
5469
 
5456
5470
  // src/client.ts
5457
5471
  init_replayContext();
5472
+
5473
+ // src/seedContext.ts
5474
+ init_asyncStorage();
5475
+ var seedContextStorage = null;
5476
+ var SEED_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.seedContextStorage");
5477
+ var seedContextReady = asyncStorageReady.then(() => {
5478
+ const shared = globalThis;
5479
+ const existing = shared[SEED_CONTEXT_STORAGE_SYMBOL];
5480
+ if (existing) {
5481
+ seedContextStorage = existing;
5482
+ return;
5483
+ }
5484
+ const created = createAsyncLocalStorage();
5485
+ if (created) {
5486
+ shared[SEED_CONTEXT_STORAGE_SYMBOL] = created;
5487
+ seedContextStorage = created;
5488
+ }
5489
+ });
5490
+ function getSeedContext() {
5491
+ return seedContextStorage?.getStore() ?? null;
5492
+ }
5493
+ function inSeedScope() {
5494
+ return getSeedContext() !== null;
5495
+ }
5496
+ function runWithSeedContext(ctx, fn) {
5497
+ if (seedContextStorage) {
5498
+ return seedContextStorage.run(ctx, fn);
5499
+ }
5500
+ return fn();
5501
+ }
5502
+
5503
+ // src/client.ts
5458
5504
  init_serialize();
5459
5505
 
5460
5506
  // src/tracing.ts
@@ -5790,7 +5836,8 @@ var BitfabVercelAiHandler = class {
5790
5836
  key,
5791
5837
  {
5792
5838
  type: "llm",
5793
- finalize: (result) => summarizeGenerate(result ?? {}, label)
5839
+ finalize: (result) => summarizeGenerate(result ?? {}, label),
5840
+ surface: "inherit"
5794
5841
  },
5795
5842
  () => doGenerate()
5796
5843
  );
@@ -5808,7 +5855,7 @@ var BitfabVercelAiHandler = class {
5808
5855
  // The wrapped fn returns immediately with the live stream, so the span
5809
5856
  // output cannot be read from the return value. `finalize` instead
5810
5857
  // awaits the summary the accumulator resolves once the stream drains.
5811
- { type: "llm", finalize: () => summary },
5858
+ { type: "llm", finalize: () => summary, surface: "inherit" },
5812
5859
  async () => {
5813
5860
  const result = await doStream();
5814
5861
  const stream = result.stream.pipeThrough(
@@ -5825,6 +5872,18 @@ var BitfabVercelAiHandler = class {
5825
5872
 
5826
5873
  // src/client.ts
5827
5874
  init_warnOnce();
5875
+ var MIXED_SURFACE_REMEDY = {
5876
+ "opt-in": "Inside a withTrace/trace subtree, configure a discovered call with node()/withNode() instead, or trace this workflow with withSpan() only.",
5877
+ "opt-out": "Wrap the caller with withTrace()/trace() as well, or wrap this function with withSpan()."
5878
+ };
5879
+ function warnMixedTracingSurfaces(traceFunctionKey, entered, enclosing) {
5880
+ const enteredApi = entered === "opt-in" ? "withSpan()" : "withTrace()";
5881
+ const enclosingApi = enclosing === "opt-in" ? "withSpan()" : "withTrace()";
5882
+ warnOnce(
5883
+ `mixed-tracing-surface:${traceFunctionKey}:${entered}`,
5884
+ `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]}`
5885
+ );
5886
+ }
5828
5887
  var activeTraceStates = /* @__PURE__ */ new Map();
5829
5888
  var asyncLocalStorage = null;
5830
5889
  var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
@@ -6188,7 +6247,13 @@ var Bitfab = class {
6188
6247
  this.serviceUrl = config.serviceUrl ?? DEFAULT_SERVICE_URL;
6189
6248
  this.timeout = config.timeout ?? 12e4;
6190
6249
  this.envVars = config.envVars ?? {};
6191
- this.explicitlyEnabled = config.enabled ?? true;
6250
+ if (config.enabled !== void 0) {
6251
+ warnOnce(
6252
+ "deprecated-enabled-option",
6253
+ "Bitfab({ enabled }) is deprecated; pass captureEnabled instead."
6254
+ );
6255
+ }
6256
+ this.captureConfigured = (config.captureEnabled ?? true) && (config.enabled ?? true);
6192
6257
  this.strict = config.strict ?? false;
6193
6258
  this.bamlClient = config.bamlClient ?? null;
6194
6259
  if (config.dbSnapshot) {
@@ -6224,9 +6289,6 @@ var Bitfab = class {
6224
6289
  if (!descriptor || typeof descriptor.value !== "function") {
6225
6290
  throw new BitfabError("@bitfab.trace can only decorate methods");
6226
6291
  }
6227
- if (!this.explicitlyEnabled) {
6228
- return;
6229
- }
6230
6292
  descriptor.value = this.createAutoTraceRoot(
6231
6293
  traceFunctionKey,
6232
6294
  String(propertyKey),
@@ -6240,9 +6302,6 @@ var Bitfab = class {
6240
6302
  if (typeof method !== "function" || context?.kind !== "method" || context.name === void 0) {
6241
6303
  throw new BitfabError("@bitfab.trace can only decorate methods");
6242
6304
  }
6243
- if (!this.explicitlyEnabled) {
6244
- return method;
6245
- }
6246
6305
  return this.createAutoTraceRoot(
6247
6306
  traceFunctionKey,
6248
6307
  String(context.name),
@@ -6258,9 +6317,6 @@ var Bitfab = class {
6258
6317
  if (!fn) {
6259
6318
  throw new BitfabError("bitfab.withTrace requires a function");
6260
6319
  }
6261
- if (!this.explicitlyEnabled) {
6262
- return fn;
6263
- }
6264
6320
  const name = fn.name !== "" ? fn.name : traceFunctionKey;
6265
6321
  return this.createAutoTraceRoot(traceFunctionKey, name, options, fn);
6266
6322
  }
@@ -6284,9 +6340,6 @@ var Bitfab = class {
6284
6340
  if (!descriptor || typeof descriptor.value !== "function") {
6285
6341
  throw new BitfabError("@bitfab.node can only decorate methods");
6286
6342
  }
6287
- if (!this.explicitlyEnabled) {
6288
- return;
6289
- }
6290
6343
  descriptor.value = this.createAutoTraceNode(
6291
6344
  configuration,
6292
6345
  descriptor.value,
@@ -6299,9 +6352,6 @@ var Bitfab = class {
6299
6352
  if (typeof method !== "function" || context?.kind !== "method") {
6300
6353
  throw new BitfabError("@bitfab.node can only decorate methods");
6301
6354
  }
6302
- if (!this.explicitlyEnabled) {
6303
- return method;
6304
- }
6305
6355
  return this.createAutoTraceNode(
6306
6356
  configuration,
6307
6357
  method,
@@ -6317,9 +6367,6 @@ var Bitfab = class {
6317
6367
  throw new BitfabError("bitfab.withNode requires a function");
6318
6368
  }
6319
6369
  const configuration = this.resolveNodeConfiguration(options);
6320
- if (!this.explicitlyEnabled) {
6321
- return fn;
6322
- }
6323
6370
  const functionName = internalFunctionName ?? fn.name;
6324
6371
  if (functionName === "") {
6325
6372
  throw new BitfabError(
@@ -6372,9 +6419,14 @@ var Bitfab = class {
6372
6419
  );
6373
6420
  const excluded = new Set(options.exclude ?? []);
6374
6421
  const includeWrappers = options.includeWrappers ?? false;
6422
+ const rootOptions = {
6423
+ name: options.name ?? name,
6424
+ type: options.type ?? "custom",
6425
+ surface: "opt-out"
6426
+ };
6375
6427
  const tracedRoot = this.withSpan(
6376
6428
  traceFunctionKey,
6377
- { name: options.name ?? name, type: options.type ?? "custom" },
6429
+ rootOptions,
6378
6430
  function(...args) {
6379
6431
  const capturePolicy = getAutoTraceCapturePolicy(self, traceFunctionKey);
6380
6432
  self.refreshAutoTraceCapturePolicy(traceFunctionKey);
@@ -6418,6 +6470,7 @@ var Bitfab = class {
6418
6470
  name: nodeConfiguration?.name ?? definition.name,
6419
6471
  type: nodeConfiguration?.type ?? "function",
6420
6472
  captureWhen: "nested",
6473
+ surface: "opt-out",
6421
6474
  functionId: definition.id,
6422
6475
  captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
6423
6476
  autoTraceDefinition: definition,
@@ -6455,7 +6508,7 @@ var Bitfab = class {
6455
6508
  }
6456
6509
  );
6457
6510
  const autoTraceRoot = function(...args) {
6458
- if (!self.isTracingEnabled()) {
6511
+ if (!self.shouldRecord()) {
6459
6512
  return fn.apply(this, args);
6460
6513
  }
6461
6514
  return tracedRoot.apply(this, args);
@@ -6463,6 +6516,7 @@ var Bitfab = class {
6463
6516
  Object.defineProperty(autoTraceRoot, "_bitfabTraceFunctionKey", {
6464
6517
  value: traceFunctionKey
6465
6518
  });
6519
+ Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
6466
6520
  return autoTraceRoot;
6467
6521
  }
6468
6522
  refreshAutoTraceCapturePolicy(traceFunctionKey) {
@@ -6546,7 +6600,7 @@ var Bitfab = class {
6546
6600
  "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`."
6547
6601
  );
6548
6602
  }
6549
- if (this.explicitlyEnabled && !this.apiKeyWarned) {
6603
+ if (this.captureConfigured && !this.apiKeyWarned) {
6550
6604
  this.apiKeyWarned = true;
6551
6605
  console.warn(
6552
6606
  "Bitfab: apiKey is empty - tracing is disabled. Provide a valid API key to enable tracing."
@@ -6554,17 +6608,21 @@ var Bitfab = class {
6554
6608
  }
6555
6609
  return void 0;
6556
6610
  }
6557
- /**
6558
- * Whether tracing should run, decided lazily at call time (not frozen at
6559
- * construction). An explicit `enabled: false` short-circuits without ever
6560
- * touching the key.
6561
- */
6562
- isTracingEnabled() {
6563
- if (!this.explicitlyEnabled) {
6611
+ isCaptureEnabled() {
6612
+ if (!this.captureConfigured) {
6613
+ return false;
6614
+ }
6615
+ return this.resolveApiKey() !== void 0;
6616
+ }
6617
+ shouldRecord() {
6618
+ if (!this.captureConfigured && !getReplayContext() && !inSeedScope()) {
6564
6619
  return false;
6565
6620
  }
6566
6621
  return this.resolveApiKey() !== void 0;
6567
6622
  }
6623
+ get captureEnabled() {
6624
+ return this.isCaptureEnabled();
6625
+ }
6568
6626
  /**
6569
6627
  * Fetch the function with its current version and BAML prompt from the server.
6570
6628
  *
@@ -6976,9 +7034,6 @@ var Bitfab = class {
6976
7034
  * @returns A wrapped function with the same signature that creates spans for inputs and outputs
6977
7035
  */
6978
7036
  withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
6979
- if (!this.explicitlyEnabled) {
6980
- return typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
6981
- }
6982
7037
  const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
6983
7038
  const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
6984
7039
  const self = this;
@@ -6992,7 +7047,7 @@ var Bitfab = class {
6992
7047
  }
6993
7048
  })();
6994
7049
  const wrappedFn = function(...args) {
6995
- if (!self.isTracingEnabled()) {
7050
+ if (!self.shouldRecord()) {
6996
7051
  return fn.apply(this, args);
6997
7052
  }
6998
7053
  initializeAsyncContext();
@@ -7040,11 +7095,26 @@ var Bitfab = class {
7040
7095
  const currentStack = getSpanStack();
7041
7096
  const parentContext = currentStack[currentStack.length - 1];
7042
7097
  const replayCtxForTraceId = parentContext ? null : getReplayContext();
7043
- const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? randomUuid();
7098
+ const seedCtxForTraceId = parentContext ? null : getSeedContext();
7099
+ const traceId = parentContext?.traceId ?? replayCtxForTraceId?.traceId ?? seedCtxForTraceId?.traceId ?? randomUuid();
7044
7100
  const spanId = randomUuid();
7045
7101
  const parentSpanId = parentContext?.spanId ?? null;
7046
7102
  const isRootSpan = parentSpanId === null;
7047
- const newContext = { traceId, spanId, contexts: [] };
7103
+ const requestedSurface = options.surface ?? "opt-in";
7104
+ const surface = requestedSurface === "inherit" ? parentContext?.surface ?? "opt-in" : requestedSurface;
7105
+ if (requestedSurface !== "inherit" && parentContext?.surface !== void 0 && parentContext.surface !== surface) {
7106
+ warnMixedTracingSurfaces(
7107
+ traceFunctionKey,
7108
+ surface,
7109
+ parentContext.surface
7110
+ );
7111
+ }
7112
+ const newContext = {
7113
+ traceId,
7114
+ spanId,
7115
+ contexts: [],
7116
+ surface
7117
+ };
7048
7118
  newStack = [...currentStack, newContext];
7049
7119
  const inputs = args;
7050
7120
  const startedAt = nowIsoTimestamp();
@@ -7326,7 +7396,7 @@ var Bitfab = class {
7326
7396
  if (registeredTraceId) {
7327
7397
  activeTraceStates.delete(registeredTraceId);
7328
7398
  }
7329
- if (getReplayContext()) {
7399
+ if (getReplayContext() || inSeedScope()) {
7330
7400
  throw setupError;
7331
7401
  }
7332
7402
  warnOnce(
@@ -7401,7 +7471,7 @@ var Bitfab = class {
7401
7471
  return {
7402
7472
  traceId,
7403
7473
  addContext: (context) => {
7404
- if (!this.isTracingEnabled()) {
7474
+ if (!this.shouldRecord()) {
7405
7475
  return Promise.resolve();
7406
7476
  }
7407
7477
  if (typeof context !== "object" || context === null) {
@@ -7412,7 +7482,7 @@ var Bitfab = class {
7412
7482
  });
7413
7483
  },
7414
7484
  setMetadata: (metadata) => {
7415
- if (!this.isTracingEnabled()) {
7485
+ if (!this.shouldRecord()) {
7416
7486
  return Promise.resolve();
7417
7487
  }
7418
7488
  if (typeof metadata !== "object" || metadata === null) {
@@ -7421,7 +7491,7 @@ var Bitfab = class {
7421
7491
  return this.httpClient.patchTrace(traceId, { mergeMetadata: metadata });
7422
7492
  },
7423
7493
  setSessionId: (sessionId) => {
7424
- if (!this.isTracingEnabled()) {
7494
+ if (!this.shouldRecord()) {
7425
7495
  return Promise.resolve();
7426
7496
  }
7427
7497
  if (typeof sessionId !== "string" || sessionId.length === 0) {
@@ -7430,7 +7500,7 @@ var Bitfab = class {
7430
7500
  return this.httpClient.patchTrace(traceId, { setSessionId: sessionId });
7431
7501
  },
7432
7502
  setName: (name) => {
7433
- if (!this.isTracingEnabled()) {
7503
+ if (!this.shouldRecord()) {
7434
7504
  return Promise.resolve();
7435
7505
  }
7436
7506
  if (typeof name !== "string" || name.length === 0) {
@@ -7666,22 +7736,13 @@ var Bitfab = class {
7666
7736
  clearMockOverrides() {
7667
7737
  this.mockOverrides.length = 0;
7668
7738
  }
7669
- /**
7670
- * Write a replayable trace from a case, without running anything.
7671
- *
7672
- * Use this to turn a corpus you already hold (a Braintrust dataset, a
7673
- * spreadsheet, hand-written cases) into traces that {@link replay} can
7674
- * select. The recorded root span carries `input` as its input and `expected`
7675
- * as its output, so replay reports each item against the value you expected
7676
- * rather than against a previous run.
7677
- *
7678
- * A seeded trace has no child spans and no database pin, so replay mocking
7679
- * has nothing recorded to substitute and `dbBranch` refuses it. Pass
7680
- * `mockOverride` at replay time for calls that must not run.
7681
- *
7682
- * @returns The trace ID, usable with `replay({ traceIds: [...] })`.
7683
- */
7684
- seedTrace(traceFunctionKey, options) {
7739
+ seedTrace(traceFunctionKey, optionsOrFn, runOptions) {
7740
+ if (typeof optionsOrFn === "function") {
7741
+ return this.seedTraceByRunning(traceFunctionKey, optionsOrFn, runOptions);
7742
+ }
7743
+ return this.seedTraceFromCase(traceFunctionKey, optionsOrFn);
7744
+ }
7745
+ seedTraceFromCase(traceFunctionKey, options) {
7685
7746
  const { input } = options;
7686
7747
  const fn = options.fn?._bitfabWrappedFn ?? options.fn;
7687
7748
  if (fn && input.length < fn.length) {
@@ -7730,6 +7791,50 @@ var Bitfab = class {
7730
7791
  }
7731
7792
  return traceId;
7732
7793
  }
7794
+ async seedTraceByRunning(traceFunctionKey, fn, options) {
7795
+ const wrappedKey = fn._bitfabTraceFunctionKey;
7796
+ let target = fn;
7797
+ if (wrappedKey === void 0) {
7798
+ target = this.withSpan(
7799
+ traceFunctionKey,
7800
+ { name: traceFunctionKey, type: "agent" },
7801
+ fn
7802
+ );
7803
+ } else if (wrappedKey !== traceFunctionKey) {
7804
+ throw new BitfabError(
7805
+ `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.`
7806
+ );
7807
+ }
7808
+ await seedContextReady;
7809
+ const traceId = randomUuid();
7810
+ activeTraceStates.set(traceId, {
7811
+ traceId,
7812
+ startedAt: nowIsoTimestamp(),
7813
+ contexts: [],
7814
+ ingestionType: "seeded",
7815
+ ...options?.sessionId !== void 0 && { sessionId: options.sessionId },
7816
+ ...options?.name !== void 0 && { name: options.name },
7817
+ ...options?.metadata !== void 0 && { metadata: options.metadata }
7818
+ });
7819
+ const args = options?.args ?? [];
7820
+ let unrecorded = true;
7821
+ try {
7822
+ await runWithSeedContext({ traceId }, async () => target(...args));
7823
+ } finally {
7824
+ try {
7825
+ const { flushTraces: flushTraces2 } = await Promise.resolve().then(() => (init_http(), http_exports));
7826
+ await flushTraces2(3e4);
7827
+ } finally {
7828
+ unrecorded = activeTraceStates.delete(traceId);
7829
+ }
7830
+ }
7831
+ if (unrecorded) {
7832
+ throw new BitfabError(
7833
+ `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.`
7834
+ );
7835
+ }
7836
+ return traceId;
7837
+ }
7733
7838
  async replay(traceFunctionKey, fn, options) {
7734
7839
  const wrappedKey = fn._bitfabTraceFunctionKey;
7735
7840
  let replayFn = fn;
@@ -7990,7 +8095,7 @@ init_replay();
7990
8095
  function defineReplayRegistry(registry) {
7991
8096
  return registry;
7992
8097
  }
7993
- async function seedFromRegistry(registry, pipeline, cases) {
8098
+ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
7994
8099
  const registration = registry[pipeline];
7995
8100
  if (registration === void 0) {
7996
8101
  throw new BitfabError(
@@ -7998,6 +8103,19 @@ async function seedFromRegistry(registry, pipeline, cases) {
7998
8103
  );
7999
8104
  }
8000
8105
  const traceFunctionKey = resolveTraceFunctionKey(registration);
8106
+ if (options.run === true) {
8107
+ const traceIds2 = [];
8108
+ for (const seedCase of cases) {
8109
+ traceIds2.push(
8110
+ await registration.client.seedTrace(traceFunctionKey, registration.fn, {
8111
+ args: seedCase.input,
8112
+ metadata: seedCase.metadata,
8113
+ sessionId: seedCase.sessionId
8114
+ })
8115
+ );
8116
+ }
8117
+ return { pipeline, traceFunctionKey, traceIds: traceIds2 };
8118
+ }
8001
8119
  const traceIds = cases.map(
8002
8120
  (seedCase) => registration.client.seedTrace(traceFunctionKey, {
8003
8121
  input: seedCase.input,