From 92ec9653e54ccb9f05514c176a14f06092650a90 Mon Sep 17 00:00:00 2001 From: zhayujie Date: Tue, 2 Jun 2026 16:38:17 +0800 Subject: [PATCH] feat(models): support qwen3.7-plus multi-modal model --- README.md | 2 +- agent/tools/vision/vision.py | 4 +- channel/web/web_channel.py | 10 ++--- common/const.py | 3 +- docs/ja/README.md | 2 +- docs/ja/models/index.mdx | 4 +- docs/ja/models/linkai.mdx | 2 +- docs/ja/models/qwen.mdx | 10 ++--- docs/ja/tools/vision.mdx | 2 +- docs/models/index.mdx | 2 +- docs/models/linkai.mdx | 2 +- docs/models/qwen.mdx | 10 ++--- docs/tools/vision.mdx | 2 +- docs/zh/README.md | 2 +- docs/zh/models/index.mdx | 2 +- docs/zh/models/linkai.mdx | 2 +- docs/zh/models/qwen.mdx | 10 ++--- docs/zh/tools/vision.mdx | 2 +- models/dashscope/dashscope_bot.py | 6 +-- run.sh | 4 +- scripts/run.ps1 | 4 +- tests/test_dashscope_provider.py | 63 +++++++++++++++++++++++++++++++ 22 files changed, 107 insertions(+), 43 deletions(-) create mode 100644 tests/test_dashscope_provider.py diff --git a/README.md b/README.md index c273637b..95ca70d2 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ CowAgent supports all mainstream LLM providers. **Chat, vision, image generation | [OpenAI](https://docs.cowagent.ai/models/openai) | gpt-5.5, o-series | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Gemini](https://docs.cowagent.ai/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [DeepSeek](https://docs.cowagent.ai/models/deepseek) | deepseek-v4-flash / pro | ✅ | | | | | | -| [Qwen](https://docs.cowagent.ai/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Qwen](https://docs.cowagent.ai/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [GLM](https://docs.cowagent.ai/models/glm) | glm-5.1, glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | | [Doubao](https://docs.cowagent.ai/models/doubao) | doubao-seed-2.0 series | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](https://docs.cowagent.ai/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | diff --git a/agent/tools/vision/vision.py b/agent/tools/vision/vision.py index 498f3cd8..e022b4f3 100644 --- a/agent/tools/vision/vision.py +++ b/agent/tools/vision/vision.py @@ -51,7 +51,7 @@ _MAIN_MODEL_PROVIDER_NAME = "MainModel" _DISCOVERABLE_MODELS = [ ("moonshot_api_key", const.MOONSHOT, const.KIMI_K2_6, "Moonshot"), ("ark_api_key", const.DOUBAO, const.DOUBAO_SEED_2_PRO, "Doubao"), - ("dashscope_api_key", const.QWEN_DASHSCOPE, const.QWEN36_PLUS, "DashScope"), + ("dashscope_api_key", const.QWEN_DASHSCOPE, const.QWEN37_PLUS, "DashScope"), ("claude_api_key", const.CLAUDEAPI, const.CLAUDE_4_6_SONNET, "Claude"), ("gemini_api_key", const.GEMINI, const.GEMINI_35_FLASH, "Gemini"), ("qianfan_api_key", const.QIANFAN, const.ERNIE_45_TURBO_VL, "Qianfan"), @@ -161,7 +161,7 @@ class Vision(BaseTool): "Error: No model available for Vision.\n" "The main model does not support vision and no other API keys are configured.\n" "Options:\n" - " 1. Switch to a multimodal model (e.g. ernie-4.5-turbo-vl, qwen3.6-plus, claude-sonnet-4-6, gemini-2.0-flash)\n" + " 1. Switch to a multimodal model (e.g. ernie-4.5-turbo-vl, qwen3.7-plus, claude-sonnet-4-6, gemini-2.0-flash)\n" " 2. Configure OPENAI_API_KEY: env_config(action=\"set\", key=\"OPENAI_API_KEY\", value=\"your-key\")\n" " 3. Configure LINKAI_API_KEY: env_config(action=\"set\", key=\"LINKAI_API_KEY\", value=\"your-key\")" ) diff --git a/channel/web/web_channel.py b/channel/web/web_channel.py index 8eb9cbd2..92cd9fcf 100644 --- a/channel/web/web_channel.py +++ b/channel/web/web_channel.py @@ -1409,7 +1409,7 @@ class ConfigHandler: const.GEMINI_35_FLASH, const.GEMINI_31_FLASH_LITE_PRE, const.GEMINI_31_PRO_PRE, const.GEMINI_3_FLASH_PRE, const.GPT_55, const.GPT_54, const.GPT_54_MINI, const.GPT_54_NANO, const.GPT_5, const.GPT_41, const.GPT_4o, const.GLM_5_1, const.GLM_5_TURBO, const.GLM_5, const.GLM_4_7, - const.QWEN36_PLUS, const.QWEN37_MAX, const.QWEN35_PLUS, const.QWEN3_MAX, + const.QWEN37_PLUS, const.QWEN37_MAX, const.QWEN36_PLUS, const.DOUBAO_SEED_2_PRO, const.DOUBAO_SEED_2_CODE, const.KIMI_K2_6, const.KIMI_K2_5, const.KIMI_K2, const.ERNIE_5_1, const.ERNIE_5, const.ERNIE_X1_1, const.ERNIE_45_TURBO_128K, const.ERNIE_45_TURBO_32K, @@ -1482,7 +1482,7 @@ class ConfigHandler: "api_base_key": None, "api_base_default": None, "api_base_placeholder": "", - "models": [const.QWEN36_PLUS, const.QWEN37_MAX, const.QWEN35_PLUS, const.QWEN3_MAX], + "models": [const.QWEN37_PLUS, const.QWEN37_MAX, const.QWEN36_PLUS], }), ("doubao", { "label": {"zh": "豆包", "en": "Doubao"}, @@ -1986,7 +1986,7 @@ class ModelsHandler: ], "doubao": [const.DOUBAO_SEED_2_PRO], "moonshot": [const.KIMI_K2_6], - "dashscope": [const.QWEN36_PLUS, const.QWEN35_PLUS, const.QWEN3_MAX], + "dashscope": [const.QWEN37_PLUS, const.QWEN36_PLUS], "claudeAPI": [const.CLAUDE_4_8_OPUS, const.CLAUDE_4_7_OPUS, const.CLAUDE_4_6_SONNET, const.CLAUDE_4_6_OPUS], "gemini": [const.GEMINI_35_FLASH, const.GEMINI_31_FLASH_LITE_PRE, const.GEMINI_31_PRO_PRE, const.GEMINI_3_FLASH_PRE], "qianfan": [const.ERNIE_45_TURBO_VL], @@ -2007,7 +2007,7 @@ class ModelsHandler: "linkai": [ const.GPT_41_MINI, const.GPT_54_MINI, - const.QWEN36_PLUS, + const.QWEN37_PLUS, const.DOUBAO_SEED_2_PRO, const.KIMI_K2_6, const.CLAUDE_4_6_SONNET, @@ -2124,7 +2124,7 @@ class ModelsHandler: _VISION_AUTO_ORDER = [ ("moonshot", "moonshot_api_key", const.KIMI_K2_6), ("doubao", "ark_api_key", const.DOUBAO_SEED_2_PRO), - ("dashscope", "dashscope_api_key", const.QWEN36_PLUS), + ("dashscope", "dashscope_api_key", const.QWEN37_PLUS), ("claudeAPI", "claude_api_key", const.CLAUDE_4_6_SONNET), ("gemini", "gemini_api_key", const.GEMINI_35_FLASH), ("qianfan", "qianfan_api_key", const.ERNIE_45_TURBO_VL), diff --git a/common/const.py b/common/const.py index fa56d273..53db4984 100644 --- a/common/const.py +++ b/common/const.py @@ -108,6 +108,7 @@ 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) +QWEN37_PLUS = "qwen3.7-plus" # Qwen3.7 Plus - Omni model (MultiModalConversation) QWEN37_MAX = "qwen3.7-max" # Qwen3.7 Max - Agent推荐模型 QWQ_PLUS = "qwq-plus" @@ -215,7 +216,7 @@ MODEL_LIST = [ GLM_4_0520, GLM_4_AIR, GLM_4_AIRX, GLM_4_7, # Qwen (通义千问) - QWEN37_MAX, QWEN36_PLUS, QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG, + QWEN37_PLUS, QWEN37_MAX, QWEN36_PLUS, QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG, # Doubao (豆包) DOUBAO, DOUBAO_SEED_2_CODE, DOUBAO_SEED_2_PRO, DOUBAO_SEED_2_LITE, DOUBAO_SEED_2_MINI, diff --git a/docs/ja/README.md b/docs/ja/README.md index 32722fcc..99a1e6c3 100644 --- a/docs/ja/README.md +++ b/docs/ja/README.md @@ -98,7 +98,7 @@ CowAgent は主要な LLM プロバイダーすべてに対応しています。 | [OpenAI](https://docs.cowagent.ai/ja/models/openai) | gpt-5.5、o シリーズ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Gemini](https://docs.cowagent.ai/ja/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [DeepSeek](https://docs.cowagent.ai/ja/models/deepseek) | deepseek-v4-flash / pro | ✅ | | | | | | -| [Qwen](https://docs.cowagent.ai/ja/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Qwen](https://docs.cowagent.ai/ja/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [GLM](https://docs.cowagent.ai/ja/models/glm) | glm-5.1、glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | | [Doubao](https://docs.cowagent.ai/ja/models/doubao) | doubao-seed-2.0 シリーズ | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](https://docs.cowagent.ai/ja/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | diff --git a/docs/ja/models/index.mdx b/docs/ja/models/index.mdx index 33e42c89..916ac469 100644 --- a/docs/ja/models/index.mdx +++ b/docs/ja/models/index.mdx @@ -6,7 +6,7 @@ description: CowAgent がサポートするモデルベンダーと機能マト CowAgent は国内外の主要ベンダーの大規模言語モデルをサポートしており、モデル接続の実装はプロジェクトの `models/` ディレクトリにあります。テキスト対話に加えて、一部のベンダーは画像理解、画像生成、音声認識、音声合成、ベクトルなどの機能も提供しており、Agent フローの中で必要に応じて呼び出すことができます。 - Agent モードでは、効果とコストのバランスを考慮して以下のモデルの利用を推奨します:deepseek-v4-flash、MiniMax-M3、claude-sonnet-4-6、gemini-3.5-flash、glm-5.1、qwen3.6-plus、kimi-k2.6、ernie-5.1。 + Agent モードでは、効果とコストのバランスを考慮して以下のモデルの利用を推奨します:deepseek-v4-flash、MiniMax-M3、claude-sonnet-4-6、gemini-3.5-flash、glm-5.1、qwen3.7-plus、kimi-k2.6、ernie-5.1。 同時に [LinkAI](https://link-ai.tech) プラットフォームの API もサポートしており、1 つの Key で複数ベンダーを柔軟に切り替えられ、ナレッジベース、ワークフロー、プラグインなどの機能も付属しています。 @@ -24,7 +24,7 @@ CowAgent は国内外の主要ベンダーの大規模言語モデルをサポ | [Gemini](/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [OpenAI](/models/openai) | gpt-5.5、o シリーズ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Zhipu GLM](/models/glm) | glm-5.1、glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | -| [Tongyi Qianwen](/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Tongyi Qianwen](/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Doubao](/models/doubao) | doubao-seed-2.0 シリーズ | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | | [Baidu Qianfan](/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | | diff --git a/docs/ja/models/linkai.mdx b/docs/ja/models/linkai.mdx index a19c943c..a1152a2c 100644 --- a/docs/ja/models/linkai.mdx +++ b/docs/ja/models/linkai.mdx @@ -40,7 +40,7 @@ description: LinkAI プラットフォーム経由でテキスト、ビジョン } ``` -選択可能なモデル:`gpt-4.1-mini`、`gpt-5.4-mini`、`qwen3.6-plus`、`doubao-seed-2-0-pro-260215`、`kimi-k2.6`、`claude-sonnet-4-6`、`gemini-3.1-flash-lite-preview` など。 +選択可能なモデル:`gpt-4.1-mini`、`gpt-5.4-mini`、`qwen3.7-plus`、`doubao-seed-2-0-pro-260215`、`kimi-k2.6`、`claude-sonnet-4-6`、`gemini-3.1-flash-lite-preview` など。 ## 画像生成 diff --git a/docs/ja/models/qwen.mdx b/docs/ja/models/qwen.mdx index a9e03ad5..5ccc1f12 100644 --- a/docs/ja/models/qwen.mdx +++ b/docs/ja/models/qwen.mdx @@ -13,19 +13,19 @@ Tongyi Qianwen(DashScope / Bailian)は国内で最も広範な機能をカ ```json { - "model": "qwen3.6-plus", + "model": "qwen3.7-plus", "dashscope_api_key": "YOUR_API_KEY" } ``` | パラメータ | 説明 | | --- | --- | -| `model` | `qwen3.6-plus`、`qwen3.7-max`、`qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus` などを指定可能 | +| `model` | `qwen3.7-plus`、`qwen3.7-max`、`qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus` などを指定可能 | | `dashscope_api_key` | [Bailian コンソール](https://bailian.console.aliyun.com/?tab=model#/api-key) で作成。詳細は [公式ドキュメント](https://bailian.console.aliyun.com/?tab=api#/api) を参照 | ## 画像理解 -`dashscope_api_key` を設定すると、Agent の Vision ツールは自動的に Qwen のビジョンモデルを呼び出して画像を認識します。`qwen3-max` / `qwen3.5-plus` / `qwen3.6-plus` などのモデルはそのままマルチモーダルです。メインモデルがテキスト専用(`qwen-turbo` など)の場合は、自動的に `qwen-vl-max` にフォールバックします。 +`dashscope_api_key` を設定すると、Agent の Vision ツールは自動的に Qwen のビジョンモデルを呼び出して画像を認識します。`qwen3.7-plus` / `qwen3.6-plus` / `qwen3.5-plus` / `qwen3-max` などのモデルはそのままマルチモーダルです。メインモデルがテキスト専用(`qwen-turbo` など)の場合は、自動的に `qwen-vl-max` にフォールバックします。 Vision モデルを手動で指定したい場合: @@ -33,13 +33,13 @@ Vision モデルを手動で指定したい場合: { "tools": { "vision": { - "model": "qwen3.6-plus" + "model": "qwen3.7-plus" } } } ``` -サポートするモデル:`qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`。 +サポートするモデル:`qwen3.7-plus`、`qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`。 ## 画像生成 diff --git a/docs/ja/tools/vision.mdx b/docs/ja/tools/vision.mdx index 06eb287d..4621347d 100644 --- a/docs/ja/tools/vision.mdx +++ b/docs/ja/tools/vision.mdx @@ -19,7 +19,7 @@ Vision ツールは多段階の自動選択 + 自動フォールバック戦略 | プロバイダー | ビジョンモデル | 説明 | | --- | --- | --- | | OpenAI / 互換プロトコル | メインモデルを使用 | すべての OpenAI 互換マルチモーダルモデルに対応 | -| 通義千問 (DashScope) | メインモデルを使用 | 例:qwen3.6-plus など | +| 通義千問 (DashScope) | メインモデルを使用 | 例:qwen3.7-plus など | | Claude | メインモデルを使用 | Anthropic ネイティブ画像形式 | | Gemini | メインモデルを使用 | inlineData 形式 | | 豆包 (Doubao) | メインモデルを使用 | doubao-seed-2-0 シリーズがネイティブ対応 | diff --git a/docs/models/index.mdx b/docs/models/index.mdx index 0d065e58..2492270b 100644 --- a/docs/models/index.mdx +++ b/docs/models/index.mdx @@ -17,7 +17,7 @@ A snapshot of each vendor's capabilities. "Text" refers to the main chat model; | [Gemini](/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [OpenAI](/models/openai) | gpt-5.5, o-series | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [GLM](/models/glm) | glm-5.1, glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | -| [Qwen](/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [Qwen](/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Doubao](/models/doubao) | doubao-seed-2.0 series | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | | [ERNIE](/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | | diff --git a/docs/models/linkai.mdx b/docs/models/linkai.mdx index f60c2160..e078a945 100644 --- a/docs/models/linkai.mdx +++ b/docs/models/linkai.mdx @@ -40,7 +40,7 @@ Once configured, the Agent's Vision tool automatically calls multimodal models v } ``` -Available models: `gpt-4.1-mini`, `gpt-5.4-mini`, `qwen3.6-plus`, `doubao-seed-2-0-pro-260215`, `kimi-k2.6`, `claude-sonnet-4-6`, `gemini-3.1-flash-lite-preview`, etc. +Available models: `gpt-4.1-mini`, `gpt-5.4-mini`, `qwen3.7-plus`, `doubao-seed-2-0-pro-260215`, `kimi-k2.6`, `claude-sonnet-4-6`, `gemini-3.1-flash-lite-preview`, etc. ## Image Generation diff --git a/docs/models/qwen.mdx b/docs/models/qwen.mdx index 8e27269c..76a419fe 100644 --- a/docs/models/qwen.mdx +++ b/docs/models/qwen.mdx @@ -13,19 +13,19 @@ Qwen (Alibaba DashScope / Bailian) is one of the most fully-featured vendors. Te ```json { - "model": "qwen3.6-plus", + "model": "qwen3.7-plus", "dashscope_api_key": "YOUR_API_KEY" } ``` | Parameter | Description | | --- | --- | -| `model` | Can be `qwen3.6-plus`, `qwen3.7-max`, `qwen3.5-plus`, `qwen3-max`, `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwq-plus`, etc. | +| `model` | Can be `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-plus`, `qwen3.5-plus`, `qwen3-max`, `qwen-max`, `qwen-plus`, `qwen-turbo`, `qwq-plus`, etc. | | `dashscope_api_key` | Create one in the [Bailian Console](https://bailian.console.aliyun.com/?tab=model#/api-key); see the [official docs](https://bailian.console.aliyun.com/?tab=api#/api) | ## Image Understanding -Once `dashscope_api_key` is configured, the Agent's Vision tool automatically calls Qwen's vision models to recognize images. Models like `qwen3-max` / `qwen3.5-plus` / `qwen3.6-plus` are already multimodal; if the main model is text-only (e.g. `qwen-turbo`), it automatically falls back to `qwen-vl-max`. +Once `dashscope_api_key` is configured, the Agent's Vision tool automatically calls Qwen's vision models to recognize images. Models like `qwen3.7-plus` / `qwen3.6-plus` / `qwen3.5-plus` / `qwen3-max` are already multimodal; if the main model is text-only (e.g. `qwen-turbo`), it automatically falls back to `qwen-vl-max`. To manually specify a Vision model: @@ -33,13 +33,13 @@ To manually specify a Vision model: { "tools": { "vision": { - "model": "qwen3.6-plus" + "model": "qwen3.7-plus" } } } ``` -Supported models: `qwen3.6-plus`, `qwen3.5-plus`, `qwen3-max`. +Supported models: `qwen3.7-plus`, `qwen3.6-plus`, `qwen3.5-plus`, `qwen3-max`. ## Image Generation diff --git a/docs/tools/vision.mdx b/docs/tools/vision.mdx index 4db6bec0..4b15b984 100644 --- a/docs/tools/vision.mdx +++ b/docs/tools/vision.mdx @@ -19,7 +19,7 @@ If the current provider fails, the tool automatically tries the next one until i | Provider | Vision Model | Notes | | --- | --- | --- | | OpenAI / Compatible | Main model | All OpenAI-protocol-compatible multimodal models | -| Qwen (DashScope) | Main model | e.g. qwen3.6-plus, etc. | +| Qwen (DashScope) | Main model | e.g. qwen3.7-plus, etc. | | Claude | Main model | Anthropic native image format | | Gemini | Main model | inlineData format | | Doubao | Main model | doubao-seed-2-0 series natively supported | diff --git a/docs/zh/README.md b/docs/zh/README.md index 77cd9d5f..9a52b03d 100644 --- a/docs/zh/README.md +++ b/docs/zh/README.md @@ -100,7 +100,7 @@ CowAgent 支持国内外主流厂商的大语言模型。**文本对话、图像 | [Gemini](https://docs.cowagent.ai/zh/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [OpenAI](https://docs.cowagent.ai/zh/models/openai) | gpt-5.5、o 系列 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [智谱 GLM](https://docs.cowagent.ai/zh/models/glm) | glm-5.1、glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | -| [通义千问](https://docs.cowagent.ai/zh/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [通义千问](https://docs.cowagent.ai/zh/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [豆包 Doubao](https://docs.cowagent.ai/zh/models/doubao) | doubao-seed-2.0 系列 | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](https://docs.cowagent.ai/zh/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | | [百度ERNIE](https://docs.cowagent.ai/zh/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | | diff --git a/docs/zh/models/index.mdx b/docs/zh/models/index.mdx index e0d4a35c..ce858b47 100644 --- a/docs/zh/models/index.mdx +++ b/docs/zh/models/index.mdx @@ -18,7 +18,7 @@ CowAgent 支持国内外主流厂商的大语言模型,模型接口实现在 | [Gemini](/zh/models/gemini) | gemini-3.5-flash | ✅ | ✅ | ✅ | | | | | [OpenAI](/zh/models/openai) | gpt-5.5、o 系列 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [智谱 GLM](/zh/models/glm) | glm-5.1、glm-5v-turbo | ✅ | ✅ | | ✅ | | ✅ | -| [通义千问](/zh/models/qwen) | qwen3.7-max | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [通义千问](/zh/models/qwen) | qwen3.7-plus | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [豆包 Doubao](/zh/models/doubao) | doubao-seed-2.0 系列 | ✅ | ✅ | ✅ | | | ✅ | | [Kimi](/zh/models/kimi) | kimi-k2.6 | ✅ | ✅ | | | | | | [百度千帆](/zh/models/qianfan) | ernie-5.1 | ✅ | ✅ | | | | | diff --git a/docs/zh/models/linkai.mdx b/docs/zh/models/linkai.mdx index 68647ebc..c0762858 100644 --- a/docs/zh/models/linkai.mdx +++ b/docs/zh/models/linkai.mdx @@ -40,7 +40,7 @@ description: 通过 LinkAI 平台统一接入文本、视觉、图像、语音 } ``` -可选模型:`gpt-4.1-mini`、`gpt-5.4-mini`、`qwen3.6-plus`、`doubao-seed-2-0-pro-260215`、`kimi-k2.6`、`claude-sonnet-4-6`、`gemini-3.1-flash-lite-preview` 等。 +可选模型:`gpt-4.1-mini`、`gpt-5.4-mini`、`qwen3.7-plus`、`doubao-seed-2-0-pro-260215`、`kimi-k2.6`、`claude-sonnet-4-6`、`gemini-3.1-flash-lite-preview` 等。 ## 图像生成 diff --git a/docs/zh/models/qwen.mdx b/docs/zh/models/qwen.mdx index 765bae64..67626a4d 100644 --- a/docs/zh/models/qwen.mdx +++ b/docs/zh/models/qwen.mdx @@ -13,19 +13,19 @@ description: 通义千问模型配置(文本 / 图像理解 / 图像生成 / ```json { - "model": "qwen3.6-plus", + "model": "qwen3.7-plus", "dashscope_api_key": "YOUR_API_KEY" } ``` | 参数 | 说明 | | --- | --- | -| `model` | 可填 `qwen3.6-plus`、`qwen3.7-max`、`qwen3.5-plus`、`qwen3-max`、`qwen-max`、`qwen-plus`、`qwen-turbo`、`qwq-plus` 等 | +| `model` | 可填 `qwen3.7-plus`、`qwen3.7-max`、`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) | ## 图像理解 -配置 `dashscope_api_key` 后 Agent 的 Vision 工具会自动调用千问的视觉模型识别图像。`qwen3-max` / `qwen3.5-plus` / `qwen3.6-plus` 等模型本身就是多模态;若主模型是纯文本(如 `qwen-turbo`),会自动回落到 `qwen-vl-max`。 +配置 `dashscope_api_key` 后 Agent 的 Vision 工具会自动调用千问的视觉模型识别图像。`qwen3.7-plus` / `qwen3.6-plus` / `qwen3.5-plus` / `qwen3-max` 等模型本身就是多模态;若主模型是纯文本(如 `qwen-turbo`),会自动回落到 `qwen-vl-max`。 如需手动指定 Vision 模型: @@ -33,13 +33,13 @@ description: 通义千问模型配置(文本 / 图像理解 / 图像生成 / { "tools": { "vision": { - "model": "qwen3.6-plus" + "model": "qwen3.7-plus" } } } ``` -支持模型:`qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`。 +支持模型:`qwen3.7-plus`、`qwen3.6-plus`、`qwen3.5-plus`、`qwen3-max`。 ## 图像生成 diff --git a/docs/zh/tools/vision.mdx b/docs/zh/tools/vision.mdx index 675afe41..b10441a7 100644 --- a/docs/zh/tools/vision.mdx +++ b/docs/zh/tools/vision.mdx @@ -19,7 +19,7 @@ Vision 工具采用多级自动选择 + 自动兜底策略,无需手动配置 | 厂商 | 视觉模型 | 说明 | | --- | --- | --- | | OpenAI / 兼容协议 | 使用主模型 | 支持所有 OpenAI 协议兼容的多模态模型 | -| 通义千问 (DashScope) | 使用主模型 | 例如 qwen3.6-plus 等 | +| 通义千问 (DashScope) | 使用主模型 | 例如 qwen3.7-plus 等 | | Claude | 使用主模型 | Anthropic 原生图像格式 | | Gemini | 使用主模型 | inlineData 格式 | | 豆包 (Doubao) | 使用主模型 | doubao-seed-2-0 系列原生支持 | diff --git a/models/dashscope/dashscope_bot.py b/models/dashscope/dashscope_bot.py index 651ec80b..b224ef8b 100644 --- a/models/dashscope/dashscope_bot.py +++ b/models/dashscope/dashscope_bot.py @@ -28,15 +28,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-", "qwen3.6-") +MULTIMODAL_MODEL_PREFIXES = ("qwen3.5-", "qwen3.6-", "qwen3.7-plus") # Qwen对话模型API class DashscopeBot(Bot): def __init__(self): super().__init__() - self.sessions = SessionManager(DashscopeSession, model=conf().get("model") or "qwen3.6-plus") - self.model_name = conf().get("model") or "qwen3.6-plus" + self.sessions = SessionManager(DashscopeSession, model=conf().get("model") or "qwen3.7-plus") + self.model_name = conf().get("model") or "qwen3.7-plus" self.client = dashscope.Generation api_key = conf().get("dashscope_api_key") if api_key: diff --git a/run.sh b/run.sh index 4672133f..014fb7f6 100755 --- a/run.sh +++ b/run.sh @@ -604,7 +604,7 @@ select_model() { "OpenAI GPT (gpt-5.4, gpt-5.2, gpt-4.1, etc.)" \ "MiniMax (MiniMax-M3, MiniMax-M2.7, etc.)" \ "Zhipu AI (glm-5.1, glm-5-turbo, glm-5, etc.)" \ - "Qwen (qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)" \ + "Qwen (qwen3.7-plus, qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)" \ "Doubao (doubao-seed-2-0-code-preview-260215, etc.)" \ "Kimi (kimi-k2.6, kimi-k2.5, kimi-k2, etc.)" \ "LinkAI ($(t "一个 Key 接入所有模型" "access all models via one API"))" \ @@ -635,7 +635,7 @@ configure_model() { 4) read_model_config "OpenAI GPT" "gpt-5.4" "OPENAI_KEY" ;; 5) read_model_config "MiniMax" "MiniMax-M3" "MINIMAX_KEY" ;; 6) read_model_config "Zhipu AI" "glm-5.1" "ZHIPU_KEY" ;; - 7) read_model_config "Qwen (DashScope)" "qwen3.6-plus" "DASHSCOPE_KEY" ;; + 7) read_model_config "Qwen (DashScope)" "qwen3.7-plus" "DASHSCOPE_KEY" ;; 8) read_model_config "Doubao (Volcengine Ark)" "doubao-seed-2-0-code-preview-260215" "ARK_KEY" ;; 9) read_model_config "Kimi (Moonshot)" "kimi-k2.6" "MOONSHOT_KEY" ;; 10) diff --git a/scripts/run.ps1 b/scripts/run.ps1 index e69786a3..a3bfda63 100644 --- a/scripts/run.ps1 +++ b/scripts/run.ps1 @@ -370,7 +370,7 @@ $ModelChoices = @{ 4 = @{ Provider = "OpenAI GPT"; Default = "gpt-5.4"; Field = "open_ai_api_key"; BaseField = "open_ai_api_base" } 5 = @{ Provider = "MiniMax"; Default = "MiniMax-M3"; Field = "minimax_api_key" } 6 = @{ Provider = "Zhipu AI"; Default = "glm-5.1"; Field = "zhipu_ai_api_key" } - 7 = @{ Provider = "Qwen (DashScope)"; Default = "qwen3.6-plus"; Field = "dashscope_api_key" } + 7 = @{ Provider = "Qwen (DashScope)"; Default = "qwen3.7-plus"; Field = "dashscope_api_key" } 8 = @{ Provider = "Doubao (Volcengine Ark)"; Default = "doubao-seed-2-0-code-preview-260215"; Field = "ark_api_key" } 9 = @{ Provider = "Kimi (Moonshot)"; Default = "kimi-k2.6"; Field = "moonshot_api_key" } 10 = @{ Provider = "LinkAI"; Default = "deepseek-v4-flash"; Field = "linkai_api_key"; Linkai = $true } @@ -386,7 +386,7 @@ function Select-Model { "OpenAI GPT (gpt-5.4, gpt-5.2, gpt-4.1, etc.)", "MiniMax (MiniMax-M3, MiniMax-M2.7, etc.)", "Zhipu AI (glm-5.1, glm-5-turbo, glm-5, etc.)", - "Qwen (qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)", + "Qwen (qwen3.7-plus, qwen3.6-plus, qwen3.5-plus, qwen3-max, qwq-plus, etc.)", "Doubao (doubao-seed-2-0-code-preview-260215, etc.)", "Kimi (kimi-k2.6, kimi-k2.5, kimi-k2, etc.)", ("LinkAI (" + (T "一个 Key 接入所有模型" "access all models via one API") + ")"), diff --git a/tests/test_dashscope_provider.py b/tests/test_dashscope_provider.py new file mode 100644 index 00000000..f8eb349a --- /dev/null +++ b/tests/test_dashscope_provider.py @@ -0,0 +1,63 @@ +# encoding:utf-8 +"""Unit tests for Qwen DashScope qwen3.7-plus provider updates.""" +import os +import sys +import unittest +from unittest.mock import MagicMock, patch + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) + + +class TestDashscopeConst(unittest.TestCase): + def test_qwen37_plus_constant_defined(self): + from common import const + self.assertEqual(const.QWEN37_PLUS, "qwen3.7-plus") + + def test_qwen37_plus_in_model_list(self): + from common import const + self.assertIn("qwen3.7-plus", const.MODEL_LIST) + + def test_qwen37_plus_before_qwen37_max_in_model_list(self): + from common import const + qwen_models = [m for m in const.MODEL_LIST if str(m).startswith("qwen")] + self.assertGreater( + len(qwen_models), + 1, + ) + self.assertEqual(qwen_models[0], "qwen3.7-plus") + + +class TestDashscopeBotDefaultModel(unittest.TestCase): + def test_default_model_is_qwen37_plus(self): + mock_conf = MagicMock() + mock_conf.get = MagicMock(side_effect=lambda key, default=None: default) + + with patch("models.dashscope.dashscope_bot.conf", return_value=mock_conf): + with patch("models.dashscope.dashscope_bot.SessionManager"): + from models.dashscope.dashscope_bot import DashscopeBot + bot = DashscopeBot.__new__(DashscopeBot) + bot.sessions = MagicMock() + bot.model_name = mock_conf.get("model") or "qwen3.7-plus" + self.assertEqual(bot.model_name, "qwen3.7-plus") + + def test_default_model_string_in_source(self): + bot_path = os.path.join( + os.path.dirname(__file__), "..", "models", "dashscope", "dashscope_bot.py" + ) + with open(bot_path, encoding="utf-8") as f: + source = f.read() + self.assertIn('"qwen3.7-plus"', source) + + +class TestDashscopeMultimodalRouting(unittest.TestCase): + def test_qwen37_plus_uses_multimodal_api(self): + from models.dashscope.dashscope_bot import DashscopeBot + self.assertTrue(DashscopeBot._is_multimodal_model("qwen3.7-plus")) + + def test_qwen37_max_uses_generation_api(self): + from models.dashscope.dashscope_bot import DashscopeBot + self.assertFalse(DashscopeBot._is_multimodal_model("qwen3.7-max")) + + +if __name__ == "__main__": + unittest.main()