agent-graph-mcp 0.2.6

Run 9 agents at once — MCP server for graph-orchestrated LLM workflows with parallel fan-out (up to 16 nodes), checkpoint/resume, HITL approvals, HMAC receipts
Documentation
use agent_graph_mcp::codex_app_server::{collect_text, is_terminal_notification, run_turn};
use serde_json::json;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::time::Duration;

#[test]
fn collects_stream_deltas_and_ignores_non_terminal_events() {
    let events = vec![
        json!({"method":"thread/started","params":{}}),
        json!({"method":"item/agentMessage/delta","params":{"delta":"hello "}}),
        json!({"method":"item/agentMessage/delta","params":{"delta":"world"}}),
        json!({"method":"thread/tokenUsage/updated","params":{}}),
        json!({"method":"turn/completed","params":{"turn":{"status":"completed"}}}),
    ];
    assert_eq!(collect_text(&events), "hello world");
    assert!(!is_terminal_notification(&events[0]));
    assert!(is_terminal_notification(&events[4]));
}

#[test]
fn falls_back_to_completed_agent_message_when_delta_is_absent() {
    let events = vec![json!({
        "method":"item/completed",
        "params":{"item":{"type":"agentMessage","text":"final answer"}}
    })];
    assert_eq!(collect_text(&events), "final answer");
}

#[test]
fn runs_complete_turn_and_collects_text_from_a_stdio_app_server() {
    let dir = tempfile::tempdir().unwrap();
    let fake = dir.path().join("fake-codex");
    fs::write(
        &fake,
        r##"#!/bin/sh
read line
printf '%s\n' '{"jsonrpc":"2.0","id":1,"result":{}}'
read line
read line
printf '%s\n' '{"jsonrpc":"2.0","id":2,"result":{"thread":{"id":"thread-1"}}}'
read line
printf '%s\n' '{"jsonrpc":"2.0","id":3,"result":{"turn":{"id":"turn-1"}}}'
printf '%s\n' '{"jsonrpc":"2.0","method":"item/agentMessage/delta","params":{"delta":"safe result"}}'
printf '%s\n' '{"jsonrpc":"2.0","method":"turn/completed","params":{"turn":{"id":"turn-1"}}}'
"##,
    )
    .unwrap();
    fs::set_permissions(&fake, fs::Permissions::from_mode(0o700)).unwrap();

    let text = run_turn(
        fake.to_str().unwrap(),
        "gpt-5.6-luna",
        dir.path(),
        "hello",
        Duration::from_secs(2),
    )
    .unwrap();
    assert_eq!(text, "safe result");
}