use std::path::PathBuf;
use std::sync::Arc;
use lash_trace::{JsonlTraceSink, TraceContext, TraceLevel, TraceSink};
use super::TerminationPolicy;
use super::host::BackgroundTaskHost;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Residency {
#[default]
KeepAll,
ActivePathOnly,
}
#[derive(Clone)]
pub struct RuntimeEnvironment {
pub plugin_host: Option<Arc<crate::PluginHost>>,
pub residency: Residency,
pub background_task_host: Option<Arc<dyn BackgroundTaskHost>>,
pub session_store_factory: Option<Arc<dyn crate::SessionStoreFactory>>,
pub attachment_store: Arc<dyn crate::AttachmentStore>,
pub prompt: crate::PromptLayer,
pub trace_sink: Option<Arc<dyn TraceSink>>,
pub trace_level: TraceLevel,
pub trace_context: TraceContext,
pub termination: TerminationPolicy,
}
impl Default for RuntimeEnvironment {
fn default() -> Self {
Self {
plugin_host: None,
residency: Residency::default(),
background_task_host: None,
session_store_factory: None,
attachment_store: Arc::new(crate::InMemoryAttachmentStore::new()),
prompt: crate::PromptLayer::new(),
trace_sink: None,
trace_level: TraceLevel::Standard,
trace_context: TraceContext::default(),
termination: TerminationPolicy::default(),
}
}
}
impl RuntimeEnvironment {
pub fn builder() -> RuntimeEnvironmentBuilder {
RuntimeEnvironmentBuilder::default()
}
}
pub struct ParkedSession {
pub(crate) session_id: String,
pub(crate) store: Arc<dyn crate::store::RuntimePersistence>,
pub(crate) policy: crate::SessionPolicy,
}
impl ParkedSession {
pub fn session_id(&self) -> &str {
&self.session_id
}
}
#[derive(Default)]
pub struct RuntimeEnvironmentBuilder {
env: RuntimeEnvironment,
}
impl RuntimeEnvironmentBuilder {
pub fn with_plugin_host(mut self, host: Arc<crate::PluginHost>) -> Self {
self.env.plugin_host = Some(if self.env.background_task_host.is_some() {
Arc::new(host.as_ref().clone().with_background_tasks())
} else {
host
});
self
}
pub fn with_residency(mut self, residency: Residency) -> Self {
self.env.residency = residency;
self
}
pub fn with_background_task_host(
mut self,
background_task_host: Arc<dyn BackgroundTaskHost>,
) -> Self {
self.env.background_task_host = Some(background_task_host);
if let Some(host) = self.env.plugin_host.take() {
self.env.plugin_host = Some(Arc::new(host.as_ref().clone().with_background_tasks()));
}
self
}
pub fn with_session_store_factory(
mut self,
factory: Arc<dyn crate::SessionStoreFactory>,
) -> Self {
self.env.session_store_factory = Some(factory);
self
}
pub fn with_attachment_store(mut self, store: Arc<dyn crate::AttachmentStore>) -> Self {
self.env.attachment_store = store;
self
}
pub fn with_prompt_template(mut self, template: crate::PromptTemplate) -> Self {
self.env.prompt.template = Some(template);
self
}
pub fn with_prompt_contribution(mut self, contribution: crate::PromptContribution) -> Self {
self.env.prompt.add_contribution(contribution);
self
}
pub fn with_replaced_prompt_slot(
mut self,
slot: crate::PromptSlot,
contributions: impl IntoIterator<Item = crate::PromptContribution>,
) -> Self {
self.env.prompt.replace_slot(slot, contributions);
self
}
pub fn with_cleared_prompt_slot(mut self, slot: crate::PromptSlot) -> Self {
self.env.prompt.clear_slot(slot);
self
}
pub fn with_prompt_layer(mut self, prompt: crate::PromptLayer) -> Self {
self.env.prompt = prompt;
self
}
pub fn with_trace_jsonl_path(mut self, path: Option<PathBuf>) -> Self {
self.env.trace_sink = path.map(|p| Arc::new(JsonlTraceSink::new(p)) as Arc<dyn TraceSink>);
self
}
pub fn with_trace_sink(mut self, sink: Option<Arc<dyn TraceSink>>) -> Self {
self.env.trace_sink = sink;
self
}
pub fn with_trace_level(mut self, level: TraceLevel) -> Self {
self.env.trace_level = level;
self
}
pub fn with_trace_context(mut self, context: TraceContext) -> Self {
self.env.trace_context = context;
self
}
pub fn with_termination(mut self, termination: TerminationPolicy) -> Self {
self.env.termination = termination;
self
}
pub fn build(self) -> RuntimeEnvironment {
self.env
}
}