Skip to content

AgentOS 2026.8.24

Choose a tag to compare

@github-actions github-actions released this 24 Aug 14:25
· 276 commits to main since this release
e00cd8c

A release about who is allowed to say yes, and what a turn actually cost. Channel approvals become a button that checks who pressed it, cost stops being a number you only see at the end of the month, Aeon joins the Partner Skills shelf, and four ways into the gateway close behind us.

An approval is a button now — and it checks who pressed it

Telegram inline keyboards, Slack Block Kit actions, and Discord message components render an Approve/Deny pair for a gated tool call, instead of asking the operator to type a reply into a channel and hope the parser agreed with them.

The button is the easy half. The hard half is that a message component is a public surface: in a group, anyone who can see the message can click it. So every click is authorized before it is honoured. The clicker has to pass the channel's own access policy and be an admitted paired user — the same admission the channel already uses to decide whether someone may talk to the agent at all, rather than a second, weaker gate invented for approvals. The approval is bound to the sessionKey that raised it, so a click that arrives from another session is refused rather than applied to whichever call happens to be pending.

And the surface is offered only in DMs. In a DM the session key is PER_CHANNEL_PEER, so the approver and the session are the same person by construction; in a group they are not, and no amount of checking after the fact makes a shared button unambiguous. Groups keep the reply flow.

Slack request signatures are verified against the raw request body rather than a parsed form. Reading request.form() consumes the ASGI body, so signature verification was working from whatever survived that read — correct until it wasn't, and failing in a way that looks like Slack's fault. Unsigned slash commands are handled explicitly instead of falling through the same path. (#364, #391)

What the turn cost, per tool and per skill

A usage ledger records the cost of each turn and attributes it to the tool and the skill that spent it. Attribution rides a ContextVar, so it follows the call into nested execution — a skill that calls a tool that calls a model still lands under the skill, without every layer having to thread an id through its signature.

agentos cost queries it:

agentos cost [--by-model] [--json] [--csv]
agentos cost --start-date YYYY-MM-DD --end-date YYYY-MM-DD
agentos cost --agent-id <agent-id> --channel-type <channel-type>
agentos cost --tool-name <tool-name> --skill <skill-name>
agentos cost --export /path/to/export.csv

The router gains a cost_aware flag, on by default, that substitutes the cheapest tier capable of the request. Image-only tiers are filtered out before the comparison, so a text request is never routed to an image model on the grounds that it is cheap. On the stock c0c3 config the flag is a no-op, since those tiers are already monotonically priced; it earns its keep on custom tier tables and on local providers, which cost zero and therefore win outright.

The usage cost fallback path used to drop query filters it could not honour and return an empty result — a filtered query that finds nothing is indistinguishable from a filtered query that was never run. It now declines the filter and says so. (#366, #392)

Aeon joins Partner Skills

Aeon (aeonfun/aeon) is a fourth Partner Skills source in the Skills hub, alongside Robinhood, Bankr, and Capminal, carrying Aeon's own brand mark. The partner tabs read Robinhood, Bankr, Aeon, Capminal, Community. (#425)

Fixed — the gateway

  • The gateway no longer accepts an auth token from the query string. A token in a URL is a token in the proxy log, the server access log, and the referrer header; the header is the only place it belongs. The uvicorn access log is gated behind config.debug for the same reason. (#350, #377)
  • Rate limiting reads X-Forwarded-For only from a verified trusted proxy, and the per-client dict is bounded. An unverified header let a caller both mint a fresh limit bucket per request and grow that dict without limit. (#354, #396)
  • Unhandled exceptions are redacted before they reach the client, with the detail shown only under debug. (#353, #378)
  • The browser tool refuses data: URLs. A data: URL carries its page in the URL itself, so it has no host to check — which meant it walked past both the SSRF check and the domain allowlist. about:blank is now the only permitted hostless target. (#356, #397)

Removed

Three configuration keys that no code read, and so quietly did nothing to the operator who set them: sandbox.network_default (#360), the memory daily-note keys (#405), and subagents.archive_after_minutes (#407).

Docs

  • cron_default_mode — the default elevation posture for unattended cron jobs, shipped in 2026.8.21 — is now documented where it is set and where it is read: agentos.toml.example, the bundled agentos skill, and the approvals and permissions guide. (#413)

Install

uv tool install --python 3.12 "use-agent-os[recommended]==2026.8.24"

Full changelog: https://github.com/use-agent-os/agent-os/blob/v2026.8.24/CHANGELOG.md