diff --git a/crates/assistant/src/assistant.rs b/crates/assistant/src/assistant.rs index 071385d745..acb39d3b45 100644 --- a/crates/assistant/src/assistant.rs +++ b/crates/assistant/src/assistant.rs @@ -55,6 +55,8 @@ actions!( ] ); +const DEFAULT_CONTEXT_LINES: usize = 20; + #[derive(Clone, Default, Deserialize, PartialEq)] pub struct InlineAssist { prompt: Option, diff --git a/crates/assistant/src/prompts.rs b/crates/assistant/src/prompts.rs index 3c955fbe7c..2a0aeafa82 100644 --- a/crates/assistant/src/prompts.rs +++ b/crates/assistant/src/prompts.rs @@ -115,11 +115,19 @@ pub fn generate_terminal_assistant_prompt( user_prompt: &str, shell: Option<&str>, working_directory: Option<&str>, + latest_output: &[String], ) -> 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(); + writeln!( + &mut prompt, + "Current OS name is '{}', architecture is '{}'.", + std::env::consts::OS, + std::env::consts::ARCH, + ) + .unwrap(); if let Some(shell) = shell { writeln!(&mut prompt, "Current shell is '{shell}'.").unwrap(); } @@ -130,6 +138,15 @@ pub fn generate_terminal_assistant_prompt( ) .unwrap(); } + if !latest_output.is_empty() { + writeln!( + &mut prompt, + "Latest non-empty {} lines of the terminal output: {:?}", + latest_output.len(), + latest_output + ) + .unwrap(); + } writeln!(&mut prompt, "Here is the description of the command:").unwrap(); prompt.push_str(user_prompt); prompt diff --git a/crates/assistant/src/slash_command/term_command.rs b/crates/assistant/src/slash_command/term_command.rs index a9072a62dd..90c3cb0fb9 100644 --- a/crates/assistant/src/slash_command/term_command.rs +++ b/crates/assistant/src/slash_command/term_command.rs @@ -11,6 +11,8 @@ use terminal_view::{terminal_panel::TerminalPanel, TerminalView}; use ui::prelude::*; use workspace::{dock::Panel, Workspace}; +use crate::DEFAULT_CONTEXT_LINES; + use super::create_label_for_command; pub(crate) struct TermSlashCommand; @@ -73,7 +75,9 @@ impl SlashCommand for TermSlashCommand { return Task::ready(Err(anyhow::anyhow!("no active terminal"))); }; - let line_count = argument.and_then(|a| parse_argument(a)).unwrap_or(20); + let line_count = argument + .and_then(|a| parse_argument(a)) + .unwrap_or(DEFAULT_CONTEXT_LINES); let lines = active_terminal .read(cx) diff --git a/crates/assistant/src/terminal_inline_assistant.rs b/crates/assistant/src/terminal_inline_assistant.rs index 029cc079ca..6ede9f536a 100644 --- a/crates/assistant/src/terminal_inline_assistant.rs +++ b/crates/assistant/src/terminal_inline_assistant.rs @@ -1,6 +1,6 @@ use crate::{ humanize_token_count, prompts::generate_terminal_assistant_prompt, AssistantPanel, - AssistantPanelEvent, ModelSelector, + AssistantPanelEvent, ModelSelector, DEFAULT_CONTEXT_LINES, }; use anyhow::{Context as _, Result}; use client::telemetry::Telemetry; @@ -217,17 +217,18 @@ impl TerminalInlineAssistant { let assist = self.assists.get(&assist_id).context("invalid assist")?; let shell = std::env::var("SHELL").ok(); - let working_directory = assist + let (latest_output, working_directory) = assist .terminal .update(cx, |terminal, cx| { - terminal - .model() - .read(cx) + let terminal = terminal.model().read(cx); + let latest_output = terminal.last_n_non_empty_lines(DEFAULT_CONTEXT_LINES); + let working_directory = terminal .working_directory() - .map(|path| path.to_string_lossy().to_string()) + .map(|path| path.to_string_lossy().to_string()); + (latest_output, working_directory) }) .ok() - .flatten(); + .unwrap_or_default(); let context_request = if assist.include_context { assist.workspace.as_ref().and_then(|workspace| { @@ -254,6 +255,7 @@ impl TerminalInlineAssistant { .prompt(cx), shell.as_deref(), working_directory.as_deref(), + &latest_output, ); let mut messages = Vec::new();