@@ -243,14 +243,23 @@ pub fn sort_examples_by_repo_and_rev(examples: &mut [Example]) {
}
pub fn group_examples_by_repo(examples: Vec<Example>) -> VecDeque<Vec<Example>> {
- let mut examples_by_repo = HashMap::default();
+ let mut examples_by_repo: HashMap<String, Vec<Example>> = HashMap::default();
+ let mut ungrouped = Vec::new();
for example in examples {
- examples_by_repo
- .entry(example.spec.repository_url.clone())
- .or_insert_with(Vec::new)
- .push(example);
+ if example.spec.repository_url.is_empty() {
+ ungrouped.push(example);
+ } else {
+ examples_by_repo
+ .entry(example.spec.repository_url.clone())
+ .or_insert_with(Vec::new)
+ .push(example);
+ }
+ }
+ let mut result: VecDeque<Vec<Example>> = examples_by_repo.into_values().collect();
+ for example in ungrouped {
+ result.push_back(vec![example]);
}
- examples_by_repo.into_values().collect()
+ result
}
fn parse_markdown_example(input: &str) -> Result<Example> {
@@ -168,6 +168,7 @@ impl TeacherPrompt {
pub(crate) const EDITABLE_REGION_START: &str = "<|editable_region_start|>\n";
pub(crate) const EDITABLE_REGION_END: &str = "\n<|editable_region_end|>";
pub(crate) const USER_CURSOR_MARKER: &str = "<|user_cursor|>";
+ pub(crate) const NO_EDITS: &str = "NO_EDITS";
/// Truncate edit history to this number of last lines
const MAX_HISTORY_LINES: usize = 128;
@@ -193,6 +194,12 @@ impl TeacherPrompt {
// Extract updated (new) editable region from the model response.
// The model may include editable region markers in its output, so we need to strip them.
let new_editable_region = extract_last_codeblock(response);
+
+ // Check if the model indicated no edits are needed
+ if new_editable_region.trim() == Self::NO_EDITS {
+ return Ok(String::new());
+ }
+
let mut new_editable_region = Self::extract_editable_region(&new_editable_region)?;
let old_editable_region = Self::extract_editable_region(
&example
@@ -551,6 +558,19 @@ mod tests {
);
}
+ #[test]
+ fn test_parse_no_edits_response() {
+ let response = indoc::indoc! {"
+ The code is already complete. There is no clear next edit to make.
+
+ `````
+ NO_EDITS
+ `````
+ "};
+ let codeblock = extract_last_codeblock(response);
+ assert_eq!(codeblock.trim(), TeacherPrompt::NO_EDITS);
+ }
+
#[test]
fn test_extract_editable_region_strips_cursor_marker() {
let text = indoc::indoc! {"
@@ -14,12 +14,18 @@ You are an edit prediction assistant in a code editor. Your task is to predict t
## Rules
+- **NEVER undo or revert the user's recent edits.** Examine the diff in the edit history carefully:
+ - If a line was removed (starts with `-`), do NOT restore that content—even if the code now appears incomplete or broken without it
+ - If a line was added (starts with `+`), do NOT delete or significantly modify it
+ - If code appears broken or incomplete after the user's edit, output `NO_EDITS` rather than "fixing" it by reverting
+ - Only add NEW content that extends the user's work forward; never restore what they removed
+ - **Key test**: if your prediction would make the code more similar to what it was BEFORE the user's edit, output `NO_EDITS` instead
+ - **Never assume a deletion was accidental.** Even if removing content breaks the code, breaks a pattern, or leaves text looking "incomplete", respect it. The user may be mid-rewrite. Do NOT "complete" partial text by restoring what was deleted.
- Do not just mechanically apply patterns - reason about what changes make sense given the context and the programmer's apparent goals.
- Do not just fix syntax errors - look for the broader refactoring pattern and apply it systematically throughout the code.
- Keep existing formatting unless it's absolutely necessary
- When edit history and surrounding code suggest different edits, prioritize the most recent edits in the history as they best reflect current intent.
- When uncertain, predict only the minimal, high-confidence portion of the edit. Prefer a small, correct prediction over a large, speculative one
-- Do not delete or remove text that was just added in the edit history. If a recent edit introduces incomplete or incorrect code, finish or fix it in place, or simply do nothing rather than removing it. Only remove a recent edit if the history explicitly shows the user undoing it themselves.
- Treat partial text at or near the cursor as the beginning of something the user is actively typing. Complete the code the user appears to be creating based on context.
# Input Format
@@ -36,8 +42,12 @@ You will be provided with:
- Briefly explain the user's current intent based on the edit history and their current cursor location.
- Output a markdown codeblock containing **only** the editable region with your predicted edits applied. The codeblock must start with `<|editable_region_start|>` and end with `<|editable_region_end|>`. Do not include any content before or after these tags.
+- If no edit is needed (the code is already complete and correct, or there is no clear next edit to make), output a codeblock containing only `NO_EDITS`:
+ `````
+ NO_EDITS
+ `````
- If the next edit has some uncertainty, you may still predict the surrounding code (such as a function definition, `for` loop, etc) and place the `<|user_cursor|>` within it for the user to fill in.
- -e.g. if a user is typing `func<|user_cursor|>`, but you don't know what the function name should be, you can predict `function <|user_cursor|>() {}`
+ - e.g. if a user is typing `func<|user_cursor|>`, but you don't know what the function name should be, you can predict `function <|user_cursor|>() {}`
## Example 1
@@ -133,9 +143,78 @@ The user is clearly starting to type `eprintln!()`, however, what they intend to
fn handle_close_button_click(modal_state: &mut ModalState, evt: &Event) {
modal_state.close();
eprintln!("<|user_cursor|>");
+ modal_state.dismiss();
<|editable_region_end|>
`````
+## Example 3
+
+The code is already complete and there is no clear next edit to make. You should output NO_EDITS.
+
+### User Edit History
+
+`````
+--- a/src/utils.rs
++++ b/src/utils.rs
+@@ -10,7 +10,7 @@
+ fn add(a: i32, b: i32) -> i32 {
+- a - b
++ a + b
+ }
+`````
+
+### Current File
+
+`````src/utils.rs
+<|editable_region_start|>
+fn add(a: i32, b: i32) -> i32 {
+ a + b<|user_cursor|>
+}
+<|editable_region_end|>
+`````
+
+### Output
+
+The user just fixed a bug in the `add` function, changing subtraction to addition. The code is now correct and complete. There is no clear next edit to make.
+
+`````
+NO_EDITS
+`````
+
+## Example 4
+
+The user just deleted code, leaving behind what looks incomplete. You must NOT "complete" it by restoring deleted content—that would undo their edit. Output NO_EDITS. **This is the correct response even though the code appears broken.**
+
+### User Edit History
+
+`````
+--- a/config.nix
++++ b/config.nix
+@@ -10,7 +10,7 @@
+ # /etc/modular/crashdb needs to be mutable
+- ln -s /tmp/crashdb $out/etc/modular/crashdb
++ ln -s /tmp/cr $out/etc/modular/crashdb
+ '';
+`````
+
+### Current File
+
+`````config.nix
+<|editable_region_start|>
+ # /etc/modular/crashdb needs to be mutable
+ ln -s /tmp/cr<|user_cursor|> $out/etc/modular/crashdb
+ '';
+<|editable_region_end|>
+`````
+
+### Output
+
+The user deleted `ashdb` from `/tmp/crashdb`, leaving `/tmp/cr`. Although this looks like incomplete text that I could "complete", doing so would restore deleted content. The user intentionally removed that text—I must not undo their deletion.
+
+`````
+NO_EDITS
+`````
+
# Your task: