From 2def96efc90a7409984c4e349e624c5bffbfd3a4 Mon Sep 17 00:00:00 2001 From: LE Quoc Dat Date: Mon, 28 Jul 2025 21:46:31 +0200 Subject: [PATCH] AI: How can we stream the edit_file tool when it generating like create_file ? Also the edit_file tool show this """Invalid File Edit Could not extract the file changes from the tool result.""" Check the state of code base and make to sure implement fully --- .../thread/content/ShowToolStream.tsx | 9 ++++---- .../tool-views/file-operation/_utils.ts | 22 +++++++++++++++++++ .../thread/tool-views/xml-parser.ts | 6 ++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/thread/content/ShowToolStream.tsx b/frontend/src/components/thread/content/ShowToolStream.tsx index a393c293..0decd71d 100644 --- a/frontend/src/components/thread/content/ShowToolStream.tsx +++ b/frontend/src/components/thread/content/ShowToolStream.tsx @@ -38,7 +38,8 @@ export const ShowToolStream: React.FC = ({ stableStartTimeRef.current = Date.now(); } - const toolName = extractToolNameFromStream(content); + const rawToolName = extractToolNameFromStream(content); + const toolName = getUserFriendlyToolName(rawToolName || ''); const isEditFile = toolName === 'AI File Edit'; // Extract code_edit content for streaming @@ -105,9 +106,9 @@ export const ShowToolStream: React.FC = ({ // Check if this is a file operation tool const isFileOperationTool = FILE_OPERATION_TOOLS.has(toolName); - const IconComponent = getToolIcon(toolName); - const displayName = getUserFriendlyToolName(toolName); - const paramDisplay = extractPrimaryParam(toolName, content); + const IconComponent = getToolIcon(rawToolName || ''); + const displayName = toolName; + const paramDisplay = extractPrimaryParam(rawToolName || '', content); // Always show tool button, conditionally show content below for file operations only if (showExpanded && (isFileOperationTool || isEditFile)) { diff --git a/frontend/src/components/thread/tool-views/file-operation/_utils.ts b/frontend/src/components/thread/tool-views/file-operation/_utils.ts index 57e8fc2e..97eceb67 100644 --- a/frontend/src/components/thread/tool-views/file-operation/_utils.ts +++ b/frontend/src/components/thread/tool-views/file-operation/_utils.ts @@ -201,6 +201,28 @@ export interface ExtractedEditData { errorMessage?: string; } +const parseContent = (content: any): any => { + if (typeof content === 'string') { + try { + return JSON.parse(content); + } catch (e) { + return content; + } + } + return content; +}; + +const parseOutput = (output: any) => { + if (typeof output === 'string') { + try { + return JSON.parse(output); + } catch { + return output; // Return as string if not JSON + } + } + return output; + }; + export const extractFileEditData = ( assistantContent: any, toolContent: any, diff --git a/frontend/src/components/thread/tool-views/xml-parser.ts b/frontend/src/components/thread/tool-views/xml-parser.ts index 877acef8..8cb8256e 100644 --- a/frontend/src/components/thread/tool-views/xml-parser.ts +++ b/frontend/src/components/thread/tool-views/xml-parser.ts @@ -100,14 +100,12 @@ export function isNewXmlFormat(content: string): boolean { export function extractToolNameFromStream(content: string): string | null { const invokeMatch = content.match(/]*)?>(?!\/)/); if (oldFormatMatch) { - const toolName = oldFormatMatch[1].replace(/_/g, '-'); - return formatToolNameForDisplay(toolName); + return oldFormatMatch[1].replace(/_/g, '-'); } return null;