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.