Skip to main content

a_agent/context/
builder.rs

1use std::fmt::Write;
2use std::path::PathBuf;
3
4use super::{AgentsFile, SkillMetadata};
5
6#[derive(Debug, Clone)]
7pub struct ContextInput {
8    pub cwd: PathBuf,
9    pub agents: Vec<AgentsFile>,
10    pub skills: Vec<SkillMetadata>,
11    pub platform: String,
12    pub shell: String,
13}
14
15pub fn build_system_prompt(input: &ContextInput) -> String {
16    let mut prompt = format!(
17        "You are a coding agent operating in {}.\n\n\
18         Inspect only what you need. Prefer minimal, targeted changes.\n\
19         Use tools only when the request requires workspace facts or actions. Answer simple conversation, formatting, and direct-answer requests without tools. Never inspect the workspace merely because it is available.\n\
20         Use read to inspect files before editing. Use apply_patch for file edits.\n\
21         Relative read and apply_patch paths are resolved from the cwd; absolute paths and parent traversal are allowed.\n\
22         Use bash for search, git, build, tests, and other shell operations.\n\
23         Before any git command, first confirm that .git exists; otherwise do not run git.\n\n\
24         When independent tool calls can run in parallel, issue them together.\n\
25         Do not parallelize dependent or conflicting mutations.\n\n\
26         Follow all active AGENTS.md instructions.\n\
27         After modifying code, run relevant validation when practical.\n",
28        input.cwd.display()
29    );
30    prompt.push_str(
31        "The Fish script records command metadata in SQLite. The Rust runtime injects recent records from the current Fish session and cwd into each request under `Runtime shell context`. Commands listed there are directly visible to you. Do not claim that the integration lacks context injection or that you cannot see listed commands. Bash tool calls in the conversation are also visible to you.\n",
32    );
33
34    if !input.agents.is_empty() {
35        prompt.push_str("\nActive AGENTS.md instructions:\n");
36        for file in &input.agents {
37            let _ = write!(prompt, "\n# {}\n{}\n", file.path.display(), file.content);
38        }
39    }
40    if !input.skills.is_empty() {
41        prompt.push_str(
42            "\nAvailable Skills. Each one lists only its name and description; when a task matches a description, read the SKILL.md at the listed path before proceeding. Resolve relative paths inside a skill against that skill's own directory, which is the parent of its SKILL.md, and pass absolute paths to tools.\n",
43        );
44        for skill in &input.skills {
45            let _ = write!(
46                prompt,
47                "- {}\n  {}\n  Path: {}\n",
48                skill.name,
49                skill.description,
50                skill.path.display()
51            );
52        }
53    }
54    let _ = write!(
55        prompt,
56        "\nEnvironment:\n- platform: {}\n- shell: {}\n",
57        input.platform, input.shell
58    );
59    prompt
60}