From 536fc890509941ba1fc5b6dc8b280df86c680f78 Mon Sep 17 00:00:00 2001 From: Till JS Date: Sat, 18 Apr 2026 16:36:22 +0200 Subject: [PATCH] fix(research): Claude Opus 4.7 rejects `temperature` param + log executor errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - claude-web-search.ts: only send `temperature` when caller explicitly sets one. Opus 4.7 deprecated the param and returns 400 invalid_request_error "`temperature` is deprecated for this model." Sonnet/Haiku still accept it, so keep the opt-in path. - execute-research.ts: log provider errors via console.warn so future integration failures are visible in stdout. Previously the executor swallowed the underlying error and only returned a generic errorCode, which made diagnosing vendor-specific API changes impossible. Discovered via smoke-testing with a real Anthropic key — the direct curl worked, but our provider 400'd because Opus 4.7 tightened the accepted param set. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/executor/execute-research.ts | 1 + .../src/providers/agent/claude-web-search.ts | 33 +++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/services/mana-research/src/executor/execute-research.ts b/services/mana-research/src/executor/execute-research.ts index bcf54e18b..30b1f166e 100644 --- a/services/mana-research/src/executor/execute-research.ts +++ b/services/mana-research/src/executor/execute-research.ts @@ -133,6 +133,7 @@ export async function executeResearch( function makeError(providerId: ProviderId, t0: number, err: Error): ExecuteResearchOutput { const code = (err as { code?: string }).code ?? err.name ?? 'ERROR'; + console.warn(`[executor.research] ${providerId} failed:`, err.message, err); return { success: false, meta: { diff --git a/services/mana-research/src/providers/agent/claude-web-search.ts b/services/mana-research/src/providers/agent/claude-web-search.ts index 5e31bb484..35ce321ec 100644 --- a/services/mana-research/src/providers/agent/claude-web-search.ts +++ b/services/mana-research/src/providers/agent/claude-web-search.ts @@ -55,6 +55,24 @@ export function createClaudeWebSearchProvider(): ResearchAgent { const model = options.model ?? DEFAULT_MODEL; + // Claude Opus 4.7 deprecated the `temperature` param; only set it + // when the caller explicitly asked for one (older Sonnet/Haiku + // accept it but Opus 4.7 rejects with 400 invalid_request_error). + const body: Record = { + model, + max_tokens: options.maxTokens ?? 2048, + system: options.systemPrompt, + messages: [{ role: 'user', content: query }], + tools: [ + { + type: 'web_search_20250305', + name: 'web_search', + max_uses: DEFAULT_MAX_SEARCHES, + }, + ], + }; + if (options.temperature !== undefined) body.temperature = options.temperature; + const res = await fetch('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { @@ -62,20 +80,7 @@ export function createClaudeWebSearchProvider(): ResearchAgent { 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json', }, - body: JSON.stringify({ - model, - max_tokens: options.maxTokens ?? 2048, - temperature: options.temperature ?? 0.3, - system: options.systemPrompt, - messages: [{ role: 'user', content: query }], - tools: [ - { - type: 'web_search_20250305', - name: 'web_search', - max_uses: DEFAULT_MAX_SEARCHES, - }, - ], - }), + body: JSON.stringify(body), signal: ctx.signal, });