Skip to main content

Module handler

Module handler 

Source
Expand description

Durable effect handlers: effects the runtime can finish without a caller.

A closure effect can only be finished by a caller holding the closure. A handler is registered with the runtime under its effect name, and its input is stored with the record. So after a crash, Runtime::recover can rebuild the call from the store and finish the effect with nobody calling: verify it, re-run it if that is safe, or escalate it.

use agent_effects::handler::{EffectHandler, Handler, VerifiableEffect};
use agent_effects::{EffectContext, EffectFailure, EffectKind, EffectOutcome, Runtime, Verification};
use agent_effects_memory::MemoryStore;

struct SendInvoice;

impl EffectHandler for SendInvoice {
    const NAME: &'static str = "invoice.send";
    type Input = String; // the customer's email
    type Output = String; // the provider's message id
    type Error = EffectFailure;

    fn kind(&self) -> EffectKind {
        EffectKind::IrreversibleWrite
    }

    async fn execute(&self, ctx: &EffectContext, to: &String) -> Result<String, EffectFailure> {
        // Send through the provider, forwarding ctx.idempotency_key().
        Ok(format!("msg-for-{to}"))
    }
}

impl VerifiableEffect for SendInvoice {
    async fn verify(&self, _: &EffectContext, to: &String) -> Result<Verification<String>, EffectFailure> {
        // Look the message up in the provider's outbox.
        Ok(Verification::Confirmed(format!("msg-for-{to}")))
    }
}

let runtime = Runtime::builder(MemoryStore::new())
    .register(Handler::new(SendInvoice).verifiable())
    .build();

let outcome = runtime
    .submit::<SendInvoice>("invoice-1001", "ada@example.com".to_string())
    .actor("agent:billing")
    .await?;
assert_eq!(outcome, EffectOutcome::Committed("msg-for-ada@example.com".to_string()));

Optional capabilities are separate traits (VerifiableEffect; the compensation trait follows), so a handler only implements what it can actually do. The Handler builder only offers .verifiable() for handlers that implement it.

Structs§

CompensationSubmission
A request to undo a registered handler’s effect. Await it. Created by Runtime::compensate.
Handler
A handler and the capabilities it is registered with. Pass it to RuntimeBuilder::register.
Submission
A submission of input to a registered handler. Await it to run the effect. Created by Runtime::submit.

Traits§

CompensableEffect
A handler whose effect can be undone.
EffectHandler
An effect the runtime can execute, and re-execute after a crash, from its stored input.
VerifiableEffect
A handler whose effect can be looked up in the remote system.