feat: 视频下载和界面预览统一使用OAI标准接口 - #2324
Conversation
WalkthroughThe pull request refactors video proxy channel-type handling to explicitly manage OpenAI and Sora video URLs with Authorization headers, relocates the video content route registration, and updates the frontend task logs UI to construct video endpoint URLs instead of using raw text values for modal display. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. 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: 0
🧹 Nitpick comments (2)
web/src/components/table/task-logs/TaskLogsColumnDefs.jsx (1)
356-377: Decouple preview availability fromfail_reasonbeing a URLNow that playback always uses
/v1/videos/${record.task_id}/content, theisUrlcheck onfail_reasonis only a heuristic gate. If you later stop storing upstream video URLs infail_reason, the preview link will vanish even though the proxy endpoint is usable.Consider basing the condition purely on task metadata (video type + SUCCESS + non‑empty
task_id), e.g.:- const isUrl = typeof text === 'string' && /^https?:\/\//.test(text); - if (isSuccess && isVideoTask && isUrl) { + if (isSuccess && isVideoTask && record.task_id) { const videoUrl = `/v1/videos/${record.task_id}/content`;This keeps the UI behavior aligned with the new unified OAI‑style endpoint instead of the internal
fail_reasonformat.controller/video_proxy.go (1)
120-125: HardenvideoURLhandling for OpenAI/Sora and the defaultFailReasonpathThe new OpenAI/Sora branch and the default
FailReasonbranch work functionally, but you can make them more robust:
- Default case:
videoURL = task.FailReasonis used directly. If it’s empty or has a non‑HTTP(S) scheme, the proxy will later fail in less obvious ways and also increases SSRF exposure.
- Consider trimming, validating non‑emptiness, and enforcing
http/httpsbefore proceeding. If validation fails, return a clear 4xx/5xx instead of attempting the upstream call.- OpenAI/Sora case: if
channel.Keyis missing, you currently sendAuthorization: Bearerand rely on upstream 401. Mirroring the Gemini branch, you might want to detect an empty key and return a clear server error immediately.A possible direction for the default branch:
- default: - // Video URL is directly in task.FailReason - videoURL = task.FailReason + default: + // Video URL is directly in task.FailReason + rawURL := strings.TrimSpace(task.FailReason) + if rawURL == "" { + logger.LogError(c.Request.Context(), fmt.Sprintf("Empty video URL for task %s", taskID)) + c.JSON(http.StatusInternalServerError, gin.H{"error": gin.H{ + "message": "Video URL not available for task", + "type": "server_error", + }}) + return + } + parsed, err := url.Parse(rawURL) + if err != nil || (parsed.Scheme != "http" && parsed.Scheme != "https") { + logger.LogError(c.Request.Context(), fmt.Sprintf("Invalid video URL %s for task %s", rawURL, taskID)) + c.JSON(http.StatusInternalServerError, gin.H{"error": gin.H{ + "message": "Invalid video URL for task", + "type": "server_error", + }}) + return + } + videoURL = parsed.String()(With an added
stringsimport.) This aligns well with the existing effort to keepFailReasonsanitized and avoids surprising failures at the HTTP layer. Based on learnings, this keeps binary/unsafe payloads out of the proxy path too.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
controller/video_proxy.go(1 hunks)router/video-router.go(1 hunks)web/src/components/table/task-logs/TaskLogsColumnDefs.jsx(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-26T09:59:00.337Z
Learnt from: Sh1n3zZ
Repo: QuantumNous/new-api PR: 1659
File: relay/relay_task.go:285-305
Timestamp: 2025-08-26T09:59:00.337Z
Learning: In controller/task_video.go, data: URLs (containing base64 encoded video data) are prevented from being stored in task.FailReason by checking if the URL starts with "data:" before assignment. This same pattern should be applied consistently across the codebase.
Applied to files:
controller/video_proxy.go
📚 Learning: 2025-08-26T09:59:00.337Z
Learnt from: Sh1n3zZ
Repo: QuantumNous/new-api PR: 1659
File: relay/relay_task.go:285-305
Timestamp: 2025-08-26T09:59:00.337Z
Learning: In controller/task_video.go, the redactVideoResponseBody function sanitizes video task responses by removing bytesBase64Encoded fields and truncating base64 strings to 256 characters to prevent large binary data from being stored in task.Data.
Applied to files:
controller/video_proxy.go
🧬 Code graph analysis (3)
controller/video_proxy.go (1)
constant/channel.go (2)
ChannelTypeOpenAI(5-5)ChannelTypeSora(55-55)
web/src/components/table/task-logs/TaskLogsColumnDefs.jsx (1)
web/src/hooks/task-logs/useTaskLogsData.js (2)
videoUrl(72-72)openVideoModal(265-268)
router/video-router.go (1)
controller/video_proxy.go (1)
VideoProxy(17-176)
🔇 Additional comments (1)
router/video-router.go (1)
14-17: Confirm that making/v1/videos/:task_id/contentgo throughTokenAuthmatches all callersBy moving this route into the block guarded by
TokenAuth()andDistribute(), the content endpoint now requires the same authentication as other/v1video routes. Please double‑check that:
- The web video modal can still access this URL with whatever auth
TokenAuthexpects (headers vs cookies,<video>tag vs XHR), and- Any documented
curlexamples for this path include the required auth parameters.
…d-oai feat: 视频下载和界面预览统一使用OAI标准接口
请求示例


curl http://localhost:3000/v1/videos/vira-891809323276095488/contentSummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.