feat(kling): 接入 Omni 视频兼容接口

This commit is contained in:
2026-07-22 00:25:05 +08:00
parent b04a7d9d3d
commit 5a71643099
10 changed files with 1886 additions and 7 deletions
@@ -0,0 +1,27 @@
package runner
import (
"testing"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)
func TestKelingO1GeneratedAudioIsRejectedInsteadOfSilentlyRemoved(t *testing.T) {
result := preprocessRequestWithLog("videos.generations", map[string]any{
"model": "kling-o1",
"audio": true,
}, store.RuntimeModelCandidate{
Provider: "keling",
ProviderModelName: "kling-video-o1",
ModelType: "video_generate",
Capabilities: map[string]any{
"video_generate": map[string]any{"output_audio": false},
},
})
if result.Err == nil {
t.Fatal("Keling O1 audio=true must be rejected")
}
if len(result.Log.Changes) == 0 || result.Log.Changes[len(result.Log.Changes)-1].Action != "reject" {
t.Fatalf("expected an auditable reject change, got %+v", result.Log.Changes)
}
}
@@ -4,6 +4,8 @@ import (
"fmt"
"math"
"strings"
"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)
type resolutionNormalizeProcessor struct{}
@@ -691,6 +693,16 @@ func (audioProcessor) ShouldProcess(params map[string]any, modelType string, con
}
func (audioProcessor) Process(params map[string]any, modelType string, context *paramProcessContext) bool {
if context != nil && kelingO1GeneratedAudioRequested(params, context.candidate) {
return context.reject(
"AudioProcessor",
"audio",
params["audio"],
"kling-video-o1 does not support generated audio",
capabilityPath(modelType, "output_audio"),
capabilityValue(context.modelCapability, modelType, "output_audio"),
)
}
capability := capabilityForType(context.modelCapability, modelType)
if capability == nil || !boolFromAny(capability["output_audio"]) {
for _, key := range []string{"audio", "output_audio"} {
@@ -712,6 +724,17 @@ func (audioProcessor) Process(params map[string]any, modelType string, context *
return true
}
func kelingO1GeneratedAudioRequested(params map[string]any, candidate store.RuntimeModelCandidate) bool {
if !strings.EqualFold(strings.TrimSpace(candidate.Provider), "keling") {
return false
}
model := strings.ToLower(strings.TrimSpace(candidate.ProviderModelName))
if model != "kling-o1" && model != "kling-video-o1" {
return false
}
return boolFromAny(params["audio"]) || boolFromAny(params["output_audio"])
}
type imageCountProcessor struct{}
func (imageCountProcessor) Name() string { return "ImageCountProcessor" }