Transport
Loopback TCP with one line of JSON per request, the envelope every request carries, the Hello handshake, limits and deadlines.
The connection
- Endpoint. A TCP listener on
127.0.0.1with a port the system picks, opened when the app starts. It is never bound to another interface. Terminals on an SSH host reach it through a reverse port forward the app opens on that host. - One request per connection. The client writes one envelope as a single line of JSON ending in
\n. The app answers with one line of JSON and closes the connection. - Streaming.
SubscribeAgentsis the exception: the connection stays open and the app writes one JSON line per message until either side closes it. See Subscriptions. - Leaving cancels. A client that closes its connection while a request waits, such as a
Waitor aCheckwith a wait, cancels it.
The app serves the bus only when it finds its krad-ade-agents CLI next to its own executable or on PATH.
Limits
| Limit | Value | When it is passed |
|---|---|---|
| Length of a request line | 64 KiB | bad_request |
| Time for the line to arrive after connecting | 10 seconds | bad_request |
Deadlines
Each request has a deadline after which the app answers the bare string "TimedOut".
| Requests | Deadline |
|---|---|
| Most requests | 10 seconds |
CreateWorktree, Changes, Close, PickVariant | 1 minute |
Spawn, RunVariants | 1 minute |
Code, ExtensionTool | 2 minutes |
Wait, and Check with wait_secs | The time asked, at most 30 minutes, plus one second |
The envelope
Every request line is an envelope:
{"api_version":1,"token":"6f1c0d9e2b7a4c58e3f09a1d7b6c2e40","from":"Client","request":"Hello"}| Field | Meaning |
|---|---|
api_version | The API version the client speaks: 1. A missing field is read as 1. |
token | The bus token: KRAD_ADE_TOKEN, or the file KRAD_ADE_TOKEN_FILE names, inside the app's terminals; the token of api.json outside them. |
from | Who is calling: "Client" outside the app, {"Terminal":{"environment":"main","terminal":4}} from a terminal. See Callers. |
request | One of the requests. A request without fields is a string ("List"); the others are an object with one key ({"Wait":{"target":4,"timeout_secs":600}}). |
Responses have the same shape: an object with one key such as {"Agents":[...]} or {"Error":{"code":"not_found","message":"..."}}, or a bare string such as "TimedOut".
The handshake
"Hello" answers the version the app serves, its build and its process id. The bus answers it itself, so it works even while the app is busy.
{"api_version":1,"token":"6f1c0d9e2b7a4c58e3f09a1d7b6c2e40","from":"Client","request":"Hello"}
{"Hello":{"api_version":1,"build":"0.3.3","pid":48211}}pid may be left out of the answer when the app does not know it.
Order of checks
The line
The app reads the line. When it is not a valid envelope, the answer is bad_request.
The token
The token is compared in constant time. A wrong one is unauthorized.
The version
An envelope whose api_version is not the one the app serves is refused before anything else, Hello included.
{"Error":{"code":"unsupported_api_version","message":"This app serves the agents API v1, not v2"}}The krad CLI exits with code 6 when that happens.
The caller and the request
The app answers according to the caller named in from. See Authentication.
Try it by hand
From one of the app's terminals on this computer, where the variables are set:
printf '{"api_version":1,"token":"%s","from":"Client","request":"Hello"}\n' "$KRAD_ADE_TOKEN" \
| nc "${KRAD_ADE_ENDPOINT%:*}" "${KRAD_ADE_ENDPOINT##*:}"krad api makes the same request and prints the version.
Overview
The Agents API v1 is the versioned protocol of the agents bus, spoken by the krad CLI and by any program that writes a line of JSON to a loopback socket.
Authentication
The bus and lead tokens, the callers and their rights, the KRAD_ADE variables, the api.json discovery file and the security model.