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 <noreply@anthropic.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,3 +7,4 @@ config.json
|
|||||||
|
|
||||||
# Temp files
|
# Temp files
|
||||||
doc_update.json
|
doc_update.json
|
||||||
|
config.json
|
||||||
|
|||||||
43
config.go
43
config.go
@@ -13,13 +13,45 @@ type Config struct {
|
|||||||
APIKey string `json:"api_key"`
|
APIKey string `json:"api_key"`
|
||||||
Model string `json:"model"`
|
Model string `json:"model"`
|
||||||
BaseURL string `json:"base_url"`
|
BaseURL string `json:"base_url"`
|
||||||
|
Provider string `json:"provider"` // "agnes" or "zhipu" or "custom"
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig returns a Config with sensible defaults.
|
// Provider presets
|
||||||
func DefaultConfig() *Config {
|
var providerPresets = map[string]struct {
|
||||||
return &Config{
|
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",
|
Model: "glm-4.6v-flash",
|
||||||
BaseURL: "https://open.bigmodel.cn/api/paas/v4/chat/completions",
|
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
|
// Override with environment variable
|
||||||
|
if envKey := os.Getenv("AGNES_API_KEY"); envKey != "" {
|
||||||
|
cfg.APIKey = envKey
|
||||||
|
}
|
||||||
if envKey := os.Getenv("ZHIPU_API_KEY"); envKey != "" {
|
if envKey := os.Getenv("ZHIPU_API_KEY"); envKey != "" {
|
||||||
cfg.APIKey = envKey
|
cfg.APIKey = envKey
|
||||||
}
|
}
|
||||||
@@ -65,7 +100,7 @@ func LoadConfig(flagKey, configPath string) (*Config, error) {
|
|||||||
if cfg.APIKey == "" {
|
if cfg.APIKey == "" {
|
||||||
return cfg, fmt.Errorf("API key not configured. Set it via:\n" +
|
return cfg, fmt.Errorf("API key not configured. Set it via:\n" +
|
||||||
" 1. --apikey flag\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")
|
" 3. config.json file in the tools directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
main.go
12
main.go
@@ -18,12 +18,13 @@ func main() {
|
|||||||
saveConfig bool
|
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(&configPath, "config", "", "Path to config.json file")
|
||||||
flag.StringVar(&prompt, "prompt", "", "Custom prompt for image analysis")
|
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(&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(&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")
|
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()
|
flag.Parse()
|
||||||
|
|
||||||
// Handle --save-config: persist the key and exit
|
// Handle --save-config: persist the key and exit
|
||||||
@@ -50,8 +51,12 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply provider preset (respects user's custom model/baseURL in config)
|
||||||
|
cfg.ApplyProvider(*provider)
|
||||||
|
|
||||||
if !quiet {
|
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
|
// Collect image paths from remaining args
|
||||||
@@ -64,8 +69,9 @@ func main() {
|
|||||||
fmt.Fprintln(os.Stderr, "")
|
fmt.Fprintln(os.Stderr, "")
|
||||||
fmt.Fprintln(os.Stderr, "Examples:")
|
fmt.Fprintln(os.Stderr, "Examples:")
|
||||||
fmt.Fprintln(os.Stderr, " vision-tool photo.jpg")
|
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 -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 --apikey YOUR_KEY photo.jpg")
|
||||||
fmt.Fprintln(os.Stderr, " vision-tool --save-config --apikey YOUR_KEY")
|
fmt.Fprintln(os.Stderr, " vision-tool --save-config --apikey YOUR_KEY")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user