In code
An agent in code is a card in your pack’s catalogue and, for a python card, an async function. The engine’s orchestrator runs the cards in dependency order, each under its own card, and holds any output with an external effect for a person’s sign-off.
The engine is Atlantic’s Python package aal_engine, delivered to your deployment as a versioned package. A public package and SDK are Coming.
The agent card in code
Section titled “The agent card in code”A catalogue is a YAML file in your own repository. This one has two agents: summary counts notes and writes one line (an internal effect: it runs unattended); publish takes that line and would publish it (an external effect at autonomy 1: it waits for a person).
pack: researchagents: - id: summary purpose: Count the notes in the inbox folder and write a one-line summary. executor: python target: research_agents:summary overseer: ops@example.com budget_usd: 1.00 effect: internal produces: out/summary-{run}.txt - id: publish purpose: Publish the summary to the team page. executor: python target: research_agents:publish overseer: ops@example.com budget_usd: 0.50 needs: [summary] effect: external autonomy: 1 produces: out/published-{run}.txtid, purpose, executor, overseer and budget_usd are required. produces is the artefact that proves the agent ran: an agent that exits cleanly having written nothing has failed. For every field, see Agents.
The agent’s code
Section titled “The agent’s code”A python card’s target is module:function, an async function that takes the agent’s context and returns an Outcome:
from pathlib import Path
from aal_engine.orchestrator import AgentContext, Outcome
async def summary(ctx: AgentContext) -> Outcome: notes = sorted(Path("inbox").glob("*.md")) out = ctx.artefact() out.parent.mkdir(parents=True, exist_ok=True) out.write_text(f"{len(notes)} notes in the inbox\n") return Outcome(note=f"{len(notes)} notes")
async def publish(ctx: AgentContext) -> Outcome: out = ctx.artefact() out.parent.mkdir(parents=True, exist_ok=True) out.write_text(Path(ctx.inputs["summary"]).read_text()) return Outcome(note="ready to publish")The context gives the agent its card, its run ID, its working directory, the artefacts of the cards it needs (ctx.inputs), and the model through the gateway (await ctx.model(prompt)), within the card’s budget.
Tools and handlers
Section titled “Tools and handlers”- Tools: a card’s
toolsis the whole list; the executor grants nothing else, and a pack’sdeny_toolsare refused to every agent. With run tokens on, each tool call is checked against a Cedar policy generated from the card. See The gateway. - Handlers: whoever decides on the
publishoutput is a handler. In a deployment whose approvals are managed by LightHouse, the decision is made there and reaches the engine as a signed command. See Handlers.
Local runs
Section titled “Local runs”import jsonfrom pathlib import Path
from aal_engine.catalog import loadfrom aal_engine.orchestrator import Orchestrator
orch = Orchestrator(load("catalog.yaml"), client="example", state_dir=Path("var/state"), workdir=Path("."))state = orch.run("run-0001")print(json.dumps(orch.summary(state), indent=2))With two notes in inbox/, PYTHONPATH=. python run.py prints:
{ "by_status": { "ok": [ "summary" ], "awaiting-approval": [ "publish" ] }, "failed_hard": [], "cost_usd": 0.0, "ok": true}publish is waiting, not failed. Running run-0001 again resumes it: an agent already done is not run again. Locally, with no LightHouse policy in force, a named person can decide in code:
orch.decide("run-0001", "publish", approve=True, by="ops@example.com")In a deployment whose approvals are managed by LightHouse, that same call is refused (approvals-managed-by-insights): the decision is made in LightHouse.
A source of knowledge is a card too, with the target aal_engine.ingest.connector:run_card and a source block. See Connect your estate.
Releasing
Section titled “Releasing”- Merge the catalogue and code change into your deployment’s repository, reviewed.
- Run the evaluations and the release gate on the new version. Only a version that passes can be made current. See Evaluations.
- Make it current: a handler’s
release.addcommand from LightHouse, or the release ledger in the deployment. See Versioning and rollback. - Watch it in Agents → Activity and the run map.
Deploying from a command line (lighthouse agents deploy) is Coming.