Repository navigation
fix: surface when a response is truncated by the output limit - #830
Conversation
agegr
left a comment
There was a problem hiding this comment.
Real gap: a stopReason: "length" turn with reasoning-only output looked exactly like a hung session. Mirroring the provider-error path is the right shape, and the ChatWindow final-answer classification fix means the message is not silently dropped.
One change pushed to the branch: the notice copy was a hardcoded English string in lib/message-display.ts; all UI copy here goes through i18n. The helper is now isAssistantTruncated(message, opts): boolean and MessageView renders t("chat.truncatedByOutputLimit") (en / zh-CN / zh-TW added). Tests adjusted; the render tests still assert the English copy through I18nProvider.
Merged current main; tsc, eslint, and message-display / MessageView / ChatWindow tests pass. Approving.
- Add getAssistantTruncationNotice() pure function mirroring getAssistantErrorMessage() - Render a yellow inline banner on assistant messages with stopReason=length - Fix the empty-content guard so thinking-only truncated messages are not hidden - Fix ChatWindow finalAnswerMessage classification to treat truncation as terminal - Add 5 test cases (3 pure-function, 2 component-rendering) for the new seam
…stantTruncated Co-authored-by: Cursor <cursoragent@cursor.com>
82bab97 to
09b4d97
Compare
) * feat: surface when a response is truncated by the output limit - Add getAssistantTruncationNotice() pure function mirroring getAssistantErrorMessage() - Render a yellow inline banner on assistant messages with stopReason=length - Fix the empty-content guard so thinking-only truncated messages are not hidden - Fix ChatWindow finalAnswerMessage classification to treat truncation as terminal - Add 5 test cases (3 pure-function, 2 component-rendering) for the new seam * Move the truncation notice copy into i18n; expose the check as isAssistantTruncated Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Alex Yang <agegcn@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
The problem (observed in real use). When an assistant turn ends on
stopReason: "length"— e.g. a thinking model spending the entire output budget on reasoning — the conversation stops with no visible answer and no warning; the UI just sits on the last thinking block. It reads exactly like a hung session. We hit this with a 128K-token reasoning-only truncation on a long session: the model never produced a final message, and nothing in the UI said so.The fix. Mirrors the existing provider-error handling:
getAssistantTruncationNotice()inlib/message-display.ts— a pure function besidegetAssistantErrorMessage(): non-streaming +stopReason === "length"-> a short notice.stopReasonreachesMessageViewintact on both the live event path (normalizeToolCallspreserves it through the spread) and the history path (verified).MessageView), including the thinking-only-truncated case; classified alongside errors in the final-answer logic (ChatWindow) so the message is never silently dropped.Notice copy: "This response was cut off after reaching the model's output limit. Send a follow-up to continue."
Tests. 5 new cases (3 on the pure function covering the discriminating states, 2 real-render cases on
MessageViewincluding thinking-only).tsc/eslintclean; 1025 tests pass on this branch.Found while building the programmatic dispatch API discussed in #829 — unrelated to that design, so it ships standalone.