CLI: async runtime + proper RPC fallback plumbing

- main.rs: use #[tokio::main] so CLI has a runtime available
- memory.rs: make run_with_local_store async (no more runtime creation)
- mcp_server.rs: cache socket connection in OnceLock, use block_in_place
  for async fallback when socket unavailable

Fixes "cannot start a runtime from within a runtime" panic when CLI
falls back to local store.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2026-04-13 11:23:52 -04:00
parent 7476e9d0db
commit dc1049f62d
3 changed files with 96 additions and 55 deletions

View file

@ -58,22 +58,14 @@ async fn cached_store() -> Result<Arc<crate::Mutex<Store>>> {
}
/// Run a tool with a temporarily-opened store (for rpc_local fallback).
pub fn run_with_local_store(tool_name: &str, args: serde_json::Value) -> Result<String> {
let store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
let arc = Arc::new(crate::Mutex::new(store));
pub async fn run_with_local_store(tool_name: &str, args: serde_json::Value) -> Result<String> {
let store = Store::cached().await.map_err(|e| anyhow::anyhow!("{}", e))?;
LOCAL_STORE.with(|s| *s.borrow_mut() = Some(arc));
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
let name = tool_name.to_string();
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(dispatch(&name, &None, args))
}));
LOCAL_STORE.with(|s| *s.borrow_mut() = Some(store));
let result = dispatch(tool_name, &None, args).await;
LOCAL_STORE.with(|s| *s.borrow_mut() = None);
result.map_err(|_| anyhow::anyhow!("tool panicked"))?
result
}
/// Get provenance from agent, or from args._provenance, or "manual".