fix: playground studios + admin responsive - #1945
Conversation
- Image studio: return JSON instead of UIMessageStream for generateImage responses, fixing "Failed to process successful response" error - Video studio: always use proxy URL for video content and support Range requests for proper browser playback - Admin: email dialog textarea max-height + scrollable - Admin: responsive search inputs, pagination, tabs, and action buttons across all pages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
WalkthroughThe PR converts image generation from streaming SSE responses to single JSON payloads, adds HTTP Range header support for video partial-content streaming with proper status/header proxying, and applies responsive layout improvements across admin dashboard components. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
apps/playground/src/components/playground/image-page-client.tsx (1)
306-315: Route this new JSON path through the typed API client.This response is still consumed via raw
fetch()+ uncheckedresponse.json(), so the/api/chatcontract remains runtime-only even after the SSE→JSON switch. Please move this call touseFetchClient()/useApi()so request and response typing catch the next shape drift earlier.As per coding guidelines,
apps/{ui,playground,code,admin}/src/**/*.{ts,tsx}: In frontend apps, always use the generated typed API client (useFetchClient()oruseApi()) to call the API; never use rawfetch()for API calls.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/playground/src/components/playground/image-page-client.tsx` around lines 306 - 315, The code currently reads the API body with response.json() and inspects generatedImages directly, leaving the /api/chat contract untyped; replace this raw fetch usage with the generated typed API client by calling useFetchClient() or useApi() (whichever the app uses) to invoke the same endpoint and consume the typed response shape, then update the logic that checks the returned images (the generatedImages variable and its existence/length check) to use the typed response properties instead of response.json(); ensure the request arguments and error handling mirror the previous behavior but rely on the typed client so TypeScript will catch any future shape drift for the /api/chat response.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/playground/src/app/api/video/`[videoId]/content/route.ts:
- Around line 67-71: The response headers currently set "Accept-Ranges" to
"bytes" in the headers object, which incorrectly advertises byte-range support;
update the headers in the route handler by removing the "Accept-Ranges" entry
(or if you prefer to keep it as a placeholder add a TODO comment) so that the
headers Record<string,string> (variable name: headers) no longer claims range
support until the upstream gateway actually handles Range requests; locate the
headers constant in route.ts and either delete the "Accept-Ranges" key or
replace it with a commented TODO noting future gateway Range support.
In `@ee/admin/src/app/models/page.tsx`:
- Around line 127-130: The form with action={handleSearch} uses className="flex
w-full items-center gap-2 sm:w-auto" but its parent wrapper is not width-aware
so w-full doesn't expand on mobile; to fix, make the parent wrapper a
width-aware block (e.g., add className="w-full" or "flex-1 w-full") or change
the form to be a block-level flexible child (e.g., replace "flex w-full" with
"flex-1 w-full" or ensure the immediate wrapper element has "w-full") so the
form truly takes full width on small screens while keeping sm:w-auto for larger
breakpoints.
---
Nitpick comments:
In `@apps/playground/src/components/playground/image-page-client.tsx`:
- Around line 306-315: The code currently reads the API body with
response.json() and inspects generatedImages directly, leaving the /api/chat
contract untyped; replace this raw fetch usage with the generated typed API
client by calling useFetchClient() or useApi() (whichever the app uses) to
invoke the same endpoint and consume the typed response shape, then update the
logic that checks the returned images (the generatedImages variable and its
existence/length check) to use the typed response properties instead of
response.json(); ensure the request arguments and error handling mirror the
previous behavior but rely on the typed client so TypeScript will catch any
future shape drift for the /api/chat response.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 2548da62-12c0-47d2-86a7-2dfbb7fda7c2
📒 Files selected for processing (11)
apps/playground/src/app/api/chat/route.tsapps/playground/src/app/api/video/[videoId]/content/route.tsapps/playground/src/components/playground/image-page-client.tsxapps/playground/src/components/playground/video-page-client.tsxee/admin/src/app/contact-submissions/[id]/reply-form.tsxee/admin/src/app/contact-submissions/page.tsxee/admin/src/app/model-provider-mappings/page.tsxee/admin/src/app/models/page.tsxee/admin/src/app/organizations/[orgId]/page.tsxee/admin/src/app/organizations/[orgId]/send-email-dialog.tsxee/admin/src/app/organizations/page.tsx
| const headers: Record<string, string> = { | ||
| "Content-Type": response.headers.get("Content-Type") ?? "video/mp4", | ||
| "Cache-Control": "private, max-age=3600", | ||
| "Accept-Ranges": "bytes", | ||
| }; |
There was a problem hiding this comment.
Accept-Ranges: bytes header may be misleading.
Setting Accept-Ranges: bytes advertises to browsers that this endpoint supports byte-range requests. However, since the upstream gateway doesn't support Range requests (always returns full content with 200), browsers may waste resources retrying partial requests that never succeed.
Consider either:
- Removing
Accept-Rangesuntil the gateway supports it - Adding a TODO comment noting this is preparation for future gateway Range support
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/playground/src/app/api/video/`[videoId]/content/route.ts around lines 67
- 71, The response headers currently set "Accept-Ranges" to "bytes" in the
headers object, which incorrectly advertises byte-range support; update the
headers in the route handler by removing the "Accept-Ranges" entry (or if you
prefer to keep it as a placeholder add a TODO comment) so that the headers
Record<string,string> (variable name: headers) no longer claims range support
until the upstream gateway actually handles Range requests; locate the headers
constant in route.ts and either delete the "Accept-Ranges" key or replace it
with a commented TODO noting future gateway Range support.
| <form | ||
| action={handleSearch} | ||
| className="flex w-full items-center gap-2 sm:w-auto" | ||
| > |
There was a problem hiding this comment.
Form full-width behavior is constrained by the parent container.
At Line 126, the parent wrapper is not width-aware, so w-full on the form may not actually expand on mobile. This can blunt the responsive fix.
💡 Suggested fix
- <div className="flex items-center gap-3">
+ <div className="flex w-full items-center gap-3 sm:w-auto">
<form
action={handleSearch}
className="flex w-full items-center gap-2 sm:w-auto"
>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ee/admin/src/app/models/page.tsx` around lines 127 - 130, The form with
action={handleSearch} uses className="flex w-full items-center gap-2 sm:w-auto"
but its parent wrapper is not width-aware so w-full doesn't expand on mobile; to
fix, make the parent wrapper a width-aware block (e.g., add className="w-full"
or "flex-1 w-full") or change the form to be a block-level flexible child (e.g.,
replace "flex w-full" with "flex-1 w-full" or ensure the immediate wrapper
element has "w-full") so the form truly takes full width on small screens while
keeping sm:w-auto for larger breakpoints.
Summary
createUIMessageStreamResponsewith plain JSON response forgenerateImageresults, fixing "Failed to process successful response" errorRangeheader, returning206/Content-Range/Accept-Ranges) for proper browser playbackmax-h-[300px] overflow-y-autoto email body textarea andmax-h-[90dvh] overflow-y-autoto dialog contentmax-h-[400px] overflow-y-autoto reply body textareaw-full sm:w-64), stacking pagination controls, wrapping action buttons, and scrollable tabs across all pagesTest plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Improvements