AgentOS 2026.8.12
A model-control and reasoning release. Choosing which model answers a turn is now a control in the chat composer rather than a slash command to remember, and a pin you set stays set. The Web UI shows the model thinking while it works, and a hub-installed skill that renames itself in its own manifest no longer masquerades as a local one.
Added
-
A route picker in the chat composer. One searchable list holding
Auto, the text tiers your[agentos_router]config actually defines — each labelled with the model it resolves to, e.g.c1 · gpt-5.6-luna— and every model the active provider publishes.Autohands routing back to the Pilot Router and reports the tier it last chose (Auto · c2), so automatic routing stays legible rather than opaque. With no Pilot Router configured the control is disabled rather than hidden, which keeps the composer from reflowing when the router is toggled.-
The pin is read back from the gateway, not mirrored in the browser. A new
router.hold.getRPC is the single source of truth, so a reload shows the pin that is really in force and a pin set from/c3agrees with one set from the picker. Two surfaces holding their own copy of the same state is how they drift. -
/use <model-id>does the same from a slash command on web, TUI and channels. It is a new verb rather than an argument to/model, whose argument already filters the listing — overloading it would make/model gptambiguous between "show me the gpt models" and "switch to gpt". -
A directly-named model rides on the default tier. Thinking level and pricing baseline live on a tier, not on a model id, so a bare model id inherits them — which also keeps the router step's
tiers[hold.tier]lookup valid. -
Only the active provider's models are offered, and accepted. Every turn runs through the single configured
llm.provider; a tier'sproviderfield is metadata, not a client selector. Anything else is refused at the moment it is chosen rather than failing on the next turn. On OpenCAP that means the bare canonical ids, not the namespaced<upstream>/<model>aliases its inference endpoint also answers to.
-
-
The Web UI shows the model thinking. Reasoning arrives as a typed
ThinkingDeltaEventfrom the Anthropic, OpenAI-compatible and Ollama providers — including models that emit<think>tags inline, split back out of the text stream as it arrives — and renders as a live collapsible block that folds itself the moment reply text starts. A fresh block opens per reasoning round, so mid-turn work stays visible instead of being appended to the first one. History carries ahas_thinkingflag so a reloaded thread still offers the block, andcontrol_ui.show_thinking(default true) gates the whole surface.- It is web-only by construction. Thinking travels on a
session.event.thinkingemit path and a CONTROL_ONLYchat.thinkingRPC, so channel adapters never receive it — reasoning is not something to page a Telegram or Discord thread with, and a flag that could be flipped the wrong way is weaker than a path that does not exist.
- It is web-only by construction. Thinking travels on a
-
The composer border carries a light sweep while a turn runs.
Changed
-
Breaking: a tier pin set by a user is now sticky.
/c0…/c3— in the Web UI, the TUI, and every channel — hold until/autoclears them, instead of lapsing after ten idle minutes. A pin is a standing instruction, and a selection that silently reverted would have made the new composer control lie about what is running. The practical consequence is a bill: pin/c3and forget, and every later turn keeps paying forc3until someone runs/auto. Routing the model chooses for itself mid-turn is unchanged and still lapses on its own. Two things still outrank a pin, both pre-existing: image turns route to a vision tier before pins are consulted (the Web UI flags such a turn), and a pinned turn skips the large-context tier floor, so it fails at the provider rather than being upgraded if the conversation outgrows the pinned model's context window. -
The router-fx strip is suppressed while a tier or model is pinned. It exists to show the router weighing candidates and settling on one; a pin decides the route up front, so the animation was dramatizing a deliberation that never happened and restating the composer's own picker every turn. It returns the moment routing goes back to
Auto. -
A pin withdraws the model's own
router_controltool for the duration, along with its target menu in the system prompt. The user's choice already outranked the model inside the router step, so leaving the lever on the surface only invited calls that could not take effect and paid tokens to describe them. Holds the model installs for itself are unaffected — hiding the tool on its own hold would strand a session on a transient escalation.
Fixed
-
A hub skill whose
SKILL.mdrenames itself no longer renders as a local one. The lockfile is keyed by the install directory — the source's slug, which is also the directory the installer writes into — but it was read back by the name the frontmatter declares, and published skills do rename themselves: hubytdlp-transcriptships a manifest namedyoutube-transcript. The lookup missed,_derive_acquisitionsaw no entry, and a perfectly ordinary hub install rendered under "Your local skills" with no source, no version, no scan facts, and neither a Remove nor an Update button — the same wrong row reachingagentos skills listand the agent'sskill_list. Entries now join by the resolved path the entry already records, falling back to the name for legacy entries written beforepathexisted. (Fixes #285)-
The removability guard read the manifest name too, so it reported a removable install as an orphan. The BUNDLED exception is still applied before either lookup, so a stale entry recording the packaged bundled directory cannot turn a shipped skill into a removable hub install.
-
skills.uninstallandskills.updatetranslate throughlock_key_for_skill. They address the installer, which is keyed by the directory, while every caller addresses the name a user sees. The wire contract is unchanged and a name no skill loads under is still passed through, so clearing a stale entry by its own key keeps working. The CLI's no-gateway uninstall path resolves the same way, against a loader now shared withskills listrather than built twice. -
Installs already on disk heal themselves: no lockfile migration, no re-install, no frontend change.
-
-
OpenCAP and Bankr routes reported
supports_reasoning=Falsefor every model, which silently no-oped a tier'sthinking_level— a setting that appeared to apply and did nothing.
Full changelog: v2026.8.11...v2026.8.12