use machi_types::{ErrorCode, MachiError, RunId};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TurnAbortReason {
Cancelled,
Deadline,
MaxSteps,
Stationarity,
Error {
code: ErrorCode,
message: String,
},
}
impl TurnAbortReason {
#[must_use]
pub fn from_error(err: &MachiError) -> Self {
match err.code() {
ErrorCode::RuntimeCancelled | ErrorCode::LlmCancelled | ErrorCode::HostCancelled => {
Self::Cancelled
}
ErrorCode::RuntimeDeadline => Self::Deadline,
ErrorCode::RuntimeMaxSteps => Self::MaxSteps,
ErrorCode::RuntimeStationarity => Self::Stationarity,
code => Self::Error {
code,
message: err.message().to_owned(),
},
}
}
}
pub trait TurnLifecycleContributor: Send + Sync {
fn on_turn_start(&self, _run_id: &RunId) {}
fn on_turn_done(&self, _run_id: &RunId, _steps: usize) {}
fn on_turn_abort(&self, _run_id: &RunId, _reason: &TurnAbortReason) {}
fn on_turn_error(&self, _run_id: &RunId, _err: &MachiError) {}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct NoopLifecycle;
impl TurnLifecycleContributor for NoopLifecycle {}
#[derive(Default)]
pub struct LifecycleFanout {
contributors: Vec<std::sync::Arc<dyn TurnLifecycleContributor>>,
}
impl std::fmt::Debug for LifecycleFanout {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LifecycleFanout")
.field("contributors", &self.contributors.len())
.finish()
}
}
impl LifecycleFanout {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn push(mut self, c: std::sync::Arc<dyn TurnLifecycleContributor>) -> Self {
self.contributors.push(c);
self
}
}
impl TurnLifecycleContributor for LifecycleFanout {
fn on_turn_start(&self, run_id: &RunId) {
for c in &self.contributors {
c.on_turn_start(run_id);
}
}
fn on_turn_done(&self, run_id: &RunId, steps: usize) {
for c in &self.contributors {
c.on_turn_done(run_id, steps);
}
}
fn on_turn_abort(&self, run_id: &RunId, reason: &TurnAbortReason) {
for c in &self.contributors {
c.on_turn_abort(run_id, reason);
}
}
fn on_turn_error(&self, run_id: &RunId, err: &MachiError) {
for c in &self.contributors {
c.on_turn_error(run_id, err);
}
}
}