feat(telemetry): WORKING ON NOW shows the mission an agent is on
deploy / test (push) Successful in 4m10s
deploy / build (push) Successful in 5m13s

The last of the three declared-but-never-emitted event types.
`agent.task.update` had no producer anywhere in the backend, so the card read
"idle — no active task" for an agent that was mid-turn.

Derived rather than newly instrumented: an agent is working on its crew's
RUNNING mission, and that mission's phases are the steps (completed/skipped →
done, running/evaluating → active, else pending). Nothing is emitted for an
agent with no running mission, so "idle" stays truthful rather than freezing on
a stale last-known task.

Verified on a live mission: 116 agent.task.update events observed on
/api/world/live, carrying the mission title and phase steps, with the state
advancing pending → active as the phase started.

That closes the set. Of the seven cards in the command centre, five were dark:
three had no emitter at all and two read a table the mission path never wrote.
DOORS and LOOPS were correctly wired the whole time and were reporting an honest
zero.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-08-15 16:03:42 -07:00
co-authored by Claude Opus 5
parent bf40d10064
commit ba9d7aa185
+63
View File
@@ -1164,6 +1164,69 @@ pub async fn world_live(
}
}
// WORKING ON NOW — the third card that was declared, listened for,
// and never emitted. `agent.task.update` has no producer anywhere in
// the backend, so the card read "idle" for an agent mid-turn.
//
// Derived rather than newly instrumented: an agent is working on its
// crew's RUNNING mission, and that mission's phases are the steps.
// Nothing is emitted for an agent with no running mission, so "idle"
// stays truthful instead of becoming a stale last-known task.
{
let rows = sqlx::query(
"SELECT tm.claw_id AS agent_id, m.id AS mission_id, m.title,
p.kind, p.status, p.order_idx
FROM team_members tm
JOIN mission_teams mt ON mt.team_id = tm.team_id
JOIN missions m ON m.id = mt.mission_id
JOIN mission_phases p ON p.mission_id = m.id
WHERE m.workspace_id = $1 AND m.status = 'running'
ORDER BY tm.claw_id, p.order_idx",
)
.bind(ws.as_uuid())
.fetch_all(&pool)
.await
.unwrap_or_default();
let mut cur: Option<(uuid::Uuid, uuid::Uuid, String)> = None;
let mut steps: Vec<serde_json::Value> = Vec::new();
let mut flush = |cur: &Option<(uuid::Uuid, uuid::Uuid, String)>,
steps: &Vec<serde_json::Value>|
-> Option<serde_json::Value> {
let (agent_id, mission_id, title) = cur.as_ref()?;
Some(json!({
"agentId": agent_id.to_string(),
"taskId": mission_id.to_string(),
"title": title,
"steps": steps,
}))
};
for r in &rows {
let agent_id: uuid::Uuid = r.get("agent_id");
let mission_id: uuid::Uuid = r.get("mission_id");
let title: String = r.get("title");
if cur.as_ref().map(|c| c.0) != Some(agent_id) {
if let Some(v) = flush(&cur, &steps) {
yield sse("agent.task.update", v);
}
steps = Vec::new();
cur = Some((agent_id, mission_id, title));
}
let status: String = r.get("status");
let kind: String = r.get("kind");
steps.push(json!({
"label": kind,
"state": match status.as_str() {
"completed" | "skipped" => "done",
"running" | "evaluating" => "active",
_ => "pending",
},
}));
}
if let Some(v) = flush(&cur, &steps) {
yield sse("agent.task.update", v);
}
}
// Workspace-wide telemetry (top-bar pills / Observe system strip).
yield sse(
"telemetry",