Agentry 0.2.0 adds a multi-agent workflow engine, a real message list API, agent update and key rotation endpoints, and a Helm chart. It also closes an admin API exposure that affected default 0.1.0 deployments, so please read the upgrade notes first.
Upgrade notes
- The admin API now fails closed. In 0.1.0, every
/v1/admin/*route was open to anonymous callers whenauth.admin_key_filewas unset, which is the default. Those routes now return401 ADMIN_AUTH_NOT_CONFIGUREDuntil an admin key file is configured (3ea6d4a). auth.require_authwithoutauth.admin_key_fileis rejected at startup instead of booting with a dead admin plane. The Helm chart fails at render time under the same condition. Withoutrequire_auththe gateway still boots with the admin API disabled and logs a warning (ee0733e).- Message query endpoints are no longer public.
GET /v1/messages,GET /v1/messages/:idandGET /v1/messages/:id/statusrequire an agent API key (Authorization: Bearer) or the admin key (X-Admin-Key). An agent only sees messages it sent or received; anything else returns 404. A client that submits a message but holds no registered local agent key can no longer poll its delivery status (4861ced, b4de450). - Check your admin key env var. The multi-domain compose file and
docs/DEPLOYMENT.mdshipped withAMTP_AUTH_ADMIN_KEY_FILE, which the config loader never read. The correct name isAMTP_ADMIN_KEY_FILE. If you copied those examples, your gateways were running without admin authentication (8a34c66). - Database: re-apply
deployment/db/*.sql. All statements are idempotent. This adds theworkflowsandworkflow_participantstables, themessages.workflow_idcolumn, and indexes onmessages.recipients(GIN),messages.workflow_idandagents.api_key.
New features
Workflow engine
- New
internal/workflowengine for parallel, sequential and conditional multi-agent coordination, replacing the inline coordination logic in the message processor. Workflow state is persisted in both the in-memory and PostgreSQL backends, with optimistic concurrency control on updates (e06dd82, 80346f9). - The send-message response now returns a
workflow_id, and every message the engine dispatches carries it in a newworkflow_idenvelope field. Replies are routed into the engine byworkflow_id, falling back toin_reply_tofor older clients (fa31ead, 1afc690). - Send requests accept
response_typeandin_reply_to. Replies withresponse_typeworkflow_errororerrormark the participant as failed, sostop_on_failuretakes effect (fb7b880). - When a workflow reaches a terminal state, the initiator receives an aggregated result notification sent from
workflow@<gateway-domain>(be3f3e8). - Engine-generated messages carry a full protocol identity with a deterministic idempotency key per step, so receiving gateways deduplicate retries (ea9501f).
Message list API
GET /v1/messagesreplaces the 0.1.0 placeholder with a real storage query. It supportssender,recipient,statusandsincefilters pluslimitandoffset, attaches the delivery status to each message, and returnstotalfor pagination (93dcc91).- An agent can filter its own traffic by the counterpart of a conversation, for example
?recipient=bob@remote.com. Filters accept bare agent names or full addresses, and domains are case-insensitive (2072639, d20dcf4). sinceis an inclusive RFC 3339 bound kept at full precision, so cursor pollers do not receive the same messages twice (3f20a34).- The admin key can inspect any message, including ones submitted by unregistered remote senders (b4de450).
- Malformed parameters return 400 with
INVALID_STATUS,INVALID_SENDERorINVALID_RECIPIENT. 403 is reserved for queries about conversations the caller is not part of.
Agent management
PATCH /v1/admin/agents/:addressupdates delivery mode, push target, push headers and supported schemas while preserving the API key (a571b29).POST /v1/admin/agents/:address/rotate-keyreturns a new API key once and invalidates the old one immediately (86b3c14).- Both endpoints accept a bare name or a full
name@domainaddress, and distinguish a missing agent (404) from invalid input (400) and storage failures (500). - Updates and rotations write only the fields they change, so a concurrent update can no longer revert a key rotation, and the rule that push mode requires a push target is enforced atomically in storage (05c6cc7, 92ecf32).
Deployment
- Helm chart under
deployment/chartwith support for TLS, PostgreSQL storage, the schema registry, DNS discovery, metrics, HPA, pod disruption budgets, ingress and Envoy Gateway (37119e4). - The Dockerfile accepts
APK_MIRRORandGOPROXYbuild arguments for regions with slow access to the default mirrors, andmake docker-buildnow points atdocker/Dockerfile(f3dfad9). - New
make utandmake fvttargets.
Fixes to 0.1.0 behavior
- Registering an agent with a non-wildcard schema while schema management is not configured no longer panics (a571b29).
DELETE /v1/admin/agents/:addressaccepts the fullname@domainaddress returned at registration, not only the bare name (20e84f1).GET /v1/messages/:idandGET /v1/messages/:id/statusreturn 500MESSAGE_READ_FAILEDon a storage failure instead of 404, so a client polling during a database outage retries rather than concluding the message was lost and sending it again (04af71b).
Performance
- Hot-path regexes are compiled once at package load instead of on every message validation and delivery (b575ef4).
- Agent API key authentication is a single indexed lookup by key hash, and
last_accesswrites are debounced to one per agent per minute (3c9fc82, 643a1bb). - The admin key file is parsed once and cached, reloaded when the file changes, and cache entries expire after 5 seconds so a revoked key stops working promptly. Key comparison remains constant time (cc74fed, 120dae0, ded9031).
- Message listing uses a GIN index on recipients, counts totals without materializing rows, and fetches delivery statuses in one batch (d3f94b4, 7ef9211, bd8fe2e).
Contributors
@sanmuny, @congwang and @matiasinsaurralde
Full changelog: v0.1.0...v0.2.0