codetether_agent/tui/app/event_loop/
mod.rs1mod autochat;
18mod select_loop;
19mod shutdown;
20mod smart_retry;
21mod terminal;
22mod watchdog;
23mod watchdog_spawn;
24
25use std::{path::Path, sync::Arc, time::Duration};
26
27use crossterm::event::EventStream;
28use ratatui::{Terminal, backend::CrosstermBackend};
29use tokio::sync::mpsc;
30
31use crate::bus::BusHandle;
32use crate::provider::ProviderRegistry;
33use crate::session::{Session, SessionEvent};
34use crate::tui::app::{state::App, worker_bridge::sync_worker_bridge_agents};
35use crate::tui::{
36 constants::MAIN_PROCESSING_WATCHDOG_TIMEOUT_SECS, ui::main::ui, worker_bridge::TuiWorkerBridge,
37};
38
39pub async fn run_event_loop(
54 terminal: &mut Terminal<CrosstermBackend<std::io::Stdout>>,
55 app: &mut App,
56 cwd: &Path,
57 registry: Option<Arc<ProviderRegistry>>,
58 session: &mut Session,
59 bus_handle: &mut BusHandle,
60 mut worker_bridge: Option<TuiWorkerBridge>,
61 event_tx: mpsc::Sender<SessionEvent>,
62 mut event_rx: mpsc::Receiver<SessionEvent>,
63 result_tx: mpsc::Sender<anyhow::Result<Session>>,
64 mut result_rx: mpsc::Receiver<anyhow::Result<Session>>,
65) -> anyhow::Result<()> {
66 let mut reader = EventStream::new();
67 let mut shutdown_rx = crate::tui::app::signal_shutdown::spawn_shutdown_listener();
68 let tick = Duration::from_millis(50);
69 let mut tick_timer = tokio::time::interval(tick);
70 let wd_interval = Duration::from_secs(MAIN_PROCESSING_WATCHDOG_TIMEOUT_SECS);
71 let mut wd_timer = tokio::time::interval(wd_interval);
72
73 loop {
74 sync_worker_bridge_agents(app, &worker_bridge);
75 terminal.draw(|f| ui(f, app, session))?;
76 if select_loop::select_once(
77 &mut reader,
78 app,
79 cwd,
80 session,
81 ®istry,
82 &mut worker_bridge,
83 &event_tx,
84 &result_tx,
85 &mut event_rx,
86 &mut result_rx,
87 &mut shutdown_rx,
88 &mut wd_timer,
89 wd_interval,
90 &mut tick_timer,
91 bus_handle,
92 )
93 .await?
94 {
95 break;
96 }
97 }
98
99 shutdown::deregister_bridge(&worker_bridge);
100 Ok(())
101}