Skip to content

feat: add kling video o1 support - #2491

Closed
feitianbubu wants to merge 4848 commits into
QuantumNous:mainfrom
feitianbubu:pr/154ad020fa082d6be76c582670a087bb92d5cfeb
Closed

feat: add kling video o1 support#2491
feitianbubu wants to merge 4848 commits into
QuantumNous:mainfrom
feitianbubu:pr/154ad020fa082d6be76c582670a087bb92d5cfeb

Conversation

@feitianbubu

@feitianbubu feitianbubu commented Dec 22, 2025

Copy link
Copy Markdown
Member

新增可灵 kling-v2-6和kling-video-o1视频模型支持
请求示例:

curl http://localhost:30001/v1/videos \
  --request POST \
  --header 'Content-Type: multipart/form-data' \
  --form 'prompt=转个圈' \
  --form 'input_reference=@logo2.png' \
  --form 'model=kling-video-o1' \
  --form 'metadata={"image_list":[
  {
    "image_url":"https://ark-project.tos-cn-beijing.volces.com/doc_image/seedream4_imagesToimages_1.png",
    "type":"first_frame"
  },
  {
    "image_url":"https://ark-project.tos-cn-beijing.volces.com/doc_image/seedream4_imagesToimages_1.png",
    "type":"end_frame"
  }
]}' \
  --form 'image=https://h2.inkwai.com/bs2/upload-ylab-stunt/se/ai_portal_queue_mmu_image_upscale_aiweb/3214b798-e1b4-4b00-b7af-72b5b0417420_raw_image_0.jpg'
image image

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Omni-Video model variant with enhanced capability to process image, element, and video lists in video generation requests.
  • Improvements

    • Improved request body handling for video task processing.

✏️ Tip: You can customize this high-level summary in your review settings.

feitianbubu and others added 30 commits November 4, 2025 20:21
feat:  EditTokenModal 中针对用户创建的 token 默认无限额度
feat: add environment variable switch for critical rate limit
…80p-image

fix: trim suffix p for jimeng image model
…odisable

fix(channel): 当没有可用密钥时返回错误而不是第一个密钥
… new sections for partners, acknowledgments, and deployment instructions
- 更新中文README.md中的语言链接
- 完全重写英文README.en.md,包含所有详细功能说明
- 完全重写法文README.fr.md,确保内容一致性
- 完全重写日文README.ja.md,提供完整的项目说明

所有语言版本现在具有:
- 相同的结构和格式
- 一致的语言导航
- 完整的功能特性和部署指南
- 统一的环境变量配置说明
…ence

修复viduq2不支持参考生视频的问题
…annel

feat: replicate channel flux model
Calcium-Ion and others added 26 commits December 13, 2025 17:55
…-tts

feat: support gpt tts series model quota calculate
…itelist-cidr

feat(auth): enhance IP restriction handling with CIDR support
… meta when token count is disabled

Clamp request body size (including post-decompression) to avoid memory exhaustion caused by huge payloads/zip bombs, especially with large-context Claude requests. Add a configurable `MAX_REQUEST_BODY_MB` (default `32`) and document it.

- Enforce max request body size after gzip/br decompression via `http.MaxBytesReader`
- Add a secondary size guard in `common.GetRequestBody` and cache-safe handling
- Return **413 Request Entity Too Large** on oversized bodies in relay entry
- Avoid building large `TokenCountMeta.CombineText` when both token counting and sensitive check are disabled (use lightweight meta for pricing)
- Update READMEs (CN/EN/FR/JA) with `MAX_REQUEST_BODY_MB`
- Fix a handful of vet/formatting issues encountered during the change
- `go test ./...` passes
Tighten oversized request handling across relay paths and make error matching reliable.

- Align `MAX_REQUEST_BODY_MB` fallback to `32` in request body reader and decompression middleware
- Stop ignoring `GetRequestBody` errors in relay retry paths; return consistent **413** on oversized bodies (400 for other read errors)
- Add `Unwrap()` to `types.NewAPIError` so `errors.Is/As` can match wrapped underlying errors
- `go test ./...` passes
…-response-id

fix: 模型设置增加针对Vertex渠道过滤content[].part[].functionResponse.id的选项,默认启用
- Replace legacy `docs.newapi.pro` paths with the new `/{lang}/docs/...` structure across all README translations
- Point key sections (installation, env vars, API, support, features) to their new locations
- Ensure language-specific links use the correct locale prefix (zh/en/ja) and keep FR aligned with English routes
Keep new-site links (/{lang}/docs/...) where matching pages exist in the current docs repo
Revert links that have no equivalent in the new docs to the legacy paths on doc.newapi.pro:
Google Gemini Chat
Midjourney-Proxy image docs
Suno music docs
Apply the same rule consistently across all README translations (zh/en/ja/fr)
…te-doc-links-new-routing

🔗 docs(readme): update documentation links to new site routing
@coderabbitai

coderabbitai Bot commented Dec 22, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Two files modified to extend Kling adaptor functionality: added three new data structures (ImageItem, ElementItem, VideoItem) and extended requestPayload with corresponding lists; modified BuildRequestURL to select Omni-Video path for "o1" model names; changed BuildRequestBody to obtain requests via relaycommon.GetTaskRequest; altered relay_utils unmarshalling to unconditionally invoke UnmarshalBodyReusable after multipart handling.

Changes

Cohort / File(s) Summary
Kling Adaptor Omni-Video Support
relay/channel/task/kling/adaptor.go
Added three new data structures: ImageItem (image URL and type), ElementItem (element ID), and VideoItem (video URL, refer type, sound settings); extended requestPayload with ImageList, ElementList, and VideoList fields to support Omni-Video requests.
Kling Adaptor Request Handling
relay/channel/task/kling/adaptor.go
Modified BuildRequestURL to check if OriginModelName contains "o1" for Omni-Video path selection; updated BuildRequestBody to retrieve request payload via relaycommon.GetTaskRequest instead of reading directly from context.
Relay Utils Unmarshalling Flow
relay/common/relay_utils.go
Changed conditional unmarshalling logic to unconditionally invoke UnmarshalBodyReusable after multipart request handling, potentially overwriting data populated by validateMultipartTaskRequest; multipart errors still return early, while subsequent unmarshalling errors return as "invalid_request".

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Attention areas:
    • The unconditional UnmarshalBodyReusable call in relay_utils.go for multipart requests may overwrite previously populated data; verify intent and side effects.
    • Model name routing logic in BuildRequestURL for "o1" handling; ensure backward compatibility with existing image2video and text2video paths.
    • Request source change from context to relaycommon.GetTaskRequest in BuildRequestBody; confirm all required task data is properly populated via the new source.

Possibly related PRs

Suggested reviewers

  • seefs001

Poem

🐰 O1 models hop on through with images in tow,
New structures bloom in payloads—a video-rich show!
Unmarshalling flows dance, where multipart meets JSON's call,
Request paths diverge like warren tunnels deep and tall. 🌿✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly references the main change: adding support for kling video o1 model, which aligns with the PR objectives of adding kling-video-o1 support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
relay/channel/task/kling/adaptor.go (1)

56-70: LGTM! Well-documented Omni-Video structures.

The new data structures are clearly defined with helpful inline comments documenting the expected values for enum-like fields (type, refer_type, keep_original_sound).

Optional: Consider typed constants for enum fields

To improve type safety and prevent invalid values, you could define constants for the enum-like fields:

// Frame type constants
const (
    FrameTypeFirst = "first_frame"
    FrameTypeEnd   = "end_frame"
)

// Refer type constants
const (
    ReferTypeFeature = "feature"
    ReferTypeBase    = "base"
)

// Sound preservation options
const (
    KeepSoundYes = "yes"
    KeepSoundNo  = "no"
)

However, this is purely optional—string fields are acceptable for external API bindings.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between afd9c29 and d0fd895.

📒 Files selected for processing (2)
  • relay/channel/task/kling/adaptor.go
  • relay/common/relay_utils.go
🧰 Additional context used
🧬 Code graph analysis (1)
relay/common/relay_utils.go (1)
common/gin.go (1)
  • UnmarshalBodyReusable (72-97)
🔇 Additional comments (2)
relay/channel/task/kling/adaptor.go (2)

88-91: LGTM! Proper field definitions for Omni-Video support.

The new fields are correctly defined with:

  • Appropriate omitempty tags to avoid sending empty arrays
  • Clear naming that matches the Omni-Video API contract
  • Proper integration with the existing requestPayload structure

171-174: Use GetTaskRequest for cleaner request retrieval.

Using relaycommon.GetTaskRequest is a good refactor that improves clarity and error handling. The call ordering is guaranteed by the orchestration logic in relay_task.go, which always invokes ValidateRequestAndSetAction before BuildRequestBody, ensuring the request is stored in context before retrieval.

Comment on lines +141 to +146
var path string
if strings.Contains(info.OriginModelName, "o1") {
path = "/v1/videos/omni-video"
} else {
path = lo.Ternary(info.Action == constant.TaskActionGenerate, "/v1/videos/image2video", "/v1/videos/text2video")
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Strengthen model name matching to avoid false positives.

Using strings.Contains(info.OriginModelName, "o1") to detect Omni-Video models could match unintended model names. For example:

  • Future models like kling-pro1 or kling-v101 would incorrectly match
  • Models containing "o1" in other contexts would be misrouted

Consider using a more specific check:

🔎 Proposed fix using suffix or exact matching

Option 1: Check for known o1 model names

 var path string
-if strings.Contains(info.OriginModelName, "o1") {
+if strings.HasSuffix(info.OriginModelName, "-o1") || info.OriginModelName == "kling-video-o1" {
     path = "/v1/videos/omni-video"
 } else {
     path = lo.Ternary(info.Action == constant.TaskActionGenerate, "/v1/videos/image2video", "/v1/videos/text2video")
 }

Option 2: Use a helper function for clarity

+func isOmniVideoModel(modelName string) bool {
+    return strings.HasSuffix(modelName, "-o1")
+}
+
 var path string
-if strings.Contains(info.OriginModelName, "o1") {
+if isOmniVideoModel(info.OriginModelName) {
     path = "/v1/videos/omni-video"
 } else {
     path = lo.Ternary(info.Action == constant.TaskActionGenerate, "/v1/videos/image2video", "/v1/videos/text2video")
 }
🤖 Prompt for AI Agents
In relay/channel/task/kling/adaptor.go around lines 141 to 146, replace the
brittle strings.Contains(info.OriginModelName, "o1") check with a precise
matcher: either test against a set of known Omni-Video model names (map or slice
of exact names), or use suffix/exact matching or a regex anchored to avoid
partial matches (e.g., endsWith or ^...$). Encapsulate this logic in a small
helper like isOmniVideoModel(name string) bool and use it here so only intended
model names (or suffixes) route to "/v1/videos/omni-video"; otherwise choose the
image2video/text2video paths as before.

Comment on lines +213 to 217
}
// 为了metadata字段的兼容性,统一UnmarshalBodyReusable
if err := common.UnmarshalBodyReusable(c, &req); err != nil {
return createTaskError(err, "invalid_request", http.StatusBadRequest, true)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find and examine relay/common/relay_utils.go around lines 209-217
if [ -f "relay/common/relay_utils.go" ]; then
  echo "=== relay/common/relay_utils.go (lines 200-225) ==="
  sed -n '200,225p' relay/common/relay_utils.go
fi

# Find validateMultipartTaskRequest
echo ""
echo "=== Searching for validateMultipartTaskRequest ==="
rg "validateMultipartTaskRequest|ValidateBasicTaskRequest" --type=go -C 3

# Find parseMultipartFormData
echo ""
echo "=== Searching for parseMultipartFormData ==="
rg "parseMultipartFormData" --type=go -C 10

# Find UnmarshalBodyReusable
echo ""
echo "=== Searching for UnmarshalBodyReusable ==="
rg "UnmarshalBodyReusable" --type=go -C 10

Repository: QuantumNous/new-api

Length of output: 40743


🏁 Script executed:

#!/bin/bash
# Get more details on parseMultipartFormData implementation
sed -n '440,520p' common/gin.go

# Also check validateMultipartTaskRequest implementation
rg "func validateMultipartTaskRequest" -A 40 --type=go

Repository: QuantumNous/new-api

Length of output: 2365


🏁 Script executed:

#!/bin/bash
# Get the parseMultipartFormData implementation from common/gin.go
rg "func parseMultipartFormData" -A 50 --type=go common/gin.go

Repository: QuantumNous/new-api

Length of output: 1455


🏁 Script executed:

#!/bin/bash
# Check if there are any data: URL handling patterns in this area
rg "data:" relay/common/relay_utils.go -B 2 -A 2

# Check the task_video.go file mentioned in learnings
if [ -f "controller/task_video.go" ]; then
  echo "=== Checking controller/task_video.go for data: URL pattern ==="
  rg "data:" controller/task_video.go -B 2 -A 2 | head -40
fi

# Check what happens to the req after both parses
sed -n '205,235p' relay/common/relay_utils.go

Repository: QuantumNous/new-api

Length of output: 1130


🏁 Script executed:

#!/bin/bash
# Check if processFormMap could cause different behavior
rg "func processFormMap" -A 30 --type=go common/gin.go

# Check the request body handling to understand reusability
rg "GetRequestBody\|KeyRequestBody" -B 2 -A 5 --type=go common/gin.go | head -50

Repository: QuantumNous/new-api

Length of output: 588


🏁 Script executed:

#!/bin/bash
# Verify the complete flow by checking what happens to the req struct
# Check if req from validateMultipartTaskRequest is actually used before UnmarshalBodyReusable overwrites it
sed -n '200,225p' relay/common/relay_utils.go

# Also check if there are any tests showing expected behavior
rg "ValidateBasicTaskRequest" -A 5 --type=go *test*.go 2>/dev/null | head -30

Repository: QuantumNous/new-api

Length of output: 885


🏁 Script executed:

#!/bin/bash
# Final verification: check if there are any side effects from validateMultipartTaskRequest besides the returned req
# that might justify the double-parsing
rg "validateMultipartTaskRequest" -B 5 -A 15 relay/common/relay_utils.go

# Check if storeTaskRequest uses the req before UnmarshalBodyReusable is called
rg "storeTaskRequest" -B 2 -A 10 relay/common/relay_utils.go | head -30

Repository: QuantumNous/new-api

Length of output: 1861


Confirm the need for sequential multipart parsing and eliminate redundancy.

For multipart requests, the code parses the form data twice:

  1. First via validateMultipartTaskRequest (line 209), which calls c.MultipartForm()
  2. Then via UnmarshalBodyReusable (line 215), which re-parses from raw body bytes via custom parseMultipartFormData

The first parse's result is completely overwritten by the second, creating unnecessary performance overhead. Either use the first parse result directly, or remove the first parse if the second serves the metadata compatibility requirement mentioned in the comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.