From e4c0259afc12c25c32b026a1d13abf965c01eed2 Mon Sep 17 00:00:00 2001 From: thzxx Date: Sat, 27 Jun 2026 21:57:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Agnes=E4=B8=8A=E4=B8=8B=E6=96=87512K?= =?UTF-8?q?=E2=86=921M=20+=20Ollama=E6=94=AF=E6=8C=81=E9=85=8D=E7=BD=AEnum?= =?UTF-8?q?=5Fctx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agnes AI: - adapter注释和API文档更新: 上下文512K→1M (官方已升级) Ollama num_ctx 支持: - MetonaGenerationParams 新增 contextLength 字段 - OllamaAdapter.toNativeRequest 发送 options.num_ctx - AgentLoopEngine 从 config 读取并传递到请求参数 - database.service 新增 ollama.numCtx 默认配置(null=由模型决定) - SettingsModal LLM设置: Ollama 选中时显示上下文长度输入框 - main.ts 启动时从 configService 读取 ollama.numCtx 数据流: Settings → configService → main.ts → AgentLoopEngine.config → MetonaRequest.params → OllamaAdapter → options.num_ctx --- apis/agnes-ai-api-docs-20260625.html | 4 ++-- electron/harness/adapters/agnes-ai.adapter.ts | 2 +- electron/harness/adapters/ollama.adapter.ts | 1 + electron/harness/agent-loop/engine.ts | 1 + electron/harness/agent-loop/types.ts | 2 ++ electron/harness/types/metona-request.ts | 2 ++ electron/main.ts | 6 +++++- electron/services/database.service.ts | 3 +++ src/components/settings/SettingsModal.tsx | 15 +++++++++++++++ 9 files changed, 32 insertions(+), 4 deletions(-) diff --git a/apis/agnes-ai-api-docs-20260625.html b/apis/agnes-ai-api-docs-20260625.html index 2f9458d..50a5a5b 100644 --- a/apis/agnes-ai-api-docs-20260625.html +++ b/apis/agnes-ai-api-docs-20260625.html @@ -495,7 +495,7 @@

在 Claw-Eval 基准测试中排名 General Leaderboard 第 9,Pass³ 分数 60.9%

模型名称: agnes-2.0-flash - 上下文: 512K | 最大输出: 65.5K + 上下文: 1M | 最大输出: 65.5K Base URL: https://apihub.agnes-ai.com/v1
@@ -1004,7 +1004,7 @@ response = client.chat.completions.create( - +
项目数值
Context512K
Context1M
Max Output65.5K
diff --git a/electron/harness/adapters/agnes-ai.adapter.ts b/electron/harness/adapters/agnes-ai.adapter.ts index cfd2d7e..7666be0 100644 --- a/electron/harness/adapters/agnes-ai.adapter.ts +++ b/electron/harness/adapters/agnes-ai.adapter.ts @@ -100,7 +100,7 @@ export class AgnesAdapter extends BaseAdapter { * Agnes AI 特有参数: * - 多模态图片:user 消息的 images[] → OpenAI content 数组 [{type:"text"}, {type:"image_url"}] * - chat_template_kwargs: { enable_thinking: true } — 启用思考模式(非 thinking 字段) - * - 默认 max_tokens: 65536(512K 上下文) + * - 默认 max_tokens: 65536(1M 上下文,65.5K 最大输出) */ private toNativeRequest(request: MetonaRequest, stream: boolean): Record { const messages = buildOpenAICompatibleMessages(request); diff --git a/electron/harness/adapters/ollama.adapter.ts b/electron/harness/adapters/ollama.adapter.ts index 20bff85..1792fbf 100644 --- a/electron/harness/adapters/ollama.adapter.ts +++ b/electron/harness/adapters/ollama.adapter.ts @@ -388,6 +388,7 @@ export class OllamaAdapter extends BaseAdapter { num_predict: request.params.maxTokens, top_p: request.params.topP, stop: request.params.stopSequences, + num_ctx: request.params.contextLength, }, }; diff --git a/electron/harness/agent-loop/engine.ts b/electron/harness/agent-loop/engine.ts index d7d8e43..696ae8a 100644 --- a/electron/harness/agent-loop/engine.ts +++ b/electron/harness/agent-loop/engine.ts @@ -147,6 +147,7 @@ export class AgentLoopEngine extends EventEmitter { stream: true, thinkingEnabled: true, thinkingEffort: 'high', + contextLength: this.config.contextLength, }, }; diff --git a/electron/harness/agent-loop/types.ts b/electron/harness/agent-loop/types.ts index ec34442..94f9c43 100644 --- a/electron/harness/agent-loop/types.ts +++ b/electron/harness/agent-loop/types.ts @@ -63,6 +63,8 @@ export interface AgentLoopConfig { contextWindow: number; retryCount: number; temperature: number; + /** Ollama 上下文窗口大小(num_ctx),其他 Provider 忽略 */ + contextLength?: number; } // ===== Agent Loop 输出 ===== diff --git a/electron/harness/types/metona-request.ts b/electron/harness/types/metona-request.ts index ddd6c71..25913bc 100644 --- a/electron/harness/types/metona-request.ts +++ b/electron/harness/types/metona-request.ts @@ -53,6 +53,8 @@ export interface MetonaGenerationParams { thinkingEnabled?: boolean; /** 思考强度(替代 thinkingBudget,各 Provider 映射见 Adapter 规范) */ thinkingEffort?: 'low' | 'medium' | 'high' | 'max'; + /** 上下文窗口大小(仅 Ollama 支持 num_ctx) */ + contextLength?: number; } // ===== 安全约束 ===== diff --git a/electron/main.ts b/electron/main.ts index 667bae5..e2cf96c 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -147,7 +147,11 @@ async function initialize(): Promise { ]; // ===== Agent Loop ===== - const agentLoop = new AgentLoopEngine({}, adapter, toolRegistry, preToolHooks, postToolHooks); + const ollamaNumCtx = configService.get('ollama.numCtx'); + const agentLoop = new AgentLoopEngine( + { contextLength: ollamaNumCtx ?? undefined }, + adapter, toolRegistry, preToolHooks, postToolHooks, + ); agentLoop.setTools(toolRegistry.listTools()); agentLoop.setWorkspacePath(workspaceInfo.path); diff --git a/electron/services/database.service.ts b/electron/services/database.service.ts index d933ed0..9bd6197 100644 --- a/electron/services/database.service.ts +++ b/electron/services/database.service.ts @@ -270,6 +270,9 @@ export class DatabaseService { { key: 'logging.auditEnabled', value: 'true', category: 'logging' }, { key: 'logging.traceEnabled', value: 'true', category: 'logging' }, + // Ollama 配置 + { key: 'ollama.numCtx', value: 'null', category: 'ollama' }, + // Onboarding { key: 'onboarding.completed', value: 'false', category: 'general' }, ]; diff --git a/src/components/settings/SettingsModal.tsx b/src/components/settings/SettingsModal.tsx index 33da5a2..b0cd1ee 100644 --- a/src/components/settings/SettingsModal.tsx +++ b/src/components/settings/SettingsModal.tsx @@ -101,6 +101,7 @@ function LLMSettings() { const [model, setModel] = useConfig('llm.model', ''); const [apiKey, setApiKey] = useConfig('llm.apiKey', ''); const [baseURL, setBaseURL] = useConfig('llm.baseURL', ''); + const [numCtx, setNumCtx] = useConfig('ollama.numCtx', null as number | null); const [showKey, setShowKey] = useState(false); return ( @@ -118,6 +119,20 @@ function LLMSettings() { setApiKey(e.target.value)} placeholder="sk-...(本地模型可留空)" slotProps={{ input: { endAdornment: setShowKey(!showKey)}>{showKey ? : } } }} /> + {provider === 'ollama' && ( + { + const v = e.target.value; + setNumCtx(v === '' ? null : Number(v)); + }} + placeholder="默认由模型决定(如 2048、4096、128000)" + slotProps={{ htmlInput: { min: 512, step: 512 } }} + /> + )} ); }