use crate::ReportError;
use agentkit_loop::{AgentEvent, LoopObserver};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum FailurePolicy {
#[default]
Ignore,
Log,
Accumulate,
FailFast,
}
pub trait FallibleObserver: Send + Sync {
fn try_handle_event(&self, event: &AgentEvent) -> Result<(), ReportError>;
}
pub struct PolicyReporter<T> {
inner: T,
policy: FailurePolicy,
errors: std::sync::Mutex<Vec<ReportError>>,
}
impl<T: FallibleObserver> PolicyReporter<T> {
pub fn new(inner: T, policy: FailurePolicy) -> Self {
Self {
inner,
policy,
errors: std::sync::Mutex::new(Vec::new()),
}
}
pub fn inner(&self) -> &T {
&self.inner
}
pub fn policy(&self) -> FailurePolicy {
self.policy
}
pub fn take_errors(&self) -> Vec<ReportError> {
std::mem::take(&mut *self.errors.lock().unwrap_or_else(|e| e.into_inner()))
}
}
impl<T: FallibleObserver> LoopObserver for PolicyReporter<T> {
fn handle_event(&self, event: AgentEvent) {
if let Err(e) = self.inner.try_handle_event(&event) {
match self.policy {
FailurePolicy::Ignore => {}
FailurePolicy::Log => {
eprintln!("reporter error: {e}");
}
FailurePolicy::Accumulate => {
self.errors.lock().unwrap_or_else(|e| e.into_inner()).push(e);
}
FailurePolicy::FailFast => {
panic!("reporter error: {e}");
}
}
}
}
}