Public API for executing agents.
Lifecycle and supervision
run/2 starts one BeamAgent.Runner under BeamAgent.RunSupervisor (a
DynamicSupervisor) and blocks the calling process until it gets a
result. Each run is an independent, unregistered GenServer — any number
of runs can be in flight concurrently, and one crashing (e.g. a tool
raising) has no effect on any other; it's caught here via
Process.monitor/1 and turned into a BeamAgent.Run.crash/2 result
rather than propagating to the caller.
There are two layers of time enforcement, and they can race:
BeamAgent.Guardrails'MaxExecutionTimecheck runs between steps and tool calls — it's graceful, and produces a normal{:max_execution_time_reached, ...}failure once the runner notices.- A tool call itself can't be preempted mid-execution (e.g. a tool that
blocks on I/O far longer than the guardrail's limit).
run/2is the backstop for that: it waitsmax_execution_time_ms + @timeout_grace_msand, if the runner still hasn't replied, force-terminates it viaDynamicSupervisor.terminate_child/2and returns aBeamAgent.Run.timeout/2result instead.
The grace period exists so the graceful path normally wins the race —
see the @timeout_grace_ms doc below.
Summary
Functions
Runs goal to completion (or failure) and returns {:ok, run} or
{:error, run}, where run is always a BeamAgent.Run.t().
Functions
@spec run( String.t(), keyword() ) :: {:ok, BeamAgent.Run.t()} | {:error, BeamAgent.Run.t()}
Runs goal to completion (or failure) and returns {:ok, run} or
{:error, run}, where run is always a BeamAgent.Run.t().
{:ok, run} only when the runner finished and verification passed;
every other outcome (a guardrail tripped, an unknown tool was called, the
hard timeout fired, the runner crashed, or verification failed a
plausible-looking finish) comes back as {:error, run} with
run.error/run.verification_error set accordingly.
Options
:llm(required) —{module, opts}, wheremoduleimplementsBeamAgent.LLM.Client.:tools—%{atom() => module}of tools available to this run, each module implementingBeamAgent.Tools.Behaviour. Defaults to%{}; a tool call for a name not in this map fails with:unknown_tool.:guardrails— keyword opts consumed byBeamAgent.Guardrails(see its submodules for individual keys/defaults, e.g.:max_execution_time_ms,:max_iterations,:max_context_messages,:max_tool_calls).:verification— keyword opts consumed byBeamAgent.Verifier, e.g.:required_tools, or:moduleto swap in a customBeamAgent.Verifier.Behaviourimplementation.