From 2df5e871dc6286080b303b4a243aaed9aeeeb138 Mon Sep 17 00:00:00 2001 From: xieyao Date: Mon, 29 Jun 2026 18:58:26 +0800 Subject: [PATCH] feat: add Agnes AI as default provider, support multi-provider switching - Default provider changed from Zhipu to Agnes AI (agnes-2.0-flash) - Add --provider flag: agnes (default), zhipu, custom - Add AGNES_API_KEY env var support (still compatible with ZHIPU_API_KEY) - Add provider presets system for easy switching between AI backends - Add .gitignore to prevent config.json with API keys from being committed - Update usage examples Co-Authored-By: Claude --- .gitignore | 1 + config.go | 49 ++++++++++++++++++++++++++++++++++++++++++------- main.go | 12 +++++++++--- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 36e3c0e..6d2cef6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ config.json # Temp files doc_update.json +config.json diff --git a/config.go b/config.go index 3e44f43..8999b3c 100644 --- a/config.go +++ b/config.go @@ -10,16 +10,48 @@ import ( // Config holds the application configuration. type Config struct { - APIKey string `json:"api_key"` - Model string `json:"model"` - BaseURL string `json:"base_url"` + APIKey string `json:"api_key"` + Model string `json:"model"` + BaseURL string `json:"base_url"` + Provider string `json:"provider"` // "agnes" or "zhipu" or "custom" } -// DefaultConfig returns a Config with sensible defaults. -func DefaultConfig() *Config { - return &Config{ +// Provider presets +var providerPresets = map[string]struct { + Model string + BaseURL string +}{ + "agnes": { + Model: "agnes-2.0-flash", + BaseURL: "https://apihub.agnes-ai.com/v1/chat/completions", + }, + "zhipu": { Model: "glm-4.6v-flash", BaseURL: "https://open.bigmodel.cn/api/paas/v4/chat/completions", + }, +} + +// DefaultConfig returns a Config with sensible defaults (Agnes AI). +func DefaultConfig() *Config { + return &Config{ + Provider: "agnes", + Model: "agnes-2.0-flash", + BaseURL: "https://apihub.agnes-ai.com/v1/chat/completions", + } +} + +// ApplyProvider applies a named provider preset, respecting user overrides. +func (c *Config) ApplyProvider(provider string) { + if preset, ok := providerPresets[provider]; ok { + c.Provider = provider + // Only override model/baseURL if user hasn't set custom ones + if c.Model == "" || c.Model == "agnes-2.0-flash" || c.Model == "glm-4.6v-flash" { + c.Model = preset.Model + } + if c.BaseURL == "" || c.BaseURL == "https://apihub.agnes-ai.com/v1/chat/completions" || + c.BaseURL == "https://open.bigmodel.cn/api/paas/v4/chat/completions" { + c.BaseURL = preset.BaseURL + } } } @@ -53,6 +85,9 @@ func LoadConfig(flagKey, configPath string) (*Config, error) { } // Override with environment variable + if envKey := os.Getenv("AGNES_API_KEY"); envKey != "" { + cfg.APIKey = envKey + } if envKey := os.Getenv("ZHIPU_API_KEY"); envKey != "" { cfg.APIKey = envKey } @@ -65,7 +100,7 @@ func LoadConfig(flagKey, configPath string) (*Config, error) { if cfg.APIKey == "" { return cfg, fmt.Errorf("API key not configured. Set it via:\n" + " 1. --apikey flag\n" + - " 2. ZHIPU_API_KEY environment variable\n" + + " 2. AGNES_API_KEY environment variable\n" + " 3. config.json file in the tools directory") } diff --git a/main.go b/main.go index f4dcba3..7acb7eb 100644 --- a/main.go +++ b/main.go @@ -18,12 +18,13 @@ func main() { saveConfig bool ) - flag.StringVar(&apiKey, "apikey", "", "Zhipu AI API key (or set ZHIPU_API_KEY env var)") + flag.StringVar(&apiKey, "apikey", "", "API key (or set AGNES_API_KEY env var)") flag.StringVar(&configPath, "config", "", "Path to config.json file") flag.StringVar(&prompt, "prompt", "", "Custom prompt for image analysis") flag.BoolVar(&quiet, "q", false, "Quiet mode — only output the model's response text") flag.BoolVar(&noThink, "no-think", false, "Disable thinking mode (faster, lower server load)") flag.BoolVar(&saveConfig, "save-config", false, "Save the API key to config.json and exit") + provider := flag.String("provider", "agnes", "AI provider: agnes (default), zhipu, or custom") flag.Parse() // Handle --save-config: persist the key and exit @@ -50,8 +51,12 @@ func main() { os.Exit(1) } + // Apply provider preset (respects user's custom model/baseURL in config) + cfg.ApplyProvider(*provider) + if !quiet { - fmt.Fprintf(os.Stderr, "Using model: %s | API key: %s\n", cfg.Model, MaskKey(cfg.APIKey)) + fmt.Fprintf(os.Stderr, "Provider: %s | Model: %s | API key: %s\n", + cfg.Provider, cfg.Model, MaskKey(cfg.APIKey)) } // Collect image paths from remaining args @@ -64,8 +69,9 @@ func main() { fmt.Fprintln(os.Stderr, "") fmt.Fprintln(os.Stderr, "Examples:") fmt.Fprintln(os.Stderr, " vision-tool photo.jpg") - fmt.Fprintln(os.Stderr, " vision-tool -prompt \"这张图里有什么文字?\" screenshot.png") + fmt.Fprintln(os.Stderr, ` vision-tool -prompt "这张图里有什么文字?" screenshot.png`) fmt.Fprintln(os.Stderr, " vision-tool -q img1.png img2.png") + fmt.Fprintln(os.Stderr, " vision-tool --provider zhipu photo.jpg") fmt.Fprintln(os.Stderr, " vision-tool --apikey YOUR_KEY photo.jpg") fmt.Fprintln(os.Stderr, " vision-tool --save-config --apikey YOUR_KEY") os.Exit(1)