Skip to main content

batuta/content/
source.rs

1//! Source context (Genchi Genbutsu)
2//!
3//! Source context for grounding content in reality.
4
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8/// Source context for grounding content in reality
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
10pub struct SourceContext {
11    /// Paths to source files/directories
12    pub paths: Vec<PathBuf>,
13    /// Extracted content snippets
14    pub snippets: Vec<SourceSnippet>,
15    /// Total tokens used
16    pub total_tokens: usize,
17}
18
19/// A snippet extracted from source material
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct SourceSnippet {
22    /// Source file path
23    pub path: PathBuf,
24    /// Line range (start, end)
25    pub lines: Option<(usize, usize)>,
26    /// Content
27    pub content: String,
28    /// Estimated tokens
29    pub tokens: usize,
30}
31
32impl SourceContext {
33    /// Create new empty source context
34    pub fn new() -> Self {
35        Self::default()
36    }
37
38    /// Add a path to include
39    pub fn add_path(&mut self, path: PathBuf) {
40        self.paths.push(path);
41    }
42
43    /// Add a snippet
44    pub fn add_snippet(&mut self, snippet: SourceSnippet) {
45        self.total_tokens += snippet.tokens;
46        self.snippets.push(snippet);
47    }
48
49    /// Format for inclusion in prompt
50    pub fn format_for_prompt(&self) -> String {
51        if self.snippets.is_empty() {
52            return String::new();
53        }
54
55        let mut output = String::new();
56        output.push_str("## Source Context (Genchi Genbutsu)\n\n");
57        output.push_str("The following source material must be referenced in your output:\n\n");
58
59        for snippet in &self.snippets {
60            output.push_str(&format!("### {}\n", snippet.path.display()));
61            if let Some((start, end)) = snippet.lines {
62                output.push_str(&format!("Lines {}-{}:\n", start, end));
63            }
64            output.push_str("```\n");
65            output.push_str(&snippet.content);
66            output.push_str("\n```\n\n");
67        }
68
69        output.push_str("**Requirement**: Quote or reference specific line numbers from the source material above.\n\n");
70        output
71    }
72}