This commit is contained in:
Seif Ghazi 2026-01-04 15:04:34 -05:00
parent 8d1f9d2277
commit fd480c67ef
No known key found for this signature in database
GPG key ID: 4519A4B1EEC1494E
3 changed files with 26 additions and 86 deletions

View file

@ -130,29 +130,12 @@ func (h *Handler) Messages(w http.ResponseWriter, r *http.Request) {
}
func (h *Handler) Models(w http.ResponseWriter, r *http.Request) {
// This proxy uses pattern-based routing and supports any model dynamically.
// Returning an empty list since the actual supported models depend on the
// upstream providers (Anthropic, OpenAI) and their current offerings.
response := &model.ModelsResponse{
Object: "list",
Data: []model.ModelInfo{
{
ID: "claude-3-sonnet-20240229",
Object: "model",
Created: 1677610602,
OwnedBy: "anthropic",
},
{
ID: "claude-3-opus-20240229",
Object: "model",
Created: 1677610602,
OwnedBy: "anthropic",
},
{
ID: "claude-3-haiku-20240307",
Object: "model",
Created: 1677610602,
OwnedBy: "anthropic",
},
},
Data: []model.ModelInfo{},
}
writeJSONResponse(w, response)

View file

@ -25,10 +25,24 @@ type ModelRouter struct {
providers map[string]provider.Provider
subagentMappings map[string]string // agentName -> targetModel
customAgentPrompts map[string]SubagentDefinition // promptHash -> definition
modelProviderMap map[string]string // model -> provider mapping
logger *log.Logger
}
// providerPattern maps model name prefixes to their provider
type providerPattern struct {
prefix string
provider string
}
// providerPatterns defines how to route models to providers based on name prefix.
// Order matters - first match wins.
var providerPatterns = []providerPattern{
{"gpt-", "openai"},
{"o1", "openai"}, // o1, o1-mini, o1-pro
{"o3", "openai"}, // o3, o3-mini, o3-pro
{"claude-", "anthropic"},
}
type SubagentDefinition struct {
Name string
TargetModel string
@ -42,7 +56,6 @@ func NewModelRouter(cfg *config.Config, providers map[string]provider.Provider,
providers: providers,
subagentMappings: cfg.Subagents.Mappings,
customAgentPrompts: make(map[string]SubagentDefinition),
modelProviderMap: initializeModelProviderMap(),
logger: logger,
}
@ -58,63 +71,6 @@ func NewModelRouter(cfg *config.Config, providers map[string]provider.Provider,
return router
}
// initializeModelProviderMap creates a mapping of model names to their providers
func initializeModelProviderMap() map[string]string {
modelMap := make(map[string]string)
// OpenAI models
openaiModels := []string{
// GPT-5 family
"gpt-5", "gpt-5-mini", "gpt-5-nano",
// GPT-4.1 family
"gpt-4.1", "gpt-4.1-2025-04-14",
"gpt-4.1-mini", "gpt-4.1-mini-2025-04-14",
"gpt-4.1-nano", "gpt-4.1-nano-2025-04-14",
// GPT-4.5
"gpt-4.5-preview", "gpt-4.5-preview-2025-02-27",
// GPT-4o variants
"gpt-4o", "gpt-4o-2024-08-06",
"gpt-4o-mini", "gpt-4o-mini-2024-07-18",
// GPT-3.5 variants
"gpt-3.5-turbo", "gpt-3.5-turbo-0125", "gpt-3.5-turbo-1106", "gpt-3.5-turbo-instruct",
// O1 series
"o1", "o1-2024-12-17",
"o1-pro", "o1-pro-2025-03-19",
"o1-mini", "o1-mini-2024-09-12",
// O3 series
"o3-pro", "o3-pro-2025-06-10",
"o3", "o3-2025-04-16",
"o3-mini", "o3-mini-2025-01-31",
}
for _, model := range openaiModels {
modelMap[model] = "openai"
}
// Anthropic models
anthropicModels := []string{
"claude-opus-4-1-20250805",
"claude-opus-4-20250514",
"claude-sonnet-4-20250514",
"claude-sonnet-4-5-20250929",
"claude-opus-4-5-20251101",
"claude-3-7-sonnet-20250219",
"claude-3-5-haiku-20241022",
}
for _, model := range anthropicModels {
modelMap[model] = "anthropic"
}
return modelMap
}
// extractStaticPrompt extracts the portion before "Notes:" if it exists
func (r *ModelRouter) extractStaticPrompt(systemPrompt string) string {
// Find the "Notes:" section
@ -265,11 +221,12 @@ func (r *ModelRouter) hashString(s string) string {
}
func (r *ModelRouter) getProviderNameForModel(model string) string {
if provider, exists := r.modelProviderMap[model]; exists {
return provider
for _, pattern := range providerPatterns {
if strings.HasPrefix(model, pattern.prefix) {
return pattern.provider
}
// Default to anthropic
r.logger.Printf("⚠️ Model '%s' doesn't match any known patterns, defaulting to anthropic", model)
}
// Default to anthropic (this is an Anthropic proxy after all)
r.logger.Printf(" Model '%s' has no matching pattern, defaulting to anthropic", model)
return "anthropic"
}