Summary
Xiaomi MiMo's paid token-plan endpoint (https://token-plan-cn.xiaomimimo.com/v1) speaks the Responses wire for plain requests, but its gateway rejects type: "custom" tools — which Codex emits for apply_patch and other freeform tools:
HTTP 400
{"error":{"code":"responses_feature_not_supported",
"message":"tool type 'custom' is not supported by this gateway phase.",
"type":"unsupported_feature"}}
With the provider configured as adapter: "openai-responses", this makes MiMo unusable as a Codex model for any tool-calling turn (Codex always attaches custom tools). Verified boundary with direct calls:
| Request |
Result |
POST /v1/responses (no tools) |
200 ✅ |
POST /v1/responses + tools:[{type:"custom",name:"apply_patch",...}] |
400 ❌ (responses_feature_not_supported) |
POST /v1/chat/completions |
200 ✅ (including reasoning_content) |
Verified fix: adapter: "openai-chat"
Switching the provider to the chat adapter makes the full Codex loop work, thanks to the existing freeform bridge (responses/parser.ts wraps custom tools as {input:string} functions; bridge.ts relays calls back as custom_tool_call):
"mimo": {
"adapter": "openai-chat",
"baseUrl": "https://token-plan-cn.xiaomimimo.com/v1",
"apiKey": "${MIMO_API_KEY}",
"models": ["mimo-v2.5-pro", "mimo-v2.5"]
}
End-to-end through the proxy (POST /v1/responses, model: "mimo/mimo-v2.5"):
- plain turn → 200, text streamed,
response.completed ✅
- turn with
apply_patch custom tool attached → 200, model emits proper response.custom_tool_call_input.delta/done (Codex's freeform handler requires this shape; a plain function_call would fatal-abort) ✅
- continuation with
custom_tool_call + custom_tool_call_output history → 200, coherent follow-up ✅
Suggestions
- Add a registry preset for MiMo token-plan (
id: "mimo") with adapter: "openai-chat" so users get the working wire by default. (Currently only mimo-free exists; token-plan users hand-roll the provider and naturally pick openai-responses because MiMo documents Responses support.)
- Alternatively/additionally: a per-provider flag to force the custom→
{input:string} function bridging on the responses wire, for gateways that reject type:"custom".
- Document that
openai-responses passthrough requires upstream support for Responses custom tools — a 400 from the gateway currently surfaces without guidance.
One friction point hit while fixing: ocx provider edit mimo --adapter openai-chat refused the change because the hostname resolves to a benchmark/fake-IP address (198.18.x.x) behind a VPN with fake-ip DNS — the runtime path works fine through it, only the CLI edit-time validation blocks. Maybe allow an explicit --force/acknowledgement for that case.
Environment: opencodex 2.10.2, Windows 11, MiMo token-plan (paid) account.
Summary
Xiaomi MiMo's paid token-plan endpoint (
https://token-plan-cn.xiaomimimo.com/v1) speaks the Responses wire for plain requests, but its gateway rejectstype: "custom"tools — which Codex emits forapply_patchand other freeform tools:With the provider configured as
adapter: "openai-responses", this makes MiMo unusable as a Codex model for any tool-calling turn (Codex always attaches custom tools). Verified boundary with direct calls:POST /v1/responses(no tools)POST /v1/responses+tools:[{type:"custom",name:"apply_patch",...}]responses_feature_not_supported)POST /v1/chat/completionsreasoning_content)Verified fix:
adapter: "openai-chat"Switching the provider to the chat adapter makes the full Codex loop work, thanks to the existing freeform bridge (
responses/parser.tswraps custom tools as{input:string}functions;bridge.tsrelays calls back ascustom_tool_call):End-to-end through the proxy (
POST /v1/responses,model: "mimo/mimo-v2.5"):response.completed✅apply_patchcustom tool attached → 200, model emits properresponse.custom_tool_call_input.delta/done(Codex's freeform handler requires this shape; a plainfunction_callwould fatal-abort) ✅custom_tool_call+custom_tool_call_outputhistory → 200, coherent follow-up ✅Suggestions
id: "mimo") withadapter: "openai-chat"so users get the working wire by default. (Currently onlymimo-freeexists; token-plan users hand-roll the provider and naturally pickopenai-responsesbecause MiMo documents Responses support.){input:string}function bridging on the responses wire, for gateways that rejecttype:"custom".openai-responsespassthrough requires upstream support for Responses custom tools — a 400 from the gateway currently surfaces without guidance.One friction point hit while fixing:
ocx provider edit mimo --adapter openai-chatrefused the change because the hostname resolves to a benchmark/fake-IP address (198.18.x.x) behind a VPN with fake-ip DNS — the runtime path works fine through it, only the CLI edit-time validation blocks. Maybe allow an explicit--force/acknowledgement for that case.Environment: opencodex 2.10.2, Windows 11, MiMo token-plan (paid) account.