harness: unify agent + manager prompts into single template (closes #519)

This commit is contained in:
damocles 2026-05-27 22:47:02 +02:00 committed by Mara
commit 01af5003d1
9 changed files with 325 additions and 75 deletions

View file

@ -164,11 +164,10 @@ pub async fn write_settings(socket: &Path) -> Result<PathBuf> {
Ok(path)
}
/// Write the agent's / manager's static system prompt to a file next to
/// the MCP config and return the path. Passed to claude via
/// `--system-prompt-file`, replacing claude's default system prompt with
/// the role + tools instructions. Per-turn prompts become much smaller
/// (just the wake message body).
/// Thin re-export of [`crate::prompt::write_system_prompt`] for
/// callers that already import this module. The actual rendering +
/// marker-block logic lives in `prompt.rs` (closes #519); this is
/// just the public entry point the binaries call.
///
/// # Errors
///
@ -178,20 +177,7 @@ pub async fn write_system_prompt(
label: &str,
flavor: mcp::Flavor,
) -> Result<PathBuf> {
let parent = socket.parent().unwrap_or_else(|| Path::new("/run/hive"));
tokio::fs::create_dir_all(parent).await.ok();
let template = match flavor {
mcp::Flavor::Agent => include_str!("../prompts/agent.md"),
mcp::Flavor::Manager => include_str!("../prompts/manager.md"),
};
let pronouns = std::env::var("HIVE_OPERATOR_PRONOUNS").unwrap_or_else(|_| "she/her".to_owned());
let body = template
.replace("{label}", label)
.replace("{operator_pronouns}", &pronouns);
let path = parent.join("claude-system-prompt.md");
tokio::fs::write(&path, body).await?;
tracing::info!(path = %path.display(), "wrote claude system prompt");
Ok(path)
crate::prompt::write_system_prompt(socket, label, flavor).await
}
/// One claude turn's outcome. The harness uses this to decide whether to