From 3d5bb8e02af6ca4eaa0d9fb9ddbd51f9fa620656 Mon Sep 17 00:00:00 2001 From: zs <143140385+Zhangs-11@users.noreply.github.com> Date: Wed, 21 Oct 2026 16:38:24 +0800 Subject: [PATCH 1/3] fix(chat): translate a reply's token usage line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The usage line under an assistant reply ("1,234 in · 567 out · 8,900 cache R · 12 cache W") was hard-coded English, while the turn duration next to it ("took 3s") is translated, so the Chinese UIs showed a line half in each language. The four labels now go through chat.* messages in en, zh-CN and zh-TW; the English text is unchanged. Co-Authored-By: Claude Opus 5.5 --- components/MessageView.tsx | 12 ++++++------ lib/i18n/messages/en.ts | 4 ++++ lib/i18n/messages/zh-CN.ts | 4 ++++ lib/i18n/messages/zh-TW.ts | 4 ++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/components/MessageView.tsx b/components/MessageView.tsx index 78ff10777b..dfdee82b83 100644 --- a/components/MessageView.tsx +++ b/components/MessageView.tsx @@ -946,7 +946,7 @@ function AssistantMessageView({ {(message.usage || turnDurationMs !== undefined) && !isStreaming && (
{[ - message.usage ? formatUsage(message.usage) : null, + message.usage ? formatUsage(message.usage, t) : null, turnDurationMs !== undefined ? t("chat.turnDuration", { time: formatTurnDuration(turnDurationMs) }) : null, ].filter(Boolean).join(" \u00b7 ")}
@@ -2225,12 +2225,12 @@ function formatUsage(usage: { cacheRead: number; cacheWrite: number; cost: { total: number }; -}): string { +}, t: (key: string, params?: Record) => string): string { const parts = []; - if (usage.input) parts.push(`${usage.input.toLocaleString()} in`); - if (usage.output) parts.push(`${usage.output.toLocaleString()} out`); - if (usage.cacheRead) parts.push(`${usage.cacheRead.toLocaleString()} cache R`); - if (usage.cacheWrite) parts.push(`${usage.cacheWrite.toLocaleString()} cache W`); + if (usage.input) parts.push(t("chat.usageInput", { count: usage.input.toLocaleString() })); + if (usage.output) parts.push(t("chat.usageOutput", { count: usage.output.toLocaleString() })); + if (usage.cacheRead) parts.push(t("chat.usageCacheRead", { count: usage.cacheRead.toLocaleString() })); + if (usage.cacheWrite) parts.push(t("chat.usageCacheWrite", { count: usage.cacheWrite.toLocaleString() })); if (usage.cost?.total) parts.push(`$${usage.cost.total.toFixed(4)}`); return parts.join(" · "); } diff --git a/lib/i18n/messages/en.ts b/lib/i18n/messages/en.ts index cd3d53ef39..cc65b6c35d 100644 --- a/lib/i18n/messages/en.ts +++ b/lib/i18n/messages/en.ts @@ -500,6 +500,10 @@ export const enLocale: LocalePlugin = { "chat.toolCall": "tool call", "chat.toolCalls": "tool calls", "chat.turnDuration": "took {time}", + "chat.usageInput": "{count} in", + "chat.usageOutput": "{count} out", + "chat.usageCacheRead": "{count} cache R", + "chat.usageCacheWrite": "{count} cache W", "chat.collapseProcess": "Collapse process details", "chat.expandProcess": "Expand process details", "transcriptNotice.costSuffix": " (~{cost})", diff --git a/lib/i18n/messages/zh-CN.ts b/lib/i18n/messages/zh-CN.ts index bb1c64868e..e79cda1cea 100644 --- a/lib/i18n/messages/zh-CN.ts +++ b/lib/i18n/messages/zh-CN.ts @@ -500,6 +500,10 @@ export const zhCNLocale: LocalePlugin = { "chat.toolCall": "次工具调用", "chat.toolCalls": "次工具调用", "chat.turnDuration": "耗时 {time}", + "chat.usageInput": "输入 {count}", + "chat.usageOutput": "输出 {count}", + "chat.usageCacheRead": "缓存读取 {count}", + "chat.usageCacheWrite": "缓存写入 {count}", "chat.collapseProcess": "收起处理详情", "chat.expandProcess": "展开处理详情", "transcriptNotice.costSuffix": "(约 {cost})", diff --git a/lib/i18n/messages/zh-TW.ts b/lib/i18n/messages/zh-TW.ts index fe29c7f3bc..ce35d75895 100644 --- a/lib/i18n/messages/zh-TW.ts +++ b/lib/i18n/messages/zh-TW.ts @@ -500,6 +500,10 @@ export const zhTWLocale: LocalePlugin = { "chat.toolCall": "次工具呼叫", "chat.toolCalls": "次工具呼叫", "chat.turnDuration": "耗時 {time}", + "chat.usageInput": "輸入 {count}", + "chat.usageOutput": "輸出 {count}", + "chat.usageCacheRead": "快取讀取 {count}", + "chat.usageCacheWrite": "快取寫入 {count}", "chat.collapseProcess": "收起處理詳細資料", "chat.expandProcess": "展開處理詳細資料", "transcriptNotice.costSuffix": "(約 {cost})", From 118843020422516e645572e8e11df4d7d23e0aee Mon Sep 17 00:00:00 2001 From: zs <143140385+Zhangs-11@users.noreply.github.com> Date: Wed, 21 Oct 2026 17:01:11 +0800 Subject: [PATCH 2/3] fix(chat): translate a long ! command's full-output links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under a truncated ! command, the "view full output" / "loading…" button and the "download full output" link were hard-coded English. They now go through chat.* messages in en, zh-CN and zh-TW; the English text is unchanged. Co-Authored-By: Claude Opus 5.5 --- components/MessageView.tsx | 5 +++-- lib/i18n/messages/en.ts | 3 +++ lib/i18n/messages/zh-CN.ts | 3 +++ lib/i18n/messages/zh-TW.ts | 3 +++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/components/MessageView.tsx b/components/MessageView.tsx index dfdee82b83..7db852ecdf 100644 --- a/components/MessageView.tsx +++ b/components/MessageView.tsx @@ -2236,6 +2236,7 @@ function formatUsage(usage: { } function BashExecutionView({ message, sessionId }: { message: BashExecutionMessage; sessionId?: string }) { + const { t } = useI18n(); const [fullOutput, setFullOutput] = useState(null); const [loadingFull, setLoadingFull] = useState(false); const [fullError, setFullError] = useState(null); @@ -2299,14 +2300,14 @@ function BashExecutionView({ message, sessionId }: { message: BashExecutionMessa disabled={loadingFull} style={{ background: "none", border: "none", color: "var(--accent)", cursor: loadingFull ? "default" : "pointer", fontSize: 11, padding: 0, textDecoration: "underline" }} > - {loadingFull ? "loading…" : "view full output"} + {loadingFull ? t("chat.loadingFullOutput") : t("chat.viewFullOutput")} )} - download full output + {t("chat.downloadFullOutput")} {fullError && ({fullError})} diff --git a/lib/i18n/messages/en.ts b/lib/i18n/messages/en.ts index cc65b6c35d..90d0889ea9 100644 --- a/lib/i18n/messages/en.ts +++ b/lib/i18n/messages/en.ts @@ -504,6 +504,9 @@ export const enLocale: LocalePlugin = { "chat.usageOutput": "{count} out", "chat.usageCacheRead": "{count} cache R", "chat.usageCacheWrite": "{count} cache W", + "chat.viewFullOutput": "view full output", + "chat.loadingFullOutput": "loading…", + "chat.downloadFullOutput": "download full output", "chat.collapseProcess": "Collapse process details", "chat.expandProcess": "Expand process details", "transcriptNotice.costSuffix": " (~{cost})", diff --git a/lib/i18n/messages/zh-CN.ts b/lib/i18n/messages/zh-CN.ts index e79cda1cea..7f8a6630a4 100644 --- a/lib/i18n/messages/zh-CN.ts +++ b/lib/i18n/messages/zh-CN.ts @@ -504,6 +504,9 @@ export const zhCNLocale: LocalePlugin = { "chat.usageOutput": "输出 {count}", "chat.usageCacheRead": "缓存读取 {count}", "chat.usageCacheWrite": "缓存写入 {count}", + "chat.viewFullOutput": "查看完整输出", + "chat.loadingFullOutput": "加载中…", + "chat.downloadFullOutput": "下载完整输出", "chat.collapseProcess": "收起处理详情", "chat.expandProcess": "展开处理详情", "transcriptNotice.costSuffix": "(约 {cost})", diff --git a/lib/i18n/messages/zh-TW.ts b/lib/i18n/messages/zh-TW.ts index ce35d75895..444feeba7b 100644 --- a/lib/i18n/messages/zh-TW.ts +++ b/lib/i18n/messages/zh-TW.ts @@ -504,6 +504,9 @@ export const zhTWLocale: LocalePlugin = { "chat.usageOutput": "輸出 {count}", "chat.usageCacheRead": "快取讀取 {count}", "chat.usageCacheWrite": "快取寫入 {count}", + "chat.viewFullOutput": "檢視完整輸出", + "chat.loadingFullOutput": "載入中…", + "chat.downloadFullOutput": "下載完整輸出", "chat.collapseProcess": "收起處理詳細資料", "chat.expandProcess": "展開處理詳細資料", "transcriptNotice.costSuffix": "(約 {cost})", From 9ea77b030cc03a47bedf882de8746a59dcab3cab Mon Sep 17 00:00:00 2001 From: zs <143140385+Zhangs-11@users.noreply.github.com> Date: Mon, 26 Oct 2026 14:24:16 +0800 Subject: [PATCH 3/3] fix(chat): translate the close button of the composer's warning banner Co-Authored-By: Claude Opus 5.5 --- components/ChatInput.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/ChatInput.tsx b/components/ChatInput.tsx index babcefe850..45a94e6944 100644 --- a/components/ChatInput.tsx +++ b/components/ChatInput.tsx @@ -565,6 +565,7 @@ function QueuedMessageRow({ kind, text }: { kind: "steer" | "follow-up"; text: s } function ModelNoticeBanner({ tone, title, body, onClose }: { tone: "error" | "warning"; title: string; body: string; onClose?: () => void }) { + const { t } = useI18n(); const color = tone === "error" ? "239,68,68" : "234,179,8"; return (