1use crate::app::domain::types::{
2 CompactionId, MessageId, NonEmptyString, OpId, RequestId, SessionId, ToolCallId,
3};
4use crate::config::model::ModelId;
5use serde::{Deserialize, Serialize};
6use steer_tools::result::ToolResult;
7use steer_tools::{ToolCall, ToolError, ToolSchema};
8
9use super::event::SessionEvent;
10
11#[derive(Debug, Clone)]
12pub enum Action {
13 UserInput {
14 session_id: SessionId,
15 text: NonEmptyString,
16 op_id: OpId,
17 message_id: MessageId,
18 model: ModelId,
19 timestamp: u64,
20 },
21
22 UserEditedMessage {
23 session_id: SessionId,
24 message_id: MessageId,
25 new_content: String,
26 op_id: OpId,
27 new_message_id: MessageId,
28 model: ModelId,
29 timestamp: u64,
30 },
31
32 ToolApprovalRequested {
33 session_id: SessionId,
34 request_id: RequestId,
35 tool_call: ToolCall,
36 },
37
38 ToolApprovalDecided {
39 session_id: SessionId,
40 request_id: RequestId,
41 decision: ApprovalDecision,
42 remember: Option<ApprovalMemory>,
43 },
44
45 ToolExecutionStarted {
46 session_id: SessionId,
47 tool_call_id: ToolCallId,
48 tool_name: String,
49 tool_parameters: serde_json::Value,
50 },
51
52 ToolResult {
53 session_id: SessionId,
54 tool_call_id: ToolCallId,
55 tool_name: String,
56 result: Result<ToolResult, ToolError>,
57 },
58
59 ToolSchemasAvailable {
60 session_id: SessionId,
61 tools: Vec<ToolSchema>,
62 },
63
64 ToolSchemasUpdated {
65 session_id: SessionId,
66 schemas: Vec<ToolSchema>,
67 source: SchemaSource,
68 },
69
70 SwitchPrimaryAgent {
71 session_id: SessionId,
72 agent_id: String,
73 },
74
75 McpServerStateChanged {
76 session_id: SessionId,
77 server_name: String,
78 state: McpServerState,
79 },
80
81 ModelResponseComplete {
82 session_id: SessionId,
83 op_id: OpId,
84 message_id: MessageId,
85 content: Vec<crate::app::conversation::AssistantContent>,
86 timestamp: u64,
87 },
88
89 ModelResponseError {
90 session_id: SessionId,
91 op_id: OpId,
92 error: String,
93 },
94
95 Cancel {
96 session_id: SessionId,
97 op_id: Option<OpId>,
98 },
99
100 DirectBashCommand {
101 session_id: SessionId,
102 op_id: OpId,
103 message_id: MessageId,
104 command: String,
105 timestamp: u64,
106 },
107
108 DequeueQueuedItem {
109 session_id: SessionId,
110 },
111
112 DrainQueuedWork {
113 session_id: SessionId,
114 },
115
116 RequestCompaction {
117 session_id: SessionId,
118 op_id: OpId,
119 model: ModelId,
120 },
121
122 Shutdown,
123
124 Hydrate {
125 session_id: SessionId,
126 events: Vec<SessionEvent>,
127 starting_sequence: u64,
128 },
129
130 WorkspaceFilesListed {
131 session_id: SessionId,
132 files: Vec<String>,
133 },
134
135 CompactionComplete {
136 session_id: SessionId,
137 op_id: OpId,
138 compaction_id: CompactionId,
139 summary_message_id: MessageId,
140 summary: String,
141 compacted_head_message_id: MessageId,
142 previous_active_message_id: Option<MessageId>,
143 model: String,
144 timestamp: u64,
145 },
146
147 CompactionFailed {
148 session_id: SessionId,
149 op_id: OpId,
150 error: String,
151 },
152}
153
154#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
155pub enum ApprovalDecision {
156 Approved,
157 Denied,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub enum ApprovalMemory {
162 Tool(String),
163 BashPattern(String),
164 PendingTool,
165}
166
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub enum SchemaSource {
169 Workspace,
170 Mcp { server_name: String },
171 Backend { backend_name: String },
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub enum McpServerState {
176 Connecting,
177 Connected { tools: Vec<ToolSchema> },
178 Disconnected { error: Option<String> },
179 Failed { error: String },
180}
181
182impl Action {
183 pub fn session_id(&self) -> Option<SessionId> {
184 match self {
185 Action::UserInput { session_id, .. }
186 | Action::UserEditedMessage { session_id, .. }
187 | Action::ToolApprovalRequested { session_id, .. }
188 | Action::ToolApprovalDecided { session_id, .. }
189 | Action::ToolExecutionStarted { session_id, .. }
190 | Action::ToolResult { session_id, .. }
191 | Action::ToolSchemasAvailable { session_id, .. }
192 | Action::ToolSchemasUpdated { session_id, .. }
193 | Action::SwitchPrimaryAgent { session_id, .. }
194 | Action::McpServerStateChanged { session_id, .. }
195 | Action::ModelResponseComplete { session_id, .. }
196 | Action::ModelResponseError { session_id, .. }
197 | Action::Cancel { session_id, .. }
198 | Action::DirectBashCommand { session_id, .. }
199 | Action::DequeueQueuedItem { session_id, .. }
200 | Action::DrainQueuedWork { session_id, .. }
201 | Action::RequestCompaction { session_id, .. }
202 | Action::Hydrate { session_id, .. }
203 | Action::WorkspaceFilesListed { session_id, .. }
204 | Action::CompactionComplete { session_id, .. }
205 | Action::CompactionFailed { session_id, .. } => Some(*session_id),
206 Action::Shutdown => None,
207 }
208 }
209
210 pub fn op_id(&self) -> Option<OpId> {
211 match self {
212 Action::UserInput { op_id, .. }
213 | Action::UserEditedMessage { op_id, .. }
214 | Action::DirectBashCommand { op_id, .. }
215 | Action::RequestCompaction { op_id, .. }
216 | Action::ModelResponseComplete { op_id, .. }
217 | Action::ModelResponseError { op_id, .. }
218 | Action::CompactionComplete { op_id, .. }
219 | Action::CompactionFailed { op_id, .. } => Some(*op_id),
220 Action::Cancel { op_id, .. } => *op_id,
221 _ => None,
222 }
223 }
224}