ai-dispatch 10.19.0

Multi-AI CLI team orchestrator
use super::call_tool;
use crate::store::Store;
use serde_json::{Value, json};
use std::sync::Arc;

fn payload_text(result: &Value) -> &str {
    result["content"][0]["text"].as_str().expect("text content")
}

#[tokio::test]
async fn agents_tool_returns_fleet_payload() {
    let temp_dir = std::env::temp_dir().join("aid-mcp-agents-tool-test");
    let _home = crate::paths::AidHomeGuard::set(&temp_dir);
    let store = Arc::new(Store::open_memory().expect("memory store"));

    let result = call_tool(store, "aid_agents", json!({}))
        .await
        .expect("call aid_agents");

    assert!(result.get("isError").is_none(), "{result}");
    let payload: Value = serde_json::from_str(payload_text(&result)).expect("payload JSON");
    assert!(payload["generated_at"].is_string());
    let agents = payload["agents"].as_array().expect("agents array");
    assert!(!agents.is_empty());
    assert!(agents.iter().all(|agent| agent["name"].is_string()));
    assert!(agents.iter().all(|agent| agent["quota"]["state"].is_string()));
}

#[tokio::test]
async fn advise_tool_returns_declared_advice_payload() {
    let temp_dir = std::env::temp_dir().join("aid-mcp-advise-tool-test");
    let _home = crate::paths::AidHomeGuard::set(&temp_dir);
    let store = Arc::new(Store::open_memory().expect("memory store"));

    let result = call_tool(
        store,
        "aid_advise",
        json!({
            "prompt": "Refactor src/main.rs into smaller modules",
            "difficulty": "complex",
            "budget": "premium",
            "urgency": "urgent",
            "rigor": "standard",
            "top": 3
        }),
    )
    .await
    .expect("call aid_advise");

    assert!(result.get("isError").is_none(), "{result}");
    let payload: Value = serde_json::from_str(payload_text(&result)).expect("payload JSON");
    assert_eq!(payload["declared"]["difficulty"], "complex");
    assert_eq!(payload["declared"]["budget"], "premium");
    assert_eq!(payload["declared"]["urgency"], "urgent");
    assert_eq!(payload["declared"]["rigor"], "standard");
    let candidates = payload["candidates"].as_array().expect("candidates array");
    assert!(!candidates.is_empty());
    assert!(candidates.len() <= 3);
}

#[tokio::test]
async fn advise_tool_errors_on_unknown_dimension_value() {
    let store = Arc::new(Store::open_memory().expect("memory store"));

    let result = call_tool(
        store,
        "aid_advise",
        json!({
            "prompt": "Refactor src/main.rs",
            "difficulty": "impossible",
            "budget": "premium",
            "urgency": "urgent",
            "rigor": "critical"
        }),
    )
    .await
    .expect("call aid_advise");

    assert_eq!(result["isError"], true);
    assert!(payload_text(&result).contains("Unknown difficulty 'impossible'"));
}

#[tokio::test]
async fn advise_tool_requires_declared_dimensions() {
    let store = Arc::new(Store::open_memory().expect("memory store"));

    let result = call_tool(
        store,
        "aid_advise",
        json!({ "prompt": "Refactor src/main.rs", "difficulty": "complex" }),
    )
    .await
    .expect("call aid_advise");

    assert_eq!(result["isError"], true);
    assert!(payload_text(&result).contains("Invalid arguments for aid_advise"));
}