From b473ead8a3e10f52bd6fb3d3ee4a1fb6691e4907 Mon Sep 17 00:00:00 2001 From: Amaan <121273095+AmaanBilwar@users.noreply.github.com> Date: Wed, 8 Apr 2026 16:18:05 +0530 Subject: [PATCH] ai: Preserve `draft_prompt` when creating a new agent threads (#53250) - added a shared helper `take_active_draft_initial_content` to resolve initial content - `draft_prompt` is copied over to a new thread and is persisted in old thread with this behavior Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] no Unsafe blocks - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable Closes #38028 Release Notes: - persist draft messages in ai thread when a new thread is created so we dont use any messages or draft prompts mistakenly Question: need some guidance on how to persist a thread when the `draft_prompt` is present but the message is unsent because currently having a draft prompt in the agent input box and thenmaking a new agent thread copies the prompt over to the new thread(changes from this pr) but on going back to the old thread new thread is destroyed --- crates/agent_ui/src/agent_panel.rs | 48 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 52336871d01d5200f4d2a6799bb969b78fde6696..291a5ff0d9da2c2c48f705358e159bc0cbfe7fcb 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -206,12 +206,13 @@ pub fn init(cx: &mut App) { if let Some(panel) = workspace.panel::(cx) { workspace.focus_panel::(window, cx); panel.update(cx, |panel, cx| { + let initial_content = panel.take_active_draft_initial_content(cx); panel.external_thread( action.agent.clone(), None, None, None, - None, + initial_content, true, window, cx, @@ -1304,7 +1305,38 @@ impl AgentPanel { pub fn new_thread(&mut self, _action: &NewThread, window: &mut Window, cx: &mut Context) { self.reset_start_thread_in_to_default(cx); - self.external_thread(None, None, None, None, None, true, window, cx); + let initial_content = self.take_active_draft_initial_content(cx); + self.external_thread(None, None, None, None, initial_content, true, window, cx); + } + + fn take_active_draft_initial_content( + &mut self, + cx: &mut Context, + ) -> Option { + self.active_thread_view(cx).and_then(|thread_view| { + thread_view.update(cx, |thread_view, cx| { + let draft_blocks = thread_view + .thread + .read(cx) + .draft_prompt() + .map(|draft| draft.to_vec()) + .filter(|draft| !draft.is_empty()); + + let draft_blocks = draft_blocks.or_else(|| { + let text = thread_view.message_editor.read(cx).text(cx); + if text.trim().is_empty() { + None + } else { + Some(vec![acp::ContentBlock::Text(acp::TextContent::new(text))]) + } + }); + + draft_blocks.map(|blocks| AgentInitialContent::ContentBlock { + blocks, + auto_submit: false, + }) + }) + }) } fn new_native_agent_thread_from_summary( @@ -2401,7 +2433,17 @@ impl AgentPanel { window: &mut Window, cx: &mut Context, ) { - self.external_thread(Some(agent), None, None, None, None, focus, window, cx); + let initial_content = self.take_active_draft_initial_content(cx); + self.external_thread( + Some(agent), + None, + None, + None, + initial_content, + focus, + window, + cx, + ); } pub fn load_agent_thread(