Configuration
Configuration in AEL, the Agent Engineering Language, is typed and reusable, and it is locked into a snapshot for each run, so settings cannot change underneath a running agent. Mistakes such as an unknown setting or a value of the wrong type are reported before anything runs.
A configuration file
A configuration lives in <name>.config.ael and declares exactly one config <name>(). It returns a struct whose fields are the settings, filled with their defaults.
# src/application.config.ael
struct Application {
port: u16,
team: Str<24>,
escalation_email: Option<Str<64>>,
}
config application() -> Application {
return Application(8080, "support", Option::None);
}
- Defaults are checked values. A configuration builds its defaults from literal values, struct values and
Optionvalues, and it can use its own private helper functions to do so, within strict limits. - Reading configuration does nothing else. Loading a configuration reads no file, environment variable or secret, opens no connection and calls no model. External values are resolved when a run starts (see below).
- One definition, many uses. The same configuration can serve
main, several agents, nodes and edges, and the packages that accept it, and each instance can receive its own values.
Settings inside a component
A component can also carry its own settings, in a config { … } block of key: value; entries:
# src/nodes/summarize.node.ael
node summarize(input: Request) -> Summary {
config {
prompt: file("prompts/summarize.md");
model: binding("primary_model");
max_attempts: 2;
}
return write_summary(input);
}
The block is a checked record of settings, not code, and it can refer to a named configuration. Agents, nodes and edges describes the settings of nodes, edges and agents.
Bindings are not settings
An agent, subagent or node declares the memory, skills, knowledge, storage and database it uses, each bound to a package you select, and the check refuses any use it did not declare. Those bindings sit in a bindings { … } record of their own, never among the fields of the config { … } block: a binding decides what a component may reach, so no configuration layer adds one or changes it. A binding's address and credentials can still come from your configuration, as references. Bindings and storage describes the record.
Where values come from
A setting's value can come from several layers. A higher layer overrides a lower one, field by field:
| Layer | Set by |
|---|---|
| 1. Defaults | The configuration file. |
| 2. Shared configurations | Configurations your project composes, in an order you declare. |
| 3. Named environment variables and files | An environment variable or a file that you name for a field, read when a run starts. |
| 4. Deployment | The settings of the place where the program runs. |
| 5. Run overrides | The caller of one run, only for the fields you allow and only when the caller is authorized. |
- The order is always the declared one. The order in which files are found never decides a value.
- Two values for the same field at the same layer are a conflict, and are reported rather than resolved by chance.
- Environment variables, files and secrets are references. The running program resolves them when a run starts, within its own permissions, and never reads the environment as a whole. Secret values never appear in your source, in compiled files or in routine logs.
- A missing optional value, a malformed value and a missing required value are reported differently, so you can tell them apart.
What the check refuses
- A field that the configuration does not declare.
- A required field that no layer sets.
- A value of the wrong type, or text longer than its field allows.
- Two layers of the same rank that set one field.
- Configurations that refer to each other in a cycle.
One snapshot per run
Before a run is admitted, its configuration is resolved, validated and pinned. The run keeps that snapshot to the end, even if a file, a variable or a deployment setting changes while it runs.
- A change applies to runs that start afterwards.
- If a new configuration fails validation, the last accepted one stays in force.
- A field that can change during a long-running agent says so, and the change happens at a checked point, such as a restart.
What configuration never does
- Raise a limit: CPU, memory, token and permission ceilings set by the deployment stay as they are.
- Grant a permission: see Effects and capabilities.
- Add a binding: bindings belong to a component's
bindings { … }record; see Bindings and storage. - Change packages or project settings: packages belong to
pack.ael, and the project's name and settings tometadata.ael. - Start work: configuration has no side effects, and
mainstays the program's only entry point.
Explaining configuration describes how you see where each value of a configuration comes from.