use std::path::Path;
use rhema_agent_tools::{ShellTools, render_system};
pub const DEFAULT_SYSTEM_MD: &str = include_str!("../SYSTEM.md");
pub fn default_system(workspace: &Path) -> String {
render_system(
DEFAULT_SYSTEM_MD,
workspace,
&[],
&ShellTools::builtin_specs(),
)
.expect("the built-in template is valid")
}
#[cfg(test)]
mod tests {
use super::*;
use rhema_core::ToolSpec;
use serde_json::json;
fn skill(name: &str, description: &str) -> rhema_agent_tools::Skill {
rhema_agent_tools::Skill {
name: name.into(),
description: description.into(),
license: None,
path: format!("/cfg/skills/{name}/SKILL.md").into(),
body: "the rules".into(),
}
}
fn tool(name: &str, description: &str) -> ToolSpec {
ToolSpec::new(
name,
description,
json!({
"type": "object",
"properties": { "command": { "type": "string" } },
"required": ["command"]
}),
)
}
#[test]
fn the_default_prompt_resolves_every_marker_and_ends_with_one_newline() {
let out = default_system(Path::new("/ws"));
assert!(!out.contains("{{") && !out.contains("{%"), "{out}");
assert!(!out.contains("/ws"), "{out}");
assert!(out.ends_with('\n') && !out.ends_with("\n\n"), "{out}");
}
#[test]
fn the_default_prompt_presents_each_skill_field_to_the_model() {
let out = render_system(
DEFAULT_SYSTEM_MD,
Path::new("/ws"),
&[skill("my-skill", "its trigger text")],
&[],
)
.unwrap();
assert!(out.contains("my-skill"), "{out}");
assert!(out.contains("its trigger text"), "{out}");
assert!(out.contains("/cfg/skills/my-skill/SKILL.md"), "{out}");
}
#[test]
fn the_default_prompt_presents_each_tool_field_to_the_model() {
let out = render_system(
DEFAULT_SYSTEM_MD,
Path::new("/ws"),
&[],
&[tool("my-tool", "its purpose")],
)
.unwrap();
assert!(out.contains("my-tool"), "{out}");
assert!(out.contains("its purpose"), "{out}");
assert!(
out.contains(r#""required":["command"]"#),
"the JSON schema rendered: {out}"
);
}
#[test]
fn a_multi_line_description_stays_inside_its_bullet() {
let out = render_system(
DEFAULT_SYSTEM_MD,
Path::new("/ws"),
&[],
&[tool(
"my-tool",
"its purpose.\n\nSubagents, by name:\n- one: does a thing",
)],
)
.unwrap();
assert!(out.contains("- my-tool | {"), "{out}");
assert!(out.contains("\n its purpose."), "{out}");
assert!(out.contains("\n Subagents, by name:"), "{out}");
assert!(out.contains("\n - one: does a thing"), "{out}");
assert!(!out.contains("\nSubagents, by name:"), "{out}");
}
#[test]
fn the_default_prompt_names_the_built_in_bash_tool() {
let out = default_system(Path::new("/ws"));
assert!(out.contains("bash"), "{out}");
assert!(out.contains("Run a shell command (`bash -c`)"), "{out}");
}
}