magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::*;

pub trait AgentOutputSink {
    fn assistant_delta(&mut self, text: &str) -> anyhow::Result<()>;
    /// Required root user input is durable; called before provider work.
    fn user_input_persisted(&mut self) -> anyhow::Result<()> {
        Ok(())
    }
    /// Durable history is incomplete even if the run later returns successfully.
    fn persistence_degraded(&mut self) {}
    /// Original individual steering inputs, only after required persistence and acknowledgement.
    fn steering_prompts_acknowledged(&mut self, _prompts: &[String]) {}
    /// Receives only completed summaries from explicit provider summary fields.
    /// Generic thinking output may contain raw reasoning and must not use this callback.
    fn provider_reasoning_summary(&mut self, _text: &str) -> anyhow::Result<()> {
        Ok(())
    }
    /// Reports the latest known token total for one provider request.
    fn request_token_total(&mut self, _sequence: u64, _total: u64) -> anyhow::Result<()> {
        Ok(())
    }
    fn activity_event(&mut self, _event: ActivityEvent) -> anyhow::Result<()> {
        Ok(())
    }
    fn activity_sender(&self) -> Option<ActivitySender> {
        None
    }
    fn current_parent_activity_id(&self) -> Option<ActivityId> {
        None
    }
    fn request_bash_approval(
        &mut self,
        _request: crate::protection::bash::BashApprovalRequest,
        _cancellation: &crate::cancellation::AgentCancellation,
    ) -> anyhow::Result<bool> {
        Ok(false)
    }
    fn tool_result(&mut self, call: &ToolCall, result: &ToolResult) -> anyhow::Result<()> {
        let block = format_tool_block(call, result);
        self.tool_block(&block)
    }
    fn output_event(&mut self, event: OutputEvent) -> anyhow::Result<()> {
        match event {
            OutputEvent::AssistantDelta { text } => self.assistant_delta(&text),
            OutputEvent::ToolResult { call, result, .. } => self.tool_result(&call, &result),
            OutputEvent::SubdirInstructionInjection { path, .. } => self.tool_block(&format!(
                "Loaded subdirectory instructions: {}",
                path.display()
            )),
            OutputEvent::SessionHeader { .. }
            | OutputEvent::UserPrompt { .. }
            | OutputEvent::SteeringInjected { .. }
            | OutputEvent::AutomaticUserPrompt { .. }
            | OutputEvent::CompactionTriggered { .. }
            | OutputEvent::CompactionStarted
            | OutputEvent::CompactionCompleted { .. }
            | OutputEvent::CompactionFailed { .. }
            | OutputEvent::FastObservation { .. }
            | OutputEvent::BashCommand { .. }
            | OutputEvent::ContextUsage { .. }
            | OutputEvent::UsageSnapshot { .. }
            | OutputEvent::ThinkingSummaryDelta { .. }
            | OutputEvent::ThinkingSummaryComplete { .. }
            | OutputEvent::ThinkingSummaryCompleteIdentified { .. }
            | OutputEvent::AssistantComplete { .. }
            | OutputEvent::Diagnostic { .. }
            | OutputEvent::HookDiagnostic { .. }
            | OutputEvent::ProviderContextInjection { .. }
            | OutputEvent::ToolStarted { .. } => Ok(()),
        }
    }
    fn tool_block(&mut self, block: &str) -> anyhow::Result<()>;
}

#[derive(Debug, Clone, Default, PartialEq)]
pub struct AgentRunOutput {
    pub text: String,
    pub usage: Option<Usage>,
    pub total_tokens: Option<u64>,
    pub(crate) fast_outcome: crate::fast::FastOutcome,
    pub tool_results: Vec<ToolResult>,
    pub(crate) persistence_degraded: bool,
    pub(crate) recovered_incomplete_stream: bool,
    pub(crate) auto_compaction_blocked_by_recovery: bool,
    pub(crate) manual_compaction_request: Option<ManualCompactionRequest>,
}