bitfab 0.18.2 → 0.19.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.
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.0";
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,33 +907,11 @@ 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 [];
@@ -1563,6 +1667,7 @@ function buildSnapshotRef(config, sdkWallClockBeforeFn) {
1563
1667
  }
1564
1668
 
1565
1669
  // src/langgraph.ts
1670
+ init_serialize();
1566
1671
  var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
1567
1672
  var LANGGRAPH_METADATA_KEYS = [
1568
1673
  "langgraph_step",
@@ -1574,56 +1679,7 @@ var LANGGRAPH_METADATA_KEYS = [
1574
1679
  function nowIso2() {
1575
1680
  return (/* @__PURE__ */ new Date()).toISOString();
1576
1681
  }
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
- }
1682
+ var safeSerialize2 = toJsonSafe;
1627
1683
  function convertMessage(message) {
1628
1684
  if (typeof message !== "object" || message === null) {
1629
1685
  return { role: "unknown", content: String(message) };