package runner import ( "testing" "github.com/easyai/easyai-ai-gateway/apps/api/internal/store" ) func volcTextCandidate(maxOutput any) store.RuntimeModelCandidate { capability := map[string]any{} if maxOutput != nil { capability["max_output_tokens"] = maxOutput } return store.RuntimeModelCandidate{ Provider: "volces-openai", BaseURL: "https://ark.cn-beijing.volces.com/api/v3", ModelType: "text_generate", ProviderModelName: "demo", Capabilities: map[string]any{"text_generate": capability}, } } func TestDefaultVolcesOutputTokens(t *testing.T) { tests := []struct { name string max int want int }{ {name: "128K", max: 131072, want: 43690}, {name: "32K", max: 32768, want: 10922}, {name: "24K below threshold", max: 24576, want: 24576}, {name: "threshold exact", max: 30720, want: 10240}, {name: "threshold minus one", max: 30719, want: 30719}, {name: "floor", max: 131071, want: 43690}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if got := defaultVolcesOutputTokens(test.max); got != test.want { t.Fatalf("defaultVolcesOutputTokens(%d)=%d, want %d", test.max, got, test.want) } }) } } func TestVolcesOutputProcessorInjectsCandidateSpecificDefaults(t *testing.T) { chat := preprocessRequestWithLog("chat.completions", map[string]any{"messages": []any{}, "max_tokens": nil}, volcTextCandidate(131072)) if chat.Err != nil || chat.Body["max_tokens"] != 43690 { t.Fatalf("unexpected Chat preprocessing: body=%+v err=%v", chat.Body, chat.Err) } if len(chat.Log.Changes) != 1 || chat.Log.Changes[0].CapabilityPath != "capabilities.text_generate.max_output_tokens" { t.Fatalf("expected auditable capability source, got %+v", chat.Log.Changes) } responses := preprocessRequestWithLog("responses", map[string]any{"input": "hello", "max_output_tokens": nil}, volcTextCandidate(24576)) if responses.Err != nil || responses.Body["max_output_tokens"] != 24576 { t.Fatalf("unexpected Responses preprocessing: body=%+v err=%v", responses.Body, responses.Err) } } func TestVolcesOutputProcessorPreservesExplicitLimits(t *testing.T) { for _, body := range []map[string]any{ {"messages": []any{}, "max_tokens": 1234}, {"messages": []any{}, "max_completion_tokens": 2345}, {"messages": []any{}, "max_tokens": 1234, "max_completion_tokens": 2345}, } { result := preprocessRequestWithLog("chat.completions", body, volcTextCandidate(32768)) if result.Err != nil || len(result.Log.Changes) != 0 { t.Fatalf("explicit Chat limit should remain unchanged: body=%+v err=%v changes=%+v", result.Body, result.Err, result.Log.Changes) } } result := preprocessRequestWithLog("responses", map[string]any{"input": "hello", "max_output_tokens": 3456}, volcTextCandidate(32768)) if result.Err != nil || result.Body["max_output_tokens"] != 3456 || len(result.Log.Changes) != 0 { t.Fatalf("explicit Responses limit should remain unchanged: %+v", result) } } func TestVolcesOutputCandidateFilterSupportsFailover(t *testing.T) { missing := volcTextCandidate(nil) missing.PlatformID = "missing" valid := volcTextCandidate(32768) valid.PlatformID = "valid" filtered, summary, err := filterRuntimeCandidatesByOutputTokens("chat.completions", "demo", "text_generate", map[string]any{"messages": []any{}}, []store.RuntimeModelCandidate{missing, valid}) if err != nil || len(filtered) != 1 || filtered[0].PlatformID != "valid" { t.Fatalf("expected missing capability candidate to be skipped: filtered=%+v summary=%+v err=%v", filtered, summary, err) } result := preprocessRequestWithLog("chat.completions", map[string]any{"messages": []any{}}, filtered[0]) if result.Body["max_tokens"] != 10922 { t.Fatalf("failover candidate must recalculate its own default, got %+v", result.Body) } } func TestVolcesOutputCandidateFilterRejectsMissingAndExceededCapabilities(t *testing.T) { _, _, err := filterRuntimeCandidatesByOutputTokens("responses", "demo", "text_generate", map[string]any{"input": "hello"}, []store.RuntimeModelCandidate{volcTextCandidate(nil)}) if store.ModelCandidateErrorCode(err) != volcesOutputCapabilityErrorCode { t.Fatalf("expected capability configuration error, got %v", err) } _, _, err = filterRuntimeCandidatesByOutputTokens("chat.completions", "demo", "text_generate", map[string]any{"messages": []any{}, "max_tokens": 32769}, []store.RuntimeModelCandidate{volcTextCandidate(32768)}) if store.ModelCandidateErrorCode(err) != volcesOutputInvalidParameterCode { t.Fatalf("expected invalid_parameter for explicit limit, got %v", err) } } func TestNonVolcesOutputProcessorDoesNotInject(t *testing.T) { candidate := volcTextCandidate(131072) candidate.Provider = "openai" candidate.BaseURL = "https://api.openai.com/v1" chat := preprocessRequestWithLog("chat.completions", map[string]any{"messages": []any{}}, candidate) if _, ok := chat.Body["max_tokens"]; ok { t.Fatalf("non-Volcengine Chat candidate must remain unchanged: %+v", chat.Body) } responses := preprocessRequestWithLog("responses", map[string]any{"input": "hello"}, candidate) if _, ok := responses.Body["max_output_tokens"]; ok { t.Fatalf("non-Volcengine Responses candidate must remain unchanged: %+v", responses.Body) } }