Run a server and workers
Run the API server and worker processes on a durable Runtime, and talk to the server from the CLI.
Prerequisites
- a
config/folder with a validated flow, its agents and its models. See Your first flow. - a store plugin and a broker plugin installed for your chosen backend, for example
afe-postgresandafe-redis.
Steps
-
Name a store and a broker in a
Runtimemanifest (see Running in production).A
Runtimemakes tickets and checkpoints durable. With a broker it also lets several processes share the work. Without aRuntime, the engine keeps tickets and checkpoints in memory and loses them when the process ends. The server does not start without aRuntimethat names a store and a broker. -
Export the API token, then start the server and the workers.
The server does not start without
AFE_API_TOKEN. It listens on127.0.0.1unless you pass--host.afe serveis API only: it accepts a request, validates it, records the ticket and queues the job. It never runs a node.afe workerprocesses execute the queued jobs.export AFE_API_TOKEN=$(openssl rand -hex 32)afe serve -c config/ # listens on 127.0.0.1:8765afe worker -c config/ # in another terminal: runs the queued ticketsafe worker -c config/ --concurrency 4 # up to four tickets at once -
Start several workers against the same store and broker.
A ticket's lock is held by the worker that runs it. Two workers never run the same ticket at once. A job delivered twice never opens the ticket twice, and never repeats a paid model call. A
resumeis bound to the request it answers, so a duplicate resume never applies a stale answer to a later pause.afe serve -c ./config # the API, one processafe worker -c ./config # runs queued tickets, one at a timeafe worker -c ./config -concurrency 4 # up to four tickets at onceafe workers # live workers and queue metrics -
Add an operations listener with
--ops-port Nonafe serveorafe worker.It serves
/livez,/readyzand/metrics, on127.0.0.1unless--ops-hostsays otherwise. Without--ops-port, nothing else listens (see Running in production). -
Serve the web UI with
afe serve --ui, on the API's own host and port.Without it, only the API, the auth endpoints and
/rpcanswer (see Web UI).
Commands
The other commands talk to the server. --url defaults to ws://127.0.0.1:8765/rpc:
| Command | Does |
|---|---|
afe validate -c DIR | Checks every manifest and prints all the issues (works on files, no server). |
afe run FLOW -i INPUT.yaml [--revision ID] | Starts a ticket and follows it until it ends or waits for a person. |
afe rerun TICKET | Starts a new ticket with the flow, input, project and revision of an existing one, and follows it. |
afe resume TICKET [ACTION] [--comment …] | Answers a waiting ticket (or restarts it) and follows it. |
afe inspect TICKET | State, revision, totals, the question it waits on, artifacts. |
afe tickets [--state STATE] | Lists tickets, with the first 12 characters of their revision. |
afe workers | Live workers and queue metrics. |
afe cancel TICKET | Cancels a ticket. Its artifacts are kept. |
When a flow works on a project (requiresWorkspace is not none), afe run takes
--project NAME. The project must exist and match the flow's workspace type. afe inspect prints
it.
Exit codes: 0 when the ticket is done, 2 when it waits for a person, 1 otherwise. Without a
terminal, afe run does not ask anything. It exits with 2 and prints the afe resume command
to use.
Notes
afe worker --dryruns every agent on the dry harness, which fills each artifact from its Schema at zero cost.- A browser session for the web UI lives in an
HttpOnlycookie:POST /auth/loginwith{"token": "…"}sets it. The token is compared in constant time.POST /auth/logoutclears it.GET /auth/sessionanswers{"expires_at": …}or401.--session-hourssets how long a session lasts, 8 hours by default.- The
/rpcWebSocket also accepts that cookie, but only when the request'sOriginis the server's own. The CLI keeps using the Bearer token, never the cookie.
afe workerstops cleanly onSIGINTorSIGTERM. It stops claiming new tickets, waits for the ones it is running, releases its locks and exits.
Troubleshooting
Symptom: afe serve exits with "set AFE_API_TOKEN: the server does not start without a
token".
Cause: the token was not exported in this shell before afe serve ran.
Fix: export AFE_API_TOKEN again, then start afe serve.
Symptom: afe run never returns, or afe workers shows no live worker.
Cause: no afe worker process is running against the same store and broker.
Fix: start at least one afe worker -c config/ in another terminal.
Symptom: two afe worker processes both try to run the same ticket.
Cause: this cannot happen against a shared Runtime. It signals the workers are pointed at
different stores, for example one still using an in-memory Runtime.
Fix: check both workers load the same config/ folder and the same store DSN.