bitfab 0.18.2 → 0.19.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.
package/dist/index.cjs CHANGED
@@ -54,6 +54,120 @@ var init_errors = __esm({
54
54
  }
55
55
  });
56
56
 
57
+ // src/serialize.ts
58
+ function describeValue(value) {
59
+ try {
60
+ const ctorName = value?.constructor?.name;
61
+ if (ctorName && ctorName !== "Object") {
62
+ return ctorName;
63
+ }
64
+ } catch {
65
+ }
66
+ return typeof value;
67
+ }
68
+ function unserializableStub(value, reason) {
69
+ let summary;
70
+ try {
71
+ summary = `<unserializable: ${describeValue(value)} (${reason})>`;
72
+ } catch {
73
+ summary = `<unserializable (${reason})>`;
74
+ }
75
+ return { json: summary };
76
+ }
77
+ function serializeValue(value) {
78
+ try {
79
+ const { json, meta } = import_superjson.default.serialize(value);
80
+ let size;
81
+ try {
82
+ size = JSON.stringify(json).length;
83
+ } catch {
84
+ return unserializableStub(value, "stringify_failed_after_superjson");
85
+ }
86
+ if (size > MAX_SERIALIZED_BYTES) {
87
+ return unserializableStub(value, `too_large_${size}_bytes`);
88
+ }
89
+ return meta ? { json, meta } : { json };
90
+ } catch {
91
+ try {
92
+ return { json: JSON.parse(JSON.stringify(value)) };
93
+ } catch {
94
+ return unserializableStub(value, "json_stringify_failed");
95
+ }
96
+ }
97
+ }
98
+ function deserializeValue(serialized) {
99
+ if (serialized.meta === void 0) {
100
+ return serialized.json;
101
+ }
102
+ return import_superjson.default.deserialize({
103
+ json: serialized.json,
104
+ meta: serialized.meta
105
+ });
106
+ }
107
+ function toJsonSafe(value) {
108
+ return toJsonSafeInner(value, 0, /* @__PURE__ */ new WeakSet());
109
+ }
110
+ function toJsonSafeInner(value, depth, seen) {
111
+ if (value === null || value === void 0) {
112
+ return value;
113
+ }
114
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
115
+ return value;
116
+ }
117
+ const className = value?.constructor?.name ?? typeof value;
118
+ if (depth > MAX_SAFE_DEPTH) {
119
+ return `<${className}>`;
120
+ }
121
+ if (typeof value !== "object") {
122
+ try {
123
+ return String(value);
124
+ } catch {
125
+ return `<${className}>`;
126
+ }
127
+ }
128
+ if (seen.has(value)) {
129
+ return `<cycle ${className}>`;
130
+ }
131
+ seen.add(value);
132
+ let result;
133
+ if (Array.isArray(value)) {
134
+ result = value.map((item) => toJsonSafeInner(item, depth + 1, seen));
135
+ } else if (typeof value.toJSON === "function") {
136
+ try {
137
+ result = toJsonSafeInner(
138
+ value.toJSON(),
139
+ depth + 1,
140
+ seen
141
+ );
142
+ } catch {
143
+ result = `<${className}>`;
144
+ }
145
+ } else {
146
+ try {
147
+ const obj = {};
148
+ for (const [k, v] of Object.entries(value)) {
149
+ if (!k.startsWith("_")) {
150
+ obj[k] = toJsonSafeInner(v, depth + 1, seen);
151
+ }
152
+ }
153
+ result = obj;
154
+ } catch {
155
+ result = `<${className}>`;
156
+ }
157
+ }
158
+ seen.delete(value);
159
+ return result;
160
+ }
161
+ var import_superjson, MAX_SERIALIZED_BYTES, MAX_SAFE_DEPTH;
162
+ var init_serialize = __esm({
163
+ "src/serialize.ts"() {
164
+ "use strict";
165
+ import_superjson = __toESM(require("superjson"), 1);
166
+ MAX_SERIALIZED_BYTES = 512e3;
167
+ MAX_SAFE_DEPTH = 6;
168
+ }
169
+ });
170
+
57
171
  // src/asyncStorage.ts
58
172
  function registerAsyncLocalStorageClass(cls) {
59
173
  if (!AsyncLocalStorageClass) {
@@ -115,65 +229,6 @@ var init_replayContext = __esm({
115
229
  }
116
230
  });
117
231
 
118
- // src/serialize.ts
119
- function describeValue(value) {
120
- try {
121
- const ctorName = value?.constructor?.name;
122
- if (ctorName && ctorName !== "Object") {
123
- return ctorName;
124
- }
125
- } catch {
126
- }
127
- return typeof value;
128
- }
129
- function unserializableStub(value, reason) {
130
- let summary;
131
- try {
132
- summary = `<unserializable: ${describeValue(value)} (${reason})>`;
133
- } catch {
134
- summary = `<unserializable (${reason})>`;
135
- }
136
- return { json: summary };
137
- }
138
- function serializeValue(value) {
139
- try {
140
- const { json, meta } = import_superjson.default.serialize(value);
141
- let size;
142
- try {
143
- size = JSON.stringify(json).length;
144
- } catch {
145
- return unserializableStub(value, "stringify_failed_after_superjson");
146
- }
147
- if (size > MAX_SERIALIZED_BYTES) {
148
- return unserializableStub(value, `too_large_${size}_bytes`);
149
- }
150
- return meta ? { json, meta } : { json };
151
- } catch {
152
- try {
153
- return { json: JSON.parse(JSON.stringify(value)) };
154
- } catch {
155
- return unserializableStub(value, "json_stringify_failed");
156
- }
157
- }
158
- }
159
- function deserializeValue(serialized) {
160
- if (serialized.meta === void 0) {
161
- return serialized.json;
162
- }
163
- return import_superjson.default.deserialize({
164
- json: serialized.json,
165
- meta: serialized.meta
166
- });
167
- }
168
- var import_superjson, MAX_SERIALIZED_BYTES;
169
- var init_serialize = __esm({
170
- "src/serialize.ts"() {
171
- "use strict";
172
- import_superjson = __toESM(require("superjson"), 1);
173
- MAX_SERIALIZED_BYTES = 512e3;
174
- }
175
- });
176
-
177
232
  // src/replay.ts
178
233
  var replay_exports = {};
179
234
  __export(replay_exports, {
@@ -442,13 +497,93 @@ __export(index_exports, {
442
497
  module.exports = __toCommonJS(index_exports);
443
498
 
444
499
  // src/version.generated.ts
445
- var __version__ = "0.18.2";
500
+ var __version__ = "0.19.1";
446
501
 
447
502
  // src/constants.ts
448
503
  var DEFAULT_SERVICE_URL = "https://bitfab.ai";
449
504
 
450
505
  // src/http.ts
451
506
  init_errors();
507
+ function serializePayloadBody(payload) {
508
+ try {
509
+ return { body: JSON.stringify(payload), dropped: [] };
510
+ } catch {
511
+ const dropped = [];
512
+ const sanitize = (value, seen) => {
513
+ const t = typeof value;
514
+ if (value === null || t === "string" || t === "number" || t === "boolean") {
515
+ return value;
516
+ }
517
+ if (t === "bigint") {
518
+ dropped.push("BigInt");
519
+ return "<unserializable: BigInt>";
520
+ }
521
+ if (t === "function") {
522
+ const name = value.name || "Function";
523
+ dropped.push(name);
524
+ return `<unserializable: ${name}>`;
525
+ }
526
+ if (t === "symbol") {
527
+ dropped.push("Symbol");
528
+ return "<unserializable: Symbol>";
529
+ }
530
+ if (t !== "object") {
531
+ return void 0;
532
+ }
533
+ const obj = value;
534
+ const className = obj.constructor?.name || "object";
535
+ if (seen.has(obj)) {
536
+ dropped.push(className);
537
+ return `<cycle: ${className}>`;
538
+ }
539
+ seen.add(obj);
540
+ let result;
541
+ if (Array.isArray(obj)) {
542
+ result = obj.map((item) => sanitize(item, seen));
543
+ } else if (typeof obj.toJSON === "function") {
544
+ try {
545
+ result = sanitize(obj.toJSON(), seen);
546
+ } catch {
547
+ dropped.push(className);
548
+ result = `<unserializable: ${className}>`;
549
+ }
550
+ } else {
551
+ const out = {};
552
+ for (const [k, v] of Object.entries(obj)) {
553
+ out[k] = sanitize(v, seen);
554
+ }
555
+ result = out;
556
+ }
557
+ seen.delete(obj);
558
+ return result;
559
+ };
560
+ let sanitized;
561
+ try {
562
+ sanitized = sanitize(payload, /* @__PURE__ */ new WeakSet());
563
+ } catch (error) {
564
+ const message = error instanceof Error ? error.message : String(error);
565
+ return {
566
+ body: JSON.stringify({ error: `payload_serialize_failed: ${message}` }),
567
+ dropped
568
+ };
569
+ }
570
+ if (dropped.length > 0 && typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized)) {
571
+ const obj = sanitized;
572
+ const existing = Array.isArray(obj.errors) ? obj.errors : [];
573
+ obj.errors = [
574
+ ...existing,
575
+ {
576
+ source: "sdk",
577
+ step: "json_serialize",
578
+ error: `stubbed non-serializable value(s): ${[
579
+ ...new Set(dropped)
580
+ ].join(", ")}`
581
+ }
582
+ ];
583
+ }
584
+ return { body: JSON.stringify(sanitized), dropped };
585
+ }
586
+ }
452
587
  var pendingTracePromises = /* @__PURE__ */ new Set();
453
588
  function awaitOnExit(promise) {
454
589
  pendingTracePromises.add(promise);
@@ -507,23 +642,14 @@ var HttpClient = class {
507
642
  const method = options?.method ?? "POST";
508
643
  const controller = new AbortController();
509
644
  const timeoutId = setTimeout(() => controller.abort(), timeout);
510
- let body;
511
- let serializationError;
512
- try {
513
- body = JSON.stringify(payload);
514
- } catch (error) {
515
- serializationError = error instanceof Error ? error.message : String(error);
516
- body = JSON.stringify({
517
- ...Object.fromEntries(
518
- Object.entries(payload).filter(
519
- ([, v]) => typeof v === "string" || typeof v === "number"
520
- )
521
- ),
522
- rawSpan: {},
523
- errors: [
524
- { source: "sdk", step: "json_serialize", error: serializationError }
525
- ]
526
- });
645
+ const { body, dropped } = serializePayloadBody(payload);
646
+ if (dropped.length > 0) {
647
+ try {
648
+ console.warn(
649
+ `Bitfab: request body to ${endpoint} held ${dropped.length} non-serializable value(s) (${[...new Set(dropped)].join(", ")}); they were stubbed so the span still sends, but the trace may be incomplete or not replayable. Capture a JSON-safe projection of this input to make it replayable.`
650
+ );
651
+ } catch {
652
+ }
527
653
  }
528
654
  try {
529
655
  const response = await fetch(url, {
@@ -781,56 +907,41 @@ var HttpClient = class {
781
907
  };
782
908
 
783
909
  // src/claudeAgentSdk.ts
910
+ init_serialize();
784
911
  function nowIso() {
785
912
  return (/* @__PURE__ */ new Date()).toISOString();
786
913
  }
787
- function safeSerialize(value) {
788
- if (value === null || value === void 0) {
789
- return value;
790
- }
791
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
792
- return value;
793
- }
794
- if (Array.isArray(value)) {
795
- return value.map(safeSerialize);
796
- }
797
- if (typeof value === "object") {
798
- if (typeof value.toJSON === "function") {
799
- return value.toJSON();
800
- }
801
- const result = {};
802
- for (const [k, v] of Object.entries(value)) {
803
- if (!k.startsWith("_")) {
804
- result[k] = safeSerialize(v);
805
- }
806
- }
807
- return result;
808
- }
809
- return String(value);
810
- }
914
+ var safeSerialize = toJsonSafe;
811
915
  function extractContentBlocks(content) {
812
916
  if (!Array.isArray(content)) {
813
917
  return [];
814
918
  }
815
919
  return content.map((block) => safeSerialize(block));
816
920
  }
921
+ function asTokenCount(val) {
922
+ return typeof val === "number" && Number.isFinite(val) ? val : null;
923
+ }
817
924
  function extractUsage(message) {
818
925
  const usageInfo = {};
819
926
  const usage = message.usage;
820
927
  if (!usage) {
821
928
  return usageInfo;
822
929
  }
823
- const mapping = {
824
- input_tokens: "inputTokens",
825
- output_tokens: "outputTokens",
826
- cache_read_input_tokens: "cacheReadTokens",
827
- cache_creation_input_tokens: "cacheCreationTokens"
828
- };
829
- for (const [srcKey, dstKey] of Object.entries(mapping)) {
830
- const val = usage[srcKey];
831
- if (val !== void 0 && val !== null) {
832
- usageInfo[dstKey] = val;
833
- }
930
+ const baseInput = asTokenCount(usage.input_tokens);
931
+ const cacheRead = asTokenCount(usage.cache_read_input_tokens);
932
+ const cacheCreation = asTokenCount(usage.cache_creation_input_tokens);
933
+ if (baseInput !== null || cacheRead !== null || cacheCreation !== null) {
934
+ usageInfo.inputTokens = (baseInput ?? 0) + (cacheRead ?? 0) + (cacheCreation ?? 0);
935
+ }
936
+ const output = asTokenCount(usage.output_tokens);
937
+ if (output !== null) {
938
+ usageInfo.outputTokens = output;
939
+ }
940
+ if (cacheRead !== null) {
941
+ usageInfo.cacheReadTokens = cacheRead;
942
+ }
943
+ if (cacheCreation !== null) {
944
+ usageInfo.cacheCreationTokens = cacheCreation;
834
945
  }
835
946
  return usageInfo;
836
947
  }
@@ -1563,6 +1674,7 @@ function buildSnapshotRef(config, sdkWallClockBeforeFn) {
1563
1674
  }
1564
1675
 
1565
1676
  // src/langgraph.ts
1677
+ init_serialize();
1566
1678
  var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
1567
1679
  var LANGGRAPH_METADATA_KEYS = [
1568
1680
  "langgraph_step",
@@ -1574,56 +1686,7 @@ var LANGGRAPH_METADATA_KEYS = [
1574
1686
  function nowIso2() {
1575
1687
  return (/* @__PURE__ */ new Date()).toISOString();
1576
1688
  }
1577
- var MAX_SERIALIZE_DEPTH = 6;
1578
- function safeSerialize2(value) {
1579
- return safeSerializeInner(value, 0, /* @__PURE__ */ new WeakSet());
1580
- }
1581
- function safeSerializeInner(value, depth, seen) {
1582
- if (value === null || value === void 0) {
1583
- return value;
1584
- }
1585
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1586
- return value;
1587
- }
1588
- const className = value?.constructor?.name ?? typeof value;
1589
- if (depth > MAX_SERIALIZE_DEPTH) {
1590
- return `<${className}>`;
1591
- }
1592
- if (typeof value === "object") {
1593
- if (seen.has(value)) {
1594
- return `<cycle ${className}>`;
1595
- }
1596
- seen.add(value);
1597
- }
1598
- if (Array.isArray(value)) {
1599
- return value.map((item) => safeSerializeInner(item, depth + 1, seen));
1600
- }
1601
- if (typeof value === "object") {
1602
- if (typeof value.toJSON === "function") {
1603
- try {
1604
- return value.toJSON();
1605
- } catch {
1606
- return `<${className}>`;
1607
- }
1608
- }
1609
- try {
1610
- const result = {};
1611
- for (const [k, v] of Object.entries(value)) {
1612
- if (!k.startsWith("_")) {
1613
- result[k] = safeSerializeInner(v, depth + 1, seen);
1614
- }
1615
- }
1616
- return result;
1617
- } catch {
1618
- return `<${className}>`;
1619
- }
1620
- }
1621
- try {
1622
- return String(value);
1623
- } catch {
1624
- return `<${className}>`;
1625
- }
1626
- }
1689
+ var safeSerialize2 = toJsonSafe;
1627
1690
  function convertMessage(message) {
1628
1691
  if (typeof message !== "object" || message === null) {
1629
1692
  return { role: "unknown", content: String(message) };
@@ -1672,7 +1735,7 @@ function extractModelName(serialized, metadata) {
1672
1735
  }
1673
1736
  return void 0;
1674
1737
  }
1675
- function asTokenCount(value) {
1738
+ function asTokenCount2(value) {
1676
1739
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1677
1740
  }
1678
1741
  function normalizeTokenUsage(raw) {
@@ -1681,10 +1744,10 @@ function normalizeTokenUsage(raw) {
1681
1744
  }
1682
1745
  const u = raw;
1683
1746
  if ("cache_read_input_tokens" in u || "cache_creation_input_tokens" in u) {
1684
- const cacheRead = asTokenCount(u.cache_read_input_tokens);
1685
- const cacheCreation = asTokenCount(u.cache_creation_input_tokens);
1686
- const baseInput = asTokenCount(u.input_tokens);
1687
- const outputTokens = asTokenCount(u.output_tokens);
1747
+ const cacheRead = asTokenCount2(u.cache_read_input_tokens);
1748
+ const cacheCreation = asTokenCount2(u.cache_creation_input_tokens);
1749
+ const baseInput = asTokenCount2(u.input_tokens);
1750
+ const outputTokens = asTokenCount2(u.output_tokens);
1688
1751
  if (cacheRead === null && cacheCreation === null && baseInput === null && outputTokens === null) {
1689
1752
  return null;
1690
1753
  }
@@ -1699,25 +1762,25 @@ function normalizeTokenUsage(raw) {
1699
1762
  if ("prompt_tokens" in u || "completion_tokens" in u || "promptTokens" in u || "completionTokens" in u) {
1700
1763
  const promptDetails = u.prompt_tokens_details ?? {};
1701
1764
  return withAnyTokenCount({
1702
- inputTokens: asTokenCount(u.prompt_tokens) ?? asTokenCount(u.promptTokens),
1703
- outputTokens: asTokenCount(u.completion_tokens) ?? asTokenCount(u.completionTokens),
1704
- totalTokens: asTokenCount(u.total_tokens) ?? asTokenCount(u.totalTokens),
1705
- cachedInputTokens: asTokenCount(promptDetails.cached_tokens)
1765
+ inputTokens: asTokenCount2(u.prompt_tokens) ?? asTokenCount2(u.promptTokens),
1766
+ outputTokens: asTokenCount2(u.completion_tokens) ?? asTokenCount2(u.completionTokens),
1767
+ totalTokens: asTokenCount2(u.total_tokens) ?? asTokenCount2(u.totalTokens),
1768
+ cachedInputTokens: asTokenCount2(promptDetails.cached_tokens)
1706
1769
  });
1707
1770
  }
1708
1771
  if ("prompt_token_count" in u || "candidates_token_count" in u) {
1709
1772
  return withAnyTokenCount({
1710
- inputTokens: asTokenCount(u.prompt_token_count),
1711
- outputTokens: asTokenCount(u.candidates_token_count),
1712
- totalTokens: asTokenCount(u.total_token_count),
1713
- cachedInputTokens: asTokenCount(u.cached_content_token_count)
1773
+ inputTokens: asTokenCount2(u.prompt_token_count),
1774
+ outputTokens: asTokenCount2(u.candidates_token_count),
1775
+ totalTokens: asTokenCount2(u.total_token_count),
1776
+ cachedInputTokens: asTokenCount2(u.cached_content_token_count)
1714
1777
  });
1715
1778
  }
1716
1779
  if ("input_tokens" in u || "output_tokens" in u) {
1717
1780
  const inputDetails = u.input_token_details ?? {};
1718
- const inputTokens = asTokenCount(u.input_tokens);
1719
- const outputTokens = asTokenCount(u.output_tokens);
1720
- let totalTokens = asTokenCount(u.total_tokens);
1781
+ const inputTokens = asTokenCount2(u.input_tokens);
1782
+ const outputTokens = asTokenCount2(u.output_tokens);
1783
+ let totalTokens = asTokenCount2(u.total_tokens);
1721
1784
  if (totalTokens === null && inputTokens !== null && outputTokens !== null) {
1722
1785
  totalTokens = inputTokens + outputTokens;
1723
1786
  }
@@ -1725,7 +1788,7 @@ function normalizeTokenUsage(raw) {
1725
1788
  inputTokens,
1726
1789
  outputTokens,
1727
1790
  totalTokens,
1728
- cachedInputTokens: asTokenCount(inputDetails.cache_read)
1791
+ cachedInputTokens: asTokenCount2(inputDetails.cache_read)
1729
1792
  });
1730
1793
  }
1731
1794
  return null;