Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: relay an agent's hive-free subjects beside the old ones

The terminal and turn-state relays now subscribe to `$SWARM.term.<agent>`
and `$SWARM.agent-state.<agent>`, the subjects a verified agent token is
granted, as well as the hive-scoped `<prefix>.<hive>.<agent>` an agent
still on its hive's shared credential publishes to. Both at once, so a
swarm-ui terminal keeps working whichever credential an agent connected
with and in whatever order hosts deploy.
This commit is contained in:
atlas 2026-09-26 01:42:23 +02:00
commit 0c1fb44a4f
2 changed files with 68 additions and 25 deletions

View file

@ -33,8 +33,8 @@ use crate::AppState;
/// Subject family carrying agent turn-state headers — must match
/// `hive-agent::swarm_agent_state::SUBJECT_PREFIX` exactly, since the two
/// ends never see the constant together. `$SWARM.agent-state.<hive>.<agent>`
/// is the full subject; as with the terminal relay's own copy, there is no
/// ends never see the constant together. `crate::term_stream::agent_subjects`
/// spells the full subjects; as with the terminal relay's own copy, there is no
/// way to check the two sides agree short of this comment and the module
/// docs on both ends staying honest about it.
const SUBJECT_PREFIX: &str = "$SWARM.agent-state";
@ -117,16 +117,12 @@ pub(crate) async fn stream_agent_state(
)
})?;
let subject = format!("{SUBJECT_PREFIX}.{hive}.{agent}");
let subscriber = client.subscribe(subject.clone()).await.map_err(|e| {
tracing::warn!(%subject, error = %e, "state stream: subscribe failed");
crate::error_problem(
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
&format!("subscribing to {subject} failed: {e}"),
)
})?;
tracing::info!(%subject, "state stream: client attached");
let subscriber = crate::term_stream::subscribe_all(
&client,
&crate::term_stream::agent_subjects(SUBJECT_PREFIX, &hive, &agent),
"state",
)
.await?;
let stream =
subscriber.map(|msg| Ok(Event::default().data(String::from_utf8_lossy(&msg.payload))));
Ok(Sse::new(stream).keep_alive(KeepAlive::default()))