@bitfab/sdk 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.
@@ -6,7 +6,7 @@ import {
6
6
  flushTraces,
7
7
  parseRetryAfterMs,
8
8
  serializePayloadBody
9
- } from "./chunk-EQ37ZZX5.js";
9
+ } from "./chunk-TOAH2RTF.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-GRRJAMJR.js.map
19
+ //# sourceMappingURL=http-ZYEYOCJ2.js.map
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.57.6";
45
+ __version__ = "0.57.8";
46
46
  __packageName__ = "@bitfab/sdk";
47
47
  }
48
48
  });
@@ -1055,7 +1055,13 @@ var init_simulationPlan = __esm({
1055
1055
  DISABLE_SIMULATION_PLAN_ENV = "BITFAB_DISABLE_SIM_PLAN";
1056
1056
  ROOT_TRACE_FUNCTION_KEY_FIELD = "rootTraceFunctionKey";
1057
1057
  CONTENT_OFF_KEY = "content_off_by_simulation_plan";
1058
- CONTENT_KEYS = ["input", "input_meta", "output", "output_meta"];
1058
+ CONTENT_KEYS = [
1059
+ "input",
1060
+ "input_meta",
1061
+ "output",
1062
+ "output_meta",
1063
+ "prompt"
1064
+ ];
1059
1065
  SimulationPlan = class {
1060
1066
  constructor(source, enabled = true) {
1061
1067
  this.source = source;
@@ -1174,13 +1180,13 @@ var init_simulationPlan = __esm({
1174
1180
  }
1175
1181
  return this.loaded;
1176
1182
  }
1177
- send(payload, traceFunctionKey, submit) {
1183
+ send(payload, traceFunctionKey, submit, drop) {
1178
1184
  this.refresh();
1179
1185
  if (this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
1180
1186
  submit(payload);
1181
1187
  return;
1182
1188
  }
1183
- const entry = { payload, traceFunctionKey, submit };
1189
+ const entry = { payload, traceFunctionKey, submit, drop };
1184
1190
  if (this.holdingForFirstRead()) {
1185
1191
  this.hold(entry);
1186
1192
  return;
@@ -1234,6 +1240,7 @@ var init_simulationPlan = __esm({
1234
1240
  try {
1235
1241
  entry.submit(this.payloadToSend(entry));
1236
1242
  } catch (error) {
1243
+ entry.drop?.();
1237
1244
  warnOnce(
1238
1245
  "sim-plan-held-span-dropped",
1239
1246
  `a span held for the sim plan was dropped when released: ${error instanceof Error ? error.message : String(error)}`
@@ -1687,7 +1694,7 @@ var init_otel = __esm({
1687
1694
  MAX_DECOMPRESSED_REQUEST_BYTES = 8e6;
1688
1695
  MAX_REQUEST_BYTES_ENV = "BITFAB_OTEL_MAX_REQUEST_BYTES";
1689
1696
  EXPORT_CONCURRENCY_ENV = "BITFAB_OTEL_EXPORT_CONCURRENCY";
1690
- MAX_QUEUE_SIZE = 8192;
1697
+ MAX_QUEUE_SIZE = 16384;
1691
1698
  DIRECT_MAX_EXPORT_BATCH_SIZE = 512;
1692
1699
  DIRECT_MAX_REQUEST_BATCH_SIZE = 128;
1693
1700
  DEFAULT_EXPORT_CONCURRENCY = 32;
@@ -2564,23 +2571,21 @@ var init_http = __esm({
2564
2571
  }
2565
2572
  const deadline = Date.now() + Math.max(timeoutMs, 0);
2566
2573
  this.closing = (async () => {
2567
- const released = await this.releaseHeldExternalSpans?.(
2568
- planWaitSliceMs(timeoutMs)
2574
+ liveHttpClients.delete(this);
2575
+ const settled2 = await this.settleDeferredWork(
2576
+ Math.max(0, deadline - Date.now())
2569
2577
  );
2570
2578
  this.stopSimulationPlan?.();
2579
+ this.closed = true;
2571
2580
  this.externalSpanTransform = void 0;
2572
2581
  this.externalTraceTransform = void 0;
2582
+ this.frameworkSpanStart = void 0;
2573
2583
  this.releaseHeldExternalSpans = void 0;
2574
2584
  this.stopSimulationPlan = void 0;
2575
- liveHttpClients.delete(this);
2576
- const settled2 = await this.settleDeferredWork(
2577
- Math.max(0, deadline - Date.now())
2578
- );
2579
- this.closed = true;
2580
2585
  const transport = this.traceTransport;
2581
2586
  this.traceTransport = void 0;
2582
2587
  const shutdownOk = await transport?.shutdown(Math.max(0, deadline - Date.now())) ?? true;
2583
- return released !== false && settled2 && shutdownOk;
2588
+ return settled2 && shutdownOk;
2584
2589
  })();
2585
2590
  return this.closing;
2586
2591
  }
@@ -2681,8 +2686,7 @@ var init_http = __esm({
2681
2686
  async getSimulationPlan() {
2682
2687
  return this.get(
2683
2688
  "/api/sdk/sim-plan",
2684
- SIMULATION_PLAN_READ_TIMEOUT_MS,
2685
- { Connection: "close" }
2689
+ SIMULATION_PLAN_READ_TIMEOUT_MS
2686
2690
  );
2687
2691
  }
2688
2692
  async getTraceSpan(traceId, lookup) {
@@ -2758,19 +2762,35 @@ var init_http = __esm({
2758
2762
  carrierMeta("internal_trace", body, void 0)
2759
2763
  );
2760
2764
  }
2765
+ reserveFrameworkSpan(traceId, spanId, parentSpanId) {
2766
+ try {
2767
+ this.frameworkSpanStart?.(traceId, spanId, parentSpanId ?? null);
2768
+ } catch (error) {
2769
+ warnOnce(
2770
+ "framework-span-reservation-failed",
2771
+ `a framework span could not be counted toward its trace's span limit: ${describeError(error)}`
2772
+ );
2773
+ }
2774
+ }
2761
2775
  sendExternalSpan(payload) {
2762
2776
  const ref2 = carrierRef(payload);
2763
2777
  if (ref2?.spanId !== void 0) {
2764
2778
  this.traceCompletion.record(ref2.traceId, ref2.spanId);
2765
2779
  }
2780
+ const drop = () => {
2781
+ if (ref2?.spanId !== void 0) {
2782
+ this.traceCompletion.abort(ref2.traceId, ref2.spanId);
2783
+ }
2784
+ };
2766
2785
  const gate = this.externalSpanTransform;
2767
2786
  if (gate === void 0) {
2768
2787
  this.submitExternalSpan(payload);
2769
2788
  return;
2770
2789
  }
2771
2790
  try {
2772
- gate(payload, (ready) => this.submitExternalSpan(ready));
2791
+ gate(payload, (ready) => this.submitExternalSpan(ready), drop);
2773
2792
  } catch (error) {
2793
+ drop();
2774
2794
  warnDroppedExternalSpan(error);
2775
2795
  }
2776
2796
  }
@@ -4656,6 +4676,11 @@ var BitfabClaudeAgentHandler = class {
4656
4676
  }
4657
4677
  this.runToSpan.set(spanId, spanInfo);
4658
4678
  this.httpClient.traceCompletion.start(spanInfo.traceId, spanInfo.spanId);
4679
+ this.httpClient.reserveFrameworkSpan(
4680
+ spanInfo.traceId,
4681
+ spanInfo.spanId,
4682
+ spanInfo.parentId
4683
+ );
4659
4684
  return spanInfo;
4660
4685
  }
4661
4686
  completeSpan(spanId, output, error, extraContexts) {
@@ -4935,6 +4960,11 @@ var BitfabClaudeAgentHandler = class {
4935
4960
  this.conversationHistory.push(...this.pendingMessages);
4936
4961
  this.pendingMessages = [];
4937
4962
  this.currentLlmSpanId = randomUuid();
4963
+ this.httpClient.reserveFrameworkSpan(
4964
+ this.ensureTrace(),
4965
+ this.currentLlmSpanId,
4966
+ this.getParentId()
4967
+ );
4938
4968
  this.currentLlmMessageId = messageId ?? null;
4939
4969
  this.currentLlmContent = [];
4940
4970
  this.currentLlmModel = inner.model ?? null;
@@ -6345,6 +6375,11 @@ var BitfabLangGraphCallbackHandler = class {
6345
6375
  this.runToSpan.set(runId, spanInfo);
6346
6376
  if (spanInfo.hidden !== true) {
6347
6377
  this.httpClient.traceCompletion.start(spanInfo.traceId, spanInfo.spanId);
6378
+ this.httpClient.reserveFrameworkSpan(
6379
+ spanInfo.traceId,
6380
+ spanInfo.spanId,
6381
+ spanInfo.parentId
6382
+ );
6348
6383
  }
6349
6384
  if (isRootInvocation) {
6350
6385
  this.sendTraceStart(spanInfo);
@@ -7890,8 +7925,14 @@ var BitfabOpenAITracingProcessor = class {
7890
7925
  async onSpanStart(span) {
7891
7926
  if (span.spanId !== void 0 && span.traceId !== null && span.traceId !== void 0) {
7892
7927
  this.startedSpans.set(span.spanId, span.traceId);
7893
- const traceId = this.activeSpanMappings[span.traceId]?.traceId ?? span.traceId;
7928
+ const mapping = this.activeSpanMappings[span.traceId];
7929
+ const traceId = mapping?.traceId ?? span.traceId;
7894
7930
  this.httpClient.traceCompletion.start(traceId, span.spanId);
7931
+ this.httpClient.reserveFrameworkSpan(
7932
+ traceId,
7933
+ span.spanId,
7934
+ span.parentId ?? mapping?.spanId
7935
+ );
7895
7936
  }
7896
7937
  }
7897
7938
  /**
@@ -8278,22 +8319,68 @@ var BitfabVercelAiHandler = class {
8278
8319
 
8279
8320
  // src/client.ts
8280
8321
  init_warnOnce();
8322
+ var TRUNCATION_LIMIT_ORDER = [
8323
+ "max_depth",
8324
+ "max_spans",
8325
+ "max_captured_subtree_spans"
8326
+ ];
8281
8327
  var activeTraceStates = /* @__PURE__ */ new Map();
8282
- function fitsTraceSpanBudget(payload) {
8283
- if (!recordedByFramework(payload)) {
8284
- return true;
8328
+ var REFUSED_FRAMEWORK_SPAN_TRACES_RETAINED = 1024;
8329
+ var refusedFrameworkSpans = /* @__PURE__ */ new Map();
8330
+ function frameworkSpanRefused(traceId, spanId) {
8331
+ return refusedFrameworkSpans.get(traceId)?.has(spanId) === true;
8332
+ }
8333
+ function refuseFrameworkSpan(traceId, spanId) {
8334
+ const refused = refusedFrameworkSpans.get(traceId);
8335
+ if (refused !== void 0) {
8336
+ refused.add(spanId);
8337
+ return;
8285
8338
  }
8286
- const traceId = traceIdOf(payload);
8287
- const spanBudget = traceId === void 0 ? void 0 : activeTraceStates.get(traceId)?.spanBudget;
8288
- if (spanBudget === void 0) {
8289
- return true;
8339
+ refusedFrameworkSpans.set(traceId, /* @__PURE__ */ new Set([spanId]));
8340
+ while (refusedFrameworkSpans.size > REFUSED_FRAMEWORK_SPAN_TRACES_RETAINED) {
8341
+ const oldest = refusedFrameworkSpans.keys().next();
8342
+ if (oldest.done) {
8343
+ return;
8344
+ }
8345
+ refusedFrameworkSpans.delete(oldest.value);
8290
8346
  }
8291
- if (spanBudget.spansUsed >= spanBudget.maxSpans) {
8292
- spanBudget.truncate();
8347
+ }
8348
+ function reserveFrameworkSpan(traceId, spanId, parentSpanId) {
8349
+ const spanBudget = activeTraceStates.get(traceId)?.spanBudget;
8350
+ const parentRefused = parentSpanId !== null && frameworkSpanRefused(traceId, parentSpanId);
8351
+ if (!parentRefused && (spanBudget === void 0 || spanBudget.spansUsed < spanBudget.maxSpans)) {
8352
+ if (spanBudget !== void 0) {
8353
+ spanBudget.spansUsed += 1;
8354
+ }
8355
+ return;
8356
+ }
8357
+ refuseFrameworkSpan(traceId, spanId);
8358
+ spanBudget?.truncate("max_spans");
8359
+ }
8360
+ function isRefusedFrameworkSpan(payload) {
8361
+ if (!recordedByFramework(payload)) {
8293
8362
  return false;
8294
8363
  }
8295
- spanBudget.spansUsed += 1;
8296
- return true;
8364
+ const rawSpan = payload.rawSpan;
8365
+ const spanId = rawSpan?.id;
8366
+ if (typeof spanId !== "string") {
8367
+ return false;
8368
+ }
8369
+ const traceIds = [payload.sourceTraceId, traceIdOf(payload)];
8370
+ return traceIds.some(
8371
+ (traceId) => typeof traceId === "string" && frameworkSpanRefused(traceId, spanId)
8372
+ );
8373
+ }
8374
+ function truncationMetadata(truncation) {
8375
+ if (truncation === void 0 || truncation.limits.size === 0) {
8376
+ return void 0;
8377
+ }
8378
+ return {
8379
+ "bitfab.truncated_by": TRUNCATION_LIMIT_ORDER.filter(
8380
+ (limit) => truncation.limits.has(limit)
8381
+ ).join(","),
8382
+ "bitfab.dropped_spans": truncation.droppedSpans
8383
+ };
8297
8384
  }
8298
8385
  function rootTraceFunctionKeyOfTrace(traceId, fallback) {
8299
8386
  return activeTraceStates.get(traceId)?.traceFunctionKey ?? fallback;
@@ -8673,9 +8760,8 @@ function readBooleanEnv(name) {
8673
8760
  return void 0;
8674
8761
  }
8675
8762
  var DEFAULT_AUTO_TRACE_MAX_DEPTH = 30;
8676
- var DEFAULT_AUTO_TRACE_MAX_SPANS = 2048;
8677
- var DEFAULT_AUTO_TRACE_MAX_CAPTURED_SUBTREE_SPANS = 512;
8678
- var AUTO_TRACE_PROTOCOL = "ts-auto-v1";
8763
+ var DEFAULT_AUTO_TRACE_MAX_SPANS = 1e4;
8764
+ var DEFAULT_AUTO_TRACE_MAX_CAPTURED_SUBTREE_SPANS = 500;
8679
8765
  function spanOwnerName(receiver) {
8680
8766
  if (typeof receiver === "function") {
8681
8767
  return receiver.name !== "" ? receiver.name : void 0;
@@ -8741,7 +8827,8 @@ var Bitfab = class {
8741
8827
  this.httpClient,
8742
8828
  config.simulationPlan ?? true
8743
8829
  );
8744
- this.httpClient.externalSpanTransform = (payload, submit) => this.applySimulationPlan(payload, submit);
8830
+ this.httpClient.externalSpanTransform = (payload, submit, drop) => this.applySimulationPlan(payload, submit, drop);
8831
+ this.httpClient.frameworkSpanStart = reserveFrameworkSpan;
8745
8832
  this.httpClient.externalTraceTransform = (payload, submit) => this.simulationPlan.sendTrace(payload, submit);
8746
8833
  this.httpClient.releaseHeldExternalSpans = (timeoutMs) => this.simulationPlan.release(timeoutMs);
8747
8834
  this.httpClient.stopSimulationPlan = () => this.simulationPlan.stop();
@@ -8937,35 +9024,31 @@ var Bitfab = class {
8937
9024
  function(...args) {
8938
9025
  self.simulationPlan.refresh();
8939
9026
  let capturedSubtreeCount = 0;
8940
- let truncated = false;
8941
- const warnTruncated = () => {
8942
- if (!truncated) {
8943
- truncated = true;
8944
- getCurrentTrace().setMetadata({
8945
- bitfabAutoTrace: {
8946
- protocol: AUTO_TRACE_PROTOCOL,
8947
- truncated: true,
8948
- maxDepth,
8949
- maxSpans,
8950
- maxCapturedSubtreeSpans
8951
- }
8952
- });
8953
- }
9027
+ const rootSpanStack = getSpanStack();
9028
+ const rootSpan = rootSpanStack[rootSpanStack.length - 1];
9029
+ const rootTraceState = rootSpan === void 0 ? void 0 : activeTraceStates.get(rootSpan.traceId);
9030
+ const truncation = rootTraceState?.truncation ?? {
9031
+ limits: /* @__PURE__ */ new Set(),
9032
+ droppedSpans: 0
9033
+ };
9034
+ const truncate = (limit) => {
9035
+ truncation.limits.add(limit);
9036
+ truncation.droppedSpans += 1;
8954
9037
  warnOnce(
8955
9038
  `auto-trace-truncated:${traceFunctionKey}`,
8956
9039
  `"${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.`
8957
9040
  );
8958
9041
  };
8959
- const rootSpanStack = getSpanStack();
8960
9042
  const spanBudget = {
8961
9043
  spansUsed: 1,
8962
9044
  maxSpans,
8963
- truncate: () => runWithSpanStack(rootSpanStack, warnTruncated)
9045
+ truncate
8964
9046
  };
8965
- const rootSpan = rootSpanStack[rootSpanStack.length - 1];
8966
- const rootTraceState = rootSpan === void 0 ? void 0 : activeTraceStates.get(rootSpan.traceId);
8967
- if (rootTraceState !== void 0 && rootTraceState.spanBudget === void 0) {
8968
- rootTraceState.spanBudget = spanBudget;
9047
+ if (rootTraceState !== void 0) {
9048
+ rootTraceState.truncation = truncation;
9049
+ if (rootTraceState.spanBudget === void 0) {
9050
+ rootTraceState.spanBudget = spanBudget;
9051
+ }
8969
9052
  }
8970
9053
  const spanStackOf = (entry) => entry.spanStack;
8971
9054
  const openChild = (entry, childOptions, inputs, isAsync, invokeFn) => {
@@ -9005,15 +9088,16 @@ var Bitfab = class {
9005
9088
  rootTraceFunctionKeyOfEntry(entry),
9006
9089
  spanName
9007
9090
  );
9008
- if (entry.depth < maxDepth && spanBudget.spansUsed < maxSpans && (!countsTowardCapturedSubtree || capturedSubtreeCount < maxCapturedSubtreeSpans)) {
9009
- spanBudget.spansUsed += 1;
9010
- if (countsTowardCapturedSubtree) {
9011
- capturedSubtreeCount += 1;
9012
- }
9013
- return true;
9091
+ const refusedBy = entry.depth >= maxDepth ? "max_depth" : spanBudget.spansUsed >= maxSpans ? "max_spans" : countsTowardCapturedSubtree && capturedSubtreeCount >= maxCapturedSubtreeSpans ? "max_captured_subtree_spans" : void 0;
9092
+ if (refusedBy !== void 0) {
9093
+ truncate(refusedBy);
9094
+ return false;
9014
9095
  }
9015
- runWithSpanStack(spanStackOf(entry), warnTruncated);
9016
- return false;
9096
+ spanBudget.spansUsed += 1;
9097
+ if (countsTowardCapturedSubtree) {
9098
+ capturedSubtreeCount += 1;
9099
+ }
9100
+ return true;
9017
9101
  };
9018
9102
  const autoTraceContext = {
9019
9103
  traceFunctionKey,
@@ -9140,11 +9224,17 @@ var Bitfab = class {
9140
9224
  Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
9141
9225
  return autoTraceRoot;
9142
9226
  }
9143
- applySimulationPlan(payload, submit) {
9144
- if (!fitsTraceSpanBudget(payload)) {
9227
+ applySimulationPlan(payload, submit, drop) {
9228
+ if (isRefusedFrameworkSpan(payload)) {
9229
+ drop();
9145
9230
  return;
9146
9231
  }
9147
- this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
9232
+ this.simulationPlan.send(
9233
+ payload,
9234
+ rootTraceFunctionKeyOf(payload),
9235
+ submit,
9236
+ drop
9237
+ );
9148
9238
  }
9149
9239
  /**
9150
9240
  * Flush and permanently close this client's tracing resources: its pending
@@ -9813,6 +9903,9 @@ var Bitfab = class {
9813
9903
  registeredTraceId = traceId;
9814
9904
  }
9815
9905
  self.httpClient.traceCompletion.start(traceId, spanId);
9906
+ if (isFrameworkInstrumentation(options.instrumentation)) {
9907
+ reserveFrameworkSpan(traceId, spanId, parentSpanId);
9908
+ }
9816
9909
  startedSpan = { traceId, spanId };
9817
9910
  const functionName = fn.name !== "" ? fn.name : void 0;
9818
9911
  const rootTraceFunctionKey = rootTraceFunctionKeyOfTrace(
@@ -9857,6 +9950,10 @@ var Bitfab = class {
9857
9950
  }
9858
9951
  if (isRootSpan) {
9859
9952
  const traceState = activeTraceStates.get(traceId);
9953
+ const truncated = truncationMetadata(traceState?.truncation);
9954
+ if (truncated !== void 0) {
9955
+ recordCallerTraceMetadata(traceId, truncated);
9956
+ }
9860
9957
  self.sendTraceCompletion({
9861
9958
  traceFunctionKey,
9862
9959
  traceId,
@@ -10409,7 +10506,7 @@ var Bitfab = class {
10409
10506
  ...params.captureContent && params.contexts && params.contexts.length > 0 && {
10410
10507
  contexts: params.contexts
10411
10508
  },
10412
- ...params.captureContent && params.prompt !== void 0 && { prompt: params.prompt },
10509
+ ...buildsContent && params.prompt !== void 0 && { prompt: params.prompt },
10413
10510
  ...contentOff && { [CONTENT_OFF_KEY]: true }
10414
10511
  }
10415
10512
  };