diff --git a/cmd/picoclaw/internal/status/helpers.go b/cmd/picoclaw/internal/status/helpers.go index ab28f4885..fbdac6b66 100644 --- a/cmd/picoclaw/internal/status/helpers.go +++ b/cmd/picoclaw/internal/status/helpers.go @@ -3,6 +3,7 @@ package status import ( "fmt" "os" + "strings" "github.com/sipeed/picoclaw/cmd/picoclaw/internal" "github.com/sipeed/picoclaw/pkg/auth" @@ -41,19 +42,89 @@ func statusCmd() { if _, err := os.Stat(configPath); err == nil { fmt.Printf("Model: %s\n", cfg.Agents.Defaults.GetModelName()) - hasOpenRouter := cfg.Providers.OpenRouter.APIKey != "" + // Show model_list entries + if len(cfg.ModelList) > 0 { + fmt.Println() + fmt.Println("--- Model List ---") + for i, mc := range cfg.ModelList { + apiStatus := "" + if mc.APIKey != "" { + apiStatus = " [API key set]" + } else if mc.APIBase != "" { + if strings.Contains(mc.APIBase, "localhost") || strings.Contains(mc.APIBase, "127.0.0.1") { + apiStatus = " [local: " + mc.APIBase + "]" + } else { + apiStatus = " [" + mc.APIBase + "]" + } + } else if mc.AuthMethod == "oauth" { + apiStatus = " [OAuth]" + } + fmt.Printf("%d. %s -> %s%s\n", i+1, mc.ModelName, mc.Model, apiStatus) + } + } + + // Show fallback chain + if len(cfg.Agents.Defaults.ModelFallbacks) > 0 { + fmt.Println() + fmt.Println("--- Fallback Chain ---") + fmt.Printf("Primary: %s\n", cfg.Agents.Defaults.GetModelName()) + fmt.Print("Fallbacks: ") + for i, fb := range cfg.Agents.Defaults.ModelFallbacks { + if i > 0 { + fmt.Print(" -> ") + } + fmt.Print(fb) + } + fmt.Println() + } + + // Check model_list for API keys/bases + modelListHasOpenRouter := false + modelListHasOpenAI := false + modelListHasOllama := false + modelListHasLocal := false + modelListHasAntigravity := false + + for _, mc := range cfg.ModelList { + // Check provider from model string + if strings.HasPrefix(mc.Model, "openrouter/") { + modelListHasOpenRouter = true + } + if strings.HasPrefix(mc.Model, "openai/") || strings.HasPrefix(mc.Model, "gpt") { + modelListHasOpenAI = true + } + if strings.HasPrefix(mc.Model, "antigravity/") { + modelListHasAntigravity = true + } + if strings.HasPrefix(mc.Model, "ollama/") { + modelListHasOllama = true + } + if mc.APIBase != "" { + if strings.Contains(mc.APIBase, "ollama") { + modelListHasOllama = true + } + // Local endpoints (not remote APIs) + if strings.Contains(mc.APIBase, "localhost") || strings.Contains(mc.APIBase, "127.0.0.1") { + modelListHasLocal = true + } + } + } + + // Check old providers config (legacy) + hasOpenRouter := cfg.Providers.OpenRouter.APIKey != "" || modelListHasOpenRouter hasAnthropic := cfg.Providers.Anthropic.APIKey != "" - hasOpenAI := cfg.Providers.OpenAI.APIKey != "" + hasOpenAI := cfg.Providers.OpenAI.APIKey != "" || modelListHasOpenAI hasGemini := cfg.Providers.Gemini.APIKey != "" hasZhipu := cfg.Providers.Zhipu.APIKey != "" hasQwen := cfg.Providers.Qwen.APIKey != "" hasGroq := cfg.Providers.Groq.APIKey != "" - hasVLLM := cfg.Providers.VLLM.APIBase != "" + hasVLLM := cfg.Providers.VLLM.APIBase != "" || modelListHasLocal hasMoonshot := cfg.Providers.Moonshot.APIKey != "" hasDeepSeek := cfg.Providers.DeepSeek.APIKey != "" hasVolcEngine := cfg.Providers.VolcEngine.APIKey != "" hasNvidia := cfg.Providers.Nvidia.APIKey != "" - hasOllama := cfg.Providers.Ollama.APIBase != "" + hasOllama := cfg.Providers.Ollama.APIBase != "" || modelListHasOllama + hasAntigravityOAuth := cfg.Providers.Antigravity.APIKey != "" || modelListHasAntigravity status := func(enabled bool) string { if enabled { @@ -61,6 +132,9 @@ func statusCmd() { } return "not set" } + + fmt.Println() + fmt.Println("--- API Keys ---") fmt.Println("OpenRouter API:", status(hasOpenRouter)) fmt.Println("Anthropic API:", status(hasAnthropic)) fmt.Println("OpenAI API:", status(hasOpenAI)) @@ -72,28 +146,46 @@ func statusCmd() { fmt.Println("DeepSeek API:", status(hasDeepSeek)) fmt.Println("VolcEngine API:", status(hasVolcEngine)) fmt.Println("Nvidia API:", status(hasNvidia)) - if hasVLLM { + + // Show local/ollama status + if cfg.Providers.VLLM.APIBase != "" { fmt.Printf("vLLM/Local: ✓ %s\n", cfg.Providers.VLLM.APIBase) + } else if modelListHasLocal { + // Find and show the local endpoint + for _, mc := range cfg.ModelList { + if mc.APIBase != "" && (strings.Contains(mc.APIBase, "localhost") || strings.Contains(mc.APIBase, "127.0.0.1")) { + fmt.Printf("Local: ✓ %s\n", mc.APIBase) + break + } + } } else { - fmt.Println("vLLM/Local: not set") + fmt.Println("vLLM/Local:", status(hasVLLM)) } - if hasOllama { + + if cfg.Providers.Ollama.APIBase != "" { fmt.Printf("Ollama: ✓ %s\n", cfg.Providers.Ollama.APIBase) + } else if modelListHasOllama { + fmt.Println("Ollama: ✓ (via model_list)") } else { - fmt.Println("Ollama: not set") + fmt.Println("Ollama:", status(hasOllama)) + } + + if hasAntigravityOAuth { + fmt.Println("Antigravity: ✓ (OAuth)") } store, _ := auth.LoadStore() if store != nil && len(store.Credentials) > 0 { - fmt.Println("\nOAuth/Token Auth:") + fmt.Println() + fmt.Println("--- OAuth/Token Auth ---") for provider, cred := range store.Credentials { - status := "authenticated" + authStatus := "authenticated" if cred.IsExpired() { - status = "expired" + authStatus = "expired" } else if cred.NeedsRefresh() { - status = "needs refresh" + authStatus = "needs refresh" } - fmt.Printf(" %s (%s): %s\n", provider, cred.AuthMethod, status) + fmt.Printf(" %s (%s): %s\n", provider, cred.AuthMethod, authStatus) } } }