diff --git a/src/mind/mod.rs b/src/mind/mod.rs index c2c79ca..cb70928 100644 --- a/src/mind/mod.rs +++ b/src/mind/mod.rs @@ -26,7 +26,7 @@ use crate::agent::{Agent, TurnResult}; use crate::agent::api::ApiClient; use crate::config::{self, AppConfig, SessionConfig}; use crate::user::{self as tui}; -use crate::user::ui_channel::{self, StatusInfo, StreamTarget, UiMessage}; +use crate::user::ui_channel::{self, StreamTarget}; use crate::subconscious::learn; /// Compaction threshold — context is rebuilt when prompt tokens exceed this. @@ -192,6 +192,17 @@ impl Mind { Self { agent, shared, config, ui_tx, turn_tx, turn_handle: None, turn_watch } } + /// Initialize — restore conversation from log, start background agents. + pub async fn init(&mut self) { + let mut ag = self.agent.lock().await; + ag.restore_from_log(); + drop(ag); + + if !self.config.no_agents { + self.start_memory_scoring(); + } + } + pub fn turn_watch(&self) -> tokio::sync::watch::Receiver { self.turn_watch.subscribe() } @@ -381,23 +392,11 @@ pub async fn run(cli: crate::user::CliArgs) -> Result<()> { let shared_context = ui_channel::shared_context_state(); let shared_active_tools = ui_channel::shared_active_tools(); - // Startup info - let _ = ui_tx.send(UiMessage::Info("consciousness v0.3 (tui)".into())); - let _ = ui_tx.send(UiMessage::Info(format!( - " model: {} (available: {})", config.model, config.app.model_names().join(", "), - ))); let client = ApiClient::new(&config.api_base, &config.api_key, &config.model); - let _ = ui_tx.send(UiMessage::Info(format!(" api: {} ({})", config.api_base, client.backend_label()))); - let _ = ui_tx.send(UiMessage::Info(format!( - " context: {}K chars ({} config, {} memory files)", - config.context_parts.iter().map(|(_, c)| c.len()).sum::() / 1024, - config.config_file_count, config.memory_file_count, - ))); let conversation_log_path = config.session_dir.join("conversation.jsonl"); let conversation_log = log::ConversationLog::new(conversation_log_path.clone()) .expect("failed to create conversation log"); - let _ = ui_tx.send(UiMessage::Info(format!(" log: {}", conversation_log.path().display()))); let agent = Arc::new(Mutex::new(Agent::new( client, @@ -410,37 +409,12 @@ pub async fn run(cli: crate::user::CliArgs) -> Result<()> { shared_active_tools.clone(), ))); - // Restore conversation from log - { - let mut agent_guard = agent.lock().await; - if agent_guard.restore_from_log() { - ui_channel::replay_session_to_ui(agent_guard.entries(), &ui_tx); - let _ = ui_tx.send(UiMessage::Info("--- restored from conversation log ---".into())); - } - } - - // Send initial budget to status bar - { - let agent_guard = agent.lock().await; - let _ = ui_tx.send(UiMessage::StatusUpdate(StatusInfo { - dmn_state: "resting".to_string(), - dmn_turns: 0, dmn_max_turns: 0, - prompt_tokens: 0, completion_tokens: 0, - model: agent_guard.model().to_string(), - turn_tools: 0, - context_budget: agent_guard.budget().status_string(), - })); - } - let (turn_tx, turn_rx) = mpsc::channel::<(Result, StreamTarget)>(1); let no_agents = config.no_agents; 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); - if !no_agents { - mind.start_memory_scoring(); - } + mind.init().await; // Start observation socket let socket_path = mind.config.session_dir.join("agent.sock"); diff --git a/src/user/event_loop.rs b/src/user/event_loop.rs index ccd5a36..6b592d8 100644 --- a/src/user/event_loop.rs +++ b/src/user/event_loop.rs @@ -181,7 +181,6 @@ pub async fn run( mut app: tui::App, agent: Arc>, shared_mind: crate::mind::SharedMindState, - turn_watch: tokio::sync::watch::Receiver, mind_tx: tokio::sync::mpsc::UnboundedSender, ui_tx: ui_channel::UiSender, @@ -202,6 +201,18 @@ pub async fn run( terminal.hide_cursor()?; + // Startup info + let _ = ui_tx.send(UiMessage::Info("consciousness v0.3 (tui)".into())); + { + let ag = agent.lock().await; + let _ = ui_tx.send(UiMessage::Info(format!(" model: {}", ag.model()))); + // Replay restored conversation to UI + if !ag.entries().is_empty() { + ui_channel::replay_session_to_ui(ag.entries(), &ui_tx); + let _ = ui_tx.send(UiMessage::Info("--- restored from conversation log ---".into())); + } + } + // Initial render app.drain_messages(&mut ui_rx); terminal.draw(|f| app.draw(f))?;