Agents: read-only agent-to-agent observer in the chat card + live agent.message
ci / gates (push) Successful in 5s
ci / rust (push) Failing after 12s
ci / frontend (push) Successful in 26s
ci / e2e (push) Has been skipped

A new "Observe" button (Eye) sits next to "+ New" in the agent chat header; clicking
flips the card into a read-only observer of that agent's conversations with other
agents, updating live as messages happen.

- frontend: AgentObserver (history from /api/claw-chat/* + live agent.message overlay
  filtered to the agent, read-only banner, no composer); ClawChatSection toggle + flip.
- backend: emit a live agent.message run-event when chat.send succeeds — events.rs
  AgentMessage variant, chat.send returns to_id, runtime emits in both tool paths,
  world.rs normalizes agent_message → agent.message SSE. No migration, no new table.

Roadmap (not built): group/multi-party rooms; A2A protocol (a2a-rs) adoption.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-06-27 09:57:29 -07:00
co-authored by Claude Opus 4.8
parent f1f1f4f862
commit 66c4a80985
6 changed files with 228 additions and 3 deletions
+9
View File
@@ -30,6 +30,14 @@ pub enum RunEventBody {
status: String,
output: Value,
},
/// An inter-agent message this run sent via `chat.send` (§7.2). Journaled so
/// the world feed can surface agent-to-agent comms live (the A2A observer).
AgentMessage {
to_agent_id: String,
to_name: String,
text: String,
thread_id: String,
},
/// A gated action awaits human review (§15): carries the exact preview
/// of what will execute, surfaced as the approval card (§10).
ApprovalRequired {
@@ -58,6 +66,7 @@ impl RunEventBody {
RunEventBody::TextDelta { .. } => "text_delta",
RunEventBody::StepStarted { .. } => "step_started",
RunEventBody::StepFinished { .. } => "step_finished",
RunEventBody::AgentMessage { .. } => "agent_message",
RunEventBody::ApprovalRequired { .. } => "approval_required",
RunEventBody::RunSuspended { .. } => "run_suspended",
RunEventBody::RunCompleted { .. } => "run_completed",