1use std::sync::Arc;
2use std::sync::Mutex;
3
4use lash_trace::{TraceContext, TraceLevel, TraceSink};
5
6use super::process::ProcessRegistry;
7use super::{
8 EffectHost, InlineEffectHost, ProcessWorkPoke, QueuedWorkPoke, SessionStoreFactory,
9 TerminationPolicy,
10};
11
12#[derive(Clone)]
14pub struct RuntimeHostConfig {
15 pub profile: RuntimeHostProfileConfig,
16 pub durability: RuntimeDurabilityConfig,
17 pub providers: RuntimeProviderConfig,
18 pub prompt: RuntimePromptConfig,
19 pub control: RuntimeControlConfig,
20 pub tracing: RuntimeTracingConfig,
21}
22
23#[derive(Clone)]
24pub struct RuntimeHostProfileConfig {
25 pub host_profile_id: String,
26}
27
28#[derive(Clone)]
29pub struct RuntimeDurabilityConfig {
30 pub attachment_store: Arc<dyn crate::AttachmentStore>,
31 pub lashlang_artifact_store: Arc<dyn lashlang::LashlangArtifactStore>,
32 pub lashlang_process_cache: Arc<Mutex<lashlang::CompiledProcessCache>>,
33}
34
35#[derive(Clone)]
36pub struct RuntimeProviderConfig {
37 pub provider_resolver: Arc<dyn crate::RuntimeProviderResolver>,
38}
39
40#[derive(Clone)]
41pub struct RuntimePromptConfig {
42 pub prompt: crate::PromptLayer,
43}
44
45#[derive(Clone)]
46pub struct RuntimeControlConfig {
47 pub effect_host: Arc<dyn EffectHost>,
48 pub process_cancel_ability: Arc<dyn crate::ProcessCancelAbility>,
49 pub termination: TerminationPolicy,
50}
51
52#[derive(Clone)]
53pub struct RuntimeTracingConfig {
54 pub trace_sink: Option<Arc<dyn TraceSink>>,
55 pub lashlang_execution_sink: Option<Arc<dyn TraceSink>>,
56 pub trace_level: TraceLevel,
57 pub trace_context: TraceContext,
58}
59
60impl RuntimeHostConfig {
61 pub fn new(
70 effect_host: Arc<dyn EffectHost>,
71 lashlang_artifact_store: Arc<dyn lashlang::LashlangArtifactStore>,
72 attachment_store: Arc<dyn crate::AttachmentStore>,
73 ) -> Self {
74 Self {
75 profile: RuntimeHostProfileConfig {
76 host_profile_id: "default".to_string(),
77 },
78 durability: RuntimeDurabilityConfig {
79 attachment_store,
80 lashlang_artifact_store,
81 lashlang_process_cache: Arc::new(Mutex::new(lashlang::CompiledProcessCache::new())),
82 },
83 providers: RuntimeProviderConfig {
84 provider_resolver: Arc::new(crate::EmptyProviderResolver),
85 },
86 prompt: RuntimePromptConfig {
87 prompt: crate::PromptLayer::new(),
88 },
89 control: RuntimeControlConfig {
90 termination: TerminationPolicy::default(),
91 effect_host,
92 process_cancel_ability: Arc::new(crate::DefaultProcessCancelAbility),
93 },
94 tracing: RuntimeTracingConfig {
95 trace_sink: None,
96 lashlang_execution_sink: None,
97 trace_level: TraceLevel::Standard,
98 trace_context: TraceContext::default(),
99 },
100 }
101 }
102
103 pub fn in_memory() -> Self {
110 Self::new(
111 Arc::new(InlineEffectHost::default()),
112 lashlang::global_in_memory_lashlang_artifact_store(),
113 Arc::new(crate::InMemoryAttachmentStore::new()),
114 )
115 }
116
117 pub fn with_process_cancel_ability(
118 mut self,
119 process_cancel_ability: Arc<dyn crate::ProcessCancelAbility>,
120 ) -> Self {
121 self.control.process_cancel_ability = process_cancel_ability;
122 self
123 }
124}
125
126#[derive(Clone)]
128pub struct EmbeddedRuntimeHost {
129 pub core: RuntimeHostConfig,
130 pub session_store_factory: Option<Arc<dyn SessionStoreFactory>>,
131 pub host_event_store: Option<Arc<dyn crate::HostEventStore>>,
132}
133
134impl EmbeddedRuntimeHost {
135 pub fn new(core: RuntimeHostConfig) -> Self {
136 Self {
137 core,
138 session_store_factory: None,
139 host_event_store: Some(Arc::new(crate::InMemoryHostEventStore::default())),
140 }
141 }
142
143 pub fn with_session_store_factory(
144 mut self,
145 session_store_factory: Arc<dyn SessionStoreFactory>,
146 ) -> Self {
147 self.session_store_factory = Some(session_store_factory);
148 self
149 }
150
151 pub fn with_host_event_store(mut self, store: Arc<dyn crate::HostEventStore>) -> Self {
152 self.host_event_store = Some(store);
153 self
154 }
155}
156
157#[derive(Clone)]
159pub struct ProcessRuntimeHost {
160 pub embedded: EmbeddedRuntimeHost,
161 pub process_registry: Arc<dyn ProcessRegistry>,
162}
163
164impl ProcessRuntimeHost {
165 pub fn new(embedded: EmbeddedRuntimeHost, process_registry: Arc<dyn ProcessRegistry>) -> Self {
166 Self {
167 embedded,
168 process_registry,
169 }
170 }
171}
172
173#[derive(Clone)]
174pub(crate) struct RuntimeHost {
175 pub core: RuntimeHostConfig,
176 pub session_store_factory: Option<Arc<dyn SessionStoreFactory>>,
177 pub host_event_store: Option<Arc<dyn crate::HostEventStore>>,
178 pub process_registry: Option<Arc<dyn ProcessRegistry>>,
179 pub process_work_poke: Option<ProcessWorkPoke>,
183 pub queued_work_poke: Option<QueuedWorkPoke>,
186}
187
188impl RuntimeHost {
189 pub(crate) fn resolve_session_policy(
190 &self,
191 session_id: &str,
192 policy: crate::SessionPolicy,
193 ) -> Result<crate::RuntimeSessionPolicy, crate::SessionError> {
194 let provider_id = policy.recorded_provider_id();
195 let binding = self
196 .core
197 .providers
198 .provider_resolver
199 .resolve_provider_binding(provider_id)
200 .map_err(|err| match err {
201 crate::ProviderResolutionError::MissingProviderId => {
202 crate::SessionError::ProviderUnconfigured {
203 session_id: session_id.to_string(),
204 }
205 }
206 crate::ProviderResolutionError::UnknownProvider { provider_id } => {
207 crate::SessionError::ProviderUnavailable {
208 provider_id,
209 session_id: session_id.to_string(),
210 }
211 }
212 crate::ProviderResolutionError::ProviderIdMismatch { expected, actual } => {
213 crate::SessionError::ProviderMismatch {
214 expected,
215 actual,
216 session_id: session_id.to_string(),
217 }
218 }
219 })?;
220 Ok(crate::RuntimeSessionPolicy::new(policy, binding))
221 }
222}
223
224impl From<EmbeddedRuntimeHost> for RuntimeHost {
225 fn from(value: EmbeddedRuntimeHost) -> Self {
226 Self {
227 core: value.core,
228 session_store_factory: value.session_store_factory,
229 host_event_store: value.host_event_store,
230 process_registry: None,
231 process_work_poke: None,
232 queued_work_poke: None,
233 }
234 }
235}
236
237impl From<ProcessRuntimeHost> for RuntimeHost {
238 fn from(value: ProcessRuntimeHost) -> Self {
239 Self {
240 core: value.embedded.core,
241 session_store_factory: value.embedded.session_store_factory,
242 host_event_store: value.embedded.host_event_store,
243 process_registry: Some(value.process_registry),
244 process_work_poke: None,
245 queued_work_poke: None,
246 }
247 }
248}