use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DelegationPrompt {
pub task: String,
pub expected_outcome: String,
pub required_tools: Vec<String>,
pub must_do: Vec<String>,
pub must_not_do: Vec<String>,
pub context: String,
}
impl DelegationPrompt {
pub fn new(
task: impl Into<String>,
expected_outcome: impl Into<String>,
context: impl Into<String>,
) -> Self {
Self {
task: task.into(),
expected_outcome: expected_outcome.into(),
required_tools: Vec::new(),
must_do: Vec::new(),
must_not_do: Vec::new(),
context: context.into(),
}
}
pub fn with_tools(mut self, tools: Vec<String>) -> Self {
self.required_tools = tools;
self
}
pub fn with_must_do(mut self, rules: Vec<String>) -> Self {
self.must_do = rules;
self
}
pub fn with_must_not_do(mut self, prohibitions: Vec<String>) -> Self {
self.must_not_do = prohibitions;
self
}
pub fn validate(&self) -> Result<()> {
let rendered = self.render();
let line_count = rendered.lines().count();
if line_count < 30 {
return Err(anyhow!(
"delegation prompt too short ({} lines, minimum 30 required)",
line_count
));
}
Ok(())
}
pub fn render(&self) -> String {
let mut out = String::new();
out.push_str("## Task\n");
out.push_str(&self.task);
out.push_str("\n\n");
out.push_str("## Expected Outcome\n");
out.push_str(&self.expected_outcome);
out.push_str("\n\n");
out.push_str("## Required Tools\n");
if self.required_tools.is_empty() {
out.push_str("(none specified)\n");
} else {
for t in &self.required_tools {
out.push_str(&format!("- {}\n", t));
}
}
out.push('\n');
out.push_str("## Must Do\n");
if self.must_do.is_empty() {
out.push_str("(no specific requirements)\n");
} else {
for r in &self.must_do {
out.push_str(&format!("- {}\n", r));
}
}
out.push('\n');
out.push_str("## Must Not Do\n");
if self.must_not_do.is_empty() {
out.push_str("(no specific prohibitions)\n");
} else {
for p in &self.must_not_do {
out.push_str(&format!("- {}\n", p));
}
}
out.push('\n');
out.push_str("## Context\n");
out.push_str(&self.context);
out.push('\n');
out
}
}
impl std::fmt::Display for DelegationPrompt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.render())
}
}