atman-runtime 1.8.1

atman flow execution runtime: evaluator, tool dispatch, provider dispatch, executor, memory stores
Documentation
mod common;

use std::sync::Arc;

use atman_dsl::parse::parse_file;
use atman_runtime::event::{Event, EventSink};
use atman_runtime::providers::mock::MockProvider;
use atman_runtime::{Executor, Value};

#[tokio::test]
async fn watch_token_warn_emits_event_and_stream_completes() {
    let _registry =
        common::ModelRegistryGuard::acquire(common::config([common::model_for_provider(
            "mock-model",
            "mock",
            8_192,
            None,
        )]))
        .await;
    let src = r#"flow review() -> string {
    primary = llm.call(
        model: "mock-model",
        prompt: "review please",
    )
    watch primary {
        on token(match: "warn me") {
            warn("HIT WARN")
        }
    }
    return primary
}
"#;
    let file = parse_file(src).unwrap();
    let sink = EventSink::new();
    let ex = Executor::with_events(sink.clone());
    ex.providers
        .register(Arc::new(MockProvider::new("mock").with_model(
            "mock-model",
            Value::Str("the answer contains warn me right here".into()),
        )));

    let out = ex.run(&file, "review", vec![]).await.unwrap();
    assert!(matches!(&out, Value::Str(s) if s.contains("warn me")));

    let events = sink.snapshot();
    let warn = events.iter().find_map(|e| match e {
        Event::WatchWarn {
            target,
            trigger,
            message,
            ..
        } => Some((target.clone(), trigger.clone(), message.clone())),
        _ => None,
    });
    let (target, trigger, message) = warn.expect("expected WatchWarn event");
    assert_eq!(target, "primary");
    assert!(trigger.starts_with("token("), "trigger: {trigger}");
    assert_eq!(message, "HIT WARN");
}

#[tokio::test]
async fn watch_warn_fires_once_per_pattern_even_on_repeats() {
    let _registry =
        common::ModelRegistryGuard::acquire(common::config([common::model_for_provider(
            "mock-model",
            "mock",
            8_192,
            None,
        )]))
        .await;
    let src = r#"flow review() -> string {
    primary = llm.call(
        model: "mock-model",
        prompt: "review",
    )
    watch primary {
        on token(match: "warn me") {
            warn()
        }
    }
    return primary
}
"#;
    let file = parse_file(src).unwrap();
    let sink = EventSink::new();
    let ex = Executor::with_events(sink.clone());
    ex.providers.register(Arc::new(
        MockProvider::new("mock")
            .with_model("mock-model", Value::Str("warn me warn me warn me".into())),
    ));

    ex.run(&file, "review", vec![]).await.unwrap();

    let warns = sink
        .snapshot()
        .iter()
        .filter(|e| matches!(e, Event::WatchWarn { .. }))
        .count();
    assert_eq!(warns, 1, "expected exactly one warn, got {warns}");
}