bamboo_server/session_app/
types.rs1use std::collections::BTreeSet;
2use std::sync::Arc;
3
4use bamboo_domain::reasoning::ReasoningEffort;
5use bamboo_domain::ProviderModelRef;
6use bamboo_domain::Session;
7use bamboo_engine::ImageFallbackConfig;
8use bamboo_infrastructure::LLMProvider;
9
10#[derive(Clone, Default)]
15pub struct ExecutionConfigSnapshot {
16 pub default_model: Option<String>,
17 pub default_model_ref: Option<ProviderModelRef>,
18 pub default_reasoning_effort: Option<ReasoningEffort>,
19 pub disabled_tools: Vec<String>,
20 pub disabled_skill_ids: Vec<String>,
21 pub provider_name: String,
22 pub provider_type: Option<String>,
23 pub fast_model: Option<String>,
24 pub fast_model_ref: Option<ProviderModelRef>,
25 pub background_model: Option<String>,
26 pub background_model_ref: Option<ProviderModelRef>,
27 pub summarization_model: Option<String>,
28 pub summarization_model_ref: Option<ProviderModelRef>,
29 pub image_fallback: Option<ImageFallbackConfig>,
30 pub provider_model_ref_enabled: bool,
31}
32
33pub struct ChatTurnInput {
37 pub session_id: String,
38 pub model: String,
39 pub model_ref: Option<ProviderModelRef>,
40 pub provider: Option<String>,
41 pub message: String,
42 pub system_prompt: Option<String>,
43 pub enhance_prompt: Option<String>,
44 pub workspace_path: Option<String>,
45 pub selected_skill_ids: Option<Vec<String>>,
46 pub copilot_conclusion_with_options_enhancement_enabled: Option<bool>,
47 pub data_dir: Option<std::path::PathBuf>,
50}
51
52pub struct PreparedChatTurn {
54 pub session: Session,
55}
56
57pub struct ExecuteInput {
61 pub session_id: String,
62 pub request_model: Option<String>,
63 pub request_model_ref: Option<ProviderModelRef>,
64 pub request_provider: Option<String>,
65 pub request_reasoning_effort: Option<ReasoningEffort>,
66 pub request_skill_mode: Option<String>,
67 pub client_sync: Option<ExecuteClientSync>,
68}
69
70#[derive(Debug, Clone)]
72pub struct ExecuteClientSync {
73 pub client_message_count: usize,
74 pub client_last_message_id: Option<String>,
75 pub client_has_pending_question: bool,
76 pub client_pending_question_tool_call_id: Option<String>,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum ExecuteSyncReason {
82 PendingQuestionMismatch,
83 MessageCountMismatch,
84 LastMessageIdMismatch,
85}
86
87impl ExecuteSyncReason {
88 pub fn as_str(&self) -> &'static str {
89 match self {
90 Self::PendingQuestionMismatch => "pending_question_mismatch",
91 Self::MessageCountMismatch => "message_count_mismatch",
92 Self::LastMessageIdMismatch => "last_message_id_mismatch",
93 }
94 }
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct ServerExecuteSnapshot {
100 pub message_count: usize,
101 pub last_message_id: Option<String>,
102 pub has_pending_question: bool,
103 pub pending_question_tool_call_id: Option<String>,
104 pub has_pending_user_message: bool,
105}
106
107#[derive(Debug, Clone)]
109pub struct ExecuteSyncInfo {
110 pub need_sync: bool,
111 pub reason: Option<ExecuteSyncReason>,
112 pub server_message_count: usize,
113 pub server_last_message_id: Option<String>,
114 pub has_pending_question: bool,
115 pub pending_question_tool_call_id: Option<String>,
116 pub has_pending_user_message: bool,
117}
118
119impl ServerExecuteSnapshot {
120 pub fn to_sync_info(&self, reason: Option<ExecuteSyncReason>) -> ExecuteSyncInfo {
121 ExecuteSyncInfo {
122 need_sync: reason.is_some(),
123 reason,
124 server_message_count: self.message_count,
125 server_last_message_id: self.last_message_id.clone(),
126 has_pending_question: self.has_pending_question,
127 pending_question_tool_call_id: self.pending_question_tool_call_id.clone(),
128 has_pending_user_message: self.has_pending_user_message,
129 }
130 }
131}
132
133pub enum ExecutePreparationOutcome {
135 Ready {
137 session: Box<Session>,
138 effective_model: String,
139 effective_reasoning_effort: Option<ReasoningEffort>,
140 model_source: &'static str,
141 reasoning_source: &'static str,
142 is_child_session: bool,
143 },
144 AlreadyRunning {
146 server_snapshot: ServerExecuteSnapshot,
147 },
148 NoPendingMessage {
150 server_snapshot: ServerExecuteSnapshot,
151 },
152 SyncMismatch {
154 reason: ExecuteSyncReason,
155 server_snapshot: ServerExecuteSnapshot,
156 },
157 ModelRequired,
159 ImageFallbackError(String),
161}
162
163pub struct RespondInput {
167 pub session_id: String,
168 pub user_response: String,
169 pub model: Option<String>,
170 pub model_ref: Option<ProviderModelRef>,
171 pub provider: Option<String>,
172 pub reasoning_effort: Option<ReasoningEffort>,
173}
174
175pub struct SubmitResponseOutcome {
177 pub session: Session,
178 pub user_response: String,
179}
180
181#[derive(Clone)]
188pub struct ResumeConfigSnapshot {
189 pub provider_name: String,
190 pub provider_type: Option<String>,
191 pub fast_model: Option<String>,
192 pub fast_model_ref: Option<ProviderModelRef>,
193 pub background_model: Option<String>,
194 pub background_model_ref: Option<ProviderModelRef>,
195 pub background_model_provider: Option<Arc<dyn LLMProvider>>,
196 pub summarization_model: Option<String>,
197 pub summarization_model_ref: Option<ProviderModelRef>,
198 pub summarization_model_provider: Option<Arc<dyn LLMProvider>>,
199 pub disabled_tools: BTreeSet<String>,
200 pub disabled_skill_ids: BTreeSet<String>,
201 pub image_fallback: Option<ImageFallbackConfig>,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq)]
206pub enum ResumeOutcome {
207 Started { run_id: String },
209 AlreadyRunning { run_id: String },
211 Completed,
213 NotFound,
215}
216
217impl ResumeOutcome {
218 pub fn as_str(&self) -> &'static str {
220 self.status_str()
221 }
222
223 pub fn status_str(&self) -> &'static str {
224 match self {
225 Self::Started { .. } => "started",
226 Self::AlreadyRunning { .. } => "already_running",
227 Self::Completed => "completed",
228 Self::NotFound => "error: session not found",
229 }
230 }
231
232 pub fn run_id(&self) -> Option<&String> {
233 match self {
234 Self::Started { run_id } | Self::AlreadyRunning { run_id } => Some(run_id),
235 _ => None,
236 }
237 }
238}