Skip to content

Commit 70ca5c1

Browse files
authored
Merge pull request #17 from Sewer56/rework-preamble-builder-2
Enhance PreambleBuilder with system_prompt, add_context, and allowed_paths support
2 parents 0222c3c + 1878ff0 commit 70ca5c1

41 files changed

Lines changed: 1542 additions & 518 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/.cargo/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build]
2+
rustdocflags = ["-D", "warnings"]

src/.cargo/verify.ps1

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Post-change verification script
2+
# All steps must pass without warnings
3+
# Keep in sync with verify.sh
4+
#
5+
# Note: llm-coding-tools-rig and llm-coding-tools-serdesai are async-only (implement async Tool traits).
6+
# The blocking feature only applies to llm-coding-tools-core.
7+
8+
$ErrorActionPreference = "Stop"
9+
10+
Write-Host "Building..."
11+
cargo build -p llm-coding-tools-core
12+
cargo build -p llm-coding-tools-rig --quiet
13+
cargo build -p llm-coding-tools-serdesai --quiet
14+
15+
Write-Host "Testing..."
16+
cargo test -p llm-coding-tools-core
17+
cargo test -p llm-coding-tools-rig --quiet
18+
cargo test -p llm-coding-tools-serdesai --quiet
19+
20+
Write-Host "Clippy..."
21+
cargo clippy -p llm-coding-tools-core -- -D warnings
22+
cargo clippy -p llm-coding-tools-rig --quiet -- -D warnings
23+
cargo clippy -p llm-coding-tools-serdesai --quiet -- -D warnings
24+
25+
Write-Host "Testing blocking feature..."
26+
cargo test -p llm-coding-tools-core --no-default-features --features blocking --quiet
27+
28+
Write-Host "Docs..."
29+
cargo doc --workspace --no-deps --quiet
30+
31+
Write-Host "Formatting..."
32+
cargo fmt --all
33+
34+
Write-Host "Publish dry-run..."
35+
cargo publish --dry-run -p llm-coding-tools-core --quiet
36+
cargo publish --dry-run -p llm-coding-tools-rig --quiet
37+
cargo publish --dry-run -p llm-coding-tools-serdesai --quiet
38+
39+
Write-Host "All checks passed!"

src/.cargo/verify.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
# Post-change verification script
3+
# All steps must pass without warnings
4+
# Keep in sync with verify.ps1
5+
#
6+
# Note: llm-coding-tools-rig and llm-coding-tools-serdesai are async-only (implement async Tool traits).
7+
# The blocking feature only applies to llm-coding-tools-core.
8+
9+
set -e
10+
11+
echo "Building..."
12+
cargo build -p llm-coding-tools-core
13+
cargo build -p llm-coding-tools-rig --quiet
14+
cargo build -p llm-coding-tools-serdesai --quiet
15+
16+
echo "Testing..."
17+
cargo test -p llm-coding-tools-core
18+
cargo test -p llm-coding-tools-rig --quiet
19+
cargo test -p llm-coding-tools-serdesai --quiet
20+
21+
echo "Clippy..."
22+
cargo clippy -p llm-coding-tools-core -- -D warnings
23+
cargo clippy -p llm-coding-tools-rig --quiet -- -D warnings
24+
cargo clippy -p llm-coding-tools-serdesai --quiet -- -D warnings
25+
26+
echo "Testing blocking feature..."
27+
cargo test -p llm-coding-tools-core --no-default-features --features blocking --quiet
28+
29+
echo "Docs..."
30+
cargo doc --workspace --no-deps --quiet
31+
32+
echo "Formatting..."
33+
cargo fmt --all
34+
35+
echo "Publish dry-run..."
36+
cargo publish --dry-run -p llm-coding-tools-core --quiet
37+
cargo publish --dry-run -p llm-coding-tools-rig --quiet
38+
cargo publish --dry-run -p llm-coding-tools-serdesai --quiet
39+
40+
echo "All checks passed!"

src/AGENTS.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,4 @@ This is a high-performance library. Optimize aggressively.
7272

7373
# Post-Change Verification
7474

75-
All must pass without warnings:
76-
77-
```bash
78-
cargo build -p llm-coding-tools-core && cargo build -p llm-coding-tools-rig --quiet && cargo build -p llm-coding-tools-serdesai --quiet && cargo test -p llm-coding-tools-core && cargo test -p llm-coding-tools-rig --quiet && cargo test -p llm-coding-tools-serdesai --quiet && cargo clippy -p llm-coding-tools-core -- -D warnings && cargo clippy -p llm-coding-tools-rig --quiet -- -D warnings && cargo clippy -p llm-coding-tools-serdesai --quiet -- -D warnings && cargo test -p llm-coding-tools-core --no-default-features --features blocking --quiet && cargo doc --workspace --no-deps --quiet && cargo fmt --all
79-
```
80-
81-
Note: `llm-coding-tools-rig` and `llm-coding-tools-serdesai` are async-only (implement async `Tool` traits).
82-
The `blocking` feature only applies to `llm-coding-tools-core`.
83-
84-
For individual crates:
85-
```bash
86-
cargo publish --dry-run -p llm-coding-tools-core --quiet && cargo publish --dry-run -p llm-coding-tools-rig --quiet && cargo publish --dry-run -p llm-coding-tools-serdesai --quiet
87-
```
75+
All must pass without warnings. Run: `.cargo/verify.sh` (or `.cargo/verify.ps1` on Windows)
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//! Preamble preview - demonstrates full preamble generation.
2+
//!
3+
//! Shows how PreambleBuilder combines:
4+
//! - Custom system prompts
5+
//! - Environment section (working directory, allowed paths)
6+
//! - Tool usage guidelines (from tracked tools)
7+
//! - Supplemental context (git workflow, GitHub CLI)
8+
//!
9+
//! Run: cargo run --example preamble_preview -p llm-coding-tools-core
10+
11+
use llm_coding_tools_core::context::ToolContext;
12+
use llm_coding_tools_core::{context, AllowedPathResolver, PreambleBuilder};
13+
14+
fn main() {
15+
// Use from_canonical to avoid filesystem requirements for the example.
16+
// In real usage, AllowedPathResolver::new() canonicalizes and validates paths.
17+
let resolver = AllowedPathResolver::from_canonical(["/home/user/project", "/tmp"]);
18+
19+
// Build preamble with all features demonstrated
20+
let mut pb = PreambleBuilder::new()
21+
.system_prompt(
22+
"# System Instructions\n\n\
23+
You are a helpful coding assistant. Follow best practices and \
24+
write clean, maintainable code.",
25+
)
26+
.working_directory("/home/user/project")
27+
.allowed_paths(&resolver)
28+
.add_context("Git Workflow", context::GIT_WORKFLOW)
29+
.add_context("GitHub CLI", context::GITHUB_CLI);
30+
31+
// Track tools - in real usage this would be:
32+
// .tool(pb.track(ReadTool::new()))
33+
// For the preview, we just register them without using the returned tool.
34+
let _ = pb.track(MockReadTool);
35+
let _ = pb.track(MockWriteTool);
36+
let _ = pb.track(MockEditTool);
37+
let _ = pb.track(MockBashTool);
38+
let _ = pb.track(MockGlobTool);
39+
let _ = pb.track(MockGrepTool);
40+
let _ = pb.track(MockWebFetchTool);
41+
let _ = pb.track(MockTodoWriteTool);
42+
let _ = pb.track(MockTodoReadTool);
43+
44+
let preamble = pb.build();
45+
46+
// Output the preamble
47+
println!("{preamble}");
48+
49+
// Show statistics for token estimation
50+
println!("\n{}", "=".repeat(60));
51+
println!("Statistics:");
52+
println!(" Characters: {}", preamble.len());
53+
println!(" Lines: {}", preamble.lines().count());
54+
println!(" Estimated tokens: ~{} (chars/4)", preamble.len() / 4);
55+
}
56+
57+
// Mock tools implementing ToolContext for demonstration.
58+
// In real usage, these would be actual tool structs from llm-coding-tools-rig.
59+
60+
struct MockReadTool;
61+
impl ToolContext for MockReadTool {
62+
const NAME: &'static str = "read";
63+
fn context(&self) -> &'static str {
64+
context::READ_ALLOWED
65+
}
66+
}
67+
68+
struct MockWriteTool;
69+
impl ToolContext for MockWriteTool {
70+
const NAME: &'static str = "write";
71+
fn context(&self) -> &'static str {
72+
context::WRITE_ALLOWED
73+
}
74+
}
75+
76+
struct MockEditTool;
77+
impl ToolContext for MockEditTool {
78+
const NAME: &'static str = "edit";
79+
fn context(&self) -> &'static str {
80+
context::EDIT_ALLOWED
81+
}
82+
}
83+
84+
struct MockBashTool;
85+
impl ToolContext for MockBashTool {
86+
const NAME: &'static str = "bash";
87+
fn context(&self) -> &'static str {
88+
context::BASH
89+
}
90+
}
91+
92+
struct MockGlobTool;
93+
impl ToolContext for MockGlobTool {
94+
const NAME: &'static str = "glob";
95+
fn context(&self) -> &'static str {
96+
context::GLOB_ALLOWED
97+
}
98+
}
99+
100+
struct MockGrepTool;
101+
impl ToolContext for MockGrepTool {
102+
const NAME: &'static str = "grep";
103+
fn context(&self) -> &'static str {
104+
context::GREP_ALLOWED
105+
}
106+
}
107+
108+
struct MockWebFetchTool;
109+
impl ToolContext for MockWebFetchTool {
110+
const NAME: &'static str = "webfetch";
111+
fn context(&self) -> &'static str {
112+
context::WEBFETCH
113+
}
114+
}
115+
116+
struct MockTodoWriteTool;
117+
impl ToolContext for MockTodoWriteTool {
118+
const NAME: &'static str = "todowrite";
119+
fn context(&self) -> &'static str {
120+
context::TODO_WRITE
121+
}
122+
}
123+
124+
struct MockTodoReadTool;
125+
impl ToolContext for MockTodoReadTool {
126+
const NAME: &'static str = "todoread";
127+
fn context(&self) -> &'static str {
128+
context::TODO_READ
129+
}
130+
}

src/llm-coding-tools-core/src/context/bash.txt

Lines changed: 38 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -6,115 +6,41 @@ IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO N
66

77
Before executing the command, please follow these steps:
88

9-
1. Directory Verification:
10-
- If the command will create new directories or files, first use `ls` to verify the parent directory exists and is the correct location
11-
- For example, before running "mkdir foo/bar", first use `ls foo` to check that "foo" exists and is the intended parent directory
12-
13-
2. Command Execution:
14-
- Always quote file paths that contain spaces with double quotes (e.g., rm "path with spaces/file.txt")
15-
- Examples of proper quoting:
16-
- mkdir "/Users/name/My Documents" (correct)
17-
- mkdir /Users/name/My Documents (incorrect - will fail)
18-
- python "/path/with spaces/script.py" (correct)
19-
- python /path/with spaces/script.py (incorrect - will fail)
20-
- After ensuring proper quoting, execute the command.
21-
- Capture the output of the command.
22-
23-
Usage notes:
24-
- The `command` argument is required.
25-
- You can specify an optional `timeout_ms` in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 120000ms (2 minutes).
26-
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
27-
- If the output exceeds 30000 characters, output will be truncated before being returned to you.
28-
29-
- Avoid using Bash with the `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
30-
- File search: Use Glob (NOT find or ls)
31-
- Content search: Use Grep (NOT grep)
32-
- Read files: Use Read (NOT cat/head/tail)
33-
- Edit files: Use Edit (NOT sed/awk)
34-
- Write files: Use Write (NOT echo >/cat <<EOF)
35-
- Communication: Output text directly (NOT echo/printf)
36-
- When issuing multiple commands:
37-
- If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel.
38-
- If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., `git add . && git commit -m "message" && git push`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead.
39-
- Use ';' only when you need to run commands sequentially but don't care if earlier commands fail
40-
- DO NOT use newlines to separate commands (newlines are ok in quoted strings)
41-
- AVOID using `cd <directory> && <command>`. Use the `workdir` parameter to change directories instead.
42-
<good-example>
43-
Use workdir="/foo/bar" with command: pytest tests
44-
</good-example>
45-
<bad-example>
46-
cd /foo/bar && pytest tests
47-
</bad-example>
48-
49-
# Committing changes with git
50-
51-
Only create commits when requested by the user. If unclear, ask first. When the user asks you to create a new git commit, follow these steps carefully:
52-
53-
Git Safety Protocol:
54-
- NEVER update the git config
55-
- NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them
56-
- NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it
57-
- NEVER run force push to main/master, warn the user if they request it
58-
- Avoid git commit --amend. ONLY use --amend when ALL conditions are met:
59-
(1) User explicitly requested amend, OR commit SUCCEEDED but pre-commit hook auto-modified files that need including
60-
(2) HEAD commit was created by you in this conversation (verify: git log -1 --format='%an %ae')
61-
(3) Commit has NOT been pushed to remote (verify: git status shows "Your branch is ahead")
62-
- CRITICAL: If commit FAILED or was REJECTED by hook, NEVER amend - fix the issue and create a NEW commit
63-
- CRITICAL: If you already pushed to remote, NEVER amend unless user explicitly requests it (requires force push)
64-
- NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive.
65-
66-
1. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following bash commands in parallel, each using the Bash tool:
67-
- Run a git status command to see all untracked files.
68-
- Run a git diff command to see both staged and unstaged changes that will be committed.
69-
- Run a git log command to see recent commit messages, so that you can follow this repository's commit message style.
70-
2. Analyze all staged changes (both previously staged and newly added) and draft a commit message:
71-
- Summarize the nature of the changes (eg. new feature, enhancement to an existing feature, bug fix, refactoring, test, docs, etc.). Ensure the message accurately reflects the changes and their purpose (i.e. "add" means a wholly new feature, "update" means an enhancement to an existing feature, "fix" means a bug fix, etc.).
72-
- Do not commit files that likely contain secrets (.env, credentials.json, etc.). Warn the user if they specifically request to commit those files
73-
- Draft a concise (1-2 sentences) commit message that focuses on the "why" rather than the "what"
74-
- Ensure it accurately reflects the changes and their purpose
75-
3. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following commands:
76-
- Add relevant untracked files to the staging area.
77-
- Create the commit with a message
78-
- Run git status after the commit completes to verify success.
79-
Note: git status depends on the commit completing, so run it sequentially after the commit.
80-
4. If the commit fails due to pre-commit hook, fix the issue and create a NEW commit (see amend rules above)
81-
82-
Important notes:
83-
- NEVER run additional commands to read or explore code, besides git bash commands
84-
- NEVER use the TodoWrite or Task tools
85-
- DO NOT push to the remote repository unless the user explicitly asks you to do so
86-
- IMPORTANT: Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported.
87-
- If there are no changes to commit (i.e., no untracked files and no modifications), do not create an empty commit
88-
89-
# Creating pull requests
90-
Use the gh command via the Bash tool for ALL GitHub-related tasks including working with issues, pull requests, checks, and releases. If given a Github URL use the gh command to get the information needed.
91-
92-
IMPORTANT: When the user asks you to create a pull request, follow these steps carefully:
93-
94-
1. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following bash commands in parallel using the Bash tool, in order to understand the current state of the branch since it diverged from the main branch:
95-
- Run a git status command to see all untracked files
96-
- Run a git diff command to see both staged and unstaged changes that will be committed
97-
- Check if the current branch tracks a remote branch and is up to date with the remote, so you know if you need to push to the remote
98-
- Run a git log command and `git diff [base-branch]...HEAD` to understand the full commit history for the current branch (from the time it diverged from the base branch)
99-
2. Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request!!!), and draft a pull request summary
100-
3. You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. run the following commands in parallel:
101-
- Create new branch if needed
102-
- Push to remote with -u flag if needed
103-
- Create PR using gh pr create with the format below. Use a HEREDOC to pass the body to ensure correct formatting.
104-
<example>
105-
gh pr create --title "the pr title" --body "$(cat <<'EOF'
106-
## Summary
107-
<1-3 bullet points>
108-
109-
## Test plan
110-
[Bulleted markdown checklist of TODOs for testing the pull request...]
111-
EOF
112-
)"
113-
</example>
114-
115-
Important:
116-
- DO NOT use the TodoWrite or Task tools
117-
- Return the PR URL when you're done, so the user can see it
118-
119-
# Other common operations
120-
- View comments on a Github PR: gh api repos/foo/bar/pulls/123/comments
9+
#### Directory Verification
10+
- If the command will create new directories or files, first use `ls` to verify the parent directory exists and is the correct location
11+
- For example, before running "mkdir foo/bar", first use `ls foo` to check that "foo" exists and is the intended parent directory
12+
13+
#### Command Execution
14+
- Always quote file paths that contain spaces with double quotes (e.g., rm "path with spaces/file.txt")
15+
- Examples of proper quoting:
16+
- mkdir "/Users/name/My Documents" (correct)
17+
- mkdir /Users/name/My Documents (incorrect - will fail)
18+
- python "/path/with spaces/script.py" (correct)
19+
- python /path/with spaces/script.py (incorrect - will fail)
20+
- After ensuring proper quoting, execute the command.
21+
- Capture the output of the command.
22+
23+
##### Usage notes
24+
- The `command` argument is required.
25+
- You can specify an optional `timeout_ms` in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 120000ms (2 minutes).
26+
- It is very helpful if you write a clear, concise description of what this command does in 5-10 words.
27+
- If the output exceeds 30000 characters, output will be truncated before being returned to you.
28+
- Avoid using Bash with the `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:
29+
- File search: Use Glob (NOT find or ls)
30+
- Content search: Use Grep (NOT grep)
31+
- Read files: Use Read (NOT cat/head/tail)
32+
- Edit files: Use Edit (NOT sed/awk)
33+
- Write files: Use Write (NOT echo >/cat <<EOF)
34+
- Communication: Output text directly (NOT echo/printf)
35+
- When issuing multiple commands:
36+
- If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel.
37+
- If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., `git add . && git commit -m "message" && git push`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead.
38+
- Use ';' only when you need to run commands sequentially but don't care if earlier commands fail
39+
- DO NOT use newlines to separate commands (newlines are ok in quoted strings)
40+
- AVOID using `cd <directory> && <command>`. Use the `workdir` parameter to change directories instead.
41+
<good-example>
42+
Use workdir="/foo/bar" with command: pytest tests
43+
</good-example>
44+
<bad-example>
45+
cd /foo/bar && pytest tests
46+
</bad-example>

0 commit comments

Comments
 (0)