Skip to content

AgentOS 2026.7.27

Choose a tag to compare

@github-actions github-actions released this 27 Jul 16:37
93fd505
Changes since v2026.7.26

- A variable reported as missing is now checked against the places a
  credential may already live. If `gh auth login` has been run, `GITHUB_TOKEN`
  is reported as available from the GitHub CLI and can be imported with
  `agentos env import GITHUB_TOKEN` or a button on the Environment screen.
  Checking runs `gh auth status`, never `gh auth token`, so nothing reads a
  secret to decide whether one exists; importing only happens when asked for.
- When a skill's requirements are unmet, `skill_view` appends a setup note
  saying what is missing and what to do about it — and what to do depends on
  who is listening. A chat channel is told a secret must not be collected
  there because it would be stored in the conversation; an unattended run is
  told to continue and state what does not work; an interactive session gets
  the actual command. The skill still loads either way.
- Environment variables can be managed from AgentOS instead of by hand-editing
  `~/.agentos/.env` and restarting. Every surface that could already *detect* a
  missing variable can now *fix* it: a new **Environment** screen in the Web UI
  (`/env`), an `agentos env list|get|set|unset` command, `env.*` gateway RPC,
  and a **Set <VAR>** action in the Skills dialog next to the existing
  install action. Setting a variable applies it to the running gateway, so a
  skill that was ineligible for want of one becomes eligible without a restart.
- Skill manifests can describe the variables they need — a description, where
  to obtain the value, and whether it is a secret — instead of only naming
  them. Existing manifests using the plain `requires.env: [NAME]` list keep
  working unchanged.
- Skills can also declare non-secret settings under `metadata.agentos.config`,
  stored in the TOML config under `[skills.config]` rather than in `.env`.
  Their current values are appended to what `skill_view` returns, so the agent
  starts from what is configured instead of asking.
- The agent has `env_list` (names and set/unset state, never values) and, gated
  behind the approval queue and hidden by default, `env_set`. There is no
  reveal tool: a model that can read back stored credentials is one prompt
  injection away from exfiltrating them.
- "Is the agent actually being offered this skill?" is now a question with an
  answer. Every skill row from the gateway, and every line the agent's own
  skill listing prints, carries whether the skill is offered and — when it is
  not — which of six reasons applies: model invocation is disabled in its
  manifest, a requirement is missing, a tool it needs is not enabled in this
  session, a native tool supersedes it as a fallback, relevance filtering
  skipped it for this message, or the injected skills block was full. The
  explanation is one sentence naming what to do, and it never contains a
  filesystem path. Ready and offered were previously the same green dot, which
  is why a perfectly installed skill could sit there being silently withheld.
  Five of the six answer from the installed set alone, so the Skills page shows
  them before you send anything; only the relevance-filtering one needs a
  message to rank against and stays in the decision log.
- With `[tools] enabled = false`, skills that require a tool are now reported as
  withheld rather than available. The Skills page previously answered against
  everything the install could offer while chat answered against a turn with no
  tools at all — the same skill, two answers.
- How a skill was acquired — `shipped` with AgentOS, installed from a `hub`, or
  a `local` directory you added — is now a fact AgentOS records and reports,
  alongside the source, identifier, version, and install time for hub installs.
  It is derived from the install record rather than guessed from which
  directory the files sit in, so moving a skill does not change the story of
  where it came from.
- The same record answers whether Update and Remove will actually work. A
  hub-installed skill whose files no longer sit where the lockfile recorded
  them keeps Update — an update re-fetches by identifier — and loses Remove,
  because AgentOS will not delete files it cannot prove it owns. The Web UI
  says so instead of offering a button that fails.
- Skills can name a publisher, so a partner's skills carry that partner's
  identity whether they shipped with AgentOS or you installed them from that
  partner's hub. Publishers are allowlisted **inside AgentOS**: a `SKILL.md` or
  a hub catalog can only *select* a recognized publisher by id, never describe
  one. A third-party skill that writes a partner's name, URL, and logo into its
  own frontmatter renders as an ordinary unbranded skill. Selecting an id is
  restricted too: only a skill shipping inside the release may name its own
  publisher, and an installed one is branded by the hub catalog row it came
  from, so a directory dropped into a skills path can never appear as a
  partner. Publisher is independent of provenance — one says whose name is on a
  skill, the other where the text came from and under what licence.
- `agentos skills list --json` gained `publisher` and `acquisition`, built by
  the same code the gateway and the Web UI use. It deliberately has no
  `availability` key: that depends on a chat session's tool surface, which a
  CLI process does not have, and an absent key means "not computed" rather than
  "not offered".

- The Skills screen's Installed tab now groups cards by where a skill came
  from — **Partners**, **Shipped with AgentOS**, **Installed from a hub**,
  **Your local skills** — instead of by which directory holds the files. The
  storage layer is still shown, as a chip on each card, because it decides
  which skill wins a name collision; it no longer decides the heading. If you
  navigated by the old `Bundled` / `Managed` headings, the cards under them are
  now under `Shipped with AgentOS` and `Installed from a hub`.
- `skills.max_skills_prompt_chars` now defaults to **24000**, up from 8000. The
  bundled skill set renders to about 16k characters with descriptions, so the
  old default silently forced every default install past the budget and into
  name-only mode — the model had never seen a skill description on a stock
  install. Raise it further if you install many skills; lower it if you run a
  model with a small context window, where the whole-request ceiling can be
  smaller than this budget. See
  [configuration.md](docs/configuration.md#skill-prompt-budget).

- Environment writes are refused for names that steer subprocess execution
  (`PATH`, `LD_PRELOAD`, `PYTHONPATH`, `EDITOR`, …) or AgentOS runtime posture
  (`AGENTOS_AGENT_PERMISSIONS`, `AGENTOS_GATEWAY_TOKEN`, `AGENTOS_STATE_DIR`,
  …). Every tool AgentOS spawns inherits `os.environ` and several guards are
  read from it, so a writable surface without this gate could widen what the
  agent is allowed to do. The gate applies on write only — values set in your
  shell or by editing the file directly keep working, and the `AGENTOS_` prefix
  is not blanket-blocked.
- Listings never carry a value. `env.reveal` is a separate method, rate limited
  to five per thirty seconds and written to the audit log.
- The Hermes migration wrote the migrated `.env` at the default umask, leaving
  imported credentials world-readable on a typical box. It now writes `0600`,
  like every other `.env` AgentOS creates.

- Two `.env` lines that AgentOS previously ignored now take effect: a
  bash-style `export KEY=value`, and the first entry in a file saved with a
  byte-order mark. Both were parsed into unusable keys before (literally
  `export KEY`, and `\ufeffKEY`), so the variable was not set. If your `.env`
  has either, expect that variable to start being applied — which is what the
  line was written to do. Values exported in your shell still win over the
  file, so nothing that was already working changes.
- CLI logs now go to stderr instead of stdout. Anything capturing a command's
  stdout to collect log output needs `2>` instead; in exchange, `--json`
  output is parseable on an install that has a populated `.env`.
- The skill snapshot cache is invalidated once on first run, so the first
  command after upgrading rescans skills from disk.

- The session-flush subsystem is gone. It wrote a "flush receipt" before
  destructive compaction and never earned its keep: roughly 8,000 lines for a
  memory path that underperformed. Compaction still records a durable
  checkpoint first, so the pre-image it recovers from is unchanged.
- The `memory.flush_*` and `memory.repair_*` configuration keys are no longer
  read. An existing `agentos.toml` keeps working — the keys are dropped on load
  with one warning naming them, and the file is rewritten on the next config
  save. They will be rejected outright in 0.2.0.

  Removing `memory.flush_enabled`, `memory.flush_compaction_safety_mode`, and
  `memory.flush_compaction_requires_safe_receipt` matters most. With no flush
  service left, no receipt can ever be written, so `flush_enabled = true`
  combined with `block` (or the legacy `requires_safe_receipt`) would have made
  compaction demand a receipt nothing could produce: refused on every turn,
  context window filling until the provider errors, with a single warning line
  as the only clue.
- `sessions.reset` and `sessions.contextCompact` no longer return a
  `flush_receipt` field, and `agentos reset` no longer prints a "Flush mode"
  line. Both described work that no longer happens.

- `env_key` is not always a variable name: providers that authenticate by
  OAuth carry the literal string `"OAuth"`, which put a variable called
  `OAuth` on the Environment screen that nobody could set.
- `skill_list` no longer tells the model to call `env_set`, which is hidden by
  default and so usually not callable — the same dead-end this feature exists
  to remove.
- A `.env` value with significant leading or trailing whitespace was written
  unquoted and then silently trimmed when read back. The OpenClaw migration
  carries a command allowlist across, and its entries are prefix patterns:
  `"^pytest "` with the trailing space matches that command, while `"^pytest"`
  without it matches anything starting with those six characters. Migrating an
  allowlist and quietly widening it is the wrong direction.
- `.env` parsing now recognises the bash-compatible `export KEY=value` form.
  A hand-written `export GITHUB_TOKEN=…` was previously invisible to AgentOS,
  and a save would have appended a second, competing definition.
- `/reset` in the standalone chat TUI works again on sessions with a non-empty
  transcript. It had been gated on a flush service that is never constructed,
  so it aborted every time; `/compact` printed a matching false warning.
- The skills block no longer writes an absolute filesystem path for every
  skill into the system prompt. Nothing read it — skills are looked up by name,
  and the skill-reading tool explicitly tells the model not to go looking on
  disk — while it accounted for roughly two thirds of the block and put the
  user's home directory in front of the model on every turn. Removing it, with
  the raised budget above, is what lets a stock install list every skill with
  its description.
- Upgrading lifts an existing `skills.max_skills_prompt_chars = 8000` to the new
  default. The key is materialised into every saved `config.toml`, so raising the
  default alone would have reached new installs only, and 8000 is exactly the
  value that cannot fit the shipped skills' descriptions. The rewrite runs with
  the config migrations on the next gateway start, takes the usual timestamped
  backup, and touches only that exact old default — a budget someone chose is
  left alone.
- A skill that appears in a skills directory while the gateway is running is
  now picked up on the next turn instead of at the next restart. The cache was
  only cleared through AgentOS's own install paths, but the directories are
  shared: `agentos skills install` runs in a separate process, and
  `~/.agents/skills` is written to by other agents on the same machine. A skill
  from either was on disk, absent from `skills.list`, absent from the prompt,
  and unmentioned in any log. The cache is now validated against the same
  file manifest the on-disk snapshot already used, which costs one stat sweep —
  measured at 0.6 ms for 65 skills — on each load.
- `~/.agents/skills` and `<project>/.agents/skills` are honoured when they are
  created after startup. Both resolved once at boot and a missing one collapsed
  to "no such layer", so the first cross-agent install on a machine stayed
  invisible until a restart. The managed directory was already exempt for this
  exact reason; these two now match it.
- The guidance above the skills list no longer argues against using it. It
  opened with "Skills are optional task playbooks" and told the model to load
  one "only when a listed entry clearly matches" — while the same block, in the
  compact mode a stock install always fell into, listed nothing but names. A
  bare name matches nothing clearly, so the instruction could not be followed
  and the honest reading was "skip it". The two failure modes are not
  symmetric: loading a skill that turned out to be unnecessary costs a little
  context, and skipping one that carried the right endpoints, commands, or
  conventions produces a confidently wrong answer. The block now says so, asks
  the model to load on partial relevance, and — when only names are listed —
  states plainly that a name is not enough to rule a skill out.
- When the skills block does overflow its budget, the skills it drops are no
  longer chosen by load order, which always landed the cut on the skills an
  operator had installed. The cut now follows layer precedence, so `extra` and
  then `bundled` skills go before the ones in a writable skills path. The drop is
  also reported instead of being silent: a `skills_filter.budget_truncated`
  warning naming the dropped skills, and a `prompt_budget` reason on each
  affected skill.
- The skill count and skill-id list in turn metadata and the
  `skills_filter.applied` log counted skills that the budget had already thrown
  away, so the one place that could have revealed the problem asserted
  everything was fine.
- Setting an environment variable or installing a missing binary now takes
  effect for the agent without a gateway restart, which is what the
  Environment feature promised. The chat path built one eligibility cache at
  import time and remembered a *negative* lookup for the life of the process,
  while every other surface rebuilt its own per call — so the Skills screen
  reported a skill as ready while the agent refused to be given it, forever.
- Browsing or searching a skill hub now also shows skills you already installed
  from that source, including ones its catalog does not list. A skill installed
  from a GitHub URL used to vanish from the page it was installed on, because
  an empty browse never returned a row for it.
- The Installed marker in the community list no longer goes stale after a
  removal, and no longer fires on a catalog entry whose *name* happens to match
  an unrelated skill's install *identifier*. Names are matched against
  installed names and identifiers against installed identifiers.
- Installing a skill while a search is open no longer loses the row when the
  search is cleared, and the skill dialog no longer unmounts itself when the
  list underneath it changes.
- A failed hub search reports the failure instead of rendering as "no skills
  match your query", and results the hub matched on a tag are no longer
  discarded by a second client-side filter that could not see the tag.