fix(daemon): register autospawned agent in store for task routing #253

Merged
clawdie merged 1 commit from fix/autospawn-agent-registration into main 2026-06-28 01:07:09 +02:00

View file

@ -630,6 +630,46 @@ pub async fn autospawn_agent_if_configured(state: &SharedState) {
if resp.ok {
info!("autospawn: agent spawned");
// Resolve agent_id from the spawn response for both registration and RPC.
let agent_id = resp
.data
.as_ref()
.and_then(|d| d.get("agent_id"))
.and_then(|v| v.as_str())
.map(str::to_string);
// Register the autospawned agent in the local store so the scheduler
// can route queued tasks to it. Without this, tasks stay stuck in
// "queued" — the scheduler only assigns work to registered agents.
if let Some(ref aid) = agent_id {
let hostname = std::env::var("HOSTNAME").unwrap_or_else(|_| "unknown".to_string());
match state.store.try_lock() {
Ok(store) => {
if let Err(e) = store.register_agent(
aid,
serde_json::json!(["shell", "freebsd", "code"]),
Some(&hostname),
) {
warn!(agent_id = %aid, error = %e, "autospawn: failed to register agent in store");
} else {
info!(agent_id = %aid, hostname = %hostname, "autospawn: agent registered for task work");
}
}
Err(std::sync::TryLockError::WouldBlock) => {
warn!("autospawn: store locked; agent registration deferred");
}
Err(std::sync::TryLockError::Poisoned(e)) => {
if let Err(e) = e.into_inner().register_agent(
aid,
serde_json::json!(["shell", "freebsd", "code"]),
Some(&hostname),
) {
warn!(agent_id = %aid, error = %e, "autospawn: failed to register agent (poisoned store)");
}
}
}
}
// An RPC agent (zot rpc) idles until it gets a prompt on stdin. Send a
// one-time bootstrap so it comes online and emits events — opt-in via
// COLIBRI_AUTOSPAWN_RPC_PROMPT so the default boot spends no tokens.
@ -637,14 +677,6 @@ pub async fn autospawn_agent_if_configured(state: &SharedState) {
.ok()
.filter(|s| !s.trim().is_empty())
{
// Resolve the agent id from the spawn response, then clone the
// RpcSender out and drop the registry guard before the async write.
let agent_id = resp
.data
.as_ref()
.and_then(|d| d.get("agent_id"))
.and_then(|v| v.as_str())
.map(str::to_string);
let sender = agent_id
.as_ref()
.and_then(|id| state.agents.get(id).and_then(|e| e.value().rpc_sender()));