feat(daemon): dynamic agent capabilities via clawdie-hw-probe --capabilities
Replaces hardcoded ["shell","freebsd","code"] with a call to clawdie-hw-probe --capabilities during autospawn agent registration. probe_capabilities(): - Runs clawdie-hw-probe --capabilities (cross-platform, < 100ms) - Parses the JSON array from stdout: ["shell","freebsd","code"] - Falls back to ["shell","code"] if probe unavailable Platform examples: FreeBSD: ["shell","freebsd","code"] Linux: ["shell","linux","code","vulkan"] This is Phase 1b of the dynamic capabilities plan. The hw-probe change (Phase 1a) is in clawdie-iso feat/hw-probe-capabilities. Phase 2 (T2.x) adds ollama/llama.cpp/cuda detection to the same probe pipeline — no new env vars, no protocol changes.
This commit is contained in:
parent
5d8016eaf0
commit
4e7b9a48e0
1 changed files with 55 additions and 0 deletions
|
|
@ -630,6 +630,43 @@ pub async fn autospawn_agent_if_configured(state: &SharedState) {
|
|||
if resp.ok {
|
||||
info!("autospawn: agent spawned");
|
||||
|
||||
// Register the autospawned agent in the local store so the scheduler
|
||||
// can route queued tasks to it. Capabilities come from hw-probe
|
||||
// (dynamic — not hardcoded per platform).
|
||||
if let Some(ref aid) = resp
|
||||
.data
|
||||
.as_ref()
|
||||
.and_then(|d| d.get("agent_id"))
|
||||
.and_then(|v| v.as_str())
|
||||
{
|
||||
let hostname =
|
||||
std::env::var("HOSTNAME").unwrap_or_else(|_| "unknown".to_string());
|
||||
let caps = probe_capabilities();
|
||||
match state.store.try_lock() {
|
||||
Ok(store) => {
|
||||
if let Err(e) =
|
||||
store.register_agent(aid, serde_json::to_value(&caps).unwrap_or_default(), Some(&hostname))
|
||||
{
|
||||
warn!(agent_id = %aid, error = %e, "autospawn: failed to register agent in store");
|
||||
} else {
|
||||
info!(agent_id = %aid, hostname = %hostname, capabilities = ?caps, "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::to_value(&caps).unwrap_or_default(),
|
||||
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.
|
||||
|
|
@ -853,6 +890,24 @@ async fn try_register_hw_with_mother(hostname: &str, hw_profile: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Run `clawdie-hw-probe --capabilities` to get a dynamic capability list.
|
||||
/// Falls back to a platform-agnostic minimum if the probe is unavailable.
|
||||
fn probe_capabilities() -> Vec<String> {
|
||||
match std::process::Command::new("clawdie-hw-probe")
|
||||
.arg("--capabilities")
|
||||
.output()
|
||||
{
|
||||
Ok(out) if out.status.success() => {
|
||||
if let Ok(caps) = serde_json::from_slice::<Vec<String>>(&out.stdout) {
|
||||
return caps;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// Fallback: minimum capabilities that any zot node has.
|
||||
vec!["shell".to_string(), "code".to_string()]
|
||||
}
|
||||
|
||||
fn basename(path: &str) -> String {
|
||||
std::path::Path::new(path)
|
||||
.file_name()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue