magi-code 0.102.1

Repository-aware CLI coding agent for terminal work
Documentation
use crate::{
    config::{EffectiveConfig, Settings},
    providers::{
        ChatMessage, ProviderEvent, ProviderRequest, ProviderSelection,
        provider_from_selection_with_settings_for_workload,
    },
};
use std::{path::Path, thread, time::Duration};

const MAX_OUTPUT_BYTES: usize = 1024 * 1024;
const PROMPT: &str = include_str!("../../prompts/progressive_event_summaries.md");

pub(crate) fn summarize_records(
    config: &EffectiveConfig,
    settings: &Settings,
    cwd: &Path,
    records: &[&str],
    status: &mut crate::sessions::progressive_summaries::Status,
) -> anyhow::Result<String> {
    let raw_records = records.join(",\n");
    status.batch(records.len(), raw_records.len() + 2);
    let mut selected = match (&settings.psm.provider, &settings.psm.model) {
        (Some(provider), Some(model)) => {
            crate::auth::load_effective_provider_selection(&config.paths, provider, model)?
        }
        _ => config.clone(),
    };
    selected.thinking_level = settings.psm.reasoning.unwrap_or(config.thinking_level);
    let selection = ProviderSelection::from_config(&selected)?;
    status.selection(&selection);
    let provider = provider_from_selection_with_settings_for_workload(
        &selected,
        &selection,
        cwd,
        settings,
        crate::providers::FastWorkload::ProgressiveSessionMaintenance,
    )?;
    let request = ProviderRequest::new_without_tools(
        selection.model,
        vec![
            ChatMessage::system(PROMPT),
            ChatMessage::user(format!("[{raw_records}]")),
        ],
    )
    .with_thinking_level(selected.thinking_level)
    .with_text_verbosity(settings.text_verbosity_for(&selection.provider));
    status.stage(crate::sessions::progressive_summaries::Stage::RequestingSummary);
    let cancellation = crate::cancellation::AgentCancellation::default();
    let (token, timeout) = cancellation.child_token();
    let (done_sender, done_receiver) = crossbeam_channel::bounded::<()>(1);
    let watchdog = thread::Builder::new()
        .name("psm-timeout".into())
        .spawn(move || {
            if done_receiver.recv_timeout(Duration::from_secs(120))
                == Err(crossbeam_channel::RecvTimeoutError::Timeout)
            {
                timeout.cancel();
            }
        })?;
    let mut raw = String::new();
    let mut receiving = false;
    let result = provider.stream_cancellable(request, &token, &mut |event| {
        token.check()?;
        if !receiving {
            receiving = true;
            status.stage(crate::sessions::progressive_summaries::Stage::ReceivingSummary);
        }
        if let ProviderEvent::TextDelta(delta) = event {
            anyhow::ensure!(
                raw.len() + delta.len() <= MAX_OUTPUT_BYTES,
                "PSM response exceeds limit"
            );
            raw.push_str(&delta);
        }
        Ok(())
    });
    let _ = done_sender.send(());
    let _ = watchdog.join();
    anyhow::ensure!(
        !token.is_canceled(),
        "PSM provider request exceeded 120-second deadline"
    );
    result?;
    token.check()?;
    Ok(raw)
}