Extending AEL
You extend AEL, the Agent Engineering Language, with code you write in AEL: a component, a connection to a system you run, or a prompt. This tutorial gives a quickstart for each, packages them for reuse, and walks through the checks an extension passes before other projects use it.
Quickstart: a component
Agents, nodes (business steps), edges (typed connections), configuration and hooks are first-class building blocks, each in its own named file. A hook is the usual first extension: a typed function that runs before or after other code.
# src/team_only.hook.ael
hook team_only(context: EntryContext<Request>) -> HookDecision {
return check_team(context);
}
fn check_team(context: EntryContext<Request>) -> HookDecision {
# Your policy: allow callers of your team, deny the rest with a reason.
}
You attach it before a component with @team_only, and the component runs only when it allows the call. Hooks attach authorization, auditing or cleanup before or after any component, function or statement, run in ordered or parallel groups, and fail closed when authorization fails. The body of check_team is a placeholder, as A first agent explains, and Hooks lists what each context holds.
Quickstart: a connection
You write your own connectors for services, models, knowledge sources, transports and log sinks. A connector is ordinary AEL code that declares its types, its permissions and its limits, and runs within the same budget and checks as the node that uses it:
- Write the typed request and result your connector exchanges with the outside system, and the typed errors it can return.
- Write its operations, each with the one permission it needs and whether a failed call is safe to repeat.
- Give its endpoint and credentials to the deployment as configuration and a secret reference, never in source.
- Call it from a node, like any other typed service.
Tools and MCP and Retrieval over your documents describe the kinds of connector.
Quickstart: a prompt
You write an agent's business policy as a system prompt (inline, from a file, from the environment or from configuration), or run it on its input alone with no system prompt. A prompt kept as a file is reviewed and versioned like code:
prompts/
summarize.md # the policy of the summarize node
review.md # the policy of the review node
A node names its file with prompt: file("prompts/summarize.md"), a path relative to the project root. System prompts describes the four sources and their order.
Recipes: package what you wrote
You build your own libraries into shareable packages that ship compiled, without your source. Put the hook, the connector and their configuration in a project whose metadata.ael names the package, then build it:
metadata {
schema = 1;
name = "acme/support";
description = "Team hook and ticket connector shared by Acme's agents";
}
ael package
You build a package with the ael package command, which produces a single package file. Every public component is an export, and a project that uses the package selects each export by name in its file header:
refer acme/support select team_only;
Every AEL package, from OpenEng or from you, is written in AEL and ships as compiled, verified AEL, with no bundled native code and no install scripts. Creating a package and Private packages describe the file and where you host it.
Walkthrough: check an extension before others use it
Run these in the extension's project, in this order:
ael fmt --check
ael check
ael test
ael refmap
ael package
- Format.
ael fmt --checkreports files that would change. - Check.
ael checkchecks names, limits, types, visibility, hooks, targets and packages. One command-line tool checks, formats, compiles, builds and runs your code, with diagnostics that point at your source. - Test.
ael testruns your tests with scripted or recorded responses, so a connector is tested without the system it connects to. Test the failures too: a denied permission, a timeout, a cancellation and malformed output. - Map.
ael refmapshows what references what and lists unused code and packages, so the package exports only what you meant to export. - Package.
ael packagechecks the whole project again before it writes the file.
Then use the package from a second project, the way its users do, and run ael check and ael test there.
Honest limits
- A hook runs only when your program runs: no hook runs while you check or build, and no hook can change what the compiler does.
- A connector's permissions keep your own code from reaching what it should not; they are not a sandbox for a hostile program.
- A package file holds compiled AEL and its exports' types, never your source, so its users check their calls against the exports, not against your code.