From 66bb34a5baa50c40bb74816271f8c6095d6fa5f6 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 19 Jul 2025 16:13:01 +0000 Subject: [PATCH] Add support for rendering 'complete' tool content and attachments Co-authored-by: tnfssc --- .../thread/content/ThreadContent.tsx | 34 +++++++++++++++++++ .../thread/tool-views/CompleteToolView.tsx | 4 +-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/thread/content/ThreadContent.tsx b/frontend/src/components/thread/content/ThreadContent.tsx index c6c2589c..46f2175a 100644 --- a/frontend/src/components/thread/content/ThreadContent.tsx +++ b/frontend/src/components/thread/content/ThreadContent.tsx @@ -150,6 +150,22 @@ export function renderMarkdownContent( {renderAttachments(attachmentArray, fileViewerHandler, sandboxId, project)} ); + } else if (toolName === 'complete') { + // Handle complete tool specially - extract text and attachments + const completeText = toolCall.parameters.text || ''; + const attachments = toolCall.parameters.attachments || ''; + + // Convert single attachment to array for consistent handling + const attachmentArray = Array.isArray(attachments) ? attachments : + (typeof attachments === 'string' ? attachments.split(',').map(a => a.trim()) : []); + + // Render complete tool content with attachment UI + contentParts.push( +
+ {completeText} + {renderAttachments(attachmentArray, fileViewerHandler, sandboxId, project)} +
+ ); } else { const IconComponent = getToolIcon(toolName); @@ -242,6 +258,24 @@ export function renderMarkdownContent( {renderAttachments(attachments, fileViewerHandler, sandboxId, project)} ); + } else if (toolName === 'complete') { + // Extract attachments from the XML attributes + const attachmentsMatch = rawXml.match(/attachments=["']([^"']*)["']/i); + const attachments = attachmentsMatch + ? attachmentsMatch[1].split(',').map(a => a.trim()) + : []; + + // Extract content from the complete tag + const contentMatch = rawXml.match(/]*>([\s\S]*?)<\/complete>/i); + const completeContent = contentMatch ? contentMatch[1] : ''; + + // Render tag content with attachment UI (using the helper) + contentParts.push( +
+ {completeContent} + {renderAttachments(attachments, fileViewerHandler, sandboxId, project)} +
+ ); } else { const IconComponent = getToolIcon(toolName); const paramDisplay = extractPrimaryParam(toolName, rawXml); diff --git a/frontend/src/components/thread/tool-views/CompleteToolView.tsx b/frontend/src/components/thread/tool-views/CompleteToolView.tsx index d92fab4d..a557eb34 100644 --- a/frontend/src/components/thread/tool-views/CompleteToolView.tsx +++ b/frontend/src/components/thread/tool-views/CompleteToolView.tsx @@ -216,11 +216,11 @@ export function CompleteToolView({ )} {/* Text/Summary Section */} - {(text || completeData.summary) && ( + {(text || completeData.summary || completeData.result) && (
- {text || completeData.summary} + {text || completeData.summary || completeData.result}