Workflows
A workflow in AEL, the Agent Engineering Language, will be the set of nodes and edges an agent runs, from its starting points to its completion. You will write it in the agent's file; the nodes and edges it uses will each have their own file. Agents, nodes and edges introduces the three building blocks.
Status
Planned for AEL Beta 0.0.1. AEL is not available yet.
Starting points and completion
# agents/support.agent.ael
agent support(input: Request) -> Decision {
config {
nodes: [summarizer = summarize, verifier = verify];
edges: [summary_to_verify(summarizer, verifier)];
starts: [summarizer];
completion: summary_to_verify.callback_result;
}
}
startswill list one or more node instances or child agents where a run begins. AEL will never infer a start from file order or from a node without incoming edges.- With several starts, the agent will declare whether they run at the same time or one after another, and how their results decide the outcome: all must succeed, the first success wins, a quorum agrees, or your own function combines them. Starts that lose will be cancelled.
completionwill name the result that ends the run and becomes the agent's output. A run will end exactly once.
Edge modes
Each edge will declare what its sender can expect:
| Mode | The sender receives | The edge declares |
|---|---|---|
| Event | Only whether the value was accepted. No reply is promised. | Queue size, what happens when it is full, and where delivery errors go. |
| Request and reply | One result or one typed error, for this request. | A finite deadline, and what happens to late or duplicate replies. |
| Callback | The result, passed to a handler you name. | The handler, and a bound on how far callbacks can chain. |
| Stream | A bounded sequence with an explicit end, error or cancellation. | The element type, backpressure, freshness and order, and what a disconnect does. |
Being accepted into a queue will not be completion: a sender that needs a result will use a request or a callback.
Delivery
An edge will also declare how its values are delivered:
- at most once or at least once, and in what order;
- the capacity of its queue, and how long a value may wait;
- an idempotency key, retries and their backoff;
- what to do when an effect's outcome is uncertain.
Exactly-once effects outside your program will never be guaranteed: at-least-once delivery will be made safe with idempotency keys, as described in Durable runs and approval.
Mappings will stay simple
An edge's body will map the value it receives to the next node's input. The mapping will be deterministic and bounded: it will select, move, copy and convert fields. Model calls, tools, network access and other work will belong in a named node, so the route of every value stays easy to follow.
The check will refuse an edge whose types do not match, a missing required field, a wrong number of values and a destination that cannot do what the edge needs, before anything is sent.
Callbacks
A callback will be the reply path of an edge. Its handler will be a helper function in the edge's own file:
# edges/summary_to_verify.edge.ael
edge summary_to_verify(summary: Summary) -> VerifyInput {
return VerifyInput(summary);
}
fn on_verified(result: Verification) -> Decision {
# Reads the verifier's reply and returns the workflow's decision.
}
The agent above uses the callback's result as its completion. How an edge names its mode, deadline and callback will be confirmed when the syntax is final. The handler's body is a placeholder, as A first agent explains.
Fan-out and feedback
- Fan-out. To send one output to several nodes, use several edges, each with its own delivery state, or a node that fans out to a bounded number of branches.
- Feedback. A workflow will be able to loop back only through a mailbox, a delay or a change of state, with a finite limit on depth, iterations or time. A cycle that would wait on itself at once will be refused when you check your code.
Timeouts and cancellation
Every request along an edge will have a finite deadline. When a run is cancelled or times out, it will start no new child work, release the values it had queued and cancel the work already running. A reply that arrives late, or twice, will not be able to complete anything a second time. Concurrency describes the model behind this.
Triggers
A run will be able to start from an event, a poll or a schedule, as well as from a call. Event, polling and scheduled triggers will have overlap, missed-run and time-zone policies, and will survive restarts:
- Events: subscriptions with filters, acknowledgements and deduplication keys.
- Polling: an interval, a timeout, retries with backoff and a cursor, so a slow poll never builds up an unbounded backlog.
- Schedules: intervals or calendar times in a named time zone, with a rule for daylight-saving changes; see Time.
- Overlap: when a new run is due while the last one is still going, skip it, queue it, replace the old one, or run both up to a limit.
- Missed runs: after a restart, catch up on missed runs up to a limit, or combine them into one.
Each trigger will create bounded runs, keep its identity across a restart and never start the same scheduled run twice.
Entry points
main will start the work: it will call an agent like a function. A console agent will need no server; add the HTTP package and declare routes to make it a REST API, or remove them to go back to console-only; see Services and APIs. An edge will never add a server by itself.