use crate::orchestrator::TaskOrchestrator;
pub(crate) const DELEGATE_CONTEXT_BUDGET_BYTES: usize = 2048;
pub(crate) const DELEGATE_CONTEXT_RECENT_LIMIT: usize = 10;
pub(crate) const DELEGATE_EPISODE_IMPORTANCE: f64 = 0.6;
impl TaskOrchestrator {
pub(super) async fn build_delegate_task_spec(&self, spec: &str) -> String {
let Some(episodic) = self.episodic.as_ref() else {
return spec.to_string();
};
let recent = episodic
.recent(DELEGATE_CONTEXT_RECENT_LIMIT, Some("personal"))
.unwrap_or_default();
if recent.is_empty() {
return spec.to_string();
}
let mut bullets: Vec<String> = Vec::new();
let mut budget = DELEGATE_CONTEXT_BUDGET_BYTES;
for ep in recent.iter() {
let line = format!("- [{}] {}: {}", ep.timestamp, ep.role, ep.content.trim());
if line.len() > budget {
break;
}
budget -= line.len();
bullets.push(line);
}
if bullets.is_empty() {
return spec.to_string();
}
format!(
"{spec}\n\n## Recent context (auto-injected by orchestrator)\n{}",
bullets.join("\n")
)
}
pub(super) async fn record_delegate_episode(
&self,
agent: &str,
spec: &str,
result: &delegate::AgentResult,
recovered_via: Option<&str>,
) {
let Some(episodic) = self.episodic.as_ref() else {
return;
};
let session_id = format!("orchestrator-{}", chrono::Utc::now().format("%Y%m%d"));
if let Err(e) = episodic.ensure_session(&session_id, "orchestrator") {
tracing::warn!("episodic ensure_session failed: {e}");
return;
}
let header = match recovered_via {
Some(via) => format!(
"[delegate {agent}→{via}] {}",
spec.lines().next().unwrap_or(spec)
),
None => format!("[delegate {agent}] {}", spec.lines().next().unwrap_or(spec)),
};
let artifact_refs: Vec<String> = result
.artifacts
.iter()
.map(|a| a.reference.clone())
.collect();
let body = format!(
"{header}\nsummary: {}\nartifacts: {}",
result.summary,
if artifact_refs.is_empty() {
"(none)".to_string()
} else {
artifact_refs.join(", ")
}
);
if let Err(e) = episodic.store_episode(
&session_id,
"agent",
&body,
DELEGATE_EPISODE_IMPORTANCE,
Some("personal"),
Some(agent),
) {
tracing::warn!("episodic store_episode failed: {e}");
}
}
}