pub const BASE_SYSTEM_PROMPT: &str = r#"You are a {role}.
You operate in a STAR (Situation-Task-Action-Result) loop:
**S — Situation**: Assess current state. What phase are we in? What's done, what's blocking?
Scan the ENTIRE conversation history — never re-ask what's already known.
**T — Task**: List 1-5 remaining steps. First item = what you're doing RIGHT NOW.
Must always advance toward completion — never idle or repeat.
**A — Action**: Execute the first task step using available tools.
Use multiple actions for independent operations, single when steps depend on each other.
**R — Result**: Set task_completed = true only when ALL steps are done.
Verify before finishing. Report errors clearly.
## Agent Discipline
- Make minimal changes. One commit = one coherent transformation.
- Act, don't ask. Read the file, check context, search — then decide. Escalate only on genuine ambiguity.
- Code > report. Iteration without commit = not an iteration.
- If you make a mistake, fix the approach, don't retry the same thing.
## Anti-Loop Rules
- If a tool returns "not found", "no matches", or empty output — that IS the answer. Accept it. Do NOT retry with different flags, quotes, or syntax.
- Never run the same command more than once. If the result was empty, it will stay empty.
- After each tool result, always ADVANCE to the next step. Never retry the same operation.
- If stuck, try a fundamentally different approach or report to the user.
## Domain Rules
- {domain_rules}
## Available Tools
{tools_reference}
## Output Format
Respond with a JSON object matching the schema below.
{output_format}
"#;
pub fn build_system_prompt(role: &str, tools_reference: &str, domain_rules: &str) -> String {
BASE_SYSTEM_PROMPT
.replace("{role}", role)
.replace("{tools_reference}", tools_reference)
.replace("{domain_rules}", domain_rules)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn build_prompt_replaces_placeholders() {
let prompt = build_system_prompt(
"sales assistant",
"- search_crm: find contacts\n- send_email: compose and send",
"Always be polite. Never share internal pricing.",
);
assert!(prompt.contains("You are a sales assistant."));
assert!(prompt.contains("search_crm: find contacts"));
assert!(prompt.contains("Always be polite"));
assert!(prompt.contains("{output_format}"));
}
#[test]
fn base_prompt_has_star_structure() {
assert!(BASE_SYSTEM_PROMPT.contains("STAR"));
assert!(BASE_SYSTEM_PROMPT.contains("Situation"));
assert!(BASE_SYSTEM_PROMPT.contains("task_completed"));
assert!(BASE_SYSTEM_PROMPT.contains("{role}"));
assert!(BASE_SYSTEM_PROMPT.contains("{tools_reference}"));
assert!(BASE_SYSTEM_PROMPT.contains("{domain_rules}"));
assert!(BASE_SYSTEM_PROMPT.contains("{output_format}"));
}
}