(body: Record<string, any>)
| 28 | * @note in-place modification |
| 29 | */ |
| 30 | export function modelPatch(body: Record<string, any>) { |
| 31 | const model: string = body.model || '' |
| 32 | if (!model) return body |
| 33 | |
| 34 | const modelName = normalizeModelName(model) |
| 35 | |
| 36 | if (modelName.startsWith('qwen')) { |
| 37 | debug('Applying Qwen patch: use higher temperature for auto fixing') |
| 38 | body.temperature = Math.max(body.temperature || 0, 1.0) |
| 39 | body.enable_thinking = false |
| 40 | } |
| 41 | |
| 42 | if (modelName.startsWith('claude')) { |
| 43 | debug('Applying Claude patch: disable thinking') |
| 44 | body.thinking = { type: 'disabled' } |
| 45 | |
| 46 | // Convert tool_choice to Claude format |
| 47 | if (body.tool_choice === 'required') { |
| 48 | // 'required' -> { type: 'any' } (must call some tool) |
| 49 | debug('Applying Claude patch: convert tool_choice "required" to { type: "any" }') |
| 50 | body.tool_choice = { type: 'any' } |
| 51 | } else if (body.tool_choice?.function?.name) { |
| 52 | // { type: 'function', function: { name: '...' } } -> { type: 'tool', name: '...' } |
| 53 | debug('Applying Claude patch: convert tool_choice format') |
| 54 | body.tool_choice = { type: 'tool', name: body.tool_choice.function.name } |
| 55 | } |
| 56 | |
| 57 | // TODO: Claude naming pattern has changed |
| 58 | // needs proper handling |
| 59 | if ( |
| 60 | modelName.startsWith('claude-opus-4-7') || |
| 61 | modelName.startsWith('claude-opus-47') || |
| 62 | modelName.startsWith('claude-opus-4-8') || |
| 63 | modelName.startsWith('claude-opus-48') |
| 64 | ) { |
| 65 | debug('Applying Claude-4.7/4.8 patch: remove temperature') |
| 66 | delete body.temperature |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | if (modelName.startsWith('grok')) { |
| 71 | debug('Applying Grok patch: removing tool_choice') |
| 72 | delete body.tool_choice |
| 73 | debug('Applying Grok patch: disable reasoning and thinking') |
| 74 | body.thinking = { type: 'disabled', effort: 'minimal' } |
| 75 | body.reasoning = { enabled: false, effort: 'low' } |
| 76 | } |
| 77 | |
| 78 | if (modelName.startsWith('gpt')) { |
| 79 | debug('Applying GPT patch: set verbosity to low') |
| 80 | body.verbosity = 'low' |
| 81 | |
| 82 | if (modelName.startsWith('gpt-52')) { |
| 83 | debug('Applying GPT-52 patch: disable reasoning') |
| 84 | body.reasoning_effort = 'none' |
| 85 | } else if (modelName.startsWith('gpt-51')) { |
| 86 | debug('Applying GPT-51 patch: disable reasoning') |
| 87 | body.reasoning_effort = 'none' |
no test coverage detected