|
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 | // |
@@ -35,7 +160,7 @@ func GetStaticModelDefinitionsByChannel(channel string) []*ModelInfo { |
35 | 160 | case "aistudio": |
36 | 161 | return GetAIStudioModels() |
37 | 162 | case "codex": |
38 | | -return GetOpenAIModels() |
| 163 | +return GetCodexProModels() |
39 | 164 | case "qwen": |
40 | 165 | return GetQwenModels() |
41 | 166 | case "iflow": |
@@ -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 | | -GetOpenAIModels(), |
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