{"repo": "alanfokco/agentscope-go", "files": {"pkg/agentscope/credential/credential.go": {"7d6926c7447f4a21cbf3fcb3b567f431562ff208": {"t": 1785745643.6107497, "n": 8168, "h": "97580991a8e6ec6d", "c": "package credential\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n)\n\n// Credential provides authentication details for a model provider.\ntype Credential interface {\n\tProvider() string\n\tAPIKey() string\n\tBaseURL() string\n}\n\n// --- Typed implementations ---\n\n// DashScopeCredential authenticates with DashScope/Qwen.\ntype DashScopeCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DashScopeCredential) Provider() string { return \"dashscope\" }\nfunc (c *DashScopeCredential) APIKey() string { return c.Key }\nfunc (c *DashScopeCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n}\n\n// OpenAICredential authenticates with OpenAI.\ntype OpenAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *OpenAICredential) Provider() string { return \"openai\" }\nfunc (c *OpenAICredential) APIKey() string { return c.Key }\nfunc (c *OpenAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.openai.com/v1\"\n}\n\n// AnthropicCredential authenticates with Anthropic.\ntype AnthropicCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *AnthropicCredential) Provider() string { return \"anthropic\" }\nfunc (c *AnthropicCredential) APIKey() string { return c.Key }\nfunc (c *AnthropicCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.anthropic.com\"\n}\n\n// DeepSeekCredential authenticates with DeepSeek.\ntype DeepSeekCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DeepSeekCredential) Provider() string { return \"deepseek\" }\nfunc (c *DeepSeekCredential) APIKey() string { return c.Key }\nfunc (c *DeepSeekCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.deepseek.com/v1\"\n}\n\n// OllamaCredential authenticates with a local Ollama instance.\ntype OllamaCredential struct {\n\tURL string\n}\n\nfunc (c *OllamaCredential) Provider() string { return \"ollama\" }\nfunc (c *OllamaCredential) APIKey() string { return \"\" }\nfunc (c *OllamaCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"http://localhost:11434/v1\"\n}\n\n// GeminiCredential authenticates with Google Gemini.\ntype GeminiCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *GeminiCredential) Provider() string { return \"gemini\" }\nfunc (c *GeminiCredential) APIKey() string { return c.Key }\nfunc (c *GeminiCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://generativelanguage.googleapis.com/v1beta\"\n}\n\n// MoonshotCredential authenticates with Moonshot/Kimi.\ntype MoonshotCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *MoonshotCredential) Provider() string { return \"moonshot\" }\nfunc (c *MoonshotCredential) APIKey() string { return c.Key }\nfunc (c *MoonshotCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.moonshot.cn\"\n}\n\n// XAICredential authenticates with xAI/Grok.\ntype XAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *XAICredential) Provider() string { return \"xai\" }\nfunc (c *XAICredential) APIKey() string { return c.Key }\nfunc (c *XAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.x.ai\"\n}\n\n// KimiCredential authenticates with Kimi (Moonshot's consumer brand).\ntype KimiCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *KimiCredential) Provider() string { return \"kimi\" }\nfunc (c *KimiCredential) APIKey() string { return c.Key }\nfunc (c *KimiCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.moonshot.cn/v1\"\n}\n\n// --- Environment auto-loading ---\n\n// FromEnv attempts to load credentials from environment variables.\n// It checks providers in order: Anthropic, DashScope, OpenAI, DeepSeek.\n// Returns nil if no credentials are found.\nfunc FromEnv() Credential {\n\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"KIMI_API_KEY\"); key != \"\" {\n\t\treturn &KimiCredential{Key: key, URL: os.Getenv(\"KIMI_BASE_URL\")}\n\t}\n\treturn nil\n}\n\n// FromEnvForProvider loads a credential for a specific provider from env vars.\nfunc FromEnvForProvider(provider string) Credential {\n\tswitch provider {\n\tcase \"dashscope\":\n\t\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t\t}\n\tcase \"openai\":\n\t\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t\t}\n\tcase \"anthropic\":\n\t\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t\t}\n\tcase \"deepseek\":\n\t\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t\t}\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: os.Getenv(\"OLLAMA_BASE_URL\")}\n\tcase \"gemini\":\n\t\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t\t}\n\tcase \"moonshot\":\n\t\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t\t}\n\tcase \"xai\":\n\t\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t\t}\n\tcase \"kimi\":\n\t\tif key := os.Getenv(\"KIMI_API_KEY\"); key != \"\" {\n\t\t\treturn &KimiCredential{Key: key, URL: os.Getenv(\"KIMI_BASE_URL\")}\n\t\t}\n\t}\n\treturn nil\n}\n\n// --- Registry ---\n\n// Registry stores named credentials for lookup.\ntype Registry struct {\n\tmu sync.RWMutex\n\tcreds map[string]Credential\n}\n\n// NewRegistry creates an empty credential registry.\nfunc NewRegistry() *Registry {\n\treturn &Registry{creds: make(map[string]Credential)}\n}\n\n// Register adds a credential under the given name.\nfunc (r *Registry) Register(name string, cred Credential) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.creds[name] = cred\n}\n\n// Get retrieves a credential by name.\nfunc (r *Registry) Get(name string) (Credential, error) {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tc, ok := r.creds[name]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"credential %q not registered\", name)\n\t}\n\treturn c, nil\n}\n\n// List returns all registered credential names.\nfunc (r *Registry) List() []string {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tout := make([]string, 0, len(r.creds))\n\tfor k := range r.creds {\n\t\tout = append(out, k)\n\t}\n\treturn out\n}\n\n// FromMap creates a Credential from a map (e.g., deserialized config).\n// Requires a \"provider\" key to discriminate type.\nfunc FromMap(m map[string]string) (Credential, error) {\n\tprovider := m[\"provider\"]\n\tkey := m[\"api_key\"]\n\turl := m[\"base_url\"]\n\n\tswitch provider {\n\tcase \"dashscope\":\n\t\treturn &DashScopeCredential{Key: key, URL: url}, nil\n\tcase \"openai\":\n\t\treturn &OpenAICredential{Key: key, URL: url}, nil\n\tcase \"anthropic\":\n\t\treturn &AnthropicCredential{Key: key, URL: url}, nil\n\tcase \"deepseek\":\n\t\treturn &DeepSeekCredential{Key: key, URL: url}, nil\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: url}, nil\n\tcase \"gemini\":\n\t\treturn &GeminiCredential{Key: key, URL: url}, nil\n\tcase \"moonshot\":\n\t\treturn &MoonshotCredential{Key: key, URL: url}, nil\n\tcase \"xai\":\n\t\treturn &XAICredential{Key: key, URL: url}, nil\n\tcase \"kimi\":\n\t\treturn &KimiCredential{Key: key, URL: url}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown provider: %q\", provider)\n\t}\n}\n"}, "07a36cafecc666e0b086d218c2f3237610c96d40": {"t": 1785755244.565841, "n": 8168, "h": "97580991a8e6ec6d", "c": "package credential\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n)\n\n// Credential provides authentication details for a model provider.\ntype Credential interface {\n\tProvider() string\n\tAPIKey() string\n\tBaseURL() string\n}\n\n// --- Typed implementations ---\n\n// DashScopeCredential authenticates with DashScope/Qwen.\ntype DashScopeCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DashScopeCredential) Provider() string { return \"dashscope\" }\nfunc (c *DashScopeCredential) APIKey() string { return c.Key }\nfunc (c *DashScopeCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n}\n\n// OpenAICredential authenticates with OpenAI.\ntype OpenAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *OpenAICredential) Provider() string { return \"openai\" }\nfunc (c *OpenAICredential) APIKey() string { return c.Key }\nfunc (c *OpenAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.openai.com/v1\"\n}\n\n// AnthropicCredential authenticates with Anthropic.\ntype AnthropicCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *AnthropicCredential) Provider() string { return \"anthropic\" }\nfunc (c *AnthropicCredential) APIKey() string { return c.Key }\nfunc (c *AnthropicCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.anthropic.com\"\n}\n\n// DeepSeekCredential authenticates with DeepSeek.\ntype DeepSeekCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DeepSeekCredential) Provider() string { return \"deepseek\" }\nfunc (c *DeepSeekCredential) APIKey() string { return c.Key }\nfunc (c *DeepSeekCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.deepseek.com/v1\"\n}\n\n// OllamaCredential authenticates with a local Ollama instance.\ntype OllamaCredential struct {\n\tURL string\n}\n\nfunc (c *OllamaCredential) Provider() string { return \"ollama\" }\nfunc (c *OllamaCredential) APIKey() string { return \"\" }\nfunc (c *OllamaCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"http://localhost:11434/v1\"\n}\n\n// GeminiCredential authenticates with Google Gemini.\ntype GeminiCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *GeminiCredential) Provider() string { return \"gemini\" }\nfunc (c *GeminiCredential) APIKey() string { return c.Key }\nfunc (c *GeminiCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://generativelanguage.googleapis.com/v1beta\"\n}\n\n// MoonshotCredential authenticates with Moonshot/Kimi.\ntype MoonshotCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *MoonshotCredential) Provider() string { return \"moonshot\" }\nfunc (c *MoonshotCredential) APIKey() string { return c.Key }\nfunc (c *MoonshotCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.moonshot.cn\"\n}\n\n// XAICredential authenticates with xAI/Grok.\ntype XAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *XAICredential) Provider() string { return \"xai\" }\nfunc (c *XAICredential) APIKey() string { return c.Key }\nfunc (c *XAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.x.ai\"\n}\n\n// KimiCredential authenticates with Kimi (Moonshot's consumer brand).\ntype KimiCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *KimiCredential) Provider() string { return \"kimi\" }\nfunc (c *KimiCredential) APIKey() string { return c.Key }\nfunc (c *KimiCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.moonshot.cn/v1\"\n}\n\n// --- Environment auto-loading ---\n\n// FromEnv attempts to load credentials from environment variables.\n// It checks providers in order: Anthropic, DashScope, OpenAI, DeepSeek.\n// Returns nil if no credentials are found.\nfunc FromEnv() Credential {\n\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"KIMI_API_KEY\"); key != \"\" {\n\t\treturn &KimiCredential{Key: key, URL: os.Getenv(\"KIMI_BASE_URL\")}\n\t}\n\treturn nil\n}\n\n// FromEnvForProvider loads a credential for a specific provider from env vars.\nfunc FromEnvForProvider(provider string) Credential {\n\tswitch provider {\n\tcase \"dashscope\":\n\t\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t\t}\n\tcase \"openai\":\n\t\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t\t}\n\tcase \"anthropic\":\n\t\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t\t}\n\tcase \"deepseek\":\n\t\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t\t}\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: os.Getenv(\"OLLAMA_BASE_URL\")}\n\tcase \"gemini\":\n\t\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t\t}\n\tcase \"moonshot\":\n\t\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t\t}\n\tcase \"xai\":\n\t\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t\t}\n\tcase \"kimi\":\n\t\tif key := os.Getenv(\"KIMI_API_KEY\"); key != \"\" {\n\t\t\treturn &KimiCredential{Key: key, URL: os.Getenv(\"KIMI_BASE_URL\")}\n\t\t}\n\t}\n\treturn nil\n}\n\n// --- Registry ---\n\n// Registry stores named credentials for lookup.\ntype Registry struct {\n\tmu sync.RWMutex\n\tcreds map[string]Credential\n}\n\n// NewRegistry creates an empty credential registry.\nfunc NewRegistry() *Registry {\n\treturn &Registry{creds: make(map[string]Credential)}\n}\n\n// Register adds a credential under the given name.\nfunc (r *Registry) Register(name string, cred Credential) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.creds[name] = cred\n}\n\n// Get retrieves a credential by name.\nfunc (r *Registry) Get(name string) (Credential, error) {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tc, ok := r.creds[name]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"credential %q not registered\", name)\n\t}\n\treturn c, nil\n}\n\n// List returns all registered credential names.\nfunc (r *Registry) List() []string {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tout := make([]string, 0, len(r.creds))\n\tfor k := range r.creds {\n\t\tout = append(out, k)\n\t}\n\treturn out\n}\n\n// FromMap creates a Credential from a map (e.g., deserialized config).\n// Requires a \"provider\" key to discriminate type.\nfunc FromMap(m map[string]string) (Credential, error) {\n\tprovider := m[\"provider\"]\n\tkey := m[\"api_key\"]\n\turl := m[\"base_url\"]\n\n\tswitch provider {\n\tcase \"dashscope\":\n\t\treturn &DashScopeCredential{Key: key, URL: url}, nil\n\tcase \"openai\":\n\t\treturn &OpenAICredential{Key: key, URL: url}, nil\n\tcase \"anthropic\":\n\t\treturn &AnthropicCredential{Key: key, URL: url}, nil\n\tcase \"deepseek\":\n\t\treturn &DeepSeekCredential{Key: key, URL: url}, nil\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: url}, nil\n\tcase \"gemini\":\n\t\treturn &GeminiCredential{Key: key, URL: url}, nil\n\tcase \"moonshot\":\n\t\treturn &MoonshotCredential{Key: key, URL: url}, nil\n\tcase \"xai\":\n\t\treturn &XAICredential{Key: key, URL: url}, nil\n\tcase \"kimi\":\n\t\treturn &KimiCredential{Key: key, URL: url}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown provider: %q\", provider)\n\t}\n}\n"}, "a0742207a0b7ab99d27021710050947b3ed6aff7": {"t": 1785755248.22236, "n": 7477, "h": "f6d215097e251ff1", "c": "package credential\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n)\n\n// Credential provides authentication details for a model provider.\ntype Credential interface {\n\tProvider() string\n\tAPIKey() string\n\tBaseURL() string\n}\n\n// --- Typed implementations ---\n\n// DashScopeCredential authenticates with DashScope/Qwen.\ntype DashScopeCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DashScopeCredential) Provider() string { return \"dashscope\" }\nfunc (c *DashScopeCredential) APIKey() string { return c.Key }\nfunc (c *DashScopeCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n}\n\n// OpenAICredential authenticates with OpenAI.\ntype OpenAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *OpenAICredential) Provider() string { return \"openai\" }\nfunc (c *OpenAICredential) APIKey() string { return c.Key }\nfunc (c *OpenAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.openai.com/v1\"\n}\n\n// AnthropicCredential authenticates with Anthropic.\ntype AnthropicCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *AnthropicCredential) Provider() string { return \"anthropic\" }\nfunc (c *AnthropicCredential) APIKey() string { return c.Key }\nfunc (c *AnthropicCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.anthropic.com\"\n}\n\n// DeepSeekCredential authenticates with DeepSeek.\ntype DeepSeekCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *DeepSeekCredential) Provider() string { return \"deepseek\" }\nfunc (c *DeepSeekCredential) APIKey() string { return c.Key }\nfunc (c *DeepSeekCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.deepseek.com/v1\"\n}\n\n// OllamaCredential authenticates with a local Ollama instance.\ntype OllamaCredential struct {\n\tURL string\n}\n\nfunc (c *OllamaCredential) Provider() string { return \"ollama\" }\nfunc (c *OllamaCredential) APIKey() string { return \"\" }\nfunc (c *OllamaCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"http://localhost:11434/v1\"\n}\n\n// GeminiCredential authenticates with Google Gemini.\ntype GeminiCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *GeminiCredential) Provider() string { return \"gemini\" }\nfunc (c *GeminiCredential) APIKey() string { return c.Key }\nfunc (c *GeminiCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://generativelanguage.googleapis.com/v1beta\"\n}\n\n// MoonshotCredential authenticates with Moonshot/Kimi.\ntype MoonshotCredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *MoonshotCredential) Provider() string { return \"moonshot\" }\nfunc (c *MoonshotCredential) APIKey() string { return c.Key }\nfunc (c *MoonshotCredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.moonshot.cn\"\n}\n\n// XAICredential authenticates with xAI/Grok.\ntype XAICredential struct {\n\tKey string\n\tURL string\n}\n\nfunc (c *XAICredential) Provider() string { return \"xai\" }\nfunc (c *XAICredential) APIKey() string { return c.Key }\nfunc (c *XAICredential) BaseURL() string {\n\tif c.URL != \"\" {\n\t\treturn c.URL\n\t}\n\treturn \"https://api.x.ai\"\n}\n\n// --- Environment auto-loading ---\n\n// FromEnv attempts to load credentials from environment variables.\n// It checks providers in order: Anthropic, DashScope, OpenAI, DeepSeek.\n// Returns nil if no credentials are found.\nfunc FromEnv() Credential {\n\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t}\n\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t}\n\treturn nil\n}\n\n// FromEnvForProvider loads a credential for a specific provider from env vars.\nfunc FromEnvForProvider(provider string) Credential {\n\tswitch provider {\n\tcase \"dashscope\":\n\t\tif key := os.Getenv(\"DASHSCOPE_API_KEY\"); key != \"\" {\n\t\t\treturn &DashScopeCredential{Key: key, URL: os.Getenv(\"DASHSCOPE_BASE_URL\")}\n\t\t}\n\tcase \"openai\":\n\t\tif key := os.Getenv(\"OPENAI_API_KEY\"); key != \"\" {\n\t\t\treturn &OpenAICredential{Key: key, URL: os.Getenv(\"OPENAI_BASE_URL\")}\n\t\t}\n\tcase \"anthropic\":\n\t\tif key := os.Getenv(\"ANTHROPIC_API_KEY\"); key != \"\" {\n\t\t\treturn &AnthropicCredential{Key: key, URL: os.Getenv(\"ANTHROPIC_BASE_URL\")}\n\t\t}\n\tcase \"deepseek\":\n\t\tif key := os.Getenv(\"DEEPSEEK_API_KEY\"); key != \"\" {\n\t\t\treturn &DeepSeekCredential{Key: key, URL: os.Getenv(\"DEEPSEEK_BASE_URL\")}\n\t\t}\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: os.Getenv(\"OLLAMA_BASE_URL\")}\n\tcase \"gemini\":\n\t\tif key := os.Getenv(\"GEMINI_API_KEY\"); key != \"\" {\n\t\t\treturn &GeminiCredential{Key: key, URL: os.Getenv(\"GEMINI_BASE_URL\")}\n\t\t}\n\tcase \"moonshot\":\n\t\tif key := os.Getenv(\"MOONSHOT_API_KEY\"); key != \"\" {\n\t\t\treturn &MoonshotCredential{Key: key, URL: os.Getenv(\"MOONSHOT_BASE_URL\")}\n\t\t}\n\tcase \"xai\":\n\t\tif key := os.Getenv(\"XAI_API_KEY\"); key != \"\" {\n\t\t\treturn &XAICredential{Key: key, URL: os.Getenv(\"XAI_BASE_URL\")}\n\t\t}\n\t}\n\treturn nil\n}\n\n// --- Registry ---\n\n// Registry stores named credentials for lookup.\ntype Registry struct {\n\tmu sync.RWMutex\n\tcreds map[string]Credential\n}\n\n// NewRegistry creates an empty credential registry.\nfunc NewRegistry() *Registry {\n\treturn &Registry{creds: make(map[string]Credential)}\n}\n\n// Register adds a credential under the given name.\nfunc (r *Registry) Register(name string, cred Credential) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.creds[name] = cred\n}\n\n// Get retrieves a credential by name.\nfunc (r *Registry) Get(name string) (Credential, error) {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tc, ok := r.creds[name]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"credential %q not registered\", name)\n\t}\n\treturn c, nil\n}\n\n// List returns all registered credential names.\nfunc (r *Registry) List() []string {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tout := make([]string, 0, len(r.creds))\n\tfor k := range r.creds {\n\t\tout = append(out, k)\n\t}\n\treturn out\n}\n\n// FromMap creates a Credential from a map (e.g., deserialized config).\n// Requires a \"provider\" key to discriminate type.\nfunc FromMap(m map[string]string) (Credential, error) {\n\tprovider := m[\"provider\"]\n\tkey := m[\"api_key\"]\n\turl := m[\"base_url\"]\n\n\tswitch provider {\n\tcase \"dashscope\":\n\t\treturn &DashScopeCredential{Key: key, URL: url}, nil\n\tcase \"openai\":\n\t\treturn &OpenAICredential{Key: key, URL: url}, nil\n\tcase \"anthropic\":\n\t\treturn &AnthropicCredential{Key: key, URL: url}, nil\n\tcase \"deepseek\":\n\t\treturn &DeepSeekCredential{Key: key, URL: url}, nil\n\tcase \"ollama\":\n\t\treturn &OllamaCredential{URL: url}, nil\n\tcase \"gemini\":\n\t\treturn &GeminiCredential{Key: key, URL: url}, nil\n\tcase \"moonshot\":\n\t\treturn &MoonshotCredential{Key: key, URL: url}, nil\n\tcase \"xai\":\n\t\treturn &XAICredential{Key: key, URL: url}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown provider: %q\", provider)\n\t}\n}\n"}}}}