Skip to main content

steer_core/app/domain/
action.rs

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}