@copilotkit/aimock 1.33.0 → 1.35.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.
Files changed (158) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +30 -0
  4. package/README.md +6 -1
  5. package/dist/agui-types.d.ts.map +1 -1
  6. package/dist/bedrock-converse.cjs +112 -10
  7. package/dist/bedrock-converse.cjs.map +1 -1
  8. package/dist/bedrock-converse.d.cts.map +1 -1
  9. package/dist/bedrock-converse.d.ts.map +1 -1
  10. package/dist/bedrock-converse.js +114 -12
  11. package/dist/bedrock-converse.js.map +1 -1
  12. package/dist/bedrock.cjs +143 -6
  13. package/dist/bedrock.cjs.map +1 -1
  14. package/dist/bedrock.d.cts.map +1 -1
  15. package/dist/bedrock.d.ts.map +1 -1
  16. package/dist/bedrock.js +145 -8
  17. package/dist/bedrock.js.map +1 -1
  18. package/dist/cohere.cjs +91 -9
  19. package/dist/cohere.cjs.map +1 -1
  20. package/dist/cohere.d.cts.map +1 -1
  21. package/dist/cohere.d.ts.map +1 -1
  22. package/dist/cohere.js +93 -11
  23. package/dist/cohere.js.map +1 -1
  24. package/dist/config-loader.d.ts.map +1 -1
  25. package/dist/fixture-loader.cjs +121 -20
  26. package/dist/fixture-loader.cjs.map +1 -1
  27. package/dist/fixture-loader.d.cts.map +1 -1
  28. package/dist/fixture-loader.d.ts.map +1 -1
  29. package/dist/fixture-loader.js +121 -20
  30. package/dist/fixture-loader.js.map +1 -1
  31. package/dist/gemini-interactions.cjs +146 -108
  32. package/dist/gemini-interactions.cjs.map +1 -1
  33. package/dist/gemini-interactions.d.cts.map +1 -1
  34. package/dist/gemini-interactions.d.ts.map +1 -1
  35. package/dist/gemini-interactions.js +147 -109
  36. package/dist/gemini-interactions.js.map +1 -1
  37. package/dist/gemini.cjs +72 -7
  38. package/dist/gemini.cjs.map +1 -1
  39. package/dist/gemini.d.cts.map +1 -1
  40. package/dist/gemini.d.ts.map +1 -1
  41. package/dist/gemini.js +74 -9
  42. package/dist/gemini.js.map +1 -1
  43. package/dist/grok-video.cjs +834 -0
  44. package/dist/grok-video.cjs.map +1 -0
  45. package/dist/grok-video.d.cts +74 -0
  46. package/dist/grok-video.d.cts.map +1 -0
  47. package/dist/grok-video.d.ts +74 -0
  48. package/dist/grok-video.d.ts.map +1 -0
  49. package/dist/grok-video.js +829 -0
  50. package/dist/grok-video.js.map +1 -0
  51. package/dist/helpers.cjs +181 -2
  52. package/dist/helpers.cjs.map +1 -1
  53. package/dist/helpers.d.cts +33 -3
  54. package/dist/helpers.d.cts.map +1 -1
  55. package/dist/helpers.d.ts +33 -3
  56. package/dist/helpers.d.ts.map +1 -1
  57. package/dist/helpers.js +181 -3
  58. package/dist/helpers.js.map +1 -1
  59. package/dist/index.cjs +11 -0
  60. package/dist/index.d.cts +5 -3
  61. package/dist/index.d.ts +5 -3
  62. package/dist/index.js +4 -2
  63. package/dist/messages.cjs +100 -11
  64. package/dist/messages.cjs.map +1 -1
  65. package/dist/messages.d.cts.map +1 -1
  66. package/dist/messages.d.ts.map +1 -1
  67. package/dist/messages.js +102 -13
  68. package/dist/messages.js.map +1 -1
  69. package/dist/metrics.cjs +11 -1
  70. package/dist/metrics.cjs.map +1 -1
  71. package/dist/metrics.d.cts.map +1 -1
  72. package/dist/metrics.d.ts.map +1 -1
  73. package/dist/metrics.js +8 -1
  74. package/dist/metrics.js.map +1 -1
  75. package/dist/ollama.cjs +77 -7
  76. package/dist/ollama.cjs.map +1 -1
  77. package/dist/ollama.d.cts.map +1 -1
  78. package/dist/ollama.d.ts.map +1 -1
  79. package/dist/ollama.js +79 -9
  80. package/dist/ollama.js.map +1 -1
  81. package/dist/openrouter-video.cjs +19 -138
  82. package/dist/openrouter-video.cjs.map +1 -1
  83. package/dist/openrouter-video.d.cts.map +1 -1
  84. package/dist/openrouter-video.d.ts.map +1 -1
  85. package/dist/openrouter-video.js +1 -120
  86. package/dist/openrouter-video.js.map +1 -1
  87. package/dist/recorder.cjs +12 -9
  88. package/dist/recorder.cjs.map +1 -1
  89. package/dist/recorder.js +12 -9
  90. package/dist/recorder.js.map +1 -1
  91. package/dist/responses.cjs +137 -59
  92. package/dist/responses.cjs.map +1 -1
  93. package/dist/responses.d.cts +2 -2
  94. package/dist/responses.d.cts.map +1 -1
  95. package/dist/responses.d.ts +2 -2
  96. package/dist/responses.d.ts.map +1 -1
  97. package/dist/responses.js +139 -61
  98. package/dist/responses.js.map +1 -1
  99. package/dist/router.cjs +236 -33
  100. package/dist/router.cjs.map +1 -1
  101. package/dist/router.d.cts +54 -2
  102. package/dist/router.d.cts.map +1 -1
  103. package/dist/router.d.ts +54 -2
  104. package/dist/router.d.ts.map +1 -1
  105. package/dist/router.js +236 -34
  106. package/dist/router.js.map +1 -1
  107. package/dist/server.cjs +163 -21
  108. package/dist/server.cjs.map +1 -1
  109. package/dist/server.d.cts +4 -0
  110. package/dist/server.d.cts.map +1 -1
  111. package/dist/server.d.ts +4 -0
  112. package/dist/server.d.ts.map +1 -1
  113. package/dist/server.js +166 -24
  114. package/dist/server.js.map +1 -1
  115. package/dist/stream-collapse.cjs +355 -79
  116. package/dist/stream-collapse.cjs.map +1 -1
  117. package/dist/stream-collapse.d.cts +27 -4
  118. package/dist/stream-collapse.d.cts.map +1 -1
  119. package/dist/stream-collapse.d.ts +27 -4
  120. package/dist/stream-collapse.d.ts.map +1 -1
  121. package/dist/stream-collapse.js +355 -79
  122. package/dist/stream-collapse.js.map +1 -1
  123. package/dist/types.d.cts +104 -7
  124. package/dist/types.d.cts.map +1 -1
  125. package/dist/types.d.ts +104 -7
  126. package/dist/types.d.ts.map +1 -1
  127. package/dist/vector-types.d.ts.map +1 -1
  128. package/dist/veo-video.cjs +794 -0
  129. package/dist/veo-video.cjs.map +1 -0
  130. package/dist/veo-video.d.cts +50 -0
  131. package/dist/veo-video.d.cts.map +1 -0
  132. package/dist/veo-video.d.ts +50 -0
  133. package/dist/veo-video.d.ts.map +1 -0
  134. package/dist/veo-video.js +789 -0
  135. package/dist/veo-video.js.map +1 -0
  136. package/dist/video-proxy-shared.cjs +145 -0
  137. package/dist/video-proxy-shared.cjs.map +1 -0
  138. package/dist/video-proxy-shared.js +140 -0
  139. package/dist/video-proxy-shared.js.map +1 -0
  140. package/dist/ws-gemini-live.cjs +96 -3
  141. package/dist/ws-gemini-live.cjs.map +1 -1
  142. package/dist/ws-gemini-live.d.cts.map +1 -1
  143. package/dist/ws-gemini-live.d.ts.map +1 -1
  144. package/dist/ws-gemini-live.js +97 -4
  145. package/dist/ws-gemini-live.js.map +1 -1
  146. package/dist/ws-realtime.cjs +281 -4
  147. package/dist/ws-realtime.cjs.map +1 -1
  148. package/dist/ws-realtime.d.cts.map +1 -1
  149. package/dist/ws-realtime.d.ts.map +1 -1
  150. package/dist/ws-realtime.js +282 -5
  151. package/dist/ws-realtime.js.map +1 -1
  152. package/dist/ws-responses.cjs +1 -1
  153. package/dist/ws-responses.cjs.map +1 -1
  154. package/dist/ws-responses.js +1 -1
  155. package/dist/ws-responses.js.map +1 -1
  156. package/fixtures/examples/llm/blocks-tool-first.json +13 -0
  157. package/package.json +1 -1
  158. package/skills/write-fixtures/SKILL.md +19 -1
@@ -1 +1 @@
1
- {"version":3,"file":"openrouter-video.d.cts","names":[],"sources":["../src/openrouter-video.ts"],"sourcesContent":[],"mappings":";;;;;cA2Da,4BAAA;KAGR,qBAAA;AAHL,UAKU,wBAAA,CAL+B;EAGpC,IAAA,EAAA,QAAA;EAEK,KAAA,EAAA,MAAA;EAAwB,MAAA,EAGxB,qBAHwB;;WAWzB,EAAA,MAAA;EAAa;EAyBZ,qBAAA,EAAA,MAAwB;EAAA;sBAYxB,EAAA,MAAA;;EAWM,KAAA,EAhDP,aAgDO,CAAA,OAAA,CAAA;EAwBJ;;;;EAAwE,gBAAA,CAAA,EAAA,OAAA;EAoBvE;;;;;AAoYb;EAAiD,mBAAA,CAAA,EAAA,OAAA;;;;;;;;;;AAiKjD;;UAxmBU,wBAAA,CAymBE;MACL,EAAA,QAAK;;OAGA,EAAA,MAAA;;;;;AAsmBZ;;;;QAGY,EA1sCF,qBA0sCE;;eAEA,EAAA,MAAA;;oBAET,EAAA,MAAA;EAAO;AAmIV;;;;;OAKW,EA30CF,OA20CE,CAAA,OAAA,CAAA;;;;;;AA+lBX;;;;;;;;;;;;;;;;;KAl5DY,kBAAA,GAAqB,2BAA2B;;;;;;;;;;;;;;cAoB/C,qBAAA;;;;;;;;;;;;oBAgBO;wBAUI;;;;;iBA0WF,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;iBAwJmB,4BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,wCAED,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;;;iBAmmBmB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,0BACA,oBACD,mBACC,uCACY,MAAA,CAAK,0BAC1B;iBAmImB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;cA2lBU"}
1
+ {"version":3,"file":"openrouter-video.d.cts","names":[],"sources":["../src/openrouter-video.ts"],"sourcesContent":[],"mappings":";;;;;cAkEa,4BAAA;KAGR,qBAAA;AAHL,UAKU,wBAAA,CAL+B;EAGpC,IAAA,EAAA,QAAA;EAEK,KAAA,EAAA,MAAA;EAAwB,MAAA,EAGxB,qBAHwB;;WAWzB,EAAA,MAAA;EAAa;EAyBZ,qBAAA,EAAA,MAAwB;EAAA;sBAYxB,EAAA,MAAA;;EAWM,KAAA,EAhDP,aAgDO,CAAA,OAAA,CAAA;EAwBJ;;;;EAAwE,gBAAA,CAAA,EAAA,OAAA;EAoBvE;;;;;AAqNb;EAAiD,mBAAA,CAAA,EAAA,OAAA;;;;;;;;;;AAiKjD;;UAzbU,wBAAA,CA0bE;MACL,EAAA,QAAK;;OAGA,EAAA,MAAA;;;;;AAsmBZ;;;;QAGY,EA3hCF,qBA2hCE;;eAEA,EAAA,MAAA;;oBAET,EAAA,MAAA;EAAO;AAmIV;;;;;OAKW,EA5pCF,OA4pCE,CAAA,OAAA,CAAA;;;;;;AA+lBX;;;;;;;;;;;;;;;;;KAnuDY,kBAAA,GAAqB,2BAA2B;;;;;;;;;;;;;;cAoB/C,qBAAA;;;;;;;;;;;;oBAgBO;wBAUI;;;;;iBA2LF,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;iBAwJmB,4BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,wCAED,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;;;iBAmmBmB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,0BACA,oBACD,mBACC,uCACY,MAAA,CAAK,0BAC1B;iBAmImB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;cA2lBU"}
@@ -1 +1 @@
1
- {"version":3,"file":"openrouter-video.d.ts","names":[],"sources":["../src/openrouter-video.ts"],"sourcesContent":[],"mappings":";;;;;cA2Da,4BAAA;KAGR,qBAAA;AAHL,UAKU,wBAAA,CAL+B;EAGpC,IAAA,EAAA,QAAA;EAEK,KAAA,EAAA,MAAA;EAAwB,MAAA,EAGxB,qBAHwB;;WAWzB,EAAA,MAAA;EAAa;EAyBZ,qBAAA,EAAA,MAAwB;EAAA;sBAYxB,EAAA,MAAA;;EAWM,KAAA,EAhDP,aAgDO,CAAA,OAAA,CAAA;EAwBJ;;;;EAAwE,gBAAA,CAAA,EAAA,OAAA;EAoBvE;;;;;AAoYb;EAAiD,mBAAA,CAAA,EAAA,OAAA;;;;;;;;;;AAiKjD;;UAxmBU,wBAAA,CAymBE;MACL,EAAA,QAAK;;OAGA,EAAA,MAAA;;;;;AAsmBZ;;;;QAGY,EA1sCF,qBA0sCE;;eAEA,EAAA,MAAA;;oBAET,EAAA,MAAA;EAAO;AAmIV;;;;;OAKW,EA30CF,OA20CE,CAAA,OAAA,CAAA;;;;;;AA+lBX;;;;;;;;;;;;;;;;;KAl5DY,kBAAA,GAAqB,2BAA2B;;;;;;;;;;;;;;cAoB/C,qBAAA;;;;;;;;;;;;oBAgBO;wBAUI;;;;;iBA0WF,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;iBAwJmB,4BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,wCAED,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;;;iBAmmBmB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,0BACA,oBACD,mBACC,uCACY,MAAA,CAAK,0BAC1B;iBAmImB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;cA2lBU"}
1
+ {"version":3,"file":"openrouter-video.d.ts","names":[],"sources":["../src/openrouter-video.ts"],"sourcesContent":[],"mappings":";;;;;cAkEa,4BAAA;KAGR,qBAAA;AAHL,UAKU,wBAAA,CAL+B;EAGpC,IAAA,EAAA,QAAA;EAEK,KAAA,EAAA,MAAA;EAAwB,MAAA,EAGxB,qBAHwB;;WAWzB,EAAA,MAAA;EAAa;EAyBZ,qBAAA,EAAA,MAAwB;EAAA;sBAYxB,EAAA,MAAA;;EAWM,KAAA,EAhDP,aAgDO,CAAA,OAAA,CAAA;EAwBJ;;;;EAAwE,gBAAA,CAAA,EAAA,OAAA;EAoBvE;;;;;AAqNb;EAAiD,mBAAA,CAAA,EAAA,OAAA;;;;;;;;;;AAiKjD;;UAzbU,wBAAA,CA0bE;MACL,EAAA,QAAK;;OAGA,EAAA,MAAA;;;;;AAsmBZ;;;;QAGY,EA3hCF,qBA2hCE;;eAEA,EAAA,MAAA;;oBAET,EAAA,MAAA;EAAO;AAmIV;;;;;OAKW,EA5pCF,OA4pCE,CAAA,OAAA,CAAA;;;;;;AA+lBX;;;;;;;;;;;;;;;;;KAnuDY,kBAAA,GAAqB,2BAA2B;;;;;;;;;;;;;;cAoB/C,qBAAA;;;;;;;;;;;;oBAgBO;wBAUI;;;;;iBA2LF,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;iBAwJmB,4BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,wCAED,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;;;iBAmmBmB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,0BACA,oBACD,mBACC,uCACY,MAAA,CAAK,0BAC1B;iBAmImB,2BAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK,+BACrB,wBACL;;;;;;;;;;;;;cA2lBU"}
@@ -1,4 +1,3 @@
1
- import { DEFAULT_TEST_ID } from "./constants.js";
2
1
  import { flattenHeaders, getContext, getTestId, isErrorResponse, isVideoResponse, resolveResponse, resolveStrictMode, serializeErrorResponse, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
3
2
  import { matchFixtureDiagnostic } from "./router.js";
4
3
  import { writeErrorResponse } from "./sse-writer.js";
@@ -6,6 +5,7 @@ import { applyChaos } from "./chaos.js";
6
5
  import { resolveUpstreamUrl } from "./url.js";
7
6
  import { buildFixtureMatch, buildForwardHeaders, clampTimeout, persistFixture, sanitizeHeaderValue } from "./recorder.js";
8
7
  import { resolveProgression } from "./fal.js";
8
+ import { DEFAULT_UPSTREAM_TIMEOUT_MS, readBodyIdle, readEnvelopeText, requestBase, testIdSuffix, upstreamTimeoutSignal } from "./video-proxy-shared.js";
9
9
  import crypto from "node:crypto";
10
10
 
11
11
  //#region src/openrouter-video.ts
@@ -98,61 +98,6 @@ function advanceJob(job) {
98
98
  else if (job.pollCount >= job.pollsBeforeCompleted) job.status = terminalStatus(job);
99
99
  }
100
100
  /**
101
- * First non-empty value of a possibly array-typed, possibly comma-joined
102
- * header. An empty header value or a leading-comma list (", host") would
103
- * otherwise yield "" — triggering a spurious rejection warn and discarding
104
- * valid later entries — so empty segments are skipped.
105
- */
106
- function firstForwardedValue(header) {
107
- const raw = Array.isArray(header) ? header.join(",") : header;
108
- if (raw === void 0) return void 0;
109
- for (const segment of raw.split(",")) {
110
- const trimmed = segment.trim();
111
- if (trimmed) return trimmed;
112
- }
113
- }
114
- const FORWARDED_HOST_RE = /^[a-zA-Z0-9._-]+(:\d+)?$/;
115
- const FORWARDED_HOST_IPV6_RE = /^\[[0-9a-fA-F:.]+\](:\d+)?$/;
116
- function requestBase(req, logger) {
117
- const candidate = firstForwardedValue(req.headers["x-forwarded-proto"])?.toLowerCase();
118
- const proto = candidate === "http" || candidate === "https" ? candidate : "http";
119
- const fwdHost = firstForwardedValue(req.headers["x-forwarded-host"]);
120
- const rawHost = req.headers.host;
121
- let host = rawHost !== void 0 && (FORWARDED_HOST_RE.test(rawHost) || FORWARDED_HOST_IPV6_RE.test(rawHost)) ? rawHost : "localhost";
122
- if (fwdHost !== void 0) if (FORWARDED_HOST_RE.test(fwdHost) || FORWARDED_HOST_IPV6_RE.test(fwdHost)) host = fwdHost;
123
- else logger.warn(`x-forwarded-host value rejected, falling back to Host header: ${JSON.stringify(fwdHost.slice(0, 100))}`);
124
- return `${proto}://${host}`;
125
- }
126
- /**
127
- * Query-string suffix embedding the request's testId into generated URLs
128
- * (polling_url, unsigned_urls). The @openrouter/sdk fetches these URLs with
129
- * standard Authorization but no aimock-specific headers (no x-test-id) — so
130
- * the testId must travel in the URL for getTestId's `?testId=` fallback to
131
- * resolve the right job scope. The default testId is omitted to keep
132
- * single-tenant URLs clean.
133
- */
134
- function testIdSuffix(testId, sep) {
135
- return testId === DEFAULT_TEST_ID ? "" : `${sep}testId=${encodeURIComponent(testId)}`;
136
- }
137
- /** Default upstream timeout for the live lifecycle proxy (matches recorder.ts). */
138
- const DEFAULT_UPSTREAM_TIMEOUT_MS = 3e4;
139
- /**
140
- * Abort signal for the SMALL-JSON upstream fetches on this surface (submit,
141
- * status poll, models listing), honoring `record.upstreamTimeoutMs` with the
142
- * same clamp conventions as recorder.ts (non-finite / non-positive values
143
- * fall back to the 30s default). Note the nuance (documented on
144
- * RecordConfig.upstreamTimeoutMs): these envelope-sized fetches use the value
145
- * as a TOTAL deadline via AbortSignal.timeout — indistinguishable from a
146
- * socket-idle timeout for small bodies. The byte-bearing content fetches use
147
- * `fetchHeadersWithTimeout` + `readBodyIdle` instead, which implement true
148
- * idle semantics. An abort rejects the fetch and surfaces through the
149
- * caller's existing failure path (502 proxy_error on submit/poll, models
150
- * synthesis fallback).
151
- */
152
- function upstreamTimeoutSignal(record) {
153
- return AbortSignal.timeout(clampTimeout(record?.upstreamTimeoutMs, DEFAULT_UPSTREAM_TIMEOUT_MS));
154
- }
155
- /**
156
101
  * Fetch a byte-bearing upstream URL with `record.upstreamTimeoutMs` gating
157
102
  * only the HEADERS: the abort timer is cleared the moment the response head
158
103
  * arrives, so a long — but steadily progressing — body download is never
@@ -173,50 +118,6 @@ async function fetchHeadersWithTimeout(url, headers, record) {
173
118
  }
174
119
  }
175
120
  /**
176
- * Buffer a fetch Response body with IDLE-based timeout semantics: a timer
177
- * clamped from `record.bodyTimeoutMs` (30s default — same clamp as
178
- * recorder.ts) is re-armed for every chunk, so a steadily-dripping body of
179
- * any total duration completes and only a silent mid-body stall rejects.
180
- * When `cap` > 0 the byte count is enforced DURING the read: on exceed the
181
- * stream is cancelled and `{ overCap: true }` is returned with NOTHING
182
- * oversized retained in memory — the cap is a memory guard as much as a
183
- * disk guard.
184
- */
185
- async function readBodyIdle(res, record, cap = 0) {
186
- const body = res.body;
187
- if (!body) return {
188
- overCap: false,
189
- buf: Buffer.alloc(0)
190
- };
191
- const idleMs = clampTimeout(record?.bodyTimeoutMs, DEFAULT_UPSTREAM_TIMEOUT_MS);
192
- const reader = body.getReader();
193
- const chunks = [];
194
- let total = 0;
195
- try {
196
- for (;;) {
197
- let idleTimer;
198
- const readPromise = reader.read();
199
- readPromise.catch(() => {});
200
- const result = await Promise.race([readPromise, new Promise((_, reject) => {
201
- idleTimer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Upstream response body idle for ${idleMs}ms`)), idleMs);
202
- })]).finally(() => clearTimeout(idleTimer));
203
- if (result.done) break;
204
- total += result.value.byteLength;
205
- if (cap > 0 && total > cap) return {
206
- overCap: true,
207
- bytesRead: total
208
- };
209
- chunks.push(Buffer.from(result.value));
210
- }
211
- } finally {
212
- reader.cancel().catch(() => {});
213
- }
214
- return {
215
- overCap: false,
216
- buf: Buffer.concat(chunks)
217
- };
218
- }
219
- /**
220
121
  * Cap on an upstream ERROR body (401/403 relays) buffered by the content
221
122
  * proxy. Error bodies are envelope-sized JSON in practice — 64 KB is generous
222
123
  * — and unlike the video bytes they are buffered in full before the relay, so
@@ -224,26 +125,6 @@ async function readBodyIdle(res, record, cap = 0) {
224
125
  */
225
126
  const OPENROUTER_VIDEO_ERROR_BODY_CAP = 64 * 1024;
226
127
  /**
227
- * Cap on the small-JSON upstream envelope bodies (submit, status poll, models
228
- * listing) buffered before parse/relay. Envelopes are KB-scale in practice —
229
- * 1 MB is generous headroom even for a large models listing — and, like the
230
- * error-body cap above, they are buffered in full, so an unbounded `text()`
231
- * would be a memory hole on a hostile upstream.
232
- */
233
- const OPENROUTER_VIDEO_ENVELOPE_BODY_CAP = 1024 * 1024;
234
- /**
235
- * Bounded read of a small-JSON upstream envelope body (submit, status poll,
236
- * models listing): readBodyIdle's idle semantics plus the envelope cap. An
237
- * over-cap body is a hard failure — the throw surfaces through each caller's
238
- * existing failure path (502 proxy_error on submit/poll, models synthesis
239
- * fallback) without retaining anything oversized in memory.
240
- */
241
- async function readEnvelopeText(res, record) {
242
- const read = await readBodyIdle(res, record, OPENROUTER_VIDEO_ENVELOPE_BODY_CAP);
243
- if (read.overCap) throw new Error(`Upstream envelope body exceeded ${OPENROUTER_VIDEO_ENVELOPE_BODY_CAP} bytes (read aborted at ${read.bytesRead})`);
244
- return read.buf.toString("utf8");
245
- }
246
- /**
247
128
  * Rewrite an upstream poll body for relay to the client. Every field is
248
129
  * relayed verbatim EXCEPT the ones that would let the client escape the mock
249
130
  * or learn upstream identifiers: