fix(model-capability): 视频模型 - 提示词默认字符上限 1000 调整为 8000 (#511)
This commit is contained in:
@@ -105,6 +105,11 @@ type VideoReferenceConfig struct {
|
||||
MaxAudioDuration int `json:"maxAudioDurationSeconds"`
|
||||
}
|
||||
|
||||
// DefaultVideoPromptMaxChars 是普通视频模型提示词字符数的默认上限。
|
||||
// 视频提示词由输入框文本、连线内容和技能上下文合成,远长于用户手输内容;
|
||||
// 默认值过小会把画布工作流正常可用的提示词拦在本地。管理员仍可按模型覆盖。
|
||||
const DefaultVideoPromptMaxChars = 8000
|
||||
|
||||
type VideoDurationConfig struct {
|
||||
Selection string `json:"selection"`
|
||||
Min int `json:"min,omitempty"`
|
||||
@@ -206,7 +211,7 @@ func DefaultModelCapabilityConfigForModel(protocol string, modelName string) *Mo
|
||||
streaming := true
|
||||
text := &TextCapabilityConfig{Streaming: &streaming, References: TextReferenceConfig{PromptMaxChars: 32000}}
|
||||
video := &VideoCapabilityConfig{
|
||||
References: VideoReferenceConfig{PromptMaxChars: 1000, MinImages: 0, MaxImages: 9, MaxImageBytes: 30 * 1024 * 1024, MaxVideos: 0, MaxVideoBytes: 0, MaxVideoDuration: 0, MaxAudios: 0, MaxAudioBytes: 0, MaxAudioDuration: 0},
|
||||
References: VideoReferenceConfig{PromptMaxChars: DefaultVideoPromptMaxChars, MinImages: 0, MaxImages: 9, MaxImageBytes: 30 * 1024 * 1024, MaxVideos: 0, MaxVideoBytes: 0, MaxVideoDuration: 0, MaxAudios: 0, MaxAudioBytes: 0, MaxAudioDuration: 0},
|
||||
Duration: VideoDurationConfig{Selection: "range", Min: 1, Max: 15, Step: 1, Default: 6},
|
||||
Ratios: []string{"16:9", "9:16", "1:1", "4:3", "3:4", "21:9"},
|
||||
DefaultRatio: "16:9",
|
||||
|
||||
@@ -52,6 +52,34 @@ func TestValidateVideoTaskRejectsPromptAboveCapabilityLimit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 视频提示词由输入框文本、连线内容和技能上下文合成,默认上限必须留出足够余量,
|
||||
// 否则画布工作流会连同线内容一起被拦在本地。这里锁定默认值与边界行为。
|
||||
func TestDefaultVideoPromptMaxCharsAllowsComposedCanvasPrompt(t *testing.T) {
|
||||
profile := DefaultModelCapabilityConfigForModel("seedance-videos-compatible", "sd-2.5").Video
|
||||
if profile.References.PromptMaxChars != 8000 {
|
||||
t.Fatalf("视频默认提示词上限 = %d, want 8000", profile.References.PromptMaxChars)
|
||||
}
|
||||
|
||||
// 画布实际合成出的提示词量级(输入框 + 连线 + 技能上下文)必须通过。
|
||||
composed := canvasGenerationInput{Mode: "video", Prompt: strings.Repeat("镜", 2399), Config: providerConfig{Model: "sd-2.5", VideoSeconds: "6", Size: "16:9", VQuality: "720p"}}
|
||||
if err := validateVideoTask(profile, composed); err != nil {
|
||||
t.Fatalf("合成提示词 2399 字符被拒绝: %v", err)
|
||||
}
|
||||
// 恰好等于上限仍然放行,与前端 `actualChars <= maxChars` 的判定保持一致。
|
||||
atLimit := composed
|
||||
atLimit.Prompt = strings.Repeat("镜", 8000)
|
||||
if err := validateVideoTask(profile, atLimit); err != nil {
|
||||
t.Fatalf("提示词 8000 字符被拒绝: %v", err)
|
||||
}
|
||||
// 超出上限必须明确失败,并保持“不自动截断”的语义。
|
||||
overLimit := composed
|
||||
overLimit.Prompt = strings.Repeat("镜", 8001)
|
||||
err := validateVideoTask(profile, overLimit)
|
||||
if err == nil || !strings.Contains(err.Error(), "最多 8000 个字符") || !strings.Contains(err.Error(), "8001 个字符") {
|
||||
t.Fatalf("validateVideoTask() error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateTaskCapabilityRejectsWorkflowPromptAboveConfiguredLimit(t *testing.T) {
|
||||
profile := DefaultModelCapabilityConfigForModel("runninghub-workflow-video", "workflow-video")
|
||||
profile.Video.References.PromptMaxChars = 10_000
|
||||
|
||||
@@ -24,6 +24,15 @@ export type TextCapabilityConfig = {
|
||||
|
||||
export type ImageSizeParameter = "none" | "size" | "aspect_ratio";
|
||||
|
||||
/**
|
||||
* 普通视频模型提示词字符数的默认上限。
|
||||
*
|
||||
* 视频提示词由「输入框文本 + 连线内容 + 技能上下文」合成,远长于用户手输内容,
|
||||
* 因此不能沿用偏小的默认值把画布工作流拦在本地。必须与后端
|
||||
* `DefaultVideoPromptMaxChars` 保持一致,否则前端放行后端拒绝(或反之)。
|
||||
*/
|
||||
export const DEFAULT_VIDEO_PROMPT_MAX_CHARS = 8000;
|
||||
|
||||
export type ImageCapabilityConfig = {
|
||||
references: {
|
||||
promptMaxChars: number;
|
||||
@@ -262,7 +271,7 @@ export function defaultModelCapabilityConfig(protocol?: ModelProtocol, model = "
|
||||
};
|
||||
const video: VideoCapabilityConfig = {
|
||||
references: {
|
||||
promptMaxChars: 1000,
|
||||
promptMaxChars: DEFAULT_VIDEO_PROMPT_MAX_CHARS,
|
||||
minImages: 0,
|
||||
maxImages: 9,
|
||||
maxImageBytes: 30 * 1024 * 1024,
|
||||
|
||||
@@ -2,7 +2,7 @@ import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
// Bun 直接执行 TypeScript 测试时需要保留扩展名;生产 tsconfig 不包含 test/。
|
||||
import { defaultModelCapabilityConfig, normalizeVideoValue } from "../src/lib/model-capabilities.ts";
|
||||
import { DEFAULT_VIDEO_PROMPT_MAX_CHARS, defaultModelCapabilityConfig, normalizeVideoValue } from "../src/lib/model-capabilities.ts";
|
||||
|
||||
test("switching to MiniMax H3 replaces an unsupported 720p value with 768P", () => {
|
||||
const profile = defaultModelCapabilityConfig("minimax-video", "MiniMax-H3").video!;
|
||||
@@ -13,3 +13,21 @@ test("switching to MiniMax H3 replaces an unsupported 720p value with 768P", ()
|
||||
resolution: "768P",
|
||||
});
|
||||
});
|
||||
|
||||
// 视频提示词由「输入框文本 + 连线内容 + 技能上下文」合成,技能上下文预算为 32000,
|
||||
// 合成结果远长于用户手输内容。默认上限过小会把正常可用的画布工作流拦在本地预检。
|
||||
// 这里锁定默认值本身,避免被改回偏小值(前端放行/后端拒绝的判定必须同源)。
|
||||
test("video prompt default allows a composed canvas prompt", () => {
|
||||
assert.equal(DEFAULT_VIDEO_PROMPT_MAX_CHARS, 8000);
|
||||
for (const protocol of [undefined, "seedance-videos-compatible", "agnes-video", "volcengine-ark-video"]) {
|
||||
const profile = defaultModelCapabilityConfig(protocol, "test-model");
|
||||
assert.equal(profile.video!.references.promptMaxChars, DEFAULT_VIDEO_PROMPT_MAX_CHARS);
|
||||
}
|
||||
});
|
||||
|
||||
test("raising the video default leaves text and image limits untouched", () => {
|
||||
// 只放宽视频默认值,避免顺带改变其它能力的判定口径。
|
||||
const profile = defaultModelCapabilityConfig("seedance-videos-compatible", "sd-2.5");
|
||||
assert.equal(profile.text!.references.promptMaxChars, 32000);
|
||||
assert.equal(profile.image!.references.promptMaxChars, 32000);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user