236 lines
6.8 KiB
Go
236 lines
6.8 KiB
Go
// Package registry provides model definitions and lookup helpers for various AI providers.
|
|
// Static model metadata is loaded from the embedded models.json file and can be refreshed from network.
|
|
package registry
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// AntigravityModelConfig captures static antigravity model overrides, including
|
|
// Thinking budget limits and provider max completion tokens.
|
|
type AntigravityModelConfig struct {
|
|
Thinking *ThinkingSupport `json:"thinking,omitempty"`
|
|
MaxCompletionTokens int `json:"max_completion_tokens,omitempty"`
|
|
}
|
|
|
|
// staticModelsJSON mirrors the top-level structure of models.json.
|
|
type staticModelsJSON struct {
|
|
Claude []*ModelInfo `json:"claude"`
|
|
Gemini []*ModelInfo `json:"gemini"`
|
|
Vertex []*ModelInfo `json:"vertex"`
|
|
GeminiCLI []*ModelInfo `json:"gemini-cli"`
|
|
AIStudio []*ModelInfo `json:"aistudio"`
|
|
CodexFree []*ModelInfo `json:"codex-free"`
|
|
CodexTeam []*ModelInfo `json:"codex-team"`
|
|
CodexPlus []*ModelInfo `json:"codex-plus"`
|
|
CodexPro []*ModelInfo `json:"codex-pro"`
|
|
Qwen []*ModelInfo `json:"qwen"`
|
|
IFlow []*ModelInfo `json:"iflow"`
|
|
Kimi []*ModelInfo `json:"kimi"`
|
|
Antigravity map[string]*AntigravityModelConfig `json:"antigravity"`
|
|
}
|
|
|
|
// GetClaudeModels returns the standard Claude model definitions.
|
|
func GetClaudeModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().Claude)
|
|
}
|
|
|
|
// GetGeminiModels returns the standard Gemini model definitions.
|
|
func GetGeminiModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().Gemini)
|
|
}
|
|
|
|
// GetGeminiVertexModels returns Gemini model definitions for Vertex AI.
|
|
func GetGeminiVertexModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().Vertex)
|
|
}
|
|
|
|
// GetGeminiCLIModels returns Gemini model definitions for the Gemini CLI.
|
|
func GetGeminiCLIModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().GeminiCLI)
|
|
}
|
|
|
|
// GetAIStudioModels returns model definitions for AI Studio.
|
|
func GetAIStudioModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().AIStudio)
|
|
}
|
|
|
|
// GetCodexFreeModels returns model definitions for the Codex free plan tier.
|
|
func GetCodexFreeModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().CodexFree)
|
|
}
|
|
|
|
// GetCodexTeamModels returns model definitions for the Codex team plan tier.
|
|
func GetCodexTeamModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().CodexTeam)
|
|
}
|
|
|
|
// GetCodexPlusModels returns model definitions for the Codex plus plan tier.
|
|
func GetCodexPlusModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().CodexPlus)
|
|
}
|
|
|
|
// GetCodexProModels returns model definitions for the Codex pro plan tier.
|
|
func GetCodexProModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().CodexPro)
|
|
}
|
|
|
|
// GetQwenModels returns the standard Qwen model definitions.
|
|
func GetQwenModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().Qwen)
|
|
}
|
|
|
|
// GetIFlowModels returns the standard iFlow model definitions.
|
|
func GetIFlowModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().IFlow)
|
|
}
|
|
|
|
// GetKimiModels returns the standard Kimi (Moonshot AI) model definitions.
|
|
func GetKimiModels() []*ModelInfo {
|
|
return cloneModelInfos(getModels().Kimi)
|
|
}
|
|
|
|
// GetAntigravityModelConfig returns static configuration for antigravity models.
|
|
// Keys use upstream model names returned by the Antigravity models endpoint.
|
|
func GetAntigravityModelConfig() map[string]*AntigravityModelConfig {
|
|
data := getModels()
|
|
if len(data.Antigravity) == 0 {
|
|
return nil
|
|
}
|
|
out := make(map[string]*AntigravityModelConfig, len(data.Antigravity))
|
|
for k, v := range data.Antigravity {
|
|
out[k] = cloneAntigravityModelConfig(v)
|
|
}
|
|
return out
|
|
}
|
|
|
|
func cloneAntigravityModelConfig(cfg *AntigravityModelConfig) *AntigravityModelConfig {
|
|
if cfg == nil {
|
|
return nil
|
|
}
|
|
copyConfig := *cfg
|
|
if cfg.Thinking != nil {
|
|
copyThinking := *cfg.Thinking
|
|
if len(cfg.Thinking.Levels) > 0 {
|
|
copyThinking.Levels = append([]string(nil), cfg.Thinking.Levels...)
|
|
}
|
|
copyConfig.Thinking = ©Thinking
|
|
}
|
|
return ©Config
|
|
}
|
|
|
|
// cloneModelInfos returns a shallow copy of the slice with each element deep-cloned.
|
|
func cloneModelInfos(models []*ModelInfo) []*ModelInfo {
|
|
if len(models) == 0 {
|
|
return nil
|
|
}
|
|
out := make([]*ModelInfo, len(models))
|
|
for i, m := range models {
|
|
out[i] = cloneModelInfo(m)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// GetStaticModelDefinitionsByChannel returns static model definitions for a given channel/provider.
|
|
// It returns nil when the channel is unknown.
|
|
//
|
|
// Supported channels:
|
|
// - claude
|
|
// - gemini
|
|
// - vertex
|
|
// - gemini-cli
|
|
// - aistudio
|
|
// - codex
|
|
// - qwen
|
|
// - iflow
|
|
// - kimi
|
|
// - antigravity (returns static overrides only)
|
|
func GetStaticModelDefinitionsByChannel(channel string) []*ModelInfo {
|
|
key := strings.ToLower(strings.TrimSpace(channel))
|
|
switch key {
|
|
case "claude":
|
|
return GetClaudeModels()
|
|
case "gemini":
|
|
return GetGeminiModels()
|
|
case "vertex":
|
|
return GetGeminiVertexModels()
|
|
case "gemini-cli":
|
|
return GetGeminiCLIModels()
|
|
case "aistudio":
|
|
return GetAIStudioModels()
|
|
case "codex":
|
|
return GetCodexProModels()
|
|
case "qwen":
|
|
return GetQwenModels()
|
|
case "iflow":
|
|
return GetIFlowModels()
|
|
case "kimi":
|
|
return GetKimiModels()
|
|
case "antigravity":
|
|
cfg := GetAntigravityModelConfig()
|
|
if len(cfg) == 0 {
|
|
return nil
|
|
}
|
|
models := make([]*ModelInfo, 0, len(cfg))
|
|
for modelID, entry := range cfg {
|
|
if modelID == "" || entry == nil {
|
|
continue
|
|
}
|
|
models = append(models, &ModelInfo{
|
|
ID: modelID,
|
|
Object: "model",
|
|
OwnedBy: "antigravity",
|
|
Type: "antigravity",
|
|
Thinking: entry.Thinking,
|
|
MaxCompletionTokens: entry.MaxCompletionTokens,
|
|
})
|
|
}
|
|
sort.Slice(models, func(i, j int) bool {
|
|
return strings.ToLower(models[i].ID) < strings.ToLower(models[j].ID)
|
|
})
|
|
return models
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// LookupStaticModelInfo searches all static model definitions for a model by ID.
|
|
// Returns nil if no matching model is found.
|
|
func LookupStaticModelInfo(modelID string) *ModelInfo {
|
|
if modelID == "" {
|
|
return nil
|
|
}
|
|
|
|
data := getModels()
|
|
allModels := [][]*ModelInfo{
|
|
data.Claude,
|
|
data.Gemini,
|
|
data.Vertex,
|
|
data.GeminiCLI,
|
|
data.AIStudio,
|
|
data.CodexPro,
|
|
data.Qwen,
|
|
data.IFlow,
|
|
data.Kimi,
|
|
}
|
|
for _, models := range allModels {
|
|
for _, m := range models {
|
|
if m != nil && m.ID == modelID {
|
|
return cloneModelInfo(m)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check Antigravity static config
|
|
if cfg := cloneAntigravityModelConfig(data.Antigravity[modelID]); cfg != nil {
|
|
return &ModelInfo{
|
|
ID: modelID,
|
|
Thinking: cfg.Thinking,
|
|
MaxCompletionTokens: cfg.MaxCompletionTokens,
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|