diff --git a/crates/assistant_tools/src/assistant_tools.rs b/crates/assistant_tools/src/assistant_tools.rs index 9dacd422f5..4b95b807d9 100644 --- a/crates/assistant_tools/src/assistant_tools.rs +++ b/crates/assistant_tools/src/assistant_tools.rs @@ -54,6 +54,7 @@ pub use edit_file_tool::{EditFileTool, EditFileToolInput}; pub use find_path_tool::FindPathToolInput; pub use open_tool::OpenTool; pub use read_file_tool::ReadFileToolInput; +pub use streaming_edit_file_tool::StreamingEditFileToolInput; pub use terminal_tool::TerminalTool; pub fn init(http_client: Arc, cx: &mut App) { diff --git a/crates/assistant_tools/src/streaming_edit_file_tool.rs b/crates/assistant_tools/src/streaming_edit_file_tool.rs index 356899bad5..e9e69de54c 100644 --- a/crates/assistant_tools/src/streaming_edit_file_tool.rs +++ b/crates/assistant_tools/src/streaming_edit_file_tool.rs @@ -61,6 +61,9 @@ pub struct StreamingEditFileToolInput { /// If true, this tool will recreate the file from scratch. /// If false, this tool will produce granular edits to an existing file. + /// + /// When a file already exists or you just created it, always prefer editing + /// it as opposed to recreating it from scratch. pub create_or_overwrite: bool, } diff --git a/crates/eval/src/examples/comment_translation.rs b/crates/eval/src/examples/comment_translation.rs new file mode 100644 index 0000000000..8c57150ddb --- /dev/null +++ b/crates/eval/src/examples/comment_translation.rs @@ -0,0 +1,61 @@ +use crate::example::{Example, ExampleContext, ExampleMetadata, JudgeAssertion}; +use anyhow::Result; +use assistant_tools::StreamingEditFileToolInput; +use async_trait::async_trait; + +pub struct CommentTranslation; + +#[async_trait(?Send)] +impl Example for CommentTranslation { + fn meta(&self) -> ExampleMetadata { + ExampleMetadata { + name: "comment_translation".to_string(), + url: "https://github.com/servo/font-kit.git".to_string(), + revision: "504d084e29bce4f60614bc702e91af7f7d9e60ad".to_string(), + language_server: None, + max_assertions: Some(1), + } + } + + async fn conversation(&self, cx: &mut ExampleContext) -> Result<()> { + cx.push_user_message(r#" + Edit the following files and translate all their comments to italian, in this exact order: + + - font-kit/src/family.rs + - font-kit/src/canvas.rs + - font-kit/src/error.rs + "#); + cx.run_to_end().await?; + + let mut create_or_overwrite_count = 0; + cx.agent_thread().read_with(cx, |thread, cx| { + for message in thread.messages() { + for tool_use in thread.tool_uses_for_message(message.id, cx) { + if tool_use.name == "edit_file" { + let input: StreamingEditFileToolInput = + serde_json::from_value(tool_use.input)?; + if input.create_or_overwrite { + create_or_overwrite_count += 1; + } + } + } + } + + anyhow::Ok(()) + })??; + cx.assert_eq(create_or_overwrite_count, 0, "no_creation_or_overwrite")?; + + Ok(()) + } + + fn diff_assertions(&self) -> Vec { + vec![JudgeAssertion { + id: "comments_translated".to_string(), + description: concat!( + "- Only `family.rs`, `canvas.rs` and `error.rs` should have changed.\n", + "- Their doc comments should have been all translated to Italian." + ) + .into(), + }] + } +} diff --git a/crates/eval/src/examples/mod.rs b/crates/eval/src/examples/mod.rs index 5487511ea0..e8718b2ae4 100644 --- a/crates/eval/src/examples/mod.rs +++ b/crates/eval/src/examples/mod.rs @@ -13,6 +13,7 @@ use crate::example::{Example, ExampleContext, ExampleMetadata, JudgeAssertion}; mod add_arg_to_trait_method; mod code_block_citations; +mod comment_translation; mod file_search; mod planets; @@ -22,6 +23,7 @@ pub fn all(examples_dir: &Path) -> Vec> { Rc::new(add_arg_to_trait_method::AddArgToTraitMethod), Rc::new(code_block_citations::CodeBlockCitations), Rc::new(planets::Planets), + Rc::new(comment_translation::CommentTranslation), ]; for example_path in list_declarative_examples(examples_dir).unwrap() {