Fix TUI: show GyanDoot banner + wire live agent responses

Two bugs fixed:

1. Banner not shown: TUI default output was a plain welcome text
   instead of the actual GyanDoot banner. Fixed by using
   banner::banner_plain() as initial TUI output content.

2. No agent responses: TUI was a standalone shell with no connection
   to the agent loop. Now uses mpsc channels:
   - user_tx: TUI → agent (user sends messages)
   - event_rx: agent → TUI (agent sends responses + telemetry)
   - TuiEvent::Response / Status / Telemetry enum for structured
     communication
   - tokio::spawn runs agent in background processing messages
   - poll_events() in render loop drains channel every frame tick

Also updated cmd_tui() in main to create channels + spawn agent.
This commit is contained in:
2026-06-12 12:47:26 +05:30
parent 73bd24dcfb
commit 93040d4fb0
2 changed files with 196 additions and 227 deletions

View File

@@ -551,10 +551,54 @@ async fn cmd_setup() -> anyhow::Result<()> {
Ok(())
}
/// Launch the TUI interface
/// Launch the TUI interface with a live agent loop
async fn cmd_tui() -> anyhow::Result<()> {
tracing::info!("Launching TUI");
gyandoot_tui::tui::run_tui()?;
tracing::info!("Launching TUI with live agent");
// Print banner to stdout too (for logs/terminal buffer)
gyandoot_tui::banner::print_banner();
// Load agent config
let config = load_agent_config();
// Create channels for TUI ↔ agent communication
let (user_tx, mut user_rx) = tokio::sync::mpsc::channel::<String>(256);
let (event_tx, event_rx) = tokio::sync::mpsc::channel::<gyandoot_tui::tui::TuiEvent>(256);
// Spawn agent task
let agent = gyandoot_agent::agent_loop::AgentLoop::new(config);
let agent_event_tx = event_tx.clone();
tokio::spawn(async move {
// Send initial telemetry
let _ = agent_event_tx.send(gyandoot_tui::tui::TuiEvent::Status("AGENT READY".to_string())).await;
// Process messages from TUI
while let Some(user_msg) = user_rx.recv().await {
let _ = agent_event_tx.send(gyandoot_tui::tui::TuiEvent::Status("PROCESSING...".to_string())).await;
match agent.run_conversation(&user_msg).await {
Ok(output) => {
let _ = agent_event_tx.send(gyandoot_tui::tui::TuiEvent::Telemetry {
provider: "—".to_string(), // populated from config
model: "—".to_string(),
total_tokens: 0,
max_tokens: 4096,
msg_count: 0,
}).await;
let _ = agent_event_tx.send(gyandoot_tui::tui::TuiEvent::Response(output.text)).await;
}
Err(e) => {
let _ = agent_event_tx.send(gyandoot_tui::tui::TuiEvent::Status(
format!("ERROR: {}", e)
)).await;
}
}
}
});
// Run TUI (this blocks until user quits)
gyandoot_tui::tui::run_tui(event_rx, user_tx).await?;
tracing::info!("TUI closed");
Ok(())
}