Skip to content

v0.1.26 — tool-turn guard: the agent loop no longer stalls on the simple route

Choose a tag to compare

@Lexus2016 Lexus2016 released this 08 Jul 12:44

Field-debugged release: three live-validated failure modes made fusion-agents stall the OpenCode agent loop ("does one step, then waits for continue"). All three are now detected and recovered on the smart simple passthrough — the route ~87 % of agent steps take.

Added

  • Single-route tool-turn completeness guard (src/strategies/tool_turn_guard.ts). Detects, on tool-carrying requests: (1) narrate-and-stop — the model describes the next action in prose and ends the turn with finish_reason:stop and no tool_calls; (2) length-cut tool calls — large-file writes truncated mid-arguments (finish_reason:length, unrunnable JSON); (3) upstream stream termination — Ollama Cloud kills generation streams at ~5 minutes. Recovery is ONE live-streamed retry (nudged to emit the tool call and write large payloads in chunks), failing open to the original response. The stream wrapper is reader-driven rather than a pipeThrough TransformStream, because flush() never runs when the source errors — a transform-based guard is structurally blind to failure (3).
  • Terminal-state instrumentation. Every tool-carrying single-route stream logs one tool-turn terminal state line (finish_reason, tool-call count, guard verdict, lengths, tail) — real-session stalls are diagnosable from the log alone.
  • Per-model request_overrides (single strategy + smart inline simple slot). Extra request-body fields merged into every upstream call; core keys (model, messages, stream, tools, tool_choice) are protected. A/B-measured flagship use: reasoning_effort:"none" stops glm-5.2 deliberating for minutes on mechanical steps (reasoning 1692→0 chars, 6 s→2 s, tool-calling intact; think:false and "low" are ignored by Ollama Cloud).
  • Fusion synth: agentic tool-action directive — when the request carries tools, the synth is told the panel's prose is deliberation, not the final shape: if the best next step is an action, emit the tool call. Inert on the tool-less research/report path.

Changed

  • fusion-agents simple route now sends reasoning_effort:"none" via the new request_overrides. The stale simple-target comment now documents the two real constraints: foreign tool-call-history compatibility and a large context window (a real session overflowed kimi's 262K — do not swap kimi in for speed).

Post-release hotfix on main

  • 8942eb7 — the guard now swallows the upstream [DONE] so its framing is canonical (exactly one [DONE], its own) even when the upstream ends without a finish_reason chunk. Found by a cross-provider post-release review; production clients were shielded by the downstream usage-injection transform, so no observable corruption occurred.

306 → 307 tests green; typecheck clean. Full details in CHANGELOG.md.