use std::path::{Path, PathBuf};
use crate::core::config::MpmConfig;
use crate::core::delegation_authority::AgentSummary;
pub fn write_prompt_file(prompt: &str) -> Option<PathBuf> {
let file = std::env::temp_dir().join(format!(
"trusty-mpm-system-prompt-{}.txt",
uuid::Uuid::new_v4()
));
match std::fs::write(&file, prompt) {
Ok(()) => Some(file),
Err(err) => {
tracing::warn!("failed to write system prompt file: {err}");
None
}
}
}
pub fn resolve_pm_model(config: &MpmConfig, explicit: Option<&str>) -> String {
crate::core::config::resolve_agent_model(config, "pm", None, explicit)
}
pub fn build_claude_command(model: Option<&str>, prompt_file: Option<&Path>) -> String {
let mut cmd = "claude".to_string();
if let Some(m) = model {
cmd.push_str(" --model ");
cmd.push_str(m);
}
if let Some(p) = prompt_file {
cmd.push_str(" --append-system-prompt-file ");
cmd.push_str(&p.display().to_string());
}
cmd
}
pub fn build_agent_command(
config: &MpmConfig,
agent: &AgentSummary,
prompt_file: Option<&Path>,
explicit: Option<&str>,
) -> String {
let model = crate::core::config::resolve_agent_model(
config,
&agent.name,
agent.model.as_deref(),
explicit,
);
build_claude_command(Some(&model), prompt_file)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn claude_command_bare() {
assert_eq!(build_claude_command(None, None), "claude");
}
#[test]
fn claude_command_with_model() {
let cmd = build_claude_command(Some("claude-opus-4-5"), None);
assert_eq!(cmd, "claude --model claude-opus-4-5");
}
#[test]
fn claude_command_with_prompt() {
let path = Path::new("/tmp/prompt.txt");
let cmd = build_claude_command(None, Some(path));
assert_eq!(cmd, "claude --append-system-prompt-file /tmp/prompt.txt");
}
#[test]
fn claude_command_with_both() {
let path = Path::new("/tmp/sys.txt");
let cmd = build_claude_command(Some("claude-haiku-4-5"), Some(path));
assert_eq!(
cmd,
"claude --model claude-haiku-4-5 --append-system-prompt-file /tmp/sys.txt"
);
}
#[test]
fn write_prompt_file_returns_path() {
let path = write_prompt_file("hello trusty-mpm").unwrap();
assert!(path.exists());
let content = std::fs::read_to_string(&path).unwrap();
assert_eq!(content, "hello trusty-mpm");
std::fs::remove_file(path).unwrap();
}
#[test]
fn pm_model_resolution() {
let cfg = MpmConfig::default();
let m = resolve_pm_model(&cfg, None);
assert_eq!(m, "claude-sonnet-4-5");
let m = resolve_pm_model(&cfg, Some("haiku"));
assert_eq!(m, "claude-haiku-4-5");
}
#[test]
fn agent_command_uses_config_model() {
let dir = tempfile::TempDir::new().unwrap();
let toml = "[models.agents]\nengineer = \"haiku\"\n";
std::fs::write(dir.path().join("config.toml"), toml).unwrap();
let cfg = MpmConfig::load(dir.path());
let agent = AgentSummary {
name: "engineer".to_string(),
role: "engineer".to_string(),
description: None,
model: Some("sonnet".to_string()),
extends_chain: vec![],
};
let cmd = build_agent_command(&cfg, &agent, None, None);
assert_eq!(cmd, "claude --model claude-haiku-4-5");
}
}