pub mod fragments;
use agent_works::prompt::{FragmentContext, PromptFragment, compose_fragments};
use fragments::{CoreInstructionsFragment, MemoryFragment, NetworkEnvironmentFragment};
pub fn build_system_prompt() -> String {
build_system_prompt_with_fragments(&[], &[], false)
}
pub fn build_system_prompt_cn() -> String {
build_system_prompt_with_fragments(&[], &[], true)
}
pub fn build_system_prompt_with_fragments(
extra_fragments: &[Box<dyn PromptFragment>],
tool_definitions: &[serde_json::Value],
include_cn: bool,
) -> String {
let ctx = FragmentContext {
tool_definitions,
session_id: "", };
let mut fragments: Vec<Box<dyn PromptFragment>> = vec![Box::new(CoreInstructionsFragment)];
if include_cn {
fragments.push(Box::new(NetworkEnvironmentFragment));
}
fragments.push(Box::new(MemoryFragment));
fragments.extend(extra_fragments.iter().map(|f| dyn_clone::clone_box(f.as_ref())));
let body = compose_fragments(&fragments, &ctx);
body.replacen("\n\n## Memory", "\n---\n\n## Memory", 1)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_system_prompt() {
let prompt = build_system_prompt();
assert!(prompt.contains("versatile AI assistant"));
assert!(prompt.contains("[Conversation Type Detection]"));
assert!(prompt.contains("[Execution Guidelines]"));
assert!(prompt.contains("[Wrap-Up]"));
assert!(prompt.contains("\n---\n"));
}
#[test]
fn test_build_system_prompt_cn() {
let prompt = build_system_prompt_cn();
assert!(prompt.contains("versatile AI assistant"));
assert!(prompt.contains("[Network Environment]"));
assert!(prompt.contains("mainland China"));
assert!(prompt.contains("Baidu"));
assert!(prompt.contains("gitee.com"));
}
#[test]
fn test_build_system_prompt_with_custom_fragments() {
#[derive(Clone)]
struct CustomFragment;
impl PromptFragment for CustomFragment {
fn name(&self) -> &str {
"custom"
}
fn priority(&self) -> i32 {
200
}
fn render(&self, _ctx: &FragmentContext) -> Option<String> {
Some("[Custom Section]".to_string())
}
}
let extra: Vec<Box<dyn PromptFragment>> = vec![Box::new(CustomFragment)];
let prompt = build_system_prompt_with_fragments(&extra, &[], false);
assert!(prompt.contains("[Custom Section]"));
assert!(prompt.contains("versatile AI assistant"));
}
#[test]
fn test_backward_compat_output_matches_original() {
let prompt = build_system_prompt();
let original_sections = [
"You are a versatile AI assistant",
"[Role]",
"[Conversation Type Detection]",
"[Thinking Approach]",
"[Execution Guidelines]",
"[File Operation Guidelines]",
"[Wrap-Up]",
"## Memory",
"MEMORY.md",
];
for section in &original_sections {
assert!(prompt.contains(section), "Missing section: {}", section);
}
}
}