From d40b49ceb91cdd567c8afa7d62dc4e3ec945c9df Mon Sep 17 00:00:00 2001 From: Agus Zubiaga Date: Mon, 31 Mar 2025 14:49:40 -0300 Subject: [PATCH] Remove edit action markers from `edit_prompt.md` (#27785) https://github.com/zed-industries/zed/pull/27778 removed most occurrences, but there were still some more in `edit_prompt.md` Release Notes: - N/A --- crates/assistant_tools/src/edit_files_tool.rs | 7 ++-- .../src/edit_files_tool/edit_action.rs | 24 ++++++++----- .../src/edit_files_tool/edit_prompt.md | 36 +++++++++---------- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/crates/assistant_tools/src/edit_files_tool.rs b/crates/assistant_tools/src/edit_files_tool.rs index 86a08d6189..b0cf740096 100644 --- a/crates/assistant_tools/src/edit_files_tool.rs +++ b/crates/assistant_tools/src/edit_files_tool.rs @@ -6,7 +6,7 @@ use crate::schema::json_schema_for; use anyhow::{anyhow, Context, Result}; use assistant_tool::{ActionLog, Tool}; use collections::HashSet; -use edit_action::{EditAction, EditActionParser}; +use edit_action::{edit_model_prompt, EditAction, EditActionParser}; use futures::{channel::mpsc, SinkExt, StreamExt}; use gpui::{App, AppContext, AsyncApp, Entity, Task}; use language_model::LanguageModelToolSchemaFormat; @@ -230,10 +230,7 @@ impl EditToolRequest { messages.push(LanguageModelRequestMessage { role: Role::User, - content: vec![ - include_str!("./edit_files_tool/edit_prompt.md").into(), - input.edit_instructions.into(), - ], + content: vec![edit_model_prompt().into(), input.edit_instructions.into()], cache: false, }); diff --git a/crates/assistant_tools/src/edit_files_tool/edit_action.rs b/crates/assistant_tools/src/edit_files_tool/edit_action.rs index bf8de1c2bd..8e17bc603c 100644 --- a/crates/assistant_tools/src/edit_files_tool/edit_action.rs +++ b/crates/assistant_tools/src/edit_files_tool/edit_action.rs @@ -342,6 +342,14 @@ impl std::fmt::Display for ParseError { } } +pub fn edit_model_prompt() -> String { + include_str!("edit_prompt.md") + .to_string() + .replace("{{SEARCH_MARKER}}", SEARCH_MARKER) + .replace("{{DIVIDER}}", DIVIDER) + .replace("{{REPLACE_MARKER}}", REPLACE_MARKER) +} + #[cfg(test)] mod tests { use super::*; @@ -808,19 +816,17 @@ fn new_utils_func() {{}} assert_eq!(parser.state, State::Default); } - const SYSTEM_PROMPT: &str = include_str!("./edit_prompt.md"); - #[test] - fn test_parse_examples_in_system_prompt() { + fn test_parse_examples_in_edit_prompt() { let mut parser = EditActionParser::new(); - let actions = parser.parse_chunk(SYSTEM_PROMPT); - assert_examples_in_system_prompt(&actions, parser.errors()); + let actions = parser.parse_chunk(&edit_model_prompt()); + assert_examples_in_edit_prompt(&actions, parser.errors()); } #[gpui::test(iterations = 10)] - fn test_random_chunking_of_system_prompt(mut rng: StdRng) { + fn test_random_chunking_of_edit_prompt(mut rng: StdRng) { let mut parser = EditActionParser::new(); - let mut remaining = SYSTEM_PROMPT; + let mut remaining: &str = &edit_model_prompt(); let mut actions = Vec::with_capacity(5); while !remaining.is_empty() { @@ -833,10 +839,10 @@ fn new_utils_func() {{}} remaining = rest; } - assert_examples_in_system_prompt(&actions, parser.errors()); + assert_examples_in_edit_prompt(&actions, parser.errors()); } - fn assert_examples_in_system_prompt(actions: &[(EditAction, String)], errors: &[ParseError]) { + fn assert_examples_in_edit_prompt(actions: &[(EditAction, String)], errors: &[ParseError]) { assert_eq!(actions.len(), 5); assert_eq!( diff --git a/crates/assistant_tools/src/edit_files_tool/edit_prompt.md b/crates/assistant_tools/src/edit_files_tool/edit_prompt.md index f4f3895157..6ef456a437 100644 --- a/crates/assistant_tools/src/edit_files_tool/edit_prompt.md +++ b/crates/assistant_tools/src/edit_files_tool/edit_prompt.md @@ -30,17 +30,17 @@ Here are the *SEARCH/REPLACE* blocks: mathweb/flask/app.py ```python -<<<<<<< SEARCH +{{SEARCH_MARKER}} from flask import Flask -======= +{{DIVIDER}} import math from flask import Flask ->>>>>>> REPLACE +{{REPLACE_MARKER}} ``` mathweb/flask/app.py ```python -<<<<<<< SEARCH +{{SEARCH_MARKER}} def factorial(n): "compute factorial" @@ -49,17 +49,17 @@ def factorial(n): else: return n * factorial(n-1) -======= ->>>>>>> REPLACE +{{DIVIDER}} +{{REPLACE_MARKER}} ``` mathweb/flask/app.py ```python -<<<<<<< SEARCH +{{SEARCH_MARKER}} return str(factorial(n)) -======= +{{DIVIDER}} return str(math.factorial(n)) ->>>>>>> REPLACE +{{REPLACE_MARKER}} ``` @@ -74,36 +74,36 @@ Here are the *SEARCH/REPLACE* blocks: hello.py ```python -<<<<<<< SEARCH -======= +{{SEARCH_MARKER}} +{{DIVIDER}} def hello(): "print a greeting" print("hello") ->>>>>>> REPLACE +{{REPLACE_MARKER}} ``` main.py ```python -<<<<<<< SEARCH +{{SEARCH_MARKER}} def hello(): "print a greeting" print("hello") -======= +{{DIVIDER}} from hello import hello ->>>>>>> REPLACE +{{REPLACE_MARKER}} ``` # *SEARCH/REPLACE block* Rules: Every *SEARCH/REPLACE block* must use this format: 1. The *FULL* file path alone on a line, verbatim. No bold asterisks, no quotes around it, no escaping of characters, etc. 2. The opening fence and code language, eg: ```python -3. The start of search block: <<<<<<< SEARCH +3. The start of search block: {{SEARCH_MARKER}} 4. A contiguous chunk of lines to search for in the existing source code -5. The dividing line: ======= +5. The dividing line: {{DIVIDER}} 6. The lines to replace into the source code -7. The end of the replace block: >>>>>>> REPLACE +7. The end of the replace block: {{REPLACE_MARKER}} 8. The closing fence: ``` Use the *FULL* file path, as shown to you by the user. Make sure to include the project's root directory name at the start of the path. *NEVER* specify the absolute path of the file!