Files and processes
Programs in AEL, the Agent Engineering Language, work with files through the standard library, and run your existing programs and shell commands as typed tools through optional official packages. Both need a permission that your program grants explicitly, and the compiler checks that code does only what it has been allowed to do.
Files
Reading and writing files is part of the standard library on targets with a file system: desktop and server programs, and containers. Small networked boards have optional storage of their own; Microcontroller boards describes what each board provides.
Scoped to the folders you grant
Code works with files through a handle to a folder that your program has been granted, never through the whole file system.
- The operations read, write and list files, and read their metadata, inside that folder and the folders below it.
- A path that would leave the folder, through
..or a link, is refused. The check works from the folder's handle, not from the text of the path, so a link or a rename made while your program runs cannot get around it. - Using files is the storage effect. A function that touches a file says so through every function that calls it; see Effects and capabilities.
Bounded reads
A read fills bounded text, a bounded list or a byte array, so it never takes more memory than the capacity you chose. Data that does not fit is reported as an error, never dropped silently. Text and collections describes the capacities.
What folder scoping is not
Scoping keeps your own program from reaching files it should not touch. It is not a sandbox for a hostile program: run code you do not trust in isolation, for example on a remote worker (see execution/remote below). Inside your application, two features run code in a sandbox, and both need the isolation facilities of Linux:
- Isolated components. You mark an agent, node or subagent as isolated: it always runs in a sandbox in its own process, outside the shared communication layer, reachable only through the edges you declare and holding only the resources it declares itself. Isolation needs the isolation facilities of Linux and runs only on the Linux target the documentation names for it: on macOS, on Windows, on microcontroller boards, on other Linux targets and on any host without those facilities, an isolated component is refused, never run without isolation. See Isolated components.
- Sandbox mode. A function in another language runs on the same machine by default or in a sandbox, which needs the isolation facilities of Linux and runs only on the Linux target the documentation names for it, and a missing toolchain, a wrong version or a missing sandbox is refused before anything runs. See Sandbox mode and isolated components.
On the smallest boards there is no file system, and file operations fail when you build, not on the device.
Running your own programs
AEL runs programs you already have, and shell commands, as typed tools: your code sends typed arguments and receives a typed result. This comes from optional official packages, so a program that does not use it carries none of it. Calling your existing programs shows the same packages from an agent's side.
A program you have, or a function you write
| Aspect | An existing program, through a package | A function in another language |
|---|---|---|
| The code | A program, script or command you already have, outside your source. | A function you write in your application, in a language file or beside a component's helpers. |
| How you call it | Through execution/process, execution/shell, execution/python and the other packages below, as a typed tool. | Like any private function, through its typed AEL signature. |
| When it is built | Never by AEL: it runs as it is, with the runtime you provide. | When you build, by your own toolchain, at the version it pins. |
| Where it runs | On your machine or a remote worker you authorize. | On the same machine as your program, or in a sandbox. |
You call your existing Python, JavaScript, Java or .NET programs, shell commands and operating-system operations as typed tools, with runtimes you provide, locally or on a remote worker. Your application can hold private functions written in other languages, with typed AEL signatures, built and run with your own toolchains, pinned by version; Functions in other languages describes them.
| Package | What it does |
|---|---|
execution/process | Start a program with a list of arguments. No shell is involved. |
execution/shell | Run a command through a shell that you choose by name. |
execution/terminal | Hold an interactive terminal session with a program. |
execution/remote | Run work on a remote worker that you authorize. |
execution/python, execution/javascript, execution/jvm, execution/dotnet | Call your own Python, JavaScript, Java or .NET programs, with runtimes you provide. |
You add one like any other package, with ael pack add:
ael pack add execution/process
These packages, like every AEL package, are written in AEL and ship as compiled, verified AEL, with no bundled native code and no install scripts.
Arguments stay data
- Arguments are a list of separate values, never joined into one command line. A file name with spaces, quotes or a leading hyphen stays one argument.
- Only the shell package interprets shell syntax, and only in the command text you give it.
- The working directory and the environment are explicit: a program receives the environment values you list, and secrets are passed by reference, never written into your source or logs.
Limits on every run
- Every run has a finite deadline.
- Standard input, output and error are bounded byte streams. When output passes its limit, the run's result says so, with the number of bytes produced and kept where they are known.
- CPU, memory, process-count and temporary-storage limits are settable per run. Where a platform cannot enforce a limit you asked for, the run is refused rather than started without it.
Outcomes
The result keeps these apart, so your code can react to each:
- the program exited normally;
- it exited with a failure status, or the operating system stopped it;
- it could not be started;
- it ran past its deadline;
- it was cancelled;
- it reached a resource limit;
- its output could not be read as the type you expected;
- the capability is not available on this target.
An exit status of zero does not skip your output checks: a typed result is accepted only after it has been decoded and checked.
Cancellation and retries
On cancellation, AEL stops the program from starting new child processes, asks it to stop, stops it by force after a grace period, and cleans up the whole process tree. A run whose result is lost, for example with a remote worker that stops answering, is reported as uncertain. It is not run again automatically: whether a command may be repeated is for your code to decide.
Runtimes are yours
AEL does not install Python, a JavaScript runtime, Java or .NET for you. You provide the runtime your programs need, on the same machine or on a remote worker. The same holds for the functions in other languages that you write: their toolchains are yours to install, at the versions your code pins. A minimal container image holds no shell or other runtime unless you put one in it, and a microcontroller board runs no processes: use a remote worker or AEL Gateway from there.
A program you start that calls a model on its own is outside AEL's accounting: its token usage is reported as not observed, never as zero.