Skip to main content

steer_core/app/domain/
action.rs

1use crate::api::provider::TokenUsage;
2use crate::app::conversation::UserContent;
3use crate::app::domain::types::{CompactionId, MessageId, OpId, RequestId, SessionId, ToolCallId};
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        content: Vec<UserContent>,
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: Vec<UserContent>,
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        usage: Option<TokenUsage>,
87        context_window_tokens: Option<u32>,
88        timestamp: u64,
89    },
90
91    ModelResponseError {
92        session_id: SessionId,
93        op_id: OpId,
94        error: String,
95    },
96
97    Cancel {
98        session_id: SessionId,
99        op_id: Option<OpId>,
100    },
101
102    DirectBashCommand {
103        session_id: SessionId,
104        op_id: OpId,
105        message_id: MessageId,
106        command: String,
107        timestamp: u64,
108    },
109
110    DequeueQueuedItem {
111        session_id: SessionId,
112    },
113
114    DrainQueuedWork {
115        session_id: SessionId,
116    },
117
118    RequestCompaction {
119        session_id: SessionId,
120        op_id: OpId,
121        model: ModelId,
122    },
123
124    Shutdown,
125
126    Hydrate {
127        session_id: SessionId,
128        events: Vec<SessionEvent>,
129        starting_sequence: u64,
130    },
131
132    WorkspaceFilesListed {
133        session_id: SessionId,
134        files: Vec<String>,
135    },
136
137    CompactionComplete {
138        session_id: SessionId,
139        op_id: OpId,
140        compaction_id: CompactionId,
141        summary_message_id: MessageId,
142        summary: String,
143        compacted_head_message_id: MessageId,
144        previous_active_message_id: Option<MessageId>,
145        model: String,
146        timestamp: u64,
147    },
148
149    CompactionFailed {
150        session_id: SessionId,
151        op_id: OpId,
152        error: String,
153    },
154}
155
156#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
157pub enum ApprovalDecision {
158    Approved,
159    Denied,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize)]
163pub enum ApprovalMemory {
164    Tool(String),
165    BashPattern(String),
166    PendingTool,
167}
168
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub enum SchemaSource {
171    Workspace,
172    Mcp { server_name: String },
173    Backend { backend_name: String },
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub enum McpServerState {
178    Connecting,
179    Connected { tools: Vec<ToolSchema> },
180    Disconnected { error: Option<String> },
181    Failed { error: String },
182}
183
184impl Action {
185    pub fn session_id(&self) -> Option<SessionId> {
186        match self {
187            Action::UserInput { session_id, .. }
188            | Action::UserEditedMessage { session_id, .. }
189            | Action::ToolApprovalRequested { session_id, .. }
190            | Action::ToolApprovalDecided { session_id, .. }
191            | Action::ToolExecutionStarted { session_id, .. }
192            | Action::ToolResult { session_id, .. }
193            | Action::ToolSchemasAvailable { session_id, .. }
194            | Action::ToolSchemasUpdated { session_id, .. }
195            | Action::SwitchPrimaryAgent { session_id, .. }
196            | Action::McpServerStateChanged { session_id, .. }
197            | Action::ModelResponseComplete { session_id, .. }
198            | Action::ModelResponseError { session_id, .. }
199            | Action::Cancel { session_id, .. }
200            | Action::DirectBashCommand { session_id, .. }
201            | Action::DequeueQueuedItem { session_id, .. }
202            | Action::DrainQueuedWork { session_id, .. }
203            | Action::RequestCompaction { session_id, .. }
204            | Action::Hydrate { session_id, .. }
205            | Action::WorkspaceFilesListed { session_id, .. }
206            | Action::CompactionComplete { session_id, .. }
207            | Action::CompactionFailed { session_id, .. } => Some(*session_id),
208            Action::Shutdown => None,
209        }
210    }
211
212    pub fn op_id(&self) -> Option<OpId> {
213        match self {
214            Action::UserInput { op_id, .. }
215            | Action::UserEditedMessage { op_id, .. }
216            | Action::DirectBashCommand { op_id, .. }
217            | Action::RequestCompaction { op_id, .. }
218            | Action::ModelResponseComplete { op_id, .. }
219            | Action::ModelResponseError { op_id, .. }
220            | Action::CompactionComplete { op_id, .. }
221            | Action::CompactionFailed { op_id, .. } => Some(*op_id),
222            Action::Cancel { op_id, .. } => *op_id,
223            _ => None,
224        }
225    }
226}