Skip to content

feat: 支持即梦视频渠道 - #1274

Merged
Calcium-Ion merged 1 commit into
QuantumNous:alphafrom
feitianbubu:feat/add-channel-jimeng
Jun 27, 2025
Merged

feat: 支持即梦视频渠道#1274
Calcium-Ion merged 1 commit into
QuantumNous:alphafrom
feitianbubu:feat/add-channel-jimeng

Conversation

@feitianbubu

@feitianbubu feitianbubu commented Jun 21, 2025

Copy link
Copy Markdown
Member
  1. 支持即梦渠道添加
  2. 即梦视频生成提交
  3. 即梦视频任务查询
    image

Summary by CodeRabbit

  • New Features

    • Added support for the "Jimeng" video generation platform, including task submission, status tracking, and result retrieval.
    • Introduced a new channel option for "Jimeng" in the channel selection menu.
    • "Jimeng" tasks now appear in task logs with a distinct label and color.
  • Improvements

    • Enhanced platform handling for video generation requests, automatically selecting "Jimeng" based on model prefix.
    • Added English translation for "Jimeng" in the interface.
  • Bug Fixes

    • Corrected task ID parameter extraction for video fetch operations.

@coderabbitai

coderabbitai Bot commented Jun 21, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces support for the "Jimeng" video generation platform across the backend and frontend. It adds new constants, relay modes, and a dedicated Jimeng task adaptor. The middleware and controller logic are extended to handle Jimeng-specific requests, and the frontend UI is updated to recognize and display the new platform.

Changes

File(s) / Area Change Summary
common/constants.go, constant/task.go, relay/constant/relay_mode.go Added Jimeng channel/platform constants and relay modes.
relay/common/relay_info.go Introduced TaskSubmitReq and TaskInfo structs for task submission/result handling.
relay/channel/adapter.go, relay/channel/task/kling/adaptor.go, relay/channel/task/suno/adaptor.go Refactored TaskAdaptor interface: replaced ParseResultUrl with ParseTaskResult; updated Kling/Suno adaptors.
relay/channel/task/jimeng/adaptor.go New: Implemented Jimeng TaskAdaptor with signing, request, and result parsing logic.
relay/relay_adaptor.go Added support for Jimeng in GetTaskAdaptor.
controller/task.go, controller/task_video.go Refactored to support Jimeng in task update logic; switched to structured result parsing.
controller/channel-test.go Disabled channel testing for Jimeng.
middleware/distributor.go Differentiated Kling/Jimeng platforms in video generation middleware logic.
relay/relay_task.go Changed task ID parameter from "id" to "task_id" for video fetch endpoint.
web/src/components/table/TaskLogsTable.js Added Jimeng platform rendering; changed Kling tag color.
web/src/constants/channel.constants.js, web/src/i18n/locales/en.json Added Jimeng to channel options and translations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Frontend
    participant Middleware
    participant Controller
    participant Relay
    participant JimengAdaptor

    User->>Frontend: Submit video generation request (model: jimeng-*)
    Frontend->>Middleware: POST /v1/video/generations (model: jimeng-*)
    Middleware->>Controller: Route as Jimeng platform
    Controller->>Relay: UpdateTaskByPlatform(platform=Jimeng)
    Relay->>JimengAdaptor: Submit/Fetch task (signed request)
    JimengAdaptor->>Relay: Return parsed TaskInfo
    Relay->>Controller: TaskInfo with status/progress/result
    Controller->>Frontend: Respond with task status/result
    Frontend->>User: Show Jimeng task info
Loading

Possibly related PRs

Poem

In the land of code, a new dream springs,
"Jimeng" arrives with digital wings.
Adaptor and relay, now friends anew,
Signed requests and progress, all shining through.
With purple tags and a bunny's cheer,
More dreams to generate—Jimeng is here!

((\
( -.-)
o_(")(")


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c19b69f and 05ea0dd.

📒 Files selected for processing (17)
  • common/constants.go (2 hunks)
  • constant/task.go (1 hunks)
  • controller/channel-test.go (1 hunks)
  • controller/task.go (1 hunks)
  • controller/task_video.go (4 hunks)
  • middleware/distributor.go (1 hunks)
  • relay/channel/adapter.go (1 hunks)
  • relay/channel/task/jimeng/adaptor.go (1 hunks)
  • relay/channel/task/kling/adaptor.go (6 hunks)
  • relay/channel/task/suno/adaptor.go (1 hunks)
  • relay/common/relay_info.go (1 hunks)
  • relay/constant/relay_mode.go (2 hunks)
  • relay/relay_adaptor.go (2 hunks)
  • relay/relay_task.go (1 hunks)
  • web/src/components/table/TaskLogsTable.js (2 hunks)
  • web/src/constants/channel.constants.js (1 hunks)
  • web/src/i18n/locales/en.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • constant/task.go
  • controller/channel-test.go
  • relay/relay_adaptor.go
  • web/src/constants/channel.constants.js
  • relay/relay_task.go
  • common/constants.go
  • web/src/i18n/locales/en.json
  • web/src/components/table/TaskLogsTable.js
  • relay/channel/task/suno/adaptor.go
  • controller/task.go
  • relay/constant/relay_mode.go
  • middleware/distributor.go
  • relay/channel/adapter.go
  • relay/common/relay_info.go
🧰 Additional context used
🧠 Learnings (1)
relay/channel/task/kling/adaptor.go (2)
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
Learnt from: feitianbubu
PR: QuantumNous/new-api#1228
File: router/main.go:28-36
Timestamp: 2025-06-15T12:38:11.806Z
Learning: gin.Context implements context.Context interface since Gin v1.8.0, providing the methods Deadline(), Done(), Err(), and Value(). When using Gin v1.8.0 or later, gin.Context can be passed directly to functions expecting context.Context without needing to extract c.Request.Context().
🪛 Gitleaks (8.26.0)
relay/channel/task/jimeng/adaptor.go

179-179: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (10)
controller/task_video.go (3)

15-15: LGTM: Platform parameter addition enables multi-platform support.

The addition of the platform parameter to both UpdateVideoTaskAll and updateVideoTaskAll functions properly enables the system to handle multiple task platforms dynamically.

Also applies to: 24-24


41-41: LGTM: Dynamic adaptor selection improves flexibility.

The change from hardcoded platform usage to relay.GetTaskAdaptor(platform) enables proper platform abstraction and supports the new Jimeng integration.


80-92: LGTM: Structured parsing improves type safety.

The transition from manual JSON parsing to using the ParseTaskResult method provides better type safety and error handling compared to the previous map-based approach.

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

50-66: LGTM: Enhanced response structure supports richer task information.

The expanded responsePayload struct with additional fields like RequestId, TaskStatus, TaskResult, and timestamps provides comprehensive task information handling.


109-109: LGTM: Context key standardization improves consistency.

The change from "kling_request" to "task_request" standardizes the context key usage across different task adaptors.

Also applies to: 135-135


316-345: LGTM: Structured task result parsing improves type safety.

The new ParseTaskResult method provides:

  • Proper JSON unmarshaling with error handling
  • Typed status mapping using model constants
  • Structured return with relaycommon.TaskInfo
  • Better error handling for unknown statuses

This is a significant improvement over the previous map-based parsing approach.

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

76-86: LGTM: Proper initialization with comma-separated API key format.

The initialization correctly handles the Jimeng-specific API key format using comma as separator, which differs from other adaptors that use pipe separators.


217-319: LGTM: Comprehensive HMAC-SHA256 request signing implementation.

The signing implementation follows AWS Signature Version 4 pattern with proper:

  • Canonical request construction
  • Header normalization and sorting
  • Query parameter encoding
  • Multi-step HMAC key derivation
  • Signature generation

The implementation is thorough and handles edge cases well.


327-353: LGTM: Flexible image handling supports both URLs and base64.

The convertToRequestPayload method properly handles both image URLs and base64-encoded images, with appropriate field assignment based on the input format.


179-179: Static analysis false positive: hardcoded API parameter.

The flagged string "jimeng_vgfm_t2v_l20" is a documented fixed value from the Jimeng API documentation, not a secret API key. This is a false positive from the static analysis tool.

✨ 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: 5

🧹 Nitpick comments (3)
middleware/distributor.go (1)

183-189: Consider a more scalable approach for platform detection.

Currently, the code assumes all non-"jimeng" prefixed models belong to Kling platform. This approach won't scale well when more video platforms are added.

Consider using a map or configuration-based approach to determine platform from model prefix:

var modelPrefixToPlatform = map[string]string{
    "jimeng": string(constant.TaskPlatformJimeng),
    "kling":  string(constant.TaskPlatformKling),
    // Add more platforms here
}

// Then use it to determine platform
platform := string(constant.TaskPlatformKling) // default
for prefix, plat := range modelPrefixToPlatform {
    if strings.HasPrefix(strings.ToLower(modelRequest.Model), prefix) {
        platform = plat
        break
    }
}
relay/channel/task/jimeng/adaptor.go (2)

344-344: Fix variable name typo.

-	medaBytes, err := json.Marshal(metadata)
+	metaBytes, err := json.Marshal(metadata)

348-348: Update variable reference to match the corrected name.

-	err = json.Unmarshal(medaBytes, &r)
+	err = json.Unmarshal(metaBytes, &r)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d487be0 and c19b69f.

📒 Files selected for processing (17)
  • common/constants.go (2 hunks)
  • constant/task.go (1 hunks)
  • controller/channel-test.go (1 hunks)
  • controller/task.go (1 hunks)
  • controller/task_video.go (4 hunks)
  • middleware/distributor.go (1 hunks)
  • relay/channel/adapter.go (1 hunks)
  • relay/channel/task/jimeng/adaptor.go (1 hunks)
  • relay/channel/task/kling/adaptor.go (6 hunks)
  • relay/channel/task/suno/adaptor.go (1 hunks)
  • relay/common/relay_info.go (1 hunks)
  • relay/constant/relay_mode.go (2 hunks)
  • relay/relay_adaptor.go (2 hunks)
  • relay/relay_task.go (1 hunks)
  • web/src/components/table/TaskLogsTable.js (2 hunks)
  • web/src/constants/channel.constants.js (1 hunks)
  • web/src/i18n/locales/en.json (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.26.0)
relay/channel/task/jimeng/adaptor.go

179-179: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (23)
common/constants.go (2)

245-245: LGTM! Channel type constant follows established pattern.

The new ChannelTypeJimeng = 51 constant follows the existing sequential numbering pattern and is appropriately placed.


302-302: LGTM! Base URL configuration is appropriate.

The base URL https://visual.volcengineapi.com at index 51 correctly corresponds to the new channel type and appears to be ByteDance's visual AI service endpoint, which is appropriate for video generation functionality.

web/src/i18n/locales/en.json (1)

803-803: LGTM! Translation entry is appropriate.

The English translation "Jimeng" for "即梦" is simple and direct, providing proper localization support for the new video platform.

constant/task.go (1)

9-9: LGTM! Task platform constant follows established pattern.

The new TaskPlatformJimeng constant with value "jimeng" follows the existing naming convention and will provide proper platform identification for Jimeng tasks.

web/src/constants/channel.constants.js (1)

133-137: LGTM! Channel option configuration is consistent.

The new channel option follows the established structure with:

  • Correct value 51 matching the backend constant
  • Appropriate color choice 'blue'
  • Proper Chinese label '即梦' that will be translated via i18n
controller/channel-test.go (1)

46-48: LGTM! Test exclusion is appropriate for video generation channel.

The test exclusion for ChannelTypeJimeng follows the same pattern as other specialized channels (Midjourney, Suno, Kling) that cannot be tested with standard chat completion requests. This is the correct approach for video generation services.

relay/relay_adaptor.go (2)

25-25: LGTM: Import addition follows established pattern.

The jimeng package import is correctly placed alphabetically with other task adaptor imports.


108-109: LGTM: Adaptor selection follows established pattern.

The new case for TaskPlatformJimeng correctly returns a jimeng.TaskAdaptor{} instance, consistent with the existing Suno and Kling implementations.

relay/relay_task.go (1)

234-234: Verify that parameter name change doesn't break existing API consumers.

The parameter name changed from "id" to "task_id". While this may align with Jimeng platform conventions, it could be a breaking change for existing clients that expect the "id" parameter in the URL path.

#!/bin/bash
# Description: Check for existing route definitions and API consumers that might expect "id" parameter
# Expected: Find route definitions and verify parameter consistency

# Search for route definitions that might use this function
rg -A 3 -B 3 "videoFetchByIDRespBodyBuilder|/task.*:id|/task.*:task_id" 

# Look for any documentation or tests that reference the parameter name
rg -A 2 -B 2 "Param.*id.*|task.*id"
web/src/components/table/TaskLogsTable.js (3)

225-226: LGTM: Function parameter rename improves clarity.

Renaming the parameter from type to platform better reflects the actual data being passed and makes the function more semantically clear.


235-235: Good color differentiation for Kling platform.

Changing the Kling platform color from 'blue' to 'orange' provides better visual distinction from other platforms, especially with the new Jimeng platform using purple.


239-244: LGTM: Jimeng platform UI integration follows established pattern.

The new Jimeng case correctly uses:

  • Purple color for visual distinction
  • Video icon consistent with video generation purpose
  • Same tag structure as other platforms
relay/channel/adapter.go (1)

48-48: LGTM: Interface method improves type safety and structure.

The new ParseTaskResult method is a good improvement over the previous approach:

  • Input change from map[string]any to []byte provides better type safety
  • Output change from string to *TaskInfo enables structured task information
  • More consistent with other parsing methods in the codebase
#!/bin/bash
# Description: Verify all TaskAdaptor implementations have been updated to implement ParseTaskResult
# Expected: All implementations should have ParseTaskResult method, none should have ParseResultUrl

# Find all TaskAdaptor implementations
ast-grep --pattern 'type $_ struct {
  $$$
}

func ($_ *$_) $$$($$$) {
  $$$
}'

# Search for any remaining ParseResultUrl methods that should be removed
rg "ParseResultUrl"

# Verify ParseTaskResult implementations exist
rg -A 5 "func.*ParseTaskResult"
relay/constant/relay_mode.go (1)

44-46: LGTM!

The new constants follow the established naming pattern and integrate well with the existing relay mode enumeration.

controller/task.go (1)

77-78: Excellent refactoring!

Combining the Kling and Jimeng platform cases eliminates code duplication and makes the platform handling more generic. The platform parameter is properly passed to UpdateVideoTaskAll.

relay/common/relay_info.go (1)

318-336: Well-structured data models!

The TaskSubmitReq and TaskInfo structs provide good type safety and clear interfaces for task operations. The JSON tags and optional fields are properly configured.

Consider adding documentation comments to clarify the purpose and expected values:

+// TaskSubmitReq represents a video generation task submission request
 type TaskSubmitReq struct {
 	Prompt   string                 `json:"prompt"`
 	Model    string                 `json:"model,omitempty"`
 	Mode     string                 `json:"mode,omitempty"`
 	Image    string                 `json:"image,omitempty"`
 	Size     string                 `json:"size,omitempty"`
 	Duration int                    `json:"duration,omitempty"`
 	Metadata map[string]interface{} `json:"metadata,omitempty"`
 }

+// TaskInfo represents the status and result of a video generation task
 type TaskInfo struct {
+	// Code indicates the response status (0 for success, non-zero for errors)
 	Code     int    `json:"code"`
 	TaskID   string `json:"task_id"`
 	Status   string `json:"status"`
 	Reason   string `json:"reason,omitempty"`
 	Url      string `json:"url,omitempty"`
 	Progress string `json:"progress,omitempty"`
 }
controller/task_video.go (3)

64-66: Why are these error checks commented out?

The status code check and error code validation are commented out. This could allow failed requests to proceed without proper error handling.

Are these checks handled elsewhere in the adaptor implementations, or should they be restored to ensure proper error handling?

Also applies to: 77-79


15-51: Great improvements to platform flexibility!

The addition of the platform parameter and dynamic adaptor selection makes the code more extensible and maintainable. The error handling with proper context is also well implemented.


73-129: Excellent refactoring with type-safe parsing!

The switch to ParseTaskResult method and explicit status handling significantly improves code clarity and type safety. The detailed status progression (10% → 20% → 30% → 100%) provides good user feedback.

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

50-67: LGTM! Well-structured response payload.

The expanded responsePayload struct provides comprehensive type safety for all response fields including task status, result videos, and timestamps.


109-109: Good unification of context keys.

Changing from "kling_request" to "task_request" aligns with the broader refactoring to support multiple platforms.

Also applies to: 134-134


297-326: Robust task result parsing implementation.

The new ParseTaskResult method properly:

  • Handles JSON unmarshaling with error wrapping
  • Maps Kling status strings to internal enums
  • Extracts the first video URL if available
  • Returns a detailed error for unknown statuses
relay/channel/task/jimeng/adaptor.go (1)

217-319: Well-implemented HMAC-SHA256 signing logic.

The request signing implementation correctly follows the standard HMAC-SHA256 authentication pattern with proper canonical request construction, header sorting, and signature generation.

Comment on lines +25 to 27
func (a *TaskAdaptor) ParseTaskResult([]byte) (*relaycommon.TaskInfo, error) {
return nil, fmt.Errorf("not implement") // todo implement this method if needed
}

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

🧩 Verification correct

Implement or gracefully handle unimplemented ParseTaskResult method.

The current implementation returns an error with "not implement", which could cause runtime failures when this method is called. Consider either:

  1. Implementing the method to parse Suno task results into TaskInfo structure
  2. Ensuring calling code gracefully handles this error case

🏁 Script executed:

#!/bin/bash
# Description: Check if ParseTaskResult is actually called for Suno platform
# Expected: Find usages and verify error handling

# Search for calls to ParseTaskResult method
rg -A 5 -B 5 "ParseTaskResult"

# Look for task result parsing logic in controllers
rg -A 10 -B 5 "suno.*task.*result|task.*result.*suno"

Length of output: 3364


Implement or gracefully handle unimplemented ParseTaskResult method.

The current implementation returns an error with "not implement", which could cause runtime failures when this method is called. Consider either:

  1. Implementing the method to parse Suno task results into TaskInfo structure
  2. Ensuring calling code gracefully handles this error case
#!/bin/bash
# Description: Check if ParseTaskResult is actually called for Suno platform
# Expected: Find usages and verify error handling

# Search for calls to ParseTaskResult method
rg -A 5 -B 5 "ParseTaskResult"

# Look for task result parsing logic in controllers
rg -A 10 -B 5 "suno.*task.*result|task.*result.*suno"
🤖 Prompt for AI Agents
In relay/channel/task/suno/adaptor.go around lines 25 to 27, the ParseTaskResult
method currently returns a generic "not implement" error which may cause runtime
failures if called. You should either implement this method to correctly parse
the Suno task result bytes into a relaycommon.TaskInfo object or ensure that all
calling code properly checks and handles this error case to avoid crashes.
Review the codebase to confirm if this method is invoked and handle accordingly.

Comment on lines +153 to +161
func Path2RelayJimeng(method, path string) int {
relayMode := RelayModeUnknown
if method == http.MethodPost && strings.HasSuffix(path, "/video/generations") {
relayMode = RelayModeJimengSubmit
} else if method == http.MethodGet && strings.Contains(path, "/video/generations/") {
relayMode = RelayModeJimengFetchByID
}
return relayMode
}

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.

🛠️ Refactor suggestion

Consider refactoring to eliminate code duplication.

The Path2RelayJimeng function is identical to Path2RelayKling except for the return values. This violates the DRY principle.

Consider creating a generic helper function:

+func pathToVideoRelayMode(method, path string, submitMode, fetchMode int) int {
+	relayMode := RelayModeUnknown
+	if method == http.MethodPost && strings.HasSuffix(path, "/video/generations") {
+		relayMode = submitMode
+	} else if method == http.MethodGet && strings.Contains(path, "/video/generations/") {
+		relayMode = fetchMode
+	}
+	return relayMode
+}

 func Path2RelayKling(method, path string) int {
-	relayMode := RelayModeUnknown
-	if method == http.MethodPost && strings.HasSuffix(path, "/video/generations") {
-		relayMode = RelayModeKlingSubmit
-	} else if method == http.MethodGet && strings.Contains(path, "/video/generations/") {
-		relayMode = RelayModeKlingFetchByID
-	}
-	return relayMode
+	return pathToVideoRelayMode(method, path, RelayModeKlingSubmit, RelayModeKlingFetchByID)
 }

 func Path2RelayJimeng(method, path string) int {
-	relayMode := RelayModeUnknown
-	if method == http.MethodPost && strings.HasSuffix(path, "/video/generations") {
-		relayMode = RelayModeJimengSubmit
-	} else if method == http.MethodGet && strings.Contains(path, "/video/generations/") {
-		relayMode = RelayModeJimengFetchByID
-	}
-	return relayMode
+	return pathToVideoRelayMode(method, path, RelayModeJimengSubmit, RelayModeJimengFetchByID)
 }
🤖 Prompt for AI Agents
In relay/constant/relay_mode.go around lines 153 to 161, the Path2RelayJimeng
function duplicates logic found in Path2RelayKling except for the specific
return values. Refactor by extracting the shared logic into a generic helper
function that takes parameters for method, path, and the specific relay mode
values to return. Then have Path2RelayJimeng and Path2RelayKling call this
helper with their respective return values to eliminate duplication and adhere
to the DRY principle.

Comment thread middleware/distributor.go
Comment on lines +177 to +178
if strings.HasPrefix(modelRequest.Model, "jimeng") {
platform = string(constant.TaskPlatformJimeng)

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.

🛠️ Refactor suggestion

Consider making the model prefix check case-insensitive.

The current check strings.HasPrefix(modelRequest.Model, "jimeng") is case-sensitive, which might cause issues if users provide model names with different casing.

-		if strings.HasPrefix(modelRequest.Model, "jimeng") {
+		if strings.HasPrefix(strings.ToLower(modelRequest.Model), "jimeng") {

Also, consider documenting the model naming convention (e.g., "jimeng-*" for Jimeng models) to ensure consistency.

📝 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
if strings.HasPrefix(modelRequest.Model, "jimeng") {
platform = string(constant.TaskPlatformJimeng)
if strings.HasPrefix(strings.ToLower(modelRequest.Model), "jimeng") {
platform = string(constant.TaskPlatformJimeng)
🤖 Prompt for AI Agents
In middleware/distributor.go around lines 177 to 178, the model prefix check
using strings.HasPrefix is case-sensitive, which can cause mismatches if the
model name casing varies. Modify the check to be case-insensitive by converting
modelRequest.Model to lowercase before the prefix check. Additionally, add a
comment near this code explaining the model naming convention, such as
"jimeng-*" prefix for Jimeng models, to improve code clarity and consistency.

Comment thread controller/task_video.go
if task.FinishTime == 0 {
task.FinishTime = now
}
task.FailReason = taskResult.Url

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

Semantic mismatch: storing URL in FailReason field.

Using the FailReason field to store the success URL is semantically incorrect and could cause confusion.

Consider using a dedicated field or the existing Data field to store the URL:

 case model.TaskStatusSuccess:
 	task.Progress = "100%"
 	if task.FinishTime == 0 {
 		task.FinishTime = now
 	}
-	task.FailReason = taskResult.Url
+	// Store URL in Data field or add a dedicated URL field to the Task model
+	task.Data = map[string]interface{}{"url": taskResult.Url}
🤖 Prompt for AI Agents
In controller/task_video.go at line 107, the code assigns a URL to the
FailReason field, which is semantically incorrect since FailReason should
describe failure causes. To fix this, store the URL in a more appropriate field
such as a dedicated URL field or the existing Data field instead of FailReason,
ensuring the data matches the field's intended purpose.

Comment on lines +369 to +376
switch resTask.Data.Status {
case "in_queue":
taskResult.Status = model.TaskStatusQueued
taskResult.Progress = "10%"
case "done":
taskResult.Status = model.TaskStatusSuccess
taskResult.Progress = "100%"
}

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.

🛠️ Refactor suggestion

Add missing task status mappings.

The method only handles "in_queue" and "done" statuses. Consider adding mappings for other potential statuses like "processing" or "failed" to avoid missing status updates.

 	switch resTask.Data.Status {
 	case "in_queue":
 		taskResult.Status = model.TaskStatusQueued
 		taskResult.Progress = "10%"
+	case "processing", "in_progress":
+		taskResult.Status = model.TaskStatusInProgress
+		taskResult.Progress = "50%"
+	case "failed", "error":
+		taskResult.Status = model.TaskStatusFailure
+		taskResult.Progress = "100%"
 	case "done":
 		taskResult.Status = model.TaskStatusSuccess
 		taskResult.Progress = "100%"
+	default:
+		// Log unknown status for debugging
+		taskResult.Status = model.TaskStatusQueued
+		taskResult.Progress = "0%"
 	}
📝 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
switch resTask.Data.Status {
case "in_queue":
taskResult.Status = model.TaskStatusQueued
taskResult.Progress = "10%"
case "done":
taskResult.Status = model.TaskStatusSuccess
taskResult.Progress = "100%"
}
switch resTask.Data.Status {
case "in_queue":
taskResult.Status = model.TaskStatusQueued
taskResult.Progress = "10%"
case "processing", "in_progress":
taskResult.Status = model.TaskStatusInProgress
taskResult.Progress = "50%"
case "failed", "error":
taskResult.Status = model.TaskStatusFailure
taskResult.Progress = "100%"
case "done":
taskResult.Status = model.TaskStatusSuccess
taskResult.Progress = "100%"
default:
// Log unknown status for debugging
taskResult.Status = model.TaskStatusQueued
taskResult.Progress = "0%"
}
🤖 Prompt for AI Agents
In relay/channel/task/jimeng/adaptor.go around lines 369 to 376, the switch
statement handling task statuses only covers "in_queue" and "done". To ensure
all task statuses are properly mapped, add cases for other possible statuses
such as "processing" and "failed", assigning appropriate values to
taskResult.Status and taskResult.Progress for each new case.

@Calcium-Ion Calcium-Ion changed the title 支持即梦视频渠道 feat: 支持即梦视频渠道 Jun 21, 2025
@feitianbubu
feitianbubu force-pushed the feat/add-channel-jimeng branch from c19b69f to 05ea0dd Compare June 27, 2025 09:12
@Calcium-Ion
Calcium-Ion merged commit 647f8d7 into QuantumNous:alpha Jun 27, 2025
@jackwong-hub

Copy link
Copy Markdown

请问即梦是通过 openai接口调用吗还是和可灵一样。
文生视频: /v1/videos/text2video
图生视频: /v1/videos/image2video

@feitianbubu

Copy link
Copy Markdown
Member Author

请问即梦是通过 openai接口调用吗还是和可灵一样。 文生视频: /v1/videos/text2video 图生视频: /v1/videos/image2video

不是, 你说的这两个格式是可灵的官方格式
New API保底支持统一的请求格式, 后续增加对即梦官方格式的支持
统一视频调用格式:

post: /v1/video/generations

body: ```
{
"model": "jimeng_vgfm_t2v_l20", // 会根据model自适应到各个视频渠道, 即梦目前默认就一个jimeng_vgfm_t2v_l20
"prompt": "一个穿着宇航服的宇航员在月球上行走",
"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",
"metadata": {
"desc": "透传官方自定义格式"
}
}

@jackwong-hub

Copy link
Copy Markdown

请问即梦是通过openai接口调用吗还是和可灵一样。 文生视频: /v1/videos/text2video 图生视频: /v1/videos/image2video

不是,你说的这两种格式是可灵的官方格式 新API保底支持统一的请求格式,后续增加对即梦官方格式的支持 统一视频调用格式:

邮政:/v1/video/generations

body: ``` { "model": "jimeng_vgfm_t2v_l20", // 会根据model适配到各个视频渠道,即梦目前默认就一个jimeng_vgfm_t2v_l20 "prompt": "一个穿着宇航服的宇航员在月球上行走", "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 ", "metadata": { "desc": "透传官方舞蹈格式" } }

好的 谢谢

@jackwong-hub

Copy link
Copy Markdown

jimeng_vgfm_t2v_l20

大佬 还有个问题。即梦的渠道密钥是放火山方舟的 api key吗还是 Secret Access Key,我试了这两个都报400。

@feitianbubu

Copy link
Copy Markdown
Member Author

你提了个非常好的问题, 实际上是要两个一起填, 中间用|分隔
image
你的界面上没有显示这个吗, 可能是我忘了提交, 我提一下

@feitianbubu

Copy link
Copy Markdown
Member Author

#1322
我提交了, 合并后和其他渠道一样使用|分隔, 没合并前你先用, @jackwong-hub

@jackwong-hub

Copy link
Copy Markdown

没合并前你

好的 谢谢大佬

@jackwong-hub

Copy link
Copy Markdown

请问即梦是通过 openai接口调用吗还是和可灵一样。 文生视频: /v1/videos/text2video 图生视频: /v1/videos/image2video

不是, 你说的这两个格式是可灵的官方格式 New API保底支持统一的请求格式, 后续增加对即梦官方格式的支持 统一视频调用格式:

post: /v1/video/generations

body: ``` { "model": "jimeng_vgfm_t2v_l20", // 会根据model自适应到各个视频渠道, 即梦目前默认就一个jimeng_vgfm_t2v_l20 "prompt": "一个穿着宇航服的宇航员在月球上行走", "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", "metadata": { "desc": "透传官方自定义格式" } }

您好,还想问一下,这个post地址只能生成视频吗。按照生图的参数提交的,也会生成视频,是不是即梦的生图功能暂时不能用。

@feitianbubu

Copy link
Copy Markdown
Member Author

是的,这个版本只支持视频,
生图如果有需要下个版本加

@jackwong-hub

Copy link
Copy Markdown

是的,这个版本只支持视频, 生图如果有需要下个版本加

需要 谢谢

@feitianbubu

Copy link
Copy Markdown
Member Author

是的,这个版本只支持视频, 生图如果有需要下个版本加

需要 谢谢

#1363 加了即梦生图功能 @jackwong-hub

@jackwong-hub

Copy link
Copy Markdown

是的,这个版本只支持视频, 生图如果有需要下个版本加

需要 谢谢

#1363 加了即梦生图功能 @jackwong-hub
感谢,大佬

@skstudying

Copy link
Copy Markdown

{
"model": "jimeng_vgfm_t2v_l20", // 会根据model自适应到各个视频渠道, 即梦目前默认就一个jimeng_vgfm_t2v_l20
"prompt": "一个穿着宇航服的宇航员在月球上行走",
"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",
"metadata": {
"desc": "透传官方自定义格式"
}

大佬您好,今天在测试您这个火山的生图+生视频。
渠道配置这里怎么都配不对,请求您的帮助:
1.我个人是在火山方舟配置了即梦视频,得到了一个 API Key
2.我在火山引擎控制台(https://console.volcengine.com/iam/keymanage),得到了Access Key ID 和 Secret Access Key

选择渠道为 ”即梦“ 并填入Access Key ID | Secret Access Key 报错没有权限。我认为应该用到API key 但是却不知道该怎么组合填入了。请指点一下。

@skstudying

Copy link
Copy Markdown

我仔细阅读了官方文档和jimeng/adaptor.go代码。解决了我现阶段的问题:
我以为大佬对接了https://www.volcengine.com/docs/82379/1520757 中的 doubao-seedance-pro 一系列即梦生视频,但其实佬主要是对接了此文档中的接口(https://www.volcengine.com/docs/85621/1792707)

我目前存在的问题是:

  1. doubao-seedance-pro、doubao-seedance-lite等 与即梦的jimeng_i2v_first_tail_v30到底是啥关系和区别 ?
  2. 佬是否有计划后续做对接火山的图生视频,即此文档https://www.volcengine.com/docs/82379/1520757

@feitianbubu

Copy link
Copy Markdown
Member Author
  1. doubao和 即梦是字节的两个团队的产品, 各做各的, 接口也不兼容(感觉字节的好些接口都是这样)
    你给的豆包的api https://www.volcengine.com/docs/82379/1520757 我看和标准的openai接口差不多, 你可以试下, 直接用openai兼容渠道的生图接口试下
  2. 有空会接,现在暂无排期, 也欢迎其他佬pr

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.

4 participants