Skip to main content

agentmux_srv/backend/subagent_watcher/
events.rs

1// Copyright 2026, AgentMux Corp.
2// SPDX-License-Identifier: Apache-2.0
3
4//! The subagent watcher's events, as typed payloads (`mps_events`). Each serializes exactly the
5//! camelCase JSON the watcher built by hand before.
6
7use serde::Serialize;
8
9use super::types::{DispatchKind, DispatchStatus, SubagentEvent};
10
11/// `subagent:activity`: new events from one subagent.
12#[derive(Debug, Clone, Serialize, ts_rs::TS)]
13#[ts(export, export_to = "../../../frontend/types/rpc/")]
14#[serde(rename_all = "camelCase")]
15pub struct SubagentActivityEvent {
16    pub agent_id: String,
17    pub parent_agent: String,
18    pub parent_block_id: String,
19    #[ts(type = "number")]
20    pub new_events: usize,
21    #[ts(type = "number")]
22    pub total_events: usize,
23    pub events: Vec<SubagentEvent>,
24    pub dispatch_id: String,
25}
26
27/// One member's new events in a `dispatch:activity` flush.
28#[derive(Debug, Clone, Serialize, ts_rs::TS)]
29#[ts(export, export_to = "../../../frontend/types/rpc/")]
30#[serde(rename_all = "camelCase")]
31pub struct DispatchMemberEvents {
32    pub agent_id: String,
33    pub events: Vec<SubagentEvent>,
34}
35
36/// `dispatch:activity`: a workflow dispatch's coalesced new events.
37#[derive(Debug, Clone, Serialize, ts_rs::TS)]
38#[ts(export, export_to = "../../../frontend/types/rpc/")]
39#[serde(rename_all = "camelCase")]
40pub struct DispatchActivityEvent {
41    pub dispatch_id: String,
42    pub parent_agent: String,
43    pub parent_block_id: String,
44    pub session_id: String,
45    #[ts(type = "number")]
46    pub new_events: usize,
47    pub members: Vec<DispatchMemberEvents>,
48}
49
50/// `subagent:spawned`.
51#[derive(Debug, Clone, Serialize, ts_rs::TS)]
52#[ts(export, export_to = "../../../frontend/types/rpc/")]
53#[serde(rename_all = "camelCase")]
54pub struct SubagentSpawnedEvent {
55    pub agent_id: String,
56    pub slug: String,
57    pub parent_agent: String,
58    pub parent_block_id: String,
59    pub session_id: String,
60    /// Null when the transcript doesn't say.
61    pub model: Option<String>,
62    pub dispatch_id: String,
63}
64
65/// `subagent:completed`. Completion found by a scan doesn't know the parent agent's name.
66#[derive(Debug, Clone, Serialize, ts_rs::TS)]
67#[ts(export, export_to = "../../../frontend/types/rpc/")]
68#[serde(rename_all = "camelCase")]
69pub struct SubagentCompletedEvent {
70    pub agent_id: String,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    #[ts(optional)]
73    pub parent_agent: Option<String>,
74    pub parent_block_id: String,
75    #[ts(type = "number")]
76    pub total_events: usize,
77    pub dispatch_id: String,
78}
79
80/// `subagent:named`: a subagent got its display name.
81#[derive(Debug, Clone, Serialize, ts_rs::TS)]
82#[ts(export, export_to = "../../../frontend/types/rpc/")]
83#[serde(rename_all = "camelCase")]
84pub struct SubagentNamedEvent {
85    pub agent_id: String,
86    pub display_name: String,
87}
88
89/// `subagent:updated`: something about a subagent changed; refetch it.
90#[derive(Debug, Clone, Serialize, ts_rs::TS)]
91#[ts(export, export_to = "../../../frontend/types/rpc/")]
92#[serde(rename_all = "camelCase")]
93pub struct SubagentUpdatedEvent {
94    pub agent_id: String,
95    pub parent_block_id: String,
96}
97
98/// `dispatch:updated`: a dispatch's membership or status.
99#[derive(Debug, Clone, Serialize, ts_rs::TS)]
100#[ts(export, export_to = "../../../frontend/types/rpc/")]
101#[serde(rename_all = "camelCase")]
102pub struct DispatchUpdatedEvent {
103    pub dispatch_id: String,
104    pub kind: DispatchKind,
105    pub parent_agent: String,
106    pub parent_block_id: String,
107    pub session_id: String,
108    #[ts(type = "number")]
109    pub member_count: usize,
110    #[ts(type = "number")]
111    pub members_done: usize,
112    pub status: DispatchStatus,
113    pub dispatch_name: Option<String>,
114}
115
116/// `subagent:abandoned`: subagents of a pane cut off without finishing.
117#[derive(Debug, Clone, Serialize, ts_rs::TS)]
118#[ts(export, export_to = "../../../frontend/types/rpc/")]
119#[serde(rename_all = "camelCase")]
120pub struct SubagentAbandonedEvent {
121    pub parent_block_id: String,
122    pub agent_ids: Vec<String>,
123}
124
125/// `subagent:block_pruned`: a pane's subagents are gone with the pane.
126#[derive(Debug, Clone, Serialize, ts_rs::TS)]
127#[ts(export, export_to = "../../../frontend/types/rpc/")]
128#[serde(rename_all = "camelCase")]
129pub struct SubagentBlockPrunedEvent {
130    pub block_id: String,
131}
132
133/// `subagent:backfill_status`: a resumed pane's subagent backfill started or finished.
134#[derive(Debug, Clone, Serialize, ts_rs::TS)]
135#[ts(export, export_to = "../../../frontend/types/rpc/")]
136pub struct SubagentBackfillStatusEvent {
137    #[ts(type = r#""started" | "done""#)]
138    pub status: String,
139}