Skip to main content

ReactionEngine

Struct ReactionEngine 

Source
pub struct ReactionEngine { /* private fields */ }
Expand description

The reaction dispatcher. Holds config, attempt trackers, and the Runtime handle needed to actually talk to the agent process.

Arc<ReactionEngine> is what gets wired into LifecycleManager.

Implementations§

Source§

impl ReactionEngine

Source

pub fn new( config: HashMap<String, ReactionConfig>, runtime: Arc<dyn Runtime>, events_tx: Sender<OrchestratorEvent>, ) -> Self

Build an engine from a loaded config. The caller owns the runtime and the broadcast channel — typically LifecycleManager hands its own events_tx in via clone() so engine events share the channel.

Source

pub fn new_with_config( ao_config: Arc<AoConfig>, runtime: Arc<dyn Runtime>, events_tx: Sender<OrchestratorEvent>, ) -> Self

Build an engine with access to per-project reactions overrides.

Global rules come from ao_config.reactions; for each session, Self::resolve_reaction_config merges in ao_config.projects[session.project_id].reactions when present.

Source

pub fn resolve_reaction_config( &self, session: &Session, key: &str, ) -> Option<ReactionConfig>

Effective reaction config for key in session’s project context.

  • Both global and project define key: start from global, overlay project — booleans and action always from project; each Option field uses project when Some, otherwise keeps global.
  • Only project: return the project entry.
  • Only global: return the global entry.
Source

pub fn with_scm(self, scm: Arc<dyn Scm>) -> Self

Attach an SCM plugin so auto-merge can actually merge.

Builder form to match LifecycleManager::with_scm. When unset, dispatch_auto_merge falls back to Phase D’s “log and emit intent only” behaviour so existing callers that don’t know about SCM keep working.

Source

pub fn with_notifier_registry(self, registry: NotifierRegistry) -> Self

Attach a notifier registry so dispatch_notify can fan out to real notifier plugins. Without a registry the engine falls back to Phase D behaviour (emit event, return success).

Source

pub async fn dispatch( &self, session: &Session, reaction_key: &str, ) -> Result<Option<ReactionOutcome>>

Fire the reaction configured for reaction_key against session, if any. Returns None when there’s no matching config — the caller (usually LifecycleManager::transition) treats that as “silently do nothing” rather than an error.

session is borrowed (not cloned) because dispatch only needs the ID and runtime handle; nothing is persisted back.

Source

pub async fn dispatch_with_message( &self, session: &Session, reaction_key: &str, message_override: String, ) -> Result<Option<ReactionOutcome>>

Like Self::dispatch but overrides the configured message with message_override. Used by call sites that build dynamic message bodies (e.g. CI-failed formatting check names/URLs from live data) without needing a static config entry.

Returns None when no reaction is configured for the key (same contract as dispatch).

Source

pub fn clear_tracker(&self, session_id: &SessionId, reaction_key: &str)

Forget any tracker state for (session, reaction_key). Called by LifecycleManager on the tick that leaves a triggering status, so the next time the session re-enters it, retries start from zero. A lingering tracker would mean a session that failed CI, was fixed, and failed again would start already half-way through the retry budget — not what anyone wants.

Source

pub fn clear_all_for_session(&self, session_id: &SessionId)

Drop every tracker entry for session_id. Called by LifecycleManager::terminate — without this, the map would grow monotonically over a long-running ao-rs watch as terminated sessions leave orphan entries behind. Cheap: one full-map walk per termination, and the N is small (reaction-key count).

Source

pub fn attempts(&self, session_id: &SessionId, reaction_key: &str) -> u32

Current attempt count for (session, reaction_key). Returns 0 if no tracker exists yet. Exposed for tests and for future CLI debugging (ao-rs react status <id>).

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more