feat: Add the Qwen provider
This commit is contained in:
parent
57dac394c5
commit
f0e90e6379
9 changed files with 46 additions and 2 deletions
|
|
@ -206,7 +206,7 @@ picoclaw onboard
|
||||||
|
|
||||||
**3. API キーの取得**
|
**3. API キーの取得**
|
||||||
|
|
||||||
- **LLM プロバイダー**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys)
|
- **LLM プロバイダー**: [OpenRouter](https://openrouter.ai/keys) · [Zhipu](https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys) · [Anthropic](https://console.anthropic.com) · [OpenAI](https://platform.openai.com) · [Gemini](https://aistudio.google.com/api-keys) · [Qwen](https://dashscope.console.aliyun.com)
|
||||||
- **Web 検索**(任意): [Brave Search](https://brave.com/search/api) - 無料枠あり(月 2000 リクエスト)
|
- **Web 検索**(任意): [Brave Search](https://brave.com/search/api) - 無料枠あり(月 2000 リクエスト)
|
||||||
|
|
||||||
> **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。
|
> **注意**: 完全な設定テンプレートは `config.example.json` を参照してください。
|
||||||
|
|
@ -765,5 +765,6 @@ Web 検索を有効にするには:
|
||||||
|---------|--------|------------|
|
|---------|--------|------------|
|
||||||
| **OpenRouter** | 月 200K トークン | 複数モデル(Claude, GPT-4 など) |
|
| **OpenRouter** | 月 200K トークン | 複数モデル(Claude, GPT-4 など) |
|
||||||
| **Zhipu** | 月 200K トークン | 中国ユーザー向け最適 |
|
| **Zhipu** | 月 200K トークン | 中国ユーザー向け最適 |
|
||||||
|
| **Qwen** | 無料枠あり | 通義千問 (Qwen) |
|
||||||
| **Brave Search** | 月 2000 クエリ | Web 検索機能 |
|
| **Brave Search** | 月 2000 クエリ | Web 検索機能 |
|
||||||
| **Groq** | 無料枠あり | 高速推論(Llama, Mixtral) |
|
| **Groq** | 無料枠あり | 高速推論(Llama, Mixtral) |
|
||||||
|
|
|
||||||
|
|
@ -663,6 +663,7 @@ The subagent has access to tools (message, web_search, etc.) and can communicate
|
||||||
| `anthropic(To be tested)` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic(To be tested)` | LLM (Claude direct) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai(To be tested)` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
| `openai(To be tested)` | LLM (GPT direct) | [platform.openai.com](https://platform.openai.com) |
|
||||||
| `deepseek(To be tested)` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek(To be tested)` | LLM (DeepSeek direct) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
|
| `qwen` | LLM (Qwen direct) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
|
|
@ -534,6 +534,7 @@ Agent 读取 HEARTBEAT.md
|
||||||
| `anthropic(待测试)` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
|
| `anthropic(待测试)` | LLM (Claude 直连) | [console.anthropic.com](https://console.anthropic.com) |
|
||||||
| `openai(待测试)` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
|
| `openai(待测试)` | LLM (GPT 直连) | [platform.openai.com](https://platform.openai.com) |
|
||||||
| `deepseek(待测试)` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
|
| `deepseek(待测试)` | LLM (DeepSeek 直连) | [platform.deepseek.com](https://platform.deepseek.com) |
|
||||||
|
| `qwen` | LLM (通义千问) | [dashscope.console.aliyun.com](https://dashscope.console.aliyun.com) |
|
||||||
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
|
| `groq` | LLM + **语音转录** (Whisper) | [console.groq.com](https://console.groq.com) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
|
||||||
|
|
@ -726,6 +726,7 @@ func statusCmd() {
|
||||||
hasOpenAI := cfg.Providers.OpenAI.APIKey != ""
|
hasOpenAI := cfg.Providers.OpenAI.APIKey != ""
|
||||||
hasGemini := cfg.Providers.Gemini.APIKey != ""
|
hasGemini := cfg.Providers.Gemini.APIKey != ""
|
||||||
hasZhipu := cfg.Providers.Zhipu.APIKey != ""
|
hasZhipu := cfg.Providers.Zhipu.APIKey != ""
|
||||||
|
hasQwen := cfg.Providers.Qwen.APIKey != ""
|
||||||
hasGroq := cfg.Providers.Groq.APIKey != ""
|
hasGroq := cfg.Providers.Groq.APIKey != ""
|
||||||
hasVLLM := cfg.Providers.VLLM.APIBase != ""
|
hasVLLM := cfg.Providers.VLLM.APIBase != ""
|
||||||
|
|
||||||
|
|
@ -740,6 +741,7 @@ func statusCmd() {
|
||||||
fmt.Println("OpenAI API:", status(hasOpenAI))
|
fmt.Println("OpenAI API:", status(hasOpenAI))
|
||||||
fmt.Println("Gemini API:", status(hasGemini))
|
fmt.Println("Gemini API:", status(hasGemini))
|
||||||
fmt.Println("Zhipu API:", status(hasZhipu))
|
fmt.Println("Zhipu API:", status(hasZhipu))
|
||||||
|
fmt.Println("Qwen API:", status(hasQwen))
|
||||||
fmt.Println("Groq API:", status(hasGroq))
|
fmt.Println("Groq API:", status(hasGroq))
|
||||||
if hasVLLM {
|
if hasVLLM {
|
||||||
fmt.Printf("vLLM/Local: ✓ %s\n", cfg.Providers.VLLM.APIBase)
|
fmt.Printf("vLLM/Local: ✓ %s\n", cfg.Providers.VLLM.APIBase)
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,10 @@
|
||||||
"api_key": "sk-xxx",
|
"api_key": "sk-xxx",
|
||||||
"api_base": ""
|
"api_base": ""
|
||||||
},
|
},
|
||||||
|
"qwen": {
|
||||||
|
"api_key": "sk-xxx",
|
||||||
|
"api_base": ""
|
||||||
|
},
|
||||||
"ollama": {
|
"ollama": {
|
||||||
"api_key": "",
|
"api_key": "",
|
||||||
"api_base": "http://localhost:11434/v1"
|
"api_base": "http://localhost:11434/v1"
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,13 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
||||||
Proxy: http.ProxyURL(proxyURL),
|
Proxy: http.ProxyURL(proxyURL),
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
} else if os.Getenv("HTTP_PROXY") != "" || os.Getenv("HTTPS_PROXY") != "" {
|
||||||
|
// Use environment proxy if configured
|
||||||
|
opts = append(opts, telego.WithHTTPClient(&http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
},
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
bot, err := telego.NewBot(telegramCfg.Token, opts...)
|
bot, err := telego.NewBot(telegramCfg.Token, opts...)
|
||||||
|
|
|
||||||
|
|
@ -180,6 +180,7 @@ type ProvidersConfig struct {
|
||||||
ShengSuanYun ProviderConfig `json:"shengsuanyun"`
|
ShengSuanYun ProviderConfig `json:"shengsuanyun"`
|
||||||
DeepSeek ProviderConfig `json:"deepseek"`
|
DeepSeek ProviderConfig `json:"deepseek"`
|
||||||
GitHubCopilot ProviderConfig `json:"github_copilot"`
|
GitHubCopilot ProviderConfig `json:"github_copilot"`
|
||||||
|
Qwen ProviderConfig `json:"qwen"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProviderConfig struct {
|
type ProviderConfig struct {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ var supportedProviders = map[string]bool{
|
||||||
"zhipu": true,
|
"zhipu": true,
|
||||||
"vllm": true,
|
"vllm": true,
|
||||||
"gemini": true,
|
"gemini": true,
|
||||||
|
"qwen": true,
|
||||||
|
"deepseek": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
var supportedChannels = map[string]bool{
|
var supportedChannels = map[string]bool{
|
||||||
|
|
@ -253,6 +255,15 @@ func MergeConfig(existing, incoming *config.Config) *config.Config {
|
||||||
if existing.Providers.Gemini.APIKey == "" {
|
if existing.Providers.Gemini.APIKey == "" {
|
||||||
existing.Providers.Gemini = incoming.Providers.Gemini
|
existing.Providers.Gemini = incoming.Providers.Gemini
|
||||||
}
|
}
|
||||||
|
if existing.Providers.DeepSeek.APIKey == "" {
|
||||||
|
existing.Providers.DeepSeek = incoming.Providers.DeepSeek
|
||||||
|
}
|
||||||
|
if existing.Providers.GitHubCopilot.APIBase == "" {
|
||||||
|
existing.Providers.GitHubCopilot = incoming.Providers.GitHubCopilot
|
||||||
|
}
|
||||||
|
if existing.Providers.Qwen.APIKey == "" {
|
||||||
|
existing.Providers.Qwen = incoming.Providers.Qwen
|
||||||
|
}
|
||||||
|
|
||||||
if !existing.Channels.Telegram.Enabled && incoming.Channels.Telegram.Enabled {
|
if !existing.Channels.Telegram.Enabled && incoming.Channels.Telegram.Enabled {
|
||||||
existing.Channels.Telegram = incoming.Channels.Telegram
|
existing.Channels.Telegram = incoming.Channels.Telegram
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ func (p *HTTPProvider) Chat(ctx context.Context, messages []Message, tools []Too
|
||||||
// Strip provider prefix from model name (e.g., moonshot/kimi-k2.5 -> kimi-k2.5, groq/openai/gpt-oss-120b -> openai/gpt-oss-120b, ollama/qwen2.5:14b -> qwen2.5:14b)
|
// Strip provider prefix from model name (e.g., moonshot/kimi-k2.5 -> kimi-k2.5, groq/openai/gpt-oss-120b -> openai/gpt-oss-120b, ollama/qwen2.5:14b -> qwen2.5:14b)
|
||||||
if idx := strings.Index(model, "/"); idx != -1 {
|
if idx := strings.Index(model, "/"); idx != -1 {
|
||||||
prefix := model[:idx]
|
prefix := model[:idx]
|
||||||
if prefix == "moonshot" || prefix == "nvidia" || prefix == "groq" || prefix == "ollama" {
|
if prefix == "moonshot" || prefix == "nvidia" || prefix == "groq" || prefix == "ollama" || prefix == "qwen" {
|
||||||
model = model[idx+1:]
|
model = model[idx+1:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,6 +324,14 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
|
||||||
model = "deepseek-chat"
|
model = "deepseek-chat"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "qwen":
|
||||||
|
if cfg.Providers.Qwen.APIKey != "" {
|
||||||
|
apiKey = cfg.Providers.Qwen.APIKey
|
||||||
|
apiBase = cfg.Providers.Qwen.APIBase
|
||||||
|
if apiBase == "" {
|
||||||
|
apiBase = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||||
|
}
|
||||||
|
}
|
||||||
case "github_copilot", "copilot":
|
case "github_copilot", "copilot":
|
||||||
if cfg.Providers.GitHubCopilot.APIBase != "" {
|
if cfg.Providers.GitHubCopilot.APIBase != "" {
|
||||||
apiBase = cfg.Providers.GitHubCopilot.APIBase
|
apiBase = cfg.Providers.GitHubCopilot.APIBase
|
||||||
|
|
@ -402,6 +410,14 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
|
||||||
apiBase = "https://api.groq.com/openai/v1"
|
apiBase = "https://api.groq.com/openai/v1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case (strings.Contains(lowerModel, "qwen") || strings.HasPrefix(model, "qwen/")) && cfg.Providers.Qwen.APIKey != "":
|
||||||
|
apiKey = cfg.Providers.Qwen.APIKey
|
||||||
|
apiBase = cfg.Providers.Qwen.APIBase
|
||||||
|
proxy = cfg.Providers.Qwen.Proxy
|
||||||
|
if apiBase == "" {
|
||||||
|
apiBase = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||||
|
}
|
||||||
|
|
||||||
case (strings.Contains(lowerModel, "nvidia") || strings.HasPrefix(model, "nvidia/")) && cfg.Providers.Nvidia.APIKey != "":
|
case (strings.Contains(lowerModel, "nvidia") || strings.HasPrefix(model, "nvidia/")) && cfg.Providers.Nvidia.APIKey != "":
|
||||||
apiKey = cfg.Providers.Nvidia.APIKey
|
apiKey = cfg.Providers.Nvidia.APIKey
|
||||||
apiBase = cfg.Providers.Nvidia.APIBase
|
apiBase = cfg.Providers.Nvidia.APIBase
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue