vv-agent 0.8.0

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use serde_json::{json, Value};
use vv_agent::RunEvent;

const FIXTURE: &str = include_str!("fixtures/parity/run_events_invalid.json");

fn contract() -> Value {
    serde_json::from_str(FIXTURE).expect("run event invalid fixture")
}

#[test]
fn invalid_run_event_inputs_are_rejected() {
    let contract = contract();
    let cases = contract["reject"].as_array().expect("reject cases");
    let ids = cases
        .iter()
        .filter_map(|case| case["id"].as_str())
        .collect::<std::collections::BTreeSet<_>>();
    for id in [
        "memory_compact_trigger_is_unknown",
        "memory_compact_capacity_is_negative",
        "memory_compact_reserved_output_source_is_unknown",
        "memory_compact_mode_is_unknown",
        "memory_compact_changed_is_not_boolean",
    ] {
        assert!(ids.contains(id), "missing invalid memory case {id}");
    }
    for case in cases {
        let result = serde_json::from_value::<RunEvent>(case["input"].clone());
        assert!(result.is_err(), "{}", case["id"]);
    }
}

#[test]
fn memory_compaction_known_non_nullable_fields_reject_explicit_null() {
    for field in [
        "trigger",
        "configured_threshold",
        "effective_threshold",
        "microcompact_threshold",
        "model_context_window",
        "reserved_output_tokens",
        "reserved_output_source",
        "autocompact_buffer_tokens",
    ] {
        let mut value = current_memory_compact_started();
        value[field] = Value::Null;
        assert!(
            serde_json::from_value::<RunEvent>(value).is_err(),
            "{field} accepted explicit null"
        );
    }

    for field in ["mode", "changed"] {
        let mut value = current_memory_compact_completed();
        value[field] = Value::Null;
        assert!(
            serde_json::from_value::<RunEvent>(value).is_err(),
            "{field} accepted explicit null"
        );
    }
}

#[test]
fn memory_compaction_model_output_capability_accepts_explicit_null() {
    let value = current_memory_compact_started();

    let event: RunEvent = serde_json::from_value(value.clone()).expect("nullable capability");
    assert_eq!(serde_json::to_value(event).expect("serialize event"), value);
}

fn current_memory_compact_started() -> Value {
    json!({
        "version": "v1",
        "type": "memory_compact_started",
        "event_id": "evt_nullable_model_capability",
        "run_id": "run_nullable_model_capability",
        "trace_id": "trace_nullable_model_capability",
        "created_at": 1,
        "message_count": 3,
        "trigger": "full_threshold",
        "configured_threshold": 250000,
        "effective_threshold": 250000,
        "microcompact_threshold": 187500,
        "model_context_window": 1000000,
        "model_max_output_tokens": null,
        "reserved_output_tokens": 16000,
        "reserved_output_source": "framework_fallback",
        "autocompact_buffer_tokens": 13000
    })
}

fn current_memory_compact_completed() -> Value {
    json!({
        "version": "v1",
        "type": "memory_compact_completed",
        "event_id": "evt_invalid_memory_completed",
        "run_id": "run_invalid_memory",
        "trace_id": "trace_invalid_memory",
        "created_at": 1,
        "before_count": 3,
        "after_count": 2,
        "mode": "summary",
        "changed": true
    })
}