Skip to content

Commit 13d4c21

Browse files
committed
fix(openrouter): bound video catalog JSON reads
1 parent 3217165 commit 13d4c21

2 files changed

Lines changed: 62 additions & 3 deletions

File tree

extensions/openrouter/video-generation-provider.test.ts

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,31 @@ vi.mock("openclaw/plugin-sdk/provider-http", async () => {
5454

5555
function releasedJson(value: unknown) {
5656
return {
57-
response: {
58-
json: async () => value,
57+
response: new Response(JSON.stringify(value), {
58+
status: 200,
59+
headers: { "content-type": "application/json" },
60+
}),
61+
release: vi.fn(async () => {}),
62+
};
63+
}
64+
65+
function releasedOversizedJsonStream() {
66+
let canceled = false;
67+
const stream = new ReadableStream<Uint8Array>({
68+
start(controller) {
69+
controller.enqueue(new Uint8Array(16 * 1024 * 1024 + 1));
5970
},
71+
cancel() {
72+
canceled = true;
73+
},
74+
});
75+
return {
76+
response: new Response(stream, {
77+
status: 200,
78+
headers: { "content-type": "application/json" },
79+
}),
6080
release: vi.fn(async () => {}),
81+
wasCanceled: () => canceled,
6182
};
6283
}
6384

@@ -292,6 +313,40 @@ describe("openrouter video generation provider", () => {
292313
});
293314
});
294315

316+
it("cancels oversized OpenRouter video catalog success bodies", async () => {
317+
const oversized = releasedOversizedJsonStream();
318+
fetchWithTimeoutGuardedMock.mockResolvedValueOnce(oversized);
319+
320+
await expect(
321+
listOpenRouterVideoModelCatalog({
322+
config: {
323+
models: {
324+
providers: {
325+
openrouter: {
326+
baseUrl: "https://custom.openrouter.test/openrouter/api/v1",
327+
},
328+
},
329+
},
330+
} as never,
331+
env: {},
332+
resolveProviderApiKey: () => ({
333+
apiKey: "OPENROUTER_API_KEY",
334+
discoveryApiKey: "resolved-openrouter-key",
335+
}),
336+
resolveProviderAuth: () => ({
337+
apiKey: "OPENROUTER_API_KEY",
338+
discoveryApiKey: "resolved-openrouter-key",
339+
mode: "api_key",
340+
source: "env",
341+
}),
342+
}),
343+
).rejects.toThrow(
344+
"OpenRouter video models request failed: JSON response exceeds 16777216 bytes",
345+
);
346+
expect(oversized.wasCanceled()).toBe(true);
347+
expect(oversized.release).toHaveBeenCalledOnce();
348+
});
349+
295350
it("skips live OpenRouter video catalog discovery without an API key", async () => {
296351
await expect(
297352
listOpenRouterVideoModelCatalog({

extensions/openrouter/video-model-catalog.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runt
77
import { getCachedLiveCatalogValue } from "openclaw/plugin-sdk/provider-catalog-shared";
88
import {
99
assertOkOrThrowHttpError,
10+
readProviderJsonResponse,
1011
resolveProviderHttpRequestConfig,
1112
} from "openclaw/plugin-sdk/provider-http";
1213
import {
@@ -234,7 +235,10 @@ async function fetchOpenRouterVideoModels(params: {
234235
});
235236
try {
236237
await assertOkOrThrowHttpError(response, "OpenRouter video models request failed");
237-
return (await response.json()) as OpenRouterVideoModelsResponse;
238+
return await readProviderJsonResponse<OpenRouterVideoModelsResponse>(
239+
response,
240+
"OpenRouter video models request failed",
241+
);
238242
} finally {
239243
await release();
240244
}

0 commit comments

Comments
 (0)