Require /file or /tab when using Suggest Edits (#19960)
Now if you try to do Suggest Edits without a file context, you see this (and it doesn't run the query). <img width="635" alt="Screenshot 2024-10-30 at 10 51 24 AM" src="https://github.com/user-attachments/assets/a3997ba6-98a9-4bfa-81b6-1d8579c26fd7"> Release Notes: - N/A --------- Co-authored-by: Antonio <antonio@zed.dev>
This commit is contained in:
parent
515fd7b75f
commit
c564a4a26c
5 changed files with 62 additions and 7 deletions
|
@ -1462,6 +1462,7 @@ type MessageHeader = MessageMetadata;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum AssistError {
|
enum AssistError {
|
||||||
|
FileRequired,
|
||||||
PaymentRequired,
|
PaymentRequired,
|
||||||
MaxMonthlySpendReached,
|
MaxMonthlySpendReached,
|
||||||
Message(SharedString),
|
Message(SharedString),
|
||||||
|
@ -1628,7 +1629,10 @@ impl ContextEditor {
|
||||||
|
|
||||||
self.last_error = None;
|
self.last_error = None;
|
||||||
|
|
||||||
if let Some(user_message) = self
|
if request_type == RequestType::SuggestEdits && !self.context.read(cx).contains_files(cx) {
|
||||||
|
self.last_error = Some(AssistError::FileRequired);
|
||||||
|
cx.notify();
|
||||||
|
} else if let Some(user_message) = self
|
||||||
.context
|
.context
|
||||||
.update(cx, |context, cx| context.assist(request_type, cx))
|
.update(cx, |context, cx| context.assist(request_type, cx))
|
||||||
{
|
{
|
||||||
|
@ -3740,6 +3744,7 @@ impl ContextEditor {
|
||||||
.elevation_2(cx)
|
.elevation_2(cx)
|
||||||
.occlude()
|
.occlude()
|
||||||
.child(match last_error {
|
.child(match last_error {
|
||||||
|
AssistError::FileRequired => self.render_file_required_error(cx),
|
||||||
AssistError::PaymentRequired => self.render_payment_required_error(cx),
|
AssistError::PaymentRequired => self.render_payment_required_error(cx),
|
||||||
AssistError::MaxMonthlySpendReached => {
|
AssistError::MaxMonthlySpendReached => {
|
||||||
self.render_max_monthly_spend_reached_error(cx)
|
self.render_max_monthly_spend_reached_error(cx)
|
||||||
|
@ -3752,6 +3757,41 @@ impl ContextEditor {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_file_required_error(&self, cx: &mut ViewContext<Self>) -> AnyElement {
|
||||||
|
v_flex()
|
||||||
|
.gap_0p5()
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.gap_1p5()
|
||||||
|
.items_center()
|
||||||
|
.child(Icon::new(IconName::Warning).color(Color::Warning))
|
||||||
|
.child(
|
||||||
|
Label::new("Suggest Edits needs a file to edit").weight(FontWeight::MEDIUM),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.id("error-message")
|
||||||
|
.max_h_24()
|
||||||
|
.overflow_y_scroll()
|
||||||
|
.child(Label::new(
|
||||||
|
"To include files, type /file or /tab in your prompt.",
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.justify_end()
|
||||||
|
.mt_1()
|
||||||
|
.child(Button::new("dismiss", "Dismiss").on_click(cx.listener(
|
||||||
|
|this, _, cx| {
|
||||||
|
this.last_error = None;
|
||||||
|
cx.notify();
|
||||||
|
},
|
||||||
|
))),
|
||||||
|
)
|
||||||
|
.into_any()
|
||||||
|
}
|
||||||
|
|
||||||
fn render_payment_required_error(&self, cx: &mut ViewContext<Self>) -> AnyElement {
|
fn render_payment_required_error(&self, cx: &mut ViewContext<Self>) -> AnyElement {
|
||||||
const ERROR_MESSAGE: &str = "Free tier exceeded. Subscribe and add payment to continue using Zed LLMs. You'll be billed at cost for tokens used.";
|
const ERROR_MESSAGE: &str = "Free tier exceeded. Subscribe and add payment to continue using Zed LLMs. You'll be billed at cost for tokens used.";
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
mod context_tests;
|
mod context_tests;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
prompts::PromptBuilder, slash_command::SlashCommandLine, AssistantEdit, AssistantPatch,
|
prompts::PromptBuilder,
|
||||||
AssistantPatchStatus, MessageId, MessageStatus,
|
slash_command::{file_command::FileCommandMetadata, SlashCommandLine},
|
||||||
|
AssistantEdit, AssistantPatch, AssistantPatchStatus, MessageId, MessageStatus,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Context as _, Result};
|
use anyhow::{anyhow, Context as _, Result};
|
||||||
use assistant_slash_command::{
|
use assistant_slash_command::{
|
||||||
|
@ -66,7 +67,7 @@ impl ContextId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum RequestType {
|
pub enum RequestType {
|
||||||
/// Request a normal chat response from the model.
|
/// Request a normal chat response from the model.
|
||||||
Chat,
|
Chat,
|
||||||
|
@ -989,6 +990,20 @@ impl Context {
|
||||||
&self.slash_command_output_sections
|
&self.slash_command_output_sections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn contains_files(&self, cx: &AppContext) -> bool {
|
||||||
|
let buffer = self.buffer.read(cx);
|
||||||
|
self.slash_command_output_sections.iter().any(|section| {
|
||||||
|
section.is_valid(buffer)
|
||||||
|
&& section
|
||||||
|
.metadata
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|metadata| {
|
||||||
|
serde_json::from_value::<FileCommandMetadata>(metadata.clone()).ok()
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pending_tool_uses(&self) -> Vec<&PendingToolUse> {
|
pub fn pending_tool_uses(&self) -> Vec<&PendingToolUse> {
|
||||||
self.pending_tool_uses_by_id.values().collect()
|
self.pending_tool_uses_by_id.values().collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ impl PromptBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_workflow_prompt(&self) -> Result<String, RenderError> {
|
pub fn generate_workflow_prompt(&self) -> Result<String, RenderError> {
|
||||||
self.handlebars.lock().render("edit_workflow", &())
|
self.handlebars.lock().render("suggest_edits", &())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_project_slash_command_prompt(
|
pub fn generate_project_slash_command_prompt(
|
||||||
|
|
|
@ -137,7 +137,7 @@ Zed has the following internal prompt templates:
|
||||||
|
|
||||||
- `content_prompt.hbs`: Used for generating content in the editor.
|
- `content_prompt.hbs`: Used for generating content in the editor.
|
||||||
- `terminal_assistant_prompt.hbs`: Used for the terminal assistant feature.
|
- `terminal_assistant_prompt.hbs`: Used for the terminal assistant feature.
|
||||||
- `edit_workflow.hbs`: Used for generating the edit workflow prompt.
|
- `suggest_edits.hbs`: Used for generating the model instructions for the XML Suggest Edits should return.
|
||||||
- `step_resolution.hbs`: Used for generating the step resolution prompt.
|
- `step_resolution.hbs`: Used for generating the step resolution prompt.
|
||||||
|
|
||||||
At this point it is unknown if we will expand templates further to be user-creatable.
|
At this point it is unknown if we will expand templates further to be user-creatable.
|
||||||
|
@ -215,7 +215,7 @@ The following templates can be overridden:
|
||||||
given system information and latest terminal output if relevant.
|
given system information and latest terminal output if relevant.
|
||||||
```
|
```
|
||||||
|
|
||||||
3. `edit_workflow.hbs`: Used for generating the edit workflow prompt.
|
3. `suggest_edits.hbs`: Used for generating the model instructions for the XML Suggest Edits should return.
|
||||||
|
|
||||||
4. `step_resolution.hbs`: Used for generating the step resolution prompt.
|
4. `step_resolution.hbs`: Used for generating the step resolution prompt.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue