Topology executor: accept a durable ZEROCLAW_TOKEN (skip one-time pairing)
ZeroClaw pairing codes are single-use, so a static ZEROCLAW_PAIRING_CODE only works for the first run. Add ZEROCLAW_TOKEN: pair once out-of-band, set the durable bearer, and runs are repeatable. PAIRING_CODE stays as a fallback; one of the two is required. Validated live on gw-04: a single-node pipeline driven through the deployed authed POST /api/topologies/run drove a real ZeroClaw role-agent over /ws/chat and returned a RunRecord with real output + token metering, persisted to topology_runs. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6d77a0acc1
commit
d1409a0776
@@ -62,26 +62,29 @@ impl ZeroClawDriveExecutor {
|
|||||||
|
|
||||||
/// Build from the environment:
|
/// Build from the environment:
|
||||||
/// - `ZEROCLAW_GATEWAY_URL` (required) e.g. `http://127.0.0.1:42617`
|
/// - `ZEROCLAW_GATEWAY_URL` (required) e.g. `http://127.0.0.1:42617`
|
||||||
/// - `ZEROCLAW_PAIRING_CODE` (required)
|
/// - `ZEROCLAW_TOKEN` (preferred) a durable bearer token — pair once
|
||||||
|
/// out-of-band, set this, and runs are repeatable. If set, no pairing.
|
||||||
|
/// - `ZEROCLAW_PAIRING_CODE` (fallback) a one-time pairing code — consumed
|
||||||
|
/// on first use, so only good for a single run. One of TOKEN/CODE required.
|
||||||
/// - `ZEROCLAW_AGENT_MAP` (optional) `role=alias,role=alias`
|
/// - `ZEROCLAW_AGENT_MAP` (optional) `role=alias,role=alias`
|
||||||
/// - `ZEROCLAW_DEFAULT_AGENT` (optional, default `scout`)
|
/// - `ZEROCLAW_DEFAULT_AGENT` (optional, default `scout`)
|
||||||
pub fn from_env() -> Result<Self, String> {
|
pub fn from_env() -> Result<Self, String> {
|
||||||
let gateway_url =
|
let gateway_url =
|
||||||
std::env::var("ZEROCLAW_GATEWAY_URL").map_err(|_| "ZEROCLAW_GATEWAY_URL not set")?;
|
std::env::var("ZEROCLAW_GATEWAY_URL").map_err(|_| "ZEROCLAW_GATEWAY_URL not set")?;
|
||||||
let pairing_code =
|
let token = std::env::var("ZEROCLAW_TOKEN").ok().filter(|t| !t.is_empty());
|
||||||
std::env::var("ZEROCLAW_PAIRING_CODE").map_err(|_| "ZEROCLAW_PAIRING_CODE not set")?;
|
let pairing_code = std::env::var("ZEROCLAW_PAIRING_CODE").unwrap_or_default();
|
||||||
|
if token.is_none() && pairing_code.is_empty() {
|
||||||
|
return Err("set ZEROCLAW_TOKEN or ZEROCLAW_PAIRING_CODE".to_string());
|
||||||
|
}
|
||||||
let default_alias =
|
let default_alias =
|
||||||
std::env::var("ZEROCLAW_DEFAULT_AGENT").unwrap_or_else(|_| "scout".to_string());
|
std::env::var("ZEROCLAW_DEFAULT_AGENT").unwrap_or_else(|_| "scout".to_string());
|
||||||
let role_aliases = std::env::var("ZEROCLAW_AGENT_MAP")
|
let role_aliases = std::env::var("ZEROCLAW_AGENT_MAP")
|
||||||
.ok()
|
.ok()
|
||||||
.map(|s| parse_agent_map(&s))
|
.map(|s| parse_agent_map(&s))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
Ok(Self::new(
|
let mut exec = Self::new(gateway_url, pairing_code, role_aliases, default_alias);
|
||||||
gateway_url,
|
exec.token = Arc::new(Mutex::new(token));
|
||||||
pairing_code,
|
Ok(exec)
|
||||||
role_aliases,
|
|
||||||
default_alias,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alias_for(&self, role: &str) -> String {
|
fn alias_for(&self, role: &str) -> String {
|
||||||
|
|||||||
Reference in New Issue
Block a user