c4cc0f3bd0
The direct Minimax OpenRouter endpoint silently drops tool-call streams on tool-calling workflows (MiniMax-M2#109, reproduced 4/4 times on 2026-04-18: zero content, no finish_reason, silent close at ~40s). PR #12072 surfaced the failure to the user; this PR avoids it entirely by routing minimax/* requests to Fireworks / NovitaAI / Google-Vertex / AtlasCloud / Together by default. New module agent/provider_tweaks.py centralizes known-broken-endpoint avoidance with a single registry entry per upstream bug. User-supplied provider preferences (provider_sort, providers_allowed/ignored/order) always win — tweaks only fill in defaults where absent, and a user who sets 'only' is fully opted out. Wired into both provider_preferences build sites in run_agent.py (main chat loop + iteration-summary call). Only applies when base_url targets openrouter.ai. Validation | | Before | After | |---|---|---| | minimax/minimax-m2.7 tool-call stream on OR (direct endpoint) | 0/4 success | 4/4 on Fireworks | | extra_body.provider injected for minimax/* on OpenRouter | no | ignore=[minimax] order=[fireworks,novitaai,google-vertex,atlascloud,together] | | extra_body.provider for anthropic/* on OpenRouter | unchanged | unchanged | | extra_body.provider for minimax/* on api.minimax.io | unchanged | unchanged | | User-supplied {only:[minimax]} | unchanged | unchanged (explicit opt-in honoured) | | tests/agent/test_provider_tweaks.py | n/a | 23 passed | | tests/run_agent/test_streaming.py | 26 passed | 26 passed | Live e2e sanity (real OpenRouter call): 89.6s clean response via Fireworks, with `extra_body.provider={'ignore': ['minimax'], 'order': ['fireworks',...]}` confirmed in the outgoing request.