langsmith 0.5.23 → 0.5.25

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.
Files changed (89) hide show
  1. package/dist/client.cjs +102 -11
  2. package/dist/client.d.ts +38 -0
  3. package/dist/client.js +103 -12
  4. package/dist/evaluation/_runner.cjs +3 -3
  5. package/dist/evaluation/_runner.js +1 -1
  6. package/dist/evaluation/evaluate_comparative.cjs +10 -10
  7. package/dist/evaluation/evaluate_comparative.js +1 -1
  8. package/dist/evaluation/evaluator.cjs +2 -2
  9. package/dist/evaluation/evaluator.js +1 -1
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +1 -1
  13. package/dist/run_trees.cjs +8 -7
  14. package/dist/run_trees.d.ts +7 -0
  15. package/dist/run_trees.js +7 -6
  16. package/dist/schemas.d.ts +4 -0
  17. package/dist/singletons/otel.cjs +3 -2
  18. package/dist/singletons/otel.js +4 -3
  19. package/dist/traceable.cjs +1 -2
  20. package/dist/traceable.js +1 -2
  21. package/dist/utils/_uuid.cjs +2 -2
  22. package/dist/utils/_uuid.js +1 -1
  23. package/dist/utils/env.cjs +33 -0
  24. package/dist/utils/env.d.ts +9 -0
  25. package/dist/utils/env.js +32 -0
  26. package/dist/utils/fast-safe-stringify/index.cjs +10 -35
  27. package/dist/utils/fast-safe-stringify/index.d.ts +14 -1
  28. package/dist/utils/fast-safe-stringify/index.js +10 -35
  29. package/dist/utils/jestlike/index.cjs +5 -5
  30. package/dist/utils/jestlike/index.js +1 -1
  31. package/dist/utils/jestlike/vendor/evaluatedBy.cjs +3 -3
  32. package/dist/utils/jestlike/vendor/evaluatedBy.js +1 -1
  33. package/dist/utils/serialize_worker.cjs +389 -0
  34. package/dist/utils/serialize_worker.d.ts +67 -0
  35. package/dist/utils/serialize_worker.js +383 -0
  36. package/dist/utils/uuid/src/index.cjs +24 -0
  37. package/dist/utils/uuid/src/index.d.ts +10 -0
  38. package/dist/utils/uuid/src/index.js +9 -0
  39. package/dist/utils/uuid/src/max.cjs +3 -0
  40. package/dist/utils/uuid/src/max.d.ts +2 -0
  41. package/dist/utils/uuid/src/max.js +1 -0
  42. package/dist/utils/uuid/src/nil.cjs +3 -0
  43. package/dist/utils/uuid/src/nil.d.ts +2 -0
  44. package/dist/utils/uuid/src/nil.js +1 -0
  45. package/dist/utils/uuid/src/parse.cjs +23 -0
  46. package/dist/utils/uuid/src/parse.d.ts +3 -0
  47. package/dist/utils/uuid/src/parse.js +18 -0
  48. package/dist/utils/uuid/src/regex.cjs +3 -0
  49. package/dist/utils/uuid/src/regex.d.ts +2 -0
  50. package/dist/utils/uuid/src/regex.js +1 -0
  51. package/dist/utils/uuid/src/rng.cjs +10 -0
  52. package/dist/utils/uuid/src/rng.d.ts +1 -0
  53. package/dist/utils/uuid/src/rng.js +7 -0
  54. package/dist/utils/uuid/src/sha1.cjs +75 -0
  55. package/dist/utils/uuid/src/sha1.d.ts +2 -0
  56. package/dist/utils/uuid/src/sha1.js +73 -0
  57. package/dist/utils/uuid/src/stringify.cjs +55 -0
  58. package/dist/utils/uuid/src/stringify.d.ts +3 -0
  59. package/dist/utils/uuid/src/stringify.js +49 -0
  60. package/dist/utils/uuid/src/types.cjs +2 -0
  61. package/dist/utils/uuid/src/types.d.ts +22 -0
  62. package/dist/utils/uuid/src/types.js +1 -0
  63. package/dist/utils/uuid/src/v35.cjs +52 -0
  64. package/dist/utils/uuid/src/v35.d.ts +7 -0
  65. package/dist/utils/uuid/src/v35.js +44 -0
  66. package/dist/utils/uuid/src/v4.cjs +40 -0
  67. package/dist/utils/uuid/src/v4.d.ts +4 -0
  68. package/dist/utils/uuid/src/v4.js +35 -0
  69. package/dist/utils/uuid/src/v5.cjs +50 -0
  70. package/dist/utils/uuid/src/v5.d.ts +9 -0
  71. package/dist/utils/uuid/src/v5.js +9 -0
  72. package/dist/utils/uuid/src/v7.cjs +88 -0
  73. package/dist/utils/uuid/src/v7.d.ts +9 -0
  74. package/dist/utils/uuid/src/v7.js +82 -0
  75. package/dist/utils/uuid/src/validate.cjs +10 -0
  76. package/dist/utils/uuid/src/validate.d.ts +2 -0
  77. package/dist/utils/uuid/src/validate.js +5 -0
  78. package/dist/utils/uuid/src/version.cjs +13 -0
  79. package/dist/utils/uuid/src/version.d.ts +2 -0
  80. package/dist/utils/uuid/src/version.js +8 -0
  81. package/dist/utils/worker_threads.browser.cjs +16 -0
  82. package/dist/utils/worker_threads.browser.d.ts +14 -0
  83. package/dist/utils/worker_threads.browser.js +13 -0
  84. package/dist/utils/worker_threads.cjs +16 -0
  85. package/dist/utils/worker_threads.d.ts +13 -0
  86. package/dist/utils/worker_threads.js +13 -0
  87. package/dist/uuid.cjs +2 -2
  88. package/dist/uuid.js +1 -1
  89. package/package.json +4 -4
@@ -0,0 +1,389 @@
1
+ "use strict";
2
+ /**
3
+ * Off-thread serialization using Node worker_threads.
4
+ *
5
+ * Gated behind LANGSMITH_PERF_OPTIMIZATION=true. Falls back silently to
6
+ * synchronous serialize() when:
7
+ * - worker_threads is unavailable (browsers, Deno, Bun without compat,
8
+ * Cloudflare Workers, Vercel Edge, React Native)
9
+ * - the worker cannot be constructed (bundler/runtime constraints)
10
+ * - DataCloneError is thrown for a payload containing non-cloneable
11
+ * values (functions, class instances with non-cloneable state, etc.)
12
+ * - the worker crashes or throws
13
+ *
14
+ * Protocol:
15
+ * main -> worker: { id, op, payload }
16
+ * op = "serialize" -> worker returns bytes as a transferable ArrayBuffer
17
+ * worker -> main: { id, bytes?: ArrayBuffer, error?: string }
18
+ *
19
+ * The worker source is inlined as a string so the library bundles cleanly
20
+ * under webpack/esbuild/ncc without requiring a separate asset file.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.SerializeWorker = void 0;
24
+ exports.getSharedSerializeWorker = getSharedSerializeWorker;
25
+ exports.hasLargeString = hasLargeString;
26
+ const worker_threads_js_1 = require("./worker_threads.cjs");
27
+ // The worker script: a self-contained mirror of the hot path of
28
+ // src/utils/fast-safe-stringify/index.ts#serialize(). We deliberately
29
+ // don't import the TS module -- the worker runs as a standalone script.
30
+ const WORKER_SOURCE = /* js */ `
31
+ const { parentPort } = require("worker_threads");
32
+
33
+ const CIRCULAR_REPLACE_NODE = { result: "[Circular]" };
34
+
35
+ function serializeWellKnownTypes(val) {
36
+ if (val && typeof val === "object") {
37
+ if (val instanceof Map) return Object.fromEntries(val);
38
+ if (val instanceof Set) return Array.from(val);
39
+ if (val instanceof Date) return val.toISOString();
40
+ if (val instanceof RegExp) return val.toString();
41
+ if (val instanceof Error) return { name: val.name, message: val.message };
42
+ } else if (typeof val === "bigint") {
43
+ return val.toString();
44
+ }
45
+ return val;
46
+ }
47
+
48
+ function defaultReplacer(_key, val) {
49
+ return serializeWellKnownTypes(val);
50
+ }
51
+
52
+ // Decirculate in-place: replace circular refs with { result: "[Circular]" }
53
+ // then restore after stringify. Mirrors fast-safe-stringify's decirc().
54
+ const restoreStack = [];
55
+ function decirc(val, k, stack, parent) {
56
+ if (typeof val === "object" && val !== null) {
57
+ for (let i = 0; i < stack.length; i++) {
58
+ if (stack[i] === val) {
59
+ const orig = parent[k];
60
+ parent[k] = CIRCULAR_REPLACE_NODE;
61
+ restoreStack.push([parent, k, orig]);
62
+ return;
63
+ }
64
+ }
65
+ stack.push(val);
66
+ if (Array.isArray(val)) {
67
+ for (let i = 0; i < val.length; i++) decirc(val[i], i, stack, val);
68
+ } else {
69
+ const normalized = serializeWellKnownTypes(val);
70
+ // Only recurse into normalized if it's still an object (arrays/objects),
71
+ // else it was replaced with a primitive (e.g. Date -> string).
72
+ if (normalized === val) {
73
+ const keys = Object.keys(val);
74
+ for (let i = 0; i < keys.length; i++) decirc(val[keys[i]], keys[i], stack, val);
75
+ }
76
+ }
77
+ stack.pop();
78
+ }
79
+ }
80
+
81
+ function serialize(obj) {
82
+ try {
83
+ return JSON.stringify(obj, defaultReplacer);
84
+ } catch (e) {
85
+ if (!String(e && e.message).includes("Converting circular structure to JSON")) {
86
+ return "[Unserializable]";
87
+ }
88
+ decirc(obj, "", [], { "": obj });
89
+ try {
90
+ return JSON.stringify(obj, defaultReplacer);
91
+ } catch (_) {
92
+ return "[unable to serialize, circular reference is too complex to analyze]";
93
+ } finally {
94
+ while (restoreStack.length) {
95
+ const [p, k, v] = restoreStack.pop();
96
+ p[k] = v;
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ parentPort.on("message", (msg) => {
103
+ const { id, op, payload } = msg;
104
+ try {
105
+ if (op === "serialize") {
106
+ const str = serialize(payload);
107
+ const buf = Buffer.from(str, "utf8");
108
+ // Slice into its own ArrayBuffer so we can transfer without dragging
109
+ // unrelated bytes from any shared pool buffer.
110
+ const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
111
+ parentPort.postMessage({ id, bytes: ab, length: buf.byteLength }, [ab]);
112
+ } else if (op === "ping") {
113
+ parentPort.postMessage({ id });
114
+ } else {
115
+ parentPort.postMessage({ id, error: "unknown op: " + op });
116
+ }
117
+ } catch (e) {
118
+ parentPort.postMessage({ id, error: String((e && e.message) || e) });
119
+ }
120
+ });
121
+ `;
122
+ class SerializeWorker {
123
+ constructor() {
124
+ Object.defineProperty(this, "worker", {
125
+ enumerable: true,
126
+ configurable: true,
127
+ writable: true,
128
+ value: null
129
+ });
130
+ Object.defineProperty(this, "nextId", {
131
+ enumerable: true,
132
+ configurable: true,
133
+ writable: true,
134
+ value: 1
135
+ });
136
+ Object.defineProperty(this, "pending", {
137
+ enumerable: true,
138
+ configurable: true,
139
+ writable: true,
140
+ value: new Map()
141
+ });
142
+ Object.defineProperty(this, "disabled", {
143
+ enumerable: true,
144
+ configurable: true,
145
+ writable: true,
146
+ value: false
147
+ });
148
+ Object.defineProperty(this, "startPromise", {
149
+ enumerable: true,
150
+ configurable: true,
151
+ writable: true,
152
+ value: null
153
+ });
154
+ }
155
+ /**
156
+ * Try to construct the worker. Returns false if the runtime can't support
157
+ * it -- in that case callers must fall back to synchronous serialization.
158
+ * Kept async so callers don't have to branch on runtime -- the promise
159
+ * resolves synchronously on the microtask queue when the worker module
160
+ * is available, which is the common Node CJS/ESM path.
161
+ */
162
+ async ensureStarted() {
163
+ if (this.disabled)
164
+ return false;
165
+ if (this.worker !== null)
166
+ return true;
167
+ if (this.startPromise !== null)
168
+ return this.startPromise;
169
+ this.startPromise = this._start();
170
+ try {
171
+ return await this.startPromise;
172
+ }
173
+ finally {
174
+ this.startPromise = null;
175
+ }
176
+ }
177
+ async _start() {
178
+ // In browser / edge builds the `worker_threads` module is swapped with
179
+ // a stub that reports unavailability via the package.json `browser`
180
+ // field. Bail out before touching any Node-only surface.
181
+ if (!worker_threads_js_1.WORKER_THREADS_AVAILABLE || worker_threads_js_1.Worker === null) {
182
+ this.disabled = true;
183
+ return false;
184
+ }
185
+ try {
186
+ const worker = new worker_threads_js_1.Worker(WORKER_SOURCE, { eval: true });
187
+ worker.on("message", (msg) => {
188
+ const p = this.pending.get(msg.id);
189
+ if (!p)
190
+ return;
191
+ this.pending.delete(msg.id);
192
+ if (msg.error) {
193
+ p.reject(new Error(msg.error));
194
+ }
195
+ else if (msg.bytes && typeof msg.length === "number") {
196
+ p.resolve(new Uint8Array(msg.bytes, 0, msg.length));
197
+ }
198
+ else {
199
+ p.reject(new Error("worker returned malformed message"));
200
+ }
201
+ });
202
+ worker.on("error", (err) => {
203
+ // Reject all pending and disable; caller will fall back.
204
+ for (const [, p] of this.pending)
205
+ p.reject(err);
206
+ this.pending.clear();
207
+ this.disabled = true;
208
+ this.worker = null;
209
+ });
210
+ worker.on("exit", (code) => {
211
+ // Reject all pending requests regardless of exit code. Even a clean
212
+ // exit (code 0) with in-flight requests means those promises would
213
+ // otherwise hang forever.
214
+ for (const [, p] of this.pending) {
215
+ p.reject(new Error(`worker exited with code ${code}`));
216
+ }
217
+ this.pending.clear();
218
+ this.worker = null;
219
+ });
220
+ // Don't let the worker keep the process alive.
221
+ worker.unref();
222
+ this.worker = worker;
223
+ return true;
224
+ }
225
+ catch {
226
+ this.disabled = true;
227
+ return false;
228
+ }
229
+ }
230
+ /**
231
+ * Serialize a payload off-thread. Rejects with DataCloneError (or similar)
232
+ * if the payload contains non-cloneable values -- callers must catch and
233
+ * fall back to synchronous serialize().
234
+ *
235
+ * Resolves with null if the worker subsystem is unavailable entirely,
236
+ * so the caller can fall back without paying try/catch overhead.
237
+ */
238
+ async serialize(payload) {
239
+ const ok = await this.ensureStarted();
240
+ if (!ok)
241
+ return null;
242
+ const id = this.nextId++;
243
+ return new Promise((resolve, reject) => {
244
+ this.pending.set(id, { resolve, reject });
245
+ try {
246
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
+ this.worker.postMessage({ id, op: "serialize", payload });
248
+ }
249
+ catch (e) {
250
+ // postMessage throws synchronously for DataCloneError, unclonable
251
+ // values, detached buffers, etc.
252
+ this.pending.delete(id);
253
+ reject(e);
254
+ }
255
+ });
256
+ }
257
+ async terminate() {
258
+ if (this.worker) {
259
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
+ await this.worker.terminate();
261
+ this.worker = null;
262
+ }
263
+ for (const [, p] of this.pending) {
264
+ p.reject(new Error("worker terminated"));
265
+ }
266
+ this.pending.clear();
267
+ }
268
+ }
269
+ exports.SerializeWorker = SerializeWorker;
270
+ let sharedWorker = null;
271
+ /**
272
+ * Process-wide shared worker. One worker serves all Client instances to
273
+ * avoid spawning multiple threads per process.
274
+ */
275
+ function getSharedSerializeWorker() {
276
+ if (sharedWorker === null)
277
+ sharedWorker = new SerializeWorker();
278
+ return sharedWorker;
279
+ }
280
+ /**
281
+ * Minimum string length (in UTF-16 code units) that justifies the overhead
282
+ * of dispatching serialization to a worker thread.
283
+ *
284
+ * Rationale: V8's postMessage / structuredClone fast-paths large strings
285
+ * across isolates by refcounting their underlying storage rather than
286
+ * copying the bytes. This makes worker offload a big win for payloads
287
+ * dominated by a handful of multi-hundred-KB strings (the classic case is
288
+ * base64-encoded images or audio in LLM messages), but a net loss for
289
+ * payloads whose bulk is structural -- thousands of keys, deep nesting,
290
+ * many small strings -- because every object node must still be walked
291
+ * and cloned.
292
+ *
293
+ * 64KB sits comfortably above typical "chunk of agent state" or "long
294
+ * prompt" values (a few KB) and below typical base64 media payloads
295
+ * (hundreds of KB to several MB).
296
+ */
297
+ const LARGE_STRING_THRESHOLD = 64 * 1024;
298
+ /**
299
+ * Maximum number of nodes to inspect before giving up and assuming the
300
+ * payload is not worth offloading. Prevents the check itself from becoming
301
+ * expensive on pathologically structural payloads (many thousands of small
302
+ * keys / array elements).
303
+ *
304
+ * When the budget is exhausted without finding a large string we return
305
+ * false (do not offload). This is the conservative choice: such payloads
306
+ * are structural by nature and worker offload empirically regresses them.
307
+ */
308
+ const NODE_BUDGET = 2048;
309
+ /**
310
+ * Cheap, short-circuiting walk that returns true iff the payload contains
311
+ * at least one string of length >= threshold anywhere in its graph.
312
+ *
313
+ * - Terminates immediately on the first qualifying string.
314
+ * - Caps total nodes visited at `nodeBudget` so cost is bounded for huge
315
+ * structural payloads.
316
+ * - Avoids allocation in the common path: uses an array as a stack and a
317
+ * Set only for cycle detection.
318
+ * - Uses `string.length` (UTF-16 units), not UTF-8 byte length, because
319
+ * that's what V8's string-sharing fast path keys on and because it's
320
+ * an O(1) property access. For ASCII content this is identical to the
321
+ * UTF-8 byte count; for non-ASCII text the two differ by at most 4x,
322
+ * well within the safety margin of the threshold.
323
+ */
324
+ function hasLargeString(value, threshold = LARGE_STRING_THRESHOLD, nodeBudget = NODE_BUDGET) {
325
+ if (value === null || typeof value !== "object") {
326
+ return typeof value === "string" && value.length >= threshold;
327
+ }
328
+ const stack = [value];
329
+ const seen = new Set();
330
+ let visited = 0;
331
+ while (stack.length > 0) {
332
+ if (visited++ >= nodeBudget)
333
+ return false;
334
+ const cur = stack.pop();
335
+ if (cur === null || cur === undefined)
336
+ continue;
337
+ const t = typeof cur;
338
+ if (t === "string") {
339
+ if (cur.length >= threshold)
340
+ return true;
341
+ continue;
342
+ }
343
+ if (t !== "object")
344
+ continue;
345
+ const obj = cur;
346
+ if (seen.has(obj))
347
+ continue;
348
+ seen.add(obj);
349
+ // Skip well-known opaque types -- none of their enumerable own
350
+ // properties produce large strings in practice, and ArrayBuffer views
351
+ // would inflate the node budget if iterated element by element.
352
+ /* eslint-disable no-instanceof/no-instanceof */
353
+ if (obj instanceof Date ||
354
+ obj instanceof RegExp ||
355
+ obj instanceof Error ||
356
+ obj instanceof ArrayBuffer ||
357
+ ArrayBuffer.isView(obj)) {
358
+ continue;
359
+ }
360
+ if (Array.isArray(obj)) {
361
+ // Iterate in reverse so the first element is popped first (stable
362
+ // left-to-right discovery order, harmless but nice for predictable
363
+ // short-circuits in tests).
364
+ for (let i = obj.length - 1; i >= 0; i--)
365
+ stack.push(obj[i]);
366
+ continue;
367
+ }
368
+ if (obj instanceof Map) {
369
+ for (const [, v] of obj)
370
+ stack.push(v);
371
+ continue;
372
+ }
373
+ if (obj instanceof Set) {
374
+ for (const v of obj)
375
+ stack.push(v);
376
+ continue;
377
+ }
378
+ /* eslint-enable no-instanceof/no-instanceof */
379
+ // Push keys in reverse so they pop in declared order. Combined with
380
+ // the similar reverse-push for arrays above, this makes discovery
381
+ // order a stable depth-first walk in source order -- which matters
382
+ // for predictable short-circuit behavior under a node budget.
383
+ const keys = Object.keys(obj);
384
+ for (let i = keys.length - 1; i >= 0; i--) {
385
+ stack.push(obj[keys[i]]);
386
+ }
387
+ }
388
+ return false;
389
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Off-thread serialization using Node worker_threads.
3
+ *
4
+ * Gated behind LANGSMITH_PERF_OPTIMIZATION=true. Falls back silently to
5
+ * synchronous serialize() when:
6
+ * - worker_threads is unavailable (browsers, Deno, Bun without compat,
7
+ * Cloudflare Workers, Vercel Edge, React Native)
8
+ * - the worker cannot be constructed (bundler/runtime constraints)
9
+ * - DataCloneError is thrown for a payload containing non-cloneable
10
+ * values (functions, class instances with non-cloneable state, etc.)
11
+ * - the worker crashes or throws
12
+ *
13
+ * Protocol:
14
+ * main -> worker: { id, op, payload }
15
+ * op = "serialize" -> worker returns bytes as a transferable ArrayBuffer
16
+ * worker -> main: { id, bytes?: ArrayBuffer, error?: string }
17
+ *
18
+ * The worker source is inlined as a string so the library bundles cleanly
19
+ * under webpack/esbuild/ncc without requiring a separate asset file.
20
+ */
21
+ export declare class SerializeWorker {
22
+ private worker;
23
+ private nextId;
24
+ private pending;
25
+ private disabled;
26
+ private startPromise;
27
+ /**
28
+ * Try to construct the worker. Returns false if the runtime can't support
29
+ * it -- in that case callers must fall back to synchronous serialization.
30
+ * Kept async so callers don't have to branch on runtime -- the promise
31
+ * resolves synchronously on the microtask queue when the worker module
32
+ * is available, which is the common Node CJS/ESM path.
33
+ */
34
+ private ensureStarted;
35
+ private _start;
36
+ /**
37
+ * Serialize a payload off-thread. Rejects with DataCloneError (or similar)
38
+ * if the payload contains non-cloneable values -- callers must catch and
39
+ * fall back to synchronous serialize().
40
+ *
41
+ * Resolves with null if the worker subsystem is unavailable entirely,
42
+ * so the caller can fall back without paying try/catch overhead.
43
+ */
44
+ serialize(payload: unknown): Promise<Uint8Array<ArrayBuffer> | null>;
45
+ terminate(): Promise<void>;
46
+ }
47
+ /**
48
+ * Process-wide shared worker. One worker serves all Client instances to
49
+ * avoid spawning multiple threads per process.
50
+ */
51
+ export declare function getSharedSerializeWorker(): SerializeWorker;
52
+ /**
53
+ * Cheap, short-circuiting walk that returns true iff the payload contains
54
+ * at least one string of length >= threshold anywhere in its graph.
55
+ *
56
+ * - Terminates immediately on the first qualifying string.
57
+ * - Caps total nodes visited at `nodeBudget` so cost is bounded for huge
58
+ * structural payloads.
59
+ * - Avoids allocation in the common path: uses an array as a stack and a
60
+ * Set only for cycle detection.
61
+ * - Uses `string.length` (UTF-16 units), not UTF-8 byte length, because
62
+ * that's what V8's string-sharing fast path keys on and because it's
63
+ * an O(1) property access. For ASCII content this is identical to the
64
+ * UTF-8 byte count; for non-ASCII text the two differ by at most 4x,
65
+ * well within the safety margin of the threshold.
66
+ */
67
+ export declare function hasLargeString(value: unknown, threshold?: number, nodeBudget?: number): boolean;