@copilotkit/aimock 1.37.0 → 1.37.2
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/CHANGELOG.md +16 -0
- package/dist/agui-recorder.cjs +62 -0
- package/dist/agui-recorder.cjs.map +1 -1
- package/dist/agui-recorder.d.cts +23 -1
- package/dist/agui-recorder.d.cts.map +1 -1
- package/dist/agui-recorder.d.ts +23 -1
- package/dist/agui-recorder.d.ts.map +1 -1
- package/dist/agui-recorder.js +60 -1
- package/dist/agui-recorder.js.map +1 -1
- package/dist/agui-types.d.cts +13 -0
- package/dist/agui-types.d.ts +13 -0
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/index.cjs +5 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/journal.cjs +35 -1
- package/dist/journal.cjs.map +1 -1
- package/dist/journal.d.cts.map +1 -1
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +35 -1
- package/dist/journal.js.map +1 -1
- package/dist/recorder.cjs +12 -4
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +12 -4
- package/dist/recorder.js.map +1 -1
- package/dist/router.cjs +53 -25
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts +20 -0
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts +20 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +53 -25
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +4 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +4 -1
- package/dist/server.js.map +1 -1
- package/dist/stream-collapse.cjs +120 -27
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +31 -8
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +31 -8
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +119 -28
- package/dist/stream-collapse.js.map +1 -1
- package/dist/ws-gemini-live.d.cts +2 -2
- package/dist/ws-realtime.d.cts +2 -2
- package/package.json +1 -1
package/dist/stream-collapse.cjs
CHANGED
|
@@ -12,6 +12,75 @@ let node_zlib = require("node:zlib");
|
|
|
12
12
|
* text followed by tool calls.
|
|
13
13
|
*/
|
|
14
14
|
/**
|
|
15
|
+
* Hard ceiling (UTF-16 code units) for any SINGLE string a collapser
|
|
16
|
+
* accumulates across deltas (`content`, `reasoning`, a tool call's
|
|
17
|
+
* `arguments`, `audioB64`, `argsStr`, and the coalesced text of `orderAtoms`).
|
|
18
|
+
*
|
|
19
|
+
* V8's maximum string length on 64-bit is 2^29 - 1 (~536.8M UTF-16 code
|
|
20
|
+
* units); appending past it throws `RangeError: Invalid string length`. The
|
|
21
|
+
* proxy path bounds the raw BYTE buffer under `PROXY_BUFFER_HARD_CEILING`
|
|
22
|
+
* (256 MiB) before collapse, but the collapser is ALSO reachable directly
|
|
23
|
+
* (exported from index.ts) and — even on the proxy path — a single accumulator
|
|
24
|
+
* can approach the byte budget in code units, so it needs its own guard rather
|
|
25
|
+
* than relying on the byte cap alone. 256Mi code units is comfortably below
|
|
26
|
+
* V8's limit while leaving huge headroom for any real completion (whose
|
|
27
|
+
* accumulated content can never exceed the total streamed body).
|
|
28
|
+
*
|
|
29
|
+
* When an append would cross the ceiling the accumulator keeps the ceiling's
|
|
30
|
+
* worth of characters, drops the overflow, and marks itself truncated — never
|
|
31
|
+
* throwing — mirroring the proxy buffer's "bound then mark truncated, never
|
|
32
|
+
* fail the client" discipline.
|
|
33
|
+
*/
|
|
34
|
+
const MAX_COLLAPSE_STRING_LENGTH = 256 * 1024 * 1024;
|
|
35
|
+
/**
|
|
36
|
+
* Test-only override of {@link MAX_COLLAPSE_STRING_LENGTH}. Lets the cap suite
|
|
37
|
+
* exercise the truncation path with a tiny budget instead of building a
|
|
38
|
+
* multi-hundred-MB string. `undefined` (the default) uses the real ceiling.
|
|
39
|
+
* NEVER set from production code.
|
|
40
|
+
*/
|
|
41
|
+
let collapseStringLimitOverride;
|
|
42
|
+
/** @internal test-only — see {@link collapseStringLimitOverride}. */
|
|
43
|
+
function setCollapseStringLimitForTests(value) {
|
|
44
|
+
collapseStringLimitOverride = value;
|
|
45
|
+
}
|
|
46
|
+
/** Effective accumulated-string ceiling, honoring any active test-only override. */
|
|
47
|
+
function effectiveCollapseStringLimit() {
|
|
48
|
+
return collapseStringLimitOverride ?? MAX_COLLAPSE_STRING_LENGTH;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Guard a raw collapse-input body against V8's max string length BEFORE any
|
|
52
|
+
* per-delta accumulation begins. Every collapser accumulates `content` /
|
|
53
|
+
* `reasoning` / a tool call's `arguments` / `audioB64` / `argsStr` (and the
|
|
54
|
+
* coalesced text of `orderAtoms`) from fragments of `body`; the sum of any one
|
|
55
|
+
* of those accumulators can never exceed the total input length, so bounding
|
|
56
|
+
* the INPUT under the ceiling bounds EVERY accumulator at once — no per-`+=`
|
|
57
|
+
* site can then build a string past the limit and throw
|
|
58
|
+
* `RangeError: Invalid string length` (the ~1/sec prod crash).
|
|
59
|
+
*
|
|
60
|
+
* Returns the body UNCHANGED when it is within the ceiling. When it exceeds the
|
|
61
|
+
* ceiling this returns a hard-truncated prefix (never throwing) — the collapse
|
|
62
|
+
* result the caller builds from it is marked incomplete via `truncated: true`
|
|
63
|
+
* (see {@link isCollapseInputTruncated}). This mirrors the proxy buffer's
|
|
64
|
+
* "bound then mark truncated, never fail the client" discipline: on the proxy
|
|
65
|
+
* path a body this large has already tripped the byte cap and skipped recording,
|
|
66
|
+
* so this is a defense-in-depth backstop that also covers the direct (exported)
|
|
67
|
+
* collapse callers where no byte cap ran.
|
|
68
|
+
*/
|
|
69
|
+
function guardCollapseBody(body) {
|
|
70
|
+
const limit = effectiveCollapseStringLimit();
|
|
71
|
+
if (body.length <= limit) return body;
|
|
72
|
+
return body.slice(0, limit);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* True when a body exceeded the accumulated-string ceiling and had to be
|
|
76
|
+
* truncated by {@link guardCollapseBody}. Collapsers stamp `truncated: true` on
|
|
77
|
+
* their result in this case so the recorder skips journaling a partial fixture,
|
|
78
|
+
* exactly like a transport-truncated stream.
|
|
79
|
+
*/
|
|
80
|
+
function isCollapseInputTruncated(body) {
|
|
81
|
+
return body.length > effectiveCollapseStringLimit();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
15
84
|
* Normalize a tool call's accumulated `arguments` into valid JSON exactly like
|
|
16
85
|
* the flat-`toolCalls` recorder path: an empty / whitespace-only / missing
|
|
17
86
|
* value becomes `"{}"`, never `""`. Mirrors `recorder.ts` `toToolCallArguments`
|
|
@@ -166,8 +235,9 @@ function extractSSEData(lines) {
|
|
|
166
235
|
* data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"Hello"}}]}\n\n
|
|
167
236
|
* data: [DONE]\n\n
|
|
168
237
|
*/
|
|
169
|
-
function collapseOpenAISSE(
|
|
170
|
-
const
|
|
238
|
+
function collapseOpenAISSE(rawBody) {
|
|
239
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
240
|
+
const lines = splitSSEEvents(guardCollapseBody(rawBody));
|
|
171
241
|
let content = "";
|
|
172
242
|
let reasoning = "";
|
|
173
243
|
const webSearchQueries = [];
|
|
@@ -288,7 +358,8 @@ function collapseOpenAISSE(body) {
|
|
|
288
358
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
289
359
|
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
290
360
|
...harmonyUnparsed ? { harmonyUnparsed: true } : {},
|
|
291
|
-
...harmonyNote ? { harmonyNote } : {}
|
|
361
|
+
...harmonyNote ? { harmonyNote } : {},
|
|
362
|
+
...inputTruncated ? { truncated: true } : {}
|
|
292
363
|
};
|
|
293
364
|
}
|
|
294
365
|
return {
|
|
@@ -298,7 +369,8 @@ function collapseOpenAISSE(body) {
|
|
|
298
369
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
299
370
|
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
300
371
|
...harmonyUnparsed ? { harmonyUnparsed: true } : {},
|
|
301
|
-
...harmonyNote ? { harmonyNote } : {}
|
|
372
|
+
...harmonyNote ? { harmonyNote } : {},
|
|
373
|
+
...inputTruncated ? { truncated: true } : {}
|
|
302
374
|
};
|
|
303
375
|
}
|
|
304
376
|
/**
|
|
@@ -308,8 +380,9 @@ function collapseOpenAISSE(body) {
|
|
|
308
380
|
* event: message_start\ndata: {...}\n\n
|
|
309
381
|
* event: content_block_delta\ndata: {"delta":{"type":"text_delta","text":"Hello"}}\n\n
|
|
310
382
|
*/
|
|
311
|
-
function collapseAnthropicSSE(
|
|
312
|
-
const
|
|
383
|
+
function collapseAnthropicSSE(rawBody) {
|
|
384
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
385
|
+
const blocks = splitSSEEvents(guardCollapseBody(rawBody));
|
|
313
386
|
let content = "";
|
|
314
387
|
let reasoning = "";
|
|
315
388
|
let reasoningSignature;
|
|
@@ -399,7 +472,8 @@ function collapseAnthropicSSE(body) {
|
|
|
399
472
|
...reasoningSignature ? { reasoningSignature } : {},
|
|
400
473
|
...redactedThinking.length > 0 ? { redactedThinking } : {},
|
|
401
474
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
402
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
475
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
476
|
+
...inputTruncated ? { truncated: true } : {}
|
|
403
477
|
};
|
|
404
478
|
}
|
|
405
479
|
return {
|
|
@@ -408,7 +482,8 @@ function collapseAnthropicSSE(body) {
|
|
|
408
482
|
...reasoningSignature ? { reasoningSignature } : {},
|
|
409
483
|
...redactedThinking.length > 0 ? { redactedThinking } : {},
|
|
410
484
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
411
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
485
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
486
|
+
...inputTruncated ? { truncated: true } : {}
|
|
412
487
|
};
|
|
413
488
|
}
|
|
414
489
|
/**
|
|
@@ -417,8 +492,9 @@ function collapseAnthropicSSE(body) {
|
|
|
417
492
|
* Format (data-only, no event prefix, no [DONE]):
|
|
418
493
|
* data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}\n\n
|
|
419
494
|
*/
|
|
420
|
-
function collapseGeminiSSE(
|
|
421
|
-
const
|
|
495
|
+
function collapseGeminiSSE(rawBody) {
|
|
496
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
497
|
+
const lines = splitSSEEvents(guardCollapseBody(rawBody));
|
|
422
498
|
let content = "";
|
|
423
499
|
let reasoning = "";
|
|
424
500
|
let droppedChunks = 0;
|
|
@@ -480,7 +556,8 @@ function collapseGeminiSSE(body) {
|
|
|
480
556
|
...reasoning ? { reasoning } : {},
|
|
481
557
|
...normalizedToolCalls.length > 0 ? { toolCalls: normalizedToolCalls } : {},
|
|
482
558
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
483
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
559
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
560
|
+
...inputTruncated ? { truncated: true } : {}
|
|
484
561
|
};
|
|
485
562
|
if (toolCalls.length > 0) {
|
|
486
563
|
const blocks = buildOrderedBlocks(orderAtoms);
|
|
@@ -490,14 +567,16 @@ function collapseGeminiSSE(body) {
|
|
|
490
567
|
toolCalls: normalizedToolCalls,
|
|
491
568
|
...reasoning ? { reasoning } : {},
|
|
492
569
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
493
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
570
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
571
|
+
...inputTruncated ? { truncated: true } : {}
|
|
494
572
|
};
|
|
495
573
|
}
|
|
496
574
|
return {
|
|
497
575
|
content,
|
|
498
576
|
...reasoning ? { reasoning } : {},
|
|
499
577
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
500
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
578
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
579
|
+
...inputTruncated ? { truncated: true } : {}
|
|
501
580
|
};
|
|
502
581
|
}
|
|
503
582
|
/**
|
|
@@ -514,8 +593,9 @@ function collapseGeminiSSE(body) {
|
|
|
514
593
|
* content is run through the same fail-safe {@link parseHarmonyContent} gate to
|
|
515
594
|
* capture structured tool calls / reasoning instead of leaking raw tokens.
|
|
516
595
|
*/
|
|
517
|
-
function collapseOllamaNDJSON(
|
|
518
|
-
const
|
|
596
|
+
function collapseOllamaNDJSON(rawBody) {
|
|
597
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
598
|
+
const lines = guardCollapseBody(rawBody).split("\n").filter((l) => l.trim().length > 0);
|
|
519
599
|
let content = "";
|
|
520
600
|
let reasoning = "";
|
|
521
601
|
let droppedChunks = 0;
|
|
@@ -589,7 +669,8 @@ function collapseOllamaNDJSON(body) {
|
|
|
589
669
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
590
670
|
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
591
671
|
...harmonyUnparsed ? { harmonyUnparsed: true } : {},
|
|
592
|
-
...harmonyNote ? { harmonyNote } : {}
|
|
672
|
+
...harmonyNote ? { harmonyNote } : {},
|
|
673
|
+
...inputTruncated ? { truncated: true } : {}
|
|
593
674
|
};
|
|
594
675
|
}
|
|
595
676
|
return {
|
|
@@ -598,7 +679,8 @@ function collapseOllamaNDJSON(body) {
|
|
|
598
679
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
599
680
|
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
600
681
|
...harmonyUnparsed ? { harmonyUnparsed: true } : {},
|
|
601
|
-
...harmonyNote ? { harmonyNote } : {}
|
|
682
|
+
...harmonyNote ? { harmonyNote } : {},
|
|
683
|
+
...inputTruncated ? { truncated: true } : {}
|
|
602
684
|
};
|
|
603
685
|
}
|
|
604
686
|
/**
|
|
@@ -607,8 +689,9 @@ function collapseOllamaNDJSON(body) {
|
|
|
607
689
|
* Format:
|
|
608
690
|
* event: content-delta\ndata: {"type":"content-delta","delta":{"message":{"content":{"text":"Hello"}}}}\n\n
|
|
609
691
|
*/
|
|
610
|
-
function collapseCohereSSE(
|
|
611
|
-
const
|
|
692
|
+
function collapseCohereSSE(rawBody) {
|
|
693
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
694
|
+
const blocks = splitSSEEvents(guardCollapseBody(rawBody));
|
|
612
695
|
let content = "";
|
|
613
696
|
let reasoning = "";
|
|
614
697
|
let droppedChunks = 0;
|
|
@@ -697,14 +780,16 @@ function collapseCohereSSE(body) {
|
|
|
697
780
|
toolCalls: orderedBlocks ? orderedToolCalls : indexSortedToolCalls,
|
|
698
781
|
...reasoning ? { reasoning } : {},
|
|
699
782
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
700
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
783
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
784
|
+
...inputTruncated ? { truncated: true } : {}
|
|
701
785
|
};
|
|
702
786
|
}
|
|
703
787
|
return {
|
|
704
788
|
content,
|
|
705
789
|
...reasoning ? { reasoning } : {},
|
|
706
790
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
707
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
791
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
792
|
+
...inputTruncated ? { truncated: true } : {}
|
|
708
793
|
};
|
|
709
794
|
}
|
|
710
795
|
/**
|
|
@@ -798,8 +883,11 @@ function decodeEventStreamFrames(buf) {
|
|
|
798
883
|
* Each frame contains a JSON payload with event types like:
|
|
799
884
|
* contentBlockDelta, contentBlockStart, etc.
|
|
800
885
|
*/
|
|
801
|
-
function collapseBedrockEventStream(
|
|
802
|
-
const
|
|
886
|
+
function collapseBedrockEventStream(rawBody) {
|
|
887
|
+
const limit = effectiveCollapseStringLimit();
|
|
888
|
+
const inputTruncated = rawBody.byteLength > limit;
|
|
889
|
+
const { frames, truncated: frameTruncated } = decodeEventStreamFrames(inputTruncated ? rawBody.subarray(0, limit) : rawBody);
|
|
890
|
+
const truncated = frameTruncated || inputTruncated;
|
|
803
891
|
let content = "";
|
|
804
892
|
let reasoning = "";
|
|
805
893
|
let reasoningSignature;
|
|
@@ -954,8 +1042,9 @@ function collapseBedrockEventStream(body) {
|
|
|
954
1042
|
* delta) are still accepted for backward compatibility with previously
|
|
955
1043
|
* recorded fixtures.
|
|
956
1044
|
*/
|
|
957
|
-
function collapseGeminiInteractionsSSE(
|
|
958
|
-
const
|
|
1045
|
+
function collapseGeminiInteractionsSSE(rawBody) {
|
|
1046
|
+
const inputTruncated = isCollapseInputTruncated(rawBody);
|
|
1047
|
+
const lines = splitSSEEvents(guardCollapseBody(rawBody));
|
|
959
1048
|
let content = "";
|
|
960
1049
|
let reasoning = "";
|
|
961
1050
|
let droppedChunks = 0;
|
|
@@ -1036,13 +1125,15 @@ function collapseGeminiInteractionsSSE(body) {
|
|
|
1036
1125
|
toolCalls,
|
|
1037
1126
|
...reasoning ? { reasoning } : {},
|
|
1038
1127
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
1039
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
1128
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
1129
|
+
...inputTruncated ? { truncated: true } : {}
|
|
1040
1130
|
};
|
|
1041
1131
|
return {
|
|
1042
1132
|
content,
|
|
1043
1133
|
...reasoning ? { reasoning } : {},
|
|
1044
1134
|
...droppedChunks > 0 ? { droppedChunks } : {},
|
|
1045
|
-
...firstDroppedSample ? { firstDroppedSample } : {}
|
|
1135
|
+
...firstDroppedSample ? { firstDroppedSample } : {},
|
|
1136
|
+
...inputTruncated ? { truncated: true } : {}
|
|
1046
1137
|
};
|
|
1047
1138
|
}
|
|
1048
1139
|
/**
|
|
@@ -1074,6 +1165,7 @@ function collapseStreamingResponse(contentType, providerKey, body, logger) {
|
|
|
1074
1165
|
}
|
|
1075
1166
|
|
|
1076
1167
|
//#endregion
|
|
1168
|
+
exports.MAX_COLLAPSE_STRING_LENGTH = MAX_COLLAPSE_STRING_LENGTH;
|
|
1077
1169
|
exports.capturedRedactedData = capturedRedactedData;
|
|
1078
1170
|
exports.collapseAnthropicSSE = collapseAnthropicSSE;
|
|
1079
1171
|
exports.collapseBedrockEventStream = collapseBedrockEventStream;
|
|
@@ -1083,4 +1175,5 @@ exports.collapseGeminiSSE = collapseGeminiSSE;
|
|
|
1083
1175
|
exports.collapseOllamaNDJSON = collapseOllamaNDJSON;
|
|
1084
1176
|
exports.collapseOpenAISSE = collapseOpenAISSE;
|
|
1085
1177
|
exports.collapseStreamingResponse = collapseStreamingResponse;
|
|
1178
|
+
exports.setCollapseStringLimitForTests = setCollapseStringLimitForTests;
|
|
1086
1179
|
//# sourceMappingURL=stream-collapse.cjs.map
|