diff --git a/assets/prompts/step_resolution.hbs b/assets/prompts/step_resolution.hbs
index 7331067db6..74bc43e078 100644
--- a/assets/prompts/step_resolution.hbs
+++ b/assets/prompts/step_resolution.hbs
@@ -1,4 +1,4 @@
-Your task is to map a step from the conversation above to operations on symbols inside the provided source files.
+Your task is to map a step from the conversation above to suggestions on symbols inside the provided source files.
Guidelines:
- There's no need to describe *what* to do, just *where* to do it.
@@ -6,13 +6,13 @@ Guidelines:
- Don't create and then update a file.
- We'll create it in one shot.
- Prefer updating symbols lower in the syntax tree if possible.
-- Never include operations on a parent symbol and one of its children in the same operations block.
-- Never nest an operation with another operation or include CDATA or other content. All operations are leaf nodes.
+- Never include suggestions on a parent symbol and one of its children in the same suggestions block.
+- Never nest an operation with another operation or include CDATA or other content. All suggestions are leaf nodes.
- Include a description attribute for each operation with a brief, one-line description of the change to perform.
-- Descriptions are required for all operations except delete.
-- When generating multiple operations, ensure the descriptions are specific to each individual operation.
+- Descriptions are required for all suggestions except delete.
+- When generating multiple suggestions, ensure the descriptions are specific to each individual operation.
- Avoid referring to the location in the description. Focus on the change to be made, not the location where it's made. That's implicit with the symbol you provide.
-- Don't generate multiple operations at the same location. Instead, combine them together in a single operation with a succinct combined description.
+- Don't generate multiple suggestions at the same location. Instead, combine them together in a single operation with a succinct combined description.
Example 1:
@@ -33,12 +33,12 @@ impl Rectangle {
Add new methods 'calculate_area' and 'calculate_perimeter' to the Rectangle struct
Implement the 'Display' trait for the Rectangle struct
-What are the operations for the step: Add a new method 'calculate_area' to the Rectangle struct
+What are the suggestions for the step: Add a new method 'calculate_area' to the Rectangle struct
A (wrong):
{
"title": "Add Rectangle methods",
- "operations": [
+ "suggestions": [
{
"kind": "AppendChild",
"path": "src/shapes.rs",
@@ -59,7 +59,7 @@ This demonstrates what NOT to do. NEVER append multiple children at the same loc
A (corrected):
{
"title": "Add Rectangle methods",
- "operations": [
+ "suggestions": [
{
"kind": "AppendChild",
"path": "src/shapes.rs",
@@ -70,12 +70,12 @@ A (corrected):
}
User:
-What are the operations for the step: Implement the 'Display' trait for the Rectangle struct
+What are the suggestions for the step: Implement the 'Display' trait for the Rectangle struct
A:
{
"title": "Implement Display for Rectangle",
- "operations": [
+ "suggestions": [
{
"kind": "InsertSiblingAfter",
"path": "src/shapes.rs",
@@ -109,12 +109,12 @@ impl User {
Update the 'print_info' method to use formatted output
Remove the 'email' field from the User struct
-What are the operations for the step: Update the 'print_info' method to use formatted output
+What are the suggestions for the step: Update the 'print_info' method to use formatted output
A:
{
"title": "Use formatted output",
- "operations": [
+ "suggestions": [
{
"kind": "Update",
"path": "src/user.rs",
@@ -125,12 +125,12 @@ A:
}
User:
-What are the operations for the step: Remove the 'email' field from the User struct
+What are the suggestions for the step: Remove the 'email' field from the User struct
A:
{
"title": "Remove email field",
- "operations": [
+ "suggestions": [
{
"kind": "Delete",
"path": "src/user.rs",
@@ -163,12 +163,12 @@ impl Vehicle {
Add a 'use std::fmt;' statement at the beginning of the file
Add a new method 'start_engine' in the Vehicle impl block
-What are the operations for the step: Add a 'use std::fmt;' statement at the beginning of the file
+What are the suggestions for the step: Add a 'use std::fmt;' statement at the beginning of the file
A:
{
"title": "Add use std::fmt statement",
- "operations": [
+ "suggestions": [
{
"kind": "PrependChild",
"path": "src/vehicle.rs",
@@ -178,12 +178,12 @@ A:
}
User:
-What are the operations for the step: Add a new method 'start_engine' in the Vehicle impl block
+What are the suggestions for the step: Add a new method 'start_engine' in the Vehicle impl block
A:
{
"title": "Add start_engine method",
- "operations": [
+ "suggestions": [
{
"kind": "InsertSiblingAfter",
"path": "src/vehicle.rs",
@@ -222,12 +222,12 @@ impl Employee {
Make salary an f32
-What are the operations for the step: Make salary an f32
+What are the suggestions for the step: Make salary an f32
A (wrong):
{
"title": "Change salary to f32",
- "operations": [
+ "suggestions": [
{
"kind": "Update",
"path": "src/employee.rs",
@@ -248,7 +248,7 @@ This example demonstrates what not to do. `struct Employee salary` is a child of
A (corrected):
{
"title": "Change salary to f32",
- "operations": [
+ "suggestions": [
{
"kind": "Update",
"path": "src/employee.rs",
@@ -259,12 +259,12 @@ A (corrected):
}
User:
-What are the correct operations for the step: Remove the 'department' field and update the 'print_details' method
+What are the correct suggestions for the step: Remove the 'department' field and update the 'print_details' method
A:
{
"title": "Remove department",
- "operations": [
+ "suggestions": [
{
"kind": "Delete",
"path": "src/employee.rs",
@@ -311,7 +311,7 @@ impl Game {
A:
{
"title": "Add level field to Player",
- "operations": [
+ "suggestions": [
{
"kind": "InsertSiblingAfter",
"path": "src/game.rs",
@@ -349,7 +349,7 @@ impl Config {
A:
{
"title": "Add load_from_file method",
- "operations": [
+ "suggestions": [
{
"kind": "PrependChild",
"path": "src/config.rs",
@@ -389,7 +389,7 @@ impl Database {
A:
{
"title": "Add error handling to query",
- "operations": [
+ "suggestions": [
{
"kind": "PrependChild",
"path": "src/database.rs",
@@ -410,4 +410,4 @@ A:
]
}
-Now generate the operations for the following step:
+Now generate the suggestions for the following step:
diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs
index d895bd1331..e2fe437b74 100644
--- a/crates/assistant/src/assistant_panel.rs
+++ b/crates/assistant/src/assistant_panel.rs
@@ -10,14 +10,14 @@ use crate::{
},
terminal_inline_assistant::TerminalInlineAssistant,
Assist, CodegenStatus, ConfirmCommand, Context, ContextEvent, ContextId, ContextStore,
- CycleMessageRole, DebugEditSteps, DeployHistory, DeployPromptLibrary, EditSuggestionGroup,
- InlineAssist, InlineAssistId, InlineAssistant, InsertIntoEditor, MessageStatus, ModelSelector,
+ CycleMessageRole, DebugEditSteps, DeployHistory, DeployPromptLibrary, InlineAssist,
+ InlineAssistId, InlineAssistant, InsertIntoEditor, MessageStatus, ModelSelector,
PendingSlashCommand, PendingSlashCommandStatus, QuoteSelection, RemoteContextMetadata,
- ResolvedWorkflowStepEditSuggestions, SavedContextMetadata, Split, ToggleFocus,
- ToggleModelSelector, WorkflowStepEditSuggestions,
+ ResolvedWorkflowStep, SavedContextMetadata, Split, ToggleFocus, ToggleModelSelector,
+ WorkflowStepStatus,
};
use crate::{ContextStoreEvent, ShowConfiguration};
-use anyhow::{anyhow, Result};
+use anyhow::{anyhow, Context as _, Result};
use assistant_slash_command::{SlashCommand, SlashCommandOutputSection};
use client::{proto, Client, Status};
use collections::{BTreeSet, HashMap, HashSet};
@@ -41,8 +41,7 @@ use gpui::{
};
use indexed_docs::IndexedDocsStore;
use language::{
- language_settings::SoftWrap, Buffer, Capability, LanguageRegistry, LspAdapterDelegate, Point,
- ToOffset,
+ language_settings::SoftWrap, Capability, LanguageRegistry, LspAdapterDelegate, Point, ToOffset,
};
use language_model::{
provider::cloud::PROVIDER_ID, LanguageModelProvider, LanguageModelProviderId,
@@ -1330,15 +1329,10 @@ struct ScrollPosition {
cursor: Anchor,
}
-struct StepAssists {
- assist_ids: Vec,
+struct WorkflowAssist {
editor: WeakView,
-}
-
-#[derive(Debug, Eq, PartialEq)]
-struct ActiveWorkflowStep {
- range: Range,
- suggestions: Option,
+ editor_was_open: bool,
+ assist_ids: Vec,
}
pub struct ContextEditor {
@@ -1353,9 +1347,9 @@ pub struct ContextEditor {
remote_id: Option,
pending_slash_command_creases: HashMap, CreaseId>,
pending_slash_command_blocks: HashMap, CustomBlockId>,
+ workflow_assists: HashMap, WorkflowAssist>,
+ active_workflow_step_range: Option>,
_subscriptions: Vec,
- assists_by_step: HashMap, StepAssists>,
- active_workflow_step: Option,
assistant_panel: WeakView,
error_message: Option,
}
@@ -1413,8 +1407,8 @@ impl ContextEditor {
pending_slash_command_creases: HashMap::default(),
pending_slash_command_blocks: HashMap::default(),
_subscriptions,
- assists_by_step: HashMap::default(),
- active_workflow_step: None,
+ workflow_assists: HashMap::default(),
+ active_workflow_step_range: None,
assistant_panel,
error_message: None,
};
@@ -1449,16 +1443,16 @@ impl ContextEditor {
}
fn assist(&mut self, _: &Assist, cx: &mut ViewContext) {
- if !self.apply_edit_step(cx) {
+ if !self.apply_workflow_step(cx) {
self.error_message = None;
self.send_to_model(cx);
cx.notify();
}
}
- fn apply_edit_step(&mut self, cx: &mut ViewContext) -> bool {
- if let Some(step) = self.active_workflow_step.as_ref() {
- if let Some(assists) = self.assists_by_step.get(&step.range) {
+ fn apply_workflow_step(&mut self, cx: &mut ViewContext) -> bool {
+ if let Some(step_range) = self.active_workflow_step_range.as_ref() {
+ if let Some(assists) = self.workflow_assists.get(&step_range) {
let assist_ids = assists.assist_ids.clone();
cx.window_context().defer(|cx| {
InlineAssistant::update_global(cx, |assistant, cx| {
@@ -1519,16 +1513,13 @@ impl ContextEditor {
.text_for_range(step.tagged_range.clone())
.collect::()
));
- match &step.edit_suggestions {
- WorkflowStepEditSuggestions::Resolved(ResolvedWorkflowStepEditSuggestions {
- title,
- edit_suggestions,
- }) => {
+ match &step.status {
+ WorkflowStepStatus::Resolved(ResolvedWorkflowStep { title, suggestions }) => {
output.push_str("Resolution:\n");
output.push_str(&format!(" {:?}\n", title));
- output.push_str(&format!(" {:?}\n", edit_suggestions));
+ output.push_str(&format!(" {:?}\n", suggestions));
}
- WorkflowStepEditSuggestions::Pending(_) => {
+ WorkflowStepStatus::Pending(_) => {
output.push_str("Resolution: Pending\n");
}
}
@@ -1676,7 +1667,7 @@ impl ContextEditor {
});
}
ContextEvent::WorkflowStepsChanged => {
- self.update_active_workflow_step(cx);
+ self.update_active_workflow_step_from_cursor(cx);
cx.notify();
}
ContextEvent::SummaryChanged => {
@@ -1941,14 +1932,14 @@ impl ContextEditor {
}
EditorEvent::SelectionsChanged { .. } => {
self.scroll_position = self.cursor_scroll_position(cx);
- self.update_active_workflow_step(cx);
+ self.update_active_workflow_step_from_cursor(cx);
}
_ => {}
}
cx.emit(event.clone());
}
- fn update_active_workflow_step(&mut self, cx: &mut ViewContext) {
+ fn update_active_workflow_step_from_cursor(&mut self, cx: &mut ViewContext) {
let new_step = self
.workflow_step_range_for_cursor(cx)
.as_ref()
@@ -1957,14 +1948,11 @@ impl ContextEditor {
.context
.read(cx)
.workflow_step_for_range(step_range.clone())?;
- Some(ActiveWorkflowStep {
- range: workflow_step.tagged_range.clone(),
- suggestions: workflow_step.edit_suggestions.as_resolved().cloned(),
- })
+ Some(workflow_step.tagged_range.clone())
});
- if new_step.as_ref() != self.active_workflow_step.as_ref() {
- if let Some(old_step) = self.active_workflow_step.take() {
- self.cancel_workflow_step_if_idle(old_step.range, cx);
+ if new_step.as_ref() != self.active_workflow_step_range.as_ref() {
+ if let Some(old_step_range) = self.active_workflow_step_range.take() {
+ self.hide_workflow_step(old_step_range, cx);
}
if let Some(new_step) = new_step {
@@ -1973,21 +1961,21 @@ impl ContextEditor {
}
}
- fn cancel_workflow_step_if_idle(
+ fn hide_workflow_step(
&mut self,
step_range: Range,
cx: &mut ViewContext,
) {
- let Some(step_assists) = self.assists_by_step.get_mut(&step_range) else {
+ let Some(step_assist) = self.workflow_assists.get_mut(&step_range) else {
return;
};
- let Some(editor) = step_assists.editor.upgrade() else {
- self.assists_by_step.remove(&step_range);
+ let Some(editor) = step_assist.editor.upgrade() else {
+ self.workflow_assists.remove(&step_range);
return;
};
InlineAssistant::update_global(cx, |assistant, cx| {
- step_assists.assist_ids.retain(|assist_id| {
+ step_assist.assist_ids.retain(|assist_id| {
match assistant.status_for_assist(*assist_id, cx) {
Some(CodegenStatus::Idle) | None => {
assistant.finish_assist(*assist_id, true, cx);
@@ -1998,14 +1986,15 @@ impl ContextEditor {
});
});
- if step_assists.assist_ids.is_empty() {
- self.assists_by_step.remove(&step_range);
+ if step_assist.assist_ids.is_empty() {
+ let editor_was_open = step_assist.editor_was_open;
+ self.workflow_assists.remove(&step_range);
self.workspace
.update(cx, |workspace, cx| {
if let Some(pane) = workspace.pane_for(&editor) {
pane.update(cx, |pane, cx| {
let item_id = editor.entity_id();
- if pane.is_active_preview_item(item_id) {
+ if !editor_was_open && pane.is_active_preview_item(item_id) {
pane.close_item_by_id(item_id, SaveIntent::Skip, cx)
.detach_and_log_err(cx);
}
@@ -2016,147 +2005,200 @@ impl ContextEditor {
}
}
- fn activate_workflow_step(&mut self, step: ActiveWorkflowStep, cx: &mut ViewContext) {
- if let Some(step_assists) = self.assists_by_step.get(&step.range) {
- if let Some(editor) = step_assists.editor.upgrade() {
- for assist_id in &step_assists.assist_ids {
- match InlineAssistant::global(cx).status_for_assist(*assist_id, cx) {
- Some(CodegenStatus::Idle) | None => {}
- _ => {
- self.workspace
- .update(cx, |workspace, cx| {
- workspace.activate_item(&editor, false, false, cx);
- })
- .ok();
- InlineAssistant::update_global(cx, |assistant, cx| {
- assistant.scroll_to_assist(*assist_id, cx)
- });
- return;
- }
- }
- }
- }
- }
-
- if let Some(ResolvedWorkflowStepEditSuggestions {
- title,
- edit_suggestions,
- }) = step.suggestions.as_ref()
- {
- if let Some((editor, assist_ids)) =
- self.suggest_edits(title.clone(), edit_suggestions.clone(), cx)
- {
- self.assists_by_step.insert(
- step.range.clone(),
- StepAssists {
- assist_ids,
- editor: editor.downgrade(),
- },
- );
- }
- }
-
- self.active_workflow_step = Some(step);
- }
-
- fn suggest_edits(
+ fn activate_workflow_step(
&mut self,
- title: String,
- edit_suggestions: HashMap, Vec>,
+ step_range: Range,
cx: &mut ViewContext,
- ) -> Option<(View, Vec)> {
- let assistant_panel = self.assistant_panel.upgrade()?;
- if edit_suggestions.is_empty() {
+ ) -> Option<()> {
+ if self.scroll_to_existing_workflow_assist(&step_range, cx) {
return None;
}
- let editor;
- let mut suggestion_groups = Vec::new();
- if edit_suggestions.len() == 1 && edit_suggestions.values().next().unwrap().len() == 1 {
- // If there's only one buffer and one suggestion group, open it directly
- let (buffer, groups) = edit_suggestions.into_iter().next().unwrap();
- let group = groups.into_iter().next().unwrap();
- editor = self
- .workspace
- .update(cx, |workspace, cx| {
- let active_pane = workspace.active_pane().clone();
- workspace.open_project_item::(active_pane, buffer, false, false, cx)
- })
- .log_err()?;
+ let step = self
+ .workflow_step(&step_range, cx)
+ .with_context(|| format!("could not find workflow step for range {:?}", step_range))
+ .log_err()?;
+ let Some(resolved) = step.status.as_resolved() else {
+ return None;
+ };
- let (&excerpt_id, _, _) = editor
- .read(cx)
- .buffer()
- .read(cx)
- .read(cx)
- .as_singleton()
- .unwrap();
+ let title = resolved.title.clone();
+ let suggestions = resolved.suggestions.clone();
- // Scroll the editor to the suggested assist
- editor.update(cx, |editor, cx| {
- let multibuffer = editor.buffer().read(cx).snapshot(cx);
- let (&excerpt_id, _, buffer) = multibuffer.as_singleton().unwrap();
- let anchor = if group.context_range.start.to_offset(buffer) == 0 {
- Anchor::min()
- } else {
- multibuffer
- .anchor_in_excerpt(excerpt_id, group.context_range.start)
- .unwrap()
- };
+ if let Some((editor, assist_ids, editor_was_open)) = {
+ let assistant_panel = self.assistant_panel.upgrade()?;
+ if suggestions.is_empty() {
+ return None;
+ }
- editor.set_scroll_anchor(
- ScrollAnchor {
- offset: gpui::Point::default(),
- anchor,
- },
- cx,
- );
- });
+ let editor;
+ let mut editor_was_open = false;
+ let mut suggestion_groups = Vec::new();
+ if suggestions.len() == 1 && suggestions.values().next().unwrap().len() == 1 {
+ // If there's only one buffer and one suggestion group, open it directly
+ let (buffer, groups) = suggestions.into_iter().next().unwrap();
+ let group = groups.into_iter().next().unwrap();
+ editor = self
+ .workspace
+ .update(cx, |workspace, cx| {
+ let active_pane = workspace.active_pane().clone();
+ editor_was_open =
+ workspace.is_project_item_open::(&active_pane, &buffer, cx);
+ workspace.open_project_item::(active_pane, buffer, false, false, cx)
+ })
+ .log_err()?;
- suggestion_groups.push((excerpt_id, group));
- } else {
- // If there are multiple buffers or suggestion groups, create a multibuffer
- let multibuffer = cx.new_model(|cx| {
- let replica_id = self.project.read(cx).replica_id();
- let mut multibuffer =
- MultiBuffer::new(replica_id, Capability::ReadWrite).with_title(title);
- for (buffer, groups) in edit_suggestions {
- let excerpt_ids = multibuffer.push_excerpts(
- buffer,
- groups.iter().map(|suggestion_group| ExcerptRange {
- context: suggestion_group.context_range.clone(),
- primary: None,
- }),
+ let (&excerpt_id, _, _) = editor
+ .read(cx)
+ .buffer()
+ .read(cx)
+ .read(cx)
+ .as_singleton()
+ .unwrap();
+
+ // Scroll the editor to the suggested assist
+ editor.update(cx, |editor, cx| {
+ let multibuffer = editor.buffer().read(cx).snapshot(cx);
+ let (&excerpt_id, _, buffer) = multibuffer.as_singleton().unwrap();
+ let anchor = if group.context_range.start.to_offset(buffer) == 0 {
+ Anchor::min()
+ } else {
+ multibuffer
+ .anchor_in_excerpt(excerpt_id, group.context_range.start)
+ .unwrap()
+ };
+
+ editor.set_scroll_anchor(
+ ScrollAnchor {
+ offset: gpui::Point::default(),
+ anchor,
+ },
cx,
);
- suggestion_groups.extend(excerpt_ids.into_iter().zip(groups));
- }
- multibuffer
- });
+ });
- editor = cx.new_view(|cx| {
- Editor::for_multibuffer(multibuffer, Some(self.project.clone()), true, cx)
- });
- self.workspace
- .update(cx, |workspace, cx| {
- workspace.add_item_to_active_pane(Box::new(editor.clone()), None, false, cx)
- })
- .log_err()?;
+ suggestion_groups.push((excerpt_id, group));
+ } else {
+ // If there are multiple buffers or suggestion groups, create a multibuffer
+ let multibuffer = cx.new_model(|cx| {
+ let replica_id = self.project.read(cx).replica_id();
+ let mut multibuffer =
+ MultiBuffer::new(replica_id, Capability::ReadWrite).with_title(title);
+ for (buffer, groups) in suggestions {
+ let excerpt_ids = multibuffer.push_excerpts(
+ buffer,
+ groups.iter().map(|suggestion_group| ExcerptRange {
+ context: suggestion_group.context_range.clone(),
+ primary: None,
+ }),
+ cx,
+ );
+ suggestion_groups.extend(excerpt_ids.into_iter().zip(groups));
+ }
+ multibuffer
+ });
+
+ editor = cx.new_view(|cx| {
+ Editor::for_multibuffer(multibuffer, Some(self.project.clone()), true, cx)
+ });
+ self.workspace
+ .update(cx, |workspace, cx| {
+ workspace.add_item_to_active_pane(Box::new(editor.clone()), None, false, cx)
+ })
+ .log_err()?;
+ }
+
+ let mut assist_ids = Vec::new();
+ for (excerpt_id, suggestion_group) in suggestion_groups {
+ for suggestion in suggestion_group.suggestions {
+ assist_ids.extend(suggestion.show(
+ &editor,
+ excerpt_id,
+ &self.workspace,
+ &assistant_panel,
+ cx,
+ ));
+ }
+ }
+
+ if let Some(range) = self.active_workflow_step_range.clone() {
+ self.workflow_assists.insert(
+ range,
+ WorkflowAssist {
+ assist_ids: assist_ids.clone(),
+ editor: editor.downgrade(),
+ editor_was_open,
+ },
+ );
+ }
+
+ Some((editor, assist_ids, editor_was_open))
+ } {
+ self.workflow_assists.insert(
+ step_range.clone(),
+ WorkflowAssist {
+ assist_ids,
+ editor_was_open,
+ editor: editor.downgrade(),
+ },
+ );
}
- let mut assist_ids = Vec::new();
- for (excerpt_id, suggestion_group) in suggestion_groups {
- for suggestion in suggestion_group.suggestions {
- assist_ids.extend(suggestion.show(
- &editor,
- excerpt_id,
- &self.workspace,
- &assistant_panel,
- cx,
- ));
+ self.active_workflow_step_range = Some(step_range);
+
+ Some(())
+ }
+
+ fn active_workflow_step<'a>(&'a self, cx: &'a AppContext) -> Option<&'a crate::WorkflowStep> {
+ self.active_workflow_step_range
+ .as_ref()
+ .and_then(|step_range| {
+ self.context
+ .read(cx)
+ .workflow_step_for_range(step_range.clone())
+ })
+ }
+
+ fn workflow_step<'a>(
+ &'a mut self,
+ step_range: &Range,
+ cx: &'a mut ViewContext,
+ ) -> Option<&'a crate::WorkflowStep> {
+ self.context
+ .read(cx)
+ .workflow_step_for_range(step_range.clone())
+ }
+
+ fn scroll_to_existing_workflow_assist(
+ &self,
+ step_range: &Range,
+ cx: &mut ViewContext,
+ ) -> bool {
+ let step_assists = match self.workflow_assists.get(step_range) {
+ Some(assists) => assists,
+ None => return false,
+ };
+ let editor = match step_assists.editor.upgrade() {
+ Some(editor) => editor,
+ None => return false,
+ };
+ for assist_id in &step_assists.assist_ids {
+ match InlineAssistant::global(cx).status_for_assist(*assist_id, cx) {
+ Some(CodegenStatus::Idle) | None => {}
+ _ => {
+ self.workspace
+ .update(cx, |workspace, cx| {
+ workspace.activate_item(&editor, false, false, cx);
+ })
+ .ok();
+ InlineAssistant::update_global(cx, |assistant, cx| {
+ assistant.scroll_to_assist(*assist_id, cx)
+ });
+ return true;
+ }
}
}
- Some((editor, assist_ids))
+ false
}
fn handle_editor_search_event(
@@ -2540,12 +2582,12 @@ impl ContextEditor {
fn render_send_button(&self, cx: &mut ViewContext) -> impl IntoElement {
let focus_handle = self.focus_handle(cx).clone();
- let button_text = match self.active_workflow_step.as_ref() {
+ let button_text = match self.active_workflow_step(cx) {
Some(step) => {
- if step.suggestions.is_none() {
- "Computing Changes..."
- } else {
+ if step.status.is_resolved() {
"Apply Changes"
+ } else {
+ "Computing Changes..."
}
}
None => "Send",
diff --git a/crates/assistant/src/context.rs b/crates/assistant/src/context.rs
index b001794d9e..33a8961800 100644
--- a/crates/assistant/src/context.rs
+++ b/crates/assistant/src/context.rs
@@ -348,37 +348,44 @@ pub struct SlashCommandId(clock::Lamport);
#[derive(Debug)]
pub struct WorkflowStep {
pub tagged_range: Range,
- pub edit_suggestions: WorkflowStepEditSuggestions,
+ pub status: WorkflowStepStatus,
}
#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct ResolvedWorkflowStepEditSuggestions {
+pub struct ResolvedWorkflowStep {
pub title: String,
- pub edit_suggestions: HashMap, Vec>,
+ pub suggestions: HashMap, Vec>,
}
-pub enum WorkflowStepEditSuggestions {
+pub enum WorkflowStepStatus {
Pending(Task