Browse the documentation

AEL 1.0.0

Project layout

A project in AEL, the Agent Engineering Language, is a folder of small source files, each with one job. Agents, subagents, nodes (business steps), edges (typed two-way connections), configuration, hooks and skills are first-class building blocks, each in its own named file, so a project's structure reads at a glance.

A complete project

support/
  main.ael                        # main support(): the program's entry point
  pack.ael                        # packages; may be empty
  metadata.ael                    # the project's name and settings
  src/
    application.config.ael
    validation.reuse.ael
    normalize.global.ael
    agents/support.agent.ael
    nodes/summarize.node.ael
    nodes/verify.node.ael
    edges/summary_to_verify.edge.ael
    auth.hook.ael
  prompts/summarize.md

ael init support creates the three root files. Every other folder and file is your choice.

The three root files

FileHolds
main.aelmain support(), the program's entry point, named after the application. Exactly one, at the project root.
pack.aelThe manifest: the packages this folder and the folders below it use. Required at the root, even when it lists none.
metadata.aelThe project's name, description and settings. The name, here support, names main and the program that ael build writes; main main() is refused. A package project names its package here instead, and its main takes the package name's last segment.

One component per file

Every other source file but a language file (below) is named <name>.<role>.ael. It declares exactly one component of that role, and the component carries the file's name: summarize.node.ael declares node summarize(…).

FileDeclaresHolds
<name>.agent.aelagent <name>(…)An agent: a workflow with its nodes, edges, starting points and completion.
<name>.subagent.aelsubagent <name>(…)A subagent: a short-lived agent that an agent spawns at run time, which does one task, returns a typed result to the agent that spawned it and ends.
<name>.node.aelnode <name>(…)A node: one business step, deterministic or model-driven.
<name>.edge.aeledge <name>(…)An edge: a typed, two-way channel between two components, a value one way and its reply back.
<name>.config.aelconfig <name>(…)Typed configuration with defaults, locked into a snapshot for each run.
<name>.hook.aelhook <name>(…)A hook: authorization, auditing or cleanup attached before or after a component, function or statement.
<name>.skill.aelskill <name>(…)A skill that an agent or subagent loads; see Skills.
<name>.global.aelglobal <name>(…)A global function, visible in its folder and every folder below it.
<name>.reuse.aelreuse <name>(…)A reusable function, available to a file that imports it by path.
<name>.routes.aelroutes <name>(…)HTTP routes, a file role that the server/http package adds.

A name is an AEL identifier: letters, digits and _, not starting with a digit, and not a keyword. Names are case-sensitive, and a file whose component name does not match its file name fails the check.

Functions in other languages

Your application can hold private functions written in other languages, with typed AEL signatures, built and run with your own toolchains, pinned by version. A function with a file of its own is in a language file, <name>.<lang>.ael, such as profile.python.ael, which declares python profile(…); a component's file holds them beside its AEL helpers as fn python …. A file name never holds both a language and a role. Functions in other languages describes both forms.

Sharing functions

Sharing follows three rules, and the check enforces each of them:

  • Helper functions (fn) stay private to the component that declares them and its extension files.
  • Global functions are visible, without an import, in their own folder and every folder below it. normalize.global.ael in src/ is callable from every file under src/.
  • Reusable functions are available only to a file that imports them by path, in its header, from its own folder or a folder above it.
# src/nodes/summarize.node.ael
import "../validation.reuse.ael";

node summarize(request: Str<4000>) -> Str<1000> {
    # validation() and normalize() can both be called here.
}

The node's body is a placeholder, as A first agent explains. When two shared functions have the same name, the one in the nearest folder wins. A file never calls a shared function from a sibling folder or from a folder below it.

Extension files

When a component needs more private helpers than fit in its file, you move them to extension files in the same folder: support.agent.extended.ael, then support.agent.extended.2.ael and up. An extension file holds only private helpers, in AEL or in another language, and they belong to that one component. main.ael uses main.extended.ael, and a language file such as profile.python.ael uses profile.python.extended.ael, which holds only functions in its language.

Every source file has a fixed size limit, so files stay small and reviewable. Limits gives the exact limit.

Packages in a project

  • pack.ael declares the packages a folder and the folders below it use. The root manifest is required, and any folder can add its own, so one part of a project can add a package without affecting the rest. The nearest manifest that declares a package wins.
  • pack.lock is generated beside each pack.ael. It records the exact versions, origins and fingerprints your builds use, so builds repeat, even offline. You never edit it by hand.
  • .package/ is generated beside each manifest that lists packages, and holds the installed packages. It is not part of your source: you never edit it.

A file names the parts of a package it uses in its header, for example refer server/http select get;, and every export it selects must be used. Using packages describes manifests, folder scopes and the lock file in full, and Private packages the packages you build and host yourself.

Prompts and other files

prompts/ is the usual place for system prompts kept as files, one per prompt. It is a convention, not a rule: a node names its prompt file by path, wherever the file is in the project.