Skip to content

fix(api): correct Haiku/large-output behaviour (adaptive-thinking guard + no truncation) - #9

Merged
tobyvee merged 2 commits into
mainfrom
fix/api-output-correctness
Jun 27, 2026
Merged

tobyvee merged 2 commits into
mainfrom
fix/api-output-correctness

Conversation

@tobyvee

@tobyvee tobyvee commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Two API-backend correctness fixes surfaced by the live local URL-shortener run (Haiku). Both are required for a ticket to reach done with real committed code; without them every ticket blocks.

1. Adaptive thinking only where supported

thinking: {type:"adaptive"} was sent unconditionally. Haiku 4.5 (and older models) reject it with 400 invalid_request_error: adaptive thinking is not supported on this model, so shaping/implement steps were skipped entirely on Haiku. Now gated by supportsAdaptiveThinking(model) (+ unit tests).

2. Stream + raise output cap so large outputs aren't truncated

A whole-component implementation easily exceeds 16K output tokens. The backend used a non-streaming messages.create capped at 16K, so the model's JSON proposal was silently cut off mid-object and dropped downstream as "agent output could not be parsed" — no code committed, QA blocks every ticket. Observed live: each implement step produced a ~48K-char proposal truncated at exactly the cap.

  • Switch to messages.stream(...).finalMessage() and raise the cap to 32K (streaming avoids the request-timeout risk at high max_tokens, per the claude-api skill guidance).
  • Detect stop_reason === "max_tokens" and return a new StoppedReason "truncated" so a cut-off output is never mistaken for a valid response.
  • Audit a truncated implement step as agent output truncated (hit token cap), distinct from a real parse failure or an empty change set.

Verification

pnpm typecheck · pnpm lint · pnpm test (102) · pnpm build all pass.

🤖 Generated with Claude Code

tobyvee and others added 2 commits June 27, 2026 15:40
The api backend hardcoded thinking:{type:adaptive}, which 400s on Haiku 4.5 / Sonnet 4.5 / older ('adaptive thinking is not supported on this model'). Now gated by supportsAdaptiveThinking(model); omitted for unsupported models. Surfaced by running with ANTHROPIC_MODEL=claude-haiku-4-5. Regression test added.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ncated

A whole-component implementation easily exceeds 16K output tokens. The API
backend used a non-streaming messages.create capped at 16K, so the model's
JSON proposal was silently cut off mid-object and dropped downstream as
"agent output could not be parsed" — no code committed, QA blocks every
ticket. Surfaced live on the local URL-shortener run (Haiku): every implement
step produced a ~48K-char proposal truncated at exactly the cap.

- api backend: switch to messages.stream(...).finalMessage() and raise the cap
  to 32K (streaming avoids the request-timeout risk at high max_tokens).
- detect stop_reason === "max_tokens" and return a new StoppedReason "truncated"
  so a cut-off output is never mistaken for a valid response.
- activities: audit a truncated implement step as "agent output truncated (hit
  token cap)", distinct from a real parse failure or an empty change set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tobyvee
tobyvee merged commit 01e0fdb into main Jun 27, 2026
1 check passed
@tobyvee
tobyvee deleted the fix/api-output-correctness branch June 27, 2026 06:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant