use std::collections::BTreeSet;
use std::sync::Arc;
use bamboo_domain::reasoning::ReasoningEffort;
use bamboo_domain::ProviderModelRef;
use bamboo_domain::Session;
use bamboo_engine::ImageFallbackConfig;
use bamboo_infrastructure::LLMProvider;
#[derive(Clone, Default)]
pub struct ExecutionConfigSnapshot {
pub default_model: Option<String>,
pub default_model_ref: Option<ProviderModelRef>,
pub default_reasoning_effort: Option<ReasoningEffort>,
pub disabled_tools: Vec<String>,
pub disabled_skill_ids: Vec<String>,
pub provider_name: String,
pub fast_model: Option<String>,
pub fast_model_ref: Option<ProviderModelRef>,
pub image_fallback: Option<ImageFallbackConfig>,
pub provider_model_ref_enabled: bool,
}
pub struct ChatTurnInput {
pub session_id: String,
pub model: String,
pub model_ref: Option<ProviderModelRef>,
pub provider: Option<String>,
pub message: String,
pub system_prompt: Option<String>,
pub enhance_prompt: Option<String>,
pub workspace_path: Option<String>,
pub selected_skill_ids: Option<Vec<String>>,
pub copilot_conclusion_with_options_enhancement_enabled: Option<bool>,
pub data_dir: Option<std::path::PathBuf>,
}
pub struct PreparedChatTurn {
pub session: Session,
}
pub struct ExecuteInput {
pub session_id: String,
pub request_model: Option<String>,
pub request_model_ref: Option<ProviderModelRef>,
pub request_provider: Option<String>,
pub request_reasoning_effort: Option<ReasoningEffort>,
pub request_skill_mode: Option<String>,
pub client_sync: Option<ExecuteClientSync>,
}
#[derive(Debug, Clone)]
pub struct ExecuteClientSync {
pub client_message_count: usize,
pub client_last_message_id: Option<String>,
pub client_has_pending_question: bool,
pub client_pending_question_tool_call_id: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExecuteSyncReason {
PendingQuestionMismatch,
MessageCountMismatch,
LastMessageIdMismatch,
}
impl ExecuteSyncReason {
pub fn as_str(&self) -> &'static str {
match self {
Self::PendingQuestionMismatch => "pending_question_mismatch",
Self::MessageCountMismatch => "message_count_mismatch",
Self::LastMessageIdMismatch => "last_message_id_mismatch",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ServerExecuteSnapshot {
pub message_count: usize,
pub last_message_id: Option<String>,
pub has_pending_question: bool,
pub pending_question_tool_call_id: Option<String>,
pub has_pending_user_message: bool,
}
#[derive(Debug, Clone)]
pub struct ExecuteSyncInfo {
pub need_sync: bool,
pub reason: Option<ExecuteSyncReason>,
pub server_message_count: usize,
pub server_last_message_id: Option<String>,
pub has_pending_question: bool,
pub pending_question_tool_call_id: Option<String>,
pub has_pending_user_message: bool,
}
impl ServerExecuteSnapshot {
pub fn to_sync_info(&self, reason: Option<ExecuteSyncReason>) -> ExecuteSyncInfo {
ExecuteSyncInfo {
need_sync: reason.is_some(),
reason,
server_message_count: self.message_count,
server_last_message_id: self.last_message_id.clone(),
has_pending_question: self.has_pending_question,
pending_question_tool_call_id: self.pending_question_tool_call_id.clone(),
has_pending_user_message: self.has_pending_user_message,
}
}
}
pub enum ExecutePreparationOutcome {
Ready {
session: Box<Session>,
effective_model: String,
effective_reasoning_effort: Option<ReasoningEffort>,
model_source: &'static str,
reasoning_source: &'static str,
is_child_session: bool,
},
AlreadyRunning {
server_snapshot: ServerExecuteSnapshot,
},
NoPendingMessage {
server_snapshot: ServerExecuteSnapshot,
},
SyncMismatch {
reason: ExecuteSyncReason,
server_snapshot: ServerExecuteSnapshot,
},
ModelRequired,
ImageFallbackError(String),
}
pub struct RespondInput {
pub session_id: String,
pub user_response: String,
pub model: Option<String>,
pub model_ref: Option<ProviderModelRef>,
pub provider: Option<String>,
pub reasoning_effort: Option<ReasoningEffort>,
}
pub struct SubmitResponseOutcome {
pub session: Session,
pub user_response: String,
}
#[derive(Clone)]
pub struct ResumeConfigSnapshot {
pub provider_name: String,
pub fast_model: Option<String>,
pub fast_model_ref: Option<ProviderModelRef>,
pub background_model_provider: Option<Arc<dyn LLMProvider>>,
pub disabled_tools: BTreeSet<String>,
pub disabled_skill_ids: BTreeSet<String>,
pub image_fallback: Option<ImageFallbackConfig>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResumeOutcome {
Started,
AlreadyRunning,
Completed,
NotFound,
}
impl ResumeOutcome {
pub fn as_str(&self) -> &'static str {
match self {
Self::Started => "started",
Self::AlreadyRunning => "already_running",
Self::Completed => "completed",
Self::NotFound => "error: session not found",
}
}
}