Skip to content

AgentOS 2026.8.7

Choose a tag to compare

@github-actions github-actions released this 07 Aug 16:18
· 534 commits to main since this release
8358cce

A Web UI release. A token price chart draws in the chat transcript instead of arriving as a file you have to open somewhere else; the console's keyboard shortcuts became one registry with a list you can actually read; and the two settings surfaces that made you type a value from memory — router tier models, and everything you lose when you switch LLM provider — stopped doing that.

Added

  • Token price charts render inline in chat. An artifact published as application/vnd.agentos.chart+json draws as an interactive candlestick chart in the transcript instead of a download chip, and the gmgn-market and gmgn-token skills emit one alongside their text summaries. The chart goes through the existing artifact seam, so history replay redraws it with no separate code path, and lightweight-charts is imported dynamically — it lands in its own chunk and never loads for a chat that has no chart, leaving the Chat route at 93.8 KB gz against a 180 KB budget. Payload strings — token names and symbols — are attacker-controlled on-chain metadata, so every one of them reaches the DOM through textContent.

    • A readout strip, because a candle you cannot read is a shape. lightweight-charts ships no tooltip, so hovering told you neither what the candle opened at nor how far it moved. A strip above the canvas now carries the hovered candle's time, OHLC and volume, plus close against open as a signed percentage — the move the body itself draws, not the move since the previous close. It rests on the newest candle until the cursor arrives and returns there when the cursor leaves, so it is never blank; it takes its own grid row rather than floating over the candles it describes; its height is reserved up front so the first hover cannot shift the transcript; and it is pointer-events: none so it cannot swallow the crosshair it reports on. Prices use the payload's own precision, so a token trading at 0.0000123 reads at full resolution instead of flattening to 0.00.

    • Four gaps closed before it shipped. The Control UI build failed on every CI runner — fancy-canvas, a dependency of lightweight-charts, publishes a files allowlist covering only its compiled JavaScript, so its MIT text never leaves the source repo and the license bundler found nothing to embed; nothing downstream of that build ever ran. The upstream license is vendored under frontend/vendor-licenses/ and used only when an installed package ships none, so a new dependency without attribution still fails the build. gmgn-token deferred to gmgn-market for the converter, and the skill loader has no skill-to-skill dependency mechanism (requires covers bins and env only) — with only gmgn-token enabled the chart silently never appeared, so each skill now carries the converter, pinned byte-for-byte against the other. Charts leaked on every session switch and every "load earlier", because the mounter disposed them only on route unmount while the transcript rebuilds its rows in place — live charts are keyed by their host now and both rebuild sites sweep. And a click anywhere inside the card matched the transcript's delegated [data-artifact-download] handler, so a pan, a zoom or a crosshair move downloaded the JSON; the attribute lives on the Download anchor now, the way the audio card already did it.

  • One keyboard shortcut registry, and a ? overlay that lists it. The console already had real key handling — Enter/Shift+Enter in the composer, Escape's abort/recover chain, Cmd/Ctrl+Shift+O for New chat, arrow navigation in the slash menu and the session switcher — spread across five files as ad-hoc document listeners. Nothing could enumerate them, so nothing documented them, and each new binding re-litigated the same guards. Components declare a shortcut now and the provider owns the single document listener, the editable-target guard and the overlay guard; keys that must stay bound to their own element register as documentation-only, so the list is complete without relocating any behaviour. Overlay detection was a hardcoded selector list per handler and already stale — layers register themselves instead. ? opens and closes the sheet, stays inert in editable fields, and has a visible sidebar entry point that also works on touch, since the composer autofocuses on desktop and a key-only affordance would not be discoverable at all. Combos match against both e.key and e.code, and the New chat tooltip renders the right keycaps per platform rather than a hardcoded ⌘⇧O. The sheet loads lazily: pulling it into the eager tree cost +44 KiB gzip for a panel most sessions never open; split out, the change is +2.0 KiB. (Closes #137)

  • Router Tiers picks models from a catalog instead of free text. Agent settings → Router Tiers made you type the provider and the model for all five tiers from memory, with nothing validating either — and a tier a request only escalates to can carry a typo for a long time before the first failed turn. The provider cell is a read-only chip: requests always go through llm.provider, a tier naming a different provider is degraded back to llm.model at boot, and five editable copies of one value were five chances to get it wrong. The model cell is a combobox over the union of two catalogs, which have to be unioned rather than chosen between — models.list is live but partial, and answers nothing before an API key is saved, which is exactly when this form is being filled in; onboarding.catalog.routerProfiles ships with the package and carries a recommended model for every tier. Either alone gets it wrong in both directions. The image row is offered only vision-capable models, from the server's capability data offline-backed by the tiers that actually generate images, never text models relabelled. Save warns and never blocks, and distinguishes three things: an id no source knows, an image tier pointed at a model with no vision capability, and having no catalog to check against at all. An untouched form seeded from the catalog warns about nothing. Context window and price per 1M render under the entered model, since browsers disagree about whether a <datalist> option label is shown at all and those numbers are the reason to pick one tier model over another. (Closes #142)

  • Onboarding remembers a per-provider profile. Switching LLM providers and coming back restores the model, the non-secret connection settings (base_url, proxy, api_key_env, max_tokens, thinking, provider routing) and that provider's router slice — enabled, tier profile, the tiers you authored, the Smart Routing judge target. Install-wide router settings (strategy, default_tier, the Pilot thresholds, judge tuning) stay global and are never reverted by a switch. Machine-written tier tables are re-derived rather than frozen, so an upgrade still moves you onto the current recommended models. Credentials are never copied into a profile. See docs/configuration.md. (Refs #188)

Fixed

  • Switching from a cloud LLM provider back to a local one no longer disables the router or leaves it pinned to the cloud provider's tier profile. (Fixes #189)

  • A stale bundled Control UI is no longer reported as a clean bill of health. Gateway boot and agentos doctor warn (gateway.control_ui.dist_stale) when the bundled React UI is older than the frontend sources in a checkout, instead of serving a stale web UI silently. The warning is advisory and never gates readiness — source mtimes are a hint, not an oracle — and wheel installs, which ship no frontend sources, are never flagged. (Fixes #200)

Documentation

  • The inline-chart contract is findable while you are writing a skill. It was documented only in artifacts-and-media.md, which nothing on the skill-authoring path links to, and features/skills.md — the canonical skills reference — never mentioned artifacts at all. So a skill author had no way to learn that publishing one mime rather than another is the whole difference between a chart and a download chip. features/skills.md now lists the mimes that render inline and links to the contract, the tools reference says the same on the publish_artifact row, and skill_create points at it in its result rather than its description, which would spend tokens on every turn to say something that only matters at the moment a skill is written. Both chart sections also say to keep --output a bare filename: publish_artifact only accepts files under the active workspace, and a model told to build a chart payload will reach for /tmp unless told otherwise — which fails the publish after the candles were already fetched.

Full changelog: v2026.8.6...v2026.8.7