mind: move send_context_info and update_status to event_loop

Both are pure UI operations that read config/shared state and format
display messages. No Mind state mutation involved.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2026-04-05 03:12:50 -04:00
parent 4eb0c891c4
commit 54cd3783eb
2 changed files with 31 additions and 35 deletions

View file

@ -295,36 +295,6 @@ impl Mind {
}); });
} }
pub fn send_context_info(&self) {
let context_groups = config::get().context_groups.clone();
let (instruction_files, memory_files) = identity::context_file_info(
&self.config.prompt_file,
self.config.app.memory_project.as_deref(),
&context_groups,
);
let _ = self.ui_tx.send(UiMessage::ContextInfoUpdate(ContextInfo {
model: self.config.model.clone(),
available_models: self.config.app.model_names(),
prompt_file: self.config.prompt_file.clone(),
backend: self.config.app.backend.clone(),
instruction_files,
memory_files,
system_prompt_chars: self.config.system_prompt.len(),
context_message_chars: self.config.context_parts.iter().map(|(_, c)| c.len()).sum(),
}));
}
pub fn update_status(&self) {
let s = self.shared.lock().unwrap();
let _ = self.ui_tx.send(UiMessage::StatusUpdate(StatusInfo {
dmn_state: s.dmn.label().to_string(),
dmn_turns: s.dmn_turns,
dmn_max_turns: s.max_dmn_turns,
prompt_tokens: 0, completion_tokens: 0,
model: String::new(), turn_tools: 0,
context_budget: String::new(),
}));
}
pub async fn shutdown(&mut self) { pub async fn shutdown(&mut self) {
if let Some(handle) = self.turn_handle.take() { handle.abort(); } if let Some(handle) = self.turn_handle.take() { handle.abort(); }
@ -396,7 +366,7 @@ impl Mind {
// Check for pending input // Check for pending input
let action = self.shared.lock().unwrap().take_pending_input(); let action = self.shared.lock().unwrap().take_pending_input();
self.execute(action); self.execute(action);
self.update_status(); crate::user::event_loop::update_status(&self.shared, &self.ui_tx);
} }
Some((result, target)) = turn_rx.recv() => { Some((result, target)) = turn_rx.recv() => {
@ -417,7 +387,7 @@ impl Mind {
self.check_compaction(); self.check_compaction();
if !self.config.no_agents { self.start_memory_scoring(); } if !self.config.no_agents { self.start_memory_scoring(); }
self.update_status(); crate::user::event_loop::update_status(&self.shared, &self.ui_tx);
let action = self.shared.lock().unwrap().take_pending_input(); let action = self.shared.lock().unwrap().take_pending_input();
self.execute(action); self.execute(action);
@ -430,7 +400,7 @@ impl Mind {
let action = self.shared.lock().unwrap().dmn_tick(); let action = self.shared.lock().unwrap().dmn_tick();
self.execute(action); self.execute(action);
} }
self.update_status(); crate::user::event_loop::update_status(&self.shared, &self.ui_tx);
} }
} }
} }
@ -528,12 +498,12 @@ pub async fn run(cli: crate::user::CliArgs) -> Result<()> {
let no_agents = config.no_agents; let no_agents = config.no_agents;
let shared_mind = shared_mind_state(config.app.dmn.max_turns); let shared_mind = shared_mind_state(config.app.dmn.max_turns);
crate::user::event_loop::send_context_info(&config, &ui_tx);
let mut mind = Mind::new(agent, shared_mind.clone(), config, ui_tx.clone(), turn_tx); let mut mind = Mind::new(agent, shared_mind.clone(), config, ui_tx.clone(), turn_tx);
mind.update_status(); crate::user::event_loop::update_status(&shared_mind, &ui_tx);
if !no_agents { if !no_agents {
mind.start_memory_scoring(); mind.start_memory_scoring();
} }
mind.send_context_info();
// Start observation socket // Start observation socket
let socket_path = mind.config.session_dir.join("agent.sock"); let socket_path = mind.config.session_dir.join("agent.sock");

View file

@ -130,6 +130,32 @@ fn cmd_adjust_sampling(agent: &Arc<Mutex<Agent>>, param: usize, delta: f32) {
} }
} }
pub fn update_status(shared: &crate::mind::SharedMindState, ui_tx: &ui_channel::UiSender) {
let s = shared.lock().unwrap();
let _ = ui_tx.send(UiMessage::StatusUpdate(ui_channel::StatusInfo {
dmn_state: s.dmn.label().to_string(),
dmn_turns: s.dmn_turns,
dmn_max_turns: s.max_dmn_turns,
prompt_tokens: 0, completion_tokens: 0,
model: String::new(), turn_tools: 0,
context_budget: String::new(),
}));
}
pub fn send_context_info(config: &crate::config::SessionConfig, ui_tx: &ui_channel::UiSender) {
let context_groups = crate::config::get().context_groups.clone();
let (instruction_files, memory_files) = crate::mind::identity::context_file_info(
&config.prompt_file,
config.app.memory_project.as_deref(),
&context_groups,
);
let _ = ui_tx.send(UiMessage::Info(format!(
" context: {}K chars ({} config, {} memory files)",
config.context_parts.iter().map(|(_, c)| c.len()).sum::<usize>() / 1024,
instruction_files.len(), memory_files.len(),
)));
}
pub async fn cmd_switch_model( pub async fn cmd_switch_model(
agent: &Arc<Mutex<Agent>>, agent: &Arc<Mutex<Agent>>,
name: &str, name: &str,