Browse the documentation

AEL 1.0.0

Calling your programs, with reports

With AEL, the Agent Engineering Language, 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. Every recipe on this page uses package-level external execution: one of the official execution packages starts your program, and your agent sees a typed operation.

The recipes

RecipePackageWhat it runs
A program with a list of argumentsexecution/processAny executable, with no shell involved.
A shell commandexecution/shellA command, through a shell you choose by name.
An interactive sessionexecution/terminalA terminal session with a program.
A Python or JavaScript programexecution/python, execution/javascriptYour scripts and modules.
A Java or .NET programexecution/jvm, execution/dotnetYour applications.
Any of these elsewhereexecution/remoteThe same calls, on a remote worker you authorize.

Add only the packages you use:

ael pack add execution/python
ael pack add execution/remote

Like every AEL package, these are written in AEL and ship as compiled, verified AEL, with no bundled native code and no install scripts. The programs they start are yours.

Recipe: your scoring script as a typed tool

# nodes/score.node.ael
node score(input: Claim) -> RiskScore {
    return run_scorer(input);
}

fn run_scorer(input: Claim) -> RiskScore {
    # Runs your scoring script through execution/python,
    # with typed arguments, a deadline and output limits.
}

Each call declares the program and its entry point, the runtime and version it needs, a list of typed arguments, the working directory and the environment values you list, the permissions the program may use, its limits and the result type its output must decode into. The body of run_scorer is a placeholder, as A first agent explains; Calling your existing programs has the full table.

Recipe: a program and a shell command

  • With execution/process, 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.
  • With execution/shell, the shell you name reads shell syntax, and only in the command text you give it.

Where the runtime comes from

Each call names the runtime it needs, and AEL checks the runtime's identity and version before running anything. It never falls back to whatever happens to be installed:

Where your program runsThe runtime
Your machine or serverYou install the runtimes your programs need.
A minimal container imageThere is no shell, Python, Java or .NET unless your deployment includes it deliberately; use an image on a small Linux distribution that includes it, or a remote worker.
A remote workerA machine you operate. The worker is authenticated and receives only the permissions, remaining budget and deadline of the call.
The smallest boardsNo processes: a call needs AEL Gateway, and without it the build or deployment is refused.

What a call returns

  • Exit does not mean success. A program that exits normally still has to produce output that decodes into your result type and passes your checks.
  • Every outcome is typed. A failure status, a program stopped by the operating system, one that could not start, a deadline passed, a cancellation, a resource limit and unreadable output are separate outcomes.
  • Standard output and standard error are separate. Both are bounded byte streams. The output becomes a result only when it decodes into your result type and passes your checks; output that cannot be read as that type is its own outcome.
  • Output is bounded. When output passes its limit, the result says how much was kept and, where it is known, how much was produced.

The reports on every channel

Time and token usage is reported by default on every channel (command line, HTTP, gRPC, WebSocket and sockets), and you can turn off each field without disabling the limits behind it.

ChannelWhere the report goes
The command lineA summary on standard error when the run ends, so the answer on standard output stays unchanged.
HTTP, bufferedThe response's metadata, with the values known when the response is sent.
HTTP, streamedA final report when the stream ends.
gRPC, WebSocket and socketsThe channel's own metadata or final message, per operation.
  • Each operation reports its elapsed time and its input, output and total tokens.
  • A count is marked as reported by the provider, estimated or unknown. An unknown count is never shown as zero.
  • Model tokens that your external program uses on its own are unknown unless they are measured; they are never guessed from its output. The time a call takes is measured on your side, starting the runtime included.
  • You can turn off all reporting, time alone, tokens alone, input, output or total tokens one at a time, or one channel. To keep output tokens private, hide the total as well.

Reporting, logs and replay describes the reports and their settings.

Honest limits

  • Permissions keep your own program from reaching what it should not. They are not a sandbox for a hostile program: run code you do not trust in isolation, for example on a remote worker you dedicate to it.
  • A client that disconnects before a stream ends does not receive the stream's final totals.
  • If the connection to a remote worker is lost after a call started, its outcome is reported as unknown, and work that cannot be repeated safely is never run again automatically.