pub mod agents;
pub use agents::{
judge_agent_prompt, mdap_microagent_prompt, planner_agent_prompt, reasoning_agent_prompt,
simple_agent_prompt,
};
use crate::roles::AgentRole;
pub enum AgentPromptKind<'a> {
Reasoning {
agent_id: &'a str,
working_directory: &'a str,
},
Planner {
agent_id: &'a str,
working_directory: &'a str,
goal: &'a str,
hints: &'a [String],
},
Judge {
agent_id: &'a str,
working_directory: &'a str,
},
Simple {
agent_id: &'a str,
working_directory: &'a str,
},
MdapMicroagent {
agent_id: &'a str,
working_directory: &'a str,
vote_round: usize,
peer_count: usize,
},
}
pub fn build_agent_prompt(kind: AgentPromptKind<'_>, role: Option<AgentRole>) -> String {
let mut prompt = match kind {
AgentPromptKind::Reasoning {
agent_id,
working_directory,
} => reasoning_agent_prompt(agent_id, working_directory),
AgentPromptKind::Planner {
agent_id,
working_directory,
goal,
hints,
} => planner_agent_prompt(agent_id, working_directory, goal, hints),
AgentPromptKind::Judge {
agent_id,
working_directory,
} => judge_agent_prompt(agent_id, working_directory),
AgentPromptKind::Simple {
agent_id,
working_directory,
} => simple_agent_prompt(agent_id, working_directory),
AgentPromptKind::MdapMicroagent {
agent_id,
working_directory,
vote_round,
peer_count,
} => mdap_microagent_prompt(agent_id, working_directory, vote_round, peer_count),
};
if let Some(r) = role {
prompt.push_str(r.system_prompt_suffix());
}
prompt
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn all_variants_build_without_panic() {
let _ = build_agent_prompt(
AgentPromptKind::Reasoning {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
let _ = build_agent_prompt(
AgentPromptKind::Planner {
agent_id: "a",
working_directory: "/tmp",
goal: "do something",
hints: &[],
},
None,
);
let _ = build_agent_prompt(
AgentPromptKind::Judge {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
let _ = build_agent_prompt(
AgentPromptKind::Simple {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
let _ = build_agent_prompt(
AgentPromptKind::MdapMicroagent {
agent_id: "a",
working_directory: "/tmp",
vote_round: 1,
peer_count: 3,
},
None,
);
}
#[test]
fn no_role_does_not_append_suffix() {
let prompt = build_agent_prompt(
AgentPromptKind::Reasoning {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
assert!(!prompt.contains("[ROLE:"));
}
#[test]
fn role_suffix_is_appended() {
let prompt = build_agent_prompt(
AgentPromptKind::Reasoning {
agent_id: "a",
working_directory: "/tmp",
},
Some(AgentRole::Exploration),
);
assert!(prompt.contains("[ROLE: Exploration]"));
}
#[test]
fn planner_embeds_goal() {
let prompt = build_agent_prompt(
AgentPromptKind::Planner {
agent_id: "a",
working_directory: "/tmp",
goal: "implement LRU cache",
hints: &[],
},
None,
);
assert!(prompt.contains("implement LRU cache"));
}
#[test]
fn mdap_embeds_vote_round_and_peer_count() {
let prompt = build_agent_prompt(
AgentPromptKind::MdapMicroagent {
agent_id: "a",
working_directory: "/tmp",
vote_round: 2,
peer_count: 5,
},
None,
);
assert!(
prompt.contains('2') || prompt.contains("round"),
"vote_round should appear in prompt"
);
assert!(
prompt.contains('5') || prompt.contains("peer"),
"peer_count should appear in prompt"
);
}
#[test]
fn simple_is_shorter_than_reasoning() {
let simple = build_agent_prompt(
AgentPromptKind::Simple {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
let reasoning = build_agent_prompt(
AgentPromptKind::Reasoning {
agent_id: "a",
working_directory: "/tmp",
},
None,
);
assert!(
simple.len() < reasoning.len(),
"Simple prompt ({} chars) should be shorter than Reasoning ({} chars)",
simple.len(),
reasoning.len()
);
}
}