fix(agents): truncate exec command detail on code-point boundaries#96424
Closed
ly-wang19 wants to merge 1 commit into
Closed
fix(agents): truncate exec command detail on code-point boundaries#96424ly-wang19 wants to merge 1 commit into
ly-wang19 wants to merge 1 commit into
Conversation
compactRawCommand in src/agents/tool-display-exec.ts middle-truncated the one-line command with raw String.prototype.slice. When the head or tail boundary fell between the two UTF-16 code units of a surrogate pair (e.g. an emoji like U+1F600), the slice kept a lone surrogate, which renders as the replacement character in the tool-call summary shown in chat/transcripts. Use the existing sliceUtf16Safe helper for both ends so the boundary falls on a code-point boundary, dropping the whole emoji instead of half of it. This is behavior-preserving for non-surrogate input. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
Closing this PR because the author has more than 20 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
compactRawCommandinsrc/agents/tool-display-exec.tsbuilds the short, redacted exec-command label shown in tool-call summaries (chat timeline and transcripts). When the one-line command is longer thanmaxLength(default 120), it middle-truncates with rawString.prototype.slice:String.prototype.sliceoperates on UTF-16 code units, not code points. When a truncation boundary falls between the two halves of a surrogate pair (e.g. an emoji such as 😀U+1F600, encoded as the surrogate pairD83D DE00), the head slice keeps the high surrogate\uD83Dand drops its low half — leaving a lone surrogate that renders as the replacement character�in the displayed detail. The symmetric tail slice can likewise begin on a lone low surrogate.Before / after repro
Input (normalized one-line form is 140 UTF-16 units; the 😀 high surrogate sits at the head boundary index 58):
git commit -m aaa…aaa\uD83D— a dangling high surrogate, shown as…aaa�…in the tool-call summary.git commit -m aaa…aaa(no trailing lone surrogate), matching the repo's existing UTF-16-safe behavior.Fix
Use the existing
sliceUtf16Safehelper fromsrc/utils.tsfor both ends. It already nudges either edge off a dangling surrogate half (the same helper backingtruncateUtf16Safe). The change is behavior-preserving for all non-surrogate input (byte-identical output).A regression test was added to
src/agents/tool-display.test.ts(alongside the existingcompactRawCommand middle truncationcases), exercising the publicresolveExecDetailAPI with an unknown binary so the compact raw form is returned directly. It asserts the rendered detail contains no lone surrogate and drops the whole emoji.Evidence
Standalone node red-green proof replicating the exact
compactRawCommandlogic before and after the fix, plussliceUtf16Safecopied verbatim fromsrc/utils.ts:The bug reproduces with the buggy slice (lone
\uD83Dat the head boundary) and is gone after switching tosliceUtf16Safe, while every non-surrogate input is byte-for-byte unchanged.🤖 Generated with Claude Code