feat: Add models lister for selected provider
This commit is contained in:
parent
24d67af543
commit
c72e810157
3 changed files with 318 additions and 4 deletions
273
pkg/config/models.go
Normal file
273
pkg/config/models.go
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
package config
|
||||
|
||||
type ModelInfo struct {
|
||||
Name string
|
||||
ID string
|
||||
Description string
|
||||
ContextSize int
|
||||
InputCost float64
|
||||
OutputCost float64
|
||||
}
|
||||
|
||||
type ProviderModels struct {
|
||||
Provider string
|
||||
Models []ModelInfo
|
||||
AuthMethod string
|
||||
}
|
||||
|
||||
var ProviderModelsList = []ProviderModels{
|
||||
{
|
||||
Provider: "openai",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "gpt-5.2", Name: "GPT-5.2", ContextSize: 128000},
|
||||
{ID: "gpt-5.2-chat-20251211", Name: "GPT-5.2 Chat", ContextSize: 128000},
|
||||
{ID: "gpt-5.2-pro-20251211", Name: "GPT-5.2 Pro", ContextSize: 128000},
|
||||
{ID: "gpt-5.2-codex-20260114", Name: "GPT-5.2 Codex", ContextSize: 128000},
|
||||
{ID: "gpt-5.1-codex-max-20251204", Name: "GPT-5.1 Codex Max", ContextSize: 128000},
|
||||
{ID: "gpt-5.1-20251113", Name: "GPT-5.1", ContextSize: 128000},
|
||||
{ID: "gpt-5-pro-2025-10-06", Name: "GPT-5 Pro", ContextSize: 128000},
|
||||
{ID: "gpt-5-2025-08-07", Name: "GPT-5", ContextSize: 128000},
|
||||
{ID: "gpt-4o-2024-11-20", Name: "GPT-4o (Nov 2024)", ContextSize: 128000},
|
||||
{ID: "gpt-4o", Name: "GPT-4o", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "anthropic",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "claude-4.6-sonnet-20260217", Name: "Claude 4.6 Sonnet", ContextSize: 200000},
|
||||
{ID: "claude-4.6-opus-20260205", Name: "Claude 4.6 Opus", ContextSize: 200000},
|
||||
{ID: "claude-4.5-opus-20251124", Name: "Claude 4.5 Opus", ContextSize: 200000},
|
||||
{ID: "claude-4.5-sonnet-20250929", Name: "Claude 4.5 Sonnet", ContextSize: 200000},
|
||||
{ID: "claude-4.5-haiku-20251001", Name: "Claude 4.5 Haiku", ContextSize: 200000},
|
||||
{ID: "claude-4.1-opus-20250805", Name: "Claude 4.1 Opus", ContextSize: 200000},
|
||||
{ID: "claude-4-sonnet-20250522", Name: "Claude 4 Sonnet", ContextSize: 200000},
|
||||
{ID: "claude-4-opus-20250522", Name: "Claude 4 Opus", ContextSize: 200000},
|
||||
{ID: "claude-3-7-sonnet-20250219", Name: "Claude 3.7 Sonnet", ContextSize: 200000},
|
||||
{ID: "claude-3.5-sonnet", Name: "Claude 3.5 Sonnet", ContextSize: 200000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "antigravity",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "gemini-2.5-flash", Name: "Gemini 2.5 Flash", ContextSize: 1000000},
|
||||
{ID: "gemini-2.5-pro", Name: "Gemini 2.5 Pro", ContextSize: 200000},
|
||||
{ID: "gemini-2.5-pro-preview-06-05", Name: "Gemini 2.5 Pro (Preview)", ContextSize: 200000},
|
||||
{ID: "gemini-2.5-flash-lite", Name: "Gemini 2.5 Flash Lite", ContextSize: 1000000},
|
||||
{ID: "gemini-2.5-flash-lite-preview-09-2025", Name: "Gemini 2.5 Flash Lite (Sep 2025)", ContextSize: 1000000},
|
||||
{ID: "gemini-2.5-flash-image", Name: "Gemini 2.5 Flash (Image)", ContextSize: 1000000},
|
||||
{ID: "gemini-2.0-flash-001", Name: "Gemini 2.0 Flash", ContextSize: 1000000},
|
||||
{ID: "gemini-2.0-flash-lite-001", Name: "Gemini 2.0 Flash Lite", ContextSize: 1000000},
|
||||
{ID: "gemma-3-27b-it", Name: "Gemma 3 27B", ContextSize: 128000},
|
||||
{ID: "gemma-3-12b-it", Name: "Gemma 3 12B", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "gemini",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "gemini-2.5-flash", Name: "Gemini 2.5 Flash", ContextSize: 1000000},
|
||||
{ID: "gemini-2.5-pro", Name: "Gemini 2.5 Pro", ContextSize: 200000},
|
||||
{ID: "gemini-2.5-pro-preview-06-05", Name: "Gemini 2.5 Pro (Preview)", ContextSize: 200000},
|
||||
{ID: "gemini-2.5-flash-lite", Name: "Gemini 2.5 Flash Lite", ContextSize: 1000000},
|
||||
{ID: "gemini-2.0-flash-001", Name: "Gemini 2.0 Flash", ContextSize: 1000000},
|
||||
{ID: "gemini-2.0-flash-lite-001", Name: "Gemini 2.0 Flash Lite", ContextSize: 1000000},
|
||||
{ID: "gemma-3-27b-it", Name: "Gemma 3 27B", ContextSize: 128000},
|
||||
{ID: "gemma-3-12b-it", Name: "Gemma 3 12B", ContextSize: 128000},
|
||||
{ID: "gemma-2-27b-it", Name: "Gemma 2 27B", ContextSize: 128000},
|
||||
{ID: "gemini-1.5-pro", Name: "Gemini 1.5 Pro", ContextSize: 200000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "deepseek",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "deepseek-v3.2-speciale-20251201", Name: "DeepSeek V3.2 Speciale", ContextSize: 64000},
|
||||
{ID: "deepseek-v3.2-20251201", Name: "DeepSeek V3.2", ContextSize: 64000},
|
||||
{ID: "deepseek-v3.1-terminus", Name: "DeepSeek V3.1 Terminus", ContextSize: 64000},
|
||||
{ID: "deepseek-chat-v3.1", Name: "DeepSeek V3.1", ContextSize: 64000},
|
||||
{ID: "deepseek-r1-0528", Name: "DeepSeek R1 (May 2025)", ContextSize: 64000},
|
||||
{ID: "deepseek-r1", Name: "DeepSeek R1", ContextSize: 64000},
|
||||
{ID: "deepseek-r1-distill-qwen-32b", Name: "DeepSeek R1 Distill Qwen 32B", ContextSize: 32000},
|
||||
{ID: "deepseek-r1-distill-llama-70b", Name: "DeepSeek R1 Distill Llama 70B", ContextSize: 128000},
|
||||
{ID: "deepseek-chat-v3-0324", Name: "DeepSeek V3 (Mar 2024)", ContextSize: 64000},
|
||||
{ID: "deepseek-chat", Name: "DeepSeek Chat", ContextSize: 64000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "moonshot",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "kimi-k2.5-0127", Name: "Kimi k2.5", ContextSize: 128000},
|
||||
{ID: "kimi-k2-thinking-20251106", Name: "Kimi k2 Thinking", ContextSize: 128000},
|
||||
{ID: "kimi-k2-0905", Name: "Kimi k2 (Sep 2024)", ContextSize: 128000},
|
||||
{ID: "kimi-k2", Name: "Kimi k2", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "qwen",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "qwen3-next-80b-a3b-instruct-2509", Name: "Qwen 3 Next 80B", ContextSize: 128000},
|
||||
{ID: "qwen3-next-80b-a3b-thinking-2509", Name: "Qwen 3 Next 80B Thinking", ContextSize: 128000},
|
||||
{ID: "qwen3-max-thinking-20260123", Name: "Qwen 3 Max Thinking", ContextSize: 128000},
|
||||
{ID: "qwen-plus-2025-07-28", Name: "Qwen Plus (Jul 2025)", ContextSize: 32000},
|
||||
{ID: "qwen3-235b-a22b-07-25", Name: "Qwen 3 235B (Jul 2025)", ContextSize: 128000},
|
||||
{ID: "qwen3-coder-480b-a35b-07-25", Name: "Qwen 3 Coder 480B", ContextSize: 128000},
|
||||
{ID: "qwen3-max", Name: "Qwen 3 Max", ContextSize: 128000},
|
||||
{ID: "qwen3-235b-a22b-thinking-2507", Name: "Qwen 3 235B Thinking", ContextSize: 128000},
|
||||
{ID: "qwen-plus-2025-01-25", Name: "Qwen Plus", ContextSize: 32000},
|
||||
{ID: "qwen-max-2025-01-25", Name: "Qwen Max", ContextSize: 32000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "mistral",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "mistral-large-2512", Name: "Mistral Large", ContextSize: 128000},
|
||||
{ID: "devstral-2512", Name: "Devstral", ContextSize: 128000},
|
||||
{ID: "codestral-2508", Name: "Codestral", ContextSize: 256000},
|
||||
{ID: "mistral-saba-2502", Name: "Mistral Saba", ContextSize: 128000},
|
||||
{ID: "mistral-small-3.2-24b-instruct-2506", Name: "Mistral Small 3.2", ContextSize: 24000},
|
||||
{ID: "mistral-small-creative-20251216", Name: "Mistral Small Creative", ContextSize: 24000},
|
||||
{ID: "mistral-large-2411", Name: "Mistral Large (Nov 2024)", ContextSize: 128000},
|
||||
{ID: "ministral-14b-2512", Name: "Ministral 14B", ContextSize: 128000},
|
||||
{ID: "ministral-8b-2512", Name: "Ministral 8B", ContextSize: 128000},
|
||||
{ID: "pixtral-large-2411", Name: "Pixtral Large", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "ollama",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "llama3.3", Name: "Llama 3.3", ContextSize: 128000},
|
||||
{ID: "llama3.1", Name: "Llama 3.1", ContextSize: 128000},
|
||||
{ID: "qwen2.5", Name: "Qwen 2.5", ContextSize: 32768},
|
||||
{ID: "phi4", Name: "Phi 4", ContextSize: 8192},
|
||||
{ID: "mistral", Name: "Mistral", ContextSize: 8192},
|
||||
{ID: "codellama", Name: "Code Llama", ContextSize: 16384},
|
||||
{ID: "llama3", Name: "Llama 3", ContextSize: 8192},
|
||||
{ID: "gemma2", Name: "Gemma 2", ContextSize: 8192},
|
||||
{ID: "granite3.1", Name: "Granite 3.1", ContextSize: 128000},
|
||||
{ID: "deepseek-llm", Name: "DeepSeek LLM", ContextSize: 16384},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "groq",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "llama-3.3-70b-versatile", Name: "Llama 3.3 70B", ContextSize: 8192},
|
||||
{ID: "llama-3.2-90b-versatile", Name: "Llama 3.2 90B", ContextSize: 8192},
|
||||
{ID: "mixtral-8x22b-32768", Name: "Mixtral 8x22B", ContextSize: 32768},
|
||||
{ID: "deepseek-r1-distill-llama-70b", Name: "DeepSeek R1 Distill Llama 70B", ContextSize: 8192},
|
||||
{ID: "llama-3.1-70b-versatile", Name: "Llama 3.1 70B", ContextSize: 8192},
|
||||
{ID: "gemma2-9b-it", Name: "Gemma 2 9B", ContextSize: 8192},
|
||||
{ID: "qwen-2.5-72b-instruct", Name: "Qwen 2.5 72B", ContextSize: 8192},
|
||||
{ID: "llama3-70b-8192", Name: "Llama 3 70B", ContextSize: 8192},
|
||||
{ID: "llama-3.1-8b-instant", Name: "Llama 3.1 8B", ContextSize: 8192},
|
||||
{ID: "mixtral-8x7b-32768", Name: "Mixtral 8x7B", ContextSize: 32768},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "openrouter",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "openai/gpt-4o", Name: "GPT-4o (OpenRouter)", ContextSize: 128000},
|
||||
{ID: "openai/gpt-4o-mini", Name: "GPT-4o Mini (OpenRouter)", ContextSize: 128000},
|
||||
{ID: "anthropic/claude-3.5-sonnet", Name: "Claude 3.5 Sonnet (OpenRouter)", ContextSize: 200000},
|
||||
{ID: "google/gemini-2.5-flash", Name: "Gemini 2.5 Flash (OpenRouter)", ContextSize: 1000000},
|
||||
{ID: "deepseek/deepseek-r1", Name: "DeepSeek R1 (OpenRouter)", ContextSize: 64000},
|
||||
{ID: "meta-llama/llama-3.3-70b-instruct", Name: "Llama 3.3 70B (OpenRouter)", ContextSize: 128000},
|
||||
{ID: "mistralai/mistral-large", Name: "Mistral Large (OpenRouter)", ContextSize: 128000},
|
||||
{ID: "qwen/qwen-2.5-72b-instruct", Name: "Qwen 2.5 72B (OpenRouter)", ContextSize: 32000},
|
||||
{ID: "x-ai/grok-3-beta", Name: "Grok 3 Beta (OpenRouter)", ContextSize: 131072},
|
||||
{ID: "cohere/command-a", Name: "Command A (OpenRouter)", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "nvidia",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "nvidia/llama-3.1-nemotron-70b-instruct", Name: "Nemotron 70B", ContextSize: 128000},
|
||||
{ID: "nvidia/llama-3.1-nemotron-70b-instruct-mini", Name: "Nemotron 70B Mini", ContextSize: 128000},
|
||||
{ID: "nvidia/llama-3.3-70b-instruct", Name: "Llama 3.3 70B", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "vllm",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "qwen-2.5-72b-instruct", Name: "Qwen 2.5 72B", ContextSize: 32768},
|
||||
{ID: "llama-3.1-8b-instruct", Name: "Llama 3.1 8B", ContextSize: 8192},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "cerebras",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "llama-3.3-70b", Name: "Llama 3.3 70B", ContextSize: 8192},
|
||||
{ID: "llama-3.1-8b", Name: "Llama 3.1 8B", ContextSize: 8192},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "zhipu",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "glm-4-plus", Name: "GLM-4 Plus", ContextSize: 128000},
|
||||
{ID: "glm-4-long", Name: "GLM-4 Long", ContextSize: 128000},
|
||||
{ID: "glm-4", Name: "GLM-4", ContextSize: 128000},
|
||||
{ID: "glm-4-flash", Name: "GLM-4 Flash", ContextSize: 128000},
|
||||
{ID: "glm-3-turbo", Name: "GLM-3 Turbo", ContextSize: 6000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "github_copilot",
|
||||
AuthMethod: "oauth",
|
||||
Models: []ModelInfo{
|
||||
{ID: "copilot", Name: "GitHub Copilot", ContextSize: 128000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "codex",
|
||||
AuthMethod: "oauth",
|
||||
Models: []ModelInfo{
|
||||
{ID: "codex-cli", Name: "OpenAI Codex CLI", ContextSize: 200000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "volcengine",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "doubao-pro-32k", Name: "Doubao Pro 32K", ContextSize: 32000},
|
||||
{ID: "doubao-lite-32k", Name: "Doubao Lite 32K", ContextSize: 32000},
|
||||
},
|
||||
},
|
||||
{
|
||||
Provider: "shengsuanyun",
|
||||
AuthMethod: "api_key",
|
||||
Models: []ModelInfo{
|
||||
{ID: "yi-large", Name: "Yi Large", ContextSize: 16000},
|
||||
{ID: "yi-medium", Name: "Yi Medium", ContextSize: 32000},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func GetModelsForProvider(provider string) []ModelInfo {
|
||||
for _, pm := range ProviderModelsList {
|
||||
if pm.Provider == provider {
|
||||
return pm.Models
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetProviderAuthMethod(provider string) string {
|
||||
for _, pm := range ProviderModelsList {
|
||||
if pm.Provider == provider {
|
||||
return pm.AuthMethod
|
||||
}
|
||||
}
|
||||
return "api_key"
|
||||
}
|
||||
|
|
@ -402,10 +402,17 @@ func BuildSessionRegistry(cfg *config.Config) SessionRegistry {
|
|||
|
||||
// Collect model options based on selected provider
|
||||
selProvider := cfg.Agents.Defaults.Provider
|
||||
var modelOptions []string
|
||||
if models := config.GetModelsForProvider(selProvider); len(models) > 0 {
|
||||
for _, m := range models {
|
||||
modelOptions = append(modelOptions, m.ID)
|
||||
}
|
||||
} else {
|
||||
modelSuggestions := config.GetPopularModels(selProvider)
|
||||
modelOptions := make([]string, len(modelSuggestions)+1)
|
||||
modelOptions = make([]string, len(modelSuggestions))
|
||||
copy(modelOptions, modelSuggestions)
|
||||
modelOptions[len(modelSuggestions)] = "custom"
|
||||
}
|
||||
modelOptions = append(modelOptions, "custom")
|
||||
|
||||
// Deep copy sessions and fill in options
|
||||
for i, sess := range AllSessions {
|
||||
|
|
|
|||
|
|
@ -607,6 +607,7 @@ func (t *tuiModel) saveAnswer(q Question) {
|
|||
// Update provider auth method options when provider is selected
|
||||
if q.ID == "provider" {
|
||||
t.updateProviderAuthOptions()
|
||||
t.updateModelOptions()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -695,6 +696,39 @@ func (t *tuiModel) updateProviderAuthOptions() {
|
|||
}
|
||||
}
|
||||
|
||||
func (t *tuiModel) updateModelOptions() {
|
||||
provider := t.answers["provider"]
|
||||
if provider == "" {
|
||||
return
|
||||
}
|
||||
|
||||
var modelIDs []string
|
||||
if models := config.GetModelsForProvider(provider); len(models) > 0 {
|
||||
for _, m := range models {
|
||||
modelIDs = append(modelIDs, m.ID)
|
||||
}
|
||||
} else {
|
||||
modelIDs = config.GetPopularModels(provider)
|
||||
}
|
||||
modelIDs = append(modelIDs, "custom")
|
||||
|
||||
for i := range t.registry.Sessions {
|
||||
if t.registry.Sessions[i].ID == "model" {
|
||||
for j := range t.registry.Sessions[i].Questions {
|
||||
q := &t.registry.Sessions[i].Questions[j]
|
||||
if q.ID == "model_select" {
|
||||
q.Options = modelIDs
|
||||
// Reset selection if out of bounds
|
||||
if idx, ok := t.selIdx[q.ID]; ok && idx >= len(q.Options) {
|
||||
t.selIdx[q.ID] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *tuiModel) applyAnswersToConfig() {
|
||||
cfg := t.setup.Cfg
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue