Shared forked agent — UI reads subconscious entries live
The forked agent is now behind Arc<tokio::sync::Mutex<Agent>>, stored on SubconsciousAgent and passed to the spawned task. The subconscious detail screen locks it via try_lock() to read entries from the fork point — live during runs, persisted after completion. Removes last_run_entries snapshot. Backend::Forked now holds the shared Arc, all push operations go through the lock. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
77b68ecc50
commit
93f5f8b0c7
3 changed files with 78 additions and 81 deletions
|
|
@ -285,15 +285,19 @@ const AGENTS: &[(&str, u64)] = &[
|
|||
("subconscious-reflect", 100_000), // every ~100KB of conversation
|
||||
];
|
||||
|
||||
/// Lightweight snapshot for the TUI.
|
||||
#[derive(Clone, Default)]
|
||||
/// Snapshot for the TUI — includes a handle to the forked agent
|
||||
/// so the detail view can read entries live.
|
||||
#[derive(Clone)]
|
||||
pub struct SubconsciousSnapshot {
|
||||
pub name: String,
|
||||
pub running: bool,
|
||||
pub current_phase: String,
|
||||
pub turn: usize,
|
||||
pub last_run_secs_ago: Option<f64>,
|
||||
pub last_run_entries: Vec<ConversationEntry>,
|
||||
/// Shared handle to the forked agent — UI locks to read entries.
|
||||
pub forked_agent: Option<Arc<tokio::sync::Mutex<crate::agent::Agent>>>,
|
||||
/// Entry index where the fork diverged.
|
||||
pub fork_point: usize,
|
||||
}
|
||||
|
||||
struct SubconsciousAgent {
|
||||
|
|
@ -301,7 +305,11 @@ struct SubconsciousAgent {
|
|||
auto: AutoAgent,
|
||||
last_trigger_bytes: u64,
|
||||
last_run: Option<Instant>,
|
||||
last_run_entries: Vec<ConversationEntry>,
|
||||
/// The forked agent for the current/last run. Shared with the
|
||||
/// spawned task so the UI can read entries live.
|
||||
forked_agent: Option<Arc<tokio::sync::Mutex<crate::agent::Agent>>>,
|
||||
/// Entry index where the fork diverged from the conscious agent.
|
||||
fork_point: usize,
|
||||
handle: Option<tokio::task::JoinHandle<(AutoAgent, Result<String, String>)>>,
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +339,7 @@ impl SubconsciousAgent {
|
|||
Some(Self {
|
||||
name: name.to_string(),
|
||||
auto, last_trigger_bytes: 0, last_run: None,
|
||||
last_run_entries: Vec::new(), handle: None,
|
||||
forked_agent: None, fork_point: 0, handle: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -352,7 +360,8 @@ impl SubconsciousAgent {
|
|||
current_phase: self.auto.current_phase.clone(),
|
||||
turn: self.auto.turn,
|
||||
last_run_secs_ago: self.last_run.map(|t| t.elapsed().as_secs_f64()),
|
||||
last_run_entries: self.last_run_entries.clone(),
|
||||
forked_agent: self.forked_agent.clone(),
|
||||
fork_point: self.fork_point,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -393,7 +402,6 @@ impl Subconscious {
|
|||
let (auto_back, result) = handle.await.unwrap_or_else(
|
||||
|e| (AutoAgent::new(String::new(), vec![], vec![], 0.0, 0),
|
||||
Err(format!("task panicked: {}", e))));
|
||||
self.agents[idx].last_run_entries = auto_back.last_run_entries.clone();
|
||||
self.agents[idx].auto = auto_back;
|
||||
|
||||
match result {
|
||||
|
|
@ -490,11 +498,17 @@ impl Subconscious {
|
|||
dbglog!("[subconscious] triggering {}", auto.name);
|
||||
|
||||
let forked = conscious.fork(auto.tools.clone());
|
||||
let fork_point = forked.context.entries.len();
|
||||
let shared_forked = Arc::new(tokio::sync::Mutex::new(forked));
|
||||
|
||||
self.agents[idx].forked_agent = Some(shared_forked.clone());
|
||||
self.agents[idx].fork_point = fork_point;
|
||||
|
||||
let keys = memory_keys.clone();
|
||||
let w = walked.clone();
|
||||
|
||||
self.agents[idx].handle = Some(tokio::spawn(async move {
|
||||
let result = auto.run_forked(&forked, &keys, &w).await;
|
||||
let result = auto.run_forked_shared(&shared_forked, &keys, &w).await;
|
||||
(auto, result)
|
||||
}));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue