SIGN IN SIGN UP

fix(responses): honour the truncation field instead of silently trimming (#391)

/v1/responses accepted "truncation": "disabled", silently truncated the
conversation anyway, and echoed "truncation": "disabled" back in the response.
ResponsesRequest never decoded the field -- it was in neither CodingKeys nor
init(from:) -- the handler hardcoded strategy: .newestFirst, and the encoder
hardcoded the literal string "disabled" into every response.

So a caller who explicitly opted out of truncation received silently truncated
data under an HTTP 200 that claimed truncation was disabled, with no way to
detect the loss from the response. Chat Completions already handles this
correctly via x_context_strategy: strict, so the two server surfaces
contradicted each other on the same underlying question. The OpenAI contract
vendored at Tests/integration/openai_spec/openapi.yaml requires a 400 when
truncation is disabled and the input exceeds the context window.

  "disabled"  -> strict strategy, 400 on oversized input
  "auto"      -> newest-first trimming (unchanged)
  absent      -> "auto", and the envelope now echoes "auto", not "disabled"
  anything else -> 400 naming the parameter

Verified against a live server with an input deliberately over the runtime
context window: disabled 400 "Input exceeds the model's context window", auto
200 echoing "auto", absent 200 echoing "auto", bogus 400.

Beyond candidate PR #408 (whose diff this takes): its error left `param` null.
Failure.errorParam mapped only .invalidModel, so an OpenAI client could not see
which field it got wrong. .invalidTruncation now maps to "truncation", matching
the .invalidModel precedent -- added red-to-green.

1072 unit tests pass.

Closes #391

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011ccLBbEaVVd4sJyUd5wyhA
A
Arthur Ficial committed
d7a4db6cecd2f8f5cb8469f0547e5709c3d8b1b7
Parent: b6f86dc