#![allow(clippy::unwrap_used)]
#![allow(clippy::pedantic, clippy::nursery, missing_docs)]
use std::sync::{Arc, Mutex};
use async_trait::async_trait;
use futures::stream::{self, StreamExt};
use polyc_agent::golden_vectors::{Vector, VectorMessage};
use polyc_agent::identifiers::{IdentifierClass, extract_identifiers, is_retained};
use polyc_agent::{LlmSummarizer, Summarizer};
use polyc_llm::error::DummyError;
use polyc_llm::{
Chunk, CompletionRequest, Content as LlmContent, LlmProvider, Message as LlmMessage, Role,
StopReason,
};
fn vectors() -> Vec<Vector> {
polyc_conformance_vectors::compaction_vectors()
.into_iter()
.map(|s| serde_json::from_str(s).expect("valid vector JSON"))
.collect()
}
fn to_llm(msg: &VectorMessage) -> LlmMessage {
match msg {
VectorMessage::User { text } => LlmMessage::user(text.clone()),
VectorMessage::Assistant { text } => LlmMessage::assistant(text.clone()),
VectorMessage::ToolCall {
id,
name,
args_json,
} => LlmMessage {
role: Role::Assistant,
content: vec![LlmContent::tool_use(
id.clone(),
name.clone(),
args_json.clone(),
)],
},
VectorMessage::ToolResult { id, result_json } => LlmMessage {
role: Role::Tool,
content: vec![LlmContent::tool_result(
id.clone(),
result_json.clone(),
false,
true,
)],
},
}
}
fn round_messages(vector: &Vector, round: usize) -> Vec<LlmMessage> {
vector.rounds[round]
.turns
.iter()
.flat_map(|t| t.messages.iter().map(to_llm))
.collect()
}
fn seeded_text(vector: &Vector) -> String {
let mut s = String::new();
for round in &vector.rounds {
for turn in &round.turns {
for msg in &turn.messages {
match msg {
VectorMessage::User { text } | VectorMessage::Assistant { text } => {
s.push_str(text);
}
VectorMessage::ToolCall { args_json, .. } => s.push_str(args_json),
VectorMessage::ToolResult { result_json, .. } => s.push_str(result_json),
}
s.push('\n');
}
}
}
s
}
fn class_from_str(s: &str) -> IdentifierClass {
match s {
"url" => IdentifierClass::Url,
"amount" => IdentifierClass::Amount,
"opaque_id" => IdentifierClass::OpaqueId,
"proper_noun" => IdentifierClass::ProperNoun,
"quoted" => IdentifierClass::Quoted,
other => panic!("unknown identifier class in vector: {other}"),
}
}
#[test]
fn required_identifiers_are_extractable_by_the_normative_definition() {
for vector in vectors() {
let extracted = extract_identifiers(&seeded_text(&vector));
for req in &vector.required {
let class = class_from_str(&req.class);
assert!(
extracted
.iter()
.any(|id| id.class == class && id.text == req.text),
"[{}] required identifier {:?} (class {:?}) is not extractable \
from the seeded transcript by the normative extractor",
vector.family,
req.text,
class,
);
}
assert!(vector.rounds.len() >= 3, "[{}] needs K >= 3", vector.family);
for round in 0..vector.rounds.len() {
assert!(
vector.required.iter().any(|r| r.round == round),
"[{}] round {round} seeds no required identifier",
vector.family,
);
}
}
}
struct CapturingProvider {
seen_user_text: Mutex<Vec<String>>,
}
impl CapturingProvider {
fn new() -> Self {
Self {
seen_user_text: Mutex::new(Vec::new()),
}
}
}
#[async_trait]
impl LlmProvider for CapturingProvider {
type Error = DummyError;
async fn complete(
&self,
req: CompletionRequest,
) -> Result<futures::stream::BoxStream<'static, Result<Chunk, Self::Error>>, Self::Error> {
let user_text = req
.messages
.iter()
.flat_map(|m| m.content.iter())
.filter_map(|c| match c {
LlmContent::Text(t) => Some(t.as_str()),
_ => None,
})
.collect::<Vec<_>>()
.join("\n");
self.seen_user_text.lock().unwrap().push(user_text);
let chunks = vec![
Ok(Chunk::text_delta("ok".to_owned())),
Ok(Chunk::Stop(StopReason::EndTurn)),
];
Ok(stream::iter(chunks).boxed())
}
}
#[tokio::test]
async fn rendering_delivers_required_identifiers_to_the_model_input() {
for vector in vectors() {
let provider = Arc::new(CapturingProvider::new());
let summarizer = LlmSummarizer::new(provider.clone(), "eval-model", 2048);
let messages: Vec<LlmMessage> = (0..vector.rounds.len())
.flat_map(|r| round_messages(&vector, r))
.collect();
let _ = summarizer.summarize("", &messages).await;
let rendered = provider.seen_user_text.lock().unwrap().join("\n");
for req in &vector.required {
assert!(
is_retained(&rendered, &req.text),
"[{}] required identifier {:?} (round {}) never reached the \
summarizer's rendered input — the pipeline structurally \
dropped it before any model could retain it",
vector.family,
req.text,
req.round,
);
}
}
}
#[tokio::test]
async fn clip_shadowed_identifiers_are_a_documented_standing_miss() {
let mut saw_shadowed_family = false;
for vector in vectors() {
if vector.clip_shadowed.is_empty() {
continue;
}
saw_shadowed_family = true;
let provider = Arc::new(CapturingProvider::new());
let summarizer = LlmSummarizer::new(provider.clone(), "eval-model", 2048);
let messages: Vec<LlmMessage> = (0..vector.rounds.len())
.flat_map(|r| round_messages(&vector, r))
.collect();
let _ = summarizer.summarize("", &messages).await;
let rendered = provider.seen_user_text.lock().unwrap().join("\n");
for shadowed in &vector.clip_shadowed {
assert!(
is_retained(&seeded_text(&vector), &shadowed.text),
"[{}] clip_shadowed {:?} missing from the seeded transcript",
vector.family,
shadowed.text,
);
assert!(
!is_retained(&rendered, &shadowed.text),
"[{}] {:?} ({}) survived the render clip — the standing miss \
has closed; promote it into the vector's `required` set",
vector.family,
shadowed.text,
shadowed.location,
);
}
}
assert!(
saw_shadowed_family,
"the tool-noise vector pins the clip boundary"
);
}
fn family_floor(family: &str, required: usize) -> usize {
match family {
"identifier-dense" => required - 1,
"contradiction-heavy" => required - 2,
"tool-noise-heavy" => required - 2,
other => panic!("no floor recorded for family {other}"),
}
}
#[tokio::test]
#[ignore = "requires a live chat-completions-compatible endpoint (set \
POLYCHROME_OLLAMA_BASE_URL / POLYCHROME_OLLAMA_MODEL; run with \
cargo test -- --ignored)"]
async fn model_backed_recall_meets_family_floors() {
use polyc_llm_openai::{OpenAiConfig, OpenAiProvider};
let base_url = std::env::var("POLYCHROME_OLLAMA_BASE_URL")
.unwrap_or_else(|_| "http://localhost:11434/v1".to_owned());
let model =
std::env::var("POLYCHROME_OLLAMA_MODEL").unwrap_or_else(|_| "gemma4:12b-mlx".to_owned());
let provider = Arc::new(OpenAiProvider::new(OpenAiConfig {
base_url,
api_key: None,
default_model: model.clone(),
web_search_forced: false,
}));
let summarizer = LlmSummarizer::new(provider, model.clone(), 2048);
let mut failures = Vec::new();
for vector in vectors() {
let mut anchor = String::new();
for round in 0..vector.rounds.len() {
let messages = round_messages(&vector, round);
let next = summarizer.summarize(&anchor, &messages).await;
assert!(
next != anchor || anchor.is_empty(),
"[{}] round {round}: summarizer failed soft (provider error?) — \
anchor unchanged",
vector.family,
);
anchor = next;
println!(
"[{}] round {round}: anchor {} bytes",
vector.family,
anchor.len()
);
}
let mut survived = 0usize;
println!("\n== {} (model {model}) ==", vector.family);
for req in &vector.required {
let ok = is_retained(&anchor, &req.text);
if ok {
survived += 1;
}
println!(
" [{}] {:?} (class {}, round {})",
if ok { "KEPT" } else { "LOST" },
req.text,
req.class,
req.round,
);
}
for old in &vector.superseded {
println!(
" [superseded {}] {:?}",
if is_retained(&anchor, old) {
"kept"
} else {
"dropped"
},
old,
);
}
let floor = family_floor(&vector.family, vector.required.len());
println!(
" {}: {survived}/{} survived (floor {floor})",
vector.family,
vector.required.len(),
);
if survived < floor {
failures.push(format!(
"{}: {survived}/{} survived, floor {floor}",
vector.family,
vector.required.len(),
));
}
}
assert!(
failures.is_empty(),
"model-backed recall regressed below its measured floors:\n {}",
failures.join("\n "),
);
}