diff --git a/apps/vscode-e2e/src/suite/tools/apply-diff.test.ts b/apps/vscode-e2e/src/suite/tools/apply-diff.test.ts index 729d6839b197..c882dc403389 100644 --- a/apps/vscode-e2e/src/suite/tools/apply-diff.test.ts +++ b/apps/vscode-e2e/src/suite/tools/apply-diff.test.ts @@ -181,14 +181,43 @@ function validateInput(input) { // Check for tool execution if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of apply_diff tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("apply_diff")) { + const text = message.text + if ( + text.includes("apply_diff") || + text.includes('"tool":"apply_diff"') || + text.includes("applyDiff") || + text.includes("appliedDiff") + ) { applyDiffExecuted = true console.log("apply_diff tool executed!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if ( + requestData && + requestData.request && + (requestData.request.includes("apply_diff") || requestData.request.includes("appliedDiff")) + ) { + applyDiffExecuted = true + console.log("apply_diff tool executed (parsed from JSON)!") + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } @@ -294,14 +323,43 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`, // Check for tool execution if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of apply_diff tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("apply_diff")) { + const text = message.text + if ( + text.includes("apply_diff") || + text.includes('"tool":"apply_diff"') || + text.includes("applyDiff") || + text.includes("appliedDiff") + ) { applyDiffExecuted = true console.log("apply_diff tool executed!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if ( + requestData && + requestData.request && + (requestData.request.includes("apply_diff") || requestData.request.includes("appliedDiff")) + ) { + applyDiffExecuted = true + console.log("apply_diff tool executed (parsed from JSON)!") + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } @@ -413,14 +471,43 @@ function keepThis() { // Check for tool execution if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of apply_diff tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("apply_diff")) { + const text = message.text + if ( + text.includes("apply_diff") || + text.includes('"tool":"apply_diff"') || + text.includes("applyDiff") || + text.includes("appliedDiff") + ) { applyDiffExecuted = true console.log("apply_diff tool executed!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if ( + requestData && + requestData.request && + (requestData.request.includes("apply_diff") || requestData.request.includes("appliedDiff")) + ) { + applyDiffExecuted = true + console.log("apply_diff tool executed (parsed from JSON)!") + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } @@ -521,14 +608,43 @@ ${testFile.content}\nAssume the file exists and you can modify it directly.`, // Check for tool execution attempt if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of apply_diff tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("apply_diff")) { + const text = message.text + if ( + text.includes("apply_diff") || + text.includes('"tool":"apply_diff"') || + text.includes("applyDiff") || + text.includes("appliedDiff") + ) { applyDiffAttempted = true console.log("apply_diff tool attempted!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if ( + requestData && + requestData.request && + (requestData.request.includes("apply_diff") || requestData.request.includes("appliedDiff")) + ) { + applyDiffAttempted = true + console.log("apply_diff tool attempted (parsed from JSON)!") + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } @@ -651,15 +767,45 @@ function checkInput(input) { // Check for tool execution if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of apply_diff tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("apply_diff")) { + const text = message.text + if ( + text.includes("apply_diff") || + text.includes('"tool":"apply_diff"') || + text.includes("applyDiff") || + text.includes("appliedDiff") + ) { applyDiffExecuted = true applyDiffCount++ console.log(`apply_diff tool executed! (count: ${applyDiffCount})`) + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if ( + requestData && + requestData.request && + (requestData.request.includes("apply_diff") || requestData.request.includes("appliedDiff")) + ) { + applyDiffExecuted = true + applyDiffCount++ + console.log(`apply_diff tool executed (parsed from JSON)! (count: ${applyDiffCount})`) + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } diff --git a/apps/vscode-e2e/src/suite/tools/execute-command.test.ts b/apps/vscode-e2e/src/suite/tools/execute-command.test.ts index f207dae685ca..5f250200cc8b 100644 --- a/apps/vscode-e2e/src/suite/tools/execute-command.test.ts +++ b/apps/vscode-e2e/src/suite/tools/execute-command.test.ts @@ -129,19 +129,42 @@ suite("Roo Code execute_command Tool", function () { console.error("Error:", message.text) } - // Check for tool execution + // Check for tool execution with more robust detection if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) - try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("execute_command")) { - executeCommandToolCalled = true - // The request contains the actual tool execution result - commandExecuted = requestData.request - console.log("execute_command tool called, full request:", commandExecuted.substring(0, 300)) + + const text = message.text + if ( + text.includes("execute_command") || + text.includes('"tool":"execute_command"') || + text.includes("executeCommand") + ) { + executeCommandToolCalled = true + commandExecuted = text + console.log("execute_command tool called!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + try { + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("execute_command")) { + executeCommandToolCalled = true + commandExecuted = requestData.request + console.log("execute_command tool called (parsed from JSON)!") + } + } catch (e) { + console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", text.substring(0, 500)) } - } catch (e) { - console.log("Failed to parse api_req_started message:", e) } } } @@ -233,21 +256,48 @@ Then use the attempt_completion tool to complete the task. Do not suggest any co console.error("Error:", message.text) } - // Check for tool execution + // Check for tool execution with more robust detection if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) - try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("execute_command")) { - executeCommandToolCalled = true - // Check if the request contains the cwd - if (requestData.request.includes(subDir) || requestData.request.includes("test-subdir")) { - cwdUsed = subDir + + const text = message.text + if ( + text.includes("execute_command") || + text.includes('"tool":"execute_command"') || + text.includes("executeCommand") + ) { + executeCommandToolCalled = true + // Check if the request contains the cwd + if (text.includes(subDir) || text.includes("test-subdir")) { + cwdUsed = subDir + } + console.log("execute_command tool called, checking for cwd in request") + } else { + // Also try to parse as JSON if it doesn't match string patterns + try { + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("execute_command")) { + executeCommandToolCalled = true + // Check if the request contains the cwd + if (requestData.request.includes(subDir) || requestData.request.includes("test-subdir")) { + cwdUsed = subDir + } + console.log("execute_command tool called (parsed from JSON), checking for cwd") } - console.log("execute_command tool called, checking for cwd in request") + } catch (e) { + console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", text.substring(0, 500)) } - } catch (e) { - console.log("Failed to parse api_req_started message:", e) } } } @@ -349,19 +399,42 @@ Avoid at all costs suggesting a command when using the attempt_completion tool`, console.error("Error:", message.text) } - // Check for tool execution + // Check for tool execution with more robust detection if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) - try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("execute_command")) { - executeCommandCallCount++ - // Store the full request to check for command content - commandsExecuted.push(requestData.request) - console.log(`execute_command tool call #${executeCommandCallCount}`) + + const text = message.text + if ( + text.includes("execute_command") || + text.includes('"tool":"execute_command"') || + text.includes("executeCommand") + ) { + executeCommandCallCount++ + commandsExecuted.push(text) + console.log(`execute_command tool call #${executeCommandCallCount}`) + } else { + // Also try to parse as JSON if it doesn't match string patterns + try { + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("execute_command")) { + executeCommandCallCount++ + commandsExecuted.push(requestData.request) + console.log(`execute_command tool call #${executeCommandCallCount} (parsed from JSON)`) + } + } catch (e) { + console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", text.substring(0, 500)) } - } catch (e) { - console.log("Failed to parse api_req_started message:", e) } } } @@ -468,19 +541,42 @@ After both commands are executed, use the attempt_completion tool to complete th console.log("Command output:", message.text?.substring(0, 200)) } - // Check for tool execution + // Check for tool execution with more robust detection if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) - try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("execute_command")) { - executeCommandToolCalled = true - // The request contains the actual tool execution result - commandExecuted = requestData.request - console.log("execute_command tool called, full request:", commandExecuted.substring(0, 300)) + + const text = message.text + if ( + text.includes("execute_command") || + text.includes('"tool":"execute_command"') || + text.includes("executeCommand") + ) { + executeCommandToolCalled = true + commandExecuted = text + console.log("execute_command tool called!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + try { + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("execute_command")) { + executeCommandToolCalled = true + commandExecuted = requestData.request + console.log("execute_command tool called (parsed from JSON)!") + } + } catch (e) { + console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", text.substring(0, 500)) } - } catch (e) { - console.log("Failed to parse api_req_started message:", e) } } } diff --git a/apps/vscode-e2e/src/suite/tools/insert-content.test.ts b/apps/vscode-e2e/src/suite/tools/insert-content.test.ts index 4dd0c209280c..a8e0b06a0ba5 100644 --- a/apps/vscode-e2e/src/suite/tools/insert-content.test.ts +++ b/apps/vscode-e2e/src/suite/tools/insert-content.test.ts @@ -78,169 +78,190 @@ function goodbye() { // Clean up after all tests suiteTeardown(async () => { // Cancel any running tasks before cleanup - test("Should insert content at the beginning of a file (line 1)", async function () { - const api = globalThis.api - // Clean up before each test - setup(async () => { - // Cancel any previous task - try { - await globalThis.api.cancelCurrentTask() - } catch { - // Task might not be running - } + try { + await globalThis.api.cancelCurrentTask() + } catch { + // Task might not be running + } - // Small delay to ensure clean state - await sleep(100) - }) + // Clean up all test files + console.log("Cleaning up test files...") + for (const [key, file] of Object.entries(testFiles)) { + try { + await fs.unlink(file.path) + console.log(`Cleaned up ${key} test file`) + } catch (error) { + console.log(`Failed to clean up ${key} test file:`, error) + } + } + }) - // Clean up after each test - teardown(async () => { - // Cancel the current task - try { - await globalThis.api.cancelCurrentTask() - } catch { - // Task might not be running - } + // Clean up before each test + setup(async () => { + // Cancel any previous task + try { + await globalThis.api.cancelCurrentTask() + } catch { + // Task might not be running + } - // Small delay to ensure clean state - await sleep(100) - }) - const messages: ClineMessage[] = [] - const testFile = testFiles.simpleText - const insertContent = "New first line" - const expectedContent = `${insertContent} + // Small delay to ensure clean state + await sleep(100) + }) + + // Clean up after each test + teardown(async () => { + // Cancel the current task + try { + await globalThis.api.cancelCurrentTask() + } catch { + // Task might not be running + } + + // Small delay to ensure clean state + await sleep(100) + }) + + test("Should insert content at the beginning of a file (line 1)", async function () { + const api = globalThis.api + const messages: ClineMessage[] = [] + const testFile = testFiles.simpleText + const insertContent = "New first line" + const expectedContent = `${insertContent} ${testFile.content}` - let taskStarted = false - let taskCompleted = false - let errorOccurred: string | null = null - let insertContentExecuted = false - - // Listen for messages - const messageHandler = ({ message }: { message: ClineMessage }) => { - messages.push(message) - - // Log important messages for debugging - if (message.type === "say" && message.say === "error") { - errorOccurred = message.text || "Unknown error" - console.error("Error:", message.text) - } - if (message.type === "ask" && message.ask === "tool") { - console.log("Tool request:", message.text?.substring(0, 200)) - } - if (message.type === "say" && (message.say === "completion_result" || message.say === "text")) { - console.log("AI response:", message.text?.substring(0, 200)) - } + let taskStarted = false + let taskCompleted = false + let errorOccurred: string | null = null + let insertContentExecuted = false - // Check for tool execution - if (message.type === "say" && message.say === "api_req_started" && message.text) { - console.log("API request started:", message.text.substring(0, 200)) + // Listen for messages + const messageHandler = ({ message }: { message: ClineMessage }) => { + messages.push(message) + + // Log important messages for debugging + if (message.type === "say" && message.say === "error") { + errorOccurred = message.text || "Unknown error" + console.error("Error:", message.text) + } + if (message.type === "ask" && message.ask === "tool") { + console.log("Tool request:", message.text?.substring(0, 200)) + } + if (message.type === "say" && (message.say === "completion_result" || message.say === "text")) { + console.log("AI response:", message.text?.substring(0, 200)) + } + + // Check for tool execution with more robust detection + if (message.type === "say" && message.say === "api_req_started" && message.text) { + console.log("API request started:", message.text.substring(0, 200)) + + const text = message.text + if ( + text.includes("insert_content") || + text.includes('"tool":"insert_content"') || + text.includes("insertContent") + ) { + insertContentExecuted = true + console.log("insert_content tool executed!") + } else { + // Also try to parse as JSON if it doesn't match string patterns try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("insert_content")) { + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("insert_content")) { insertContentExecuted = true - console.log("insert_content tool executed!") + console.log("insert_content tool executed (parsed from JSON)!") } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", text.substring(0, 500)) } } } - api.on(RooCodeEventName.Message, messageHandler) + } + api.on(RooCodeEventName.Message, messageHandler) - // Listen for task events - const taskStartedHandler = (id: string) => { - if (id === taskId) { - taskStarted = true - console.log("Task started:", id) - } + // Listen for task events + const taskStartedHandler = (id: string) => { + if (id === taskId) { + taskStarted = true + console.log("Task started:", id) } - api.on(RooCodeEventName.TaskStarted, taskStartedHandler) + } + api.on(RooCodeEventName.TaskStarted, taskStartedHandler) - const taskCompletedHandler = (id: string) => { - if (id === taskId) { - taskCompleted = true - console.log("Task completed:", id) - } + const taskCompletedHandler = (id: string) => { + if (id === taskId) { + taskCompleted = true + console.log("Task completed:", id) } - api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler) + } + api.on(RooCodeEventName.TaskCompleted, taskCompletedHandler) - let taskId: string - try { - // Start the task - taskId = await api.startNewTask({ - configuration: { - mode: "code", - autoApprovalEnabled: true, - alwaysAllowWrite: true, - alwaysAllowReadOnly: true, - alwaysAllowReadOnlyOutsideWorkspace: true, - }, - text: `Use insert_content to add "${insertContent}" at line 1 (beginning) of the file ${testFile.name}. The file already exists with this content: + let taskId: string + try { + // Start the task + taskId = await api.startNewTask({ + configuration: { + mode: "code", + autoApprovalEnabled: true, + alwaysAllowWrite: true, + alwaysAllowReadOnly: true, + alwaysAllowReadOnlyOutsideWorkspace: true, + }, + text: `Use insert_content to add "${insertContent}" at line 1 (beginning) of the file ${testFile.name}. The file already exists with this content: ${testFile.content} Assume the file exists and you can modify it directly.`, - }) - - console.log("Task ID:", taskId) - console.log("Test filename:", testFile.name) + }) - // Wait for task to start - await waitFor(() => taskStarted, { timeout: 45_000 }) + console.log("Task ID:", taskId) + console.log("Test filename:", testFile.name) - // Check for early errors - if (errorOccurred) { - console.error("Early error detected:", errorOccurred) - } + // Wait for task to start + await waitFor(() => taskStarted, { timeout: 45_000 }) - // Wait for task completion - await waitFor(() => taskCompleted, { timeout: 45_000 }) - - // Give extra time for file system operations - await sleep(2000) - - // Check if the file was modified correctly - const actualContent = await fs.readFile(testFile.path, "utf-8") - console.log("File content after insertion:", actualContent) - - // Verify tool was executed - assert.strictEqual(insertContentExecuted, true, "insert_content tool should have been executed") - - // Verify file content - assert.strictEqual( - actualContent.trim(), - expectedContent.trim(), - "Content should be inserted at the beginning of the file", - ) - - // Verify no errors occurred - assert.strictEqual( - errorOccurred, - null, - `Task should complete without errors, but got: ${errorOccurred}`, - ) - - console.log("Test passed! insert_content tool executed and content inserted at beginning successfully") - } finally { - api.off(RooCodeEventName.Message, messageHandler) - api.off(RooCodeEventName.TaskStarted, taskStartedHandler) - api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler) + // Check for early errors + if (errorOccurred) { + console.error("Early error detected:", errorOccurred) } - }) - try { - await globalThis.api.cancelCurrentTask() - } catch { - // Task might not be running - } - // Clean up all test files - console.log("Cleaning up test files...") - for (const [key, file] of Object.entries(testFiles)) { - try { - await fs.unlink(file.path) - console.log(`Cleaned up ${key} test file`) - } catch (error) { - console.log(`Failed to clean up ${key} test file:`, error) - } + // Wait for task completion + await waitFor(() => taskCompleted, { timeout: 45_000 }) + + // Give extra time for file system operations + await sleep(2000) + + // Check if the file was modified correctly + const actualContent = await fs.readFile(testFile.path, "utf-8") + console.log("File content after insertion:", actualContent) + + // Verify tool was executed + assert.strictEqual(insertContentExecuted, true, "insert_content tool should have been executed") + + // Verify file content + assert.strictEqual( + actualContent.trim(), + expectedContent.trim(), + "Content should be inserted at the beginning of the file", + ) + + // Verify no errors occurred + assert.strictEqual(errorOccurred, null, `Task should complete without errors, but got: ${errorOccurred}`) + + console.log("Test passed! insert_content tool executed and content inserted at beginning successfully") + } finally { + api.off(RooCodeEventName.Message, messageHandler) + api.off(RooCodeEventName.TaskStarted, taskStartedHandler) + api.off(RooCodeEventName.TaskCompleted, taskCompletedHandler) } }) diff --git a/apps/vscode-e2e/src/suite/tools/list-files.test.ts b/apps/vscode-e2e/src/suite/tools/list-files.test.ts index 5a1fd6cc3be3..2cb42261fe13 100644 --- a/apps/vscode-e2e/src/suite/tools/list-files.test.ts +++ b/apps/vscode-e2e/src/suite/tools/list-files.test.ts @@ -187,22 +187,35 @@ This directory contains various files and subdirectories for testing the list_fi // Check for tool execution and capture results if (message.type === "say" && message.say === "api_req_started") { const text = message.text || "" - if (text.includes("list_files")) { + console.log("Checking for list_files tool in api_req_started...") + + // More robust detection of list_files tool + if (text.includes("list_files") || text.includes('"tool":"list_files"') || text.includes("listFiles")) { toolExecuted = true console.log("list_files tool executed:", text.substring(0, 200)) - // Extract list results from the tool execution + // Extract list results from the tool execution with better error handling try { - const jsonMatch = text.match(/\{"request":".*?"\}/) - if (jsonMatch) { - const requestData = JSON.parse(jsonMatch[0]) - if (requestData.request && requestData.request.includes("Result:")) { - listResults = requestData.request - console.log("Captured list results:", listResults?.substring(0, 300)) + let requestData: { request?: string } | null = null + + // Try to parse the entire text as JSON + try { + requestData = JSON.parse(text) + } catch { + // Try to extract JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) } } + + if (requestData && requestData.request && requestData.request.includes("Result:")) { + listResults = requestData.request + console.log("Captured list results:", listResults?.substring(0, 300)) + } } catch (e) { console.log("Failed to parse list results:", e) + console.log("Raw text:", text.substring(0, 500)) } } } diff --git a/apps/vscode-e2e/src/suite/tools/read-file.test.ts b/apps/vscode-e2e/src/suite/tools/read-file.test.ts index 99e3f1845779..6d56c20a0c85 100644 --- a/apps/vscode-e2e/src/suite/tools/read-file.test.ts +++ b/apps/vscode-e2e/src/suite/tools/read-file.test.ts @@ -136,35 +136,58 @@ suite("Roo Code read_file Tool", function () { // Check for tool execution and extract result if (message.type === "say" && message.say === "api_req_started") { const text = message.text || "" - if (text.includes("read_file")) { + console.log("Checking for read_file tool in api_req_started...") + + // More robust detection of read_file tool + if (text.includes("read_file") || text.includes('"tool":"read_file"') || text.includes("readFile")) { toolExecuted = true console.log("Tool executed:", text.substring(0, 200)) - // Parse the tool result from the api_req_started message + // Parse the tool result from the api_req_started message with better error handling try { - const requestData = JSON.parse(text) - if (requestData.request && requestData.request.includes("[read_file")) { - console.log("Full request for debugging:", requestData.request) - // Try multiple patterns to extract the content - // Pattern 1: Content between triple backticks - let resultMatch = requestData.request.match(/```[^`]*\n([\s\S]*?)\n```/) - if (!resultMatch) { - // Pattern 2: Content after "Result:" with line numbers - resultMatch = requestData.request.match(/Result:[\s\S]*?\n((?:\d+\s*\|[^\n]*\n?)+)/) + let requestData: { request?: string } | null = null + + // Try to parse the entire text as JSON + try { + requestData = JSON.parse(text) + } catch { + // Try to extract JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) } - if (!resultMatch) { - // Pattern 3: Simple content after Result: - resultMatch = requestData.request.match(/Result:\s*\n([\s\S]+?)(?:\n\n|$)/) - } - if (resultMatch) { - toolResult = resultMatch[1] - console.log("Extracted tool result:", toolResult) - } else { - console.log("Could not extract tool result from request") + } + + if (requestData && requestData.request) { + console.log("Full request for debugging:", requestData.request.substring(0, 500)) + + // Check if it's a read_file request + if ( + requestData.request.includes("[read_file") || + requestData.request.includes("read_file") + ) { + // Try multiple patterns to extract the content + // Pattern 1: Content between triple backticks + let resultMatch = requestData.request.match(/```[^`]*\n([\s\S]*?)\n```/) + if (!resultMatch) { + // Pattern 2: Content after "Result:" with line numbers + resultMatch = requestData.request.match(/Result:[\s\S]*?\n((?:\d+\s*\|[^\n]*\n?)+)/) + } + if (!resultMatch) { + // Pattern 3: Simple content after Result: + resultMatch = requestData.request.match(/Result:\s*\n([\s\S]+?)(?:\n\n|$)/) + } + if (resultMatch) { + toolResult = resultMatch[1] || null + console.log("Extracted tool result:", toolResult) + } else { + console.log("Could not extract tool result from request") + } } } } catch (e) { console.log("Failed to parse tool result:", e) + console.log("Raw text:", text.substring(0, 500)) } } } diff --git a/apps/vscode-e2e/src/suite/tools/search-and-replace.test.ts b/apps/vscode-e2e/src/suite/tools/search-and-replace.test.ts index 801a829a74b9..a1af7077c110 100644 --- a/apps/vscode-e2e/src/suite/tools/search-and-replace.test.ts +++ b/apps/vscode-e2e/src/suite/tools/search-and-replace.test.ts @@ -164,14 +164,39 @@ Final content`, // Check for tool execution if (message.type === "say" && message.say === "api_req_started" && message.text) { console.log("API request started:", message.text.substring(0, 200)) + + // More robust detection of search_and_replace tool try { - const requestData = JSON.parse(message.text) - if (requestData.request && requestData.request.includes("search_and_replace")) { + // Try multiple patterns to detect the tool + const text = message.text + if ( + text.includes("search_and_replace") || + text.includes('"tool":"search_and_replace"') || + text.includes("searchAndReplace") + ) { searchReplaceExecuted = true console.log("search_and_replace tool executed!") + } else { + // Also try to parse as JSON if it doesn't match string patterns + let requestData: { request?: string } | null = null + try { + requestData = JSON.parse(text) + } catch { + // Try extracting JSON from the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request && requestData.request.includes("search_and_replace")) { + searchReplaceExecuted = true + console.log("search_and_replace tool executed (parsed from JSON)!") + } } } catch (e) { console.log("Failed to parse api_req_started message:", e) + console.log("Raw text:", message.text.substring(0, 500)) } } } diff --git a/apps/vscode-e2e/src/suite/tools/search-files.test.ts b/apps/vscode-e2e/src/suite/tools/search-files.test.ts index 98cfd1b3eedf..15d313218589 100644 --- a/apps/vscode-e2e/src/suite/tools/search-files.test.ts +++ b/apps/vscode-e2e/src/suite/tools/search-files.test.ts @@ -303,22 +303,38 @@ The search should find matches across different file types and provide context f // Check for tool execution and capture results if (message.type === "say" && message.say === "api_req_started") { const text = message.text || "" - if (text.includes("search_files")) { + console.log("Received api_req_started message, checking for search_files...") + + // More robust check for search_files tool + if (text.includes("search_files") || text.includes('"tool":"search_files"')) { toolExecuted = true console.log("search_files tool executed:", text.substring(0, 200)) - // Extract search results from the tool execution + // Extract search results from the tool execution with better error handling try { - const jsonMatch = text.match(/\{"request":".*?"\}/) - if (jsonMatch) { - const requestData = JSON.parse(jsonMatch[0]) - if (requestData.request && requestData.request.includes("Result:")) { + // Try multiple patterns to extract the request data + let requestData: { request?: string } | null = null + + // Pattern 1: Full JSON object + try { + requestData = JSON.parse(text) + } catch { + // Pattern 2: JSON object within the text + const jsonMatch = text.match(/\{[\s\S]*\}/) + if (jsonMatch) { + requestData = JSON.parse(jsonMatch[0]) + } + } + + if (requestData && requestData.request) { + if (requestData.request.includes("Result:")) { searchResults = requestData.request console.log("Captured search results:", searchResults?.substring(0, 300)) } } } catch (e) { console.log("Failed to parse search results:", e) + console.log("Raw text that failed to parse:", text.substring(0, 500)) } } } @@ -482,7 +498,13 @@ The search should find matches across different file types and provide context f // Check for tool execution with file pattern if (message.type === "say" && message.say === "api_req_started") { const text = message.text || "" - if (text.includes("search_files") && text.includes("*.ts")) { + console.log("Checking for search_files with TS filter in:", text.substring(0, 200)) + + // More flexible pattern matching + if ( + (text.includes("search_files") || text.includes('"tool":"search_files"')) && + (text.includes("*.ts") || text.includes("\\.ts") || text.includes("file_pattern")) + ) { toolExecuted = true console.log("search_files tool executed with TypeScript filter") }