diff --git a/README.md b/README.md
index 2c58bc12..7478b99d 100644
--- a/README.md
+++ b/README.md
@@ -218,7 +218,7 @@ cow install-browser
2. 其他配置
-+ `model`: 模型名称,Agent 模式下推荐使用 `MiniMax-M2.7`、`glm-5-turbo`、`kimi-k2.5`、`qwen3.5-plus`、`claude-sonnet-4-6`、`gemini-3.1-pro-preview`,全部模型名称参考[common/const.py](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py)文件
++ `model`: 模型名称,Agent 模式下推荐使用 `MiniMax-M2.7`、`glm-5-turbo`、`kimi-k2.5`、`qwen3.6-plus`、`claude-sonnet-4-6`、`gemini-3.1-pro-preview`,全部模型名称参考[common/const.py](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py)文件
+ `character_desc`:普通对话模式下的机器人系统提示词。在 Agent 模式下该配置不生效,由工作空间中的文件内容构成。
+ `subscribe_msg`:订阅消息,公众号和企业微信 channel 中请填写,当被订阅时会自动回复, 可使用特殊占位符。目前支持的占位符有{trigger_prefix},在程序中它会自动替换成 bot 的触发词。
@@ -303,7 +303,7 @@ sudo docker logs -f chatgpt-on-wechat
## 模型说明
-以下对所有可支持的模型的配置和使用方法进行说明,模型接口实现在项目的 `models/` 目录下。
+推荐通过 Web 控制台在线管理模型配置,无需手动编辑文件,详见 [模型文档](https://docs.cowagent.ai/models)。以下是手动修改 `config.json` 配置模型的说明:
OpenAI
@@ -411,18 +411,18 @@ sudo docker logs -f chatgpt-on-wechat
```json
{
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"dashscope_api_key": "sk-qVxxxxG"
}
```
- - `model`: 可填写 `qwen3.5-plus、qwen3-max、qwen-max、qwen-plus、qwen-turbo、qwen-long、qwq-plus` 等
- - `dashscope_api_key`: 通义千问的 API-KEY,参考 [官方文档](https://bailian.console.aliyun.com/?tab=api#/api) ,在 [控制台](https://bailian.console.aliyun.com/?tab=model#/api-key) 创建
+ - `model`: 可填写 `qwen3.6-plus、qwen3.5-plus、qwen3-max、qwen-max、qwen-plus、qwen-turbo、qwen-long、qwq-plus` 等
+ - `dashscope_api_key`: 通义千问的 API-KEY,参考 [官方文档](https://bailian.console.aliyun.com/?tab=api#/api) ,在 [百炼控制台](https://bailian.console.aliyun.com/?tab=model#/api-key) 创建
方式二:OpenAI 兼容方式接入,配置如下:
```json
{
"bot_type": "openai",
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"open_ai_api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"open_ai_api_key": "sk-qVxxxxG"
}
@@ -674,7 +674,7 @@ Coding Plan 是各厂商推出的编程包月套餐,所有厂商均可通过 O
## 通道说明
-以下对可接入通道的配置方式进行说明,应用通道代码在项目的 `channel/` 目录下。
+推荐通过 Web 控制台在线管理通道配置,无需手动编辑文件,详见 [通道文档](https://docs.cowagent.ai/channels/weixin)。以下为手动修改 `config.json` 配置通道的说明:
支持同时可接入多个通道,配置时可通过逗号进行分割,例如 `"channel_type": "feishu,dingtalk"`。
diff --git a/bridge/agent_bridge.py b/bridge/agent_bridge.py
index 8f81f325..84b7aad6 100644
--- a/bridge/agent_bridge.py
+++ b/bridge/agent_bridge.py
@@ -67,7 +67,7 @@ class AgentLLMModel(LLMModel):
_MODEL_BOT_TYPE_MAP = {
"wenxin": const.BAIDU, "wenxin-4": const.BAIDU,
- "xunfei": const.XUNFEI, const.QWEN: const.QWEN,
+ "xunfei": const.XUNFEI, const.QWEN: const.QWEN_DASHSCOPE,
const.MODELSCOPE: const.MODELSCOPE,
}
_MODEL_PREFIX_MAP = [
diff --git a/bridge/bridge.py b/bridge/bridge.py
index 388c2999..3cf55a80 100644
--- a/bridge/bridge.py
+++ b/bridge/bridge.py
@@ -39,11 +39,8 @@ class Bridge(object):
self.btype["chat"] = const.BAIDU
if model_type in ["xunfei"]:
self.btype["chat"] = const.XUNFEI
- if model_type in [const.QWEN]:
- self.btype["chat"] = const.QWEN
- if model_type in [const.QWEN_TURBO, const.QWEN_PLUS, const.QWEN_MAX]:
+ if model_type in [const.QWEN, const.QWEN_TURBO, const.QWEN_PLUS, const.QWEN_MAX]:
self.btype["chat"] = const.QWEN_DASHSCOPE
- # Support Qwen3 and other DashScope models
if model_type and (model_type.startswith("qwen") or model_type.startswith("qwq") or model_type.startswith("qvq")):
self.btype["chat"] = const.QWEN_DASHSCOPE
if model_type and model_type.startswith("gemini"):
diff --git a/channel/web/web_channel.py b/channel/web/web_channel.py
index a7ea74ed..a5bf389a 100644
--- a/channel/web/web_channel.py
+++ b/channel/web/web_channel.py
@@ -563,7 +563,7 @@ class ConfigHandler:
_RECOMMENDED_MODELS = [
const.MINIMAX_M2_7, const.MINIMAX_M2_5, const.MINIMAX_M2_1, const.MINIMAX_M2_1_LIGHTNING,
const.GLM_5_TURBO, const.GLM_5, const.GLM_4_7,
- const.QWEN35_PLUS, const.QWEN3_MAX,
+ const.QWEN36_PLUS, const.QWEN35_PLUS, const.QWEN3_MAX,
const.KIMI_K2_5, const.KIMI_K2,
const.DOUBAO_SEED_2_PRO, const.DOUBAO_SEED_2_CODE,
const.CLAUDE_4_6_SONNET, const.CLAUDE_4_6_OPUS, const.CLAUDE_4_5_SONNET,
@@ -592,7 +592,7 @@ class ConfigHandler:
"api_key_field": "dashscope_api_key",
"api_base_key": None,
"api_base_default": None,
- "models": [const.QWEN35_PLUS, const.QWEN3_MAX],
+ "models": [const.QWEN36_PLUS, const.QWEN35_PLUS, const.QWEN3_MAX],
}),
("moonshot", {
"label": "Kimi",
diff --git a/common/const.py b/common/const.py
index 654ee5da..f7e67e52 100644
--- a/common/const.py
+++ b/common/const.py
@@ -7,8 +7,8 @@ XUNFEI = "xunfei"
CHATGPTONAZURE = "chatGPTOnAzure"
LINKAI = "linkai"
CLAUDEAPI= "claudeAPI"
-QWEN = "qwen" # 旧版千问接入
-QWEN_DASHSCOPE = "dashscope" # 新版千问接入(百炼)
+QWEN = "qwen" # 千问 (兼容旧配置,实际走 DashscopeBot)
+QWEN_DASHSCOPE = "dashscope" # 千问 DashScope 接入
GEMINI = "gemini"
ZHIPU_AI = "zhipu"
MOONSHOT = "moonshot"
@@ -81,14 +81,14 @@ TTS_1_HD = "tts-1-hd"
DEEPSEEK_CHAT = "deepseek-chat" # DeepSeek-V3对话模型
DEEPSEEK_REASONER = "deepseek-reasoner" # DeepSeek-R1模型
-# Qwen (通义千问 - 阿里云)
-QWEN = "qwen"
+# Qwen (通义千问 - 阿里云 DashScope)
QWEN_TURBO = "qwen-turbo"
QWEN_PLUS = "qwen-plus"
QWEN_MAX = "qwen-max"
QWEN_LONG = "qwen-long"
QWEN3_MAX = "qwen3-max" # Qwen3 Max - Agent推荐模型
QWEN35_PLUS = "qwen3.5-plus" # Qwen3.5 Plus - Omni model (MultiModalConversation)
+QWEN36_PLUS = "qwen3.6-plus" # Qwen3.6 Plus - Omni model (MultiModalConversation)
QWQ_PLUS = "qwq-plus"
# MiniMax
@@ -172,7 +172,7 @@ MODEL_LIST = [
DEEPSEEK_CHAT, DEEPSEEK_REASONER,
# Qwen
- QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG, QWEN,
+ QWEN36_PLUS, QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG,
# MiniMax
MiniMax, MINIMAX_M2_7, MINIMAX_M2_5, MINIMAX_M2_1, MINIMAX_M2_1_LIGHTNING, MINIMAX_M2, MINIMAX_ABAB6_5,
diff --git a/docs/en/README.md b/docs/en/README.md
index 3090e1b1..8b75ed25 100644
--- a/docs/en/README.md
+++ b/docs/en/README.md
@@ -165,7 +165,7 @@ Supports mainstream model providers. Recommended models for Agent mode:
| GLM | `glm-5-turbo` |
| Kimi | `kimi-k2.5` |
| Doubao | `doubao-seed-2-0-code-preview-260215` |
-| Qwen | `qwen3.5-plus` |
+| Qwen | `qwen3.6-plus` |
| Claude | `claude-sonnet-4-6` |
| Gemini | `gemini-3.1-pro-preview` |
| OpenAI | `gpt-5.4` |
diff --git a/docs/en/models/index.mdx b/docs/en/models/index.mdx
index 8d76af86..90fde345 100644
--- a/docs/en/models/index.mdx
+++ b/docs/en/models/index.mdx
@@ -6,7 +6,7 @@ description: Supported models and recommended choices for CowAgent
CowAgent supports mainstream LLMs from domestic and international providers. Model interfaces are implemented in the project's `models/` directory.
- For Agent mode, the following models are recommended based on quality and cost: MiniMax-M2.7, glm-5-turbo, kimi-k2.5, qwen3.5-plus, claude-sonnet-4-6, gemini-3.1-pro-preview
+ For Agent mode, the following models are recommended based on quality and cost: MiniMax-M2.7, glm-5-turbo, kimi-k2.5, qwen3.6-plus, claude-sonnet-4-6, gemini-3.1-pro-preview
## Configuration
@@ -25,7 +25,7 @@ You can also use the [LinkAI](https://link-ai.tech) platform interface to flexib
glm-5-turbo, glm-5 and other series models
- qwen3.5-plus, qwen3-max and more
+ qwen3.6-plus, qwen3-max and more
kimi-k2.5, kimi-k2 and more
diff --git a/docs/en/models/qwen.mdx b/docs/en/models/qwen.mdx
index 50dff08b..30f7e485 100644
--- a/docs/en/models/qwen.mdx
+++ b/docs/en/models/qwen.mdx
@@ -5,14 +5,14 @@ description: Tongyi Qianwen model configuration
```json
{
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"dashscope_api_key": "YOUR_API_KEY"
}
```
| Parameter | Description |
| --- | --- |
-| `model` | Options include `qwen3.5-plus`, `qwen3-max`, `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwq-plus`, etc. |
+| `model` | Options include `qwen3.6-plus`, `qwen3.5-plus`, `qwen3-max`, `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwq-plus`, etc. |
| `dashscope_api_key` | Create at [Bailian Console](https://bailian.console.aliyun.com/?tab=model#/api-key). See [official docs](https://bailian.console.aliyun.com/?tab=api#/api) |
OpenAI-compatible configuration is also supported:
@@ -20,7 +20,7 @@ OpenAI-compatible configuration is also supported:
```json
{
"bot_type": "openai",
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"open_ai_api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"open_ai_api_key": "YOUR_API_KEY"
}
diff --git a/docs/guide/upgrade.mdx b/docs/guide/upgrade.mdx
index 48b45005..7a36d706 100644
--- a/docs/guide/upgrade.mdx
+++ b/docs/guide/upgrade.mdx
@@ -36,7 +36,7 @@ pip3 install -e .
更新完成后重启服务:
```bash
-# 使用 Cow CLI
+# 使用 Cow CLI (推荐)
cow restart
# 或使用 run.sh
diff --git a/docs/ja/README.md b/docs/ja/README.md
index ac1bb879..eff98b6b 100644
--- a/docs/ja/README.md
+++ b/docs/ja/README.md
@@ -165,7 +165,7 @@ sudo docker logs -f chatgpt-on-wechat
| GLM | `glm-5-turbo` |
| Kimi | `kimi-k2.5` |
| Doubao | `doubao-seed-2-0-code-preview-260215` |
-| Qwen | `qwen3.5-plus` |
+| Qwen | `qwen3.6-plus` |
| Claude | `claude-sonnet-4-6` |
| Gemini | `gemini-3.1-pro-preview` |
| OpenAI | `gpt-5.4` |
diff --git a/docs/ja/models/index.mdx b/docs/ja/models/index.mdx
index 8d79416b..4cec8960 100644
--- a/docs/ja/models/index.mdx
+++ b/docs/ja/models/index.mdx
@@ -6,7 +6,7 @@ description: CowAgentがサポートするモデルとおすすめの選択肢
CowAgentは国内外の主要なLLMをサポートしています。モデルインターフェースはプロジェクトの`models/`ディレクトリに実装されています。
- Agent モードでは、品質とコストのバランスから以下のモデルをおすすめします: MiniMax-M2.7、glm-5-turbo、kimi-k2.5、qwen3.5-plus、claude-sonnet-4-6、gemini-3.1-pro-preview
+ Agent モードでは、品質とコストのバランスから以下のモデルをおすすめします: MiniMax-M2.7、glm-5-turbo、kimi-k2.5、qwen3.6-plus、claude-sonnet-4-6、gemini-3.1-pro-preview
## 設定
@@ -25,7 +25,7 @@ CowAgentは国内外の主要なLLMをサポートしています。モデルイ
glm-5-turbo、glm-5およびその他のシリーズモデル
- qwen3.5-plus、qwen3-maxなど
+ qwen3.6-plus、qwen3-maxなど
kimi-k2.5、kimi-k2など
diff --git a/docs/ja/models/qwen.mdx b/docs/ja/models/qwen.mdx
index 2e686d18..c491b5e3 100644
--- a/docs/ja/models/qwen.mdx
+++ b/docs/ja/models/qwen.mdx
@@ -1,18 +1,18 @@
---
-title: Qwen (通义千问)
-description: 通义千问モデルの設定
+title: Qwen (通義千問)
+description: 通義千問モデルの設定
---
```json
{
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"dashscope_api_key": "YOUR_API_KEY"
}
```
| パラメータ | 説明 |
| --- | --- |
-| `model` | `qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus`などから選択可能 |
+| `model` | `qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus`などから選択可能 |
| `dashscope_api_key` | [百炼 Console](https://bailian.console.aliyun.com/?tab=model#/api-key)で作成。[公式ドキュメント](https://bailian.console.aliyun.com/?tab=api#/api)を参照 |
OpenAI互換の設定もサポートしています:
@@ -20,7 +20,7 @@ OpenAI互換の設定もサポートしています:
```json
{
"bot_type": "openai",
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"open_ai_api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"open_ai_api_key": "YOUR_API_KEY"
}
diff --git a/docs/models/index.mdx b/docs/models/index.mdx
index 6f20d1b3..3e2b0a47 100644
--- a/docs/models/index.mdx
+++ b/docs/models/index.mdx
@@ -6,19 +6,20 @@ description: CowAgent 支持的模型及推荐选择
CowAgent 支持国内外主流厂商的大语言模型,模型接口实现在项目的 `models/` 目录下。
- Agent 模式下推荐使用以下模型,可根据效果及成本综合选择:MiniMax-M2.7、glm-5-turbo、kimi-k2.5、qwen3.5-plus、claude-sonnet-4-6、gemini-3.1-pro-preview
+ Agent 模式下推荐使用以下模型,可根据效果及成本综合选择:MiniMax-M2.7、glm-5-turbo、kimi-k2.5、qwen3.6-plus、claude-sonnet-4-6、gemini-3.1-pro-preview
+
+ 同时支持使用 [LinkAI](https://link-ai.tech) 平台接口,可灵活切换多种模型,并支持知识库、工作流、插件等 Agent 能力。
## 配置方式
-根据所选模型,在 `config.json` 中填写对应的模型名称和 API Key 即可。每个模型也支持 OpenAI 兼容方式接入,将 `bot_type` 设为 `openai`,配置 `open_ai_api_base` 和 `open_ai_api_key`。
-
-同时支持使用 [LinkAI](https://link-ai.tech) 平台接口,可灵活切换多种模型,并支持知识库、工作流、插件等 Agent 能力。
-
-也可以通过 [Web 控制台](/channels/web) 在线管理模型配置,无需手动编辑配置文件:
+**方式一(推荐):** 通过 [Web 控制台](/channels/web) 在线管理模型配置,无需手动编辑配置文件:
+**方式二:** 手动编辑 `config.json`,根据所选模型填写对应的模型名称和 API Key。每个模型也支持 OpenAI 兼容方式接入,将 `bot_type` 设为 `openai`,配置 `open_ai_api_base` 和 `open_ai_api_key` 即可。
+
+
## 支持的模型
@@ -29,7 +30,7 @@ CowAgent 支持国内外主流厂商的大语言模型,模型接口实现在
glm-5-turbo、glm-5 等系列模型
- qwen3.5-plus、qwen3-max 等
+ qwen3.6-plus、qwen3-max 等
kimi-k2.5、kimi-k2 等
@@ -54,6 +55,7 @@ CowAgent 支持国内外主流厂商的大语言模型,模型接口实现在
+
全部模型名称可参考项目 [`common/const.py`](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/common/const.py) 文件。
diff --git a/docs/models/qwen.mdx b/docs/models/qwen.mdx
index df670937..2bc6517d 100644
--- a/docs/models/qwen.mdx
+++ b/docs/models/qwen.mdx
@@ -5,14 +5,14 @@ description: 通义千问模型配置
```json
{
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"dashscope_api_key": "YOUR_API_KEY"
}
```
| 参数 | 说明 |
| --- | --- |
-| `model` | 可填 `qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus` 等 |
+| `model` | 可填 `qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus` 等 |
| `dashscope_api_key` | 在 [百炼控制台](https://bailian.console.aliyun.com/?tab=model#/api-key) 创建,参考 [官方文档](https://bailian.console.aliyun.com/?tab=api#/api) |
也支持 OpenAI 兼容方式接入:
@@ -20,7 +20,7 @@ description: 通义千问模型配置
```json
{
"bot_type": "openai",
- "model": "qwen3.5-plus",
+ "model": "qwen3.6-plus",
"open_ai_api_base": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"open_ai_api_key": "YOUR_API_KEY"
}
diff --git a/models/ali/ali_qwen_bot.py b/models/ali/ali_qwen_bot.py
deleted file mode 100644
index c8c25882..00000000
--- a/models/ali/ali_qwen_bot.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# encoding:utf-8
-
-import json
-import time
-from typing import List, Tuple
-
-import openai
-from models.openai.openai_compat import RateLimitError, Timeout, APIError, APIConnectionError
-import broadscope_bailian
-from broadscope_bailian import ChatQaMessage
-
-from models.bot import Bot
-from models.ali.ali_qwen_session import AliQwenSession
-from models.session_manager import SessionManager
-from bridge.context import ContextType
-from bridge.reply import Reply, ReplyType
-from common.log import logger
-from common import const
-from config import conf, load_config
-
-class AliQwenBot(Bot):
- def __init__(self):
- super().__init__()
- self.api_key_expired_time = self.set_api_key()
- self.sessions = SessionManager(AliQwenSession, model=conf().get("model", const.QWEN))
-
- def api_key_client(self):
- return broadscope_bailian.AccessTokenClient(access_key_id=self.access_key_id(), access_key_secret=self.access_key_secret())
-
- def access_key_id(self):
- return conf().get("qwen_access_key_id")
-
- def access_key_secret(self):
- return conf().get("qwen_access_key_secret")
-
- def agent_key(self):
- return conf().get("qwen_agent_key")
-
- def app_id(self):
- return conf().get("qwen_app_id")
-
- def node_id(self):
- return conf().get("qwen_node_id", "")
-
- def temperature(self):
- return conf().get("temperature", 0.2 )
-
- def top_p(self):
- return conf().get("top_p", 1)
-
- def reply(self, query, context=None):
- # acquire reply content
- if context.type == ContextType.TEXT:
- logger.info("[QWEN] query={}".format(query))
-
- session_id = context["session_id"]
- reply = None
- clear_memory_commands = conf().get("clear_memory_commands", ["#清除记忆"])
- if query in clear_memory_commands:
- self.sessions.clear_session(session_id)
- reply = Reply(ReplyType.INFO, "记忆已清除")
- elif query == "#清除所有":
- self.sessions.clear_all_session()
- reply = Reply(ReplyType.INFO, "所有人记忆已清除")
- elif query == "#更新配置":
- load_config()
- reply = Reply(ReplyType.INFO, "配置已更新")
- if reply:
- return reply
- session = self.sessions.session_query(query, session_id)
- logger.debug("[QWEN] session query={}".format(session.messages))
-
- reply_content = self.reply_text(session)
- logger.debug(
- "[QWEN] new_query={}, session_id={}, reply_cont={}, completion_tokens={}".format(
- session.messages,
- session_id,
- reply_content["content"],
- reply_content["completion_tokens"],
- )
- )
- if reply_content["completion_tokens"] == 0 and len(reply_content["content"]) > 0:
- reply = Reply(ReplyType.ERROR, reply_content["content"])
- elif reply_content["completion_tokens"] > 0:
- self.sessions.session_reply(reply_content["content"], session_id, reply_content["total_tokens"])
- reply = Reply(ReplyType.TEXT, reply_content["content"])
- else:
- reply = Reply(ReplyType.ERROR, reply_content["content"])
- logger.debug("[QWEN] reply {} used 0 tokens.".format(reply_content))
- return reply
-
- else:
- reply = Reply(ReplyType.ERROR, "Bot不支持处理{}类型的消息".format(context.type))
- return reply
-
- def reply_text(self, session: AliQwenSession, retry_count=0) -> dict:
- """
- call bailian's ChatCompletion to get the answer
- :param session: a conversation session
- :param retry_count: retry count
- :return: {}
- """
- try:
- prompt, history = self.convert_messages_format(session.messages)
- self.update_api_key_if_expired()
- # NOTE 阿里百炼的call()函数未提供temperature参数,考虑到temperature和top_p参数作用相同,取两者较小的值作为top_p参数传入,详情见文档 https://help.aliyun.com/document_detail/2587502.htm
- response = broadscope_bailian.Completions().call(app_id=self.app_id(), prompt=prompt, history=history, top_p=min(self.temperature(), self.top_p()))
- completion_content = self.get_completion_content(response, self.node_id())
- completion_tokens, total_tokens = self.calc_tokens(session.messages, completion_content)
- return {
- "total_tokens": total_tokens,
- "completion_tokens": completion_tokens,
- "content": completion_content,
- }
- except Exception as e:
- need_retry = retry_count < 2
- result = {"completion_tokens": 0, "content": "我现在有点累了,等会再来吧"}
- if isinstance(e, RateLimitError):
- logger.warn("[QWEN] RateLimitError: {}".format(e))
- result["content"] = "提问太快啦,请休息一下再问我吧"
- if need_retry:
- time.sleep(20)
- elif isinstance(e, Timeout):
- logger.warn("[QWEN] Timeout: {}".format(e))
- result["content"] = "我没有收到你的消息"
- if need_retry:
- time.sleep(5)
- elif isinstance(e, APIError):
- logger.warn("[QWEN] Bad Gateway: {}".format(e))
- result["content"] = "请再问我一次"
- if need_retry:
- time.sleep(10)
- elif isinstance(e, APIConnectionError):
- logger.warn("[QWEN] APIConnectionError: {}".format(e))
- need_retry = False
- result["content"] = "我连接不到你的网络"
- else:
- logger.exception("[QWEN] Exception: {}".format(e))
- need_retry = False
- self.sessions.clear_session(session.session_id)
-
- if need_retry:
- logger.warn("[QWEN] 第{}次重试".format(retry_count + 1))
- return self.reply_text(session, retry_count + 1)
- else:
- return result
-
- def set_api_key(self):
- api_key, expired_time = self.api_key_client().create_token(agent_key=self.agent_key())
- broadscope_bailian.api_key = api_key
- return expired_time
-
- def update_api_key_if_expired(self):
- if time.time() > self.api_key_expired_time:
- self.api_key_expired_time = self.set_api_key()
-
- def convert_messages_format(self, messages) -> Tuple[str, List[ChatQaMessage]]:
- history = []
- user_content = ''
- assistant_content = ''
- system_content = ''
- for message in messages:
- role = message.get('role')
- if role == 'user':
- user_content += message.get('content')
- elif role == 'assistant':
- assistant_content = message.get('content')
- history.append(ChatQaMessage(user_content, assistant_content))
- user_content = ''
- assistant_content = ''
- elif role =='system':
- system_content += message.get('content')
- if user_content == '':
- raise Exception('no user message')
- if system_content != '':
- # NOTE 模拟系统消息,测试发现人格描述以"你需要扮演ChatGPT"开头能够起作用,而以"你是ChatGPT"开头模型会直接否认
- system_qa = ChatQaMessage(system_content, '好的,我会严格按照你的设定回答问题')
- history.insert(0, system_qa)
- logger.debug("[QWEN] converted qa messages: {}".format([item.to_dict() for item in history]))
- logger.debug("[QWEN] user content as prompt: {}".format(user_content))
- return user_content, history
-
- def get_completion_content(self, response, node_id):
- if not response['Success']:
- return f"[ERROR]\n{response['Code']}:{response['Message']}"
- text = response['Data']['Text']
- if node_id == '':
- return text
- # TODO: 当使用流程编排创建大模型应用时,响应结构如下,最终结果在['finalResult'][node_id]['response']['text']中,暂时先这么写
- # {
- # 'Success': True,
- # 'Code': None,
- # 'Message': None,
- # 'Data': {
- # 'ResponseId': '9822f38dbacf4c9b8daf5ca03a2daf15',
- # 'SessionId': 'session_id',
- # 'Text': '{"finalResult":{"LLM_T7islK":{"params":{"modelId":"qwen-plus-v1","prompt":"${systemVars.query}${bizVars.Text}"},"response":{"text":"作为一个AI语言模型,我没有年龄,因为我没有生日。\n我只是一个程序,没有生命和身体。"}}}}',
- # 'Thoughts': [],
- # 'Debug': {},
- # 'DocReferences': []
- # },
- # 'RequestId': '8e11d31551ce4c3f83f49e6e0dd998b0',
- # 'Failed': None
- # }
- text_dict = json.loads(text)
- completion_content = text_dict['finalResult'][node_id]['response']['text']
- return completion_content
-
- def calc_tokens(self, messages, completion_content):
- completion_tokens = len(completion_content)
- prompt_tokens = 0
- for message in messages:
- prompt_tokens += len(message["content"])
- return completion_tokens, prompt_tokens + completion_tokens
diff --git a/models/ali/ali_qwen_session.py b/models/ali/ali_qwen_session.py
deleted file mode 100644
index 48c5eea7..00000000
--- a/models/ali/ali_qwen_session.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from models.session_manager import Session
-from common.log import logger
-
-"""
- e.g.
- [
- {"role": "system", "content": "You are a helpful assistant."},
- {"role": "user", "content": "Who won the world series in 2020?"},
- {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
- {"role": "user", "content": "Where was it played?"}
- ]
-"""
-
-class AliQwenSession(Session):
- def __init__(self, session_id, system_prompt=None, model="qianwen"):
- super().__init__(session_id, system_prompt)
- self.model = model
- self.reset()
-
- def discard_exceeding(self, max_tokens, cur_tokens=None):
- precise = True
- try:
- cur_tokens = self.calc_tokens()
- except Exception as e:
- precise = False
- if cur_tokens is None:
- raise e
- logger.debug("Exception when counting tokens precisely for query: {}".format(e))
- while cur_tokens > max_tokens:
- if len(self.messages) > 2:
- self.messages.pop(1)
- elif len(self.messages) == 2 and self.messages[1]["role"] == "assistant":
- self.messages.pop(1)
- if precise:
- cur_tokens = self.calc_tokens()
- else:
- cur_tokens = cur_tokens - max_tokens
- break
- elif len(self.messages) == 2 and self.messages[1]["role"] == "user":
- logger.warn("user message exceed max_tokens. total_tokens={}".format(cur_tokens))
- break
- else:
- logger.debug("max_tokens={}, total_tokens={}, len(messages)={}".format(max_tokens, cur_tokens, len(self.messages)))
- break
- if precise:
- cur_tokens = self.calc_tokens()
- else:
- cur_tokens = cur_tokens - max_tokens
- return cur_tokens
-
- def calc_tokens(self):
- return num_tokens_from_messages(self.messages, self.model)
-
-def num_tokens_from_messages(messages, model):
- """Returns the number of tokens used by a list of messages."""
- # 官方token计算规则:"对于中文文本来说,1个token通常对应一个汉字;对于英文文本来说,1个token通常对应3至4个字母或1个单词"
- # 详情请产看文档:https://help.aliyun.com/document_detail/2586397.html
- # 目前根据字符串长度粗略估计token数,不影响正常使用
- tokens = 0
- for msg in messages:
- tokens += len(msg["content"])
- return tokens
diff --git a/models/bot_factory.py b/models/bot_factory.py
index 5c91c7c6..5f2b9370 100644
--- a/models/bot_factory.py
+++ b/models/bot_factory.py
@@ -46,10 +46,7 @@ def create_bot(bot_type):
elif bot_type == const.CLAUDEAPI:
from models.claudeapi.claude_api_bot import ClaudeAPIBot
return ClaudeAPIBot()
- elif bot_type == const.QWEN:
- from models.ali.ali_qwen_bot import AliQwenBot
- return AliQwenBot()
- elif bot_type == const.QWEN_DASHSCOPE:
+ elif bot_type in (const.QWEN, const.QWEN_DASHSCOPE):
from models.dashscope.dashscope_bot import DashscopeBot
return DashscopeBot()
elif bot_type == const.GEMINI:
diff --git a/models/dashscope/dashscope_bot.py b/models/dashscope/dashscope_bot.py
index 1b677317..0887751f 100644
--- a/models/dashscope/dashscope_bot.py
+++ b/models/dashscope/dashscope_bot.py
@@ -26,15 +26,15 @@ dashscope_models = {
# Model name prefixes that require MultiModalConversation API instead of Generation API.
# Qwen3.5+ series are omni models that only support MultiModalConversation.
-MULTIMODAL_MODEL_PREFIXES = ("qwen3.5-",)
+MULTIMODAL_MODEL_PREFIXES = ("qwen3.5-", "qwen3.6-")
# Qwen对话模型API
class DashscopeBot(Bot):
def __init__(self):
super().__init__()
- self.sessions = SessionManager(DashscopeSession, model=conf().get("model") or "qwen-plus")
- self.model_name = conf().get("model") or "qwen-plus"
+ self.sessions = SessionManager(DashscopeSession, model=conf().get("model") or "qwen3.6-plus")
+ self.model_name = conf().get("model") or "qwen3.6-plus"
self.client = dashscope.Generation
api_key = conf().get("dashscope_api_key")
if api_key:
diff --git a/plugins/cow_cli/cow_cli.py b/plugins/cow_cli/cow_cli.py
index aed0b410..d08a8414 100644
--- a/plugins/cow_cli/cow_cli.py
+++ b/plugins/cow_cli/cow_cli.py
@@ -407,7 +407,7 @@ class CowCliPlugin(Plugin):
from common import const
_EXACT = {
"wenxin": const.BAIDU, "wenxin-4": const.BAIDU,
- "xunfei": const.XUNFEI, const.QWEN: const.QWEN,
+ "xunfei": const.XUNFEI, const.QWEN: const.QWEN_DASHSCOPE,
const.MODELSCOPE: const.MODELSCOPE,
const.MOONSHOT: const.MOONSHOT,
"moonshot-v1-8k": const.MOONSHOT, "moonshot-v1-32k": const.MOONSHOT,
diff --git a/plugins/godcmd/godcmd.py b/plugins/godcmd/godcmd.py
index d844a506..6439411d 100644
--- a/plugins/godcmd/godcmd.py
+++ b/plugins/godcmd/godcmd.py
@@ -315,7 +315,7 @@ class Godcmd(Plugin):
except Exception as e:
ok, result = False, "你没有设置私有GPT模型"
elif cmd == "reset":
- if bottype in [const.OPEN_AI, const.OPENAI, const.CHATGPT, const.CHATGPTONAZURE, const.LINKAI, const.BAIDU, const.XUNFEI, const.QWEN, const.GEMINI, const.ZHIPU_AI, const.CLAUDEAPI]:
+ if bottype in [const.OPEN_AI, const.OPENAI, const.CHATGPT, const.CHATGPTONAZURE, const.LINKAI, const.BAIDU, const.XUNFEI, const.QWEN, const.QWEN_DASHSCOPE, const.GEMINI, const.ZHIPU_AI, const.CLAUDEAPI]:
bot.sessions.clear_session(session_id)
if Bridge().chat_bots.get(bottype):
Bridge().chat_bots.get(bottype).sessions.clear_session(session_id)
@@ -341,7 +341,7 @@ class Godcmd(Plugin):
ok, result = True, "配置已重载"
elif cmd == "resetall":
if bottype in [const.OPEN_AI, const.OPENAI, const.CHATGPT, const.CHATGPTONAZURE, const.LINKAI,
- const.BAIDU, const.XUNFEI, const.QWEN, const.GEMINI, const.ZHIPU_AI, const.MOONSHOT,
+ const.BAIDU, const.XUNFEI, const.QWEN, const.QWEN_DASHSCOPE, const.GEMINI, const.ZHIPU_AI, const.MOONSHOT,
const.MODELSCOPE]:
channel.cancel_all_session()
bot.sessions.clear_all_session()
diff --git a/run.sh b/run.sh
index 0ee3aa0c..ab47faf4 100755
--- a/run.sh
+++ b/run.sh
@@ -271,7 +271,7 @@ select_model() {
echo -e "${YELLOW}2) Zhipu AI (glm-5-turbo, glm-5, etc.)${NC}"
echo -e "${YELLOW}3) Kimi (kimi-k2.5, kimi-k2, etc.)${NC}"
echo -e "${YELLOW}4) Doubao (doubao-seed-2-0-code-preview-260215, etc.)${NC}"
- echo -e "${YELLOW}5) Qwen (qwen3.5-plus, qwen3-max, qwq-plus, etc.)${NC}"
+ echo -e "${YELLOW}5) Qwen (qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)${NC}"
echo -e "${YELLOW}6) Claude (claude-sonnet-4-6, claude-opus-4-6, etc.)${NC}"
echo -e "${YELLOW}7) Gemini (gemini-3.1-flash-lite-preview, gemini-3.1-pro-preview, etc.)${NC}"
echo -e "${YELLOW}8) OpenAI GPT (gpt-5.4, gpt-5.2, gpt-4.1, etc.)${NC}"
@@ -318,7 +318,7 @@ configure_model() {
2) read_model_config "Zhipu AI" "glm-5-turbo" "ZHIPU_KEY" ;;
3) read_model_config "Kimi (Moonshot)" "kimi-k2.5" "MOONSHOT_KEY" ;;
4) read_model_config "Doubao (Volcengine Ark)" "doubao-seed-2-0-code-preview-260215" "ARK_KEY" ;;
- 5) read_model_config "Qwen (DashScope)" "qwen3.5-plus" "DASHSCOPE_KEY" ;;
+ 5) read_model_config "Qwen (DashScope)" "qwen3.6-plus" "DASHSCOPE_KEY" ;;
6)
read_model_config "Claude" "claude-sonnet-4-6" "CLAUDE_KEY"
read_api_base "CLAUDE_BASE" "https://api.anthropic.com/v1"
diff --git a/scripts/run.ps1 b/scripts/run.ps1
index aaa99a47..b68a4bd9 100644
--- a/scripts/run.ps1
+++ b/scripts/run.ps1
@@ -154,7 +154,7 @@ $ModelChoices = @{
"2" = @{ Provider = "Zhipu AI"; Default = "glm-5-turbo"; Key = "ZHIPU_KEY" }
"3" = @{ Provider = "Kimi (Moonshot)"; Default = "kimi-k2.5"; Key = "MOONSHOT_KEY" }
"4" = @{ Provider = "Doubao (Volcengine Ark)"; Default = "doubao-seed-2-0-code-preview-260215"; Key = "ARK_KEY" }
- "5" = @{ Provider = "Qwen (DashScope)"; Default = "qwen3.5-plus"; Key = "DASHSCOPE_KEY" }
+ "5" = @{ Provider = "Qwen (DashScope)"; Default = "qwen3.6-plus"; Key = "DASHSCOPE_KEY" }
"6" = @{ Provider = "Claude"; Default = "claude-sonnet-4-6"; Key = "CLAUDE_KEY"; Base = "https://api.anthropic.com/v1" }
"7" = @{ Provider = "Gemini"; Default = "gemini-3.1-pro-preview"; Key = "GEMINI_KEY"; Base = "https://generativelanguage.googleapis.com" }
"8" = @{ Provider = "OpenAI GPT"; Default = "gpt-5.4"; Key = "OPENAI_KEY"; Base = "https://api.openai.com/v1" }
@@ -169,7 +169,7 @@ function Select-Model {
Write-Host "2) Zhipu AI (glm-5-turbo, glm-5, etc.)"
Write-Host "3) Kimi (kimi-k2.5, kimi-k2, etc.)"
Write-Host "4) Doubao (doubao-seed-2-0-code-preview-260215, etc.)"
- Write-Host "5) Qwen (qwen3.5-plus, qwen3-max, qwq-plus, etc.)"
+ Write-Host "5) Qwen (qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)"
Write-Host "6) Claude (claude-sonnet-4-6, claude-opus-4-6, etc.)"
Write-Host "7) Gemini (gemini-3.1-flash-lite-preview, gemini-3.1-pro-preview, etc.)"
Write-Host "8) OpenAI GPT (gpt-5.4, gpt-5.2, gpt-4.1, etc.)"