Fix prevent openrouter provider models from getting cut
This commit is contained in:
parent
26f623ed32
commit
17efd415bb
4 changed files with 62 additions and 7 deletions
|
|
@ -183,7 +183,7 @@ func NewAgentInstance(
|
|||
if fullModel == raw {
|
||||
return ensureProtocol(fullModel), true
|
||||
}
|
||||
_, modelID := providers.ExtractProtocol(fullModel)
|
||||
_, modelID := providers.ExtractProtocol(fullModel, cfg.GetAPIBase())
|
||||
if modelID == raw {
|
||||
return ensureProtocol(fullModel), true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,16 +38,21 @@ func createCodexAuthProvider() (LLMProvider, error) {
|
|||
|
||||
// ExtractProtocol extracts the protocol prefix and model identifier from a model string.
|
||||
// If no prefix is specified, it defaults to "openai".
|
||||
// If the model is from OpenRouter, it returns the model as is.
|
||||
// Examples:
|
||||
// - "openai/gpt-4o" -> ("openai", "gpt-4o")
|
||||
// - "anthropic/claude-sonnet-4.6" -> ("anthropic", "claude-sonnet-4.6")
|
||||
// - "gpt-4o" -> ("openai", "gpt-4o") // default protocol
|
||||
func ExtractProtocol(model string) (protocol, modelID string) {
|
||||
// - "openai/gpt-4o", "https://openrouter.ai/api/v1" -> ("openai", "gpt-4o")
|
||||
// - "anthropic/claude-sonnet-4.6", "https://api.anthropic.com/v1" -> ("anthropic", "claude-sonnet-4.6")
|
||||
// - "gpt-4o", "https://api.openai.com/v1" -> ("openai", "gpt-4o") // default protocol
|
||||
// - "openrouter/gpt-4o", "https://openrouter.ai/api/v1" -> ("openrouter", "openrouter/gpt-4o")
|
||||
func ExtractProtocol(model string, url string) (protocol, modelID string) {
|
||||
model = strings.TrimSpace(model)
|
||||
protocol, modelID, found := strings.Cut(model, "/")
|
||||
if !found {
|
||||
return "openai", model
|
||||
}
|
||||
if strings.Contains(strings.ToLower(url), "openrouter.ai") {
|
||||
return protocol, model
|
||||
}
|
||||
return protocol, modelID
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +69,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
|||
return nil, "", fmt.Errorf("model is required")
|
||||
}
|
||||
|
||||
protocol, modelID := ExtractProtocol(cfg.Model)
|
||||
protocol, modelID := ExtractProtocol(cfg.Model, cfg.APIBase)
|
||||
|
||||
switch protocol {
|
||||
case "openai":
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ func TestExtractProtocol(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
model string
|
||||
apiBase string
|
||||
wantProtocol string
|
||||
wantModelID string
|
||||
}{
|
||||
|
|
@ -64,11 +65,18 @@ func TestExtractProtocol(t *testing.T) {
|
|||
wantProtocol: "nvidia",
|
||||
wantModelID: "meta/llama-3.1-8b",
|
||||
},
|
||||
{
|
||||
name: "open router model",
|
||||
model: "openrouter/llama-3.1-8b",
|
||||
wantProtocol: "openrouter",
|
||||
wantModelID: "openrouter/llama-3.1-8b",
|
||||
apiBase: "https://openrouter.ai/api/v1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
protocol, modelID := ExtractProtocol(tt.model)
|
||||
protocol, modelID := ExtractProtocol(tt.model, tt.apiBase)
|
||||
if protocol != tt.wantProtocol {
|
||||
t.Errorf("ExtractProtocol(%q) protocol = %q, want %q", tt.model, protocol, tt.wantProtocol)
|
||||
}
|
||||
|
|
@ -99,6 +107,27 @@ func TestCreateProviderFromConfig_OpenAI(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreateProviderFromConfig_OpenRouter(t *testing.T) {
|
||||
target := "openai/gpt-4o"
|
||||
cfg := &config.ModelConfig{
|
||||
ModelName: "test-openai",
|
||||
Model: target,
|
||||
APIKey: "test-key",
|
||||
APIBase: "https://openrouter.ai/api/v1",
|
||||
}
|
||||
|
||||
provider, modelID, err := CreateProviderFromConfig(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("CreateProviderFromConfig() error = %v", err)
|
||||
}
|
||||
if provider == nil {
|
||||
t.Fatal("CreateProviderFromConfig() returned nil provider")
|
||||
}
|
||||
if modelID != target {
|
||||
t.Errorf("modelID = %q, want %q", modelID, target)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateProviderFromConfig_DefaultAPIBase(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -523,6 +523,27 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
|||
if got := normalizeModel("vivgrid/auto", "https://api.vivgrid.com/v1"); got != "auto" {
|
||||
t.Fatalf("normalizeModel(vivgrid auto) = %q, want %q", got, "auto")
|
||||
}
|
||||
|
||||
// Bug fix: qwen/qwen3-235b-a22b-2507 sent to openrouter.ai must be preserved in full
|
||||
if got := normalizeModel("qwen/qwen3-235b-a22b-2507", "https://openrouter.ai/api/v1"); got != "qwen/qwen3-235b-a22b-2507" {
|
||||
t.Fatalf("normalizeModel(qwen@openrouter) = %q, want %q", got, "qwen/qwen3-235b-a22b-2507")
|
||||
}
|
||||
// Same prefix, different (native) provider: strip the prefix
|
||||
if got := normalizeModel("qwen/qwen3-235b-a22b-2507", "https://dashscope.aliyuncs.com/compatible-mode/v1"); got != "qwen3-235b-a22b-2507" {
|
||||
t.Fatalf("normalizeModel(qwen@dashscope) = %q, want %q", got, "qwen3-235b-a22b-2507")
|
||||
}
|
||||
// openai/ prefix should be stripped for non-openrouter providers
|
||||
if got := normalizeModel("openai/gpt-4o", "https://api.openai.com/v1"); got != "gpt-4o" {
|
||||
t.Fatalf("normalizeModel(openai) = %q, want %q", got, "gpt-4o")
|
||||
}
|
||||
// anthropic/ prefix should be stripped for non-openrouter providers
|
||||
if got := normalizeModel("anthropic/claude-sonnet-4.6", "https://api.anthropic.com/v1"); got != "claude-sonnet-4.6" {
|
||||
t.Fatalf("normalizeModel(anthropic) = %q, want %q", got, "claude-sonnet-4.6")
|
||||
}
|
||||
// Models with unknown prefix are left unchanged
|
||||
if got := normalizeModel("meta-llama/llama-3.1-8b", "https://openrouter.ai/api/v1"); got != "meta-llama/llama-3.1-8b" {
|
||||
t.Fatalf("normalizeModel(meta-llama@openrouter) = %q, want %q", got, "meta-llama/llama-3.1-8b")
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_RequestTimeoutDefault(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue