harn_vm/agent_events/worker.rs
1use serde::{Deserialize, Serialize};
2
3/// Structured terminal outcome for one delegated sub-agent run.
4#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub enum SubagentTerminalStatus {
7 Success,
8 Failure,
9 Cancellation,
10 Timeout,
11}
12
13/// One coalesced filesystem notification from a hostlib `fs_watch`
14/// subscription.
15#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct FsWatchEvent {
17 pub kind: String,
18 pub paths: Vec<String>,
19 pub relative_paths: Vec<String>,
20 pub raw_kind: String,
21 pub error: Option<String>,
22}
23
24/// Typed worker lifecycle events emitted by delegated/background agent
25/// execution. Bridge-facing worker updates still derive a string status
26/// from these variants, but the runtime no longer passes raw status
27/// strings around internally.
28///
29/// `Spawned`/`Completed`/`Failed`/`Stopped`/`Cancelled` are the terminal-or-start
30/// states. `Progressed` is fired on intermediate milestones (e.g. a
31/// retriggerable worker resuming from `awaiting_input`, or a workflow
32/// stage completing without ending the worker). `WaitingForInput` covers
33/// retriggerable workers that finish a cycle but stay alive pending the
34/// next host-supplied trigger payload. `Suspended`/`Resumed` cover
35/// cooperative mid-loop pause and warm resume (harn#1836); the
36/// `agent_loop` honors the pause signal at the next turn boundary,
37/// distinct from a graceful `Stopped` handoff or hard `Cancelled` interrupt.
38#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
39pub enum WorkerEvent {
40 WorkerSpawned,
41 WorkerProgressed,
42 WorkerWaitingForInput,
43 WorkerSuspended,
44 WorkerResumed,
45 WorkerCompleted,
46 WorkerFailed,
47 WorkerStopped,
48 WorkerCancelled,
49}
50
51impl WorkerEvent {
52 /// The full set of `WorkerEvent` variants in canonical order. Mirrors
53 /// the pattern used by `ToolCallStatus::ALL` so the protocol-artifact
54 /// dumper can enumerate worker status wire values without
55 /// special-casing each lifecycle event.
56 pub const ALL: [Self; 9] = [
57 Self::WorkerSpawned,
58 Self::WorkerProgressed,
59 Self::WorkerWaitingForInput,
60 Self::WorkerSuspended,
61 Self::WorkerResumed,
62 Self::WorkerCompleted,
63 Self::WorkerFailed,
64 Self::WorkerStopped,
65 Self::WorkerCancelled,
66 ];
67
68 /// Wire-level status string used by bridge `worker_update` payloads
69 /// and ACP `worker_update` session updates. The four canonical
70 /// states are mirrored from harn's internal worker `status` field
71 /// (`running`/`completed`/`failed`/`cancelled`), and the four newer
72 /// lifecycle states pick names that don't collide with any existing
73 /// status string.
74 pub fn as_status(self) -> &'static str {
75 match self {
76 Self::WorkerSpawned => "running",
77 Self::WorkerProgressed => "progressed",
78 Self::WorkerWaitingForInput => "awaiting_input",
79 Self::WorkerSuspended => "suspended",
80 Self::WorkerResumed => "running",
81 Self::WorkerCompleted => "completed",
82 Self::WorkerFailed => "failed",
83 Self::WorkerStopped => "stopped",
84 Self::WorkerCancelled => "cancelled",
85 }
86 }
87
88 pub fn as_str(self) -> &'static str {
89 match self {
90 Self::WorkerSpawned => "WorkerSpawned",
91 Self::WorkerProgressed => "WorkerProgressed",
92 Self::WorkerWaitingForInput => "WorkerWaitingForInput",
93 Self::WorkerSuspended => "WorkerSuspended",
94 Self::WorkerResumed => "WorkerResumed",
95 Self::WorkerCompleted => "WorkerCompleted",
96 Self::WorkerFailed => "WorkerFailed",
97 Self::WorkerStopped => "WorkerStopped",
98 Self::WorkerCancelled => "WorkerCancelled",
99 }
100 }
101
102 /// True for lifecycle events that mean the worker has reached a
103 /// final, non-resumable state. Retriggerable awaiting, progressed,
104 /// and cooperative suspend/resume milestones are *not* terminal —
105 /// the worker keeps running, is waiting for a trigger, or is parked
106 /// awaiting an external resume.
107 pub fn is_terminal(self) -> bool {
108 matches!(
109 self,
110 Self::WorkerCompleted
111 | Self::WorkerFailed
112 | Self::WorkerStopped
113 | Self::WorkerCancelled
114 )
115 }
116}