bitfab 0.52.6 → 0.53.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.
@@ -19,19 +19,23 @@ import {
19
19
  serializeValue,
20
20
  toJsonSafe,
21
21
  toJsonSafeReport
22
- } from "./chunk-DRTHTSHO.js";
22
+ } from "./chunk-MMT5MWG5.js";
23
23
  import {
24
24
  BitfabError,
25
25
  DEFAULT_SERVICE_URL,
26
26
  HttpClient,
27
27
  MixedTracingError,
28
+ PolicyRefresh,
29
+ ROOT_TRACE_FUNCTION_KEY_FIELD,
30
+ SimulationPlan,
28
31
  callerTraceMetadata,
29
32
  getReplayContext,
33
+ makeSpanOrigin,
30
34
  readEnv,
31
35
  recordCallerTraceMetadata,
32
36
  retireTraceMetadata,
33
37
  warnOnce
34
- } from "./chunk-NXC6NYIY.js";
38
+ } from "./chunk-ASMHSKFS.js";
35
39
  import {
36
40
  __privateAdd,
37
41
  __privateGet,
@@ -340,6 +344,7 @@ var BitfabClaudeAgentHandler = class {
340
344
  trace_id: spanInfo.traceId,
341
345
  started_at: spanInfo.startedAt,
342
346
  ended_at: spanInfo.endedAt ?? nowIso(),
347
+ span_origin: makeSpanOrigin("claude-agent-sdk"),
343
348
  span_data: spanData
344
349
  };
345
350
  if (spanInfo.parentId !== null) {
@@ -1825,6 +1830,7 @@ var BitfabLangGraphCallbackHandler = class {
1825
1830
  trace_id: spanInfo.traceId,
1826
1831
  started_at: spanInfo.startedAt,
1827
1832
  ended_at: spanInfo.endedAt ?? nowIso2(),
1833
+ span_origin: makeSpanOrigin("langgraph"),
1828
1834
  span_data: spanData
1829
1835
  };
1830
1836
  if (spanInfo.parentId !== null) {
@@ -2284,7 +2290,8 @@ var BitfabLangGraphIntegration = class {
2284
2290
  captureWhen: "nested",
2285
2291
  mockOnReplay: shouldMock,
2286
2292
  finalize: finalizeToolResult,
2287
- surface: "inherit"
2293
+ surface: "inherit",
2294
+ instrumentation: "langgraph"
2288
2295
  },
2289
2296
  async (_args) => await originalInvoke(input, ...rest)
2290
2297
  );
@@ -2327,7 +2334,12 @@ var BitfabLangGraphIntegration = class {
2327
2334
  wrapInvoke(fn) {
2328
2335
  return this.client.withSpan(
2329
2336
  this.traceFunctionKey,
2330
- { name: this.traceFunctionKey, type: "agent", surface: "inherit" },
2337
+ {
2338
+ name: this.traceFunctionKey,
2339
+ type: "agent",
2340
+ surface: "inherit",
2341
+ instrumentation: "langgraph"
2342
+ },
2331
2343
  fn
2332
2344
  );
2333
2345
  }
@@ -2380,7 +2392,8 @@ var BitfabOpenAIAgentHandler = class {
2380
2392
  const options_ = {
2381
2393
  type: "agent",
2382
2394
  finalize,
2383
- surface: "inherit"
2395
+ surface: "inherit",
2396
+ instrumentation: "openai-agents"
2384
2397
  };
2385
2398
  const traced = this.withSpanFn(
2386
2399
  this.traceFunctionKey,
@@ -2671,6 +2684,7 @@ var BitfabOpenAITracingProcessor = class {
2671
2684
  * Build span payload for the external spans API.
2672
2685
  */
2673
2686
  buildSpanPayload(serializedSpan, errors) {
2687
+ serializedSpan.span_origin = makeSpanOrigin("openai-agents");
2674
2688
  const payload = {
2675
2689
  id: randomUuid(),
2676
2690
  type: "openai",
@@ -2800,7 +2814,8 @@ var BitfabVercelAiHandler = class {
2800
2814
  {
2801
2815
  type: "llm",
2802
2816
  finalize: (result) => summarizeGenerate(result ?? {}, label),
2803
- surface: "inherit"
2817
+ surface: "inherit",
2818
+ instrumentation: "vercel-ai"
2804
2819
  },
2805
2820
  () => doGenerate()
2806
2821
  );
@@ -2818,7 +2833,12 @@ var BitfabVercelAiHandler = class {
2818
2833
  // The wrapped fn returns immediately with the live stream, so the span
2819
2834
  // output cannot be read from the return value. `finalize` instead
2820
2835
  // awaits the summary the accumulator resolves once the stream drains.
2821
- { type: "llm", finalize: () => summary, surface: "inherit" },
2836
+ {
2837
+ type: "llm",
2838
+ finalize: () => summary,
2839
+ surface: "inherit",
2840
+ instrumentation: "vercel-ai"
2841
+ },
2822
2842
  async () => {
2823
2843
  const result = await doStream();
2824
2844
  const stream = result.stream.pipeThrough(
@@ -2835,6 +2855,19 @@ var BitfabVercelAiHandler = class {
2835
2855
 
2836
2856
  // src/client.ts
2837
2857
  var activeTraceStates = /* @__PURE__ */ new Map();
2858
+ function rootTraceFunctionKeyOf(payload) {
2859
+ const captured = payload[ROOT_TRACE_FUNCTION_KEY_FIELD];
2860
+ if (typeof captured === "string") {
2861
+ return captured;
2862
+ }
2863
+ const traceId = payload.traceId;
2864
+ const live = typeof traceId === "string" ? activeTraceStates.get(traceId)?.traceFunctionKey : void 0;
2865
+ if (typeof live === "string") {
2866
+ return live;
2867
+ }
2868
+ const own = payload.traceFunctionKey;
2869
+ return typeof own === "string" ? own : void 0;
2870
+ }
2838
2871
  var asyncLocalStorage = null;
2839
2872
  var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
2840
2873
  var initializeAsyncContext = () => {
@@ -3177,6 +3210,26 @@ var DEFAULT_AUTO_TRACE_MAX_SPANS = 500;
3177
3210
  var AUTO_TRACE_PROTOCOL = "ts-auto-v1";
3178
3211
  var AUTO_TRACE_POLICY_REFRESH_MS = 6e4;
3179
3212
  var AUTO_TRACE_POLICY_RETRY_MS = 1e4;
3213
+ function spanOwnerName(receiver) {
3214
+ if (typeof receiver === "function") {
3215
+ return receiver.name !== "" ? receiver.name : void 0;
3216
+ }
3217
+ if (typeof receiver !== "object" || receiver === null) {
3218
+ return void 0;
3219
+ }
3220
+ const owner = receiver.constructor;
3221
+ if (typeof owner !== "function" || owner === Object || owner.name === "") {
3222
+ return void 0;
3223
+ }
3224
+ return owner.name;
3225
+ }
3226
+ function qualifiedSpanName(receiver, functionName) {
3227
+ if (functionName === void 0) {
3228
+ return void 0;
3229
+ }
3230
+ const owner = spanOwnerName(receiver);
3231
+ return owner === void 0 ? functionName : `${owner}.${functionName}`;
3232
+ }
3180
3233
  function autoTraceLimit(value, fallback) {
3181
3234
  return value !== void 0 && Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
3182
3235
  }
@@ -3219,6 +3272,14 @@ var Bitfab = class {
3219
3272
  serviceUrl: this.serviceUrl,
3220
3273
  timeout: this.timeout
3221
3274
  });
3275
+ this.simulationPlan = new SimulationPlan(
3276
+ this.httpClient,
3277
+ config.simulationPlan ?? true
3278
+ );
3279
+ this.httpClient.externalSpanTransform = (payload, submit) => this.applySimulationPlan(payload, submit);
3280
+ this.httpClient.externalTraceTransform = (payload, submit) => this.simulationPlan.sendTrace(payload, submit);
3281
+ this.httpClient.releaseHeldExternalSpans = (timeoutMs) => this.simulationPlan.release(timeoutMs);
3282
+ this.httpClient.stopSimulationPlan = () => this.simulationPlan.stop();
3222
3283
  this.datasets = new DatasetsClient(this.httpClient);
3223
3284
  this.traces = new TracesClient(this.httpClient);
3224
3285
  this.labels = new LabelsClient(this.httpClient);
@@ -3369,6 +3430,7 @@ var Bitfab = class {
3369
3430
  }
3370
3431
  createAutoTraceRoot(traceFunctionKey, name, options, fn) {
3371
3432
  const self = this;
3433
+ self.simulationPlan.refresh();
3372
3434
  const maxDepth = autoTraceLimit(
3373
3435
  options.maxDepth,
3374
3436
  DEFAULT_AUTO_TRACE_MAX_DEPTH
@@ -3379,12 +3441,14 @@ var Bitfab = class {
3379
3441
  );
3380
3442
  const excluded = new Set(options.exclude ?? []);
3381
3443
  const includeWrappers = options.includeWrappers ?? false;
3444
+ const rootNameFor = (receiver) => options.name ?? (fn.name !== "" ? qualifiedSpanName(receiver, name) ?? name : name);
3382
3445
  const rootOptions = {
3383
- name: options.name ?? name,
3446
+ name: options.name,
3447
+ nameFor: rootNameFor,
3384
3448
  type: options.type ?? "custom",
3385
- surface: "opt-out"
3449
+ surface: "opt-out",
3450
+ instrumentation: "trace"
3386
3451
  };
3387
- const rootName = options.name ?? name;
3388
3452
  const buildTracedRoot = (spanOptions) => this.withSpan(
3389
3453
  traceFunctionKey,
3390
3454
  spanOptions,
@@ -3394,6 +3458,7 @@ var Bitfab = class {
3394
3458
  traceFunctionKey
3395
3459
  );
3396
3460
  self.refreshAutoTraceCapturePolicy(traceFunctionKey);
3461
+ self.simulationPlan.refresh();
3397
3462
  let spansUsed = 0;
3398
3463
  let truncated = false;
3399
3464
  const warnTruncated = () => {
@@ -3470,6 +3535,7 @@ var Bitfab = class {
3470
3535
  type: nodeConfiguration?.type ?? "function",
3471
3536
  captureWhen: "nested",
3472
3537
  surface: "opt-out",
3538
+ instrumentation: "trace",
3473
3539
  functionId: definition.id,
3474
3540
  captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
3475
3541
  autoTraceDefinition: definition,
@@ -3501,6 +3567,7 @@ var Bitfab = class {
3501
3567
  type: "function",
3502
3568
  captureWhen: "nested",
3503
3569
  surface: "opt-out",
3570
+ instrumentation: "trace",
3504
3571
  captureContent: true,
3505
3572
  ...link !== void 0 && { nestedTrace: link }
3506
3573
  };
@@ -3524,6 +3591,7 @@ var Bitfab = class {
3524
3591
  return tracedRoot.apply(this, args);
3525
3592
  }
3526
3593
  const link = getReplayContext() || inSeedScope() ? void 0 : { traceFunctionKey };
3594
+ const rootName = rootNameFor(this);
3527
3595
  return invokeThroughAutoTraceEntries(
3528
3596
  enclosing,
3529
3597
  (entry, next) => entry.context.invokeNestedRoot(
@@ -3565,38 +3633,36 @@ var Bitfab = class {
3565
3633
  Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
3566
3634
  return autoTraceRoot;
3567
3635
  }
3636
+ applySimulationPlan(payload, submit) {
3637
+ this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
3638
+ }
3568
3639
  refreshAutoTraceCapturePolicy(traceFunctionKey) {
3569
- const now = Date.now();
3570
- const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? {
3571
- refreshAfter: 0
3572
- };
3573
- if (state.inFlight || now < state.refreshAfter) {
3574
- return;
3575
- }
3576
- const request = this.httpClient.getAutoTracePolicy(
3577
- traceFunctionKey,
3578
- AUTO_TRACE_PROTOCOL
3579
- ).then((policy) => {
3580
- if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
3581
- state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
3582
- return;
3583
- }
3584
- const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
3585
- (id) => typeof id === "string" && id.startsWith(`${AUTO_TRACE_PROTOCOL}:`)
3586
- ).slice(0, DEFAULT_AUTO_TRACE_MAX_SPANS) : [];
3587
- __setBitfabAutoTraceCapturePolicy(
3588
- this,
3589
- traceFunctionKey,
3590
- policy.revision === null ? void 0 : functionIds
3591
- );
3592
- state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_REFRESH_MS;
3593
- }).catch(() => {
3594
- state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
3595
- }).finally(() => {
3596
- state.inFlight = void 0;
3597
- });
3598
- state.inFlight = request;
3640
+ const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
3599
3641
  this.autoTracePolicyRefreshes.set(traceFunctionKey, state);
3642
+ state.run(
3643
+ () => this.httpClient.getAutoTracePolicy(
3644
+ traceFunctionKey,
3645
+ AUTO_TRACE_PROTOCOL
3646
+ ),
3647
+ (policy) => {
3648
+ if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
3649
+ state.hold(AUTO_TRACE_POLICY_RETRY_MS);
3650
+ return;
3651
+ }
3652
+ const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
3653
+ (id) => typeof id === "string" && id.startsWith(`${AUTO_TRACE_PROTOCOL}:`)
3654
+ ).slice(0, DEFAULT_AUTO_TRACE_MAX_SPANS) : [];
3655
+ __setBitfabAutoTraceCapturePolicy(
3656
+ this,
3657
+ traceFunctionKey,
3658
+ policy.revision === null ? void 0 : functionIds
3659
+ );
3660
+ state.hold(AUTO_TRACE_POLICY_REFRESH_MS);
3661
+ },
3662
+ () => {
3663
+ state.hold(AUTO_TRACE_POLICY_RETRY_MS);
3664
+ }
3665
+ );
3600
3666
  }
3601
3667
  /**
3602
3668
  * Flush and permanently close this client's tracing resources: its pending
@@ -4080,6 +4146,7 @@ var Bitfab = class {
4080
4146
  * @returns A wrapped function with the same signature that creates spans for inputs and outputs
4081
4147
  */
4082
4148
  withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
4149
+ this.simulationPlan.refresh();
4083
4150
  const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
4084
4151
  const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
4085
4152
  const self = this;
@@ -4171,8 +4238,10 @@ var Bitfab = class {
4171
4238
  const testRunId = replayCtxAtStart?.testRunId ?? options.testRunId;
4172
4239
  if (isRootSpan && !activeTraceStates.has(traceId)) {
4173
4240
  const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
4241
+ self.simulationPlan.refresh();
4174
4242
  activeTraceStates.set(traceId, {
4175
4243
  traceId,
4244
+ traceFunctionKey,
4176
4245
  startedAt,
4177
4246
  contexts: [],
4178
4247
  ...testRunId !== void 0 && { testRunId },
@@ -4187,16 +4256,19 @@ var Bitfab = class {
4187
4256
  registeredTraceId = traceId;
4188
4257
  }
4189
4258
  const functionName = fn.name !== "" ? fn.name : void 0;
4259
+ const rootTraceFunctionKey = activeTraceStates.get(traceId)?.traceFunctionKey ?? traceFunctionKey;
4190
4260
  const baseSpanParams = {
4191
4261
  traceFunctionKey,
4262
+ rootTraceFunctionKey,
4192
4263
  functionName,
4193
- spanName: options.name ?? functionName ?? traceFunctionKey,
4264
+ spanName: options.name ?? options.nameFor?.(this) ?? qualifiedSpanName(this, functionName) ?? traceFunctionKey,
4194
4265
  traceId,
4195
4266
  spanId,
4196
4267
  parentSpanId,
4197
4268
  inputs,
4198
4269
  startedAt,
4199
4270
  spanType: options.type ?? "custom",
4271
+ instrumentation: options.instrumentation ?? "span",
4200
4272
  functionId: options.functionId,
4201
4273
  captureContent: options.captureContent ?? true,
4202
4274
  autoTraceDefinition: options.autoTraceDefinition,
@@ -4612,6 +4684,7 @@ var Bitfab = class {
4612
4684
  * @returns A BitfabFunction instance for wrapping functions
4613
4685
  */
4614
4686
  getFunction(traceFunctionKey) {
4687
+ this.simulationPlan.refresh();
4615
4688
  return new BitfabFunction(this, traceFunctionKey);
4616
4689
  }
4617
4690
  /**
@@ -4699,6 +4772,7 @@ var Bitfab = class {
4699
4772
  trace_id: params.traceId,
4700
4773
  started_at: params.startedAt,
4701
4774
  ended_at: params.endedAt,
4775
+ span_origin: makeSpanOrigin(params.instrumentation),
4702
4776
  span_data: {
4703
4777
  name: params.spanName,
4704
4778
  type: params.spanType,
@@ -4759,6 +4833,9 @@ var Bitfab = class {
4759
4833
  source: "typescript-sdk-function",
4760
4834
  sourceTraceId: params.traceId,
4761
4835
  traceFunctionKey: params.traceFunctionKey,
4836
+ ...params.rootTraceFunctionKey !== void 0 && {
4837
+ [ROOT_TRACE_FUNCTION_KEY_FIELD]: params.rootTraceFunctionKey
4838
+ },
4762
4839
  rawSpan: externalSpan,
4763
4840
  ...params.testRunId && { testRunId: params.testRunId },
4764
4841
  ...params.mocked && { mocked: true },
@@ -4827,6 +4904,7 @@ var Bitfab = class {
4827
4904
  }
4828
4905
  activeTraceStates.set(traceId, {
4829
4906
  traceId,
4907
+ traceFunctionKey,
4830
4908
  startedAt,
4831
4909
  contexts: [],
4832
4910
  ingestionType: "seeded",
@@ -4836,6 +4914,7 @@ var Bitfab = class {
4836
4914
  try {
4837
4915
  this.sendWrapperSpan({
4838
4916
  traceFunctionKey,
4917
+ rootTraceFunctionKey: traceFunctionKey,
4839
4918
  spanName: options.spanName ?? traceFunctionKey,
4840
4919
  traceId,
4841
4920
  spanId: randomUuid(),
@@ -4845,6 +4924,7 @@ var Bitfab = class {
4845
4924
  startedAt,
4846
4925
  endedAt: startedAt,
4847
4926
  spanType: options.spanType ?? "agent",
4927
+ instrumentation: "span",
4848
4928
  captureContent: true
4849
4929
  });
4850
4930
  this.sendTraceCompletion({
@@ -4890,6 +4970,7 @@ var Bitfab = class {
4890
4970
  }
4891
4971
  activeTraceStates.set(traceId, {
4892
4972
  traceId,
4973
+ traceFunctionKey,
4893
4974
  startedAt: nowIsoTimestamp(),
4894
4975
  contexts: [],
4895
4976
  ingestionType: "seeded",
@@ -4902,7 +4983,7 @@ var Bitfab = class {
4902
4983
  await runWithSeedContext({ traceId }, async () => target(...args));
4903
4984
  } finally {
4904
4985
  try {
4905
- const { flushTraces: flushTraces2 } = await import("./http-MGES3ZVX.js");
4986
+ const { flushTraces: flushTraces2 } = await import("./http-2OOKOZQ3.js");
4906
4987
  await flushTraces2(3e4);
4907
4988
  } finally {
4908
4989
  unrecorded = activeTraceStates.delete(traceId);
@@ -4961,7 +5042,7 @@ var Bitfab = class {
4961
5042
  `Function is wrapped with trace function key '${wrappedKey}' but replay was called with '${traceFunctionKey}'. Pass matching keys, or pass the unwrapped function to replay it under the explicit key.`
4962
5043
  );
4963
5044
  }
4964
- const { replay: doReplay } = await import("./replay-5XES2LBL.js");
5045
+ const { replay: doReplay } = await import("./replay-KJKIGXRH.js");
4965
5046
  return doReplay(
4966
5047
  this.httpClient,
4967
5048
  this.serviceUrl,
@@ -5245,7 +5326,7 @@ async function seedFromRegistry(registry, pipeline, cases, options = {}) {
5245
5326
  sessionId: seedCase.sessionId
5246
5327
  })
5247
5328
  );
5248
- const { flushTraces: flushTraces2 } = await import("./http-MGES3ZVX.js");
5329
+ const { flushTraces: flushTraces2 } = await import("./http-2OOKOZQ3.js");
5249
5330
  await flushTraces2(3e4);
5250
5331
  return { pipeline, traceFunctionKey, traceIds };
5251
5332
  }
@@ -5282,4 +5363,4 @@ export {
5282
5363
  reseedFromRegistry,
5283
5364
  seedFromRegistry
5284
5365
  };
5285
- //# sourceMappingURL=chunk-P26KVTI5.js.map
5366
+ //# sourceMappingURL=chunk-ZCOZHNAA.js.map