use language::BufferSnapshot; use std::{fmt::Write, ops::Range}; pub fn generate_content_prompt( user_prompt: String, language_name: Option<&str>, buffer: BufferSnapshot, range: Range, _project_name: Option, ) -> anyhow::Result { let mut prompt = String::new(); let content_type = match language_name { None | Some("Markdown" | "Plain Text") => { writeln!( prompt, "Here's a file of text that I'm going to ask you to make an edit to." )?; "text" } Some(language_name) => { writeln!( prompt, "Here's a file of {language_name} that I'm going to ask you to make an edit to." )?; "code" } }; const MAX_CTX: usize = 50000; let mut is_truncated = false; if range.is_empty() { prompt.push_str("The point you'll need to insert at is marked with .\n\n"); } else { prompt.push_str("The section you'll need to rewrite is marked with tags.\n\n"); } // Include file content. let before_range = 0..range.start; let truncated_before = if before_range.len() > MAX_CTX { is_truncated = true; range.start - MAX_CTX..range.start } else { before_range }; let mut non_rewrite_len = truncated_before.len(); for chunk in buffer.text_for_range(truncated_before) { prompt.push_str(chunk); } if !range.is_empty() { prompt.push_str("\n"); for chunk in buffer.text_for_range(range.clone()) { prompt.push_str(chunk); } prompt.push_str("\n"); } else { prompt.push_str(""); } let after_range = range.end..buffer.len(); let truncated_after = if after_range.len() > MAX_CTX { is_truncated = true; range.end..range.end + MAX_CTX } else { after_range }; non_rewrite_len += truncated_after.len(); for chunk in buffer.text_for_range(truncated_after) { prompt.push_str(chunk); } write!(prompt, "\n\n").unwrap(); if is_truncated { writeln!(prompt, "The context around the relevant section has been truncated (possibly in the middle of a line) for brevity.\n")?; } if range.is_empty() { writeln!( prompt, "You can't replace {content_type}, your answer will be inserted in place of the `` tags. Don't include the insert_here tags in your output.", ) .unwrap(); writeln!( prompt, "Generate {content_type} based on the following prompt:\n\n\n{user_prompt}\n", ) .unwrap(); writeln!(prompt, "Match the indentation in the original file in the inserted {content_type}, don't include any indentation on blank lines.\n").unwrap(); prompt.push_str("Immediately start with the following format with no remarks:\n\n```\n{{INSERTED_CODE}}\n```"); } else { writeln!(prompt, "Edit the section of {content_type} in tags based on the following prompt:'").unwrap(); writeln!(prompt, "\n\n{user_prompt}\n\n").unwrap(); let rewrite_len = range.end - range.start; if rewrite_len < 20000 && rewrite_len * 2 < non_rewrite_len { writeln!(prompt, "And here's the section to rewrite based on that prompt again for reference:\n\n\n").unwrap(); for chunk in buffer.text_for_range(range.clone()) { prompt.push_str(chunk); } writeln!(prompt, "\n\n").unwrap(); } writeln!(prompt, "Only make changes that are necessary to fulfill the prompt, leave everything else as-is. All surrounding {content_type} will be preserved.\n").unwrap(); write!( prompt, "Start at the indentation level in the original file in the rewritten {content_type}. " ) .unwrap(); prompt.push_str("Don't stop until you've rewritten the entire section, even if you have no more changes to make, always write out the whole section with no unnecessary elisions."); prompt.push_str("\n\nImmediately start with the following format with no remarks:\n\n```\n{{REWRITTEN_CODE}}\n```"); } Ok(prompt) } pub fn generate_terminal_assistant_prompt( user_prompt: &str, shell: Option<&str>, working_directory: Option<&str>, ) -> String { let mut prompt = String::new(); writeln!(&mut prompt, "You are an expert terminal user.").unwrap(); writeln!(&mut prompt, "You will be given a description of a command and you need to respond with a command that matches the description.").unwrap(); writeln!(&mut prompt, "Do not include markdown blocks or any other text formatting in your response, always respond with a single command that can be executed in the given shell.").unwrap(); if let Some(shell) = shell { writeln!(&mut prompt, "Current shell is '{shell}'.").unwrap(); } if let Some(working_directory) = working_directory { writeln!( &mut prompt, "Current working directory is '{working_directory}'." ) .unwrap(); } writeln!(&mut prompt, "Here is the description of the command:").unwrap(); prompt.push_str(user_prompt); prompt }