@@ -414,10 +414,15 @@ prior code fell back to a `{ _raw: <partial JSON> }` tool_call block, which
414414the reactor dispatched — executing a tool with truncated arguments when the
415415model was cut off by ` max_tokens ` (CL-7783: a truncated ` Bash `
416416` rm -rf /tm… ` fragment reached the executor). Now: when ` stopReason ` is
417- ` max_tokens ` and a tool call is still open, the turn fails retryably with a
418- message naming the tool and the truncated prefix, telling the model to retry
419- with a narrower scope; any other unparseable-args case fails retryably as
420- invalid JSON. Two supporting changes: ` providers/anthropic.ts ` parses
417+ ` max_tokens ` and a tool call is still open, the turn fails with an
418+ ` inference.error ` naming the tool and the truncated prefix, advising a
419+ larger budget or a narrower scope for the model's next attempt; any other
420+ unparseable-args case fails the same way as invalid JSON. Both errors carry
421+ category ` retryable ` , but end-of-stream finalization always runs after the
422+ attempt has committed visible output, so the harness commitment boundary
423+ suppresses the mechanical retry — the failure is terminal for the turn, and
424+ the message is guidance for the next attempt rather than a re-issued retry.
425+ Two supporting changes: ` providers/anthropic.ts ` parses
421426` stop_reason ` out of ` MessageDelta ` (previously stripped by the schema) and
422427surfaces it on ` inference.usage ` , and ` vendor/intx-types ` ' ` InferenceUsageEvent `
423428gains the optional ` stopReason ` field both halves flow through. Guarded by the
@@ -426,7 +431,12 @@ exact incident wire sequence and asserts no `tool_call` block reaches the
426431reactor. The OpenAI-compatible adapter was audited for the same path: it has
427432no adapter-local args fallback (the harness was the only dispatch site) but
428433still drops ` finish_reason ` on both paths, so OpenAI streams get the generic
429- invalid-JSON failure rather than the truncation-specific message.
434+ invalid-JSON failure rather than the truncation-specific message. The Gemini
435+ adapter forwards its terminal ` finishReason ` onto ` inference.usage ` (same
436+ spread idiom as Anthropic), but forwards the provider's raw spelling
437+ (` MAX_TOKENS ` ), which the harness ` max_tokens ` comparison does not match —
438+ so Gemini truncation still lands on the generic invalid-JSON failure until
439+ the harness normalizes provider spellings.
430440
431441** Disposition:** Promotion candidate. Safety/correctness fix — prevents
432442executing tools with truncated arguments after a ` max_tokens ` cutoff.
0 commit comments