Skip to content

RecoveryAction

RecoveryAction is the return value of every strategy. It declares intent — Agent executes it.

RecoveryAction

Returned by every strategy to tell the Agent wrapper what to do next.

RETRY classmethod

RETRY(hint: str | None = None, inject: dict[str, Any] | None = None, delay: float = 0.0) -> RecoveryAction

Re-run from the critical step, optionally injecting context.

REPLAN classmethod

REPLAN(hint: str | None = None) -> RecoveryAction

Abort the current plan branch and generate a new plan from scratch.

ROLLBACK classmethod

ROLLBACK(checkpoint_id: str | None = None) -> RecoveryAction

Restore state to a named checkpoint and re-run from there.

RESUME classmethod

RESUME(from_subgoal: str | None = None) -> RecoveryAction

Continue execution from an incomplete sub-goal.

ESCALATE classmethod

ESCALATE(message: str | None = None) -> RecoveryAction

Surface to a human. Halt autonomous execution.

ABORT classmethod

ABORT(reason: str | None = None) -> RecoveryAction

Hard stop. No recovery attempted.

SUSPEND classmethod

SUSPEND(message: str | None = None, metadata: dict[str, Any] | None = None) -> RecoveryAction

Pause execution and await a human decision.

Unlike ESCALATE (which raises immediately), SUSPEND serializes the current run state to the SuspensionStore and raises TriageSuspendedError carrying a token. The caller routes the token to a human, waits for a decision, then calls agent.resume(token, action=...).

Parameters:

Name Type Description Default
message str | None

Human-readable description of why the run was suspended.

None
metadata dict[str, Any] | None

Arbitrary key/value pairs to store alongside the suspended run (e.g. routing hints like {"channel": "#ops"}).

None

Conceptual notes

Constructors are UPPERCASE classmethods

RecoveryAction.RETRY(hint="...", inject={"key": "val"}, delay=1.0)
RecoveryAction.REPLAN(hint="...")
RecoveryAction.ROLLBACK(checkpoint_id=None)  # None → latest checkpoint in the run
RecoveryAction.RESUME(from_subgoal="Step 3: summarise results")
RecoveryAction.ESCALATE(message="Needs human review")
RecoveryAction.ABORT(reason="Unrecoverable state")
RecoveryAction.SUSPEND(message="Approve?", metadata={"channel": "#ops"})

Accessing the payload

action.kind    # str: "retry" | "replan" | "rollback" | "resume" | "escalate" | "abort" | "suspend"
action.params  # dict: non-None kwargs passed to the constructor

None kwargs are excluded from params. Access with .get(), never by direct key:

hint = action.params.get("hint")

Custom strategy example

async def my_strategy(ctx: FailureContext) -> RecoveryAction:
    faults = sum(1 for ft, _ in ctx.attempt_history if ft == FailureType.EXTERNAL_FAULT)
    if faults >= 3:
        return RecoveryAction.ESCALATE("Service unavailable after 3 retries.")
    return RecoveryAction.RETRY(delay=2.0**faults)