bitfab 0.57.6 → 0.57.8

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
@@ -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.57.6";
54
+ __version__ = "0.57.8";
55
55
  __packageName__ = "bitfab";
56
56
  }
57
57
  });
@@ -1064,7 +1064,13 @@ var init_simulationPlan = __esm({
1064
1064
  DISABLE_SIMULATION_PLAN_ENV = "BITFAB_DISABLE_SIM_PLAN";
1065
1065
  ROOT_TRACE_FUNCTION_KEY_FIELD = "rootTraceFunctionKey";
1066
1066
  CONTENT_OFF_KEY = "content_off_by_simulation_plan";
1067
- CONTENT_KEYS = ["input", "input_meta", "output", "output_meta"];
1067
+ CONTENT_KEYS = [
1068
+ "input",
1069
+ "input_meta",
1070
+ "output",
1071
+ "output_meta",
1072
+ "prompt"
1073
+ ];
1068
1074
  SimulationPlan = class {
1069
1075
  constructor(source, enabled = true) {
1070
1076
  this.source = source;
@@ -1183,13 +1189,13 @@ var init_simulationPlan = __esm({
1183
1189
  }
1184
1190
  return this.loaded;
1185
1191
  }
1186
- send(payload, traceFunctionKey, submit) {
1192
+ send(payload, traceFunctionKey, submit, drop) {
1187
1193
  this.refresh();
1188
1194
  if (this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
1189
1195
  submit(payload);
1190
1196
  return;
1191
1197
  }
1192
- const entry = { payload, traceFunctionKey, submit };
1198
+ const entry = { payload, traceFunctionKey, submit, drop };
1193
1199
  if (this.holdingForFirstRead()) {
1194
1200
  this.hold(entry);
1195
1201
  return;
@@ -1243,6 +1249,7 @@ var init_simulationPlan = __esm({
1243
1249
  try {
1244
1250
  entry.submit(this.payloadToSend(entry));
1245
1251
  } catch (error) {
1252
+ entry.drop?.();
1246
1253
  warnOnce(
1247
1254
  "sim-plan-held-span-dropped",
1248
1255
  `a span held for the sim plan was dropped when released: ${error instanceof Error ? error.message : String(error)}`
@@ -1696,7 +1703,7 @@ var init_otel = __esm({
1696
1703
  MAX_DECOMPRESSED_REQUEST_BYTES = 8e6;
1697
1704
  MAX_REQUEST_BYTES_ENV = "BITFAB_OTEL_MAX_REQUEST_BYTES";
1698
1705
  EXPORT_CONCURRENCY_ENV = "BITFAB_OTEL_EXPORT_CONCURRENCY";
1699
- MAX_QUEUE_SIZE = 8192;
1706
+ MAX_QUEUE_SIZE = 16384;
1700
1707
  DIRECT_MAX_EXPORT_BATCH_SIZE = 512;
1701
1708
  DIRECT_MAX_REQUEST_BATCH_SIZE = 128;
1702
1709
  DEFAULT_EXPORT_CONCURRENCY = 32;
@@ -2573,23 +2580,21 @@ var init_http = __esm({
2573
2580
  }
2574
2581
  const deadline = Date.now() + Math.max(timeoutMs, 0);
2575
2582
  this.closing = (async () => {
2576
- const released = await this.releaseHeldExternalSpans?.(
2577
- planWaitSliceMs(timeoutMs)
2583
+ liveHttpClients.delete(this);
2584
+ const settled2 = await this.settleDeferredWork(
2585
+ Math.max(0, deadline - Date.now())
2578
2586
  );
2579
2587
  this.stopSimulationPlan?.();
2588
+ this.closed = true;
2580
2589
  this.externalSpanTransform = void 0;
2581
2590
  this.externalTraceTransform = void 0;
2591
+ this.frameworkSpanStart = void 0;
2582
2592
  this.releaseHeldExternalSpans = void 0;
2583
2593
  this.stopSimulationPlan = void 0;
2584
- liveHttpClients.delete(this);
2585
- const settled2 = await this.settleDeferredWork(
2586
- Math.max(0, deadline - Date.now())
2587
- );
2588
- this.closed = true;
2589
2594
  const transport = this.traceTransport;
2590
2595
  this.traceTransport = void 0;
2591
2596
  const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
2592
- return released !== false && settled2 && shutdownOk;
2597
+ return settled2 && shutdownOk;
2593
2598
  })();
2594
2599
  return this.closing;
2595
2600
  }
@@ -2690,8 +2695,7 @@ var init_http = __esm({
2690
2695
  async getSimulationPlan() {
2691
2696
  return this.get(
2692
2697
  "/api/sdk/sim-plan",
2693
- SIMULATION_PLAN_READ_TIMEOUT_MS,
2694
- { Connection: "close" }
2698
+ SIMULATION_PLAN_READ_TIMEOUT_MS
2695
2699
  );
2696
2700
  }
2697
2701
  async getTraceSpan(traceId, lookup) {
@@ -2767,19 +2771,35 @@ var init_http = __esm({
2767
2771
  carrierMeta("internal_trace", body, void 0)
2768
2772
  );
2769
2773
  }
2774
+ reserveFrameworkSpan(traceId, spanId, parentSpanId) {
2775
+ try {
2776
+ this.frameworkSpanStart?.(traceId, spanId, parentSpanId ?? null);
2777
+ } catch (error) {
2778
+ warnOnce(
2779
+ "framework-span-reservation-failed",
2780
+ `a framework span could not be counted toward its trace's span limit: ${describeError(error)}`
2781
+ );
2782
+ }
2783
+ }
2770
2784
  sendExternalSpan(payload) {
2771
2785
  const ref2 = carrierRef(payload);
2772
2786
  if (ref2?.spanId !== void 0) {
2773
2787
  this.traceCompletion.record(ref2.traceId, ref2.spanId);
2774
2788
  }
2789
+ const drop = () => {
2790
+ if (ref2?.spanId !== void 0) {
2791
+ this.traceCompletion.abort(ref2.traceId, ref2.spanId);
2792
+ }
2793
+ };
2775
2794
  const gate = this.externalSpanTransform;
2776
2795
  if (gate === void 0) {
2777
2796
  this.submitExternalSpan(payload);
2778
2797
  return;
2779
2798
  }
2780
2799
  try {
2781
- gate(payload, (ready) => this.submitExternalSpan(ready));
2800
+ gate(payload, (ready) => this.submitExternalSpan(ready), drop);
2782
2801
  } catch (error) {
2802
+ drop();
2783
2803
  warnDroppedExternalSpan(error);
2784
2804
  }
2785
2805
  }
@@ -4665,6 +4685,11 @@ var BitfabClaudeAgentHandler = class {
4665
4685
  }
4666
4686
  this.runToSpan.set(spanId, spanInfo);
4667
4687
  this.httpClient.traceCompletion.start(spanInfo.traceId, spanInfo.spanId);
4688
+ this.httpClient.reserveFrameworkSpan(
4689
+ spanInfo.traceId,
4690
+ spanInfo.spanId,
4691
+ spanInfo.parentId
4692
+ );
4668
4693
  return spanInfo;
4669
4694
  }
4670
4695
  completeSpan(spanId, output, error, extraContexts) {
@@ -4944,6 +4969,11 @@ var BitfabClaudeAgentHandler = class {
4944
4969
  this.conversationHistory.push(...this.pendingMessages);
4945
4970
  this.pendingMessages = [];
4946
4971
  this.currentLlmSpanId = randomUuid();
4972
+ this.httpClient.reserveFrameworkSpan(
4973
+ this.ensureTrace(),
4974
+ this.currentLlmSpanId,
4975
+ this.getParentId()
4976
+ );
4947
4977
  this.currentLlmMessageId = messageId ?? null;
4948
4978
  this.currentLlmContent = [];
4949
4979
  this.currentLlmModel = inner.model ?? null;
@@ -6354,6 +6384,11 @@ var BitfabLangGraphCallbackHandler = class {
6354
6384
  this.runToSpan.set(runId, spanInfo);
6355
6385
  if (spanInfo.hidden !== true) {
6356
6386
  this.httpClient.traceCompletion.start(spanInfo.traceId, spanInfo.spanId);
6387
+ this.httpClient.reserveFrameworkSpan(
6388
+ spanInfo.traceId,
6389
+ spanInfo.spanId,
6390
+ spanInfo.parentId
6391
+ );
6357
6392
  }
6358
6393
  if (isRootInvocation) {
6359
6394
  this.sendTraceStart(spanInfo);
@@ -7899,8 +7934,14 @@ var BitfabOpenAITracingProcessor = class {
7899
7934
  async onSpanStart(span) {
7900
7935
  if (span.spanId !== void 0 && span.traceId !== null && span.traceId !== void 0) {
7901
7936
  this.startedSpans.set(span.spanId, span.traceId);
7902
- const traceId = this.activeSpanMappings[span.traceId]?.traceId ?? span.traceId;
7937
+ const mapping = this.activeSpanMappings[span.traceId];
7938
+ const traceId = mapping?.traceId ?? span.traceId;
7903
7939
  this.httpClient.traceCompletion.start(traceId, span.spanId);
7940
+ this.httpClient.reserveFrameworkSpan(
7941
+ traceId,
7942
+ span.spanId,
7943
+ span.parentId ?? mapping?.spanId
7944
+ );
7904
7945
  }
7905
7946
  }
7906
7947
  /**
@@ -8287,22 +8328,68 @@ var BitfabVercelAiHandler = class {
8287
8328
 
8288
8329
  // src/client.ts
8289
8330
  init_warnOnce();
8331
+ var TRUNCATION_LIMIT_ORDER = [
8332
+ "max_depth",
8333
+ "max_spans",
8334
+ "max_captured_subtree_spans"
8335
+ ];
8290
8336
  var activeTraceStates = /* @__PURE__ */ new Map();
8291
- function fitsTraceSpanBudget(payload) {
8292
- if (!recordedByFramework(payload)) {
8293
- return true;
8337
+ var REFUSED_FRAMEWORK_SPAN_TRACES_RETAINED = 1024;
8338
+ var refusedFrameworkSpans = /* @__PURE__ */ new Map();
8339
+ function frameworkSpanRefused(traceId, spanId) {
8340
+ return refusedFrameworkSpans.get(traceId)?.has(spanId) === true;
8341
+ }
8342
+ function refuseFrameworkSpan(traceId, spanId) {
8343
+ const refused = refusedFrameworkSpans.get(traceId);
8344
+ if (refused !== void 0) {
8345
+ refused.add(spanId);
8346
+ return;
8294
8347
  }
8295
- const traceId = traceIdOf(payload);
8296
- const spanBudget = traceId === void 0 ? void 0 : activeTraceStates.get(traceId)?.spanBudget;
8297
- if (spanBudget === void 0) {
8298
- return true;
8348
+ refusedFrameworkSpans.set(traceId, /* @__PURE__ */ new Set([spanId]));
8349
+ while (refusedFrameworkSpans.size > REFUSED_FRAMEWORK_SPAN_TRACES_RETAINED) {
8350
+ const oldest = refusedFrameworkSpans.keys().next();
8351
+ if (oldest.done) {
8352
+ return;
8353
+ }
8354
+ refusedFrameworkSpans.delete(oldest.value);
8299
8355
  }
8300
- if (spanBudget.spansUsed >= spanBudget.maxSpans) {
8301
- spanBudget.truncate();
8356
+ }
8357
+ function reserveFrameworkSpan(traceId, spanId, parentSpanId) {
8358
+ const spanBudget = activeTraceStates.get(traceId)?.spanBudget;
8359
+ const parentRefused = parentSpanId !== null && frameworkSpanRefused(traceId, parentSpanId);
8360
+ if (!parentRefused && (spanBudget === void 0 || spanBudget.spansUsed < spanBudget.maxSpans)) {
8361
+ if (spanBudget !== void 0) {
8362
+ spanBudget.spansUsed += 1;
8363
+ }
8364
+ return;
8365
+ }
8366
+ refuseFrameworkSpan(traceId, spanId);
8367
+ spanBudget?.truncate("max_spans");
8368
+ }
8369
+ function isRefusedFrameworkSpan(payload) {
8370
+ if (!recordedByFramework(payload)) {
8302
8371
  return false;
8303
8372
  }
8304
- spanBudget.spansUsed += 1;
8305
- return true;
8373
+ const rawSpan = payload.rawSpan;
8374
+ const spanId = rawSpan?.id;
8375
+ if (typeof spanId !== "string") {
8376
+ return false;
8377
+ }
8378
+ const traceIds = [payload.sourceTraceId, traceIdOf(payload)];
8379
+ return traceIds.some(
8380
+ (traceId) => typeof traceId === "string" && frameworkSpanRefused(traceId, spanId)
8381
+ );
8382
+ }
8383
+ function truncationMetadata(truncation) {
8384
+ if (truncation === void 0 || truncation.limits.size === 0) {
8385
+ return void 0;
8386
+ }
8387
+ return {
8388
+ "bitfab.truncated_by": TRUNCATION_LIMIT_ORDER.filter(
8389
+ (limit) => truncation.limits.has(limit)
8390
+ ).join(","),
8391
+ "bitfab.dropped_spans": truncation.droppedSpans
8392
+ };
8306
8393
  }
8307
8394
  function rootTraceFunctionKeyOfTrace(traceId, fallback) {
8308
8395
  return activeTraceStates.get(traceId)?.traceFunctionKey ?? fallback;
@@ -8682,9 +8769,8 @@ function readBooleanEnv(name) {
8682
8769
  return void 0;
8683
8770
  }
8684
8771
  var DEFAULT_AUTO_TRACE_MAX_DEPTH = 30;
8685
- var DEFAULT_AUTO_TRACE_MAX_SPANS = 2048;
8686
- var DEFAULT_AUTO_TRACE_MAX_CAPTURED_SUBTREE_SPANS = 512;
8687
- var AUTO_TRACE_PROTOCOL = "ts-auto-v1";
8772
+ var DEFAULT_AUTO_TRACE_MAX_SPANS = 1e4;
8773
+ var DEFAULT_AUTO_TRACE_MAX_CAPTURED_SUBTREE_SPANS = 500;
8688
8774
  function spanOwnerName(receiver) {
8689
8775
  if (typeof receiver === "function") {
8690
8776
  return receiver.name !== "" ? receiver.name : void 0;
@@ -8750,7 +8836,8 @@ var Bitfab = class {
8750
8836
  this.httpClient,
8751
8837
  config.simulationPlan ?? true
8752
8838
  );
8753
- this.httpClient.externalSpanTransform = (payload, submit) => this.applySimulationPlan(payload, submit);
8839
+ this.httpClient.externalSpanTransform = (payload, submit, drop) => this.applySimulationPlan(payload, submit, drop);
8840
+ this.httpClient.frameworkSpanStart = reserveFrameworkSpan;
8754
8841
  this.httpClient.externalTraceTransform = (payload, submit) => this.simulationPlan.sendTrace(payload, submit);
8755
8842
  this.httpClient.releaseHeldExternalSpans = (timeoutMs) => this.simulationPlan.release(timeoutMs);
8756
8843
  this.httpClient.stopSimulationPlan = () => this.simulationPlan.stop();
@@ -8946,35 +9033,31 @@ var Bitfab = class {
8946
9033
  function(...args) {
8947
9034
  self.simulationPlan.refresh();
8948
9035
  let capturedSubtreeCount = 0;
8949
- let truncated = false;
8950
- const warnTruncated = () => {
8951
- if (!truncated) {
8952
- truncated = true;
8953
- getCurrentTrace().setMetadata({
8954
- bitfabAutoTrace: {
8955
- protocol: AUTO_TRACE_PROTOCOL,
8956
- truncated: true,
8957
- maxDepth,
8958
- maxSpans,
8959
- maxCapturedSubtreeSpans
8960
- }
8961
- });
8962
- }
9036
+ const rootSpanStack = getSpanStack();
9037
+ const rootSpan = rootSpanStack[rootSpanStack.length - 1];
9038
+ const rootTraceState = rootSpan === void 0 ? void 0 : activeTraceStates.get(rootSpan.traceId);
9039
+ const truncation = rootTraceState?.truncation ?? {
9040
+ limits: /* @__PURE__ */ new Set(),
9041
+ droppedSpans: 0
9042
+ };
9043
+ const truncate = (limit) => {
9044
+ truncation.limits.add(limit);
9045
+ truncation.droppedSpans += 1;
8963
9046
  warnOnce(
8964
9047
  `auto-trace-truncated:${traceFunctionKey}`,
8965
9048
  `"${traceFunctionKey}" hit an automatic subtree capture limit (maxDepth=${maxDepth}, maxCapturedSubtreeSpans=${maxCapturedSubtreeSpans}, maxSpans=${maxSpans}); its trace is incomplete. Raise the limits, declare the calls you need with node(), or narrow the subtree with exclude.`
8966
9049
  );
8967
9050
  };
8968
- const rootSpanStack = getSpanStack();
8969
9051
  const spanBudget = {
8970
9052
  spansUsed: 1,
8971
9053
  maxSpans,
8972
- truncate: () => runWithSpanStack(rootSpanStack, warnTruncated)
9054
+ truncate
8973
9055
  };
8974
- const rootSpan = rootSpanStack[rootSpanStack.length - 1];
8975
- const rootTraceState = rootSpan === void 0 ? void 0 : activeTraceStates.get(rootSpan.traceId);
8976
- if (rootTraceState !== void 0 && rootTraceState.spanBudget === void 0) {
8977
- rootTraceState.spanBudget = spanBudget;
9056
+ if (rootTraceState !== void 0) {
9057
+ rootTraceState.truncation = truncation;
9058
+ if (rootTraceState.spanBudget === void 0) {
9059
+ rootTraceState.spanBudget = spanBudget;
9060
+ }
8978
9061
  }
8979
9062
  const spanStackOf = (entry) => entry.spanStack;
8980
9063
  const openChild = (entry, childOptions, inputs, isAsync, invokeFn) => {
@@ -9014,15 +9097,16 @@ var Bitfab = class {
9014
9097
  rootTraceFunctionKeyOfEntry(entry),
9015
9098
  spanName
9016
9099
  );
9017
- if (entry.depth < maxDepth && spanBudget.spansUsed < maxSpans && (!countsTowardCapturedSubtree || capturedSubtreeCount < maxCapturedSubtreeSpans)) {
9018
- spanBudget.spansUsed += 1;
9019
- if (countsTowardCapturedSubtree) {
9020
- capturedSubtreeCount += 1;
9021
- }
9022
- return true;
9100
+ const refusedBy = entry.depth >= maxDepth ? "max_depth" : spanBudget.spansUsed >= maxSpans ? "max_spans" : countsTowardCapturedSubtree && capturedSubtreeCount >= maxCapturedSubtreeSpans ? "max_captured_subtree_spans" : void 0;
9101
+ if (refusedBy !== void 0) {
9102
+ truncate(refusedBy);
9103
+ return false;
9023
9104
  }
9024
- runWithSpanStack(spanStackOf(entry), warnTruncated);
9025
- return false;
9105
+ spanBudget.spansUsed += 1;
9106
+ if (countsTowardCapturedSubtree) {
9107
+ capturedSubtreeCount += 1;
9108
+ }
9109
+ return true;
9026
9110
  };
9027
9111
  const autoTraceContext = {
9028
9112
  traceFunctionKey,
@@ -9149,11 +9233,17 @@ var Bitfab = class {
9149
9233
  Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
9150
9234
  return autoTraceRoot;
9151
9235
  }
9152
- applySimulationPlan(payload, submit) {
9153
- if (!fitsTraceSpanBudget(payload)) {
9236
+ applySimulationPlan(payload, submit, drop) {
9237
+ if (isRefusedFrameworkSpan(payload)) {
9238
+ drop();
9154
9239
  return;
9155
9240
  }
9156
- this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
9241
+ this.simulationPlan.send(
9242
+ payload,
9243
+ rootTraceFunctionKeyOf(payload),
9244
+ submit,
9245
+ drop
9246
+ );
9157
9247
  }
9158
9248
  /**
9159
9249
  * Flush and permanently close this client's tracing resources: its pending
@@ -9822,6 +9912,9 @@ var Bitfab = class {
9822
9912
  registeredTraceId = traceId;
9823
9913
  }
9824
9914
  self.httpClient.traceCompletion.start(traceId, spanId);
9915
+ if (isFrameworkInstrumentation(options.instrumentation)) {
9916
+ reserveFrameworkSpan(traceId, spanId, parentSpanId);
9917
+ }
9825
9918
  startedSpan = { traceId, spanId };
9826
9919
  const functionName = fn.name !== "" ? fn.name : void 0;
9827
9920
  const rootTraceFunctionKey = rootTraceFunctionKeyOfTrace(
@@ -9866,6 +9959,10 @@ var Bitfab = class {
9866
9959
  }
9867
9960
  if (isRootSpan) {
9868
9961
  const traceState = activeTraceStates.get(traceId);
9962
+ const truncated = truncationMetadata(traceState?.truncation);
9963
+ if (truncated !== void 0) {
9964
+ recordCallerTraceMetadata(traceId, truncated);
9965
+ }
9869
9966
  self.sendTraceCompletion({
9870
9967
  traceFunctionKey,
9871
9968
  traceId,
@@ -10418,7 +10515,7 @@ var Bitfab = class {
10418
10515
  ...params.captureContent && params.contexts && params.contexts.length > 0 && {
10419
10516
  contexts: params.contexts
10420
10517
  },
10421
- ...params.captureContent && params.prompt !== void 0 && { prompt: params.prompt },
10518
+ ...buildsContent && params.prompt !== void 0 && { prompt: params.prompt },
10422
10519
  ...contentOff && { [CONTENT_OFF_KEY]: true }
10423
10520
  }
10424
10521
  };