llm_coding_tools_core/context/
mod.rs

1//! Tool context strings for LLM agents.
2//!
3//! These provide usage guidance, best practices, and behavioral instructions
4//! for LLM agents when using coding tools. Context strings are sourced from
5//! OpenCode's tool documentation.
6//!
7//! # Path-based Tools
8//!
9//! Tools operating on file paths have two variants:
10//! - `*_ABSOLUTE`: For unrestricted filesystem access (absolute paths required)
11//! - `*_ALLOWED`: For sandboxed access (paths relative to allowed directories)
12//!
13//! # Example
14//!
15//! ```rust
16//! use llm_coding_tools_core::context::{BASH, READ_ABSOLUTE, READ_ALLOWED};
17//!
18//! // Use BASH context for bash tool
19//! println!("Bash guidance: {}", BASH);
20//!
21//! // Use appropriate read context based on path resolver
22//! let sandboxed = true;
23//! let read_context = if sandboxed { READ_ALLOWED } else { READ_ABSOLUTE };
24//! ```
25
26/// Bash tool context - shell command execution guidance.
27pub const BASH: &str = include_str!("bash.txt");
28
29/// Git workflow context - commit creation guidance.
30///
31/// Supplemental context for agents using git via the Bash tool.
32/// Include via [`SystemPromptBuilder::add_context`](crate::SystemPromptBuilder::add_context).
33pub const GIT_WORKFLOW: &str = include_str!("git_workflow.txt");
34
35/// GitHub CLI context - gh command usage guidance.
36///
37/// Supplemental context for agents using the GitHub CLI via the Bash tool.
38/// Include via [`SystemPromptBuilder::add_context`](crate::SystemPromptBuilder::add_context).
39pub const GITHUB_CLI: &str = include_str!("github_cli.txt");
40
41/// Todo read tool context - reading task lists.
42pub const TODO_READ: &str = include_str!("todoread.txt");
43
44/// Todo write tool context - managing task lists.
45pub const TODO_WRITE: &str = include_str!("todowrite.txt");
46
47/// Webfetch tool context - URL content retrieval.
48pub const WEBFETCH: &str = include_str!("webfetch.txt");
49
50/// Read tool context for absolute path mode.
51pub const READ_ABSOLUTE: &str = include_str!("read_absolute.txt");
52
53/// Read tool context for allowed/sandboxed path mode.
54pub const READ_ALLOWED: &str = include_str!("read_allowed.txt");
55
56/// Write tool context for absolute path mode.
57pub const WRITE_ABSOLUTE: &str = include_str!("write_absolute.txt");
58
59/// Write tool context for allowed/sandboxed path mode.
60pub const WRITE_ALLOWED: &str = include_str!("write_allowed.txt");
61
62/// Edit tool context for absolute path mode.
63pub const EDIT_ABSOLUTE: &str = include_str!("edit_absolute.txt");
64
65/// Edit tool context for allowed/sandboxed path mode.
66pub const EDIT_ALLOWED: &str = include_str!("edit_allowed.txt");
67
68/// Glob tool context for absolute path mode.
69pub const GLOB_ABSOLUTE: &str = include_str!("glob_absolute.txt");
70
71/// Glob tool context for allowed/sandboxed path mode.
72pub const GLOB_ALLOWED: &str = include_str!("glob_allowed.txt");
73
74/// Grep tool context for absolute path mode.
75pub const GREP_ABSOLUTE: &str = include_str!("grep_absolute.txt");
76
77/// Grep tool context for allowed/sandboxed path mode.
78pub const GREP_ALLOWED: &str = include_str!("grep_allowed.txt");
79
80/// Trait for tools that provide usage context for LLM system prompts.
81///
82/// Implement this trait on tool types (for frameworks like rig) to enable automatic system prompt
83/// generation via [`SystemPromptBuilder`](crate::SystemPromptBuilder).
84///
85/// # Example
86///
87/// ```rust
88/// use llm_coding_tools_core::context::ToolContext;
89///
90/// struct MyTool;
91///
92/// impl ToolContext for MyTool {
93///     const NAME: &'static str = "mytool";
94///
95///     fn context(&self) -> &'static str {
96///         "Instructions for using MyTool..."
97///     }
98/// }
99/// ```
100pub trait ToolContext {
101    /// Tool name used for section headers in generated system prompt.
102    ///
103    /// Should be lowercase (e.g., "read", "bash", "glob").
104    /// SystemPromptBuilder capitalizes this for display.
105    const NAME: &'static str;
106
107    /// Returns the tool's context string for system prompt generation.
108    ///
109    /// This should return one of the context constants from this module.
110    fn context(&self) -> &'static str;
111}
112
113#[cfg(test)]
114mod tests {
115    use super::*;
116
117    #[test]
118    fn context_strings_are_not_empty() {
119        // Non-path tools
120        assert!(!BASH.is_empty(), "BASH context should not be empty");
121        assert!(
122            !GIT_WORKFLOW.is_empty(),
123            "GIT_WORKFLOW context should not be empty"
124        );
125        assert!(
126            !GITHUB_CLI.is_empty(),
127            "GITHUB_CLI context should not be empty"
128        );
129        assert!(
130            !TODO_READ.is_empty(),
131            "TODO_READ context should not be empty"
132        );
133        assert!(
134            !TODO_WRITE.is_empty(),
135            "TODO_WRITE context should not be empty"
136        );
137        assert!(!WEBFETCH.is_empty(), "WEBFETCH context should not be empty");
138
139        // Path-based tools (absolute variants)
140        assert!(
141            !READ_ABSOLUTE.is_empty(),
142            "READ_ABSOLUTE context should not be empty"
143        );
144        assert!(
145            !WRITE_ABSOLUTE.is_empty(),
146            "WRITE_ABSOLUTE context should not be empty"
147        );
148        assert!(
149            !EDIT_ABSOLUTE.is_empty(),
150            "EDIT_ABSOLUTE context should not be empty"
151        );
152        assert!(
153            !GLOB_ABSOLUTE.is_empty(),
154            "GLOB_ABSOLUTE context should not be empty"
155        );
156        assert!(
157            !GREP_ABSOLUTE.is_empty(),
158            "GREP_ABSOLUTE context should not be empty"
159        );
160
161        // Path-based tools (allowed variants)
162        assert!(
163            !READ_ALLOWED.is_empty(),
164            "READ_ALLOWED context should not be empty"
165        );
166        assert!(
167            !WRITE_ALLOWED.is_empty(),
168            "WRITE_ALLOWED context should not be empty"
169        );
170        assert!(
171            !EDIT_ALLOWED.is_empty(),
172            "EDIT_ALLOWED context should not be empty"
173        );
174        assert!(
175            !GLOB_ALLOWED.is_empty(),
176            "GLOB_ALLOWED context should not be empty"
177        );
178        assert!(
179            !GREP_ALLOWED.is_empty(),
180            "GREP_ALLOWED context should not be empty"
181        );
182    }
183
184    #[test]
185    fn absolute_variants_mention_absolute_path() {
186        assert!(
187            READ_ABSOLUTE.contains("absolute path"),
188            "READ_ABSOLUTE should mention absolute path"
189        );
190    }
191
192    #[test]
193    fn allowed_variants_mention_allowed_directories() {
194        assert!(
195            READ_ALLOWED.contains("allowed directories"),
196            "READ_ALLOWED should mention allowed directories"
197        );
198        assert!(
199            WRITE_ALLOWED.contains("allowed directories"),
200            "WRITE_ALLOWED should mention allowed directories"
201        );
202        assert!(
203            EDIT_ALLOWED.contains("allowed directories"),
204            "EDIT_ALLOWED should mention allowed directories"
205        );
206        assert!(
207            GLOB_ALLOWED.contains("allowed directories"),
208            "GLOB_ALLOWED should mention allowed directories"
209        );
210        assert!(
211            GREP_ALLOWED.contains("allowed directories"),
212            "GREP_ALLOWED should mention allowed directories"
213        );
214    }
215
216    #[test]
217    fn git_workflow_contains_expected_content() {
218        assert!(
219            GIT_WORKFLOW.contains("git commit"),
220            "GIT_WORKFLOW should mention git commit"
221        );
222        assert!(
223            GIT_WORKFLOW.contains("NEVER"),
224            "GIT_WORKFLOW should contain safety rules"
225        );
226    }
227
228    #[test]
229    fn github_cli_contains_expected_content() {
230        assert!(
231            GITHUB_CLI.contains("gh "),
232            "GITHUB_CLI should mention gh command"
233        );
234        assert!(
235            GITHUB_CLI.contains("pull request"),
236            "GITHUB_CLI should mention pull requests"
237        );
238    }
239
240    #[test]
241    fn bash_does_not_contain_git_workflow() {
242        assert!(
243            !BASH.contains("# Committing changes with git"),
244            "BASH should not contain git workflow section"
245        );
246    }
247
248    #[test]
249    fn bash_does_not_contain_github_cli() {
250        assert!(
251            !BASH.contains("# Creating pull requests"),
252            "BASH should not contain GitHub CLI section"
253        );
254    }
255}