magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
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;
        };
        // A closed modal or changed session must not be revived by a late result.
        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
    }
}