From cccec122422a5b2d352e0e3f88c0fa36c4a8a65b Mon Sep 17 00:00:00 2001 From: Elvis Tran <40386529+elvistranhere@users.noreply.github.com> Date: Sun, 22 Mar 2026 02:56:23 +1030 Subject: [PATCH 1/3] Show file path in activity status for running tool calls The activity status bar showed generic text like "Running Edit..." without indicating which file was being operated on. Now extracts file_path from the streaming tool input JSON and updates the activity text to show it, e.g. "Running Edit: .../src/theme.ts". Fixes part of the tool call visibility issue. --- src/renderer/stores/sessionStore.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/renderer/stores/sessionStore.ts b/src/renderer/stores/sessionStore.ts index aafcc43a..71df2ceb 100644 --- a/src/renderer/stores/sessionStore.ts +++ b/src/renderer/stores/sessionStore.ts @@ -699,6 +699,20 @@ export const useSessionStore = create((set, get) => ({ const lastTool = [...msgs].reverse().find((m) => m.role === 'tool' && m.toolStatus === 'running') if (lastTool) { lastTool.toolInput = (lastTool.toolInput || '') + event.partialInput + // Update activity text with file path when available + const toolName = lastTool.toolName || 'Tool' + try { + const parsed = JSON.parse(lastTool.toolInput) + const filePath = parsed.file_path || parsed.path || parsed.command + if (filePath) { + const short = typeof filePath === 'string' && filePath.length > 40 + ? '...' + filePath.slice(-37) + : filePath + updated.currentActivity = `Running ${toolName}: ${short}` + } + } catch { + // Input JSON not complete yet, keep existing activity + } } updated.messages = msgs break From ca5e0bc6d329a9dfca5890e732f2f3100a98e47e Mon Sep 17 00:00:00 2001 From: Elvis Tran <40386529+elvistranhere@users.noreply.github.com> Date: Sun, 22 Mar 2026 03:27:42 +1030 Subject: [PATCH 2/3] Address review feedback: use regex instead of JSON.parse Use lightweight regex to extract file_path/path/command from the streaming tool input instead of re-parsing the entire accumulated JSON on every chunk. Avoids performance issues with large payloads. --- src/renderer/stores/sessionStore.ts | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/renderer/stores/sessionStore.ts b/src/renderer/stores/sessionStore.ts index 71df2ceb..90832ecc 100644 --- a/src/renderer/stores/sessionStore.ts +++ b/src/renderer/stores/sessionStore.ts @@ -699,19 +699,18 @@ export const useSessionStore = create((set, get) => ({ const lastTool = [...msgs].reverse().find((m) => m.role === 'tool' && m.toolStatus === 'running') if (lastTool) { lastTool.toolInput = (lastTool.toolInput || '') + event.partialInput - // Update activity text with file path when available + // Update activity text with file path when available, using + // lightweight regex to avoid re-parsing large JSON on every chunk. const toolName = lastTool.toolName || 'Tool' - try { - const parsed = JSON.parse(lastTool.toolInput) - const filePath = parsed.file_path || parsed.path || parsed.command - if (filePath) { - const short = typeof filePath === 'string' && filePath.length > 40 - ? '...' + filePath.slice(-37) - : filePath - updated.currentActivity = `Running ${toolName}: ${short}` - } - } catch { - // Input JSON not complete yet, keep existing activity + const input = lastTool.toolInput || '' + const match = + input.match(/"file_path"\s*:\s*"([^"]+)"/) || + input.match(/"path"\s*:\s*"([^"]+)"/) || + input.match(/"command"\s*:\s*"([^"]+)"/) + if (match && match[1]) { + const detail = match[1] + const short = detail.length > 40 ? '...' + detail.slice(-37) : detail + updated.currentActivity = `Running ${toolName}: ${short}` } } updated.messages = msgs From fc87ef18eb3a471c15924c24f9b8fa2447cfd1cd Mon Sep 17 00:00:00 2001 From: Elvis Tran <40386529+elvistranhere@users.noreply.github.com> Date: Sun, 22 Mar 2026 03:43:34 +1030 Subject: [PATCH 3/3] Address review: parse once with JSON.parse, handle quoted strings Use JSON.parse instead of regex to correctly handle escaped quotes in Bash commands. Only attempt parsing until the activity detail is set, avoiding repeated parsing of large payloads on subsequent chunks. --- src/renderer/stores/sessionStore.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/renderer/stores/sessionStore.ts b/src/renderer/stores/sessionStore.ts index 90832ecc..55f94ced 100644 --- a/src/renderer/stores/sessionStore.ts +++ b/src/renderer/stores/sessionStore.ts @@ -699,18 +699,21 @@ export const useSessionStore = create((set, get) => ({ const lastTool = [...msgs].reverse().find((m) => m.role === 'tool' && m.toolStatus === 'running') if (lastTool) { lastTool.toolInput = (lastTool.toolInput || '') + event.partialInput - // Update activity text with file path when available, using - // lightweight regex to avoid re-parsing large JSON on every chunk. + // Update activity text with file path once when the JSON is + // first parseable. Skip further attempts after activity is set + // to avoid re-parsing large payloads on every chunk. const toolName = lastTool.toolName || 'Tool' - const input = lastTool.toolInput || '' - const match = - input.match(/"file_path"\s*:\s*"([^"]+)"/) || - input.match(/"path"\s*:\s*"([^"]+)"/) || - input.match(/"command"\s*:\s*"([^"]+)"/) - if (match && match[1]) { - const detail = match[1] - const short = detail.length > 40 ? '...' + detail.slice(-37) : detail - updated.currentActivity = `Running ${toolName}: ${short}` + if (updated.currentActivity === `Running ${toolName}...`) { + try { + const parsed = JSON.parse(lastTool.toolInput) + const detail = parsed.file_path || parsed.path || parsed.command + if (typeof detail === 'string' && detail) { + const short = detail.length > 40 ? '...' + detail.slice(-37) : detail + updated.currentActivity = `Running ${toolName}: ${short}` + } + } catch { + // JSON not complete yet + } } } updated.messages = msgs