Creating a package
With AEL, the Agent Engineering Language, you build your own libraries into shareable packages that ship compiled, without your source. You build a package with the ael package command, which produces a single package file. You then host that file yourself; see Private packages.
A package project
A package is an ordinary AEL project, with main.ael, pack.ael and metadata.ael at its root. What makes it a package is its name in metadata.ael:
metadata {
schema = 1;
name = "acme/billing";
description = "Billing checks shared by Acme's agents";
}
billing/
main.ael # required; never runs as part of the package
pack.ael # the packages this package uses
metadata.ael # name = "acme/billing"
src/
check_invoice.reuse.ael # exported as check_invoice
audit.hook.ael # exported as audit
invoice.node.ael # exported as invoice
rules.config.ael # exported as rules
- The name follows the package name rules: lower case and slash-separated. Start it with your own organization's name, such as
acme/. main.aelstays required and may do nothing. It is compiled, but it never runs as part of the package and never starts when someone installs it.
Building the file
ael package
ael package ../billing -o dist/acme-billing-0.3.1.zip
ael package builds the project you are in, or the project folder you name; -o chooses where the file is written. Building a package describes the command in full. Before it writes anything, it checks the whole project: the package name, the three root files, the lock files of every scope, source limits, names, visibility, hooks, targets and packages. Every refer … select has to be used, as in any other build. A missing package name fails before any file is written.
The same project, built with the same toolchain, gives the same package file, so its fingerprint changes only when its content does.
What goes into the file
- Every component, compiled. Each agent, node, edge, hook, configuration and shared function in the project, including those that nothing else in the project calls. An extension file's helpers are folded into their component.
- Its public interface. The exports, with their types, effects and capabilities, so projects can check their calls against it without your source.
- References to its own packages. Their exact versions and fingerprints, never copies of them.
Never in the file: your source files, comments, scripts, native code, executables, model weights or any other files. Descriptions and other notices travel as data.
Building a package publishes nothing. It never uploads anything, and you cannot publish to the official registry, which never hosts or lists private packages.
Exports
Every public component is an export: agents, nodes, edges, hooks, configuration, global and reusable functions, skills, and file roles such as routes. A helper fn is never exported, including the helpers in extension files.
A skill, declared in its own <name>.skill.ael file, is exported like any other component, and skill packages take names of the form skills/<publisher>/<name>. A skill is a versioned, reusable bundle of instructions, typed tools and functions that an agent or subagent loads through the skills it declares. A run pins each skill it loads by its version and the fingerprint of its instructions. See Skills.
A project uses your exports by name, in its header, and has to use each one it selects:
refer acme/billing select check_invoice, audit;
A global function in a package is visible only to a file that selects it: installing a package never adds names to anyone's folders.
You can write a hook either as get.hook.ael, declaring hook get, or as get/main.hook.ael, declaring hook main. Both export the name get. A package that has both is refused as ambiguous.
Every package is written in AEL
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. That rule covers everything a package does:
- no native libraries, embedded interpreters or code in another language, inside the file or shipped beside it;
- no file in another language,
<name>.<lang>.ael, and no function in another language,fn <lang>: the check refuses a package that holds one; - no install, build or post-install scripts, and no compiler plug-ins;
- no helper programs that do the package's work outside it.
Functions in other languages belong to applications: your application can hold private functions written in other languages, with typed AEL signatures, built and run with your own toolchains, pinned by version. No such function stands in for a package's own behaviour. Functions in other languages describes them.
When a package talks to an outside system, such as a database, a model server, a robot or a quantum computer, it uses that system's own interface, and you run that system. A package can also start programs you choose, such as your own Python or Java programs, with runtimes you provide; see the Package catalog. The package's own logic stays in AEL.
For you, this means one language to read, whoever wrote a package. The same checks that apply to your code apply to every package: types, effects, capabilities and limits. Every package builds for your targets the way your own code does, the reference map sees into it, and nothing in it runs when you install it.
Limits
- Every source file of the package stays within the source limits: at most 5,000 bytes and at most 5,000 lines.
- A package name is at most 128 characters.
- The limits for a package file are 64 MiB in total, at most 4,096 entries, and no single file inside it larger than 16 MiB. A file over these limits is refused when it is installed.