diff --git a/llm/oai/oai.go b/llm/oai/oai.go index 4349630d766a25e6b5c9aabac6b7c4b39162917b..02b46f1d33a387346d79b530c1789c89be3fe89e 100644 --- a/llm/oai/oai.go +++ b/llm/oai/oai.go @@ -250,6 +250,13 @@ var ( APIKeyEnv: FireworksAPIKeyEnv, } + GLM47Fireworks = Model{ + UserName: "glm-4.7-fireworks", + ModelName: "accounts/fireworks/models/glm-4p7", + URL: FireworksURL, + APIKeyEnv: FireworksAPIKeyEnv, + } + GPTOSS20B = Model{ UserName: "gpt-oss-20b", ModelName: "accounts/fireworks/models/gpt-oss-20b", @@ -359,6 +366,7 @@ var ModelsRegistry = []Model{ Qwen3CoderCerebras, ZaiGLM45CoderFireworks, GLM4P6Fireworks, + GLM47Fireworks, GPTOSS120B, GPTOSS20B, // Skaband-supported models diff --git a/models/models.go b/models/models.go index 9eb04ccb0fed442554c541cd76816e8cef75be32..bb572e9868b00366e3476c8c59405be0a9de27c5 100644 --- a/models/models.go +++ b/models/models.go @@ -48,9 +48,15 @@ type Model struct { // Description is a human-readable description Description string + // Tags is a comma-separated list of tags (e.g., "slug") + Tags string + // RequiredEnvVars are the environment variables required for this model RequiredEnvVars []string + // GatewayEnabled indicates whether this model is available when using a gateway + GatewayEnabled bool + // Factory creates an llm.Service instance for this model Factory func(config *Config, httpc *http.Client) (llm.Service, error) } @@ -155,6 +161,7 @@ func All() []Model { Provider: ProviderAnthropic, Description: "Claude Opus 4.5 (default)", RequiredEnvVars: []string{"ANTHROPIC_API_KEY"}, + GatewayEnabled: true, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { if config.AnthropicAPIKey == "" { return nil, fmt.Errorf("claude-opus-4.5 requires ANTHROPIC_API_KEY") @@ -167,31 +174,50 @@ func All() []Model { }, }, { - ID: "qwen3-coder-fireworks", - Provider: ProviderFireworks, - Description: "Qwen3 Coder 480B on Fireworks", - RequiredEnvVars: []string{"FIREWORKS_API_KEY"}, + ID: "claude-sonnet-4.5", + Provider: ProviderAnthropic, + Description: "Claude Sonnet 4.5", + RequiredEnvVars: []string{"ANTHROPIC_API_KEY"}, + GatewayEnabled: true, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { - if config.FireworksAPIKey == "" { - return nil, fmt.Errorf("qwen3-coder-fireworks requires FIREWORKS_API_KEY") + if config.AnthropicAPIKey == "" { + return nil, fmt.Errorf("claude-sonnet-4.5 requires ANTHROPIC_API_KEY") } - svc := &oai.Service{Model: oai.Qwen3CoderFireworks, APIKey: config.FireworksAPIKey, HTTPC: httpc} - if url := config.getFireworksURL(); url != "" { - svc.ModelURL = url + svc := &ant.Service{APIKey: config.AnthropicAPIKey, Model: ant.Claude45Sonnet, HTTPC: httpc} + if url := config.getAnthropicURL(); url != "" { + svc.URL = url } return svc, nil }, }, { - ID: "glm-4p6-fireworks", + ID: "claude-haiku-4.5", + Provider: ProviderAnthropic, + Description: "Claude Haiku 4.5", + RequiredEnvVars: []string{"ANTHROPIC_API_KEY"}, + GatewayEnabled: true, + Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { + if config.AnthropicAPIKey == "" { + return nil, fmt.Errorf("claude-haiku-4.5 requires ANTHROPIC_API_KEY") + } + svc := &ant.Service{APIKey: config.AnthropicAPIKey, Model: ant.Claude45Haiku, HTTPC: httpc} + if url := config.getAnthropicURL(); url != "" { + svc.URL = url + } + return svc, nil + }, + }, + { + ID: "glm-4.7-fireworks", Provider: ProviderFireworks, - Description: "GLM-4P6 on Fireworks", + Description: "GLM-4.7 on Fireworks", RequiredEnvVars: []string{"FIREWORKS_API_KEY"}, + GatewayEnabled: true, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { if config.FireworksAPIKey == "" { - return nil, fmt.Errorf("glm-4p6-fireworks requires FIREWORKS_API_KEY") + return nil, fmt.Errorf("glm-4.7-fireworks requires FIREWORKS_API_KEY") } - svc := &oai.Service{Model: oai.GLM4P6Fireworks, APIKey: config.FireworksAPIKey, HTTPC: httpc} + svc := &oai.Service{Model: oai.GLM47Fireworks, APIKey: config.FireworksAPIKey, HTTPC: httpc} if url := config.getFireworksURL(); url != "" { svc.ModelURL = url } @@ -203,6 +229,7 @@ func All() []Model { Provider: ProviderOpenAI, Description: "GPT-5.2 Codex", RequiredEnvVars: []string{"OPENAI_API_KEY"}, + GatewayEnabled: true, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { if config.OpenAIAPIKey == "" { return nil, fmt.Errorf("gpt-5.2-codex requires OPENAI_API_KEY") @@ -215,33 +242,35 @@ func All() []Model { }, }, { - ID: "claude-sonnet-4.5", - Provider: ProviderAnthropic, - Description: "Claude Sonnet 4.5", - RequiredEnvVars: []string{"ANTHROPIC_API_KEY"}, + ID: "qwen3-coder-fireworks", + Provider: ProviderFireworks, + Description: "Qwen3 Coder 480B on Fireworks", + Tags: "slug", + RequiredEnvVars: []string{"FIREWORKS_API_KEY"}, + GatewayEnabled: true, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { - if config.AnthropicAPIKey == "" { - return nil, fmt.Errorf("claude-sonnet-4.5 requires ANTHROPIC_API_KEY") + if config.FireworksAPIKey == "" { + return nil, fmt.Errorf("qwen3-coder-fireworks requires FIREWORKS_API_KEY") } - svc := &ant.Service{APIKey: config.AnthropicAPIKey, Model: ant.Claude45Sonnet, HTTPC: httpc} - if url := config.getAnthropicURL(); url != "" { - svc.URL = url + svc := &oai.Service{Model: oai.Qwen3CoderFireworks, APIKey: config.FireworksAPIKey, HTTPC: httpc} + if url := config.getFireworksURL(); url != "" { + svc.ModelURL = url } return svc, nil }, }, { - ID: "claude-haiku-4.5", - Provider: ProviderAnthropic, - Description: "Claude Haiku 4.5", - RequiredEnvVars: []string{"ANTHROPIC_API_KEY"}, + ID: "glm-4p6-fireworks", + Provider: ProviderFireworks, + Description: "GLM-4P6 on Fireworks", + RequiredEnvVars: []string{"FIREWORKS_API_KEY"}, Factory: func(config *Config, httpc *http.Client) (llm.Service, error) { - if config.AnthropicAPIKey == "" { - return nil, fmt.Errorf("claude-haiku-4.5 requires ANTHROPIC_API_KEY") + if config.FireworksAPIKey == "" { + return nil, fmt.Errorf("glm-4p6-fireworks requires FIREWORKS_API_KEY") } - svc := &ant.Service{APIKey: config.AnthropicAPIKey, Model: ant.Claude45Haiku, HTTPC: httpc} - if url := config.getAnthropicURL(); url != "" { - svc.URL = url + svc := &oai.Service{Model: oai.GLM4P6Fireworks, APIKey: config.FireworksAPIKey, HTTPC: httpc} + if url := config.getFireworksURL(); url != "" { + svc.ModelURL = url } return svc, nil }, @@ -500,7 +529,12 @@ func NewManager(cfg *Config) (*Manager, error) { manager.cfg = cfg // Load built-in models first + useGateway := cfg.Gateway != "" for _, model := range All() { + // Skip non-gateway-enabled models when using a gateway + if useGateway && !model.GatewayEnabled { + continue + } svc, err := model.Factory(cfg, httpc) if err != nil { // Model not available (e.g., missing API key) - skip it @@ -513,6 +547,7 @@ func NewManager(cfg *Config) (*Manager, error) { modelID: model.ID, source: model.Source(cfg), displayName: model.ID, // built-in models use ID as display name + tags: model.Tags, } manager.modelOrder = append(manager.modelOrder, model.ID) }