forked from kent/consciousness
Wire AgentCycleState through runner and TUI
Runner owns AgentCycleState, calls trigger() on each user message instead of the old run_hook() JSON round-trip. Sends AgentUpdate messages to TUI after each cycle. TUI F2 screen reads agent state from messages instead of scanning the filesystem on every frame. HookSession::from_fields() lets poc-agent construct sessions without JSON serialization. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
d097c8e067
commit
1c190a3925
5 changed files with 48 additions and 38 deletions
|
|
@ -348,6 +348,8 @@ pub struct App {
|
|||
agent_selected: usize,
|
||||
/// Agent screen: viewing log for selected agent.
|
||||
agent_log_view: bool,
|
||||
/// Agent state from last cycle update.
|
||||
agent_state: Vec<crate::subconscious::hook::AgentInfo>,
|
||||
}
|
||||
|
||||
/// Overlay screens toggled by F-keys.
|
||||
|
|
@ -410,6 +412,7 @@ impl App {
|
|||
shared_context,
|
||||
agent_selected: 0,
|
||||
agent_log_view: false,
|
||||
agent_state: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -508,6 +511,9 @@ impl App {
|
|||
UiMessage::ContextInfoUpdate(info) => {
|
||||
self.context_info = Some(info);
|
||||
}
|
||||
UiMessage::AgentUpdate(agents) => {
|
||||
self.agent_state = agents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1047,41 +1053,27 @@ impl App {
|
|||
lines.push(Line::raw(""));
|
||||
|
||||
for (i, &name) in AGENT_NAMES.iter().enumerate() {
|
||||
let agent_dir = output_dir.join(name);
|
||||
let live = crate::subconscious::knowledge::scan_pid_files(&agent_dir, 0);
|
||||
let selected = i == self.agent_selected;
|
||||
|
||||
let prefix = if selected { "▸ " } else { " " };
|
||||
let bg = if selected { Style::default().bg(Color::DarkGray) } else { Style::default() };
|
||||
|
||||
if live.is_empty() {
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!("{}{:<20}", prefix, name), bg.fg(Color::Gray)),
|
||||
Span::styled("○ idle", bg.fg(Color::DarkGray)),
|
||||
]));
|
||||
} else {
|
||||
for (phase, pid) in &live {
|
||||
let agent = self.agent_state.iter().find(|a| a.name == name);
|
||||
|
||||
match agent.and_then(|a| a.pid) {
|
||||
Some(pid) => {
|
||||
let phase = agent.and_then(|a| a.phase.as_deref()).unwrap_or("?");
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!("{}{:<20}", prefix, name), bg.fg(Color::Green)),
|
||||
Span::styled("● ", bg.fg(Color::Green)),
|
||||
Span::styled(format!("pid {} phase: {}", pid, phase), bg),
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recent output
|
||||
lines.push(Line::raw(""));
|
||||
lines.push(Line::styled("── Recent Activity ──", section));
|
||||
lines.push(Line::raw(""));
|
||||
|
||||
for &name in AGENT_NAMES {
|
||||
let agent_dir = output_dir.join(name);
|
||||
if let Some((file, ago)) = Self::most_recent_file(&agent_dir) {
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!(" {:<20}", name), dim),
|
||||
Span::raw(format!("{} ({})", file, ago)),
|
||||
]));
|
||||
None => {
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(format!("{}{:<20}", prefix, name), bg.fg(Color::Gray)),
|
||||
Span::styled("○ idle", bg.fg(Color::DarkGray)),
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue