@copilotkit/aimock 1.37.0 → 1.37.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/agui-recorder.cjs +62 -0
  3. package/dist/agui-recorder.cjs.map +1 -1
  4. package/dist/agui-recorder.d.cts +23 -1
  5. package/dist/agui-recorder.d.cts.map +1 -1
  6. package/dist/agui-recorder.d.ts +23 -1
  7. package/dist/agui-recorder.d.ts.map +1 -1
  8. package/dist/agui-recorder.js +60 -1
  9. package/dist/agui-recorder.js.map +1 -1
  10. package/dist/agui-types.d.cts +13 -0
  11. package/dist/agui-types.d.ts +13 -0
  12. package/dist/config-loader.d.cts.map +1 -1
  13. package/dist/index.cjs +5 -0
  14. package/dist/index.d.cts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +3 -3
  17. package/dist/recorder.cjs +12 -4
  18. package/dist/recorder.cjs.map +1 -1
  19. package/dist/recorder.d.cts.map +1 -1
  20. package/dist/recorder.d.ts.map +1 -1
  21. package/dist/recorder.js +12 -4
  22. package/dist/recorder.js.map +1 -1
  23. package/dist/router.cjs +53 -25
  24. package/dist/router.cjs.map +1 -1
  25. package/dist/router.d.cts +20 -0
  26. package/dist/router.d.cts.map +1 -1
  27. package/dist/router.d.ts +20 -0
  28. package/dist/router.d.ts.map +1 -1
  29. package/dist/router.js +53 -25
  30. package/dist/router.js.map +1 -1
  31. package/dist/stream-collapse.cjs +120 -27
  32. package/dist/stream-collapse.cjs.map +1 -1
  33. package/dist/stream-collapse.d.cts +31 -8
  34. package/dist/stream-collapse.d.cts.map +1 -1
  35. package/dist/stream-collapse.d.ts +31 -8
  36. package/dist/stream-collapse.d.ts.map +1 -1
  37. package/dist/stream-collapse.js +119 -28
  38. package/dist/stream-collapse.js.map +1 -1
  39. package/dist/vector-types.d.ts.map +1 -1
  40. package/dist/ws-gemini-live.d.ts +2 -2
  41. package/dist/ws-realtime.d.ts +2 -2
  42. package/package.json +1 -1
@@ -3,6 +3,29 @@ import { FixtureBlock, RecordProviderKey, ToolCall } from "./types.js";
3
3
 
4
4
  //#region src/stream-collapse.d.ts
5
5
 
6
+ /**
7
+ * Hard ceiling (UTF-16 code units) for any SINGLE string a collapser
8
+ * accumulates across deltas (`content`, `reasoning`, a tool call's
9
+ * `arguments`, `audioB64`, `argsStr`, and the coalesced text of `orderAtoms`).
10
+ *
11
+ * V8's maximum string length on 64-bit is 2^29 - 1 (~536.8M UTF-16 code
12
+ * units); appending past it throws `RangeError: Invalid string length`. The
13
+ * proxy path bounds the raw BYTE buffer under `PROXY_BUFFER_HARD_CEILING`
14
+ * (256 MiB) before collapse, but the collapser is ALSO reachable directly
15
+ * (exported from index.ts) and — even on the proxy path — a single accumulator
16
+ * can approach the byte budget in code units, so it needs its own guard rather
17
+ * than relying on the byte cap alone. 256Mi code units is comfortably below
18
+ * V8's limit while leaving huge headroom for any real completion (whose
19
+ * accumulated content can never exceed the total streamed body).
20
+ *
21
+ * When an append would cross the ceiling the accumulator keeps the ceiling's
22
+ * worth of characters, drops the overflow, and marks itself truncated — never
23
+ * throwing — mirroring the proxy buffer's "bound then mark truncated, never
24
+ * fail the client" discipline.
25
+ */
26
+ declare const MAX_COLLAPSE_STRING_LENGTH: number;
27
+ /** @internal test-only — see {@link collapseStringLimitOverride}. */
28
+ declare function setCollapseStringLimitForTests(value: number | undefined): void;
6
29
  interface CollapseResult {
7
30
  content?: string;
8
31
  reasoning?: string;
@@ -76,7 +99,7 @@ interface CollapseResult {
76
99
  * data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"Hello"}}]}\n\n
77
100
  * data: [DONE]\n\n
78
101
  */
79
- declare function collapseOpenAISSE(body: string): CollapseResult;
102
+ declare function collapseOpenAISSE(rawBody: string): CollapseResult;
80
103
  /**
81
104
  * Collapse Anthropic Claude Messages SSE stream into a single response.
82
105
  *
@@ -84,14 +107,14 @@ declare function collapseOpenAISSE(body: string): CollapseResult;
84
107
  * event: message_start\ndata: {...}\n\n
85
108
  * event: content_block_delta\ndata: {"delta":{"type":"text_delta","text":"Hello"}}\n\n
86
109
  */
87
- declare function collapseAnthropicSSE(body: string): CollapseResult;
110
+ declare function collapseAnthropicSSE(rawBody: string): CollapseResult;
88
111
  /**
89
112
  * Collapse Gemini SSE stream into a single response.
90
113
  *
91
114
  * Format (data-only, no event prefix, no [DONE]):
92
115
  * data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}\n\n
93
116
  */
94
- declare function collapseGeminiSSE(body: string): CollapseResult;
117
+ declare function collapseGeminiSSE(rawBody: string): CollapseResult;
95
118
  /**
96
119
  * Collapse Ollama NDJSON stream into a single response.
97
120
  *
@@ -106,21 +129,21 @@ declare function collapseGeminiSSE(body: string): CollapseResult;
106
129
  * content is run through the same fail-safe {@link parseHarmonyContent} gate to
107
130
  * capture structured tool calls / reasoning instead of leaking raw tokens.
108
131
  */
109
- declare function collapseOllamaNDJSON(body: string): CollapseResult;
132
+ declare function collapseOllamaNDJSON(rawBody: string): CollapseResult;
110
133
  /**
111
134
  * Collapse Cohere SSE stream into a single response.
112
135
  *
113
136
  * Format:
114
137
  * event: content-delta\ndata: {"type":"content-delta","delta":{"message":{"content":{"text":"Hello"}}}}\n\n
115
138
  */
116
- declare function collapseCohereSSE(body: string): CollapseResult;
139
+ declare function collapseCohereSSE(rawBody: string): CollapseResult;
117
140
  /**
118
141
  * Collapse Bedrock binary Event Stream into a single response.
119
142
  *
120
143
  * Each frame contains a JSON payload with event types like:
121
144
  * contentBlockDelta, contentBlockStart, etc.
122
145
  */
123
- declare function collapseBedrockEventStream(body: Buffer): CollapseResult;
146
+ declare function collapseBedrockEventStream(rawBody: Buffer): CollapseResult;
124
147
  /**
125
148
  * Collapse Gemini Interactions SSE stream into a single response.
126
149
  *
@@ -135,7 +158,7 @@ declare function collapseBedrockEventStream(body: Buffer): CollapseResult;
135
158
  * delta) are still accepted for backward compatibility with previously
136
159
  * recorded fixtures.
137
160
  */
138
- declare function collapseGeminiInteractionsSSE(body: string): CollapseResult;
161
+ declare function collapseGeminiInteractionsSSE(rawBody: string): CollapseResult;
139
162
  /**
140
163
  * Collapse a streaming response body into a non-streaming fixture response.
141
164
  * Returns null if the content type is not a known streaming format.
@@ -144,5 +167,5 @@ declare function collapseGeminiInteractionsSSE(body: string): CollapseResult;
144
167
  declare function collapseStreamingResponse(contentType: string, providerKey: RecordProviderKey, body: string | Buffer, logger?: Logger): CollapseResult | null;
145
168
  //# sourceMappingURL=stream-collapse.d.ts.map
146
169
  //#endregion
147
- export { CollapseResult, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse };
170
+ export { CollapseResult, MAX_COLLAPSE_STRING_LENGTH, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, setCollapseStringLimitForTests };
148
171
  //# sourceMappingURL=stream-collapse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stream-collapse.d.ts","names":[],"sources":["../src/stream-collapse.ts"],"sourcesContent":[],"mappings":";;;;;AAkgBgB,UAhfC,cAAA,CAgfmB;EA8LpB,OAAA,CAAA,EAAA,MAAA;EAoJA,SAAA,CAAA,EAAA,MAAA;EA+HA;AAqRhB;;;;;AAoPA;AAoLA;;;;oBAIW,CAAA,EAAA,MAAA;;;;;;;;cA5mDG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAgCH;;;;;;;;;;;;;;;;;;;iBA+MK,iBAAA,gBAAiC;;;;;;;;iBA2OjC,oBAAA,gBAAoC;;;;;;;iBA8LpC,iBAAA,gBAAiC;;;;;;;;;;;;;;;iBAoJjC,oBAAA,gBAAoC;;;;;;;iBA+HpC,iBAAA,gBAAiC;;;;;;;iBAqRjC,0BAAA,OAAiC,SAAS;;;;;;;;;;;;;;;iBAoP1C,6BAAA,gBAA6C;;;;;;iBAoL7C,yBAAA,mCAED,kCACE,iBACN,SACR"}
1
+ {"version":3,"file":"stream-collapse.d.ts","names":[],"sources":["../src/stream-collapse.ts"],"sourcesContent":[],"mappings":";;;;;;AAsWA;AA+OA;AAkMA;AAyJA;AAmIA;AAyRA;;;;;AA8PA;AAwLA;;;;;;;;cA5tDa;;iBAWG,8BAAA;UAgDC,cAAA;;;;;;;;;;;;;;;;;;;;;;cAsBH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAgCH;;;;;;;;;;;;;;;;;;;iBA+MK,iBAAA,mBAAoC;;;;;;;;iBA+OpC,oBAAA,mBAAuC;;;;;;;iBAkMvC,iBAAA,mBAAoC;;;;;;;;;;;;;;;iBAyJpC,oBAAA,mBAAuC;;;;;;;iBAmIvC,iBAAA,mBAAoC;;;;;;;iBAyRpC,0BAAA,UAAoC,SAAS;;;;;;;;;;;;;;;iBA8P7C,6BAAA,mBAAgD;;;;;;iBAwLhD,yBAAA,mCAED,kCACE,iBACN,SACR"}
@@ -11,6 +11,75 @@ import { crc32 } from "node:zlib";
11
11
  * text followed by tool calls.
12
12
  */
13
13
  /**
14
+ * Hard ceiling (UTF-16 code units) for any SINGLE string a collapser
15
+ * accumulates across deltas (`content`, `reasoning`, a tool call's
16
+ * `arguments`, `audioB64`, `argsStr`, and the coalesced text of `orderAtoms`).
17
+ *
18
+ * V8's maximum string length on 64-bit is 2^29 - 1 (~536.8M UTF-16 code
19
+ * units); appending past it throws `RangeError: Invalid string length`. The
20
+ * proxy path bounds the raw BYTE buffer under `PROXY_BUFFER_HARD_CEILING`
21
+ * (256 MiB) before collapse, but the collapser is ALSO reachable directly
22
+ * (exported from index.ts) and — even on the proxy path — a single accumulator
23
+ * can approach the byte budget in code units, so it needs its own guard rather
24
+ * than relying on the byte cap alone. 256Mi code units is comfortably below
25
+ * V8's limit while leaving huge headroom for any real completion (whose
26
+ * accumulated content can never exceed the total streamed body).
27
+ *
28
+ * When an append would cross the ceiling the accumulator keeps the ceiling's
29
+ * worth of characters, drops the overflow, and marks itself truncated — never
30
+ * throwing — mirroring the proxy buffer's "bound then mark truncated, never
31
+ * fail the client" discipline.
32
+ */
33
+ const MAX_COLLAPSE_STRING_LENGTH = 256 * 1024 * 1024;
34
+ /**
35
+ * Test-only override of {@link MAX_COLLAPSE_STRING_LENGTH}. Lets the cap suite
36
+ * exercise the truncation path with a tiny budget instead of building a
37
+ * multi-hundred-MB string. `undefined` (the default) uses the real ceiling.
38
+ * NEVER set from production code.
39
+ */
40
+ let collapseStringLimitOverride;
41
+ /** @internal test-only — see {@link collapseStringLimitOverride}. */
42
+ function setCollapseStringLimitForTests(value) {
43
+ collapseStringLimitOverride = value;
44
+ }
45
+ /** Effective accumulated-string ceiling, honoring any active test-only override. */
46
+ function effectiveCollapseStringLimit() {
47
+ return collapseStringLimitOverride ?? MAX_COLLAPSE_STRING_LENGTH;
48
+ }
49
+ /**
50
+ * Guard a raw collapse-input body against V8's max string length BEFORE any
51
+ * per-delta accumulation begins. Every collapser accumulates `content` /
52
+ * `reasoning` / a tool call's `arguments` / `audioB64` / `argsStr` (and the
53
+ * coalesced text of `orderAtoms`) from fragments of `body`; the sum of any one
54
+ * of those accumulators can never exceed the total input length, so bounding
55
+ * the INPUT under the ceiling bounds EVERY accumulator at once — no per-`+=`
56
+ * site can then build a string past the limit and throw
57
+ * `RangeError: Invalid string length` (the ~1/sec prod crash).
58
+ *
59
+ * Returns the body UNCHANGED when it is within the ceiling. When it exceeds the
60
+ * ceiling this returns a hard-truncated prefix (never throwing) — the collapse
61
+ * result the caller builds from it is marked incomplete via `truncated: true`
62
+ * (see {@link isCollapseInputTruncated}). This mirrors the proxy buffer's
63
+ * "bound then mark truncated, never fail the client" discipline: on the proxy
64
+ * path a body this large has already tripped the byte cap and skipped recording,
65
+ * so this is a defense-in-depth backstop that also covers the direct (exported)
66
+ * collapse callers where no byte cap ran.
67
+ */
68
+ function guardCollapseBody(body) {
69
+ const limit = effectiveCollapseStringLimit();
70
+ if (body.length <= limit) return body;
71
+ return body.slice(0, limit);
72
+ }
73
+ /**
74
+ * True when a body exceeded the accumulated-string ceiling and had to be
75
+ * truncated by {@link guardCollapseBody}. Collapsers stamp `truncated: true` on
76
+ * their result in this case so the recorder skips journaling a partial fixture,
77
+ * exactly like a transport-truncated stream.
78
+ */
79
+ function isCollapseInputTruncated(body) {
80
+ return body.length > effectiveCollapseStringLimit();
81
+ }
82
+ /**
14
83
  * Normalize a tool call's accumulated `arguments` into valid JSON exactly like
15
84
  * the flat-`toolCalls` recorder path: an empty / whitespace-only / missing
16
85
  * value becomes `"{}"`, never `""`. Mirrors `recorder.ts` `toToolCallArguments`
@@ -165,8 +234,9 @@ function extractSSEData(lines) {
165
234
  * data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"Hello"}}]}\n\n
166
235
  * data: [DONE]\n\n
167
236
  */
168
- function collapseOpenAISSE(body) {
169
- const lines = splitSSEEvents(body);
237
+ function collapseOpenAISSE(rawBody) {
238
+ const inputTruncated = isCollapseInputTruncated(rawBody);
239
+ const lines = splitSSEEvents(guardCollapseBody(rawBody));
170
240
  let content = "";
171
241
  let reasoning = "";
172
242
  const webSearchQueries = [];
@@ -287,7 +357,8 @@ function collapseOpenAISSE(body) {
287
357
  ...droppedChunks > 0 ? { droppedChunks } : {},
288
358
  ...firstDroppedSample ? { firstDroppedSample } : {},
289
359
  ...harmonyUnparsed ? { harmonyUnparsed: true } : {},
290
- ...harmonyNote ? { harmonyNote } : {}
360
+ ...harmonyNote ? { harmonyNote } : {},
361
+ ...inputTruncated ? { truncated: true } : {}
291
362
  };
292
363
  }
293
364
  return {
@@ -297,7 +368,8 @@ function collapseOpenAISSE(body) {
297
368
  ...droppedChunks > 0 ? { droppedChunks } : {},
298
369
  ...firstDroppedSample ? { firstDroppedSample } : {},
299
370
  ...harmonyUnparsed ? { harmonyUnparsed: true } : {},
300
- ...harmonyNote ? { harmonyNote } : {}
371
+ ...harmonyNote ? { harmonyNote } : {},
372
+ ...inputTruncated ? { truncated: true } : {}
301
373
  };
302
374
  }
303
375
  /**
@@ -307,8 +379,9 @@ function collapseOpenAISSE(body) {
307
379
  * event: message_start\ndata: {...}\n\n
308
380
  * event: content_block_delta\ndata: {"delta":{"type":"text_delta","text":"Hello"}}\n\n
309
381
  */
310
- function collapseAnthropicSSE(body) {
311
- const blocks = splitSSEEvents(body);
382
+ function collapseAnthropicSSE(rawBody) {
383
+ const inputTruncated = isCollapseInputTruncated(rawBody);
384
+ const blocks = splitSSEEvents(guardCollapseBody(rawBody));
312
385
  let content = "";
313
386
  let reasoning = "";
314
387
  let reasoningSignature;
@@ -398,7 +471,8 @@ function collapseAnthropicSSE(body) {
398
471
  ...reasoningSignature ? { reasoningSignature } : {},
399
472
  ...redactedThinking.length > 0 ? { redactedThinking } : {},
400
473
  ...droppedChunks > 0 ? { droppedChunks } : {},
401
- ...firstDroppedSample ? { firstDroppedSample } : {}
474
+ ...firstDroppedSample ? { firstDroppedSample } : {},
475
+ ...inputTruncated ? { truncated: true } : {}
402
476
  };
403
477
  }
404
478
  return {
@@ -407,7 +481,8 @@ function collapseAnthropicSSE(body) {
407
481
  ...reasoningSignature ? { reasoningSignature } : {},
408
482
  ...redactedThinking.length > 0 ? { redactedThinking } : {},
409
483
  ...droppedChunks > 0 ? { droppedChunks } : {},
410
- ...firstDroppedSample ? { firstDroppedSample } : {}
484
+ ...firstDroppedSample ? { firstDroppedSample } : {},
485
+ ...inputTruncated ? { truncated: true } : {}
411
486
  };
412
487
  }
413
488
  /**
@@ -416,8 +491,9 @@ function collapseAnthropicSSE(body) {
416
491
  * Format (data-only, no event prefix, no [DONE]):
417
492
  * data: {"candidates":[{"content":{"parts":[{"text":"Hello"}]}}]}\n\n
418
493
  */
419
- function collapseGeminiSSE(body) {
420
- const lines = splitSSEEvents(body);
494
+ function collapseGeminiSSE(rawBody) {
495
+ const inputTruncated = isCollapseInputTruncated(rawBody);
496
+ const lines = splitSSEEvents(guardCollapseBody(rawBody));
421
497
  let content = "";
422
498
  let reasoning = "";
423
499
  let droppedChunks = 0;
@@ -479,7 +555,8 @@ function collapseGeminiSSE(body) {
479
555
  ...reasoning ? { reasoning } : {},
480
556
  ...normalizedToolCalls.length > 0 ? { toolCalls: normalizedToolCalls } : {},
481
557
  ...droppedChunks > 0 ? { droppedChunks } : {},
482
- ...firstDroppedSample ? { firstDroppedSample } : {}
558
+ ...firstDroppedSample ? { firstDroppedSample } : {},
559
+ ...inputTruncated ? { truncated: true } : {}
483
560
  };
484
561
  if (toolCalls.length > 0) {
485
562
  const blocks = buildOrderedBlocks(orderAtoms);
@@ -489,14 +566,16 @@ function collapseGeminiSSE(body) {
489
566
  toolCalls: normalizedToolCalls,
490
567
  ...reasoning ? { reasoning } : {},
491
568
  ...droppedChunks > 0 ? { droppedChunks } : {},
492
- ...firstDroppedSample ? { firstDroppedSample } : {}
569
+ ...firstDroppedSample ? { firstDroppedSample } : {},
570
+ ...inputTruncated ? { truncated: true } : {}
493
571
  };
494
572
  }
495
573
  return {
496
574
  content,
497
575
  ...reasoning ? { reasoning } : {},
498
576
  ...droppedChunks > 0 ? { droppedChunks } : {},
499
- ...firstDroppedSample ? { firstDroppedSample } : {}
577
+ ...firstDroppedSample ? { firstDroppedSample } : {},
578
+ ...inputTruncated ? { truncated: true } : {}
500
579
  };
501
580
  }
502
581
  /**
@@ -513,8 +592,9 @@ function collapseGeminiSSE(body) {
513
592
  * content is run through the same fail-safe {@link parseHarmonyContent} gate to
514
593
  * capture structured tool calls / reasoning instead of leaking raw tokens.
515
594
  */
516
- function collapseOllamaNDJSON(body) {
517
- const lines = body.split("\n").filter((l) => l.trim().length > 0);
595
+ function collapseOllamaNDJSON(rawBody) {
596
+ const inputTruncated = isCollapseInputTruncated(rawBody);
597
+ const lines = guardCollapseBody(rawBody).split("\n").filter((l) => l.trim().length > 0);
518
598
  let content = "";
519
599
  let reasoning = "";
520
600
  let droppedChunks = 0;
@@ -588,7 +668,8 @@ function collapseOllamaNDJSON(body) {
588
668
  ...droppedChunks > 0 ? { droppedChunks } : {},
589
669
  ...firstDroppedSample ? { firstDroppedSample } : {},
590
670
  ...harmonyUnparsed ? { harmonyUnparsed: true } : {},
591
- ...harmonyNote ? { harmonyNote } : {}
671
+ ...harmonyNote ? { harmonyNote } : {},
672
+ ...inputTruncated ? { truncated: true } : {}
592
673
  };
593
674
  }
594
675
  return {
@@ -597,7 +678,8 @@ function collapseOllamaNDJSON(body) {
597
678
  ...droppedChunks > 0 ? { droppedChunks } : {},
598
679
  ...firstDroppedSample ? { firstDroppedSample } : {},
599
680
  ...harmonyUnparsed ? { harmonyUnparsed: true } : {},
600
- ...harmonyNote ? { harmonyNote } : {}
681
+ ...harmonyNote ? { harmonyNote } : {},
682
+ ...inputTruncated ? { truncated: true } : {}
601
683
  };
602
684
  }
603
685
  /**
@@ -606,8 +688,9 @@ function collapseOllamaNDJSON(body) {
606
688
  * Format:
607
689
  * event: content-delta\ndata: {"type":"content-delta","delta":{"message":{"content":{"text":"Hello"}}}}\n\n
608
690
  */
609
- function collapseCohereSSE(body) {
610
- const blocks = splitSSEEvents(body);
691
+ function collapseCohereSSE(rawBody) {
692
+ const inputTruncated = isCollapseInputTruncated(rawBody);
693
+ const blocks = splitSSEEvents(guardCollapseBody(rawBody));
611
694
  let content = "";
612
695
  let reasoning = "";
613
696
  let droppedChunks = 0;
@@ -696,14 +779,16 @@ function collapseCohereSSE(body) {
696
779
  toolCalls: orderedBlocks ? orderedToolCalls : indexSortedToolCalls,
697
780
  ...reasoning ? { reasoning } : {},
698
781
  ...droppedChunks > 0 ? { droppedChunks } : {},
699
- ...firstDroppedSample ? { firstDroppedSample } : {}
782
+ ...firstDroppedSample ? { firstDroppedSample } : {},
783
+ ...inputTruncated ? { truncated: true } : {}
700
784
  };
701
785
  }
702
786
  return {
703
787
  content,
704
788
  ...reasoning ? { reasoning } : {},
705
789
  ...droppedChunks > 0 ? { droppedChunks } : {},
706
- ...firstDroppedSample ? { firstDroppedSample } : {}
790
+ ...firstDroppedSample ? { firstDroppedSample } : {},
791
+ ...inputTruncated ? { truncated: true } : {}
707
792
  };
708
793
  }
709
794
  /**
@@ -797,8 +882,11 @@ function decodeEventStreamFrames(buf) {
797
882
  * Each frame contains a JSON payload with event types like:
798
883
  * contentBlockDelta, contentBlockStart, etc.
799
884
  */
800
- function collapseBedrockEventStream(body) {
801
- const { frames, truncated } = decodeEventStreamFrames(body);
885
+ function collapseBedrockEventStream(rawBody) {
886
+ const limit = effectiveCollapseStringLimit();
887
+ const inputTruncated = rawBody.byteLength > limit;
888
+ const { frames, truncated: frameTruncated } = decodeEventStreamFrames(inputTruncated ? rawBody.subarray(0, limit) : rawBody);
889
+ const truncated = frameTruncated || inputTruncated;
802
890
  let content = "";
803
891
  let reasoning = "";
804
892
  let reasoningSignature;
@@ -953,8 +1041,9 @@ function collapseBedrockEventStream(body) {
953
1041
  * delta) are still accepted for backward compatibility with previously
954
1042
  * recorded fixtures.
955
1043
  */
956
- function collapseGeminiInteractionsSSE(body) {
957
- const lines = splitSSEEvents(body);
1044
+ function collapseGeminiInteractionsSSE(rawBody) {
1045
+ const inputTruncated = isCollapseInputTruncated(rawBody);
1046
+ const lines = splitSSEEvents(guardCollapseBody(rawBody));
958
1047
  let content = "";
959
1048
  let reasoning = "";
960
1049
  let droppedChunks = 0;
@@ -1035,13 +1124,15 @@ function collapseGeminiInteractionsSSE(body) {
1035
1124
  toolCalls,
1036
1125
  ...reasoning ? { reasoning } : {},
1037
1126
  ...droppedChunks > 0 ? { droppedChunks } : {},
1038
- ...firstDroppedSample ? { firstDroppedSample } : {}
1127
+ ...firstDroppedSample ? { firstDroppedSample } : {},
1128
+ ...inputTruncated ? { truncated: true } : {}
1039
1129
  };
1040
1130
  return {
1041
1131
  content,
1042
1132
  ...reasoning ? { reasoning } : {},
1043
1133
  ...droppedChunks > 0 ? { droppedChunks } : {},
1044
- ...firstDroppedSample ? { firstDroppedSample } : {}
1134
+ ...firstDroppedSample ? { firstDroppedSample } : {},
1135
+ ...inputTruncated ? { truncated: true } : {}
1045
1136
  };
1046
1137
  }
1047
1138
  /**
@@ -1073,5 +1164,5 @@ function collapseStreamingResponse(contentType, providerKey, body, logger) {
1073
1164
  }
1074
1165
 
1075
1166
  //#endregion
1076
- export { capturedRedactedData, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse };
1167
+ export { MAX_COLLAPSE_STRING_LENGTH, capturedRedactedData, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, setCollapseStringLimitForTests };
1077
1168
  //# sourceMappingURL=stream-collapse.js.map