mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
feat(tui/auto_drive): export rendered history for coordinator
This commit is contained in:
@@ -1264,6 +1264,12 @@ enum SystemPlacement {
|
||||
PrePromptInCurrent,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum AutoDriveRole {
|
||||
User,
|
||||
Assistant,
|
||||
}
|
||||
|
||||
impl ChatWidget<'_> {
|
||||
const MAX_UNDO_CONVERSATION_MESSAGES: usize = 8;
|
||||
const MAX_UNDO_PREVIEW_CHARS: usize = 160;
|
||||
@@ -3543,6 +3549,26 @@ impl ChatWidget<'_> {
|
||||
rows.join("\n")
|
||||
}
|
||||
|
||||
fn auto_drive_role_for_kind(kind: HistoryCellType) -> Option<AutoDriveRole> {
|
||||
use AutoDriveRole::{Assistant, User};
|
||||
match kind {
|
||||
HistoryCellType::User => Some(Assistant),
|
||||
HistoryCellType::Assistant
|
||||
| HistoryCellType::Reasoning
|
||||
| HistoryCellType::Error
|
||||
| HistoryCellType::Exec { .. }
|
||||
| HistoryCellType::Tool { .. }
|
||||
| HistoryCellType::Patch { .. }
|
||||
| HistoryCellType::PlanUpdate
|
||||
| HistoryCellType::BackgroundEvent
|
||||
| HistoryCellType::Notice
|
||||
| HistoryCellType::Diff
|
||||
| HistoryCellType::Plain
|
||||
| HistoryCellType::Image => Some(User),
|
||||
HistoryCellType::AnimatedWelcome | HistoryCellType::Loading => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn auto_drive_cell_text(cell: &dyn HistoryCell) -> Option<String> {
|
||||
let text = Self::auto_drive_lines_to_string(cell.display_lines());
|
||||
if text.trim().is_empty() {
|
||||
@@ -3658,31 +3684,12 @@ impl ChatWidget<'_> {
|
||||
pub(crate) fn export_auto_drive_items(&self) -> Vec<codex_protocol::models::ResponseItem> {
|
||||
let mut items = Vec::new();
|
||||
for cell in &self.history_cells {
|
||||
match cell.kind() {
|
||||
HistoryCellType::User => {
|
||||
if let Some(text) = Self::auto_drive_cell_text(cell.as_ref()) {
|
||||
if let Some(item) = Self::auto_drive_make_assistant_message(text) {
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
HistoryCellType::Assistant => {
|
||||
if let Some(text) = Self::auto_drive_cell_text(cell.as_ref()) {
|
||||
if let Some(item) = Self::auto_drive_make_user_message(text) {
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
HistoryCellType::Reasoning => {
|
||||
if let Some(text) = Self::auto_drive_cell_text(cell.as_ref()) {
|
||||
use codex_protocol::models::{ContentItem, ResponseItem};
|
||||
items.push(ResponseItem::Message {
|
||||
id: Some("auto-drive-reasoning".to_string()),
|
||||
role: "user".to_string(),
|
||||
content: vec![ContentItem::InputText { text }],
|
||||
});
|
||||
}
|
||||
}
|
||||
let Some(role) = Self::auto_drive_role_for_kind(cell.kind()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let text = match cell.kind() {
|
||||
HistoryCellType::Reasoning => Self::auto_drive_cell_text(cell.as_ref()).map(|text| (text, true)),
|
||||
HistoryCellType::PlanUpdate => {
|
||||
if let Some(plan) = cell.as_any().downcast_ref::<PlanUpdateCell>() {
|
||||
let state = plan.state();
|
||||
@@ -3711,22 +3718,45 @@ impl ChatWidget<'_> {
|
||||
}
|
||||
}
|
||||
let text = lines.join("\n");
|
||||
if let Some(item) = Self::auto_drive_make_user_message(text) {
|
||||
items.push(item);
|
||||
}
|
||||
Some((text, false))
|
||||
} else {
|
||||
Self::auto_drive_cell_text(cell.as_ref()).map(|text| (text, false))
|
||||
}
|
||||
}
|
||||
HistoryCellType::Diff => {
|
||||
if let Some(diff_cell) = cell.as_any().downcast_ref::<DiffCell>() {
|
||||
if let Some(summary) = Self::auto_drive_diff_summary(diff_cell.record()) {
|
||||
if let Some(item) = Self::auto_drive_make_user_message(summary) {
|
||||
items.push(item);
|
||||
}
|
||||
}
|
||||
Self::auto_drive_diff_summary(diff_cell.record()).map(|text| (text, false))
|
||||
} else {
|
||||
Self::auto_drive_cell_text(cell.as_ref()).map(|text| (text, false))
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => Self::auto_drive_cell_text(cell.as_ref()).map(|text| (text, false)),
|
||||
};
|
||||
|
||||
let Some((text, is_reasoning)) = text else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let item = if is_reasoning {
|
||||
codex_protocol::models::ResponseItem::Message {
|
||||
id: Some("auto-drive-reasoning".to_string()),
|
||||
role: "user".to_string(),
|
||||
content: vec![codex_protocol::models::ContentItem::InputText { text }],
|
||||
}
|
||||
} else {
|
||||
match role {
|
||||
AutoDriveRole::Assistant => match Self::auto_drive_make_assistant_message(text) {
|
||||
Some(item) => item,
|
||||
None => continue,
|
||||
},
|
||||
AutoDriveRole::User => match Self::auto_drive_make_user_message(text) {
|
||||
Some(item) => item,
|
||||
None => continue,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
items.push(item);
|
||||
}
|
||||
items
|
||||
}
|
||||
|
||||
@@ -11,12 +11,17 @@ use crate::app_event::{
|
||||
};
|
||||
use crate::app_event_sender::AppEventSender;
|
||||
use crate::history::state::{
|
||||
ArgumentValue,
|
||||
ExecStatus,
|
||||
ExploreEntryStatus,
|
||||
HistoryDomainRecord,
|
||||
HistoryId,
|
||||
HistoryRecord,
|
||||
HistoryState,
|
||||
ToolArgument,
|
||||
ToolCallState,
|
||||
ToolResultPreview,
|
||||
ToolStatus,
|
||||
};
|
||||
use crate::slash_command::SlashCommand;
|
||||
use super::auto_coordinator::AutoCoordinatorHandle;
|
||||
@@ -3663,6 +3668,24 @@ fn export_auto_drive_items_includes_cli_outputs() {
|
||||
let diff = "diff --git a/foo.rs b/foo.rs\n--- a/foo.rs\n+++ b/foo.rs\n@@ -1 +1,2 @@\n-println!(\"old\");\n+println!(\"new\");\n+println!(\"extra\");\n";
|
||||
chat.add_diff_output(diff.to_string());
|
||||
|
||||
let tool_state = ToolCallState {
|
||||
id: HistoryId::ZERO,
|
||||
call_id: Some("tool-1".to_string()),
|
||||
status: ToolStatus::Success,
|
||||
title: "Run formatter".to_string(),
|
||||
duration: None,
|
||||
arguments: vec![ToolArgument {
|
||||
name: "command".to_string(),
|
||||
value: ArgumentValue::Text("just fmt".to_string()),
|
||||
}],
|
||||
result_preview: Some(ToolResultPreview {
|
||||
lines: vec!["Formatted 12 files".to_string()],
|
||||
truncated: false,
|
||||
}),
|
||||
error_message: None,
|
||||
};
|
||||
chat.history_push(history_cell::ToolCallCell::new(tool_state));
|
||||
|
||||
let items = chat.export_auto_drive_items();
|
||||
|
||||
let coordinator = items
|
||||
@@ -3707,6 +3730,12 @@ fn export_auto_drive_items_includes_cli_outputs() {
|
||||
.map(|text| text.contains("Files changed") && text.contains("foo.rs"))
|
||||
.unwrap_or(false)
|
||||
}), "diff summary present");
|
||||
|
||||
assert!(items.iter().any(|item| {
|
||||
message_text(item)
|
||||
.map(|text| text.contains("Run formatter") && text.contains("Formatted 12 files"))
|
||||
.unwrap_or(false)
|
||||
}), "tool call output present");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user