Add more context to the terminal assistant (#15492)
Release Notes: - N/A
This commit is contained in:
parent
73e3dfc0c3
commit
eedef487ac
4 changed files with 33 additions and 8 deletions
|
@ -55,6 +55,8 @@ actions!(
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const DEFAULT_CONTEXT_LINES: usize = 20;
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize, PartialEq)]
|
#[derive(Clone, Default, Deserialize, PartialEq)]
|
||||||
pub struct InlineAssist {
|
pub struct InlineAssist {
|
||||||
prompt: Option<String>,
|
prompt: Option<String>,
|
||||||
|
|
|
@ -115,11 +115,19 @@ pub fn generate_terminal_assistant_prompt(
|
||||||
user_prompt: &str,
|
user_prompt: &str,
|
||||||
shell: Option<&str>,
|
shell: Option<&str>,
|
||||||
working_directory: Option<&str>,
|
working_directory: Option<&str>,
|
||||||
|
latest_output: &[String],
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut prompt = String::new();
|
let mut prompt = String::new();
|
||||||
writeln!(&mut prompt, "You are an expert terminal user.").unwrap();
|
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, "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, "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 {
|
if let Some(shell) = shell {
|
||||||
writeln!(&mut prompt, "Current shell is '{shell}'.").unwrap();
|
writeln!(&mut prompt, "Current shell is '{shell}'.").unwrap();
|
||||||
}
|
}
|
||||||
|
@ -130,6 +138,15 @@ pub fn generate_terminal_assistant_prompt(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.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();
|
writeln!(&mut prompt, "Here is the description of the command:").unwrap();
|
||||||
prompt.push_str(user_prompt);
|
prompt.push_str(user_prompt);
|
||||||
prompt
|
prompt
|
||||||
|
|
|
@ -11,6 +11,8 @@ use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
|
||||||
use ui::prelude::*;
|
use ui::prelude::*;
|
||||||
use workspace::{dock::Panel, Workspace};
|
use workspace::{dock::Panel, Workspace};
|
||||||
|
|
||||||
|
use crate::DEFAULT_CONTEXT_LINES;
|
||||||
|
|
||||||
use super::create_label_for_command;
|
use super::create_label_for_command;
|
||||||
|
|
||||||
pub(crate) struct TermSlashCommand;
|
pub(crate) struct TermSlashCommand;
|
||||||
|
@ -73,7 +75,9 @@ impl SlashCommand for TermSlashCommand {
|
||||||
return Task::ready(Err(anyhow::anyhow!("no active terminal")));
|
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
|
let lines = active_terminal
|
||||||
.read(cx)
|
.read(cx)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
humanize_token_count, prompts::generate_terminal_assistant_prompt, AssistantPanel,
|
humanize_token_count, prompts::generate_terminal_assistant_prompt, AssistantPanel,
|
||||||
AssistantPanelEvent, ModelSelector,
|
AssistantPanelEvent, ModelSelector, DEFAULT_CONTEXT_LINES,
|
||||||
};
|
};
|
||||||
use anyhow::{Context as _, Result};
|
use anyhow::{Context as _, Result};
|
||||||
use client::telemetry::Telemetry;
|
use client::telemetry::Telemetry;
|
||||||
|
@ -217,17 +217,18 @@ impl TerminalInlineAssistant {
|
||||||
let assist = self.assists.get(&assist_id).context("invalid assist")?;
|
let assist = self.assists.get(&assist_id).context("invalid assist")?;
|
||||||
|
|
||||||
let shell = std::env::var("SHELL").ok();
|
let shell = std::env::var("SHELL").ok();
|
||||||
let working_directory = assist
|
let (latest_output, working_directory) = assist
|
||||||
.terminal
|
.terminal
|
||||||
.update(cx, |terminal, cx| {
|
.update(cx, |terminal, cx| {
|
||||||
terminal
|
let terminal = terminal.model().read(cx);
|
||||||
.model()
|
let latest_output = terminal.last_n_non_empty_lines(DEFAULT_CONTEXT_LINES);
|
||||||
.read(cx)
|
let working_directory = terminal
|
||||||
.working_directory()
|
.working_directory()
|
||||||
.map(|path| path.to_string_lossy().to_string())
|
.map(|path| path.to_string_lossy().to_string());
|
||||||
|
(latest_output, working_directory)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
.flatten();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let context_request = if assist.include_context {
|
let context_request = if assist.include_context {
|
||||||
assist.workspace.as_ref().and_then(|workspace| {
|
assist.workspace.as_ref().and_then(|workspace| {
|
||||||
|
@ -254,6 +255,7 @@ impl TerminalInlineAssistant {
|
||||||
.prompt(cx),
|
.prompt(cx),
|
||||||
shell.as_deref(),
|
shell.as_deref(),
|
||||||
working_directory.as_deref(),
|
working_directory.as_deref(),
|
||||||
|
&latest_output,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue