Agent/AgentState split complete — separate context and state locks
Agent is now Arc<Agent> (immutable config). ContextState and AgentState have separate tokio::sync::Mutex locks. The parser locks only context, tool dispatch locks only state. No contention between the two. All callers migrated: mind/, user/, tools/, oneshot, dmn, learn. 28 tests pass, zero errors. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
1d61b091b0
commit
0b9813431a
8 changed files with 156 additions and 159 deletions
|
|
@ -179,9 +179,9 @@ async fn start(cli: crate::user::CliArgs) -> Result<()> {
|
|||
let (turn_tx, turn_rx) = tokio::sync::mpsc::channel(1);
|
||||
let (mind_tx, mind_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let mind = crate::mind::Mind::new(config, turn_tx);
|
||||
let mind = crate::mind::Mind::new(config, turn_tx).await;
|
||||
|
||||
let shared_active_tools = mind.agent.lock().await.active_tools.clone();
|
||||
let shared_active_tools = mind.agent.state.lock().await.active_tools.clone();
|
||||
|
||||
let mut result = Ok(());
|
||||
tokio_scoped::scope(|s| {
|
||||
|
|
@ -203,7 +203,7 @@ async fn start(cli: crate::user::CliArgs) -> Result<()> {
|
|||
}
|
||||
|
||||
fn hotkey_cycle_reasoning(mind: &crate::mind::Mind) {
|
||||
if let Ok(mut ag) = mind.agent.try_lock() {
|
||||
if let Ok(mut ag) = mind.agent.state.try_lock() {
|
||||
let next = match ag.reasoning_effort.as_str() {
|
||||
"none" => "low",
|
||||
"low" => "high",
|
||||
|
|
@ -221,17 +221,17 @@ fn hotkey_cycle_reasoning(mind: &crate::mind::Mind) {
|
|||
}
|
||||
|
||||
async fn hotkey_kill_processes(mind: &crate::mind::Mind) {
|
||||
let mut ag = mind.agent.lock().await;
|
||||
let active_tools = ag.active_tools.clone();
|
||||
let mut st = mind.agent.state.lock().await;
|
||||
let active_tools = st.active_tools.clone();
|
||||
let mut tools = active_tools.lock().unwrap();
|
||||
if tools.is_empty() {
|
||||
ag.notify("no running tools");
|
||||
st.notify("no running tools");
|
||||
} else {
|
||||
let count = tools.len();
|
||||
for entry in tools.drain(..) {
|
||||
entry.handle.abort();
|
||||
}
|
||||
ag.notify(format!("killed {} tools", count));
|
||||
st.notify(format!("killed {} tools", count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ fn hotkey_cycle_autonomy(mind: &crate::mind::Mind) {
|
|||
};
|
||||
s.dmn_turns = 0;
|
||||
drop(s);
|
||||
if let Ok(mut ag) = mind.agent.try_lock() {
|
||||
if let Ok(mut ag) = mind.agent.state.try_lock() {
|
||||
ag.notify(format!("DMN → {}", label));
|
||||
}
|
||||
}
|
||||
|
|
@ -325,13 +325,13 @@ async fn run(
|
|||
}
|
||||
});
|
||||
|
||||
let agent_changed = agent.lock().await.changed.clone();
|
||||
let agent_changed = agent.state.lock().await.changed.clone();
|
||||
let mut turn_watch = mind.turn_watch();
|
||||
let mut pending: Vec<ratatui::crossterm::event::Event> = Vec::new();
|
||||
|
||||
terminal.hide_cursor()?;
|
||||
|
||||
if let Ok(mut ag) = agent.try_lock() { ag.notify("consciousness v0.3"); }
|
||||
if let Ok(mut ag) = agent.state.try_lock() { ag.notify("consciousness v0.3"); }
|
||||
|
||||
// Initial render
|
||||
{
|
||||
|
|
@ -378,8 +378,8 @@ async fn run(
|
|||
app.agent_state = mind.subconscious_snapshots().await;
|
||||
app.walked_count = mind.subconscious_walked().await.len();
|
||||
if !startup_done {
|
||||
if let Ok(mut ag) = agent.try_lock() {
|
||||
let model = ag.model().to_string();
|
||||
if let Ok(mut ag) = agent.state.try_lock() {
|
||||
let model = agent.model().to_string();
|
||||
ag.notify(format!("model: {}", model));
|
||||
startup_done = true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue