package llm import ( "testing" "github.com/sundynix/sundynix-shared/contract" ) func TestNormalizeBaseURL(t *testing.T) { cases := []struct { provider, in, want string }{ {"ollama", "http://localhost:11434", "http://localhost:11434/v1"}, // 补 /v1 {"ollama", "http://localhost:11434/", "http://localhost:11434/v1"}, // 去尾斜杠再补 {"ollama", "http://localhost:11434/v1", "http://localhost:11434/v1"}, // 已有不重复补 {"vllm", "http://gpu-node:8000", "http://gpu-node:8000/v1"}, {"vllm", "http://gpu-node:8000/v1", "http://gpu-node:8000/v1"}, {"openai-compatible", "https://api.deepseek.com", "https://api.deepseek.com"}, // 在线不动 {"", "https://api.deepseek.com", "https://api.deepseek.com"}, } for _, c := range cases { got := normalizeBaseURL(&contract.ModelConfig{Provider: c.provider, BaseURL: c.in}) if got != c.want { t.Errorf("normalizeBaseURL(%s,%q)=%q want %q", c.provider, c.in, got, c.want) } } } func TestAPIKeyOrPlaceholder(t *testing.T) { // 本地后端缺 key → 占位(openai 客户端要求非空)。 if got := apiKeyOrPlaceholder(&contract.ModelConfig{Provider: "ollama"}); got != "ollama" { t.Errorf("ollama 缺 key 应占位 'ollama', got %q", got) } if got := apiKeyOrPlaceholder(&contract.ModelConfig{Provider: "vllm"}); got != "EMPTY" { t.Errorf("vllm 缺 key 应占位 'EMPTY', got %q", got) } // 显式 key 一律尊重(vLLM 带 --api-key 启动的情况)。 if got := apiKeyOrPlaceholder(&contract.ModelConfig{Provider: "vllm", APIKey: "sk-real"}); got != "sk-real" { t.Errorf("显式 key 应原样, got %q", got) } // 在线 provider 缺 key 不占位(保持空,由 Ready/调用方处理)。 if got := apiKeyOrPlaceholder(&contract.ModelConfig{Provider: "openai-compatible"}); got != "" { t.Errorf("在线 provider 缺 key 不应占位, got %q", got) } }