fix(*): MiniMax 视频能力 - 放行参考素材视频生成并统一操作推导

This commit is contained in:
ddCat
2026-08-20 23:43:59 +08:00
parent 11ee5aafec
commit 87ff997020
5 changed files with 23 additions and 7 deletions

View File

@@ -229,6 +229,7 @@ func DefaultModelCapabilityConfigForModel(protocol string, modelName string) *Mo
video.Resolutions = []string{"1080p"}
video.DefaultResolution = "1080p"
case model.ChannelInterfaceMiniMaxVideo:
video.Operations = append(video.Operations, "reference_to_video")
video.References.MaxImages = 9
video.References.MaxImageBytes = 30 * 1024 * 1024
video.References.MaxVideos = 3

View File

@@ -83,6 +83,16 @@ func TestDefaultVideoCapabilityUsesProtocolSpecificResolutionTiers(t *testing.T)
}
}
func TestDefaultMiniMaxVideoCapabilitySupportsReferenceGeneration(t *testing.T) {
profile := DefaultModelCapabilityConfigForModel("minimax-video", "MiniMax-H3")
if profile == nil || profile.Video == nil {
t.Fatal("MiniMax video profile = nil")
}
if !containsCapabilityString(profile.Video.Operations, "reference_to_video") {
t.Fatalf("operations = %v, want reference_to_video", profile.Video.Operations)
}
}
func TestCapabilitySpecFromModelCapabilityConfigRestoresLegacyWildcardImageSizes(t *testing.T) {
config := &ModelCapabilityConfig{
Version: 1,

View File

@@ -315,6 +315,7 @@ export function defaultModelCapabilityConfig(protocol?: ModelProtocol, model = "
video.resolutions = ["768P", "2K"];
video.defaultResolution = "768P";
video.watermark = { supported: true, default: false };
video.operations.push("reference_to_video");
}
return { version: 1, text, image: defaultImageCapabilityConfig(protocol, model), video };
}

View File

@@ -312,14 +312,13 @@ export function modelGroupReferenceLimits(config: AiConfig, selected: string, ca
export function inferVideoOperation(input: ModelInputSummary) {
const visualInputCount = input.imageCount + input.characterCount;
if (input.audioCount > 0 && visualInputCount === 0 && input.videoCount === 0) return "audio_to_video";
if (input.videoCount > 0) return "extend";
if (input.audioCount > 0 || input.videoCount > 0 || visualInputCount > 2) return "reference_to_video";
if (visualInputCount > 0) return "image_to_video";
return "text_to_video";
}
export function resolveVideoOperation(input: ModelInputSummary, storedOperation?: string) {
if (storedOperation && !["text_to_video", "image_to_video", "audio_to_video", "extend"].includes(storedOperation)) return storedOperation;
if (storedOperation && !["text_to_video", "image_to_video", "audio_to_video", "extend", "reference_to_video"].includes(storedOperation)) return storedOperation;
return inferVideoOperation(input);
}
@@ -327,6 +326,7 @@ function videoOperationLabel(operation: string) {
if (operation === "text_to_video") return "文生视频";
if (operation === "image_to_video") return "图生视频";
if (operation === "audio_to_video") return "音频生视频";
if (operation === "reference_to_video") return "参考素材生视频";
if (operation === "extend") return "视频续写";
return "当前生成模式";
}

View File

@@ -6,6 +6,7 @@ import { LOCAL_DREAMINA_WAIT_STOPPED_CODE, LocalDreaminaGenerationClientError, r
import { isLocalDreaminaBackgroundTask, localDreaminaTaskId, projectLocalDreaminaTask, stripLocalDreaminaTaskPrefix } from "@/services/local-dreamina-task-projection";
import { modelCapabilityConfigFor } from "@/lib/model-capabilities";
import { grokImagePromptLimitError } from "@/lib/grok-image-prompt-limit";
import { resolveVideoOperation } from "@/lib/model-selection";
import { modelOptionName, resolveModelChannel, resolveModelRequestConfig, type AiConfig } from "@/stores/use-config-store";
import { useLocalDreaminaModelStore } from "@/stores/use-local-dreamina-model-store";
import type { ReferenceImage } from "@/types/image";
@@ -268,10 +269,13 @@ async function runLocalDreaminaGeneration(options: BackendGenerationTaskOptions,
function generationOperation(options: BackendGenerationTaskOptions) {
if (options.mode !== "video") return options.mode;
const imageCount = options.referenceImages?.length ?? 0;
if ((options.referenceVideos?.length ?? 0) > 0 || (options.referenceAudios?.length ?? 0) > 0 || imageCount > 2) return "reference_to_video";
if (imageCount > 0) return "image_to_video";
return "text_to_video";
return resolveVideoOperation({
textCount: 0,
imageCount: options.referenceImages?.length ?? 0,
videoCount: options.referenceVideos?.length ?? 0,
audioCount: options.referenceAudios?.length ?? 0,
characterCount: 0,
}, options.metadata?.videoEditOperation as string | undefined);
}
export function isGenerationTaskCancelled(error: unknown, signal?: AbortSignal) {