From 3fd485a2e9eedc8c4fb5f87298cead5baeeadee7 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sat, 21 Mar 2026 15:04:47 -0400 Subject: [PATCH] cli: route agent run through daemon RPC when available Previously 'poc-memory agent run --count N' always ran locally, loading the full store and executing synchronously. This was slow and bypassed the daemon's concurrency control and persistent task queue. Now the CLI checks for a running daemon first and queues via RPC (returning instantly) unless --local, --debug, or --dry-run is set. Falls back to local execution if the daemon isn't running. This also avoids the expensive Store::load() on the fast path. Co-Authored-By: Claude Opus 4.6 (1M context) --- poc-memory/src/cli/agent.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/poc-memory/src/cli/agent.rs b/poc-memory/src/cli/agent.rs index b5ad55b..27beaa7 100644 --- a/poc-memory/src/cli/agent.rs +++ b/poc-memory/src/cli/agent.rs @@ -8,6 +8,19 @@ pub fn cmd_run_agent(agent: &str, count: usize, target: &[String], query: Option // SAFETY: single-threaded at this point (CLI startup, before any agent work) unsafe { std::env::set_var("POC_MEMORY_DRY_RUN", "1"); } } + + let needs_local = local || debug || dry_run; + let has_targets = !target.is_empty() || query.is_some(); + + // Fast path: no explicit targets, daemon available — just queue via RPC + if !needs_local && !has_targets { + if crate::agents::daemon::send_rpc_pub("ping").is_some() { + return crate::agents::daemon::rpc_run_agent(agent, count); + } + eprintln!("Daemon not running — falling back to local execution"); + } + + // Slow path: need the store for local execution or target resolution let mut store = store::Store::load()?; let log = |msg: &str| eprintln!("[{}] {}", agent, msg); @@ -30,8 +43,8 @@ pub fn cmd_run_agent(agent: &str, count: usize, target: &[String], query: Option if !resolved_targets.is_empty() { // --local or daemon unavailable: run directly - if local || crate::agents::daemon::send_rpc_pub("ping").is_none() { - if !local { + if needs_local || crate::agents::daemon::send_rpc_pub("ping").is_none() { + if !needs_local { eprintln!("Daemon not running — falling back to local execution"); } for (i, key) in resolved_targets.iter().enumerate() { @@ -55,13 +68,10 @@ pub fn cmd_run_agent(agent: &str, count: usize, target: &[String], query: Option } } eprintln!("[{}] queued {} tasks to daemon", agent, queued); - } else if debug { - crate::agents::knowledge::run_one_agent( - &mut store, agent, count, "test", &log, true, - )?; } else { - crate::agents::knowledge::run_and_apply_with_log( - &mut store, agent, count, "test", &log, + // Local execution (--local, --debug, dry-run, or daemon unavailable) + crate::agents::knowledge::run_one_agent( + &mut store, agent, count, "test", &log, debug, )?; } Ok(())