diff --git a/crates/goose-mcp/src/developer/rmcp_developer.rs b/crates/goose-mcp/src/developer/rmcp_developer.rs index 006c5a9c175a..0a1b3ce147a6 100644 --- a/crates/goose-mcp/src/developer/rmcp_developer.rs +++ b/crates/goose-mcp/src/developer/rmcp_developer.rs @@ -1835,10 +1835,9 @@ mod tests { .as_text() .unwrap(); - assert!( - assistant_content.text.contains("The file") - && assistant_content.text.contains("has been edited") - ); + assert!(assistant_content + .text + .contains("Successfully replaced text in")); // Verify the file contents changed let content = fs::read_to_string(&file_path).unwrap(); @@ -2308,7 +2307,7 @@ mod tests { .as_text() .unwrap(); - assert!(text.text.contains("Text has been inserted at line 1")); + assert!(text.text.contains("Successfully inserted") && text.text.contains("at line 1")); // Verify the file content by reading it directly let file_content = fs::read_to_string(&file_path).unwrap(); @@ -2365,7 +2364,7 @@ mod tests { .as_text() .unwrap(); - assert!(text.text.contains("Text has been inserted at line 3")); + assert!(text.text.contains("Successfully inserted") && text.text.contains("at line 3")); // Verify the file content by reading it directly let file_content = fs::read_to_string(&file_path).unwrap(); @@ -2427,7 +2426,7 @@ mod tests { .as_text() .unwrap(); - assert!(text.text.contains("Text has been inserted at line 4")); + assert!(text.text.contains("Successfully inserted") && text.text.contains("at line 4")); // Verify the file content by reading it directly let file_content = fs::read_to_string(&file_path).unwrap(); @@ -2484,7 +2483,7 @@ mod tests { .as_text() .unwrap(); - assert!(text.text.contains("Text has been inserted at line 4")); + assert!(text.text.contains("Successfully inserted") && text.text.contains("at line 4")); // Verify the file content by reading it directly let file_content = fs::read_to_string(&file_path).unwrap(); diff --git a/crates/goose-mcp/src/developer/text_editor.rs b/crates/goose-mcp/src/developer/text_editor.rs index ebe69a5c95ad..6cd45a37d736 100644 --- a/crates/goose-mcp/src/developer/text_editor.rs +++ b/crates/goose-mcp/src/developer/text_editor.rs @@ -799,9 +799,9 @@ pub async fn text_editor_replace( // Simple success message for Editor API return Ok(vec![ - Content::text(format!("Successfully edited {}", path.display())) + Content::text(format!("Successfully replaced text in {}.", path.display())) .with_audience(vec![Role::Assistant]), - Content::text(format!("File {} has been edited", path.display())) + Content::text(format!("Successfully replaced text in {}.", path.display())) .with_audience(vec![Role::User]) .with_priority(0.2), ]); @@ -848,11 +848,7 @@ pub async fn text_editor_replace( ) })?; - // Try to detect the language from the file extension - let language = lang::get_language_identifier(path); - - // Show a snippet of the changed content with context - const SNIPPET_LINES: usize = 4; + let new_line_count = new_str.lines().count(); // Count newlines before the replacement to find the line number let replacement_line = content @@ -860,13 +856,18 @@ pub async fn text_editor_replace( .next() .expect("should split on already matched content") .matches('\n') - .count(); + .count() + + 1; // 1-indexed - // Calculate start and end lines for the snippet - let start_line = replacement_line.saturating_sub(SNIPPET_LINES); - let end_line = replacement_line + SNIPPET_LINES + new_content.matches('\n').count(); + let summary = format!("Successfully replaced text in {}.", path.display()); - // Get the relevant lines for our snippet + // Try to detect the language from the file extension + let language = lang::get_language_identifier(path); + + // Show a snippet of the changed content with context for the user only + const SNIPPET_LINES: usize = 4; + let start_line = replacement_line.saturating_sub(SNIPPET_LINES + 1); + let end_line = replacement_line + SNIPPET_LINES + new_line_count; let lines: Vec<&str> = new_content.lines().collect(); let snippet = lines .iter() @@ -876,27 +877,21 @@ pub async fn text_editor_replace( .collect::>() .join("\n"); - let output = formatdoc! {r#" + let user_output = formatdoc! {r#" + Successfully replaced text in {path} at line {line}. ```{language} {snippet} ``` "#, + path=path.display(), + line=replacement_line, language=language, snippet=snippet }; - let success_message = formatdoc! {r#" - The file {} has been edited, and the section now reads: - {} - Review the changes above for errors. Undo and edit the file again if necessary! - "#, - path.display(), - output - }; - Ok(vec![ - Content::text(success_message).with_audience(vec![Role::Assistant]), - Content::text(output) + Content::text(summary).with_audience(vec![Role::Assistant]), + Content::text(user_output) .with_audience(vec![Role::User]) .with_priority(0.2), ]) @@ -988,48 +983,44 @@ pub async fn text_editor_insert( ) })?; + let insertion_line = insert_line + 1; // Convert to 1-indexed for display + let inserted_line_count = new_str.lines().count(); + + let summary = format!( + "Successfully inserted {} lines at line {} in {}", + inserted_line_count, + insertion_line, + path.display() + ); + // Try to detect the language from the file extension let language = lang::get_language_identifier(path); - // Show a snippet of the inserted content with context + // Show a snippet of the inserted content with context for the user only const SNIPPET_LINES: usize = 4; - let insertion_line = insert_line + 1; // Convert to 1-indexed for display - - // Calculate start and end lines for the snippet let start_line = insertion_line.saturating_sub(SNIPPET_LINES); let end_line = std::cmp::min(insertion_line + SNIPPET_LINES, new_lines.len()); - - // Get the relevant lines for our snippet with line numbers let snippet_lines: Vec = new_lines[start_line.saturating_sub(1)..end_line] .iter() .enumerate() .map(|(i, line)| format!("{}: {}", start_line + i, line)) .collect(); - let snippet = snippet_lines.join("\n"); - let output = formatdoc! {r#" + let user_output = formatdoc! {r#" + {summary} ```{language} {snippet} ``` "#, + summary=summary, language=language, snippet=snippet }; - let success_message = formatdoc! {r#" - Text has been inserted at line {} in {}. The section now reads: - {} - Review the changes above for errors. Undo and edit the file again if necessary! - "#, - insertion_line, - path.display(), - output - }; - Ok(vec![ - Content::text(success_message).with_audience(vec![Role::Assistant]), - Content::text(output) + Content::text(summary).with_audience(vec![Role::Assistant]), + Content::text(user_output) .with_audience(vec![Role::User]) .with_priority(0.2), ])