From 67a67df35a65fe4bc0c2b50a2548e8ec918463ee Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 3 Jan 2026 06:44:17 +0100 Subject: [PATCH] fix: avoid unsafe string coercion in tui --- src/tui/tui.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tui/tui.ts b/src/tui/tui.ts index 31801c5cf..9e3218045 100644 --- a/src/tui/tui.ts +++ b/src/tui/tui.ts @@ -95,6 +95,14 @@ function formatTokens(total?: number | null, context?: number | null) { return `tokens ${total ?? 0}/${context}${pct !== null ? ` (${pct}%)` : ""}`; } +function asString(value: unknown, fallback = ""): string { + if (typeof value === "string") return value; + if (typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return fallback; +} + export async function runTui(opts: TuiOptions) { const config = loadConfig(); const defaultSession = @@ -235,8 +243,8 @@ export async function runTui(opts: TuiOptions) { continue; } if (message.role === "toolResult") { - const toolCallId = String(message.toolCallId ?? ""); - const toolName = String(message.toolName ?? "tool"); + const toolCallId = asString(message.toolCallId, ""); + const toolName = asString(message.toolName, "tool"); const component = chatLog.startTool(toolCallId, toolName, {}); component.setResult( { @@ -327,9 +335,9 @@ export async function runTui(opts: TuiOptions) { if (!currentSessionId || evt.runId !== currentSessionId) return; if (evt.stream === "tool") { const data = evt.data ?? {}; - const phase = String(data.phase ?? ""); - const toolCallId = String(data.toolCallId ?? ""); - const toolName = String(data.name ?? "tool"); + const phase = asString(data.phase, ""); + const toolCallId = asString(data.toolCallId, ""); + const toolName = asString(data.name, "tool"); if (!toolCallId) return; if (phase === "start") { chatLog.startTool(toolCallId, toolName, data.args);