use super::super::*;
use super::MissionControlApp;
struct SystemPromptWorker {
generation: u64,
handle: super::completion_worker::CompletionWorker<String>,
}
#[derive(Default)]
pub(super) struct SystemPromptRuntime {
worker: Option<SystemPromptWorker>,
}
impl SystemPromptRuntime {
pub(super) fn is_pending(&self) -> bool {
self.worker.is_some()
}
pub(super) fn cleanup(&mut self) -> Vec<String> {
let Some(worker) = self.worker.take() else {
return Vec::new();
};
let deadline = Instant::now() + WORKER_EXIT_JOIN_TIMEOUT;
while !worker.handle.is_finished() && Instant::now() < deadline {
thread::sleep(Duration::from_millis(5));
}
if !worker.handle.is_finished() {
return vec!["system prompt preparation did not finish before shutdown".into()];
}
worker.handle.join().err().into_iter().collect()
}
}
impl MissionControlApp {
pub(super) fn start_system_prompt_preparation(&mut self, ui: &mut state::MissionControlState) {
if self.system_prompt.is_pending() {
ui.status = "system prompt preparation already in progress".into();
return;
}
let mut run_config = self
.state
.config
.clone()
.unwrap_or_else(|| self.config.clone());
run_config.model = Some(self.state.model.clone());
let disabled_tools = self.disabled_tools.clone();
let disabled_profiles = self.disabled_subagent_profiles.clone();
let discovery = self.subagent_profile_discovery.clone();
let instructions = self.instructions.clone();
let skills = self.skills.clone();
let primary_agent = ui.selected_primary_agent_profile();
let handle =
super::completion_worker::CompletionWorker::spawn(
"magi-system-prompt",
self.events.clone(),
move || {
let disabled_tools = disabled_tools
.lock()
.map(|disabled| disabled.clone())
.unwrap_or_else(|_| {
crate::tools::MVP_TOOL_CAPABILITIES
.iter()
.map(|tool| tool.canonical_name().to_string())
.collect()
});
let disabled_profiles = disabled_profiles
.lock()
.map(|disabled| disabled.clone())
.map_err(|_| "disabled subagent profiles lock poisoned".to_string())?;
let discovery = crate::subagents::profiles::filter_enabled_profiles(
&discovery,
&disabled_profiles,
);
let section =
if disabled_tools.contains(crate::tools::contract::tool_name::SUBAGENTS) {
None
} else {
crate::subagents::profiles::render_subagent_profiles_prompt(
Some(&run_config.paths.prompts),
&discovery,
)
.map_err(|error| error.to_string())?
};
let agent = crate::agent::AgentSession::new_with_prompt_dir_and_subagents(
run_config
.model
.clone()
.unwrap_or_else(|| crate::providers::DEFAULT_CODEX_MODEL.to_string()),
Some(&run_config.paths.prompts),
&instructions,
&skills,
section.as_deref(),
)
.map_err(|error| error.to_string())?;
let agent = append_primary_agent_to_main_prompt(agent, primary_agent.as_ref());
let prompt = agent.system_prompt();
let provider_id = run_config.provider_id();
let model = run_config.model.as_deref().unwrap_or_else(|| {
crate::providers::default_model_for_provider(provider_id)
});
let count = crate::context::project_text_tokens(provider_id, model, prompt);
let max_tokens = crate::config::load_context_budget(&run_config)
.unwrap_or_default()
.max_tokens;
let percent = count.tokens.saturating_mul(100) / max_tokens.max(1);
Ok(format!(
"~{} tokens / {} max ({}%)\n\n{}",
count.tokens, max_tokens, percent, prompt
))
},
);
match handle {
Ok(handle) => {
self.system_prompt.worker = Some(SystemPromptWorker {
generation: self.session_generation,
handle,
});
ui.open_system_prompt_modal("Preparing system prompt…".into());
ui.status = "preparing system prompt…".into();
}
Err(error) => ui.status = format!("failed to start system prompt preparation: {error}"),
}
}
pub(in crate::tui) fn reconcile_system_prompt_worker(
&mut self,
ui: &mut state::MissionControlState,
) -> bool {
let Some(worker) = self.system_prompt.worker.as_mut() else {
return false;
};
let result = worker.handle.take_result();
let generation = worker.generation;
if worker.handle.ready_to_reap()
&& let Some(worker) = self.system_prompt.worker.take()
{
let _ = worker.handle.join();
}
let Some(result) = result else {
return false;
};
if generation != self.session_generation || !ui.system_prompt_modal_visible() {
return false;
}
match result {
Ok(prompt) => {
ui.open_system_prompt_modal(prompt);
ui.status = "showing current computed system prompt".into();
}
Err(error) => {
ui.open_system_prompt_modal(format!("Failed to compute system prompt: {error}"));
ui.status = "failed to compute system prompt".into();
}
}
true
}
}