Branch conversations when editing earlier TUI prompts (#33201)

## What changed

- Fork the conversation immediately before the selected prompt instead of rolling back the current thread in place, preserving the original conversation.
- Reopen the selected prompt in the new conversation with its images, text elements, and mention bindings intact.
- Start a fresh conversation when editing the first prompt, show a dedicated continuation notice, and restore the prompt with an error if branching fails.

## Testing

- Cover branching before first and later prompts, source preservation, prompt restoration, hidden review prompts, mid-turn steering, in-progress turns, stale transcript entries, and mention bindings.

GitOrigin-RevId: 15473535b3f9733b0300711a498969e6d389db79
This commit is contained in:
Felipe Coury authored and copyberry committed 2026-07-15 01:36:44 +00:00
1 parent 72b41c55fb
commit 469ce0db51
17 files changed
+928 -549

No files matched your search

+25 -1
View File
@@ -111,7 +111,10 @@ impl ChatWidget {
self.sync_goal_command_enabled();
self.refresh_plugin_mentions();
let model_for_header = self.current_model().to_string();
if display == SessionConfiguredDisplay::Normal {
if matches!(
display,
SessionConfiguredDisplay::Normal | SessionConfiguredDisplay::PromptEdit
) {
let startup_tooltip_override = self.startup_tooltip_override.take();
let show_fast_status = self
.should_show_fast_status(&model_for_header, self.effective_service_tier.as_deref());
@@ -169,6 +172,16 @@ impl ChatWidget {
);
}
pub(crate) fn handle_prompt_edit_thread_session(&mut self, session: ThreadSessionState) {
self.instruction_source_paths = session.instruction_source_paths.clone();
let fork_parent_title = session.fork_parent_title.clone();
self.on_session_configured_with_display_and_fork_parent_title(
session,
SessionConfiguredDisplay::PromptEdit,
fork_parent_title,
);
}
pub(crate) fn handle_side_thread_session(&mut self, session: ThreadSessionState) {
self.instruction_source_paths = session.instruction_source_paths.clone();
let fork_parent_title = session.fork_parent_title.clone();
@@ -210,6 +223,17 @@ impl ChatWidget {
)));
}
pub(crate) fn emit_prompt_edit_thread_event(&mut self) {
let line: Line<'static> = vec![
"• ".dim(),
"You’re continuing from this point in a new conversation".into(),
]
.into();
self.app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(
PlainHistoryCell::new(vec![line]),
)));
}
pub(super) fn on_thread_name_updated(
&mut self,
thread_id: ThreadId,