relay-knowledge 1.1.16

Graph-database-based knowledge graph project.
Documentation
use super::*;
use crate::domain::{ContextEntity, RankingSignal};

#[test]
fn graph_search_outcome_applies_request_trace_budget() {
    let request = graph_search_request(1);
    let mut hit = retrieval_hit("ev-0", 1.0);
    hit.entities = (0..20)
        .map(|index| ContextEntity {
            id: format!("entity-{index}"),
            label: format!("Entity {index}"),
        })
        .collect();
    hit.ranking = (0..20)
        .map(|index| RankingSignal {
            source: RetrieverSource::GraphPath,
            rank: index + 1,
            score: 1.0 / (index + 1) as f64,
            explanation: format!("signal {index}"),
        })
        .collect();

    let outcome = GraphSearchOutcome::from_hits(&request, vec![hit]);
    let max_trace_items = request.max_trace_items();

    assert!(outcome.trace.truncated);
    assert!(outcome.trace.visited_nodes.len() <= max_trace_items);
    assert!(outcome.trace.ranking_contributions.len() <= max_trace_items);
}

#[test]
fn graph_search_trace_budget_preserves_requested_candidate_evidence() {
    let request = graph_search_request(80);
    let hits = (0..80)
        .map(|index| retrieval_hit(&format!("ev-{index:02}"), 100.0 - index as f64))
        .collect::<Vec<_>>();

    let outcome = GraphSearchOutcome::from_hits(&request, hits);

    assert_eq!(outcome.trace.visited_but_uncited.len(), 80);
    assert_eq!(outcome.trace.ranking_contributions.len(), 80);
    assert!(
        outcome
            .trace
            .visited_but_uncited
            .iter()
            .any(|evidence| evidence.evidence_id == "ev-79")
    );
}

fn graph_search_request(limit: usize) -> GraphSearchRequest {
    GraphSearchRequest {
        query: "trace".to_owned(),
        source_scope: Some("docs".to_owned()),
        graph_version: GraphVersion::new(1),
        limit,
        disabled_retriever_sources: Vec::new(),
    }
}

fn retrieval_hit(evidence_id: &str, score: f64) -> RetrievalHit {
    RetrievalHit {
        evidence_id: evidence_id.to_owned(),
        source_scope: "docs".to_owned(),
        source_path: None,
        source_span: None,
        content: format!("trace content {evidence_id}"),
        entity_labels: Vec::new(),
        entities: Vec::new(),
        graph_facts: Vec::new(),
        code_artifact: None,
        retriever_sources: vec![RetrieverSource::GraphPath],
        ranking: vec![RankingSignal {
            source: RetrieverSource::GraphPath,
            rank: 1,
            score,
            explanation: "graph path traversal".to_owned(),
        }],
        rerank: None,
        score,
    }
}