v1.1.3 — qwen3-coder ↔ opencode tool-format fix; hybrid loop now operational
The qwen3-coder + opencode tool-message format issue from v1.1.2 is fixed. Hybrid strategies now run the agent loop end-to-end without 400 errors.
What was the issue
Ollama's qwen3-coder renderer rejected OpenAI-standard tool messages:
tool_calls[].function.argumentsas JSON-encoded STRING (OpenAI spec) → Ollama wants OBJECT- Multi-part
toolcontent as ARRAY (OpenAI 1.x) → Ollama wants STRING
Bisected via curl probes. Confirmed against Ollama issue #11621 + goose issue #6883.
The fix
translateForLocal() in router/server.mjs (scoped to local backend only):
- Parse
tool_calls[].function.argumentsstring → object - Flatten array content → string
Inverse of the v1.1.1 outbound normalizer.
Updated canonical headline (60 rows × 3 seeds × 4 strategies)
| Strategy | Pass | Cloud tok | Local tok | Cloud_frac (calls) |
|---|---|---|---|---|
| always-cloud (gpt-5.5) | 15/15 ✓ | 16,094 | 0 | 1.00 |
| always-local (qwen3-coder:30b) | 0/15 | 0 | 2,916 | 0.00 |
| heuristic (agent-aware) | 0/15 | 2,064 | 1,439 | 0.50 |
| cascade | 0/15 | 447 | 2,774 | 0.10 |
Routing layer verified working. Hybrid strategies now make real cloud+local decisions. The remaining 0% hybrid pass is a model-quality gap — qwen3-coder writes prose instead of tool_calls on tool-interpretation turns. v1.2 unblockers: larger local model, or router-level system-prompt augmentation.
Attached
results-v1.1.3-canonical.tar.gz— 60-row canonical sweepfindings.md— diagnostic write-up