|
1 | 1 | // Package registry provides model definitions and lookup helpers for various AI providers. |
2 | | -// Static model metadata is stored in model_definitions_static_data.go. |
| 2 | +// Static model metadata is loaded from the embedded models.json file and can be refreshed from network. |
3 | 3 | package registry |
4 | 4 |
|
5 | 5 | import ( |
6 | 6 | "sort" |
7 | 7 | "strings" |
8 | 8 | ) |
9 | 9 |
|
| 10 | +// AntigravityModelConfig captures static antigravity model overrides, including |
| 11 | +// Thinking budget limits and provider max completion tokens. |
| 12 | +type AntigravityModelConfig struct { |
| 13 | + Thinking *ThinkingSupport `json:"thinking,omitempty"` |
| 14 | + MaxCompletionTokens int `json:"max_completion_tokens,omitempty"` |
| 15 | +} |
| 16 | + |
| 17 | +// staticModelsJSON mirrors the top-level structure of models.json. |
| 18 | +type staticModelsJSON struct { |
| 19 | + Claude []*ModelInfo `json:"claude"` |
| 20 | + Gemini []*ModelInfo `json:"gemini"` |
| 21 | + Vertex []*ModelInfo `json:"vertex"` |
| 22 | + GeminiCLI []*ModelInfo `json:"gemini-cli"` |
| 23 | + AIStudio []*ModelInfo `json:"aistudio"` |
| 24 | + CodexFree []*ModelInfo `json:"codex-free"` |
| 25 | + CodexTeam []*ModelInfo `json:"codex-team"` |
| 26 | + CodexPlus []*ModelInfo `json:"codex-plus"` |
| 27 | + CodexPro []*ModelInfo `json:"codex-pro"` |
| 28 | + Qwen []*ModelInfo `json:"qwen"` |
| 29 | + IFlow []*ModelInfo `json:"iflow"` |
| 30 | + Kimi []*ModelInfo `json:"kimi"` |
| 31 | + Antigravity map[string]*AntigravityModelConfig `json:"antigravity"` |
| 32 | +} |
| 33 | + |
| 34 | +// GetClaudeModels returns the standard Claude model definitions. |
| 35 | +func GetClaudeModels() []*ModelInfo { |
| 36 | + return cloneModelInfos(getModels().Claude) |
| 37 | +} |
| 38 | + |
| 39 | +// GetGeminiModels returns the standard Gemini model definitions. |
| 40 | +func GetGeminiModels() []*ModelInfo { |
| 41 | + return cloneModelInfos(getModels().Gemini) |
| 42 | +} |
| 43 | + |
| 44 | +// GetGeminiVertexModels returns Gemini model definitions for Vertex AI. |
| 45 | +func GetGeminiVertexModels() []*ModelInfo { |
| 46 | + return cloneModelInfos(getModels().Vertex) |
| 47 | +} |
| 48 | + |
| 49 | +// GetGeminiCLIModels returns Gemini model definitions for the Gemini CLI. |
| 50 | +func GetGeminiCLIModels() []*ModelInfo { |
| 51 | + return cloneModelInfos(getModels().GeminiCLI) |
| 52 | +} |
| 53 | + |
| 54 | +// GetAIStudioModels returns model definitions for AI Studio. |
| 55 | +func GetAIStudioModels() []*ModelInfo { |
| 56 | + return cloneModelInfos(getModels().AIStudio) |
| 57 | +} |
| 58 | + |
| 59 | +// GetCodexFreeModels returns model definitions for the Codex free plan tier. |
| 60 | +func GetCodexFreeModels() []*ModelInfo { |
| 61 | + return cloneModelInfos(getModels().CodexFree) |
| 62 | +} |
| 63 | + |
| 64 | +// GetCodexTeamModels returns model definitions for the Codex team plan tier. |
| 65 | +func GetCodexTeamModels() []*ModelInfo { |
| 66 | + return cloneModelInfos(getModels().CodexTeam) |
| 67 | +} |
| 68 | + |
| 69 | +// GetCodexPlusModels returns model definitions for the Codex plus plan tier. |
| 70 | +func GetCodexPlusModels() []*ModelInfo { |
| 71 | + return cloneModelInfos(getModels().CodexPlus) |
| 72 | +} |
| 73 | + |
| 74 | +// GetCodexProModels returns model definitions for the Codex pro plan tier. |
| 75 | +func GetCodexProModels() []*ModelInfo { |
| 76 | + return cloneModelInfos(getModels().CodexPro) |
| 77 | +} |
| 78 | + |
| 79 | +// GetQwenModels returns the standard Qwen model definitions. |
| 80 | +func GetQwenModels() []*ModelInfo { |
| 81 | + return cloneModelInfos(getModels().Qwen) |
| 82 | +} |
| 83 | + |
| 84 | +// GetIFlowModels returns the standard iFlow model definitions. |
| 85 | +func GetIFlowModels() []*ModelInfo { |
| 86 | + return cloneModelInfos(getModels().IFlow) |
| 87 | +} |
| 88 | + |
| 89 | +// GetKimiModels returns the standard Kimi (Moonshot AI) model definitions. |
| 90 | +func GetKimiModels() []*ModelInfo { |
| 91 | + return cloneModelInfos(getModels().Kimi) |
| 92 | +} |
| 93 | + |
| 94 | +// GetAntigravityModelConfig returns static configuration for antigravity models. |
| 95 | +// Keys use upstream model names returned by the Antigravity models endpoint. |
| 96 | +func GetAntigravityModelConfig() map[string]*AntigravityModelConfig { |
| 97 | + data := getModels() |
| 98 | + if len(data.Antigravity) == 0 { |
| 99 | + return nil |
| 100 | + } |
| 101 | + out := make(map[string]*AntigravityModelConfig, len(data.Antigravity)) |
| 102 | + for k, v := range data.Antigravity { |
| 103 | + out[k] = cloneAntigravityModelConfig(v) |
| 104 | + } |
| 105 | + return out |
| 106 | +} |
| 107 | + |
| 108 | +func cloneAntigravityModelConfig(cfg *AntigravityModelConfig) *AntigravityModelConfig { |
| 109 | + if cfg == nil { |
| 110 | + return nil |
| 111 | + } |
| 112 | + copyConfig := *cfg |
| 113 | + if cfg.Thinking != nil { |
| 114 | + copyThinking := *cfg.Thinking |
| 115 | + if len(cfg.Thinking.Levels) > 0 { |
| 116 | + copyThinking.Levels = append([]string(nil), cfg.Thinking.Levels...) |
| 117 | + } |
| 118 | + copyConfig.Thinking = ©Thinking |
| 119 | + } |
| 120 | + return ©Config |
| 121 | +} |
| 122 | + |
| 123 | +// cloneModelInfos returns a shallow copy of the slice with each element deep-cloned. |
| 124 | +func cloneModelInfos(models []*ModelInfo) []*ModelInfo { |
| 125 | + if len(models) == 0 { |
| 126 | + return nil |
| 127 | + } |
| 128 | + out := make([]*ModelInfo, len(models)) |
| 129 | + for i, m := range models { |
| 130 | + out[i] = cloneModelInfo(m) |
| 131 | + } |
| 132 | + return out |
| 133 | +} |
| 134 | + |
10 | 135 | // GetStaticModelDefinitionsByChannel returns static model definitions for a given channel/provider. |
11 | 136 | // It returns nil when the channel is unknown. |
12 | 137 | // |
@@ -77,27 +202,28 @@ func LookupStaticModelInfo(modelID string) *ModelInfo { |
77 | 202 | return nil |
78 | 203 | } |
79 | 204 |
|
| 205 | + data := getModels() |
80 | 206 | allModels := [][]*ModelInfo{ |
81 | | - GetClaudeModels(), |
82 | | - GetGeminiModels(), |
83 | | - GetGeminiVertexModels(), |
84 | | - GetGeminiCLIModels(), |
85 | | - GetAIStudioModels(), |
86 | | - GetCodexProModels(), |
87 | | - GetQwenModels(), |
88 | | - GetIFlowModels(), |
89 | | - GetKimiModels(), |
| 207 | + data.Claude, |
| 208 | + data.Gemini, |
| 209 | + data.Vertex, |
| 210 | + data.GeminiCLI, |
| 211 | + data.AIStudio, |
| 212 | + data.CodexPro, |
| 213 | + data.Qwen, |
| 214 | + data.IFlow, |
| 215 | + data.Kimi, |
90 | 216 | } |
91 | 217 | for _, models := range allModels { |
92 | 218 | for _, m := range models { |
93 | 219 | if m != nil && m.ID == modelID { |
94 | | - return m |
| 220 | + return cloneModelInfo(m) |
95 | 221 | } |
96 | 222 | } |
97 | 223 | } |
98 | 224 |
|
99 | 225 | // Check Antigravity static config |
100 | | - if cfg := GetAntigravityModelConfig()[modelID]; cfg != nil { |
| 226 | + if cfg := cloneAntigravityModelConfig(data.Antigravity[modelID]); cfg != nil { |
101 | 227 | return &ModelInfo{ |
102 | 228 | ID: modelID, |
103 | 229 | Thinking: cfg.Thinking, |
|
0 commit comments