Skip to main content

beam_daemon/
daemon_types.rs

1use super::*;
2
3#[derive(Clone)]
4pub struct RunOptions {
5    pub worker_exe: PathBuf,
6}
7
8#[derive(Debug, Clone, serde::Serialize)]
9pub(crate) struct ZellijAdoptCandidate {
10    pub(crate) zellij_session: String,
11    pub(crate) zellij_pane_id: String,
12    pub(crate) title: String,
13    pub(crate) cwd: String,
14    pub(crate) cli_id: String,
15    pub(crate) cli_pid: Option<i32>,
16    pub(crate) pane_cols: Option<u16>,
17    pub(crate) pane_rows: Option<u16>,
18}
19
20#[derive(Debug, Clone, serde::Deserialize)]
21pub(crate) struct AdoptZellijSessionRequest {
22    pub(crate) zellij_session: String,
23    pub(crate) zellij_pane_id: String,
24    pub(crate) cli_id: String,
25    pub(crate) cli_bin: String,
26    pub(crate) title: Option<String>,
27    pub(crate) cwd: String,
28    pub(crate) pane_cols: Option<u16>,
29    pub(crate) pane_rows: Option<u16>,
30    #[serde(default)]
31    pub(crate) lark_app_id: Option<String>,
32    #[serde(default)]
33    pub(crate) chat_id: Option<String>,
34    #[serde(default)]
35    pub(crate) chat_type: Option<String>,
36    #[serde(default)]
37    pub(crate) root_message_id: Option<String>,
38    #[serde(default)]
39    pub(crate) scope: Option<SessionScope>,
40    #[serde(default)]
41    pub(crate) thread_id: Option<String>,
42    #[serde(default)]
43    pub(crate) owner_open_id: Option<String>,
44}
45
46#[derive(Clone)]
47pub(crate) struct AppState {
48    pub(crate) paths: BeamPaths,
49    pub(crate) started_at: chrono::DateTime<Utc>,
50    pub(crate) sessions: Arc<Mutex<HashMap<String, Session>>>,
51    pub(crate) workers: Arc<Mutex<HashMap<String, WorkerHandle>>>,
52    pub(crate) attempt_resumes: Arc<Mutex<HashMap<String, AttemptResumeEntry>>>,
53    pub(crate) shutdown: Arc<Mutex<Option<tokio::sync::oneshot::Sender<()>>>>,
54    pub(crate) options: RunOptions,
55    pub(crate) http: Client,
56    pub(crate) config: Config,
57    pub(crate) bots: Arc<HashMap<String, BotConfig>>,
58    pub(crate) lark_tokens: Arc<Mutex<HashMap<String, CachedLarkToken>>>,
59    pub(crate) chat_mode_cache: Arc<Mutex<HashMap<String, CachedChatMode>>>,
60    pub(crate) recent_lark_events: Arc<Mutex<HashMap<String, Instant>>>,
61    pub(crate) inflight_final_output_turns: Arc<Mutex<HashSet<String>>>,
62    pub(crate) workflow_progress_cards: Arc<Mutex<HashMap<String, String>>>,
63    pub(crate) ask_pending: Arc<Mutex<HashMap<String, ask::AskPendingEntry>>>,
64    pub(crate) grant_pending: Arc<Mutex<HashMap<String, grant::GrantPendingEntry>>>,
65    pub(crate) pending_creates: Arc<Mutex<HashMap<String, dir_select::PendingCreateSession>>>,
66    pub(crate) dashboard_token: Arc<Mutex<Option<DashboardAuthToken>>>,
67    pub(crate) external_host: String,
68}
69
70pub(crate) struct WorkerHandle {
71    pub(crate) child: Child,
72    pub(crate) stdin: Arc<Mutex<ChildStdin>>,
73}
74
75#[derive(Debug, Clone)]
76pub(crate) struct CachedLarkToken {
77    pub(crate) token: String,
78    pub(crate) expires_at: Instant,
79}
80
81#[derive(Debug, Clone)]
82pub(crate) struct CachedChatMode {
83    pub(crate) mode: ChatMode,
84    pub(crate) cached_at: Instant,
85}
86
87#[derive(Debug, Clone)]
88pub(crate) struct DashboardAuthToken {
89    pub(crate) token: String,
90    pub(crate) expires_at: Instant,
91}
92
93#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
94pub(crate) struct AttemptResumeSidecar {
95    pub(crate) schema_version: u64,
96    pub(crate) resume_id: String,
97    pub(crate) run_id: String,
98    pub(crate) activity_id: String,
99    pub(crate) attempt_id: String,
100    pub(crate) session_id: String,
101    pub(crate) original_session_id: String,
102    pub(crate) cli_session_id: Option<String>,
103    pub(crate) web_port: Option<u16>,
104    pub(crate) write_token: Option<String>,
105    pub(crate) status: String,
106    pub(crate) lark_app_id: String,
107    pub(crate) bot_name: Option<String>,
108    pub(crate) cli_id: String,
109    pub(crate) working_dir: String,
110    pub(crate) log_path: String,
111    pub(crate) started_at: u64,
112    pub(crate) updated_at: u64,
113    pub(crate) closed_at: Option<u64>,
114    pub(crate) close_reason: Option<String>,
115}
116
117#[derive(Debug, Clone)]
118pub(crate) struct AttemptResumeEntry {
119    pub(crate) resume_id: String,
120    pub(crate) run_id: String,
121    pub(crate) activity_id: String,
122    pub(crate) attempt_id: String,
123    pub(crate) session_id: String,
124    pub(crate) original_session_id: String,
125    pub(crate) cli_session_id: Option<String>,
126    pub(crate) lark_app_id: String,
127    pub(crate) bot_name: Option<String>,
128    pub(crate) cli_id: String,
129    pub(crate) working_dir: String,
130    pub(crate) log_path: String,
131    pub(crate) sidecar_path: String,
132    pub(crate) started_at: u64,
133    pub(crate) updated_at: u64,
134    pub(crate) web_port: Option<u16>,
135    pub(crate) write_token: Option<String>,
136    pub(crate) close_reason: Option<String>,
137}
138
139#[derive(Debug)]
140pub(crate) enum AttemptResumeWaitOutcome {
141    Ready(AttemptResumeEntry),
142    Failed {
143        error: String,
144        message: Option<String>,
145    },
146}
147
148#[derive(Debug, serde::Deserialize)]
149pub(crate) struct LarkTokenResponse {
150    pub(crate) code: i32,
151    pub(crate) msg: Option<String>,
152    pub(crate) tenant_access_token: Option<String>,
153    pub(crate) expire: Option<u64>,
154}
155
156#[derive(Debug, serde::Deserialize)]
157pub(crate) struct LarkMessageResponse {
158    pub(crate) code: Option<i32>,
159    pub(crate) msg: Option<String>,
160    pub(crate) data: Option<LarkMessageResponseData>,
161}
162
163#[derive(Debug, serde::Deserialize)]
164pub(crate) struct LarkMessageResponseData {
165    pub(crate) message_id: Option<String>,
166}
167
168#[derive(Debug, Clone, serde::Deserialize)]
169pub(crate) struct WorkflowRunRequest {
170    #[serde(default, rename = "rawParams")]
171    pub(crate) raw_params: BTreeMap<String, String>,
172    #[serde(default)]
173    pub(crate) initiator: Option<String>,
174    #[serde(default, rename = "chatBinding")]
175    pub(crate) chat_binding: Option<RunChatBinding>,
176}
177
178#[derive(Debug, Clone, serde::Deserialize, Default)]
179pub(crate) struct WorkflowWindowQuery {
180    #[serde(default)]
181    pub(crate) tail: Option<usize>,
182    #[serde(default, rename = "beforeSeq")]
183    pub(crate) before_seq: Option<u64>,
184    #[serde(default, rename = "afterSeq")]
185    pub(crate) after_seq: Option<u64>,
186    #[serde(default)]
187    pub(crate) limit: Option<usize>,
188}
189
190#[derive(Debug, Clone, serde::Deserialize, Default)]
191pub(crate) struct WorkflowRunsQuery {
192    #[serde(default)]
193    pub(crate) all: Option<String>,
194    #[serde(default)]
195    pub(crate) status: Option<String>,
196}
197
198#[derive(Debug, Clone, serde::Deserialize)]
199pub(crate) struct WorkflowCancelRequest {
200    #[serde(default)]
201    pub(crate) reason: Option<String>,
202}
203
204#[derive(Debug, Clone, serde::Deserialize)]
205pub(crate) struct WorkflowWaitActionRequest {
206    #[serde(default)]
207    pub(crate) comment: Option<String>,
208}
209
210#[derive(Debug, Clone, serde::Deserialize)]
211pub(crate) struct WorkflowResumeRequest {
212    #[serde(default)]
213    pub(crate) reason: Option<String>,
214}
215
216#[derive(Debug, Clone, serde::Deserialize)]
217pub(crate) struct WorkflowRunTriggerBody {
218    #[serde(default, rename = "params")]
219    pub(crate) params: BTreeMap<String, Value>,
220    #[serde(default, rename = "chatBinding")]
221    pub(crate) chat_binding: Option<RunChatBinding>,
222}
223
224#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
225#[serde(rename_all = "camelCase")]
226pub(crate) struct ApiTriggerSource {
227    #[serde(rename = "type")]
228    pub(crate) source_type: String,
229    #[serde(default)]
230    pub(crate) connector_id: Option<String>,
231    #[serde(default)]
232    pub(crate) request_id: Option<String>,
233    #[serde(default)]
234    pub(crate) received_at: Option<String>,
235}
236
237#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
238#[serde(rename_all = "camelCase")]
239pub(crate) struct ApiTriggerTarget {
240    pub(crate) kind: String,
241    #[serde(default)]
242    pub(crate) bot_id: Option<String>,
243    #[serde(default)]
244    pub(crate) chat_id: Option<String>,
245    #[serde(default)]
246    pub(crate) session_id: Option<String>,
247    #[serde(default)]
248    pub(crate) workflow_id: Option<String>,
249}
250
251#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
252#[serde(rename_all = "camelCase")]
253pub(crate) struct ApiTriggerEnvelope {
254    pub(crate) format: String,
255    pub(crate) source_name: String,
256    pub(crate) trusted: bool,
257    #[serde(default)]
258    pub(crate) headers: Option<Value>,
259    #[serde(default)]
260    pub(crate) payload: Option<Value>,
261    #[serde(default)]
262    pub(crate) raw_text: Option<String>,
263}
264
265#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, Default)]
266#[serde(rename_all = "camelCase")]
267pub(crate) struct ApiTriggerOptions {
268    #[serde(default)]
269    pub(crate) dry_run: Option<bool>,
270    #[serde(default)]
271    pub(crate) dedup_key: Option<String>,
272    #[serde(default)]
273    pub(crate) status: Option<String>,
274}
275
276#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
277#[serde(rename_all = "camelCase")]
278pub(crate) struct ApiTriggerRequest {
279    pub(crate) source: ApiTriggerSource,
280    pub(crate) target: ApiTriggerTarget,
281    pub(crate) envelope: ApiTriggerEnvelope,
282    #[serde(default)]
283    pub(crate) options: ApiTriggerOptions,
284}
285
286#[derive(Debug, Clone, serde::Deserialize)]
287pub(crate) struct FeishuResumeInput {
288    #[serde(rename = "larkAppId")]
289    pub(crate) lark_app_id: String,
290    #[serde(rename = "chatId", default)]
291    pub(crate) chat_id: Option<String>,
292    #[serde(rename = "rootMessageId", default)]
293    pub(crate) root_message_id: Option<String>,
294    pub(crate) content: String,
295}
296
297#[derive(Debug, Clone, PartialEq, Eq)]
298pub(crate) struct FeishuResumeOutcome {
299    pub(crate) activity_id: String,
300    pub(crate) attempt_id: String,
301    pub(crate) decision: String,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
305#[serde(rename_all = "camelCase")]
306pub(crate) struct FeishuTransientFailure {
307    pub(crate) activity_id: String,
308    pub(crate) attempt_id: String,
309    pub(crate) provider: String,
310    pub(crate) idempotency_key: String,
311    pub(crate) error_code: String,
312    pub(crate) error_class: String,
313    pub(crate) error_message: String,
314}
315
316#[derive(Debug, Clone, PartialEq, Eq, Default)]
317pub(crate) struct FeishuResumeResult {
318    pub(crate) reconciled: Vec<FeishuResumeOutcome>,
319    pub(crate) fresh_retry: Vec<FeishuResumeOutcome>,
320    pub(crate) transient_failures: Vec<FeishuTransientFailure>,
321    pub(crate) skipped: Vec<String>,
322}
323
324#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
325pub(crate) struct WorkflowFeishuSendInput {
326    #[serde(rename = "larkAppId")]
327    pub(crate) lark_app_id: String,
328    #[serde(rename = "chatId")]
329    pub(crate) chat_id: String,
330    pub(crate) content: String,
331    #[serde(rename = "msgType", default)]
332    pub(crate) _msg_type: Option<String>,
333}
334
335#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
336pub(crate) struct WorkflowFeishuReplyInput {
337    #[serde(rename = "larkAppId")]
338    pub(crate) lark_app_id: String,
339    #[serde(rename = "rootMessageId")]
340    pub(crate) root_message_id: String,
341    pub(crate) content: String,
342    #[serde(rename = "msgType", default)]
343    pub(crate) _msg_type: Option<String>,
344    #[serde(rename = "replyInThread", default)]
345    pub(crate) _reply_in_thread: Option<bool>,
346}
347
348#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
349pub(crate) struct FrozenCard {
350    pub(crate) message_id: String,
351    pub(crate) content: String,
352    pub(crate) title: String,
353    #[serde(default)]
354    pub(crate) display_mode: Option<DisplayMode>,
355    #[serde(default)]
356    pub(crate) image_key: Option<String>,
357}
358
359#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
360pub(crate) struct PendingResponsePatchMarker {
361    pub(crate) session_id: String,
362    pub(crate) card_id: String,
363    pub(crate) state: String,
364    pub(crate) created_at: String,
365    #[serde(default)]
366    pub(crate) patched_at: Option<String>,
367}
368
369pub(crate) const FINAL_OUTPUT_RETRY_BACKOFF_MS: [u64; 3] = [0, 5_000, 15_000];
370
371#[derive(Debug, Clone, Copy, PartialEq, Eq)]
372pub(crate) enum PrivateCardDelivery {
373    Ephemeral,
374    DirectMessage,
375}
376
377#[derive(Debug, Clone, PartialEq, Eq)]
378pub(crate) enum CardRenderTarget {
379    CallbackRaw,
380    PatchMessage(String),
381}
382
383#[derive(Debug, Clone, Copy, PartialEq, Eq)]
384pub(crate) enum LarkCardDeliveryPlan {
385    NotReady,
386    PostNew,
387    PatchExisting,
388}