mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
feat(tui/auto-drive): persist conversation between turns
This commit is contained in:
@@ -47,6 +47,7 @@ use codex_protocol::num_format::format_with_separators;
|
||||
|
||||
|
||||
mod auto_coordinator;
|
||||
mod auto_drive_history;
|
||||
mod auto_observer;
|
||||
#[cfg(feature = "dev-faults")]
|
||||
mod faults;
|
||||
@@ -78,6 +79,7 @@ use self::agent_install::{
|
||||
start_upgrade_terminal_session,
|
||||
wrap_command,
|
||||
};
|
||||
use self::auto_drive_history::AutoDriveHistory;
|
||||
use self::auto_coordinator::{start_auto_coordinator, AutoCoordinatorCommand, AutoCoordinatorHandle};
|
||||
use self::limits_overlay::{LimitsOverlay, LimitsOverlayContent, LimitsTab};
|
||||
use self::rate_limit_refresh::start_rate_limit_refresh;
|
||||
@@ -654,6 +656,7 @@ pub(crate) struct ChatWidget<'a> {
|
||||
|
||||
auto_state: AutoCoordinatorUiState,
|
||||
auto_handle: Option<AutoCoordinatorHandle>,
|
||||
auto_history: AutoDriveHistory,
|
||||
|
||||
// Event sequencing to preserve original order across streaming/tool events
|
||||
// and stream-related flags moved into stream_state
|
||||
@@ -2888,6 +2891,7 @@ impl ChatWidget<'_> {
|
||||
pending_snapshot_dispatches: VecDeque::new(),
|
||||
auto_state: AutoCoordinatorUiState::default(),
|
||||
auto_handle: None,
|
||||
auto_history: AutoDriveHistory::new(),
|
||||
browser_is_external: false,
|
||||
// Stable ordering & routing init
|
||||
cell_order_seq: vec![OrderKey {
|
||||
@@ -3142,6 +3146,7 @@ impl ChatWidget<'_> {
|
||||
pending_snapshot_dispatches: VecDeque::new(),
|
||||
auto_state: AutoCoordinatorUiState::default(),
|
||||
auto_handle: None,
|
||||
auto_history: AutoDriveHistory::new(),
|
||||
browser_is_external: false,
|
||||
// Strict ordering init for forked widget
|
||||
cell_order_seq: vec![OrderKey {
|
||||
@@ -3387,6 +3392,19 @@ impl ChatWidget<'_> {
|
||||
items
|
||||
}
|
||||
|
||||
fn rebuild_auto_history(&mut self) -> Vec<codex_protocol::models::ResponseItem> {
|
||||
let conversation = self.export_auto_drive_items();
|
||||
self.auto_history.replace(conversation.clone());
|
||||
conversation
|
||||
}
|
||||
|
||||
fn current_auto_history(&mut self) -> Vec<codex_protocol::models::ResponseItem> {
|
||||
if self.auto_history.is_empty() {
|
||||
return self.rebuild_auto_history();
|
||||
}
|
||||
self.auto_history.snapshot()
|
||||
}
|
||||
|
||||
/// Export current user/assistant messages into ResponseItem list for forking.
|
||||
pub(crate) fn export_response_items(&self) -> Vec<codex_protocol::models::ResponseItem> {
|
||||
use codex_protocol::models::ContentItem;
|
||||
@@ -10003,7 +10021,7 @@ impl ChatWidget<'_> {
|
||||
self.auto_stop(None);
|
||||
}
|
||||
|
||||
let conversation = self.export_auto_drive_items();
|
||||
let conversation = self.rebuild_auto_history();
|
||||
match start_auto_coordinator(
|
||||
self.app_event_tx.clone(),
|
||||
goal_text.clone(),
|
||||
@@ -10042,10 +10060,10 @@ impl ChatWidget<'_> {
|
||||
if !self.auto_state.active || self.auto_state.waiting_for_response {
|
||||
return;
|
||||
}
|
||||
let conversation = self.current_auto_history();
|
||||
let Some(handle) = self.auto_handle.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let conversation = self.export_auto_drive_items();
|
||||
if handle
|
||||
.send(AutoCoordinatorCommand::UpdateConversation(conversation))
|
||||
.is_err()
|
||||
@@ -10294,6 +10312,7 @@ impl ChatWidget<'_> {
|
||||
}
|
||||
self.bottom_pane.set_standard_terminal_hint(None);
|
||||
self.auto_state.reset();
|
||||
self.auto_history.clear();
|
||||
self.bottom_pane.clear_auto_coordinator_view();
|
||||
self.bottom_pane.clear_live_ring();
|
||||
let any_exec_running = !self.exec.running_commands.is_empty();
|
||||
@@ -10335,6 +10354,7 @@ impl ChatWidget<'_> {
|
||||
self.update_header_border_activation();
|
||||
self.auto_rebuild_live_ring();
|
||||
self.request_redraw();
|
||||
self.rebuild_auto_history();
|
||||
self.auto_send_conversation();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
use codex_protocol::models::ResponseItem;
|
||||
|
||||
/// Maintains the Auto Drive conversation transcript between coordinator turns.
|
||||
pub(crate) struct AutoDriveHistory {
|
||||
items: Vec<ResponseItem>,
|
||||
}
|
||||
|
||||
impl AutoDriveHistory {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { items: Vec::new() }
|
||||
}
|
||||
|
||||
/// Replace the stored transcript with the provided items.
|
||||
pub(crate) fn replace(&mut self, items: Vec<ResponseItem>) {
|
||||
self.items = items;
|
||||
}
|
||||
|
||||
pub(crate) fn snapshot(&self) -> Vec<ResponseItem> {
|
||||
self.items.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.items.clear();
|
||||
}
|
||||
|
||||
pub(crate) fn is_empty(&self) -> bool {
|
||||
self.items.is_empty()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user