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