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