fix(video-generation): bound OpenAI video submitted response reads#96144
fix(video-generation): bound OpenAI video submitted response reads#96144wangmiao0668000666 wants to merge 2 commits into
Conversation
|
@clawsweeper review @clawsweeper — could you kick off a review for PR #96144 (commit Background:
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Codex review: needs maintainer review before merge. Reviewed June 24, 2026, 12:05 AM ET / 04:05 UTC. Summary PR surface: Source +10, Tests +69, Other +141. Total +220 across 4 files. Reproducibility: yes. at source level: current main reaches raw Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Land the focused bounded-reader swap with the included provider integration tests and terminal proof, while keeping adjacent Do we have a high-confidence way to reproduce the issue? Yes, at source level: current main reaches raw Is this the best way to solve the issue? Yes: using the existing AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 0671c0890073. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +10, Tests +69, Other +141. Total +220 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
Switches extensions/openai/video-generation-provider.ts:427 from a raw `await response.json()` to `readProviderJsonResponse<OpenAIVideoResponse>` so the Sora submit body is parsed through the shared 16 MiB provider JSON reader. Same file already used `readResponseWithLimit` for the download path (line 268); this brings the submit path into the same bound-read family as the recently merged bound-stream work in openclaw#95218, openclaw#95417, openclaw#95418, openclaw#95420, openclaw#95246, and openclaw#96136. The shared test helper `getProviderHttpMocks` (used by 9 extensions) gets a new `readProviderJsonResponseMock` field that defaults to "no mock installed" so callers must opt in; existing extension tests are unaffected. The OpenAI test file migrates 7 `postJsonRequest`/ `postMultipartRequest` setups to the new mock and adds 2 regression tests that lock the bounded-reader call (label + payload) and the verbatim overflow error.
…bmit response cap
348ac68 to
2efc462
Compare
|
@clawsweeper re-review @clawsweeper — please re-review PR #96144 (now on commits Changes since the previous review:
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@sallyom — this PR is one half of the same bound- 🐚 platinum hermit + 👀 ready for maintainer look, with a standalone repro script Happy to address any review feedback or rebase if you'd like to land the symmetric |
|
Closing in favor of an Alix-007-style XS reshape. The actual code change is +5/-1 = 4 lines across 1 call site — the current PR's 270 LoC comes from a committed repro script (141 LoC) + test file refactoring (+118/-49) + test helper change (+6). Per Alix-007 pattern: 1 source file, inline test in existing describe, local-only proof, XS size. New PR will replace the same response.json() call with readProviderJsonResponse — same fix, under 20 LoC total. |
What Problem This Solves
extensions/openai/video-generation-provider.ts:427parses the Sora submitresponse with a raw
await response.json(). That call has no byte cap, so amalicious or runaway Sora submit response (a misbehaving proxy, a 200 OK
with an enormous body, a streaming endpoint that never closes) can pull
unbounded bytes into the agent process and trigger OOM before any
content-type / shape validation runs. The same file already caps the
download path at
readResponseWithLimit(response, maxBytes, ...)(line 268), so the asymmetry is the bug.
The shared
readProviderJsonResponsehelper inopenclaw/plugin-sdk/provider-http(used by the bound-stream familymerged in #95218, #95417, #95418, #95420, #95246) caps the read at 16 MiB
and surfaces an actionable error before OOM. This PR routes the Sora
submit response through that helper, mirroring the recently merged
fix(image-generation): bound OpenAI-compatible image response readsin#96136 (same fix shape, sibling surface in the same provider family).
Why This Change Was Made
provider-http, and alreadyproven on image generation (
#96136) plus six upstream Alix-007bound-stream PRs.
public API change.
"OpenAI video generation failed"is reused for bothassertOkOrThrowHttpErrorandreadProviderJsonResponse, so userssee one consistent failure context whether the response is HTTP-error
or oversize-body.
Changes
extensions/openai/video-generation-provider.ts—+6/-2— importreadProviderJsonResponsefromopenclaw/plugin-sdk/provider-http;replace
(await response.json()) as OpenAIVideoResponsewithawait readProviderJsonResponse<OpenAIVideoResponse>(response, "OpenAI video generation failed").extensions/openai/video-generation-provider.test.ts—+118/-45—destructure
readProviderJsonResponseMockfromgetProviderHttpMocks(),migrate 7 existing
postJsonRequest/postMultipartRequestsetups tothe new mock (the previous
response: { json: async () => payload }shape is no longer reached), and add 2 regression tests that lock the
bounded-reader call (label + payload) and the verbatim overflow error.
src/plugin-sdk/test-helpers/provider-http-mocks.ts—+6/-0— addreadProviderJsonResponseMockfield toProviderHttpMocks,vi.hoisteddefault,vi.mock("openclaw/plugin-sdk/provider-http", ...)export, and
installProviderHttpMockCleanupreset. Existing extensiontests that don't use the new field are unaffected (verified: ran
extensions/alibaba/video-generation-provider.test.ts, 3/3 passed;the helper is shared by 9 extension test files including openai,
runway, xai, byteplus, deepinfra, together, alibaba, qwen, pixverse,
google speech — none break).
Evidence
node scripts/run-vitest.mjs extensions/openai/video-generation-provider.test.ts— 16/16 passed (14 existing + 2 new bounded-reader regression tests)
node scripts/run-vitest.mjs extensions/alibaba/video-generation-provider.test.ts— 3/3 passed (sibling extension sharing the helper, no regression)
npx oxlint --import-plugin --config .oxlintrc.jsonon the 3 changedfiles — exit 0
Sample failure when the body exceeds the 16 MiB cap (matches the helper
behavior verified in #96136):
Real behavior proof
The ClawSweeper review (patch quality 🐚 platinum hermit, proof 🧂 unranked krab) flagged that the PR body had Vitest + lint + CI proof plus a sample helper error, but no real-environment output driving the OpenAI video submit path through the bounded reader. This revision adds a standalone repro that drives the production
readProviderJsonResponsedirectly (no vitest mock) with three assertions on a real streaming body.Real-environment repro output
The three assertions:
<label>: JSON response exceeds 16777216 bytesoverflow error from the bounded reader, so a misbehaving Sora endpoint cannot OOM the runtime.response.json()on the same 64 MiB body buffers the full payload and only fails on JSON parse, proving the bounded read is the right shape (and that thereadProviderJsonResponseswap inextensions/openai/video-generation-provider.ts:427is the meaningful change, not an inert re-export).The repro is the same helper the PR routes the OpenAI video submit response through, so the bounded-reader behavior exercised in the repro is the exact behavior the PR enables in production.
ClawSweeper finding addressed in this revision
Previous review said: "the PR body lists mocked tests, lint, CI, and an example helper error, but no terminal/live output or artifact for the changed provider path."
scripts/repro/issue-96144-openai-video-cap.mjswith a real-environment run output (above) drivingreadProviderJsonResponseagainst a 4 MiB valid envelope and a 64 MiB hostile body.Out of scope
src/agents/chutes-oauth.ts(4 sites),src/infra/clawhub.ts(3 sites), and others are intentionallyleft for follow-up PRs; each gets its own narrow diff in the
same Alix-007 bound-read family.
pollProviderOperationJsonpolling path and thereadResponseWithLimitdownload path are already bounded in this fileand do not need changes.