@@ -248,7 +249,7 @@ function ProcessDetailsGroup({ messageCount, toolCallCount, durationMs, cacheMis
}
export function ChatWindow({ session, searchTarget, onSearchTargetHandled, initialScrollPosition, onScrollPositionChange, sessionRunning, newSessionCwd, newSessionDraftKey, newSessionContextBar, initialNewSessionChoices, onNewSessionChoicesChange, onAgentEnd, onToolEnd, onAttentionNeeded, onSessionCreated, onSessionForked, modelsRefreshKey, chatInputRef, onBranchDataChange, onSystemPromptChange, onSystemToolsChange, onSystemInfoLoaderChange, onSessionStatsChange, onSessionStatsPanelOpen, onOpenSettings, onContextUsageChange, onOpenFile, onFilesUploaded, onOpenSubagent, onAskInNewChat, quoteSelectionEnabled = false, initialPrompt, onInitialPromptConsumed, soundEnabled = true, onSoundToggle, playDoneSound = () => {}, unlockAudio, holdAudio }: Props) {
- const { t } = useI18n();
+ const { locale, t } = useI18n();
const isMobile = useIsMobile();
const completionNotificationsEnabled = session?.relation?.kind !== "subagent";
@@ -1284,7 +1285,7 @@ export function ChatWindow({ session, searchTarget, onSearchTargetHandled, initi
would otherwise stay open once its answer shows up, e.g. when
switching between an answered and an unanswered leaf of the same
turn. Manual toggles survive every other re-render. */}
-
+
{processViews}
,
diff --git a/components/CodemodeToolView.tsx b/components/CodemodeToolView.tsx
index 51fa7fa019..9a301893af 100644
--- a/components/CodemodeToolView.tsx
+++ b/components/CodemodeToolView.tsx
@@ -25,7 +25,7 @@ const STATUS_STYLE: Record
};
function CallRow({ call }: { call: CodemodeCallView }) {
- const { t } = useI18n();
+ const { locale, t } = useI18n();
const status = STATUS_STYLE[call.status];
const duration = formatCodemodeDuration(call.durationMs);
return (
@@ -49,7 +49,7 @@ function CallRow({ call }: { call: CodemodeCallView }) {
{duration}
)}
{call.cost !== undefined && (
- {formatCodemodeCost(call.cost)}
+ {formatCodemodeCost(call.cost, locale)}
)}
{call.error && (
@@ -65,7 +65,7 @@ export function CodemodeCallList({ calls, omitted, isError }: {
omitted: number;
isError: boolean;
}) {
- const { t } = useI18n();
+ const { locale, t } = useI18n();
const [showAll, setShowAll] = useState(false);
if (calls.length === 0 && omitted === 0) return null;
const hidden = showAll ? 0 : Math.max(0, calls.length - CODEMODE_VISIBLE_CALLS);
@@ -106,7 +106,7 @@ export function CodemodeCallList({ calls, omitted, isError }: {
))}
{totalCost !== null && (
- {t("codemode.modelCost", { cost: formatCodemodeCost(totalCost) })}
+ {t("codemode.modelCost", { cost: formatCodemodeCost(totalCost, locale) })}
)}
);
diff --git a/components/MessageView.tsx b/components/MessageView.tsx
index 78ff10777b..8861fa7a96 100644
--- a/components/MessageView.tsx
+++ b/components/MessageView.tsx
@@ -26,6 +26,8 @@ import { toolFieldsOfInput, type ToolField } from "@/lib/tool-fields";
import { mcpToolLabel, prettyMcpResultText } from "@/lib/mcp-tool-display";
import { streamRateKey, streamRateStart, streamTokensPerSecond, type StreamRateStart } from "@/lib/stream-token-rate";
import { getTranscriptNotices } from "@/lib/transcript-notices";
+import { formatMoney } from "@/lib/money";
+import type { Locale } from "@/lib/i18n/types";
import { TRANSCRIPT_NOTICE_WARNING_COLOR, transcriptNoticeText } from "@/components/TranscriptNotices";
import type {
AgentMessage,
@@ -680,7 +682,7 @@ function AssistantMessageView({
isCompacting?: boolean;
compactError?: string | null;
}) {
- const { t } = useI18n();
+ const { locale, t } = useI18n();
const time = showTimestamp ? formatTime(message.timestamp) : null;
const blockItems = useMemo(() => (message.content ?? [])
.map((block, originalIndex) => ({ block, originalIndex }))
@@ -946,7 +948,7 @@ function AssistantMessageView({
{(message.usage || turnDurationMs !== undefined) && !isStreaming && (
{[
- message.usage ? formatUsage(message.usage) : null,
+ message.usage ? formatUsage(message.usage, locale) : null,
turnDurationMs !== undefined ? t("chat.turnDuration", { time: formatTurnDuration(turnDurationMs) }) : null,
].filter(Boolean).join(" \u00b7 ")}
@@ -1799,7 +1801,7 @@ function PairedResult({ text, isEmpty, isError }: {
}
function CompactionMessageView({ message }: { message: CustomMessage }) {
- const { t } = useI18n();
+ const { locale, t } = useI18n();
// Collapsed by default, as in pi's TUI: a summary can run to pages.
const [expanded, setExpanded] = useState(false);
const summary = getMessageText(message.content);
@@ -1869,7 +1871,7 @@ function CompactionMessageView({ message }: { message: CustomMessage }) {
)}
{costNotice && (
- {transcriptNoticeText(t, costNotice)}
+ {transcriptNoticeText(t, costNotice, locale)}
)}