Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions crates/goose-mcp/src/developer/rmcp_developer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
79 changes: 35 additions & 44 deletions crates/goose-mcp/src/developer/text_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
]);
Expand Down Expand Up @@ -848,25 +848,26 @@ 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
.split(old_str)
.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()
Expand All @@ -876,27 +877,21 @@ pub async fn text_editor_replace(
.collect::<Vec<&str>>()
.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),
])
Expand Down Expand Up @@ -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<String> = 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),
])
Expand Down
Loading