supercode-interchange 0.4.1

Canonical, provider-neutral session interchange primitives for Supercode
Documentation
use supercode_interchange::{
    estimate_tokens, estimate_view_tokens, mark_tool_outcome_unknown, measure_fidelity,
    tool_outcome, ChatMessage, ToolOutcome,
};

#[test]
fn metadata_stays_canonical_and_never_enters_the_provider_wire_shape() {
    let mut message = ChatMessage::tool_result("call-1", "shell", "output");
    mark_tool_outcome_unknown(&mut message);

    assert_eq!(tool_outcome(&message), ToolOutcome::Unknown);
    let wire = serde_json::to_value(&message).unwrap();
    assert!(wire.get("metadata").is_none());
    assert!(!wire.to_string().contains("sc.tool_outcome_unknown"));
}

#[test]
fn fidelity_measurement_reports_named_canonical_metadata_residue() {
    let source = vec![ChatMessage::assistant("done").with_meta("harness.phase", "final")];
    let reloaded = vec![ChatMessage::assistant("done")];

    let metric = measure_fidelity(&source, &reloaded);

    assert_eq!(metric.matched, 1);
    assert_eq!(
        metric.residue.dropped_metadata_keys,
        ["harness.phase".to_string()].into_iter().collect()
    );
    assert!(!metric.is_semantically_lossless());
}

#[test]
fn canonical_estimates_need_no_provider_or_runtime_types() {
    let messages = vec![
        ChatMessage::user("inspect this session"),
        ChatMessage::assistant("ready"),
    ];
    let expected: u64 = messages
        .iter()
        .map(|message| estimate_tokens(&serde_json::to_string(message).unwrap()))
        .sum();

    assert_eq!(estimate_view_tokens(&messages), expected);
}