diff --git a/hive-ag3nt/src/bin/hive-ag3nt.rs b/hive-ag3nt/src/bin/hive-ag3nt.rs index ee6fd0c..48def74 100644 --- a/hive-ag3nt/src/bin/hive-ag3nt.rs +++ b/hive-ag3nt/src/bin/hive-ag3nt.rs @@ -76,7 +76,7 @@ async fn main() -> Result<()> { let turn_lock: TurnLock = Arc::new(tokio::sync::Mutex::new(())); plugins::install_configured(&cli.socket, Some("manager")).await; tokio::spawn(web_ui::serve( - label, + label.clone(), port, login_state.clone(), bus.clone(), @@ -93,6 +93,7 @@ async fn main() -> Result<()> { bus, &files, turn_lock, + &label, ) .await } @@ -108,6 +109,7 @@ async fn main() -> Result<()> { bus, &files, turn_lock, + &label, ) .await } @@ -143,6 +145,7 @@ async fn serve( bus: Bus, files: &turn::TurnFiles, turn_lock: TurnLock, + label: &str, ) -> Result<()> { tracing::info!(socket = %socket.display(), "hive-ag3nt serve"); let _ = state; // reserved for future state transitions (turn-loop -> needs-login) @@ -182,7 +185,7 @@ async fn serve( // manager so it can investigate / restart / page the // operator; best-effort, swallow the send error. if let turn::TurnOutcome::Failed(e) = &outcome { - notify_manager_of_failure(socket, e).await; + notify_manager_of_failure(socket, label, e).await; } // After turn completes, check if there are pending messages waiting. @@ -235,13 +238,15 @@ fn format_wake_prompt(from: &str, body: &str, unread: u64) -> String { /// Best-effort: tell the manager that this agent's last turn crashed /// (claude exited non-zero, compaction didn't help, etc.). Routed /// through the normal send path so the manager's inbox surfaces it -/// like any other message; the agent's label is what the broker -/// stamps as `from`, so the message body doesn't need to repeat it. -/// Swallows transport errors — we just logged the failure, the worst -/// case is the manager learns about the crash from the dashboard -/// instead of inbox. -async fn notify_manager_of_failure(socket: &Path, err: &anyhow::Error) { - let body = format!("claude turn failed:\n{err:#}"); +/// as a system-style event; `label` is included explicitly in the +/// body so the manager can identify the failing agent without having +/// to look at the `from` field (which is broker-stamped and may +/// differ from what the operator sees in the dashboard). Swallows +/// transport errors — we just logged the failure, the worst case is +/// the manager learns about the crash from the dashboard instead of +/// inbox. +async fn notify_manager_of_failure(socket: &Path, label: &str, err: &anyhow::Error) { + let body = format!("[system] agent `{label}` claude turn failed:\n{err:#}"); let res = client::request::<_, AgentResponse>( socket, &AgentRequest::Send { diff --git a/hive-ag3nt/src/bin/hive-m1nd.rs b/hive-ag3nt/src/bin/hive-m1nd.rs index 9d89038..89eab9f 100644 --- a/hive-ag3nt/src/bin/hive-m1nd.rs +++ b/hive-ag3nt/src/bin/hive-m1nd.rs @@ -158,7 +158,8 @@ async fn serve( ManagerResponse::Ok | ManagerResponse::Status { .. } | ManagerResponse::QuestionQueued { .. } - | ManagerResponse::Recent { .. }, + | ManagerResponse::Recent { .. } + | ManagerResponse::Logs { .. }, ) => { tracing::warn!("recv produced unexpected response kind"); }