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 {
|
if fullModel == raw {
|
||||||
return ensureProtocol(fullModel), true
|
return ensureProtocol(fullModel), true
|
||||||
}
|
}
|
||||||
_, modelID := providers.ExtractProtocol(fullModel)
|
_, modelID := providers.ExtractProtocol(fullModel, cfg.GetAPIBase())
|
||||||
if modelID == raw {
|
if modelID == raw {
|
||||||
return ensureProtocol(fullModel), true
|
return ensureProtocol(fullModel), true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,16 +38,21 @@ func createCodexAuthProvider() (LLMProvider, error) {
|
||||||
|
|
||||||
// ExtractProtocol extracts the protocol prefix and model identifier from a model string.
|
// ExtractProtocol extracts the protocol prefix and model identifier from a model string.
|
||||||
// If no prefix is specified, it defaults to "openai".
|
// If no prefix is specified, it defaults to "openai".
|
||||||
|
// If the model is from OpenRouter, it returns the model as is.
|
||||||
// Examples:
|
// Examples:
|
||||||
// - "openai/gpt-4o" -> ("openai", "gpt-4o")
|
// - "openai/gpt-4o", "https://openrouter.ai/api/v1" -> ("openai", "gpt-4o")
|
||||||
// - "anthropic/claude-sonnet-4.6" -> ("anthropic", "claude-sonnet-4.6")
|
// - "anthropic/claude-sonnet-4.6", "https://api.anthropic.com/v1" -> ("anthropic", "claude-sonnet-4.6")
|
||||||
// - "gpt-4o" -> ("openai", "gpt-4o") // default protocol
|
// - "gpt-4o", "https://api.openai.com/v1" -> ("openai", "gpt-4o") // default protocol
|
||||||
func ExtractProtocol(model string) (protocol, modelID string) {
|
// - "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)
|
model = strings.TrimSpace(model)
|
||||||
protocol, modelID, found := strings.Cut(model, "/")
|
protocol, modelID, found := strings.Cut(model, "/")
|
||||||
if !found {
|
if !found {
|
||||||
return "openai", model
|
return "openai", model
|
||||||
}
|
}
|
||||||
|
if strings.Contains(strings.ToLower(url), "openrouter.ai") {
|
||||||
|
return protocol, model
|
||||||
|
}
|
||||||
return protocol, modelID
|
return protocol, modelID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +69,7 @@ func CreateProviderFromConfig(cfg *config.ModelConfig) (LLMProvider, string, err
|
||||||
return nil, "", fmt.Errorf("model is required")
|
return nil, "", fmt.Errorf("model is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol, modelID := ExtractProtocol(cfg.Model)
|
protocol, modelID := ExtractProtocol(cfg.Model, cfg.APIBase)
|
||||||
|
|
||||||
switch protocol {
|
switch protocol {
|
||||||
case "openai":
|
case "openai":
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ func TestExtractProtocol(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
model string
|
model string
|
||||||
|
apiBase string
|
||||||
wantProtocol string
|
wantProtocol string
|
||||||
wantModelID string
|
wantModelID string
|
||||||
}{
|
}{
|
||||||
|
|
@ -64,11 +65,18 @@ func TestExtractProtocol(t *testing.T) {
|
||||||
wantProtocol: "nvidia",
|
wantProtocol: "nvidia",
|
||||||
wantModelID: "meta/llama-3.1-8b",
|
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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
protocol, modelID := ExtractProtocol(tt.model)
|
protocol, modelID := ExtractProtocol(tt.model, tt.apiBase)
|
||||||
if protocol != tt.wantProtocol {
|
if protocol != tt.wantProtocol {
|
||||||
t.Errorf("ExtractProtocol(%q) protocol = %q, want %q", tt.model, 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) {
|
func TestCreateProviderFromConfig_DefaultAPIBase(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,27 @@ func TestNormalizeModel_UsesAPIBase(t *testing.T) {
|
||||||
if got := normalizeModel("vivgrid/auto", "https://api.vivgrid.com/v1"); got != "auto" {
|
if got := normalizeModel("vivgrid/auto", "https://api.vivgrid.com/v1"); got != "auto" {
|
||||||
t.Fatalf("normalizeModel(vivgrid auto) = %q, want %q", 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) {
|
func TestProvider_RequestTimeoutDefault(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue