magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
use crate::tools::{MVP_TOOL_CAPABILITIES, ToolCapability, ToolRuntime};
use serde_json::{Value, json};

pub(crate) const COMPACT_DIRECT_TOOLS: &[&str] = &[
    "read",
    "hash_edit",
    "bash",
    "grep",
    "view_image",
    "subagents",
    "web",
    "magi_control",
];

#[derive(Clone, Copy)]
pub(crate) enum ToolCatalogSurface {
    DirectProviderFull,
    DirectProviderCompact,
    CodeModeInternal,
}

/// Enabled and permitted for this runtime; inspection-only agents cannot batch tools.
pub(crate) fn code_mode_available(runtime: &ToolRuntime) -> bool {
    runtime.code_mode.enabled && !runtime.is_tool_disabled(super::TOOL_NAME)
}

pub(crate) fn effective_catalog(runtime: &ToolRuntime, surface: ToolCatalogSurface) -> Vec<Value> {
    let internal_runtime;
    let runtime = if matches!(surface, ToolCatalogSurface::CodeModeInternal) {
        internal_runtime = runtime.for_code_mode();
        &internal_runtime
    } else {
        runtime
    };
    let mut definitions: Vec<_> = MVP_TOOL_CAPABILITIES
        .iter()
        .copied()
        .filter(|tool| !runtime.is_tool_disabled(tool.canonical_name()))
        .filter(|tool| *tool != ToolCapability::Subagents || runtime.subagents_schema_enabled())
        .map(ToolCapability::provider_definition_json)
        .chain(
            runtime
                .dynamic_provider_tool_definitions()
                .into_iter()
                .filter(|definition| {
                    definition["name"].as_str().is_some_and(|name| {
                        name != super::TOOL_NAME
                            && ToolCapability::from_dispatch_name(name).is_none()
                            && !runtime.is_tool_disabled(name)
                    })
                }),
        )
        .filter(|definition| match surface {
            ToolCatalogSurface::DirectProviderFull => true,
            ToolCatalogSurface::DirectProviderCompact => definition["name"]
                .as_str()
                .is_some_and(|name| COMPACT_DIRECT_TOOLS.contains(&name)),
            ToolCatalogSurface::CodeModeInternal => definition["name"] != "magi_control",
        })
        .collect();
    if matches!(surface, ToolCatalogSurface::CodeModeInternal) {
        let mut schemas = runtime.dynamic_tool_output_schemas();
        for definition in &mut definitions {
            if let Some(schema) = definition["name"]
                .as_str()
                .and_then(|name| schemas.remove(name))
            {
                definition["output_schema"] = json!({"type":"object","properties":{
                    "success":{"type":"boolean"},"content":{"type":"object","properties":{
                        "content":{"type":"array","items":{"type":"object"}},
                        "structuredContent":{"anyOf":[schema,{"type":"null"}]},
                        "complete":{"type":"boolean"}
                    }}
                },"required":["success"]});
            }
        }
    }
    if !matches!(surface, ToolCatalogSurface::CodeModeInternal) && code_mode_available(runtime) {
        definitions.push(super::definition());
    }
    definitions
}

pub(crate) struct Catalog(pub(crate) Vec<Value>);

impl Catalog {
    pub(crate) fn discover(&self, operation: &str, query: &str) -> Value {
        let canonical = ToolCapability::from_dispatch_name(query)
            .map(ToolCapability::canonical_name)
            .unwrap_or(query);
        match operation {
            "describe" => self
                .0
                .iter()
                .find(|entry| entry["name"] == canonical)
                .map(|entry| {
                    let mut entry = entry.clone();
                    entry.as_object_mut().unwrap().remove("type");
                    if let Some(tool) = ToolCapability::from_dispatch_name(query) {
                        entry["output_schema"] = tool.output_schema();
                    }
                    entry
                })
                .unwrap_or(Value::Null),
            _ => {
                let words: Vec<_> = query.split_whitespace().map(str::to_lowercase).collect();
                Value::Array(self.0.iter().filter(|entry| {
                    let text = format!("{} {}", entry["name"], entry["description"]).to_lowercase();
                    words.iter().all(|word| text.contains(word))
                }).map(|entry| json!({"name": entry["name"], "description": entry["description"]})).collect())
            }
        }
    }

    pub(crate) fn canonical_name(&self, name: &str) -> Option<String> {
        let canonical = ToolCapability::from_dispatch_name(name)
            .map(ToolCapability::canonical_name)
            .unwrap_or(name);
        self.0
            .iter()
            .any(|entry| entry["name"] == canonical)
            .then(|| canonical.to_owned())
    }
}