Detailed changes
@@ -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,
});
@@ -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!(
@@ -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!