Skip to content

Workflow Engine

Every agent execution is driven by the workflow engine: a BFS state-graph executor that runs a queue of nodes, checkpointing after each one, and dispatching to one of 11 node type handlers.


Execution Lifecycle

Create execution record → Validate workflow graph
BFS loop
├── pop node from queue
├── enforce timeout / visit limits / budget
├── dispatch to node handler
├── checkpoint to Redis (hot)
└── queue activated downstream nodes
Terminate (Completed / Failed / paused state)

Termination States

StateTrigger
CompletedBFS queue fully drained
FailedTimeout, visit limit, budget cap, or unrecoverable error
AwaitingApprovalHumanGate node paused — waiting for human decision
WaitingForExternalEventMediaGeneration node submitted — waiting for Fal.ai webhook
AwaitingClientToolLLM emitted a client-tool call — waiting for your app to fulfil
CancelledCancelled via API

Node Types

#NodePurpose
1TriggerEntry point — emits initial parameters and input
2Ai (LLM)LLM call via intelligence layer — sync or streaming, with output-schema validation retry
3RouterBranch selection — rules engine, round-robin, random, or LLM-based
4ParallelFan-out — run sub-graphs concurrently under a configurable semaphore
5JoinMerge parallel results — concat, select_best, aggregate, first, last, llm_judge, or custom template
6MemoryRecall (hybrid retrieval) or Learn (async episode queue)
7HumanGateHuman-in-the-Loop pause — execution resumes on approved/rejected/skipped decision
8ActionHTTP / webhook dispatch with SSRF protection and configurable timeout
9AgentInvocationNested agent execution as a child — max depth 3
10LogicConditionals, loops, variable mutation, schema validation, pass-through
11MediaGenerationFal.ai image/video submission — the only node that pauses for an external event

Execution Limits

LimitDefaultTermination
Wall-clock timeout300 sFailedTimeout
Total node visits25FailedRecursionLimitExceeded
Per-node visits10FailedNodeVisitLimitExceeded
Aggregate output bytes50 MBFailedBadRequest
AgentInvocation depth3Validation error
Action node timeout30 s default, 600 s max
LLM stream buffer per node256 KBTruncated, not failed

Checkpointing

After every node execution, the engine writes a checkpoint so paused and crashed executions can resume:

TierStoreTTLCompression
HotCache layer24 hzstd-3
ColdPrimary datastore30 d

Write triggers (in addition to every-node saves):

TriggerWhen
save_at_human_gateHumanGate pause — includes gate info and timeout
save_at_external_eventMediaGen pause
save_at_client_tool_pauseLLM yields to client-tool fulfilment

On resume, the hot checkpoint is tried first; cold is the fallback.


HumanGate (HITL)

When execution reaches a HumanGate node:

  1. Status → AwaitingApproval
  2. human_gate_info saved to execution record with timeout_at
  3. Your app shows an approval UI

To resume, POST to /executions/{id}/resume:

{
"decision": "approved",
"comment": "Looks good — proceed",
"variables": {}
}
DecisionEffect
approvedExecution continues downstream
rejectedContinues via fallback_branch edge if configured
skippedContinues via fallback_branch edge if configured

If timeout_at has passed when you call /resume, the server applies the node’s configured timeout_action (Approve / Reject / Skip / Route) automatically.


MediaGeneration Node

MediaGeneration is the only async-pausing node:

  1. Path A (first visit): Submits job to Fal.ai with a webhook URL. Returns immediately with status WaitingForExternalEvent.
  2. Fal.ai delivers result via webhook — Athena injects ai_result:{node_id} into execution variables and resumes from checkpoint.
  3. Path B (resume): Node detects ai_result:{node_id} in variables and processes the result, continuing the workflow.

Client-Tool Calls

If an LLM node emits a tool call for a client-registered tool, execution suspends:

  1. Status → AwaitingClientTool
  2. SSE emits tool_call_awaiting_client event
  3. Your app runs the tool locally and POSTs result to POST /executions/{id}/tool-result
{
"tool_call_id": "tc_abc123",
"outcome": "success",
"result": { "balance": 42.50 }
}

The last fulfilled tool call resumes execution automatically.


Retry Policy

Individual nodes can be configured with retry and timeout settings:

Retryable errorsNon-retryable
ExternalService, RateLimit, ServiceUnavailableValidation, NotFound, Unauthorized, Forbidden, PaymentRequired, Conflict

Retry delay is linear by default; configurable to exponential backoff (base_delay × 2^attempt, capped at 5 minutes).


  • Architecture — 3-layer execution pipeline
  • Intelligence — LLM dispatch invoked by Ai/LLM node
  • Credits — credit pre-deduct/reconcile wired into every AI node
  • Execute — client-tool calls, HITL resume, SSE events
  • Error Codes — workflow error codes