WIP: Output tool via Arc<Mutex<Subconscious>>, ToolHandler to Arc<dyn Fn>

- ToolHandler changed to Arc<dyn Fn(...)> (supports closures)
- Subconscious wrapped in Arc<Mutex<>> on Mind
- init_output_tool() pushes output tool closure capturing the Arc
- Output removed from static memory_tools()
- Most tool handlers wrapped in Arc::new() but some have paren issues

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-08 20:37:19 -04:00
parent d167b11283
commit 12798eeae2
15 changed files with 74 additions and 51 deletions

View file

@ -9,7 +9,7 @@ pub(super) fn tools() -> [super::Tool; 3] {
Tool { name: "switch_model",
description: "Switch to a different LLM model mid-conversation. Memories and history carry over.",
parameters_json: r#"{"type":"object","properties":{"model":{"type":"string","description":"Name of the model to switch to"}},"required":["model"]}"#,
handler: |agent, v| Box::pin(async move {
handler: Arc::new(|agent, v| Box::pin(async move {
let model = v.get("model").and_then(|v| v.as_str())
.ok_or_else(|| anyhow::anyhow!("'model' parameter is required"))?;
if model.is_empty() { anyhow::bail!("'model' parameter cannot be empty"); }
@ -22,7 +22,7 @@ pub(super) fn tools() -> [super::Tool; 3] {
Tool { name: "pause",
description: "Pause all autonomous behavior. Only the user can unpause (Ctrl+P or /wake).",
parameters_json: r#"{"type":"object","properties":{}}"#,
handler: |agent, _v| Box::pin(async move {
handler: Arc::new(|agent, _v| Box::pin(async move {
if let Some(agent) = agent {
let mut a = agent.state.lock().await;
a.pending_yield = true;
@ -33,7 +33,7 @@ pub(super) fn tools() -> [super::Tool; 3] {
Tool { name: "yield_to_user",
description: "Wait for user input before continuing. The only way to enter a waiting state.",
parameters_json: r#"{"type":"object","properties":{"message":{"type":"string","description":"Optional status message"}}}"#,
handler: |agent, v| Box::pin(async move {
handler: Arc::new(|agent, v| Box::pin(async move {
let msg = v.get("message").and_then(|v| v.as_str()).unwrap_or("Waiting for input.");
if let Some(agent) = agent {
let mut a = agent.state.lock().await;