-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path04_provenance_tracking.rs
More file actions
117 lines (97 loc) · 3.87 KB
/
04_provenance_tracking.rs
File metadata and controls
117 lines (97 loc) · 3.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use anyhow::Result;
use neleus_db::{Database, Evidence, ProvenanceManifest, ProvenanceRecord, SourceType};
use tempfile::TempDir;
fn main() -> Result<()> {
let temp_dir = TempDir::new()?;
Database::init(temp_dir.path())?;
let db = Database::open(temp_dir.path())?;
let agent_id = "assistant_v1";
let source_doc = b"The capital of France is Paris. Population: 2.1M.";
let source_blob = db.blob_store.put(source_doc)?;
println!("Stored source document: {}", source_blob);
let mut record = ProvenanceRecord::new(
"claim_001".to_string(),
"The capital of France is Paris".to_string(),
agent_id.to_string(),
0.95,
);
let evidence = Evidence {
source_blob,
source_type: SourceType::Document,
extracted_text: "The capital of France is Paris".to_string(),
position: Some((0, 31)),
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs(),
metadata: {
let mut m = std::collections::BTreeMap::new();
m.insert("extraction_method".to_string(), "substring".to_string());
m
},
};
record.add_evidence(evidence);
record = record
.with_reasoning("Direct quote from authoritative source document".to_string())
.with_tags(vec!["geography".to_string(), "fact".to_string()]);
record.validate()?;
println!("\n✓ Created provenance record:");
println!(" Claim: {}", record.claim_text);
println!(" Confidence: {}", record.confidence);
println!(" Evidence count: {}", record.evidence.len());
let mut manifest = ProvenanceManifest::new(agent_id.to_string());
manifest.add_record(record)?;
let tool_output = b"API response: {temperature: 22C, condition: sunny}";
let tool_blob = db.blob_store.put(tool_output)?;
let mut weather_record = ProvenanceRecord::new(
"claim_002".to_string(),
"Current weather is sunny, 22C".to_string(),
agent_id.to_string(),
0.88,
);
weather_record.add_evidence(Evidence {
source_blob: tool_blob,
source_type: SourceType::ToolOutput,
extracted_text: String::from_utf8_lossy(tool_output).to_string(),
position: None,
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs(),
metadata: {
let mut m = std::collections::BTreeMap::new();
m.insert("tool".to_string(), "weather_api".to_string());
m
},
});
weather_record = weather_record.with_tags(vec!["weather".to_string(), "realtime".to_string()]);
manifest.add_record(weather_record)?;
let manifest_json = serde_json::to_vec(&manifest)?;
let manifest_hash = db.blob_store.put(&manifest_json)?;
println!("\n✓ Stored provenance manifest: {}", manifest_hash);
let retrieved_json = db.blob_store.get(manifest_hash)?;
let retrieved_manifest: ProvenanceManifest = serde_json::from_slice(&retrieved_json)?;
println!(
"\nRetrieved manifest with {} records",
retrieved_manifest.records.len()
);
if let Some(claim) = retrieved_manifest.find_by_claim_id("claim_001") {
println!("\nFound claim by ID:");
println!(" Text: {}", claim.claim_text);
println!(" Confidence: {}", claim.confidence);
println!(" Evidence sources: {}", claim.evidence.len());
for (i, ev) in claim.evidence.iter().enumerate() {
println!(
" Evidence {}: {:?} from {}",
i + 1,
ev.source_type,
ev.source_blob
);
}
}
let geography_claims = retrieved_manifest.find_by_tag("geography");
println!(
"\nFound {} claims tagged 'geography'",
geography_claims.len()
);
println!("\nProvenance tracking complete!");
Ok(())
}