From e161fe059fdacc9f38b355f21ae7913c5da42a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B4=AB=E5=BD=B1233?= <1440196015@qq.com> Date: Wed, 22 Jul 2026 20:51:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20MiMo=20=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E7=AA=97=E5=8F=A3=201M=20+=20Agnes=20=E5=A4=9A=E6=A8=A1?= =?UTF-8?q?=E6=80=81=E6=94=AF=E6=8C=81=20Base64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++---- electron/harness/adapters/agnes-ai.adapter.ts | 5 +++-- electron/harness/adapters/mimo.adapter.ts | 12 ++++++------ electron/services/database.service.ts | 4 ++-- electron/services/global-config.service.ts | 2 +- src/components/onboarding/OnboardingWizard.tsx | 2 +- src/components/settings/SettingsModal.tsx | 8 ++++---- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c576503..b3c434b 100644 --- a/README.md +++ b/README.md @@ -332,8 +332,8 @@ Metona 通过统一的 `IMetonaProviderAdapter` 接口抽象了所有 LLM Provid | 适配器 | Provider | 模型 | 上下文 | 流式格式 | Thinking | 多模态 | |:---|:---|:---|:---|:---|:---|:---| | **DeepSeekAdapter** | `deepseek` | deepseek-v4-pro / deepseek-v4-flash | 1M tokens | SSE | `thinking.type` + `reasoning_effort` | 否 | -| **AgnesAdapter** | `agnes` | agnes-2.0-flash | 1M tokens | SSE | `chat_template_kwargs` / Anthropic 兼容 | 是 (URL) | -| **MimoAdapter** | `mimo` | mimo-v2.5-pro / mimo-v2.5 | 131K tokens | SSE | `thinking.type: enabled` | 是 (URL + Base64) | +| **AgnesAdapter** | `agnes` | agnes-2.0-flash | 1M tokens | SSE | `chat_template_kwargs` / Anthropic 兼容 | 是 (URL + Base64) | +| **MimoAdapter** | `mimo` | mimo-v2.5-pro / mimo-v2.5 | 1M tokens | SSE | `thinking.type: enabled` | 是 (URL + Base64) | | **OllamaAdapter** | `ollama` | qwen3 / gemma3 / deepseek-r1 等 | 可配 (num_ctx) | NDJSON | `think` 参数 | 是 (Base64) | ### 适配器核心能力 @@ -622,7 +622,7 @@ VITE_APP_TITLE=MetonaAI Desktop | `agent.confirmationTimeoutMs` | `120000` | 确认弹窗超时 (30s ~ 600s) | | `deepseek.contextWindow` | `1000000` | DeepSeek 上下文窗口 | | `agnes.contextWindow` | `1000000` | Agnes 上下文窗口 | -| `mimo.contextWindow` | `131072` | MiMo 上下文窗口 | +| `mimo.contextWindow` | `1000000` | MiMo 上下文窗口 | | `ollama.numCtx` | `4096` | Ollama num_ctx 参数 | ### SearXNG 元搜索引擎 (可选) @@ -664,7 +664,7 @@ MetonaAI-Desktop/ │ │ │ ├── 📄 base-adapter.ts # 抽象基类 (fetchWithTimeout) │ │ │ ├── 📄 deepseek.adapter.ts # DeepSeek v4 (SSE, 1M ctx) │ │ │ ├── 📄 agnes-ai.adapter.ts # Agnes AI 2.0 (SSE, 多模态) -│ │ │ ├── 📄 mimo.adapter.ts # MiMo 2.5 (SSE, 131K ctx) +│ │ │ ├── 📄 mimo.adapter.ts # MiMo 2.5 (SSE, 1M ctx) │ │ │ ├── 📄 ollama.adapter.ts # Ollama (NDJSON, 600 行) │ │ │ └── 📂 shared/ # 共享: OpenAI 格式 · SSE 解析 │ │ ├── 📂 tools/ # 工具系统 diff --git a/electron/harness/adapters/agnes-ai.adapter.ts b/electron/harness/adapters/agnes-ai.adapter.ts index a07bd2f..fe47a72 100644 --- a/electron/harness/adapters/agnes-ai.adapter.ts +++ b/electron/harness/adapters/agnes-ai.adapter.ts @@ -1,7 +1,7 @@ /** * Agnes AI Provider Adapter * - * OpenAI 兼容 API。支持 Tool Calling、Thinking 模式、多模态(图片)。 + * OpenAI 兼容 API。支持 Tool Calling、Thinking 模式、多模态(图片 — URL + Base64)。 * * 独立继承 BaseAdapter,通过 shared/openai-format 和 shared/sse-stream 复用 * OpenAI 兼容格式构建和 SSE 流式解析逻辑。不与其他 Provider Adapter 耦合。 @@ -37,7 +37,7 @@ export class AgnesAdapter extends BaseAdapter { maxOutputTokens: 65_536, supportsToolCalling: true, supportsThinking: true, - description: 'Agnes AI 快速版,1M 上下文,支持多模态图片与思考模式', + description: 'Agnes AI 快速版,1M 上下文,支持多模态图片(URL + Base64)与思考模式', }, }; @@ -136,6 +136,7 @@ export class AgnesAdapter extends BaseAdapter { * * Agnes AI 特有参数: * - 多模态图片:user 消息的 images[] → OpenAI content 数组 [{type:"text"}, {type:"image_url"}] + * 支持 HTTPS URL 或 base64 Data URI(与 MiMo 一致) * - chat_template_kwargs: { enable_thinking: true } — 启用思考模式(非 thinking 字段) * - 默认 max_tokens: 65536(1M 上下文,65.5K 最大输出) */ diff --git a/electron/harness/adapters/mimo.adapter.ts b/electron/harness/adapters/mimo.adapter.ts index f69ad8e..1fff036 100644 --- a/electron/harness/adapters/mimo.adapter.ts +++ b/electron/harness/adapters/mimo.adapter.ts @@ -2,7 +2,7 @@ * MiMo (Xiaomi) Provider Adapter * * 基于 OpenAI 兼容 API。支持 Tool Calling、Thinking 模式、流式输出。 - * 模型: mimo-v2.5-pro(131072 max_tokens)/ mimo-v2.5(32768 max_tokens) + * 模型: mimo-v2.5-pro(1M 上下文 / 131072 max_tokens)/ mimo-v2.5(1M 上下文 / 32768 max_tokens) * * 独立继承 BaseAdapter,通过 shared/openai-format 和 shared/sse-stream 复用 * OpenAI 兼容格式构建和 SSE 流式解析逻辑。不与其他 Provider Adapter 耦合。 @@ -31,13 +31,12 @@ export class MimoAdapter extends BaseAdapter { readonly supportsThinking = true; // MiMo 模型元信息 - // mimo-v2.5-pro: 131072 max_completion_tokens;mimo-v2.5: 32768 - // 官方未公布上下文窗口大小,保守设为 131072(与 pro 的 max_output 一致) + // mimo-v2.5-pro: 1M 上下文(与 DeepSeek 一致)/ 131072 max_tokens;mimo-v2.5: 1M 上下文 / 32768 max_tokens private static readonly MODEL_INFO: Record = { 'mimo-v2.5-pro': { id: 'mimo-v2.5-pro', name: 'MiMo V2.5 Pro', - contextWindow: 131_072, + contextWindow: 1_000_000, maxOutputTokens: 131_072, supportsToolCalling: true, supportsThinking: true, @@ -46,7 +45,7 @@ export class MimoAdapter extends BaseAdapter { 'mimo-v2.5': { id: 'mimo-v2.5', name: 'MiMo V2.5', - contextWindow: 131_072, + contextWindow: 1_000_000, maxOutputTokens: 32_768, supportsToolCalling: true, supportsThinking: true, @@ -143,7 +142,7 @@ export class MimoAdapter extends BaseAdapter { return this.config.contextWindow; } const modelInfo = MimoAdapter.MODEL_INFO[this.config.defaultModel]; - return modelInfo?.contextWindow ?? 131_072; + return modelInfo?.contextWindow ?? 1_000_000; } // ========== 私有方法 ========== @@ -153,6 +152,7 @@ export class MimoAdapter extends BaseAdapter { * * MiMo 特有参数: * - 多模态图片:user 消息的 images[] → OpenAI content 数组 [{type:"text"}, {type:"image_url"}] + * 支持 HTTPS URL 或 base64 Data URI * - thinking: { type: "enabled" / "disabled" } — 与 DeepSeek 一致 * - max_completion_tokens — 非 max_tokens(MiMo 使用新字段名) * - stream_options: { include_usage: true } — 流式返回 usage diff --git a/electron/services/database.service.ts b/electron/services/database.service.ts index 5560e83..9bdca7a 100644 --- a/electron/services/database.service.ts +++ b/electron/services/database.service.ts @@ -394,8 +394,8 @@ export class DatabaseService { // v0.3.1: DeepSeek/Agnes 改为可配置,不再写死 1M { key: 'deepseek.contextWindow', value: '1000000', category: 'deepseek' }, { key: 'agnes.contextWindow', value: '1000000', category: 'agnes' }, - // v0.3.4: MiMo 上下文窗口(官方未公布,保守设为 131072) - { key: 'mimo.contextWindow', value: '131072', category: 'mimo' }, + // v0.3.4: MiMo 上下文窗口(与 DeepSeek 一致,1M) + { key: 'mimo.contextWindow', value: '1000000', category: 'mimo' }, // Onboarding { key: 'onboarding.completed', value: 'false', category: 'general' }, diff --git a/electron/services/global-config.service.ts b/electron/services/global-config.service.ts index 389aafc..75619ef 100644 --- a/electron/services/global-config.service.ts +++ b/electron/services/global-config.service.ts @@ -78,7 +78,7 @@ export const SEED_DEFAULTS: Record = { 'ollama.numCtx': null, 'deepseek.contextWindow': 1000000, 'agnes.contextWindow': 1000000, - 'mimo.contextWindow': 131072, + 'mimo.contextWindow': 1000000, 'onboarding.completed': false, }; diff --git a/src/components/onboarding/OnboardingWizard.tsx b/src/components/onboarding/OnboardingWizard.tsx index 579f1b1..097b065 100644 --- a/src/components/onboarding/OnboardingWizard.tsx +++ b/src/components/onboarding/OnboardingWizard.tsx @@ -73,7 +73,7 @@ export function OnboardingWizard(): React.JSX.Element | null { const DEFAULT_CTX: Record = { deepseek: 1_000_000, agnes: 1_000_000, - mimo: 131_072, + mimo: 1_000_000, ollama: null, }; // 上下文窗口校验:ollama 允许空,最小 512;其他 provider 最小 4096 diff --git a/src/components/settings/SettingsModal.tsx b/src/components/settings/SettingsModal.tsx index 0d523f0..1dc3d33 100644 --- a/src/components/settings/SettingsModal.tsx +++ b/src/components/settings/SettingsModal.tsx @@ -364,7 +364,7 @@ function LLMSettings() { // v0.3.1: DeepSeek/Agnes/MiMo contextWindow 可配置(不再写死) const [dsCtxWindow, setDsCtxWindow] = useState(1000000); const [agnesCtxWindow, setAgnesCtxWindow] = useState(1000000); - const [mimoCtxWindow, setMimoCtxWindow] = useState(131072); + const [mimoCtxWindow, setMimoCtxWindow] = useState(1000000); const [showKey, setShowKey] = useState(false); const [loaded, setLoaded] = useState(false); const [saving, setSaving] = useState(false); @@ -608,11 +608,11 @@ function LLMSettings() { label="上下文窗口 (contextWindow)" type="number" value={mimoCtxWindow} - onChange={(e) => setMimoCtxWindow(Number(e.target.value) || 131072)} - placeholder="如 32768、65536、131072" + onChange={(e) => setMimoCtxWindow(Number(e.target.value) || 1000000)} + placeholder="如 65536、131072、1000000" slotProps={{ htmlInput: { min: 4096, step: 4096 } }} error={mimoCtxError} - helperText={mimoCtxError ? '最小值为 4096' : '官方未公布具体值,默认 131072,用于压缩判断'} + helperText={mimoCtxError ? '最小值为 4096' : '默认 1000000(1M),用于上下文压缩判断'} /> )}