From aa0dd464ac700c06616bdc374e551fd3e33dc0bc Mon Sep 17 00:00:00 2001 From: thzxx Date: Sat, 27 Jun 2026 21:48:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AF=B9=E7=85=A7=20API=20=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E4=BF=AE=E5=A4=8D=203=20=E4=B8=AA=20Adapter=20?= =?UTF-8?q?=E7=9A=84=208=20=E4=B8=AA=E5=AE=9E=E7=8E=B0=E5=B7=AE=E5=BC=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通过逐接口对比 DeepSeek/AgnesAI/Ollama 官方文档与实现代码,发现并修复: DeepSeek (4 fix): - temperature 默认值: 错误发送 0(API默认=1),改为 undefined 让 API 用默认值 - thinking 禁用: API 默认 enabled,不传=开启。改为显式发送 {type:disabled} - reasoning_effort: 补充 xhigh→max 映射(文档规定) - stream 请求: 补充 AbortSignal.timeout 超时控制 Agnes AI (2 fix): - temperature 默认值: 同上 - 图片 image_url: 移除文档未提及的 detail 字段 Ollama (3 fix): - temperature 默认值: 同上(Ollama默认≈0.8) - tool_calls arguments: 从对象改为 JSON 字符串(REST API 要求) - finishReason: 使用 done_reason 字段正确映射(之前始终返回 STOP) --- electron/harness/adapters/agnes-ai.adapter.ts | 4 +-- electron/harness/adapters/deepseek.adapter.ts | 10 ++++--- electron/harness/adapters/ollama.adapter.ts | 27 ++++++++++++++++--- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/electron/harness/adapters/agnes-ai.adapter.ts b/electron/harness/adapters/agnes-ai.adapter.ts index 6502b53..cfd2d7e 100644 --- a/electron/harness/adapters/agnes-ai.adapter.ts +++ b/electron/harness/adapters/agnes-ai.adapter.ts @@ -122,7 +122,7 @@ export class AgnesAdapter extends BaseAdapter { for (const img of origMsg.images) { contentParts.push({ type: 'image_url', - image_url: { url: img.url, detail: img.detail ?? 'auto' }, + image_url: { url: img.url }, }); } messages[i].content = contentParts; @@ -131,7 +131,7 @@ export class AgnesAdapter extends BaseAdapter { const body: Record = { model: this.config.defaultModel, messages, - temperature: request.params.temperature ?? 0, + temperature: request.params.temperature, max_tokens: request.params.maxTokens ?? 65536, stream, }; diff --git a/electron/harness/adapters/deepseek.adapter.ts b/electron/harness/adapters/deepseek.adapter.ts index 2957458..9f0427f 100644 --- a/electron/harness/adapters/deepseek.adapter.ts +++ b/electron/harness/adapters/deepseek.adapter.ts @@ -74,6 +74,7 @@ export class DeepSeekAdapter extends BaseAdapter { ...this.config.headers, }, body: JSON.stringify(body), + signal: AbortSignal.timeout(this.config.timeoutMs ?? 300_000), }); if (!response.ok || !response.body) { @@ -150,7 +151,7 @@ export class DeepSeekAdapter extends BaseAdapter { const body: Record = { model: this.config.defaultModel, messages, - temperature: request.params.temperature ?? 0, + temperature: request.params.temperature, max_tokens: request.params.maxTokens, stream, }; @@ -164,10 +165,13 @@ export class DeepSeekAdapter extends BaseAdapter { } // Thinking 模式 - if (request.params.thinkingEnabled) { + // API 默认 thinking.type = "enabled",必须显式发送 disabled 才能关闭 + if (request.params.thinkingEnabled === false) { + body.thinking = { type: 'disabled' }; + } else if (request.params.thinkingEnabled) { body.thinking = { type: 'enabled' }; const effortMap: Record = { - low: 'high', medium: 'high', high: 'high', max: 'max', + low: 'high', medium: 'high', high: 'high', xhigh: 'max', max: 'max', }; body.reasoning_effort = effortMap[request.params.thinkingEffort ?? 'high'] ?? 'high'; } diff --git a/electron/harness/adapters/ollama.adapter.ts b/electron/harness/adapters/ollama.adapter.ts index ce401a2..20bff85 100644 --- a/electron/harness/adapters/ollama.adapter.ts +++ b/electron/harness/adapters/ollama.adapter.ts @@ -370,10 +370,10 @@ export class OllamaAdapter extends BaseAdapter { ? m.toolResult.result : JSON.stringify(m.toolResult.result); } - // assistant 工具调用 + // assistant 工具调用(Ollama REST API 要求 arguments 为 JSON 字符串) if (m.role === 'assistant' && m.toolCalls?.length) { msg.tool_calls = m.toolCalls.map((tc) => ({ - function: { name: tc.name, arguments: tc.args }, + function: { name: tc.name, arguments: JSON.stringify(tc.args) }, })); } return msg; @@ -384,7 +384,7 @@ export class OllamaAdapter extends BaseAdapter { model: this.config.defaultModel, messages, options: { - temperature: request.params.temperature ?? 0, + temperature: request.params.temperature, num_predict: request.params.maxTokens, top_p: request.params.topP, stop: request.params.stopSequences, @@ -448,7 +448,26 @@ export class OllamaAdapter extends BaseAdapter { outputTokens: (data.eval_count as number) ?? 0, totalTokens: ((data.prompt_eval_count as number) ?? 0) + ((data.eval_count as number) ?? 0), }, - finishReason: data.done ? MetonaFinishReason.STOP : MetonaFinishReason.LENGTH, + finishReason: mapOllamaDoneReason(data.done_reason as string | undefined, !!message?.tool_calls), }; } } + +/** + * 映射 Ollama done_reason → MetonaFinishReason + * + * @see apis/ollama-api-docs-20260518.html — /api/chat 响应字段 + */ +function mapOllamaDoneReason( + reason: string | undefined, + hasToolCalls: boolean, +): MetonaFinishReason { + if (hasToolCalls) return MetonaFinishReason.TOOL_CALLS; + switch (reason) { + case 'stop': return MetonaFinishReason.STOP; + case 'length': return MetonaFinishReason.LENGTH; + case 'load': return MetonaFinishReason.ERROR; + case 'unload': return MetonaFinishReason.ERROR; + default: return MetonaFinishReason.STOP; + } +}