magi-code 0.64.0

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

#[test]
fn subagents_schema_bounds_tasks_and_concurrency() {
    let definitions = mvp_tool_definitions_json();
    let parallel = definitions
        .as_array()
        .unwrap()
        .iter()
        .find(|definition| definition["name"] == "subagents")
        .unwrap();
    let tasks = &parallel["parameters"]["properties"]["tasks"];
    assert_eq!(tasks["minItems"], 1);
    assert_eq!(tasks["maxItems"], 10);
    assert_eq!(
        parallel["parameters"]["properties"]["concurrency"]["minimum"],
        1
    );
    assert_eq!(
        parallel["parameters"]["properties"]["concurrency"]["maximum"],
        4
    );
    let task_properties = &tasks["items"]["properties"];
    assert_eq!(tasks["items"]["required"], json!(["intent"]));
    assert!(task_properties.get("identity").is_some());
    assert!(
        parallel["description"]
            .as_str()
            .unwrap()
            .contains("identity")
    );
    assert!(
        task_properties["agent"]["description"]
            .as_str()
            .unwrap()
            .contains("not the same as identity")
    );
}

#[test]
fn subagents_accepts_missing_identity_before_dispatch() {
    let (_temp, runtime) = runtime();
    let captured_arguments = Arc::new(Mutex::new(None));
    let captured_by_runner = Arc::clone(&captured_arguments);
    let runtime = runtime.with_subagents(move |arguments, _context| {
        *captured_by_runner.lock().unwrap() = Some(arguments);
        ToolResult {
            tool_name: "subagents".to_string(),
            success: true,
            content: "runner called".to_string(),
            metadata: json!({}),
            display: crate::tools::ToolResultDisplay::default(),
        }
    });

    let result = runtime.dispatch(
        "subagents",
        json!({"tasks":[{"intent":"inspect"}],"concurrency":1}),
    );

    assert!(result.success, "{}", result.content);
    assert_eq!(result.content, "runner called");
    let arguments = captured_arguments
        .lock()
        .unwrap()
        .clone()
        .expect("runner should receive validated arguments");
    let task = &arguments["tasks"][0];
    assert_eq!(task["intent"], "inspect");
    assert!(
        task.get("identity").is_none(),
        "missing identity must stay omitted before dispatch: {arguments}"
    );
}

#[test]
fn subagents_accepts_optional_identity_and_rejects_invalid_identity() {
    let (_temp, runtime) = runtime();
    let valid = runtime.dispatch(
        "subagents",
        json!({"tasks":[{"intent":"inspect","identity":"frontend-dev_1"}],"concurrency":1}),
    );
    assert!(!valid.success);
    assert!(
        valid.content.contains("runtime is not configured"),
        "{}",
        valid.content
    );

    for identity in ["../frontend", " frontend-dev", "frontend-dev "] {
        let invalid = runtime.dispatch(
            "subagents",
            json!({"tasks":[{"intent":"inspect","identity":identity}],"concurrency":1}),
        );
        assert!(!invalid.success);
        assert!(
            invalid.content.contains("identity id"),
            "identity {identity:?}: {}",
            invalid.content
        );
    }
}

#[test]
fn subagents_rejects_whitespace_identity_before_dispatch() {
    let (_temp, runtime) = runtime();
    let runtime = runtime.with_subagents(|_arguments, _context| ToolResult {
        tool_name: "subagents".to_string(),
        success: true,
        content: "runner called".to_string(),
        metadata: json!({}),
        display: crate::tools::ToolResultDisplay::default(),
    });

    let result = runtime.dispatch(
        "subagents",
        json!({"tasks":[{"intent":"inspect","identity":" frontend-dev"}],"concurrency":1}),
    );

    assert!(!result.success);
    assert!(result.content.contains("identity id"), "{}", result.content);
    assert_ne!(result.content, "runner called");
}