mind: add turn_watch, move /retry to event_loop
Add tokio::sync::watch for turn_in_progress state. Commands in the UI event loop can wait for turns to complete via wait_for() instead of checking-and-bailing. Move /retry to event_loop: waits for turn completion, pops agent history, sends retried text as MindMessage::UserInput. Mind doesn't need to know about retry — it just sees a new input message. Make agent field pub on Mind for UI access. Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
178824fa01
commit
b05c956ab8
2 changed files with 63 additions and 36 deletions
|
|
@ -52,6 +52,34 @@ fn send_help(ui_tx: &ui_channel::UiSender) {
|
|||
));
|
||||
}
|
||||
|
||||
async fn cmd_retry(
|
||||
agent: &Arc<Mutex<Agent>>,
|
||||
ui_tx: &ui_channel::UiSender,
|
||||
mind_tx: &tokio::sync::mpsc::UnboundedSender<MindMessage>,
|
||||
) {
|
||||
let mut agent_guard = agent.lock().await;
|
||||
let entries = agent_guard.entries_mut();
|
||||
let mut last_user_text = None;
|
||||
while let Some(entry) = entries.last() {
|
||||
if entry.message().role == crate::agent::api::types::Role::User {
|
||||
last_user_text = Some(entries.pop().unwrap().message().content_text().to_string());
|
||||
break;
|
||||
}
|
||||
entries.pop();
|
||||
}
|
||||
drop(agent_guard);
|
||||
match last_user_text {
|
||||
Some(text) => {
|
||||
let preview_len = text.len().min(60);
|
||||
let _ = ui_tx.send(UiMessage::Info(format!("(retrying: {}...)", &text[..preview_len])));
|
||||
let _ = mind_tx.send(MindMessage::UserInput(text));
|
||||
}
|
||||
None => {
|
||||
let _ = ui_tx.send(UiMessage::Info("(nothing to retry)".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn cmd_switch_model(
|
||||
agent: &Arc<Mutex<Agent>>,
|
||||
name: &str,
|
||||
|
|
@ -94,6 +122,7 @@ pub async fn cmd_switch_model(
|
|||
pub async fn run(
|
||||
mut app: tui::App,
|
||||
agent: Arc<Mutex<Agent>>,
|
||||
turn_watch: tokio::sync::watch::Receiver<bool>,
|
||||
mind_tx: tokio::sync::mpsc::UnboundedSender<MindMessage>,
|
||||
ui_tx: ui_channel::UiSender,
|
||||
mut ui_rx: ui_channel::UiReceiver,
|
||||
|
|
@ -203,6 +232,17 @@ pub async fn run(
|
|||
let _ = ui_tx.send(UiMessage::Info("(busy)".into()));
|
||||
}
|
||||
}
|
||||
"/retry" => {
|
||||
let agent = agent.clone();
|
||||
let ui_tx = ui_tx.clone();
|
||||
let mind_tx = mind_tx.clone();
|
||||
let mut tw = turn_watch.clone();
|
||||
tokio::spawn(async move {
|
||||
// Wait for any in-progress turn to complete
|
||||
let _ = tw.wait_for(|&active| !active).await;
|
||||
cmd_retry(&agent, &ui_tx, &mind_tx).await;
|
||||
});
|
||||
}
|
||||
cmd if cmd.starts_with("/model ") => {
|
||||
let name = cmd[7..].trim().to_string();
|
||||
if name.is_empty() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue