magi-code 0.96.1

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

pub(super) fn provider_context_content_pairs(
    events: &[SessionEvent],
    settings: &InjectedContentSettings,
) -> std::collections::HashMap<String, String> {
    if settings.style != InjectedContentStyle::Content {
        return std::collections::HashMap::new();
    }

    let injections = events
        .iter()
        .filter(|event| event.kind() == Some(SessionEventKind::HookContextInjection))
        .filter_map(HydratedContextInjection::from_event)
        .collect::<Vec<_>>();
    let provider_items = events
        .iter()
        .filter(|event| event.kind() == Some(SessionEventKind::ProviderContextItem))
        .filter(|event| {
            event
                .payload
                .get("source")
                .and_then(serde_json::Value::as_str)
                != Some("subdir_agents")
        })
        .filter_map(provider_context_item_content)
        .collect::<Vec<_>>();

    let successful = injections
        .iter()
        .filter(|injection| injection.status == "success" && injection.item_count > 0)
        .collect::<Vec<_>>();
    let total_items = successful
        .iter()
        .map(|injection| injection.item_count)
        .sum::<usize>();
    if successful.is_empty() || total_items != provider_items.len() {
        return std::collections::HashMap::new();
    }
    let can_pair_by_order = successful
        .iter()
        .all(|injection| injection.injection_id.is_some())
        || successful.len() == 1;
    if !can_pair_by_order {
        return std::collections::HashMap::new();
    }

    let mut pairs = std::collections::HashMap::new();
    let mut cursor = 0usize;
    for injection in successful {
        let end = cursor.saturating_add(injection.item_count);
        let content = provider_items[cursor..end].join("\n");
        if !content.is_empty() {
            pairs.insert(injection.content_key(), bounded_injected_content(&content));
        }
        cursor = end;
    }
    pairs
}

#[derive(Debug, Clone)]
pub(super) struct HydratedContextInjection {
    pub(super) phase: HookPhase,
    pub(super) label: String,
    target: String,
    pub(super) status: String,
    item_count: usize,
    byte_count: usize,
    hook_index: usize,
    pub(super) tool_call_id: Option<String>,
    injection_id: Option<String>,
}

impl HydratedContextInjection {
    fn from_event(event: &SessionEvent) -> Option<Self> {
        let payload = &event.payload;
        Some(Self {
            phase: parse_hook_phase(payload.get("phase")?.as_str()?),
            label: sanitized_payload_str(payload, "label").unwrap_or_else(|| "hook".to_string()),
            target: sanitized_payload_str(payload, "target_tool")
                .or_else(|| sanitized_payload_str(payload, "target"))
                .unwrap_or_else(|| "unknown".to_string()),
            status: sanitized_payload_str(payload, "status")
                .unwrap_or_else(|| "unknown".to_string()),
            item_count: payload
                .get("item_count")
                .and_then(serde_json::Value::as_u64)
                .unwrap_or(0) as usize,
            byte_count: payload
                .get("byte_count")
                .and_then(serde_json::Value::as_u64)
                .unwrap_or(0) as usize,
            hook_index: payload
                .get("hook_index")
                .and_then(serde_json::Value::as_u64)
                .unwrap_or(0) as usize,
            tool_call_id: sanitized_payload_str(payload, "tool_call_id"),
            injection_id: sanitized_payload_str(payload, "injection_id"),
        })
    }

    fn content_key(&self) -> String {
        self.injection_id.clone().unwrap_or_else(|| {
            format!(
                "{}:{}:{}",
                self.phase.as_str(),
                self.target,
                self.hook_index
            )
        })
    }
}

fn provider_context_item_content(event: &SessionEvent) -> Option<String> {
    let role = event.payload.get("role")?.as_str()?;
    if role != "user" {
        return None;
    }
    event
        .payload
        .get("content")
        .and_then(serde_json::Value::as_str)
        .map(str::to_string)
}

pub(super) fn hydrate_hook_context_injection_event(
    ui_state: &mut state::MissionControlState,
    event: &SessionEvent,
    settings: &InjectedContentSettings,
    content_pairs: &std::collections::HashMap<String, String>,
    tool_activity_ids: &std::collections::HashMap<String, ActivityId>,
) {
    if !settings.show_in_transcript && !settings.show_in_activity_tree {
        return;
    }
    let Some(injection) = HydratedContextInjection::from_event(event) else {
        return;
    };
    let content =
        if settings.style == InjectedContentStyle::Content && injection.status == "success" {
            injection
                .injection_id
                .as_ref()
                .and_then(|id| content_pairs.get(id).cloned())
                .or_else(|| content_pairs.get(&injection.content_key()).cloned())
        } else {
            None
        };
    let display = ProviderContextInjectionDisplay::new(
        injection.phase,
        injection.label.clone(),
        injection.target.clone(),
        injection.status.clone(),
        injection.item_count,
        injection.byte_count,
        content,
    );
    if settings.show_in_transcript {
        ui_state.apply_output_event_at(
            &OutputEvent::ProviderContextInjection {
                metadata: display.clone(),
            },
            Some(event.timestamp),
        );
    }
    if settings.show_in_activity_tree {
        hydrate_provider_context_injection_activity(
            ui_state,
            &injection,
            &display,
            tool_activity_ids,
        );
    }
}

fn hydrate_provider_context_injection_activity(
    ui_state: &mut state::MissionControlState,
    injection: &HydratedContextInjection,
    display: &ProviderContextInjectionDisplay,
    tool_activity_ids: &std::collections::HashMap<String, ActivityId>,
) {
    let parent_id = injection
        .tool_call_id
        .as_deref()
        .and_then(|call_id| tool_activity_ids.get(call_id).cloned());
    let id = provider_context_injection_activity_id(parent_id.as_ref(), injection);
    let metadata = provider_context_injection_activity_metadata(display);
    let status = if injection.status == "success" {
        ActivityStatus::Success
    } else {
        ActivityStatus::Failed
    };
    ui_state.apply_historical_activity_event(ActivityEvent::Started {
        id: id.clone(),
        parent_id,
        kind: ActivityKind::ProviderContextInjection,
        status: ActivityStatus::Running,
        metadata: metadata.clone(),
    });
    ui_state.apply_historical_activity_event(ActivityEvent::Finished {
        id,
        status,
        metadata: Some(metadata),
    });
}

fn provider_context_injection_activity_id(
    parent_activity_id: Option<&ActivityId>,
    injection: &HydratedContextInjection,
) -> ActivityId {
    let phase = injection.phase.as_str();
    if let Some(parent_activity_id) = parent_activity_id {
        parent_activity_id.child(format!(
            "{phase}-provider-context-injection-{}",
            injection.content_key()
        ))
    } else {
        ActivityId::new(format!(
            "provider-context-injection/{}/{}/{}",
            injection.target,
            phase,
            injection.content_key()
        ))
    }
}

fn provider_context_injection_activity_metadata(
    display: &ProviderContextInjectionDisplay,
) -> ActivityMetadata {
    ActivityMetadata {
        label: format!("provider context injection {}", display.label),
        detail: Some(format!(
            "provider context injection '{}' for {} {}: {} {} {} bytes",
            display.label,
            display.target,
            display.phase.as_str(),
            display.status,
            item_count_text(display.item_count),
            display.byte_count
        )),
        fields: vec![
            ("phase".to_string(), display.phase.as_str().to_string()),
            ("hook_label".to_string(), display.label.clone()),
            ("target".to_string(), display.target.clone()),
            ("status".to_string(), display.status.clone()),
            ("item_count".to_string(), display.item_count.to_string()),
            ("bytes".to_string(), display.byte_count.to_string()),
        ],
    }
}

fn item_count_text(count: usize) -> String {
    if count == 1 {
        "1 item".to_string()
    } else {
        format!("{count} items")
    }
}

fn bounded_injected_content(text: &str) -> String {
    const MAX_INJECTED_CONTENT_CHARS: usize = 2000;
    let redacted = redact_sensitive_text(text);
    let mut chars = redacted.chars();
    let truncated = chars
        .by_ref()
        .take(MAX_INJECTED_CONTENT_CHARS)
        .collect::<String>();
    if chars.next().is_some() {
        format!("{truncated}…")
    } else {
        truncated
    }
}

pub(super) fn hydrate_subdir_instruction_load_event(
    ui_state: &mut state::MissionControlState,
    event: &SessionEvent,
    tool_activity_ids: &std::collections::HashMap<String, ActivityId>,
) {
    let payload = &event.payload;
    if payload.get("source").and_then(serde_json::Value::as_str) != Some("subdir_agents") {
        return;
    }
    if payload.get("status").and_then(serde_json::Value::as_str) != Some("success") {
        return;
    }
    let Some(path) = sanitized_payload_str(payload, "path") else {
        return;
    };
    let bytes = payload
        .get("bytes")
        .and_then(serde_json::Value::as_u64)
        .unwrap_or(0) as usize;
    let parent_activity_id = payload
        .get("tool_call_id")
        .and_then(serde_json::Value::as_str)
        .and_then(|call_id| tool_activity_ids.get(call_id))
        .map(|id| id.as_str().to_string());
    ui_state.apply_output_event_at(
        &OutputEvent::SubdirInstructionInjection {
            path: std::path::PathBuf::from(&path),
            bytes,
            parent_activity_id: parent_activity_id.clone(),
        },
        Some(event.timestamp),
    );
    let id = ActivityId::new(format!(
        "history/subdir-instruction-load/{}",
        event.timestamp.timestamp_micros()
    ));
    let metadata = ActivityMetadata {
        label: format!("Loaded subdirectory instructions: {path}"),
        detail: Some(format!(
            "Loaded subdirectory instructions: {path} ({bytes} bytes)"
        )),
        fields: vec![
            ("source".to_string(), "subdir_agents".to_string()),
            ("path".to_string(), path),
            ("status".to_string(), "success".to_string()),
            ("bytes".to_string(), bytes.to_string()),
        ],
    };
    ui_state.apply_historical_activity_event(ActivityEvent::Started {
        id: id.clone(),
        parent_id: parent_activity_id.map(ActivityId::new),
        kind: ActivityKind::ProviderContextInjection,
        status: ActivityStatus::Running,
        metadata: metadata.clone(),
    });
    ui_state.apply_historical_activity_event(ActivityEvent::Finished {
        id,
        status: ActivityStatus::Success,
        metadata: Some(metadata),
    });
}