event_loop: diff MindState on input submission, fix input display
Extract diff_mind_state() — reused on render tick and input submit. When pushing user input, lock shared, diff (catches any Mind state changes), push input, snapshot. The next diff sees the input was consumed → displays it. Fixes: user text not appearing in conversation window. Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
7dc515b985
commit
3b15c690ec
1 changed files with 47 additions and 34 deletions
|
|
@ -215,6 +215,46 @@ pub async fn cmd_switch_model(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn diff_mind_state(
|
||||||
|
cur: &crate::mind::MindState,
|
||||||
|
prev: &crate::mind::MindState,
|
||||||
|
ui_tx: &ui_channel::UiSender,
|
||||||
|
dirty: &mut bool,
|
||||||
|
) {
|
||||||
|
if cur.dmn.label() != prev.dmn.label() || cur.dmn_turns != prev.dmn_turns {
|
||||||
|
let _ = ui_tx.send(UiMessage::StatusUpdate(ui_channel::StatusInfo {
|
||||||
|
dmn_state: cur.dmn.label().to_string(),
|
||||||
|
dmn_turns: cur.dmn_turns,
|
||||||
|
dmn_max_turns: cur.max_dmn_turns,
|
||||||
|
prompt_tokens: 0, completion_tokens: 0,
|
||||||
|
model: String::new(), turn_tools: 0,
|
||||||
|
context_budget: String::new(),
|
||||||
|
}));
|
||||||
|
*dirty = true;
|
||||||
|
}
|
||||||
|
// Turn started — input was consumed
|
||||||
|
if cur.turn_active && !prev.turn_active && !prev.input.is_empty() {
|
||||||
|
let text = prev.input.join("\n");
|
||||||
|
let _ = ui_tx.send(UiMessage::UserInput(text));
|
||||||
|
*dirty = true;
|
||||||
|
}
|
||||||
|
if cur.turn_active != prev.turn_active {
|
||||||
|
*dirty = true;
|
||||||
|
}
|
||||||
|
if cur.scoring_in_flight != prev.scoring_in_flight {
|
||||||
|
if !cur.scoring_in_flight && prev.scoring_in_flight {
|
||||||
|
let _ = ui_tx.send(UiMessage::Info("[scoring complete]".into()));
|
||||||
|
}
|
||||||
|
*dirty = true;
|
||||||
|
}
|
||||||
|
if cur.compaction_in_flight != prev.compaction_in_flight {
|
||||||
|
if !cur.compaction_in_flight && prev.compaction_in_flight {
|
||||||
|
let _ = ui_tx.send(UiMessage::Info("[compacted]".into()));
|
||||||
|
}
|
||||||
|
*dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn run(
|
pub async fn run(
|
||||||
mut app: tui::App,
|
mut app: tui::App,
|
||||||
agent: &Arc<Mutex<Agent>>,
|
agent: &Arc<Mutex<Agent>>,
|
||||||
|
|
@ -304,39 +344,9 @@ pub async fn run(
|
||||||
|
|
||||||
// Diff MindState — generate UI messages from changes
|
// Diff MindState — generate UI messages from changes
|
||||||
{
|
{
|
||||||
let cur = shared_mind.lock().unwrap().clone();
|
let cur = shared_mind.lock().unwrap();
|
||||||
if cur.dmn.label() != prev_mind.dmn.label() || cur.dmn_turns != prev_mind.dmn_turns {
|
diff_mind_state(&cur, &prev_mind, &ui_tx, &mut dirty);
|
||||||
let _ = ui_tx.send(UiMessage::StatusUpdate(ui_channel::StatusInfo {
|
prev_mind = cur.clone();
|
||||||
dmn_state: cur.dmn.label().to_string(),
|
|
||||||
dmn_turns: cur.dmn_turns,
|
|
||||||
dmn_max_turns: cur.max_dmn_turns,
|
|
||||||
prompt_tokens: 0, completion_tokens: 0,
|
|
||||||
model: String::new(), turn_tools: 0,
|
|
||||||
context_budget: String::new(),
|
|
||||||
}));
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if cur.turn_active && !prev_mind.turn_active && !prev_mind.input.is_empty() {
|
|
||||||
let text = prev_mind.input.join("\n");
|
|
||||||
let _ = ui_tx.send(UiMessage::UserInput(text));
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if cur.turn_active != prev_mind.turn_active {
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if cur.scoring_in_flight != prev_mind.scoring_in_flight {
|
|
||||||
if !cur.scoring_in_flight && prev_mind.scoring_in_flight {
|
|
||||||
let _ = ui_tx.send(UiMessage::Info("[scoring complete]".into()));
|
|
||||||
}
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if cur.compaction_in_flight != prev_mind.compaction_in_flight {
|
|
||||||
if !cur.compaction_in_flight && prev_mind.compaction_in_flight {
|
|
||||||
let _ = ui_tx.send(UiMessage::Info("[compacted]".into()));
|
|
||||||
}
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
prev_mind = cur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(notif) = notify_rx.try_recv() {
|
while let Ok(notif) = notify_rx.try_recv() {
|
||||||
|
|
@ -433,7 +443,10 @@ pub async fn run(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
shared_mind.lock().unwrap().input.push(input);
|
let mut s = shared_mind.lock().unwrap();
|
||||||
|
diff_mind_state(&s, &prev_mind, &ui_tx, &mut dirty);
|
||||||
|
s.input.push(input);
|
||||||
|
prev_mind = s.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue