lash_core/runtime/
config_ops.rs1use crate::SessionError;
8use crate::provider::ProviderHandle;
9
10use super::LashRuntime;
11
12impl LashRuntime {
13 pub fn set_model(&mut self, model: crate::ModelSpec) {
15 self.policy.model = model;
16 self.state.policy.model = self.policy.model.clone();
17 if let Some(frame) = self.state.current_agent_frame_mut() {
18 frame.assignment.policy.model = self.policy.model.clone();
19 }
20 }
21
22 pub fn set_provider(&mut self, provider: ProviderHandle) {
24 self.host.core.providers.provider_resolver =
25 std::sync::Arc::new(crate::SingleProviderResolver::new(provider.clone()));
26 self.policy.provider_id = provider.kind().to_string();
27 self.state.policy.provider_id = self.policy.provider_id.clone();
28 if let Some(frame) = self.state.current_agent_frame_mut() {
29 frame.assignment.policy.provider_id = self.policy.provider_id.clone();
30 }
31 }
32
33 pub fn set_session_id(&mut self, session_id: Option<String>) {
35 self.policy.session_id = session_id;
36 self.state.policy.session_id = self.policy.session_id.clone();
37 if let Some(frame) = self.state.current_agent_frame_mut() {
38 frame.assignment.policy.session_id = self.policy.session_id.clone();
39 }
40 }
41
42 pub async fn update_session_config(
43 &mut self,
44 provider: Option<ProviderHandle>,
45 model: Option<crate::ModelSpec>,
46 prompt: Option<crate::PromptLayer>,
47 ) {
48 let previous = self.session_policy();
49 if let Some(provider) = provider {
50 self.set_provider(provider);
51 }
52 if let Some(model) = model {
53 self.policy.model = model;
54 }
55 if let Some(prompt) = prompt {
56 self.policy.prompt = prompt;
57 }
58 self.state.policy = self.policy.clone();
59 if let Some(frame) = self.state.current_agent_frame_mut() {
60 frame.assignment.policy = self.policy.clone();
61 }
62 let new_max = Some(self.policy.context_window_tokens());
64 let old_max = Some(previous.context_window_tokens());
65 if new_max < old_max {
66 let _ = self
67 .rewrite_history(crate::RewriteTrigger::WindowShrink { old_max, new_max })
68 .await;
69 }
70 self.apply_session_config_mutations(previous.clone()).await;
71 self.notify_session_config_changed(previous).await;
72 }
73
74 pub async fn set_prompt_template(&mut self, template: crate::PromptTemplate) {
75 let mut prompt = self.policy.prompt.clone();
76 prompt.template = Some(template);
77 self.update_session_config(None, None, Some(prompt)).await;
78 }
79
80 pub async fn clear_prompt_template(&mut self) {
81 let mut prompt = self.policy.prompt.clone();
82 prompt.template = None;
83 self.update_session_config(None, None, Some(prompt)).await;
84 }
85
86 pub async fn add_prompt_contribution(&mut self, contribution: crate::PromptContribution) {
87 let mut prompt = self.policy.prompt.clone();
88 prompt.add_contribution(contribution);
89 self.update_session_config(None, None, Some(prompt)).await;
90 }
91
92 pub async fn replace_prompt_slot(
93 &mut self,
94 slot: crate::PromptSlot,
95 contributions: impl IntoIterator<Item = crate::PromptContribution>,
96 ) {
97 let mut prompt = self.policy.prompt.clone();
98 prompt.replace_slot(slot, contributions);
99 self.update_session_config(None, None, Some(prompt)).await;
100 }
101
102 pub async fn clear_prompt_slot(&mut self, slot: crate::PromptSlot) {
103 let mut prompt = self.policy.prompt.clone();
104 prompt.clear_slot(slot);
105 self.update_session_config(None, None, Some(prompt)).await;
106 }
107
108 pub async fn refresh_session_tool_surface(&mut self) -> Result<(), SessionError> {
110 let Some(session) = self.session.as_mut() else {
111 return Err(SessionError::Protocol(
112 "runtime session not available".to_string(),
113 ));
114 };
115 session
116 .plugins()
117 .tool_registry()
118 .refresh_sources()
119 .map_err(|err| SessionError::Protocol(format!("tool refresh failed: {err}")))?;
120 session.refresh_tool_surface().await?;
121 self.stamp_live_plugin_state();
122 Ok(())
123 }
124
125 pub async fn apply_tool_state(
126 &mut self,
127 snapshot: crate::ToolState,
128 ) -> Result<u64, SessionError> {
129 let Some(session) = self.session.as_mut() else {
130 return Err(SessionError::Protocol(
131 "runtime session not available".to_string(),
132 ));
133 };
134 let generation = session
135 .plugins()
136 .tool_registry()
137 .apply_state(snapshot)
138 .map_err(|err| SessionError::Protocol(format!("tool reconfigure failed: {err}")))?;
139 session.refresh_tool_surface().await?;
140 self.stamp_live_plugin_state();
141 Ok(generation)
142 }
143
144 pub async fn restore_tool_state(
152 &mut self,
153 snapshot: crate::ToolState,
154 ) -> Result<u64, SessionError> {
155 let Some(session) = self.session.as_mut() else {
156 return Err(SessionError::Protocol(
157 "runtime session not available".to_string(),
158 ));
159 };
160 let generation = session
161 .plugins()
162 .tool_registry()
163 .restore_state(snapshot)
164 .map_err(|err| SessionError::Protocol(format!("tool restore failed: {err}")))?;
165 session.refresh_tool_surface().await?;
166 self.stamp_live_plugin_state();
167 Ok(generation)
168 }
169}