fix(google-media): bound JSON response reads#96920
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 27, 2026, 9:45 AM ET / 13:45 UTC. Summary PR surface: Source +1, Tests +67. Total +68 across 2 files. Reproducibility: yes. Current main has a direct Review metrics: 1 noteworthy metric.
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. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Use the shared 16 MiB provider JSON cap for this helper unless maintainers explicitly document a Google media-specific larger cap before merge. Do we have a high-confidence way to reproduce the issue? Yes. Current main has a direct Is this the best way to solve the issue? Yes. Replacing the single shared audio/video success reader with the existing SDK bounded JSON helper is the narrowest maintainable fix, and adjacent Google/GoogleChat bounded-reader work does not cover this helper. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c5d34c8376f8. Label changesLabel justifications:
Evidence reviewedPR surface: Source +1, Tests +67. Total +68 across 2 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
|
58f2c78 to
d7d942c
Compare
|
Maintainer review and merge prep done. What changed in prep:
Evidence:
Known proof gap: no credential-backed live Google Generative AI call was run; the changed contract is the response-body reader boundary and is exercised through the provider entry point with a loopback streamed |
|
Merged via squash.
|
* fix(google-media): bound JSON response reads * test(google): relax media response cap assertion --------- Co-authored-by: Vincent Koc <[email protected]>
* fix(google-media): bound JSON response reads * test(google): relax media response cap assertion --------- Co-authored-by: Vincent Koc <[email protected]>
* fix(google-media): bound JSON response reads * test(google): relax media response cap assertion --------- Co-authored-by: Vincent Koc <[email protected]>
* fix(google-media): bound JSON response reads * test(google): relax media response cap assertion --------- Co-authored-by: Vincent Koc <[email protected]>
Summary
readProviderJsonResponseinstead of directres.json().What Problem This Solves
Google media understanding shared video/audio response parsing used a local helper that called
res.json()directly after the provider HTTP status check. A successful Google Generative AI response with an oversized body could be materialized through the native JSON reader before parsing, unlike provider paths already using the shared bounded JSON reader.User Impact
generateGeminiInlineDataText, while the canonicalreadProviderJsonResponsecontract remains the source-of-truth for provider JSON byte limits and malformed JSON wrapping.Origin / follow-up
Follows #96605.
extensions/google/media-understanding-provider.tsstill parsed Google media understanding video/audio success responses through directres.json().Competition / linked PR analysis
Before submission I rechecked open PR overlap for Google/Gemini/media-understanding/bounded-reader work, including high-frequency bounded-reader submissions.
extensions/googlechat/src/api.tsandextensions/googlechat/src/auth.ts, not Google media understanding.extensions/google/media-understanding-provider.ts.extensions/google/media-understanding-provider.ts.No open PR found in this pass covers
extensions/google/media-understanding-provider.tsor the Google media understanding video/audio success JSON reader.Real behavior proof
/media/vdb/code/ai/aispace/openclaw-worktrees/followup-96605, usingdescribeGeminiVideo()with a local loopback HTTP server returning a real streamedResponsebody.pnpm check:test-types,node scripts/run-vitest.mjs extensions/google/media-understanding-provider.video.test.ts, and a standalone loopback proof invokingdescribeGeminiVideo()against an oversized local HTTP response./media/vdb/code/ai/aispace/openclaw-followup-96605-evidence/google-media-test-types.txt,/media/vdb/code/ai/aispace/openclaw-followup-96605-evidence/google-media-vitest.txt, and/media/vdb/code/ai/aispace/openclaw-followup-96605-evidence/google-media-loopback-proof.txtpnpm check:test-typescompleted successfully. The Google media video Vitest shard reportedTest Files 1 passed (1)andTests 6 passed (6). The loopback proof observedVideo description failed: JSON response exceeds 16777216 bytes,closed_bytes=16908288,exceeded_cap=true, andclosed_before_full_response=true.Review findings addressed
N/A — new follow-up PR.
Regression Test Plan
extensions/google/media-understanding-provider.video.test.tsdescribeGeminiVideo()through a local loopback HTTP server that streams an 18 MiB JSON response and asserts the provider reportsVideo description failed: JSON response exceeds 16777216 bytes.describeGeminiVideo()provider entry point and a real HTTP streamedResponse, so it fails if Google media understanding regresses to directres.json()or stops closing oversized response streams early.pnpm check:test-typesnode scripts/run-vitest.mjs extensions/google/media-understanding-provider.video.test.tsRisk / Compatibility
Low. Successful Google media understanding JSON responses still parse into the same candidate text shape and still flow through the same missing-text validation. Responses larger than 16 MiB now fail with a bounded-reader error, matching existing provider JSON response limits.
Merge risk
merge-risk: compatibility, provider/auth surface, media-understanding provider surface.What was not changed
Root Cause
res.json()for HTTP success responses instead of the shared bounded provider JSON reader contract.