use super::agent::{AgentConfig, ChatMessage, LlmProvider, Role};
use super::llm::LlmClient;
use crate::traits::Result;
pub struct ImmunologySupervisor {
pub enabled: bool,
pub doctor_provider: Option<LlmProvider>,
}
impl ImmunologySupervisor {
pub fn new(doctor_provider: Option<LlmProvider>) -> Self {
Self {
enabled: doctor_provider.is_some(),
doctor_provider,
}
}
pub async fn heal_agent(
&self,
llm: &LlmClient,
mut failed_agent: AgentConfig,
error_context: &str,
) -> Result<AgentConfig> {
let provider = match &self.doctor_provider {
Some(p) => p,
None => return Ok(failed_agent),
};
let system_prompt =
"You are the Swarm Immunology Agent. Another agent in the swarm has failed. \
You will be provided with its current system prompt and the error it encountered. \
Your job is to REWRITE its system prompt to patch the blind spot so it doesn't fail again. \
Output ONLY the new system prompt as plain text, no markdown blocks, no explanations.";
let user_prompt = format!(
"AGENT NAME: {}\n\nCURRENT PROMPT:\n{}\n\nERROR ENCOUNTERED:\n{}",
failed_agent.name, failed_agent.system_prompt, error_context
);
let messages = vec![
ChatMessage::new(Role::System, system_prompt),
ChatMessage::new(Role::User, user_prompt),
];
let response = llm.chat(provider, &messages).await?;
let new_prompt = response
.content
.trim()
.trim_start_matches("```text")
.trim_end_matches("```")
.trim()
.to_string();
if !new_prompt.is_empty() {
println!(
"💉 Immunology Agent vaccinated [{}] with a patched prompt.",
failed_agent.id
);
failed_agent.system_prompt = new_prompt;
}
Ok(failed_agent)
}
}