Skip to main content

bamboo_agent/agent/tools/guide/
context.rs

1//! Context for building tool usage guides.
2//!
3//! This module provides language detection and context building for generating
4//! localized tool usage guidelines that match the language of the system prompt.
5
6/// Language options for guide generation.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum GuideLanguage {
9    Chinese,
10    English,
11}
12
13impl GuideLanguage {
14    /// Detects the language from source text.
15    ///
16    /// Returns `Chinese` if CJK characters are detected, otherwise `English`.
17    pub fn detect(source: &str) -> Self {
18        if source.chars().any(is_cjk) {
19            Self::Chinese
20        } else {
21            Self::English
22        }
23    }
24}
25
26/// Build context for generating tool guides.
27///
28/// Contains language settings and configuration options for guide generation.
29#[derive(Debug, Clone)]
30pub struct GuideBuildContext {
31    /// Detected or configured language for guide content
32    pub language: GuideLanguage,
33    /// Whether to include best practices section
34    pub include_best_practices: bool,
35    /// Maximum number of examples to include per tool
36    pub max_examples_per_tool: usize,
37}
38
39impl Default for GuideBuildContext {
40    fn default() -> Self {
41        Self {
42            language: GuideLanguage::English,
43            include_best_practices: true,
44            max_examples_per_tool: 1,
45        }
46    }
47}
48
49impl GuideBuildContext {
50    /// Creates a build context by detecting language from a system prompt.
51    ///
52    /// # Arguments
53    ///
54    /// * `prompt` - The system prompt to analyze for language detection
55    pub fn from_system_prompt(prompt: &str) -> Self {
56        Self {
57            language: GuideLanguage::detect(prompt),
58            ..Self::default()
59        }
60    }
61
62    /// Returns best practices appropriate for the configured language.
63    pub fn best_practices(&self) -> &'static [&'static str] {
64        match self.language {
65            GuideLanguage::Chinese => &[
66                "Verify the target path exists before reading or writing.",
67                "Search first, then edit, so the impact is explicit.",
68                "Create a todo list for multi-step tasks and keep it updated.",
69                "Use ask_user before destructive actions or unclear decisions.",
70            ],
71            GuideLanguage::English => &[
72                "Verify the target path exists before reading or writing.",
73                "Search first, then edit, so the impact is explicit.",
74                "Create a todo list for multi-step tasks and keep it updated.",
75                "Use ask_user before destructive actions or unclear decisions.",
76            ],
77        }
78    }
79}
80
81fn is_cjk(ch: char) -> bool {
82    matches!(
83        ch,
84        '\u{3400}'..='\u{4DBF}' | '\u{4E00}'..='\u{9FFF}' | '\u{F900}'..='\u{FAFF}'
85    )
86}
87
88#[cfg(test)]
89mod tests {
90    use super::{GuideBuildContext, GuideLanguage};
91
92    #[test]
93    fn detect_language_prefers_chinese_when_cjk_present() {
94        assert_eq!(
95            GuideLanguage::detect("Please help me modify this file"),
96            GuideLanguage::English
97        );
98    }
99
100    #[test]
101    fn detect_language_defaults_to_english_without_cjk() {
102        assert_eq!(
103            GuideLanguage::detect("Please inspect the codebase"),
104            GuideLanguage::English
105        );
106    }
107
108    #[test]
109    fn from_system_prompt_carries_detected_language() {
110        let context = GuideBuildContext::from_system_prompt("You are a coding assistant.");
111        assert_eq!(context.language, GuideLanguage::English);
112    }
113}