Skip to content

Commit 74a0a32

Browse files
committed
fix(auto-reply): truncate user-facing text on UTF-16 boundary
Use truncateUtf16Safe in agent-runner-execution (message preview) and dispatch-from-config (plan working label) to prevent surrogate pair splitting when non-BMP characters straddle truncation boundaries.
1 parent 1bdde66 commit 74a0a32

2 files changed

Lines changed: 4 additions & 2 deletions

File tree

src/auto-reply/reply/agent-runner-execution.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import { CommandLaneClearedError, GatewayDrainingError } from "../../process/com
8787
import { CommandLane } from "../../process/lanes.js";
8888
import { defaultRuntime } from "../../runtime.js";
8989
import { shouldPreserveUserFacingSessionStateForInputProvenance } from "../../sessions/input-provenance.js";
90+
import { truncateUtf16Safe } from "../../shared/utf16-slice.js";
9091
import {
9192
isMarkdownCapableMessageChannel,
9293
resolveMessageChannel,
@@ -753,7 +754,7 @@ function extractCodexUsageLimitMessage(text: string): string | undefined {
753754
if (!message) {
754755
return undefined;
755756
}
756-
return message.length > 500 ? `${message.slice(0, 497)}...` : message;
757+
return message.length > 500 ? `${truncateUtf16Safe(message, 497)}...` : message;
757758
}
758759

759760
function isPureTransientRateLimitSummary(err: unknown): boolean {

src/auto-reply/reply/dispatch-from-config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import { isAcpSessionKey } from "../../routing/session-key.js";
9595
import { resolveSendPolicy } from "../../sessions/send-policy.js";
9696
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
9797
import { resolveSilentReplyPolicyFromPolicies } from "../../shared/silent-reply-policy.js";
98+
import { truncateUtf16Safe } from "../../shared/utf16-slice.js";
9899
import { createTtsDirectiveTextStreamCleaner } from "../../tts/directives.js";
99100
import {
100101
normalizeTtsAutoMode,
@@ -2565,7 +2566,7 @@ export async function dispatchReplyFromConfig(
25652566
if (collapsed.length <= 80) {
25662567
return collapsed;
25672568
}
2568-
return `${collapsed.slice(0, 77).trimEnd()}...`;
2569+
return `${truncateUtf16Safe(collapsed, 77).trimEnd()}...`;
25692570
};
25702571
const formatPlanUpdateText = (payload: { explanation?: string; steps?: string[] }) => {
25712572
const explanation = payload.explanation?.replace(/\s+/g, " ").trim();

0 commit comments

Comments
 (0)