use std::{path::PathBuf, sync::Arc};
use super::workspaces::ConfiguredSource;
use crate::mode::ApprovalMode;
use basis_core::{McpServer, PersistedSession, PreparedRun, RunConfig, RunError};
#[async_trait::async_trait]
pub trait SessionSource: Send + Sync + 'static {
async fn create(&self, cwd: PathBuf, mcp: Vec<McpServer>) -> Result<PreparedRun, RunError>;
async fn resume(
&self,
agent_id: &str,
cwd: PathBuf,
mcp: Vec<McpServer>,
) -> Result<PreparedRun, RunError> {
let _ = (agent_id, cwd, mcp);
Err(RunError::NoSuchSession)
}
fn lists_sessions(&self) -> bool {
false
}
async fn list_sessions(&self, cwd: PathBuf) -> Result<Vec<PersistedSession>, RunError> {
let _ = cwd;
Ok(Vec::new())
}
}
#[derive(Clone)]
pub struct ServeConfig {
pub(super) source: Arc<dyn SessionSource>,
pub(super) initial_mode: ApprovalMode,
}
impl std::fmt::Debug for ServeConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ServeConfig")
.field("initial_mode", &self.initial_mode)
.finish_non_exhaustive()
}
}
impl Default for ServeConfig {
fn default() -> Self {
Self::new(None)
}
}
impl ServeConfig {
pub fn new(template: impl Into<Option<RunConfig>>) -> Self {
Self {
source: Arc::new(ConfiguredSource::new(template.into())),
initial_mode: ApprovalMode::default(),
}
}
pub fn with_source(source: impl SessionSource) -> Self {
Self {
source: Arc::new(source),
initial_mode: ApprovalMode::default(),
}
}
pub fn with_initial_mode(self, mode: ApprovalMode) -> Self {
Self {
initial_mode: mode,
..self
}
}
}