1use serde::Serialize;
2
3use crate::ast::PgnPacket;
4use crate::resolver::{ResolvedRef, ResolutionStatus};
5
6#[derive(Debug, Serialize)]
7pub struct ContextPlan {
8 pub run_id: String,
9 pub primary_refs: Vec<ContextRef>,
10 pub retrieval_methods: Vec<String>,
11 pub token_budget: usize,
12 pub compression_allowed: bool,
13}
14
15#[derive(Debug, Serialize)]
16pub struct ContextRef {
17 pub reference: String,
18 pub resolved: bool,
19 pub path: Option<String>,
20}
21
22pub fn build_context_plan(packet: &PgnPacket, resolved: &[ResolvedRef]) -> ContextPlan {
23 let primary_refs: Vec<ContextRef> = resolved
24 .iter()
25 .map(|r| ContextRef {
26 reference: r.original.clone(),
27 resolved: matches!(r.status, ResolutionStatus::Resolved),
28 path: r
29 .resolved_path
30 .as_ref()
31 .map(|p| p.display().to_string()),
32 })
33 .collect();
34
35 let total_chars: usize = resolved
36 .iter()
37 .map(|r| r.original.len())
38 .sum();
39 let token_budget = total_chars.div_ceil(4);
40
41 ContextPlan {
42 run_id: packet.run_id.clone(),
43 primary_refs,
44 retrieval_methods: vec![
45 "direct_path".to_string(),
46 "full_text".to_string(),
47 ],
48 token_budget: token_budget.max(1000),
49 compression_allowed: true,
50 }
51}