Skip to content

feat: channel kling support New API - #1412

Merged
creamlike1024 merged 1 commit into
QuantumNous:alphafrom
feitianbubu:pr/support-New-API-proxy-kling
Jul 21, 2025
Merged

feat: channel kling support New API#1412
creamlike1024 merged 1 commit into
QuantumNous:alphafrom
feitianbubu:pr/support-New-API-proxy-kling

Conversation

@feitianbubu

@feitianbubu feitianbubu commented Jul 21, 2025

Copy link
Copy Markdown
Member

支持New API代理可灵渠道
可灵渠道同时支持官方接口和New API接口
ApiKey如果是可灵官方输入: AccessKey|SecretKey
如果上游是New API,则直接输ApiKey

Summary by CodeRabbit

  • New Features

    • Added GET endpoints to retrieve the status and results of video generation tasks by task ID for both image-to-video and text-to-video processes.
  • Improvements

    • Enhanced compatibility with new and existing API response formats for video task status retrieval.
    • Unified API key input, allowing direct entry of ApiKey for new upstream APIs, with updated user prompts for clarity.
  • Bug Fixes

    • Improved path matching logic for video generation task retrieval to handle more cases.

@coderabbitai

coderabbitai Bot commented Jul 21, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces new GET endpoints for querying Kling video generation tasks by task ID, adds corresponding handler stubs and routes, and adjusts both backend and frontend logic to support a unified API key format for the Kling adaptor. The response parsing logic is updated to handle multiple formats, and related user prompts are clarified.

Changes

File(s) Change Summary
controller/swag_video.go Added two empty handler functions with Swagger docs for GET endpoints to query Kling video tasks by task ID.
router/video-router.go Registered new GET routes for /videos/text2video/:task_id and /videos/image2video/:task_id, handled by controller.RelayTask.
controller/task_video.go Modified task update logic to support parsing a new API response format with conditional fallback and adjusted data assignment.
relay/channel/task/kling/adaptor.go Unified API key handling, added TaskId to response struct, simplified response parsing, and refactored JWT token creation.
relay/constant/relay_mode.go Relaxed path matching for Kling GET requests to allow paths without a trailing slash.
web/src/pages/Channel/EditChannel.js Updated user prompt for API key input to clarify new and old formats.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Frontend
    participant Router
    participant Controller
    participant Adaptor
    participant UpstreamAPI

    User->>Frontend: Request task status (GET /videos/text2video/:task_id)
    Frontend->>Router: Forward GET request
    Router->>Controller: Call RelayTask handler
    Controller->>Adaptor: Prepare request, parse API key
    Adaptor->>UpstreamAPI: Query task status/result
    UpstreamAPI-->>Adaptor: Respond with task status/result
    Adaptor->>Controller: Parse response (new or old format)
    Controller->>Frontend: Return task status/result
    Frontend->>User: Display task status/result
Loading

Estimated code review effort

4 (60–120 minutes)

Possibly related PRs

Poem

In the warren where the code flows free,
New routes for Kling hop in with glee.
API keys now in one tidy string,
Empty handlers wait for what tasks will bring.
Rabbits query, parse, and relay—
Another bright patch in the meadow today! 🐇

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@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: 1

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

53-53: Consider documenting the purpose of the redundant TaskId field.

The addition of a top-level TaskId field duplicates the existing nested Data.TaskId. While this may be necessary for API compatibility, it would be helpful to add a comment explaining why both fields exist to prevent confusion for future maintainers.

 type responsePayload struct {
 	Code      int    `json:"code"`
 	Message   string `json:"message"`
-	TaskId    string `json:"task_id"`
+	TaskId    string `json:"task_id"` // Top-level task ID for New API compatibility
 	RequestId string `json:"request_id"`

84-86: Update or remove the misleading comment about API key format.

The comment on line 86 suggests a specific format "access_key|secret_key", but the Init method doesn't validate or enforce this format. Consider either:

  1. Removing the comment since the actual parsing happens in createJWTTokenWithKey
  2. Updating it to reflect that both formats are supported
 	a.apiKey = info.ApiKey
-
-	// apiKey format: "access_key|secret_key"
+	// apiKey can be either "access_key|secret_key" (official) or direct API key (New API)

282-288: Remove commented-out code.

The commented-out code adds no value and creates confusion. Please remove it to improve code readability.

 func (a *TaskAdaptor) createJWTToken() (string, error) {
 	return a.createJWTTokenWithKey(a.apiKey)
 }
 
-//func (a *TaskAdaptor) createJWTTokenWithKey(apiKey string) (string, error) {
-//	parts := strings.Split(apiKey, "|")
-//	if len(parts) != 2 {
-//		return "", fmt.Errorf("invalid API key format, expected 'access_key,secret_key'")
-//	}
-//	return a.createJWTTokenWithKey(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]))
-//}
-
 func (a *TaskAdaptor) createJWTTokenWithKey(apiKey string) (string, error) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d0037a and fcc006e.

📒 Files selected for processing (6)
  • controller/swag_video.go (1 hunks)
  • controller/task_video.go (2 hunks)
  • relay/channel/task/kling/adaptor.go (5 hunks)
  • relay/constant/relay_mode.go (1 hunks)
  • router/video-router.go (1 hunks)
  • web/src/pages/Channel/EditChannel.js (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
relay/channel/task/kling/adaptor.go (1)

Learnt from: 9Ninety
PR: #1273
File: relay/channel/gemini/relay-gemini.go:97-116
Timestamp: 2025-06-21T03:37:41.726Z
Learning: In relay/channel/gemini/relay-gemini.go, the thinking budget calculation logic (including the MaxOutputTokens multiplication) was introduced in PR #1247. PR #1273 focused specifically on decoupling the thoughts summary feature from thinking budget settings and did not modify the existing thinking budget behavior.

🧬 Code Graph Analysis (1)
controller/task_video.go (2)
relay/common/relay_info.go (1)
  • TaskInfo (337-344)
common/json.go (1)
  • Unmarshal (8-10)
🔇 Additional comments (8)
relay/constant/relay_mode.go (1)

153-153: LGTM: Path matching updated to support task ID endpoints.

The change from HasSuffix to Contains correctly enables routing for the new GET endpoints /videos/text2video/:task_id and /videos/image2video/:task_id by matching paths that contain "/video/generations" anywhere in the string.

web/src/pages/Channel/EditChannel.js (1)

71-71: LGTM: User prompt updated for dual API key support.

The updated prompt clearly informs users about the two authentication formats:

  • Official Kling API: AccessKey|SecretKey
  • New API proxy: Direct ApiKey input

This aligns perfectly with the PR objective of supporting both interfaces simultaneously.

router/video-router.go (1)

23-24: LGTM: GET endpoints added for task status queries.

The new routes properly complement the existing POST endpoints by enabling task status retrieval:

  • /videos/text2video/:task_id and /videos/image2video/:task_id
  • Consistent middleware usage and controller reuse
  • Follows RESTful patterns for resource querying

These align with the Swagger documentation added in controller/swag_video.go.

controller/swag_video.go (1)

118-136: LGTM: Swagger documentation added for new GET endpoints.

The empty handler functions serve as proper Swagger documentation stubs for the new task query endpoints:

  • Clear summaries and descriptions in both Chinese and English
  • Correct HTTP method and path parameter specification
  • Appropriate categorization with Tags

Since the actual implementation is handled by controller.RelayTask (as configured in the router), these documentation stubs are sufficient.

relay/channel/task/kling/adaptor.go (4)

77-77: Good simplification of API key handling.

Consolidating the separate access/secret keys into a single apiKey field improves flexibility and aligns well with the PR objective of supporting both official and New API formats.


166-177: LGTM! Simplified response handling.

The streamlined response parsing removes unnecessary complexity while maintaining proper error handling. The direct JSON response aligns well with the New API support objective.


290-297: Well-implemented dual API key format support.

The logic correctly handles both API key formats as described in the PR objectives:

  • Direct API key (New API): Returns the key as-is
  • "AccessKey|SecretKey" format (Official): Generates JWT token

This implementation provides the flexibility needed for supporting both interfaces.


310-310:

Comment thread controller/task_video.go
Comment on lines +83 to 97
taskResult := &relaycommon.TaskInfo{}
// try parse as New API response format
var responseItems dto.TaskResponse[model.Task]
if err = json.Unmarshal(responseBody, &responseItems); err == nil {
t := responseItems.Data
taskResult.TaskID = t.TaskID
taskResult.Status = string(t.Status)
taskResult.Url = t.FailReason
taskResult.Progress = t.Progress
taskResult.Reason = t.FailReason
} else if taskResult, err = adaptor.ParseTaskResult(responseBody); err != nil {
return fmt.Errorf("parseTaskResult failed for task %s: %w", taskId, err)
} else {
task.Data = responseBody
}

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

Fix field mapping errors in New API response parsing.

The new dual-format parsing approach is good for compatibility, but there are several issues with the field mapping:

  1. Incorrect URL assignment: Line 90 assigns t.FailReason to taskResult.Url, which should likely be a URL field from the response
  2. Duplicate assignment: Both taskResult.Url and taskResult.Reason are assigned the same t.FailReason value
  3. Missing task data: task.Data = responseBody is only set in the fallback branch (line 96), but may be needed for both parsing paths

Please verify the correct field mappings from the model.Task struct and apply this correction:

 // try parse as New API response format
 var responseItems dto.TaskResponse[model.Task]
 if err = json.Unmarshal(responseBody, &responseItems); err == nil {
     t := responseItems.Data
     taskResult.TaskID = t.TaskID
     taskResult.Status = string(t.Status)
-    taskResult.Url = t.FailReason
+    taskResult.Url = t.ResultURL // or appropriate URL field
     taskResult.Progress = t.Progress
     taskResult.Reason = t.FailReason
+    task.Data = responseBody
 } else if taskResult, err = adaptor.ParseTaskResult(responseBody); err != nil {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
taskResult := &relaycommon.TaskInfo{}
// try parse as New API response format
var responseItems dto.TaskResponse[model.Task]
if err = json.Unmarshal(responseBody, &responseItems); err == nil {
t := responseItems.Data
taskResult.TaskID = t.TaskID
taskResult.Status = string(t.Status)
taskResult.Url = t.FailReason
taskResult.Progress = t.Progress
taskResult.Reason = t.FailReason
} else if taskResult, err = adaptor.ParseTaskResult(responseBody); err != nil {
return fmt.Errorf("parseTaskResult failed for task %s: %w", taskId, err)
} else {
task.Data = responseBody
}
taskResult := &relaycommon.TaskInfo{}
// try parse as New API response format
var responseItems dto.TaskResponse[model.Task]
if err = json.Unmarshal(responseBody, &responseItems); err == nil {
t := responseItems.Data
taskResult.TaskID = t.TaskID
taskResult.Status = string(t.Status)
taskResult.Url = t.ResultURL // or appropriate URL field
taskResult.Progress = t.Progress
taskResult.Reason = t.FailReason
task.Data = responseBody
} else if taskResult, err = adaptor.ParseTaskResult(responseBody); err != nil {
return fmt.Errorf("parseTaskResult failed for task %s: %w", taskId, err)
} else {
task.Data = responseBody
}
🤖 Prompt for AI Agents
In controller/task_video.go around lines 83 to 97, fix the incorrect field
mappings when parsing the new API response: assign the correct URL field from
the response (not FailReason) to taskResult.Url, avoid duplicating FailReason in
both Url and Reason fields, and ensure task.Data is set to responseBody in both
successful parsing branches, not just the fallback. Review the model.Task struct
to identify the proper URL field and update the assignments accordingly.

@creamlike1024
creamlike1024 merged commit efe894c into QuantumNous:alpha Jul 21, 2025
3 checks passed
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.

2 participants