1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum GuideLanguage {
9 Chinese,
10 English,
11}
12
13impl GuideLanguage {
14 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#[derive(Debug, Clone)]
30pub struct GuideBuildContext {
31 pub language: GuideLanguage,
33 pub include_best_practices: bool,
35 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: 2,
45 }
46 }
47}
48
49impl GuideBuildContext {
50 pub fn from_system_prompt(prompt: &str) -> Self {
56 Self {
57 language: GuideLanguage::detect(prompt),
58 ..Self::default()
59 }
60 }
61
62 pub fn best_practices(&self) -> &'static [&'static str] {
64 match self.language {
65 GuideLanguage::Chinese => &[
66 "Assist with defensive security tasks only; refuse offensive security requests, credential harvesting, and malware-oriented code changes.",
67 "For multi-step or non-trivial work, use Task to maintain a shared task list and keep statuses updated continuously.",
68 "Keep exactly one Task item in in_progress whenever possible; mark items completed immediately after finishing.",
69 "Read existing files before editing them. Use Edit for targeted replacements and Write only for full-file writes.",
70 "Use Glob for file discovery and Grep for content search. Do not use Bash for find/grep/cat/head/tail/sed/awk/echo style file operations when dedicated tools exist.",
71 "For code search, narrow scope first: Glob -> Grep(files_with_matches) -> Read -> Grep(content/multiline).",
72 "Avoid broad Grep queries; keep head_limit small and add path/glob/type before multiline or content-heavy searches.",
73 "Use Bash only for real terminal operations (build/test/git/npm/docker/etc.), not for file browsing or user-facing communication.",
74 "When multiple Bash commands are independent, run them in parallel tool calls. For dependent commands, chain with &&.",
75 "**Parallel tool calls are strongly preferred.** The following read-only tools can safely run in parallel and SHOULD be called together in the same response whenever possible: FileExists, Glob, GetCurrentDir, GetFileInfo, Grep, Read, WebFetch, WebSearch, recall. For example, if you need to read 3 files, emit all 3 Read calls in one response instead of one at a time.",
76 "For commit requests: inspect git status, git diff, and recent git log first; commit only when explicitly requested; avoid interactive git flags; use HEREDOC for multi-line commit messages.",
77 "For pull request requests: review all commits/diff since base branch, use gh to create PR with summary and test plan, and return the PR URL.",
78 "When referencing code locations in responses, use file_path:line_number format.",
79 "Use ExitPlanMode before switching from planning to implementation.",
80 ],
81 GuideLanguage::English => &[
82 "Assist with defensive security tasks only; refuse offensive security requests, credential harvesting, and malware-oriented code changes.",
83 "For multi-step or non-trivial work, use Task to maintain a shared task list and keep statuses updated continuously.",
84 "Keep exactly one Task item in in_progress whenever possible; mark items completed immediately after finishing.",
85 "Read existing files before editing them. Use Edit for targeted replacements and Write only for full-file writes.",
86 "Use Glob for file discovery and Grep for content search. Do not use Bash for find/grep/cat/head/tail/sed/awk/echo style file operations when dedicated tools exist.",
87 "For code search, narrow scope first: Glob -> Grep(files_with_matches) -> Read -> Grep(content/multiline).",
88 "Avoid broad Grep queries; keep head_limit small and add path/glob/type before multiline or content-heavy searches.",
89 "Use Bash only for real terminal operations (build/test/git/npm/docker/etc.), not for file browsing or user-facing communication.",
90 "When multiple Bash commands are independent, run them in parallel tool calls. For dependent commands, chain with &&.",
91 "**Parallel tool calls are strongly preferred.** The following read-only tools can safely run in parallel and SHOULD be called together in the same response whenever possible: FileExists, Glob, GetCurrentDir, GetFileInfo, Grep, Read, WebFetch, WebSearch, recall. For example, if you need to read 3 files, emit all 3 Read calls in one response instead of one at a time.",
92 "For commit requests: inspect git status, git diff, and recent git log first; commit only when explicitly requested; avoid interactive git flags; use HEREDOC for multi-line commit messages.",
93 "For pull request requests: review all commits/diff since base branch, use gh to create PR with summary and test plan, and return the PR URL.",
94 "When referencing code locations in responses, use file_path:line_number format.",
95 "Use ExitPlanMode before switching from planning to implementation.",
96 ],
97 }
98 }
99}
100
101fn is_cjk(ch: char) -> bool {
102 matches!(
103 ch,
104 '\u{3400}'..='\u{4DBF}' | '\u{4E00}'..='\u{9FFF}' | '\u{F900}'..='\u{FAFF}'
105 )
106}
107
108#[cfg(test)]
109mod tests {
110 use super::{GuideBuildContext, GuideLanguage};
111
112 #[test]
113 fn detect_language_prefers_chinese_when_cjk_present() {
114 assert_eq!(
115 GuideLanguage::detect("Please help me modify this file"),
116 GuideLanguage::English
117 );
118 }
119
120 #[test]
121 fn detect_language_defaults_to_english_without_cjk() {
122 assert_eq!(
123 GuideLanguage::detect("Please inspect the codebase"),
124 GuideLanguage::English
125 );
126 }
127
128 #[test]
129 fn from_system_prompt_carries_detected_language() {
130 let context = GuideBuildContext::from_system_prompt("You are a coding assistant.");
131 assert_eq!(context.language, GuideLanguage::English);
132 }
133}