CHANGELOG.md
Rama main · réplica de lectura del repositorio original.
# Changelog
Notable changes to AgenticOS. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
[Semantic Versioning](https://semver.org/spec/v2.0.0.html) with one exception:
AgenticOS stays on major version 1, so a change a deployment has to act on ships
in a MINOR release. Read a minor release's notes before upgrading.
Two things are versioned separately from this file and worth knowing about:
- **`SPEC_VERSION`** — the agent spec format, currently **14**. A published agent
and a client's exported YAML both carry it, so it only ever moves forward with a
migration that keeps old documents loading. See
[the spec reference](docs/reference/spec.md).
- **The migration chain** — `backend/alembic/versions/`, squashed to a single
`0001_baseline` for this first version. Revision ids named below (`0038`,
`0059`, `0066`) are history: they describe when something changed, not a file
that still exists. Schema changes are listed here by what they do.
## [Unreleased]
## [1.64.0] - 2026-11-11
### Added
- Public app and shared conversation viewers show the AgenticOS logo and a GitHub link, with a responsive floating badge and an organization setting to hide it. Enabled by default; password-protected apps show it after unlocking.
## [1.63.0] - 2026-11-10
### Added
- Maintain a Helm chart for the API, worker and console with external pgvector
PostgreSQL, Redis/Valkey and S3, blocking migration hooks, restricted container
settings, health probes and a reproducible Kubernetes smoke test. Include an
OpenShift configuration candidate without claiming cluster validation (#2872).
### Fixed
- Download S3-backed ingestion sources in the worker instead of requiring the
API's local scratch directory to be shared across pods (#2872). **Existing S3
deployments must drain ingestion and replace workers before upgrading the API,
or use a maintenance window:** new API processes no longer write the shared
scratch files old workers expect. Local file storage keeps its shared path.
## [1.62.8] - 2026-11-10
### Fixed
- **A workflow run's steps are listed in the order they started.** The run
view listed steps in the order they were recorded, so a loop's item step
came after the steps it started. The list now holds only the steps that
started, sorted by start; a step still waiting or skipped shows on the
canvas only. Clicking a loop step's iteration now shows that iteration's
input and output, not the last iteration's; an iteration with no result yet
shows none. A step test still pins the last iteration's data. A long step
list now scrolls inside its panel instead of making the canvas taller. Start
order preserves sub-millisecond timestamp precision (#2866).
## [1.62.7] - 2026-11-10
### Fixed
- **Keep the Architect's bundled guide links usable.** Resolve links to included
pages within the skill and send other documentation links to the published
site. Generate the same output from an empty directory and preserve external
links and Markdown code examples (#2862).
## [1.62.6] - 2026-11-10
### Changed
- Remove an unused serialized channel access-policy default and its outdated
SQLite comment. Active channel-bot defaults and policies are unchanged (#2869).
## [1.62.5] - 2026-11-10
### Fixed
- **Reclaim old release images before deployment pulls fill the host.** Retain
current and rollback images with local pins based on healthy containers, plus
two additional unused image IDs per release repository. Protect every running
or stopped container, other image aliases and repositories, sandbox runtimes
and volumes. Check for 5 GiB of storage headroom before pulling, and download
backend and frontend images before restarting either service (#2849).
## [1.62.4] - 2026-11-10
### Fixed
- **Parent deletion no longer depends on foreign-key trigger order.** Deleting
a routine's creator clears its delivery chat, and deleting an agent preserves
its pages with their publisher and environment cleared. Defer the two
cross-link checks until transaction end so cascading deletes can finish first;
invalid references are still rejected. Existing deployments receive the same
fix through a data-preserving migration (#2841).
- **Keep the CI checks independent of runner timing.** Successful artifact-read
tests use a controlled deadline clock, while the real timeout tests retain
their own clocks and PostgreSQL limits. Improve notification tests check every
event and duplicate without assuming an order for identical transaction
timestamps (#2868).
## [1.62.3] - 2026-11-10
### Fixed
- **Refresh the AWS SDK and CLI dependencies.** Update boto3 to 1.43.126 and
Click to 8.5.1, with the third-party notices regenerated. Soup Sieve stays on
3.0.4 within the existing `<4` constraint: its 4.x template-selector change
breaks the established `html.parse` links and matches contract (#2857).
## [1.62.2] - 2026-11-10
### Fixed
- **Password sign-ins no longer prompt everyone to check invitations.** The
generic mailbox-verification notice is removed, so deployments without email
delivery and accounts without a working mailbox are not repeatedly offered an
unusable sign-in link. Verified sessions still see actual addressed invitations;
original invitation links remain usable without an email provider (#2858).
## [1.62.1] - 2026-11-10
### Fixed
- **Existing notifications survive the evaluation upgrade.** The early evaluation
migrations retain `capability_requested`, `suggestion` and `finding` while
rebuilding the notification and preference checks. Previously, upgrading a
populated 1.61 deployment could fail before the final merge revision restored
those values. No notification is deleted or rewritten. Deployments whose
1.62.0 upgrade rolled back can upgrade directly to this patch; deployments
already at the merged head need no additional migration.
## [1.62.0] - 2026-11-10
Agents can now be measured and improved from evidence: datasets of test
questions, eval runs and suites, guarded promotions, knowledge gaps and the
Improve wizard. Nothing in it changes an agent, a knowledge base or an
environment without a person's decision.
### Upgrading
- **Serve the `eval` worker pool.** `WORKER_POOLS` now defaults to
`agent,eval,ingest,system,workflow`. A deployment that sets it explicitly must add
`eval` to one worker, or eval runs stay queued until they fail a day later.
`WORKER_EVAL_CONCURRENCY` (default `4`) sizes that pool, and
`agenticos cmd doctor` names a pool no live worker serves.
- **Evaluation settings belong to datasets.** Choose the grading model and
instructions in **Settings**, alongside generation/improvement models and
instructions, using the Agent Builder's model picker and Markdown editor.
Code-defined helpers keep internal run identities, budgets and historical pins
without appearing in the agent catalog or consuming the user-agent allowance.
There is no organization-wide AI-assistance switch or grading-model override.
Queued tasks keep their admitted model and instructions.
- **`GET /runs` lists every run.** Activity and the runs API now include eval
runs and the platform's own agents at work beside conversations. A client
that wants people's runs only passes `source=conversation`; the export takes
the same filter.
- **Knowledge searches made during runs are recorded.** Each search an agent
makes in a run that answers a person is kept (the first 1,000 characters of
the query, what came back and how close it was) to find knowledge gaps. It is
deleted with its run and when the person is erased; data exports and erasure
also cover dataset cases, eval results and drafts taken from a person's
conversations. See [Data protection](docs/data-protection.md).
- **New permissions.** `datasets:view`, `datasets:edit`, `datasets:run` and
`promotions:override` join the catalog with defaults for every built-in role.
Starting or estimating an eval also needs `runs:view`.
- **Migrations `0160_datasets.py` to `0253_freeze_dataset_helper_settings.py`** add
the dataset, eval, suite, knowledge gap and improvement tables and new
columns on agents, agent runs, MCP connections, knowledge-base documents, API
keys and background jobs, and extend the agent kind and notification event
checks. Existing grader and queued-task settings are preserved; a downgrade drops these tables with
everything in them.
- **`0304_merge_evals_platform.py`** joins evaluation previews with the released
platform history. Upgrade either branch normally; existing revisions keep
their identities and apply only once.
- **New settings**, all optional: the `EVAL_*` settings in
[Eval runs](docs/evals.md#settings), `KNOWLEDGE_GAP_MIN_SIMILARITY`,
`KNOWLEDGE_GAP_TOPIC_SIMILARITY` and `DATASET_MAX_VERSION_ROWS_PER_ORG`.
### Added
- **Datasets.** Versioned test questions with expected tool calls, checks, a
reference answer and tags. Cases are written in the console, imported from
CSV or JSONL, added from a rated chat answer with **Add to dataset**, or
drafted by the case generator from the agent, its knowledge, real chats and
red teaming and accepted under **Generated**. Each agent can build its own
test set from its rated answers. Every edit makes a new version, and a
warning appears before a second case asks the same question. Leaving a
dataset with an unsaved case, grading or details edit asks to save, discard
or stay, and an unsaved case or grading edit is kept in the browser and
offered back on return. The dataset list counts each dataset at one version,
so its figures stay consistent while cases are being added.
- **Grading.** A dataset is graded by checks, expected tool calls and a judge
with criteria, a scale and a pass mark. A dataset can have a judge of its
own; criteria can be scoped to case tags. The judge quotes the answer for
every grade, and unverified quotes are kept apart. **Review** lets a person
confirm or overrule a score, with notes that can become judge criteria, and
shows how often people agree with each judge.
- **Eval runs.** An agent's published version or draft answers every case of a
dataset version, optionally on several models and beside a baseline version
in the same run. The estimate comes first and the run starts on a second
click. Flipped cases are re-asked before a regression counts, and results
are compared on quality first, then cost, tokens and latency. Each answer,
criterion and flip reads as one pass, fail or undecided badge, and a check
reads as a rule. **Evals** lists every run in the organization.
- **Isolated runs and test connections.** An eval runs the agent without
touching the outside world: tools that write are held and answered from
recorded calls, and capabilities declare which tools only read. A named
environment can swap an organization MCP server or a capability's vault key
for a test one, or switch a binding off, for every run in it.
- **Eval suites.** A dataset an agent is held to, run on a schedule, on
publish, on promotion, when a skill, context file or knowledge base it uses
changes, or by hand, with a threshold each result must meet. The owner is
notified when a result fails, is inconclusive or does not run.
- **Guarded promotions.** An environment can name suites that must pass on a
version before it takes it; a promotion that has not passed is refused and
names each guard. A guard is pinned to its dataset version, grading and judge
publication until **Move the pin**. **Override**, with
`promotions:override` and a reason, promotes past the guards and is audited.
- **Knowledge gaps.** Questions a knowledge base could not answer, grouped into
topics on the knowledge base's and the agent's **Knowledge gaps** tab. The
classifier sorts rated-down answers by cause; the drafter writes the missing
passage with its sources and `{{what to fill in}}` placeholders. A person
reviews and adds every document, and can turn a topic into dataset cases.
- **Authoring assistant.** **Improve** suggests changes to an agent's
instructions, tool descriptions, configuration, skills and context files from
rated-down and failed runs; **Verify** reviews your own draft. Each
suggestion is accepted, edited or dismissed on its own and lands in the draft.
A suggestion that widens access is marked **Adds access** and keeps writing
tools behind approval, and a model change is accepted only after a check with
evals. The assistant can also propose a new skill from repeated answers.
- **Text changes read as a diff.** A changed text (instructions, a tool
description, a field or a context file) shows removed and added lines with the
changed words marked, unchanged lines folded, unified or side by side.
**Edit** on an instructions suggestion opens the whole instructions, current
beside proposed, with the diff redrawn as you type. The assistant's reasons
cite numbered conversations rather than run ids.
- **Create skill** from a skill idea the assistant did not add because fewer
than three answers back it. Whoever holds `skills:edit` and may edit the
agent previews and edits it, and creating it adds the skill to the library
and binds it to the agent's draft only. No model is called. Anyone who may
edit the agent can dismiss the idea instead, and undo that.
- **To review and Decided.** The assistant's card on the Build tab splits
suggestions into what still needs a decision, shown whole, and what was
accepted, edited or dismissed, each folded to its kind, decision and a
one-line summary. Both tabs group changes by kind. Publishing the agent ends
the cycle: the card stops showing suggestions and findings from before the
publication, which stay stored with their decisions.
- **The Improve wizard.** A resumable session at `/agents/<agent>/improve/<session>`
that analyses evidence, proposes changes, tests them on held-out questions,
and stops at a result for a person to accept and publish. It shows the
estimate and expected time before anything is spent, separates problems with
the agent from missing knowledge (a person can leave an example out with
**Ignore this**), makes up to three rounds within a spending
limit, can test a knowledge draft in context or through search, and offers
more test questions when too few remain. Each step opens on figures and
charts, with full answers, quotes and reasons folded into cards. **Improve**,
an outline button with a trending-up icon in the agent header, on the Build
tab's assistant strip, the **Needs attention** badge, the dashboard and the
**Knowledge gaps** tab, opens the agent's session still in progress or
waiting for a decision, stopped and failed ones included, and a new one once
that session is kept as a draft, published, discarded, cancelled or outdated;
a dot on it says when the agent
needs attention. The agent's **History** tab lists every session as an
**Improvement history**; a finished one opens read-only, its last step saying
what was decided, by whom, with which changes and knowledge documents. A
first improvement has a guided tour. Background sessions and a one-off Improve request are
also available through the API.
- **Evaluation workspace.** All dataset tabs share full-screen controls and
console tables. Case and review details open in side panels; case forms put
input and answers first and optional checks behind expandable sections.
Import explains CSV and JSONL and downloads ready-to-use examples. Creation,
import, generation and Activity actions sit beside the cases table.
- **Verify my edits** saves the draft and opens the standard eval comparison
against the published version, with an estimate before starting.
- **Activity shows whose work a run was.** A **Source** filter narrows to
conversations, Improve and evals, or system agents, and each platform run
names its agent and links the eval run, Improve session, gap topic or
dataset it worked on.
- **Notifications** for a failed or re-evaluated suite, an override, an applied
shared change, a finished improvement session, eval run and case generation,
each with a preference under **Settings → Notifications**.
- **Dashboard.** Widgets for datasets, eval runs, eval suites, the review
queue, knowledge gaps, suggestions waiting by agent, skill and file, and the
agents that need attention, with **Improve**. An agent needs attention for
answers rated down and failed runs on the version it serves now, so
publishing a fix clears its badge until the new version earns its own. The
greeting counts everything waiting on the reader, and spend on improvements
is shown apart from evals.
### Changed
- The agent page's tabs are reordered, with an **Evals** tab that shows results
first.
- A publish refusal offers the one-click fixes it names beside it.
- Open eval, dataset, suite and improvement pages refresh from live change
events instead of polling.
### Fixed
- Preserve trusted MCP account identity alongside evaluation isolation metadata.
- Hide private datasets from unauthorized sharing-route callers, matching other resources.
- Keep initial background schedule times distinct when short intervals cap their startup delay.
- Give isolated evaluation attempts disposable run-scoped workspaces, so agents
configured with conversation workspaces can run without a chat and never reuse
persistent files. Clarify setup failures and refresh the evaluation results UI.
- Avoid a duplicate sandbox binding when recognizing a legacy Architect agent,
which could prevent the console's assistant from loading.
- Simplify dataset navigation to Cases, Results and Settings, keep grading cards
equally tall, and choose saved pipeline models through a searchable selector.
Show all scored answers together in a table, without review-state segments, a review-policy
card or the dataset journey banner.
- Guide dataset setup from cases through grading, evals and review, with direct
writing/import/generation actions, contextual next steps, coloured option
chips and a cases table matching Virtual Tables.
- Make evaluation workspaces easier to use: split case editing into conversation
and expectations, keep save actions visible, choose saved pipeline models first,
fold default instructions, and lay out grading, helper settings and knowledge
gaps side by side on wide screens. Evaluation targets support keyboard arrows.
- Align datasets, evals and Improve with the current console cards, dialogs,
status text and chart tooltips. Preserve routine approval policies and join
both published migration histories when upgrading from the preview or main.
- Match eval trends to dashboard charts with the shared accent, gradient and axis typography, and distinguish runs within a past day by their start times.
- Present dataset cases with the chat message layout, labelled Markdown reference answers, expandable context and tool arguments, and editing in the fixed panel header.
- Simplify Agent Builder by keeping Improve and suggestions in Evals, and make dataset cases and eval histories easier to scan with grouped creation actions, separate model and result columns, case counts and a compact trend above the run history. Keep creation buttons visible but disabled on historical dataset versions so switching snapshots preserves the toolbar layout.
- Join the eval-helper and RAG-index migration histories so installations on
either branch upgrade to one head without rewriting applied revisions.
- Keep incomparable eval runs and improvement rounds from presenting score
differences as confirmed regressions or fixes, including knowledge checks and
acceptance summaries. Exclude invalid comparisons from measurement noise;
retain their individual answers and grading results.
- Preserve assistant replies with file origins in chat history by serializing
their UUID references before writing JSONB.
- Show an exceeded eval budget explicitly instead of describing a negative
amount as money left after the run.
- Clearing the Architect's uploaded avatar restores its generated face, just as
it does for other agents. The special mark no longer overrides an empty avatar.
- Recognize OpenRouter's dated Mistral embedding identifier when pricing RAG
searches and improvement sessions, using the existing upstream price snapshot.
- Serialize grading edits, source erasure and promotion guard changes, and refuse
queue-level retries of an eval that has already ended.
- Match the new dataset, evaluation, authoring and Improve views to the console:
use the available page width, keep editor actions reachable, stack comparison
metrics and case fields on phones, and offer the shared full-window editor
for proposed instructions. All dataset tabs and knowledge gaps expand in
place, and opening an agent from its card keeps the normal builder entry.
A walkthrough still selects a tab after its
spotlight adds disclosure attributes.
- Price embedding models OpenRouter serves by their bare OpenAI names, so
knowledge searches through OpenRouter are no longer booked at $0.
- Recommend a workspace the organization can publish when creating an agent,
and ask again when sandbox connections change.
- Keep a tour's Back and Next live while a tab or popover opens, skip optional
stops missing from the page at once, and offer the page's help on the Improve
wizard and an eval run.
- Show an agent page's controls from the reader's access to that agent,
including edit grants, and stop an agent page of another organization from
loading forever.
### Security
- Reading or deciding assistant-generated proposals requires `runs:view` as well
as target access. Summaries and proposed text can contain conversation content
even when explicit evidence quotes are hidden.
- Recognised secrets are redacted from dataset cases, eval answers, tool-call
evidence and errors before they are stored.
- A dataset case copied from a conversation shows its text only to readers who
may read runs or that conversation; review answers and evidence need
`runs:view` and access to the agent.
- Queued case generation and improvement work runs with the original API key
and rechecks its current scopes and membership before each paid step.
- A system agent never reads anyone's memory, even from a version published
with memory before that was refused, and reads only the context files and
skills shared with the whole organization. Case generation removes the
personal data the detectors find from people's questions and comments before
the generator reads them.
- A suite and a promotion override can be set up only by a person signed in as
themselves, not through an API key or impersonation.
## [1.61.5] - 2026-11-09
### Changed
- Update the backend runtime, development and documentation dependencies from
#2836. Keep Soup Sieve below 4 to preserve HTML parsing inside templates, and
refresh the distributed third-party notices.
## [1.61.4] - 2026-11-09
### Fixed
- Refuse paused sync sources at the shared service boundary, disable their console
sync button, and reject ambiguous collection-name assignments. Resolve tied
knowledge bases consistently regardless of candidate order (#2744).
## [1.61.3] - 2026-11-09
### Fixed
- Float invitation and onboarding notices in one overlay without reserving a blank
strip or shortening the application. Keep mobile navigation reachable and stack
simultaneous notices.
## [1.61.2] - 2026-11-09
### Fixed
- Tool failures now keep actionable structured details through model continuation,
approval resume and saved transcripts: named missing fields, allowed values,
numeric and collection bounds, safe compiler diagnostics, correction examples,
execution disposition, recovery guidance and an error ID that identifies the
detailed server log. Unknown tool names report
unavailable registration rather than missing permission, and agents check uncertain
execution outcomes before retrying. Budgets, guardrails, loop stops and usage limits
retain their terminal behavior through code mode. Only calls that pass complete
validation count as successful argument repairs.
- MCP schema checks run in isolated processes with bounded concurrency and a deadline,
so server-controlled regular expressions cannot block the application's event loop.
## [1.61.1] - 2026-11-09
### Fixed
- **A step stays in the loop it belongs to (#2770).** A For each body was
whatever the loop's **Each item** port's wires reached, so deleting a wire
inside a body moved the steps after it out of the loop, and a second wire from
that port, which no view drew, made publishing fail with "A loop's body must
start at exactly one loop item step". Each step now names its loop
(`scope_id`), the loop has no **Each item** port, and a body starts at its
**Loop item**. A new loop comes with its **Loop item** and **Loop result**,
which go only with the loop; a step added or pasted in a body stays there; and
deleting a loop deletes its body. Publishing refuses a body step **Loop item**
never reaches. Migration `0301_workflow_loop_scope` rewrites stored drafts,
versions and test-run snapshots, moving an extra wire from the old port onto
the body's **Loop item**; a graph sent or imported in the old shape is read the
same way. See [Workflows](docs/workflows.md#connections-and-foreach-scope).
## [1.61.0] - 2026-11-09
### Added
- A shared first-task hub for web, invitations and desktop, with editable fictional
examples, clearly labelled demonstrations without a model, membership-scoped
goals and real completed-chat progress. Authorized builders can explicitly
prepare a text-only starter without a sandbox.
### Changed
- Require session-bound mailbox proof for received invitations and their logos, paginate older offers, preserve onboarding position across language changes, and use the server clock for snooze expiry. Reject a zero monthly budget before submission.
- Let members enter the trusted AgenticOS setup chat from onboarding without requiring model-management permissions or treating a draft as a runnable agent.
- Default new maps to bundled SVG country outlines and routes without tile-server setup; keep optional street-map configuration and hide its unconfigured dashboard check.
- Preserve focus outlines in onboarding profile cards and spacing below form labels.
- Show organization logos and fallback colors in received invitations before joining.
- Align chat activity rails and keep them outside expanded tool details.
- Reveal new AgenticOS and Architect setup replies progressively before showing the model setup card.
- Select and display onboarding monthly budgets in whole dollars.
- Show optional deployment settings as cards with immediately visible links.
- Prefill the onboarding welcome announcement with an editable message and live preview.
- Place optional onboarding skip actions beside Save and continue in profile cards.
- Match onboarding loading states to workspace cards, profile forms, guided settings, budgets and the first-task canvas.
- Simplify the onboarding budget step to presets and a slider, without a separate numeric input.
- Show pending email invitations after sign-in, with explicit acceptance and organization welcome without needing the emailed link.
- Give Architect the shared model-setup card and a normal chat before model setup, including persisted setup replies in its widget and full chat.
- Guide setup through one decision at a time with a scripted AgenticOS companion,
a monthly-budget slider and announcement previews. Separate administrator, new
member and returning-member journeys; keep operational credentials optional.
Respect legacy completion for existing memberships without hiding a later join.
- Select the shipped AgenticOS before publication and answer first-use chat messages
with a persistent model-setup card. Guide builders to configuration and members
to their administrator without executing a draft or charging a model call.
- Snooze dismissed start offers for 24 hours. Record walkthrough completion
separately after the final step, without requiring optional settings or an AI run.
- Make product tours opt-in, continue accepted invitations into the joined
workspace's start, and sign in new password accounts without repeating the login
form when possible. Keep the invitation destination if sign-in needs a retry.
- Localize native desktop setup in English, Polish, German and Turkish, reduce
required workspace fields, and keep system permissions optional. Explain local
data versus remote AI processing and warn about loopback invitation links.
- Start administrator onboarding with company workspace creation and immediate
team invitations, followed by the existing deployment and organization settings
forms. A sequential wizard replaces the settings sidebar, with separate company
logo, user identity and agent-context questions, Back and save-and-continue actions.
Use actual workspace avatars, equal-height adjacent cards, directional transitions
and transient field highlights that respect Motion preferences. Give the chat
start notice role-aware guidance, blobby, a clear primary action and a dismiss
control that fits desktop and phone layouts. Float it over the desktop console
with a translucent surface, preserving both sidebars at full viewport height. Keep personal workspaces optional and enforce
effective permissions.
- Give onboarding the console's controls, animated blobby and violet workspace
preview that follows the entered name. Present member examples in a split view
with source and result tabs; motion respects reduced-motion preferences.
### Fixed
- Recognize existing agents and personal chat activity, including legacy and
failed chats, so automatic welcome links and start offers do not repeat setup.
Keep manually opened setup available without resetting existing data.
- Keep example navigation on the start page and AI setup in a dismissible dialog
with Escape support and focus restoration. Separate demonstration material
from its recorded result.
- Keep recorded examples available while a preference save is pending or fails,
restore keyboard focus on return, and avoid late chat navigation after leaving
the start. Scope pending start operations to their initiating membership.
- Reserve the dashboard start panel during loading and offer an explicit retry
after failed checks, without shifting the adjacent briefing on successful load.
## [1.60.3] - 2026-11-09
### Fixed
- Include shared resource visibility helpers in the platform coverage and type-checking gates, and guard against their accidental removal (#2143).
## [1.60.2] - 2026-11-09
### Changed
- Update Pydantic AI, its harness and skills integration, pricing data and
Logfire to the versions locked by the agent-framework dependency update.
Normalize wrapped question answers before saving a parked run so the
durable answer remains JSON data.
## [1.60.1] - 2026-11-09
### Fixed
- Probe the readiness endpoint after production deploys; the old health URL returned 404 despite a healthy deployment.
- Paused knowledge sources refuse manual API synchronization, and workers
recheck the pause before downloading or indexing queued or CLI runs.
Knowledge-base collection-name lookups break creation-date ties by ID,
keeping the selected base stable (#2744).
## [1.60.0] - 2026-11-09
### Added
- **Fork a conversation at an answer (#2762).** **Fork into a new conversation**
under an agent's answer opens a new conversation of your own, in the same
project, holding the history up to and including that answer, so you can try
another approach or take a side question elsewhere without changing the
original. Only the owner can fork, up to ten a minute, within 2,000 messages,
10,000 tool calls and 20 MiB; concurrent transcript updates are fenced before
copying. Retained copies have a 100 MiB member and 1 GiB organization
allowance, including fixed row reservations, freed when a fork is deleted.
Drawings with stored image files are refused before copying. The fork copies
messages, tool calls and a long conversation's summary, including its
externalized text and media within the copy limits, not attachment or
workspace files, generated images, cost or runs. Conversations with a saved
checklist fork only at the latest answer and retain its tasks and dependencies.
Its **Forked from** line
is shown only to you. `POST /conversations/{id}/fork` does the same over the
API. See [the console guide](docs/console.md#forking).
- **Conversations shared with you, in the chat sidebar.** They sit under
**Shared with you**, below your favourites, for the organization you are in,
with their agents, unread dots and running state; until now a conversation shared
with you could only be opened by its link. Renaming, sharing, archiving and
deleting stay the owner's; their menu holds **Remove from my chats**, which
ends your own access (`DELETE /conversations/{id}/shared-with-me`).
- **A conversation shared with you to read has no message box.** It used to
offer one, and the message failed with "Conversation not found".
`GET /conversations/shared-with-me` now says each share's `share_permission`.
- **Change a person's access to a conversation in place.** Each person in the
Share dialog has a View/Edit picker, so turning a reader into an editor no
longer means revoking and sharing again. The owner only; a share link stays
view-only (`PATCH /conversations/{id}/shares/{share_id}`).
- **A notification when a conversation is shared with you.** It opens the
conversation, and follows your preference for "Shared with you or your
group" (in the inbox, by email or by push), which the "Shared with your
group" preference is now called.
### Fixed
- Shared conversation favourites and read receipts update immediately, including
new answers arriving in an open shared thread. Channel participants' direct
share permissions are checked even when their thread is already listed.
- Shared sidebar refreshes read only listing columns. Direct-share notification
fanout is rate-limited across conversations by organization, sender, recipient
and pair, retaining a local floor when Redis is unavailable.
## [1.59.1] - 2026-11-09
### Fixed
- Knowledge sync failures now show their error on the dashboard. Knowledge-base
write controls follow effective access to that base, including edit grants,
instead of the member's organization-wide permission (#2772).
## [1.59.0] - 2026-11-09
### Changed
- **Breaking: global unfiled knowledge needs operator provenance.** App-scoped
bases no longer publish or clear ambiguous legacy chunks merely by claiming a
retained collection name. New CLI imports record operator origin; tracked
ingestions retain document origin after their owner or base is deleted.
Migration `0300_unfiled_writer_provenance.py` preserves certain document
ownership and quarantines unknown data. Operators must audit retained imports
with `agenticos cmd rag-unfiled-provenance <name>` and, only after inspecting
their source, explicitly use `--confirm-operator` to share unknown operator
imports with every organization. Known document data is never promoted by
that command. Re-ingest private data into its authorized base instead (#2773).
## [1.58.3] - 2026-11-08
### Fixed
- Desktop and mobile native dependencies use an immutable GTK-compatible backport of the GLib string iterator soundness fix (RUSTSEC-2024-0429). The mobile build no longer enables the legacy HTML path that pulled vulnerable `rand` 0.7.3 (RUSTSEC-2026-0097).
## [1.58.2] - 2026-11-08
### Fixed
- Concurrent first ingests into the same new collection no longer fail on PostgreSQL catalog uniqueness. Table and index creation is serialized per collection, and a rolled-back creator releases waiting writes (#2774).
## [1.58.1] - 2026-11-08
### Fixed
- Nightly proactivity uses its own look attempts rather than watches to decide when someone is due. Successful looks remember which prompts they read, so deferred prompts survive intervening watches and a settled approval or question wait does not cause an extra model call. Watches still count toward personal spending limits. Existing recent messages may receive one catch-up look after upgrading (#2777).
## [1.58.0] - 2026-11-08
### Added
- Workflow agent steps can use the existing Ask Question tool to wait for a user and resume the same conversation. Questions remain available in the originating chat and workflow run view after reload; answers are saved before the workflow worker continues under its current budget. Question cards honor current workflow grants and retain newer questions when polling overlaps a delayed answer response. Completed answers remain in agent context after chat compaction, and question waits do not stall shared mailbox polling.
## [1.57.0] - 2026-11-08
### Added
- Workflow Manual, API and Called by a workflow triggers can declare an optional
JSON Schema Draft 2020-12 input contract, including nested objects, arrays,
enums, required fields, length limits, additional-property restrictions and
local `$defs`/`$ref` references. Published versions freeze the contract; invalid
input is rejected before a run starts with field paths. API and MCP discovery
expose the effective schema, preserving existing simple-field and untyped inputs.
Raw-schema validation runs in an isolated process with bounded resources and
diagnostics, with Linux address-space limits and native macOS support. Step tests use the contract of the entry that reaches the tested step.
Publication rejects negations that exclude every object; discovered legacy
date fields retain calendar validation without requiring format assertions.
Discovery marks the additional integer-token requirement of legacy simple fields.
Validator memory exhaustion returns a controlled input refusal rather than
a retryable server failure.
### Changed
- **Breaking:** agent `list_workflows` discovery refuses encoded responses above
32 KiB. Narrow the agent's workflow binding or input contracts, or inspect
contracts through the HTTP input-schema endpoint outside the agent context.
## [1.56.4] - 2026-11-08
### Changed
- Add optional CodeRabbit review preferences and document installation and review triggers; the GitHub App must be installed separately (#2812).
## [1.56.3] - 2026-11-08
### Fixed
- Keep guardrail-refused prompts out of later models through queued workflow branches, retries and calls, routine retention, conversation search, platform MCP readers, cached summaries, parked continuations, voice reconnects and transcript titles (#2767). Existing cached summaries are rebuilt once after upgrading.
## [1.56.2] - 2026-11-07
### Fixed
- Keep renamed tools’ chat views, drawings, drafts and run steps through streaming, reloads and shared links; prevent external tools from claiming built-in renderers by name (#2740).
- Cancel clipboard feedback timers when a copied card closes, including copies that finish after the card unmounts.
## [1.56.1] - 2026-11-07
### Fixed
- **Skills use skill-specific names.** Models open a skill with `read_skill`
from an “available skills” catalog; `read_skill_resource` still reads its
supporting files. Native deferred loading, approval policies and saved
conversation histories remain compatible, including existing `load_capability`
approval keys and histories.
## [1.56.0] - 2026-11-07
### Added
- Local routines ask once: the desktop app lets all your routines in an organization work in a folder (or your home folder, for the whole computer), and every later routine there is saved without another dialog. The permission survives app updates and signing in again; a routine follows your current desktop session. Approving another folder or stronger operations keeps earlier grants. On Windows, routine folders must use local drives rather than UNC or device paths.
- The public API lists, opens and renames your conversations (`GET`/`POST /api/v1/conversations`, `PATCH /api/v1/conversations/{id}`), checks one of your own MCP connections (`POST /api/v1/me/mcp-connections/{id}/test`), and the platform MCP server gains `list_conversations`, `create_conversation`, `test_my_connection` and `update_proactivity_settings`, so a routine's topic chat and the organization's watch cadence and briefing can be set up without the console.
### Fixed
- A replacement desktop that does not hold a routine’s grant leaves its incoming events waiting for the approved computer and warns the owner; it does not disable the routine or discard those events. Delegates retain a shared local-workspace requirement before computer access has been granted, so they can ask for access too.
- Routine permissions are verified against the current store fingerprint in the OS keychain, so editing the JSON or replaying a revoked store cannot extend consent. **Upgrade:** explicitly unlink and relink the computer, then approve existing local routines again; older grants have no trusted fingerprint. A missing keychain or interrupted permission write fails closed and requires the same reset.
- Routine folder admission refuses symbolic links in the root path, including a replaced grant root, instead of resolving them before checking access. Local folder commands retain the approved directory through Linux sandbox startup, preventing a concurrent folder rename or symlink replacement from changing what is mounted. Linux needs bubblewrap with `--bind-fd` support. On Linux, task environment variables are applied inside the sandbox and passed privately through a descriptor.
- An agent whose workspace is your computer no longer refuses a message, or asks where it may work before you send one, when no folder is chosen. It answers what needs no files and asks for your computer only when a request needs your files; the chat continues with them once you choose.
- An API key you issued, or an MCP client you authorized, with the explicitly selected `personal:consent` scope can now create and change your own routines that act as you and your watches, review a routine's sources, and publish an agent without withdrawing your routines' consent. This scope is excluded from all presets, including Full access, and existing credentials gain no consent automatically. It used to be refused as if it were somebody else; an agent's run credential outside your private chat and an administrator impersonating you are still refused.
- A routine its agent cannot run - for example one whose agent works on your computer and that names no folder - no longer leaves a run that the stale-run sweep later reports as a crash; it stops with a notification that says why.
- A watch check is bounded: at most 30 model requests, with long tool results trimmed and an overgrown history summarized. A first check of a whole Notion workspace had made about 40 requests and cost $2.
- Connecting an MCP server in the desktop app opens the provider's sign-in in your own browser instead of inside the app window, so saved passwords, passkeys and existing sign-ins work there. Finish signing in and return to the app; the server appears once it is authorised.
## [1.55.0] - 2026-11-07
### Changed
- The organization switcher now sits at the top of the sidebar, showing the active organization's name and avatar without opening the account menu. It remains available in the collapsed sidebar and phone menu, with organization management and creation in the same dropdown.
## [1.54.1] - 2026-11-07
### Fixed
- Chat questions are saved before their answer card appears. Switching chats or reopening the conversation restores the unanswered card and answering continues the same run, instead of leaving the agent waiting on a connection with no visible form. Chat answers retain the live question channel so delegates can ask follow-up questions during the continuation.
## [1.54.0] - 2026-11-07
### Added
- Tool search can defer eligible tools from enabled capabilities as well as bound
MCP servers. Choose either group or both, and keep whole capabilities, MCP
server namespaces or individual exposed tools visible from the first request.
Existing configurations keep their MCP-only deferral behavior.
## [1.53.0] - 2026-11-07
### Fixed
- Public embed messages now spend a per-connection allowance before attachment parsing, reject lists above three file IDs before inspecting them, and aggregate invalid IDs into one bounded log entry without their values. Malformed frames cannot spend the allowance shared with other anonymous visitors. This prevents malformed frames from amplifying the newly enabled application logs.
- API, worker, ingestion children and CLI now emit timestamped, redacted application logs to stderr, with `LOG_LEVEL=INFO` by default. SQL queries and HTTP transport chatter stay quiet; Logfire console spans are opt-in with `LOGFIRE_CONSOLE=true` in every environment. (#2771)
## [1.52.0] - 2026-11-06
### Fixed
- Opening chat on a phone no longer focuses the editor automatically. The keyboard stays closed, and the welcome screen reserves matching space for loading placeholders and agent details so the attachment action stays in place while being tapped.
- Creating a knowledge base or claiming a collection name now waits at most one second for a name held by an unfiled chunk write, then answers 409 with a request to retry. Previously an unbounded wait could occupy the database connection pool and delay or refuse unrelated requests. The timeout rolls back only its savepoint, leaving the caller's transaction usable. Teardown and ingestion locks remain transaction-scoped and keep their existing behavior. (#2781)
### Added
- A coding agent runs several named sessions at once. `run_coding_agent` takes a `session` name: the same name continues that session, a new one opens another, and `main` keeps the session conversations used before. On the person's computer a session may also choose its `harness` (Claude Code or Codex, on that computer's sign-in) and a `folder` inside the chat's folder, so two projects or both harnesses work side by side. Local sessions run concurrently; sandbox tasks in the same toolset queue to keep their workspace diffs separate. Chat corrections can target a named local session with `[session:name]`; unaddressed corrections stay with the parent when several sessions are active. The desktop app runs up to eight local sessions and lets one start in a folder inside a full-access grant; revoking a folder stops the sessions inside it too.
### Changed
- An agent whose workspace is **Computer** no longer fails a new desktop chat with "This agent uses your computer". The first message asks once where it may work - the whole computer or a folder - and the answer is remembered for that agent, so its later chats start there. **Work on** offers no Cloud for such an agent. Whole-computer consent given this way belongs to the agent in the desktop app rather than to one conversation; consent given in **Work on** for other agents still belongs to that chat. A local coding agent can now work under whole-computer consent, in the home folder or a folder inside it. Device operations under whole-computer consent carry the run's agent, and the agent listing gains `local_workspace`. The desktop app must be updated for agent consent; an older app keeps asking per conversation.
## [1.51.0] - 2026-11-06
### Fixed
- A local instance created by the desktop app can be set up with a provider key again. The app wrote a `SANDBOXD_TOKEN` for a sandbox service it never starts, so new agents kept container workspaces publish refused, and bootstrap stopped at the Architect's publish. The instance no longer gets a token, and its agents get the files-only workspace. A publish refusal now leaves the Architect waiting for a model instead of failing every console load. An instance created earlier keeps its token: delete the `SANDBOXD_TOKEN` line from its `.env` and restart it.
- Finished synchronous delegations no longer repeat below the answer. Their byline keeps the exchange, reasoning, actions, token usage and run link; nested specialists remain promotable. (#2782)
- Quick Ask and blobby refresh a previously signed-out session when shown or when the console signs in. Blobby waits for a fresh session check before its first signed-out greeting. (#2784)
### Changed
- Chat controls split into three tabs: **Model** holds only the model, **Tools & files** holds the coding agent, Work on, browser, computer use and skills, and **Preferences** is unchanged. The chat no longer lists both coding accounts under the model: where an agent codes as a private cloud task on the person's account, Tools & files offers that account to connect. Agents with subagents retain both account connections for delegated coding tasks. The agent listing gains `personal_coding_harness`.
- The default AgenticOS agent no longer has the Architect pinned as a delegate. It answered platform questions by asking the Architect, which took a minute and a second model's cost for what its own platform tools and guide already cover. Organizations pick the change up on the next console load; a starter whose delegates somebody changed keeps them.
## [1.50.2] - 2026-11-06
### Security
- A sync, a local-directory sync or `rag-ingest` now clears earlier failed attempts at a file only in the new row's own scope: the knowledge base it is filed under, or, for a row with no base, rows of the same organization. Until now it cleared every failed row at that path under the collection name, so one organization's sync deleted another organization's failed rows (their error and retry) when both used the same collection name and path. The same applied to two knowledge bases of one organization that share a name. (#2747)
- Creating a knowledge base or collection (`POST /kb`, `POST /rag/collections/{name}`) now refuses a name that no knowledge base holds while it holds content of another tenant, for example a collection written by `rag-ingest`. Until now a member with `collections:edit` could create a base on such a name and then delete it, which dropped the operator's vector table. An app admin can still adopt such a name. A name held only by bases the caller may write is not affected. (#2747)
- Deleting the last knowledge base on a name (`DELETE /kb/{id}`, `DELETE /rag/collections/{name}`) now keeps the vector table while it holds unfiled chunks the base does not take: an operator's `rag-ingest` or `rag-sync-gdrive`/`rag-sync-s3` into the held name, or another organization's. Only the chunks the base takes are purged, and the other rows under the name stay as they are. Until now the table went with those chunks, so a member with `collections:edit` could destroy content written after their base claimed the name. `rag-drop` still drops the whole table. A chunk write with no base now holds the name until it commits, so the table is asked only after such a write in flight has finished, and one that reaches the name while it is reserved is refused. The cleanup job now drops only a reserved name, so a rerun leaves what was written after its first drop. (#2747)
- **Sync source settings and run logs stay with their audience (#2745).** The
knowledge base wizard's list of existing integrations
(`GET /kb/{kb_id}/sync-sources/org-integrations`) and `GET /rag/sync/sources`
returned every source of the organization, with its configuration, vault
secret id and last error, to anyone who could read one base. The wizard's list
now needs `connections:manage`, like `/org/integrations`, and the wizard leaves
out the offer without it. `GET /rag/sync/sources` returns the whole list only
with `connections:manage`, and otherwise the sources that feed a base the
caller reads, so its `collection_name` filter answers 404 for a collection the
caller cannot read, where it answered 200. A member of one organization who read an app-scoped base could
read the run logs of another organization's source that fed it. A source's run
log and `GET /rag/sync/logs` now list only the caller organization's sources,
unless the caller is a platform admin. Runs with no source, such as those of a
deleted source, are still listed by their collection name. `PATCH`, `DELETE` and `POST .../trigger` on
`/rag/sync/sources/{id}` checked the organization and, on a move, the new base.
So a member could detach (`collection_name: null`), reconfigure, delete or run
the source of a base they cannot write. They now also need write access to the
base the source feeds. An unassigned source still needs only the organization.
That check and the change it allows now run under a lock on the source, on
these routes and on their `/kb/{kb_id}/sync-sources/{id}` counterparts, so a
move that commits between them can no longer leave a caller changing, or
queueing a run of, a source that feeds a base they cannot write. A run already
queued when a move lands still runs into the new base. The wizard also stops
offering integrations it already fetched when the member loses
`connections:manage`, and leaves clone mode if none remain to pick. A run that
finishes while its source is deleted keeps its outcome.
See [Configure sync sources](docs/howto/configure-sync-sources.md#api-reference).
## [1.50.1] - 2026-11-06
### Security
- The nightly proactive job now reads only a prompt that passed the input guardrail of the agent it was sent to. It read every message a person sent in the last week and passed them to the organization's proactivity model, which runs with no guardrails, so a prompt the input edge had stopped, or never reached, still reached a model once a night and could come back in a suggestion or a first message. Left out: a refused prompt, a prompt no run took (an archived agent, a refusal before the run opened, a chat prompt passed to a workflow) and a prompt whose run stopped before its first model request and that the run's own input guardrail blocks when the job asks it. A prompt whose run is still going waits, and a later look reads it once the run has ended. A prompt that lost its run to retention is read only if a model's answer follows it, so `POST /conversations/{id}/messages` no longer stores `model_name` on a turn a person writes. A refused prompt no longer counts as new activity that wakes the look. Prompts a guardrail redacted rather than refused are stored unredacted and still reach it; that is #2655. (#2746)
## [1.50.0] - 2026-11-06
### Fixed
- Fence personal coding result publication against account and membership revocation;
restrict telephone controls to the call owner and serialize SMS bot deactivation
with call admission.
- Purge project memories and their derived shares and deregister provider webhooks
before deleting a project. Revalidate credential generations during tracker setup.
- Keep channel conversations separate from private console history, and bound retained
inbound email bodies and delivery receipts before queue admission.
- Require fresh approval for gated skill loads, retain answered questions in their
original timeline order, and bind system-agent cache mutations to the initiating tenant.
- Preserve approval continuation segments and overlapping run activity in chat;
hide task creation on archived boards and refresh legacy Architect instructions
without reattaching optional skills.
### Fixed
- Preserve question-card answers and successful skill loads between conversation turns, without replaying full tool outputs. Join streamed thinking chunks exactly, including chunks split inside words.
- Return actual question cards from synchronous API and MCP draft tests; answer them through `answer_agent_questions`. Support renaming an agent draft through MCP, clarify table column IDs, private sharing and draft starter fields, and prevent resolved approval cards from reappearing after stream replay.
- Stream web-chat continuations after tool approvals and answers, including after navigation. Reuse the live turn trace, avoid duplicate HTTP answers, and clear completed sidebar activity.
- Reduce default-agent prompt overhead and duplicate skill manuals; retain focused procedures and load detailed design recipes on demand. Match the Routines loading placeholder to its row layout.
- Rearm planned human reminders when their task board is restored, and serialize private coding-result publication against edit sharing.
- Acknowledge saved partial replies after Stop, discard buffered model frames, and clear the stopped conversation’s sidebar activity immediately.
- Filter managed task reviewers by current board access, keep agent placeholders as skeletons during chat loading, and let project editors manage ownerless scheduled project conversations. Other members’ private conversation ownership remains unchanged.
- Reconcile HTTP continuation answers with their stored text and tool-call identities, preventing duplicate final replies before a reload. Show animated tool activity while calls run, then restore the operation's object icon.
- Always show Google sign-in and registration; disable the button with an explanation when the deployment has no Google credentials.
- Keep the mobile chat welcome visible when an empty composer receives focus; collapse it only after writing starts.
- Revoke unattended routine and telephone consent when a member leaves; stop personal coding tasks when their source conversation becomes editable by collaborators, and serialize descendant memory sharing with personal erasure.
- Include private task records, retained history, column schemas and routine action consents in bounded personal-data exports. Serialize shared memory corrections with sharing and durably end superseded routine telephone calls.
- Cancel important-case telephone calls when their notification is read or the case is settled, including calls already starting or active; serialize admission and queue provider cleanup. Reject abandoned Google consent after membership removal, block inaccessible reminders for review, and preserve native drafts on embedded and background streams.
- Bind Google account grants to their OAuth client’s organization and current credential generation; preserve that authority across terminal approval pauses and routine source reviews. Include safe account metadata in personal exports and audit organization account changes. Older unverifiable personal grants need reconnecting after migration 0293.
- Preserve renamed draft cards with server-owned presentation provenance (migration `0294_tool_presentation.py`); provider-controlled tool results cannot mark arbitrary arguments as public drafts.
- Cancel parked approvals when task execution ends, block reminders whose creator has left, require actionable reviewer access, fence agent deletion against task assignment, and recheck delegate instructions and account authority after pauses. Removing a member revokes their tenant-bound Google grants permanently.
- Refuse deleting an agent while a managed task still depends on its scheduled execution; reassign or settle the task first.
### Added
- Remember a tool approval for this conversation or this agent version and account, scoped to the consenting person. Recheck organization policy and current membership on use; revoke remembered choices from Chat controls. Apply `0295_tool_approval_consent.py` and update API and workers together.
- Official Google Workspace and Cloud remote MCP catalog entries, including Calendar, Gmail, Drive, Docs, Sheets, Slides, Chat, People and Universal Search; Google OAuth offline consent and visible connection prerequisites.
- Promote personal coding accounts directly in Chat controls, with shared profile
connections, inline setup and Claude Code/Codex branding.
- Connect personal Claude Code/Codex accounts in Profile with explicit organization consent, user-sealed credentials and serialized ChatGPT refresh. Private cloud tasks use disposable containers and return a redacted report, diff and ZIP without changing shared project files automatically. Apply `0290_personal_coding_accounts.py` and update API/workers together; schedules, channels, API keys and impersonation cannot use personal accounts. Existing organization-key and desktop-local modes remain available.
- Import PR #2728: show bounded per-task coding diffs, changed files and Copy patch in chat, with conversation-scoped access and cascading deletion. Apply `0289_coding_task_changes.py`; desktop-local tasks do not yet record a diff. Reverting a task is not offered.
- Show pulsing setup indicators on organization tabs and configuration cards, with permission-aware explanations for missing Voice, memory, Architect and iPhone-push setup or disabled nightly suggestions.
- Nine built-in platform and production skills, automatically delivered to existing organizations with edit/deletion protection; AgenticOS, Architect and new default agents bind them alongside presentation skills. Stronger completion, questions, delegation and document-quality guidance; Architect gains Apps and Charts.
- Platform MCP operations for standing Context, agent context bindings, skill editing and text resources.
- Choose a shared saved view as the table default, with explicit URL overrides; start task boards in Kanban and use rich-text notes plus linked Person/Agent references and an explicit next-step actor.
- Durable tasks share one Virtual Table record across scoped boards, working chats and Inbox. Provision personal, project, group and organization boards on first use; schedule model-free reminders or one-shot agent work with existing routine authority, retain review state, and settle the same commitment from Tables or Inbox.
- Manage scheduled tasks, event tasks and read-only monitoring in one Routines list. Choose reports on every run or quiet Inbox cases with full drafts in private working chats; deduplicate source revisions, reopen the same case on new replies, and settle it from chat through AgenticOS MCP. Monitoring no longer requires a nightly-suggestions model.
- Choose icons and short titles for an agent's first-message suggestions in the Builder, persist them in published specs and YAML, and display equal-height suggestion cards in chat.
- Equip shipped and new console agents with command monitors, background work, bounded conversation search, portable BM25 tool discovery and dynamic specialists. Pin Architect on AgenticOS, add optional access-checked delegation discovery, and include approved-desktop coding/computer capabilities on AgenticOS.
- Offer Discord private chats as opt-in notification destinations alongside the other supported chat channels.
- Important-case telephone consent for selected agents, explicit criteria and optional delay after an unacknowledged notification; shared case settlement cancels pending calls and event deduplication survives receipt expiry.
- Twilio telephone conversations and spoken reports, opt-in verified contacts, quiet hours, bounded rates/budgets, permitted transfers, call cards and private transcripts.
- Optional follow-up drafting in Await reply: explicitly selected model/cost ceiling, tool-free drafting after a verified deadline and a saved result for human review.
- Structured, scoped decision episodes with alternatives, expected/observed outcomes and append-only corrections; explicitly reviewed JSONL handoff to Improve datasets.
- Project tracking preset: explicitly review a published agent's sources, then create a private tracker, task table, saved views and a project-bound routine. Recheck project access for tools and queued notifications.
- Bind routine execution, parked runs and queued events to reviewed source and account ceilings. Add owner-only source review in the console. **Upgrade:** apply `0276_routine_sources.py`, update API/workers together and explicitly review existing routines; migration grants no legacy consent.
### Changed
- Open answer sources directly in a responsive side panel alongside chat, coordinate it with the Files panel, and use site favicons with a fallback instead of generic web marks.
- Keep batched chat approvals in one full-width scrolling list, with the scrollbar at the card edge and decision buttons outside the scrolling area.
- Give the page-help walkthrough action a distinct neutral fill and a compass icon.
- Preserve shared layouts across console navigation, wait for saved dashboard layouts and permissions before rendering their contents, and reserve asynchronous filter and Inbox metadata slots. Avoid an empty user-list flash and repair Inbox links to working conversations.
- Stabilize chat opening: load saved transcripts independently from the sidebar, reserve starter space until personalized prompts resolve, and place quiet suggestions beneath the composer. Remove workspace previews and keyboard hints from chat home, greet by local time and soften shared overlays and explicit-send scrolling with reduced-motion support.
- Keep quoted replies inside the user message, with a matching compact composer preview, keyboard cancellation and reduced-motion navigation.
- Collapse chat activity after agent messages by default, grouping adjacent thinking and tool steps while keeping actionable approvals beside the composer.
- Keep chat approvals as a simple inline card with readable nested task subjects, optional details and adjacent decisions. Give platform objects distinct icons, keep operation marks stable while tools run, and distinguish finished, waiting and active activity without animating every tool row.
- Keep chat outcome notices beside the composer instead of at the top of the transcript, and suppress approval notices whenever the chat already shows its approval decision panel.
- Complete the coding-task diff integration from PR #2728: bound rendering to 2,000 lines across a change set, retry transient fetch failures once, keep sandbox stderr out of snapshot failure logs, and preserve UUIDs in refusal details.
- Remove the standalone Tables capability and its UI and toolset. Table operations use AgenticOS MCP. Stored specs migrate to version 14: existing app table grants are retained as `table_bindings`, and project trackers connect MCP instead of adding Tables. Operators must explicitly connect platform MCP on old agents that do not already have it; existing connection restrictions and approvals are preserved.
- Recover every pending approval batch after worker continuations and refresh parked chat turns on run updates without replacing live drafts. Keep live activity grouping stable, avoid marking pending steps Done, and update elapsed labels once per second. Page long skill references, prioritize exact tool names over nested schemas, and avoid requesting duplicate Tables tools when AgenticOS MCP already provides record operations.
- Use muted, theme-aware table option colors with readable ink in explicit Light mode even on a dark OS, and place Kanban grouping alongside filters and sorting in the view toolbar.
- Route approval notifications to real decisions, hide duplicate chat notices when their run already has an approval panel, and refresh outcomes when approvals change.
- Group chat reasoning and routine actions into one collapsed activity section, keep tool details closed until selected, restore unanswered questions after leaving a chat, announce new conversations before live-room setup, and show waiting states separately from active work.
- **Breaking:** inbound email relays must attest to an aligned DMARC pass for the exact From address in `sender_authentication`. Upgrade relays to supply the trusted receiver verdict before updating the API; signed messages without it are ignored.
- Refresh shipped AgenticOS and Architect defaults on console open while preserving custom prompts, tool settings, models, budgets and unpublished edits. New console agents retain the same AgenticOS baseline; apply `0284_shipped_agent_defaults.py` before starting the updated API.
- Offer watch setup cards in chat, show confirmed claim writes and corrections, and group routine/watch execution and delivery settings under advanced options.
- Make personal memory browsable with separate memories and notes, whole-store search, type and scope filters, decision details, shared file previews and confirmed note deletion.
- **Breaking:** routines and watches now pause after three consecutive unsuccessful executions by default. Owners can choose 1–20 or disable this limit; waiting and delivery errors do not count. Acknowledgement does not reset health. Resume after correcting the issue to start a fresh window. Migration `0275_routine_health.py` requires API/workers to be updated together.
- **Breaking:** local routines require native grants bound to their routine, owner, organization, device, folder and operation limits. Create paused, confirm on the desktop and then activate. Offline activations wait durably without model calls; changed authority cancels old work and three failed pre-admission dispatches stop the routine. Update API, workers and desktop together and review legacy local routines.
- **Breaking:** private notification routes now support Slack, Telegram, Mattermost, Microsoft Teams and SMS alongside email/push. Explicit personal opt-in is required per organization; account relinking or bot credential/server replacement invalidates the route. Unconfirmed chat sends use one durable attempt; explicit Slack HTTP 429 refusals may retry after the requested delay with a five-claim bound. Slack notifications use plain-text blocks linked to the shared case. Drain workers and update API/workers together before using new channel selections.
- **Breaking:** resumed routines and delegates retain their admitted MCP accounts and original tool aliases. New defaults, credential replacements and renamed accounts cannot retarget existing approvals. Start a new run for old parked routines without account-admission state.
- **Breaking:** watch source consent now binds the MCP authorization generation. Review existing watches after migration `0270_mcp_authorization_generation.py`; OAuth re-consent and explicit token/endpoint replacements require another review, while ordinary token refresh preserves consent. Drain old workers and upgrade API/workers together.
- **Breaking:** unattended routines now require approval for actions, local file
mutations and delegation. Owners can authorize individual capability actions
for one published version and routine configuration in the console; required
agent approvals remain required. Existing routines get no exceptions. Drain
old workers and upgrade API and workers together before resuming duties.
### Added
- **Await a reply** workflow template: explicitly select the connected mailbox, publish a private draft and enter thread/sender/timestamps in the Run form. A verified reply completes one branch; the deadline branch writes one review reminder through the existing notification center. No follow-up email is sent automatically.
- Workflow **Notify members** can select push, Slack, Telegram, Mattermost, Microsoft Teams, SMS and iMessage alongside in-app/email delivery. The shared notification queue still requires each recipient’s own preferences, permissions and explicit private-channel route; choosing a channel never opts somebody in.
- Durable **Await email reply** workflow step for explicitly selected Gmail/Outlook mailboxes, including shared Outlook mailboxes: exact authenticated thread/sender matching, separate reply/deadline branches, restart-safe timers and run-page pause/correction controls. Metadata-only scans fail explicitly on unreadable mailboxes; no follow-up is sent by this step.
- iMessage through an explicitly configured company BlueBubbles Mac: authenticated webhook, text/files, separate group context, numbered approvals, optional tapbacks and explicit private notification routes. Configure the bridge in Channels and register its webhook after saving. API/workers must be updated together for migration `0274_imessage_notifications.py`.
- Routine owners can select individual MCP action exceptions on a concrete account together with capability actions. Version, intent, endpoint and authorization generation remain bound; explicit agent/binding approvals cannot be waived. The console shows account identity, unavailable tool inventories and refreshed reviews after rejected saves.
- Unattended routines honor granted internal Virtual Table writes without a routine exception; explicit agent approval policies still apply.
- Routine and watch end-time cleanup now runs independently of activation cadence, including paused work, closes obsolete blockers and cancels pending notifications after restart.
- Resumed routine answers use durable, retryable console delivery with one
receipt per run. Restarts and concurrent retries cannot duplicate messages
or repeat model calls. Archived chats and lost current access block delivery.
- Routine and watch failures share a recoverable owner incident. Continuing
errors stay quiet, retries cannot undo decisions, and terminal callbacks cover
resumed runs. Current source readings and delivery recover their own blockers;
expiry or removal closes them. Agent-budget incidents reuse the owner’s alert; organization and department
budget alerts remain independent financial notices.
- Routine and watch budget pauses notify their owner once per monthly limit
and open a shared case. Available budget or removal resolves the case and
cancels pending sends; existing budget preferences and routine channels apply.
- Routine rows show when the last answer could not reach its console conversation.
Delivery rechecks current access and isolates message-write failures from the
completed run; completion notices link to a chat only after delivery.
- Watch findings share one case across the Inbox, source chat and notifications.
Resolving or dismissing stops pending deliveries; acknowledging keeps the
finding actionable without repeating it in the daily briefing. Explicit restore
reopens the same case without resending old messages.
- Routines can narrow inherited notification channels, including app-only
delivery, and pending sends recheck those limits. Watches can send requested
no-change reports with durable activation deduplication.
- SMS bots send explicit files and charts through Twilio MMS using expiring
media handoffs, with file-type, count and size limits checked before sending.
- Watches run through a selected published agent, follow or pin its version,
retain approved account and knowledge/context boundaries, and return new
findings to the source chat. The same controls work in chat and Routines.
- Incoming Twilio MMS files use the existing channel attachment pipeline, including media-only messages. Downloads are restricted to the bot’s own account and incoming message, reject redirects and enforce upload size and transfer-time limits. A number with media is retained as a message rather than settling a numbered prompt.
- **Set and remove a routine's end in its form.** The end-time field names the device time zone it uses and sends an offset-aware timestamp. Invalid or past edits are refused; changing another field preserves the exact existing end rather than rounding it to the input's minute precision.
- **Automatic memory capture keeps each turn's audience.** Completed linked channel turns and personally authorized scheduled/workflow work can be read by memory maintenance alongside private web chat. A group turn writes only to its source room, never a personal profile. Jobs retain the runner's admitted audience and recheck terminal state, membership and erasure; embeds, API keys, impersonation and outsider events remain excluded.
- **Pin a routine to one published version.** The routine form and MCP tools can select an immutable agent version or follow the default environment again. Pins are checked against the same agent and organization, cannot coexist with a named environment, and prevent deletion of the selected version. They keep using the shared runner with current access, budgets and approvals. Migration `0259_trigger_version_pin`.
- **Manage a routine from the chat that requested it.** Private chat runs retain their source conversation on internal platform credentials, so a newly created routine answers there by default. The chat shows a card with its current authorized state, next activation, edit, pause and removal controls. The platform MCP tools expose end times, delivery destinations and monthly budgets, including explicit removal of limits. Ordinary API keys cannot acquire personal standing authority through this provenance. Migration `0257_run_conversation_provenance`.
- **SMS through Twilio is a channel platform.** Add an SMS bot under Channels with `ACCOUNT_SID:AUTH_TOKEN:+NUMBER` and paste its webhook URL into the number. A text reaches the agent through the same router, linked identity, access policy and budgets as any direct message; every request is verified with Twilio's signature, a number is only a claim until it is linked to an account, and a reply is plain text cut at about 1,500 characters. An approval or question is sent as numbered lines and answered by texting the number. A phone number's link to an account lapses after `SMS_LINK_MAX_AGE_DAYS` (90 by default) because a number can be reassigned or taken over, and the bot's page shows the webhook URL to paste into the number. Migration `0252` lets an agent be exposed on SMS.(#2082).
- **A routine answers where its person reads.** `answer_to` on a trigger delivers each completed fire's answer to the creator's own conversation with the agent (`primary`, the new default) or to one of their chats (`conversation`), beside the run log that always records it. `ends_at` stops a routine by itself: the first fire due after it pauses the trigger instead. The trigger form has an "Also answer in" choice. Migration `0255_trigger_delivery`.
- **A routine can carry its own monthly budget.** `monthly_budget_usd` limits what the runs a routine started may cost in a calendar month. Once spent its fires are skipped before a run opens, the routine shows "Paused - budget", and it starts again on the first with nothing to resume. It only narrows the agent's and the organization's limits. Migration `0256_trigger_budget`.
- **One outcome, settled once.** An approval waiting, a failed run and a watch's finding open an outcome: one item per person and cause, however many places tell them. The card above the chat it came from, the bell's row, the push and the e-mail are deliveries of it. Acknowledge, resolve or mute it from the chat or the bell (`POST /outcomes/{id}/settle`) and every place follows: the push and mail still waiting to go out are cancelled, a delivery a worker already holds is re-checked before it is sent, and deciding a run's last pending approval resolves the outcome that asked. A muted cause stays muted. `GET /outcomes` lists the caller's own. Migration `0254_outcomes`.
- **E-mail is a channel platform.** Add an e-mail bot under Channels with the address it answers from and a signing secret, then point your mail relay (a Cloudflare Email Worker, a Postmark or Mailgun inbound route) at the webhook shown for it. The relay POSTs one signed JSON document per message; the agent answers by mail as a reply in the same thread, with files attached, through the deployment's e-mail provider. Approvals and questions are answered by replying with the number. Quoted history is cut before the agent reads a reply, a retried delivery runs once, and a deployment on the `log` provider refuses to answer rather than pretend. `EmailMessage` gains `headers` and `attachments`. Migration `0253_exposure_surface_email` allows the new surface.
- **One stable private conversation per person and agent.** `POST /agents/{agent_id}/primary-conversation` returns the caller's own conversation with that agent, creating it the first time; the same person, organization and agent always get the same one, a colleague gets theirs, and clearing it opens a fresh one next time. Project, group and task conversations are never this one. The agent page's **Continue my conversation** opens it in the chat; **Open in chat** still starts a fresh thread. A linked person's first direct message to a bot with an agent - on any platform, SMS included - lands in it too, so what was said on the web is there when they text, and `/new` still starts over; rooms, unlinked senders and routines are unchanged (#2575).
- **System agents give the platform's own background work an owner.** Organizations → Members → System agents lists each role with its model, this month's spend and its recent executions. Memory maintenance has a profile of its own (a switch, a model chosen rather than defaulted, a monthly budget); the daily briefing is shown read-only because it is the Proactivity setting, so there is still one model and one limit for it. Background runs now carry the role that did them, and Activity names it, instead of reading as the starter agent's, and a role's spend is not counted against a person's proactivity limit. Memory maintenance reads a finished web chat once and records the durable facts, preferences and decisions in it, in the conversation's own scope only; it never runs where memory does not, and never without a model somebody chose (#2575, #2090).
- **Memory records what an agent was told, with where it came from.** An agent can `remember` a fact, preference or decision, `recall` what is relevant without reading everything, `correct_memory` on a person's word and `share_memory` into a project or the organization when an authorized person asks and approves it - that tool always waits for a person, whatever the agent's approval settings say. A claim lives in a person profile (shared by every agent acting for them), a person-agent relationship, a group chat, a project or the organization; automatic writes stay in the conversation's own scope and only an explicit share widens one. A correction supersedes and keeps what it corrects, a person's word outranks an inference, and a scheduled pass folds agreement and flags disagreement without a model call, only where a scope changed. Settings → Memory shows what is on record about you with its source and lets you correct or retract it. Erasing a person removes their claims and the copies shared out of them (#2090).
### Changed
- Existing watches require an explicit published agent and source approval
after migration `0262_watch_agent_sources.py`; their IDs and findings remain.
- **Planning cache and history migration:** Harness 0.64 returns framed plans with tool metadata and records a missing or changed visible plan as user-channel run history. It no longer inserts a planning cache breakpoint. Existing `planning.cache_ttl` values still load but are ignored: move custom retention to `cache` in the agent or model profile's model settings, for example `cache: "1h"`. Platform prompt caching remains enabled by default.
### Fixed
- Refine neutral surface levels and control contrast across Standard, Glass, Graphite, Midnight and Paper in light and dark modes. Keep full system-dark look palettes aligned with the selected theme to prevent first-paint colour shifts.
- Distinguish New chat and Search from sidebar navigation with primary and subtle search surfaces shared by desktop and mobile.
- Position global search lower in the viewport and bound its result list to keep the palette comfortable on smaller screens.
- Refine the Memory settings tab with a unified search/filter toolbar, lighter memory and note rows, and a responsive detail panel with clearer metadata and actions.
- Google MCP sign-in now opens required OAuth client setup before connecting, and client registration errors explain how to recover.
- Constrain dialog grid columns to their viewport width and keep the project picker searchable on small screens, with wrapped descriptions and an independently scrolling list.
- Let the default agents finish one-off requests without blocking the completed answer on an optional automation question. Ask setup questions only after the person requests or accepts recurring work.
- Keep sent messages and user portraits below the floating mobile chat controls, using the same top clearance when reserving space for the reply.
- Keep progress messages and tool groups chronological while agents work; collapse the complete run history only after the final answer, including approval continuations.
- Show the three most recently active projects in navigation and mark projects with unread chat answers for the current reader.
- Give the conversation sidebar an intermediate surface shade between navigation and chat in every theme.
- Resolve resumed tool results in their original chat segment and share the persisted run clock between the transcript and conversation sidebar.
- Run read-only AgenticOS MCP tools automatically under `writes`, including project and conversation reads; keep approvals for state changes and the explicit `all` policy.
- Combine page explanations and onboarding in one information menu beside the title, on mobile and desktop.
- Reduce the shared page bottom clearance from 64px to 16px on desktop, keeping mobile safe-area spacing.
- List OpenAI, OpenAI subscription, Anthropic and OpenRouter first in provider pickers,
preserving the order of all remaining providers.
- Refresh background chat answers in place; sidebar run updates no longer clear
and reload the open transcript between queued messages.
- Link Inbox task titles to their tables instead of displaying a separate Open table button.
- Keep queued chat turns from moving the reader to each new question, and keep
sidebar clocks and completed statuses consistent with the local conversation.
- Persist accepted SMS/iMessage deliveries before acknowledging their webhooks; enforce table-edit authority on project tasks, purge managed boards with deleted scopes, and recover the task selector after access loss.
- Refuse personal cloud coding accounts on shared source workspaces before credential loading, including project snapshots and conversations shared for editing.
- Persist accepted inbound emails and their attachments in transactional background jobs before acknowledging the relay, and require API-key scope plus personal consent when deleting watches.
- Release inbound email attachment capacity when files are consumed, expire or processing fails; store delivery batches atomically and bound file counts.
- Preserve reminders after reviewer access loss, keep project task chats in their project, and deliver Inbox findings when optional task boards hit quotas. Require edit authority on group boards, revoke personal coding grants on membership removal, and include coding patches in bounded personal-data exports.
- Give agent test comparisons a full workspace, preserve chats and unsent text when returning to the Builder, separate version selection from test actions, and switch between preserved comparison chats on phones.
- Fit the agent configuration map into its canvas, keep large groups compact with complete details on demand, and restore the workflow minimap’s graph coordinates.
- Limit expanded chat activity to a keyboard-accessible scrolling region instead of stretching long tool histories across the transcript.
- Keep live chat activity in one truncated status row instead of a changing tool or reasoning preview beneath it; detailed steps remain available in the disclosure.
- Flatten Agents, Tables, Workflows, Apps and Routines catalogs, soften shared buttons, fields, select menus and dialogs, and use an opaque chat composer without a focus beam. Keep received chat text readable while its Markdown renderer loads.
- Quiet the console navigation with borderless sidebar sections, understated search and filter controls, and soft selected-row fills while retaining keyboard focus indicators.
- Keep completed and nested agent exchanges visible, show the latest live step, combine activity-only chat segments and use the actual run start time. Render confirmed MCP writes as linked resource cards, anchor newly sent messages near the top, and restore scrolling in record Person/Agent pickers.
- Preserve question support after HTTP approval continuations and allow project task creation from a private source chat without linking its transcript; guide agents toward managed task tools and stable console links.
- Focus the chat composer after every New chat action, including when the editor is reused or the preceding draft is already empty.
- Allow chat approval waivers by default in new organizations while preserving existing organization choices and per-conversation consent.
- Remove scratch planning tools from AgenticOS, Architect and new-agent defaults; keep progress guidance in messages and durable commitments in managed Tasks.
- Restore approvals and questions for delegated tools from the parent run pause even when the parent timeline only contains a task call; show paused delegates as working during an approved HTTP continuation and reconcile finished published delegates independently when the parent pauses again.
- Keep approved chat turns visibly working while their HTTP continuation runs, preserve their live state during transcript refreshes and queue follow-up messages until the continuation returns.
- Mount the console task API proxy so project Tasks buttons and task lists reach the backend instead of returning a frontend 404.
- Prevent already-approved chat requests from reappearing during HTTP continuations, and submit each in-flight approval batch only once.
- Prevent duplicate chat answers and setup cards when stored history arrives before the live message receives its saved ID. Collapse answered questions by default and give approval details full-width nested sections and readable descriptions.
- Mark installed shipped gallery skills, including starter-agent skills such as `agent-budgets`, as built-in on existing installations without changing their content.
- Persist Kanban grouping changes automatically and keep the chosen default table format consistent when switching between saved views.
- Focus the writable chat composer after navigation even when its opener retains focus during connection; increase shared secondary-button and filter contrast across the console.
- Show saved browser sign-ins in a compact settings panel with service logos and site favicons instead of a stretched placeholder card.
- Unify personal settings panels with visible descriptions and compact forms while retaining the horizontal tabs. Move active sessions into Account and place password submission below its fields.
- Rebalance organization tabs: combine profile and voice settings in Workspace, and move background services beside the Architect under AI & services. Preserve drafts, permission gates and existing Voice links.
- Organize deployment settings into focused sections with persistent drafts, a visible save/discard toolbar, and responsive form layouts.
- Show the Inbox and background-work overview in every agent’s empty chat, while retaining agent-specific greetings and opening messages.
- Apply the same visible hover and keyboard selection to model, member, sharing and workflow command pickers; retain readable destructive-action colors in agent menus.
- Keep highlighted dropdown, context-menu and select rows visible against dark popover surfaces, including action descriptions and keyboard focus. The chat composer menu now clearly indicates the full action under the pointer.
- Reorganize organization Proactivity into independent feature cards, shared budget and delivery settings, explicit draft-save controls and collapsible background-service configuration. Clarify the minimum monitoring interval and retain visible usage and run history.
- Allow the schedule time-zone list to scroll inside a dialog, with its own nested scroll lock and a list height constrained to the available space.
- Give single-select and multi-select toolbar filters the same surface, dimensions and focus treatment. Compact selects show consistent icons, with specific marks for sorting, accounts and approval controls.
- Wrap Skills and Context cards in the shared full-height resource-list panel, keeping search, filters, loading and empty states inside the same frame as other console pages.
- Restore contrast between dialog surfaces, gallery and template cards, audience choices and file editors. Skill and context editors now separate the file tree, toolbar and document from the surrounding form. Skill descriptions use single-line inputs in create and edit forms.
- Unify scheduled, event and monitoring routine dialogs with one form frame, shared navigation and message editor. Creating a watch now uses three steps, preserves the draft when going back and groups advanced settings in one panel. Agent pickers display their avatars.
- Keep chart axes, legends and tooltip text readable in both themes across dashboard charts, sparklines and charts made by agents.
- Simplify the Builder's default sections, distinguish voice modes, align catalog search and filters, and refine table, list and kanban surfaces.
- Soften text-field and select edges and keyboard focus, and align search boxes and toolbar filters at the same height.
- Give console modules a shared set of product icons, consistent optical weight and quieter icon surfaces across navigation, chat and resource cards.
- Persist telephone cleanup before provider requests, immediately finish cancellations accepted during dialing, and retain SMS credentials until all calls finish.
- Invalidate unattended action exceptions after bound instruction edits, preserve unfinished telephone calls during account/organization deletion, export all personal outcomes with full size accounting, and reject malformed email reply references.
- Run memory maintenance using its explicitly configured role/model and originating agent, without depending on a published AgenticOS starter. Recheck memory sharing after the person-erasure lock so a stale read cannot republish an erased claim, and report mutation conflicts to the agent.
- Keep persistent routine/watch creation and updates behind the platform MCP binding's configured write approval.
- Serialize watches and nightly work sharing a member budget; drain proactive jobs and apply `0285_member_proactivity.py` before updating API/workers together. Prevent deleting SMS bots with unfinished telephone calls, rotate private bot sessions after agent rebinding, reject overlapping future memory corrections, and expose removable unavailable phone agents/transfer targets.
- Deliver routines created from a chat turn or setup proposal back to that originating conversation by default, with an explicit choice to use the primary chat or run log. Expired approval runs also resolve their shared case and cancel pending notifications.
- Show failed chat attention reads with retry and report rejected actions, retain retriable email deliveries when inbound state cannot be saved, accept numeric replies above mail signatures, serialize concurrent memory writes/corrections, disable maintenance after model removal, and refresh reopened cases to their current conversation.
- Keep concurrent email replies and approval prompts in their originating mail thread, give inbound files unique handles, bound aggregate attachment admission before caching, and remove consumed file blobs.
- Reject timezone-less memory corrections, allow disabling a watch failure limit, extract facts from the newest conversation turns, rotate parked device work fairly, and announce committed conversation updates across chat, workflows, watches and phone calls.
- Reject malformed or nonpositive routine budgets instead of silently removing their spending limit.
- Deduplicate signed webhook retries before charging routine run allowances, and return throttled delivery claims so provider retries can be admitted later.
- Show an explicit access/organization error and retry action when the agent Builder cannot load, instead of leaving its loading skeleton indefinitely.
- Document native-memory and routine-continuity upgrade/rollback steps. Correct the mem0 retirement guidance: removing agent bindings does not delete encrypted vault credentials or import/erase memories at the old provider.
- Creating or changing a private-account watch requires the person's own signed-in session or trusted private-chat credential. Ordinary API keys, publisher/background contexts and impersonation cannot establish or expand standing account access.
- Watches show unavailable sources, lost access and incomplete model checks separately from successful no-change readings. Failed attempts no longer advance the successful-reading timestamp. Workers recheck that the connection still belongs to the watch owner before resolving credentials. Migration `0261_watch_attempt_status.py`.
- **Private-chat authority is not transferable to background work.** Routine/workflow runs, public or group audiences, API keys and impersonation cannot mint the private source hint that permits a routine to act as a person. Approval continuations retain the original audience, so resuming a group turn never turns it into private standing consent.
- **Routine authorization is checked before every tool.** Root runs, delegates and approval continuations refuse subsequent tools after pause, deletion, expiry, personal-consent withdrawal, role changes or revoked run grants. The actor remains the original creator. Immutable run provenance survives deletion so a parked routine cannot lose its guard when its reporting FK clears; unverifiable old parked schedules are refused. Migration `0260_routine_run_origin`.
- **Platform model calls no longer claim to have executed the starter agent's version.** Their role remains recorded and the run manifest contains the actual platform instructions; the unrelated agent version is left empty.
- **An erasure wins over extraction waiting to write.** Memory maintenance obtains the personal-data lock before its final erasure check, so a concurrent forget request cannot be followed by a recreated claim.
- **Existing private channel history is adopted once.** Migration `0258_primary_channel_history` seeds missing primary conversations only when provider identifiers prove a direct chat and recorded runs prove the selected agent. Existing choices win; groups, project threads and uncertain history stay separate. Opening a conversation after clearing it still starts fresh. New channel sessions now retain their actual chat type.
- The current memory inventory excludes expired claims and future-dated replacements until they take effect; history retains both.
- SMS and e-mail prompts reserve reply numbers atomically before delivery and retain unused numbers after settlement, preventing concurrent sends and delayed replies from deciding another approval.
- Memory corrections require organization-wide edit authority for organization claims; expired claims cannot be corrected or shared. Same-scope sharing is refused, and person-memory erasure waits for concurrent claim writes.
- Declare the Harness tool argument repair extra so dependency upgrades retain `json-repair` and agent startup does not fail when importing `RepairToolArguments`. Update Harness and its matching Pydantic AI and graph packages to the compatible releases, preserve plan metadata and step IDs in structured tool returns, and keep goal reminders from repeating user text. Dependency freshness runs the whole suite with the same bounded parallel runner as CI so validation finishes within its job limit.
### Removed
- **mem0 is gone; native memory is the only store.** The `memory_mem0` capability, its secret kind, `MEM0_ALLOWED_HOSTS` and `mem0ai` are removed (#2090). **Upgrade:** `0248_drop_memory_mem0.py` stops while any legacy binding remains. Inventory endpoints and vault mappings, verify external erasure, then explicitly remove bindings from drafts and published versions before retrying; follow the [upgrade checklist](docs/deploy.md#native-memory-upgrade). No remote data is imported or erased by the migration. Recover mappings from the pre-upgrade backup if an earlier development build already stripped them. Native erasure reports `claims_deleted` and reaches native stores only. Agents now use the Memory capability.
### Fixed
- Show the same Architect avatar in the assistant widget and agent list after its stored picture is cleared, including its selected colour.
### Fixed
- Restore visible, horizontally scrollable settings tabs on desktop and mobile instead of the section dropdown.
## [1.49.0] - 2026-11-05
### Added
- **A virtual terminal over the services an author mounts (#2191).** The new
`mirage` capability gives an agent the seven sandbox tools, prefixed
`mirage_`, over folders that are a Google Drive, a GitHub repository, Notion,
a database, an SSH server or a mailbox, through
[Mirage](https://github.com/strukto-ai/mirage) and with no container. Each
folder is read only or writable, and a writable one can ask a person to
approve each write, including a write inside a shell command. A folder signs
in with vault keys, an Entra app, or a Google account. A Google account is
the organization's or each person's own, connected on the vault page. Typed
hosts must be on the new `MIRAGE_ALLOWED_HOSTS`. The terminal is the optional
`mirage` extra (`EXTRAS="--extra mirage"`). See
[Virtual terminal](docs/reference/capabilities.md#mirage). Box service accounts use Client Credentials;
LanceDB Cloud/Enterprise mounts require a vault key and an allowlisted HTTPS
endpoint. Local LanceDB storage and rotating Box grants are refused.
## [1.48.1] - 2026-11-05
### Fixed
- Authenticate the GitHub metadata lookup used to publish the Homebrew cask, so a refusal of anonymous API access does not stop tap publication. SSH host-key checking and deploy-key cleanup remain enforced.
### Security
- **Skills** → **Changes** (`GET /skill-changes` and `GET /skill-changes/{id}`) now lists and opens an agent's proposed change only for a person who may edit the skill it targets, including through a grant. A proposal for a new skill is still shown to anyone holding `skills:edit`. Until now anyone with `skills:edit` at any scope could list and read the full proposed body for every skill in the organization, including private skills of other people, and could discard those proposals. A proposal for a skill the caller cannot edit now answers 404, the same as an id that does not exist. (#2422)
## [1.48.0] - 2026-11-05
### Added
- A new Drafts capability: when the web chat is asked for text to send or paste elsewhere, such as an e-mail, a reply or a post, the agent shows it as a card with one segment per part, a plain-text copy icon on each, versions as tabs and a small type hint. Reopening a conversation or opening it by shared link shows the same card. Details the agent leaves for the person to fill in, written in square brackets such as `[Your Name]`, show in red so a draft is not sent unfilled. A markdown part has a Preview button that shows it rendered, with images not loaded; copy always gives the source. New agents, every template and the agents the Architect creates have it on; existing agents are unchanged until their author switches it on and publishes. (#2737)
- A `.zip` or `.tar.gz` (`.tgz`) can be attached to a chat. For an agent with a workspace it is unpacked into `uploads/<id>-<name>/` with its folders kept, so a repository goes in as a tree the coding agent can run its tests in; an agent without a workspace says it cannot open it. Each archive is read whole at upload and refused with a 400 before it is stored if a member leads outside it (`../`, an absolute path), is a link or a device file, is encrypted, or the archive passes `WORKSPACE_ARCHIVE_MAX_ENTRIES` (5000), `WORKSPACE_ARCHIVE_MAX_BYTES` (200 MiB unpacked) or `WORKSPACE_ARCHIVE_MAX_RATIO` (100x its compressed size), or one file in it passes `WORKSPACE_ARCHIVE_MAX_MEMBER_BYTES` (50 MiB). Archives sent through Slack, Telegram, Mattermost or Teams take the same path, and a refused one is named in the bot's reply. A workflow started by an email still skips archive attachments. (#2479)
- **Download as .zip** in a chat's **Files** panel, for one folder or the whole workspace, from the new `GET /api/v1/conversations/{id}/workspace/archive?path=`. It is authorised as `/workspace/raw` is, streamed one file at a time, keeps folders as entries so an empty one comes back out (downloaded on its own, an empty folder is a zip of that folder), leaves out the tooling folders the panel hides (`.git`, `node_modules`, `.venv`, ...), and refuses a folder past the same entry and byte limits with a 413 before anything is sent. A file the host will not serve once the download has started, such as one over its 8 MiB read limit, is left out and named in a `NOT-INCLUDED.txt` in the zip. (#2479)
- Workflow trigger input fields support **List of text**: validated JSON arrays of strings through the API, one item per line in run and public forms, and typed array bindings for downstream steps.
### Fixed
- With code mode on, charts and drawings were run from scripts and never appeared; they now stay ordinary calls.
- Web chat now warns when an assistant reply cannot be saved, including partial replies from interrupted runs, while keeping the streamed text visible. (#2732)
- Keep PDF chat uploads working when extracted text contains NUL characters.
- Book Stav's billed request cost from response bodies or headers, including
streamed Chat Completions and Responses, so models absent from the price
snapshot count towards budget caps. USD is used directly; **operators using
NOK billing must set `STAV_NOK_PER_USD`** (NOK per dollar) in the backend
environment. No rate is guessed or fetched; without conversion and without a
catalog price, costs remain visibly partial. (#2729)
### Security
- The sharing routes (`/{type}/{id}/sharing`) now answer a resource the caller cannot view with the same 404, message and `details` as an id that does not exist, for reading the share list and for changing grants or visibility alike. Until now a change on a hidden resource answered 403 and reading answered a different 404 than for a missing id, so a member could tell that a private resource existed. A caller who can view the resource but not edit it still gets 403, and an API key issued for edit without view can still change the sharing of a resource it may edit. (#2619)
## [1.47.3] - 2026-11-04
### Fixed
- Show the same Architect avatar in the assistant widget and agent list after its stored picture is cleared, including its selected colour.
## [1.47.2] - 2026-11-04
### Security
- An uploaded document's parse copy under `MEDIA_DIR/_rag_tmp` is now removed: by its ingest job when it ends (indexed, refused, its document gone, or failed on its last attempt - kept while a retry is still to come), after the commit that deletes the document, and by a new hourly `sweep-rag-scratch` job once its document is gone or no longer processing. Until now every copy stayed on the media volume for good, so the content of a deleted document, knowledge base or account was still on disk. **Operators:** nothing to run - the first sweep after the upgrade removes the copies earlier releases left, except those of documents still processing and any written in the last hour. A job queued for a document that is gone now ends at once instead of failing into a retry, and **Retry** on a dead document ingest in Background jobs is refused: retry the document from its knowledge base instead, which parses its stored file again. (#2681)
## [1.47.1] - 2026-11-04
### Fixed
- Deleting an account no longer fails with 500 when the person writes in their personal organization at the same moment, for example creates a knowledge base, or when a failed ingest of their document is being recorded. While the account's rows stay busy the deletion keeps trying for about 10 seconds, then returns 409 and deletes nothing. (#2682)
## [1.47.0] - 2026-11-04
### Added
- Add Turkish console translations, account language selection and Turkish voice previews.
- Search the web through Keenable without an account, or select an optional vault key for account-backed requests. The Builder and vault show the official logo; query-relevant snippets are normalized into the existing cited search results.
### Fixed
- MCP connections with **Include instructions** enabled no longer abort agent
turns while Pydantic AI collects their instructions. Toolset IDs use the
connection’s safe tool prefix. (#2713)
- Save assistant message parts containing local or conversation file origins without UUID serialization errors in JSONB, preserving their order and omitting unset fields. (#2709)
## [1.46.0] - 2026-11-04
### Added
- Select Otari as an LLM provider with a vault API key, hosted or self-hosted endpoint, authenticated model discovery and model-family profiles from `pydantic-ai-otari`.
## [1.45.1] - 2026-11-04
### Fixed
- The MCP servers Connected filter includes accessible organization and personal
accounts across catalog pages, including custom servers, with one card per
service and consistent filtering, result counts and pagination.
- Saved MCP server links reopen accounts whose registry checks failed. URL grouping
preserves case-sensitive paths and query values, and reauthorization uses each
account's saved endpoint.
## [1.45.0] - 2026-11-04
### Added
- Map a role in a Discord bot's server to a group of the organization, from the bot's row on **Channels** (#2569). A linked member who holds the role joins the group before each message to the bot and by a `sync-discord-roles` job every 15 minutes, and leaves it when the role is taken away. A mapping can also name an organization role, which admits linked holders who are not members yet. The sync changes only memberships it made, marked **Discord**: group memberships added by hand, directory memberships and owners are left alone, and Discord users who have not linked an account get nothing. Migration `0256_discord_role_mappings` adds the `discord_role_mappings` table and the `discord` membership source.
### Fixed
- Directory and Discord grants hand over the same organization membership instead of revoking API keys, connected-app consent and unrelated groups while the other source still grants access. The directory takes priority at sign-in; an unreadable Discord grant preserves the current membership. (#2674)
## [1.44.0] - 2026-11-04
### Added
- A decision or an answer made in the console, the web chat or over a session API now continues a run asked in a chat, as the person who made it, and posts the answer in that chat. A key's decision is recorded and does not continue the run. (#2656)
- `continues_in_chat` on approvals, on a run's single read and on the result of a resume or an answer. It is true when the server continues the run in its chat. (#2656)
- A console **Stop**, an expiry and a decided run that nothing continued each tell the chat once, in one fixed message. (#2656)
### Changed
- **A session API client that decides a chat run no longer resumes it.** Read `continues_in_chat` and skip `POST /runs/{id}/resume` when it is true; a late resume answers 400 with the run's status. (#2656)
- Chat runs whose approvals were all decided but never continued are now ended about an hour after the last decision. (#2656)
- On the first sweep after upgrading, such runs decided more than 7 days ago are ended without a chat message. (#2656)
- Schema: `agent_runs` gains a nullable `chat_notice_sent_at`, which records that a chat was told its run could not continue. No backfill. (#2656)
### Fixed
- Chat buttons answered elsewhere no longer act on a stale question. (#2656)
- A Discord run parked before its server was removed from the bot's approved servers is no longer continued by a console decision; the server is read from Discord again and one that cannot be confirmed is refused. (#2656)
- A chat button pressed at the moment the request is decided elsewhere is now closed instead of staying open. (#2656)
- The question sweep no longer overwrites an answer pressed at the last moment. (#2656)
- The approvals queue, the dashboard widget, the CSV export, the approval email and the in-app approval notification name the chat account instead of the publisher for an unlinked asker, and filtering the queue by the publisher no longer lists those calls. Who receives the email is unchanged. (#2656)
## [1.43.0] - 2026-11-04
### Added
- Browse a live fullscreen graph of Markdown notes in project, sandbox and Desktop folder
file explorers. Wiki links, inline Markdown links and frontmatter relationships
supply the graph and backlinks, refreshed without an agent-generated App. Coloured
points, thin links and optional arrows fill the canvas, with floating panels,
folder/tag groups and the shared file tree for notes and attachments.
## [1.42.0] - 2026-11-04
### Added
- Support manual Podman deployments through Docker Compose, add a sandbox override for socket and SELinux workspace access, and direct quickstart users to that path. Document the reproduced migration dependency failure in podman-compose 1.6.0.
## [1.41.0] - 2026-11-04
### Added
- Connect Stav models with a vault API key and an EU (default), EEA or global region. Region restrictions remain enforced when request settings include custom headers; existing profiles retain their settings. Model catalogs choose Chat Completions or Responses from the model’s advertised surfaces. Custom Stav catalogs use the selected visible vault key, with credential-isolated caching.
## [1.40.0] - 2026-11-03
### Added
- Delegate explicit work to durable background topics in the same project, keep talking in the source conversation, inspect or stop each task, and receive one source-bound result turn. Tasks retain pinned agent versions, ordinary budgets and approvals, the selected main model and exact local device; interrupted external actions are not automatically replayed.
- Choose a local Claude Code/Codex model and reasoning level per conversation from the installed harness's reported choices, including resumed coding sessions. Reference recent accessible conversations in the `@` menu through the existing Past conversations capability.
## [1.39.2] - 2026-11-03
### Fixed
- Deleting an account no longer deadlocks with an ingest that is recording the embedding spend of a document in that account's personal knowledge base. The deletion now locks the personal organization before it deletes the documents under it. An ingest whose organization is deleted while it runs no longer fails when it records its spend. In the rare case that a knowledge collection is created during the deletion and is busy, the deletion now returns 409 and deletes nothing, so it can be retried.
## [1.39.1] - 2026-11-03
### Changed
- Deleting a document, reading its chunks and expanding a search hit to its neighbouring chunks no longer scan the collection. Each knowledge-base collection table now has an index on the document id: new collections get it when they are created, and migration `0252_index_rag_parent_doc_id` adds it to existing ones. On a 300k-chunk collection these operations went from 40–100 ms to under 1 ms.
**Upgrade action (optional, large deployments):** The migration builds the index inside the upgrade transaction. Searches keep working, but ingestion and deletes into a collection wait until the upgrade commits (the build takes about 0.2 s per 300k chunks). To avoid that pause, build the indexes online before you upgrade. Run this in `psql` connected to the application database:
```sql
SELECT format('CREATE INDEX CONCURRENTLY IF NOT EXISTS %I ON %I (parent_doc_id)',
table_name || '_parent_idx', table_name)
FROM information_schema.columns
WHERE table_schema = 'public' AND column_name = 'metadata'
AND data_type = 'jsonb' AND table_name LIKE 'rag\_%' ESCAPE '\'
\gexec
```
The migration then finds the indexes valid and leaves those collections alone. Let the statement finish before you upgrade: if the migration finds a build still running, it stops with an error, and you run the upgrade again after the build ends. If a concurrent build fails, it leaves an invalid index. Drop it with `DROP INDEX CONCURRENTLY <name>` and run the statement again. If you upgrade with an invalid index in place, the migration drops and rebuilds it, and searches in that collection also wait until the upgrade commits.
## [1.39.0] - 2026-11-03
### Added
- Prepare private, checksummed coding runtimes and pinned Claude Code/Codex adapters without host developer tools. Coding-agent setup and browser sign-in are available in desktop settings.
- Install the verified local runtime on Windows and supported Linux desktops, resume Windows setup after a required restart, show download progress and retry the same workspace. Pin new local instances to the packaged platform release and back up database, media and deployment keys before updates.
### Fixed
- Keep existing workspaces visible after starting the local runtime, repair incomplete macOS runtime installations and verify Docker Inc's signing identity before requesting installer elevation.
- Remember native coding-agent startup consent per agent, folder, adapter version and connection; revoke it with folder/account access and stop affected agents. Preserve local grants on reconnect, avoid repeated credential probes on focus, hide background Windows console windows, wait for HTTP readiness and refuse remote Docker contexts or platform downgrades during local setup.
- Prepare the local runtime from the macOS setup wizard and restart saved local workspaces when the desktop app opens. Pull public product images with a private anonymous configuration to avoid credential-helper and keychain prompts, and pass Docker helper paths to subprocesses launched from Finder.
## [1.38.4] - 2026-11-03
### Fixed
- Deleting the last knowledge base on a collection name deletes the same rows on every path (`DELETE /kb/{id}`, `DELETE /rag/collections/{name}` and `rag-drop`): the base's own document rows and its tenant's unfiled rows, with their files, before the vector table is dropped. A tenant is the base's organization, or, for an app-scoped base, the rows with no organization that `rag-ingest` writes. `DELETE /kb/{id}` used to leave the tenant's unfiled rows and files behind the dropped table, for its next base on the name to list again; for an app-scoped base it now deletes the `rag-ingest` rows under the name. The collection drop used to delete every row under the name whichever tenant it belonged to, including another organization's unfiled rows and files, which the caller had no authority over. Another tenant's rows now stay, marked as failed because their chunks went with the table: an upload has to be uploaded again, and a sync indexes a synced document again. `POST /rag/documents/{id}/retry` refuses an organization's document filed under no knowledge base, whose retry would index it where its base does not read. After a drop by an organization's base, `rag-drop` of the same name, which no base then holds, removes the `rag-ingest` rows left under it. The three paths run one teardown.
## [1.38.3] - 2026-11-03
### Fixed
- Background-job audit and table-retention integration tests no longer depend on
PostgreSQL returning rows in insertion order.
- Clearing the Architect's uploaded avatar restores its generated face, just as
it does for other agents. The special mark no longer overrides an empty avatar.
## [1.38.2] - 2026-11-03
### Fixed
- Initialize the desktop TLS crypto provider before plugins and background connections start. Paired computers can connect to the server again instead of leaving local Claude Code or Codex chats waiting for the computer.
## [1.38.1] - 2026-11-03
### Fixed
- Keep dashboard bar lists at their natural height so ranked agents and provider costs do not overlap idle-agent chips, monthly spend or other card content. Small cards scroll instead of compressing rows.
## [1.38.0] - 2026-11-03
### Added
- Desktop chat controls can select local Claude Code or Codex for one conversation even when Coding agent is disabled or absent from the published agent. Existing approval and read-only rules remain active; a full-access folder and native task confirmation are still required.
- Local coding tasks resume their conversation's harness session across process restarts. Mid-task corrections interrupt and continue the same session, with applied updates recorded in the transcript and report. Resume identifiers stay outside the repository and are isolated by account, agent, conversation, folder and access policy.
- Local project instructions support both `AGENTS.md` and `CLAUDE.md`, with a tool to read the hierarchy inside the approved folder. Sign-in opens a native terminal on macOS, Windows and Linux.
- The desktop app finds Claude Code and Codex on the computer, shows their version and whether they are signed in under Settings → Desktop app, and opens each agent's own sign-in in Terminal. AgenticOS never reads or copies the files an agent keeps its credentials in.
- The `coding_agent` capability can run Claude Code or Codex on the person's own computer (**Where it runs: On this computer**), in a folder granted full access, over the Agent Client Protocol. The agent signs in with its own command, so no key is needed. Each start is confirmed in a native dialog; permission requests inside a task are answered from the binding's access, and the capability's approval stays once per task.
- Chat controls → Work on → **My skills and instructions** lets a chat use the skills in `~/.agents`, `~/.claude` and `~/.codex` and your `AGENTS.md` (the newer of `~/.codex` and `~/.claude`, then the working folder's), read in place on the desktop and never copied. Off for every new chat and chosen per folder; a name clash goes to `.agents`, then `.claude`, then `.codex`.
- Help → **Export Diagnostics…** in the desktop app writes one JSON file, to a place you choose, to attach to a bug report: version, operating system, permissions, coding agents installed and signed in, the server's origin and the last crashes - no credentials, tokens, conversations or home-folder paths, and nothing is sent. A panic is saved to `crash.log` as it happens.
- A **Watch a command** capability (`monitor`): the agent starts a long-running command - a test watcher, a log tail, a CI poll - in its workspace and is told about its new output on its following steps, filtered by an optional pattern, without polling. At most four watches run at once and they all stop when the turn ends.
- The composer shows which coding agent will work in which folder (`Claude Code · agenticos · can edit`) when the chosen agent runs one on this computer, or what is missing.
- A world map in visuals and apps that needs no tile server or extra container: `AOWorldMap` draws countries shaded by a value, pins and routes as SVG from outlines the deployment serves itself.
- Three bundled skills for building a slide deck as an app: `presentation-decks` (with a ready deck template), `deck-storyline` and `deck-review`.
- A Homebrew tap, `vstorm-co/homebrew-agenticos`, published by the release workflow when `HOMEBREW_TAP_TOKEN` is set; `scripts/install_macos.sh` installs a release after checking its SHA-256.
### Changed
- **The first desktop window opens at 80% of the screen**, centred, until a size has been saved.
- Releases are signed on macOS with one self-signed certificate when `MACOS_SELF_SIGNED_P12` is configured (`scripts/create_macos_signing_cert.sh` makes it), so macOS keeps Screen Recording and Microphone grants across updates. With the committed publisher pin, missing signing material stops the release; neither signing mode is notarized.
- `GET /conversations` leaves out threads a bot answers in (Slack, Mattermost, Telegram, Teams) by default, so `/chat` no longer fills with them. Pass `hide_channels=false` to list them again; they stay reachable from Runs and the channel's page.
### Fixed
- Table, Kanban and List share one content background; local file-link origins use opaque identifiers with private desktop folder mappings.
- Homebrew publication authenticates both Mac disk images against the pinned publisher before generating trusted tap checksums.
- Bound the entire local ACP stream and close adapters on output overflow. Refuse monitors on desktop shells that cannot retain background processes. Require signing material when the publisher certificate is pinned. File links retain their original turn workspace, and HTML previews resolve nested CSS assets through that same authorized source.
- The egress inventory includes per-chat local coding overrides; local launches recheck revoked grants after confirmation. Coding folder choices exclude incompatible grants, and file trees normalize current-directory path components.
- Monitor starts reserve their limit before waiting, unfinished output stays bounded while matching full lines, and shutdown escalates unresponsive processes. Cancelled local coding-agent starts also reap sessions whose open replies were not observed; switching to local execution clears a sandbox-only model.
- Coding-agent instructions remain fully readable, execution locations use icon cards, desktop readiness refreshes on native focus with guidance for macOS grants, and Tables uses consistent empty states across views without a large-screen catalog expansion button.
- Conversation lists identify Claude Code and Codex used in a thread alongside its main agent, based on saved task reports and retained after refresh.
- File viewers keep clear of macOS window controls, load directly linked workspace stylesheets and preserve original HTML in Source. Chat files retain their folder hierarchy, and files changed by a turn can be opened below its answer.
- Live chat progress folds into an expandable line on small screens while answers and requests for attention stay visible.
- Chat controls opens above the composer with direct coding-agent choices, compact tool switches and expandable folder and approval settings.
- Tables and Workflows cards have the same default height on the dashboard.
- Desktop chat settings open in a larger dialog with Tools & files and Preferences tabs. Selecting a local coding agent prepares an approved full-access folder automatically; cancelling preserves the previous choice. Finished coding tasks no longer leave a duplicate status panel below the answer.
- The desktop console can list local coding agents and skills and open coding-agent sign-in. Their native commands are declared and granted to the main console, fixing the `Command not found` refusal.
- Local Claude Code read-only tasks disable bypass permissions and expose reading tools only. Local Codex read-only is available in the Builder and selects its native read-only mode. Launch consent has a five-minute interaction timeout, and local skill counts follow the enabled sources.
- Homebrew publishing supports a deploy key restricted to the tap repository, with temporary key cleanup on success and failure. The stable macOS publisher fingerprint is pinned for installer verification.
- The desktop app can be allowed to use the microphone: the bundle now declares the audio-input and Apple Events entitlements it needs under the hardened runtime, and the setup wizard offers the microphone next to Screen Recording and Accessibility.
- The cask attached to a release clears the download quarantine flag from the installed app, so Gatekeeper does not refuse an unnotarized build installed through Homebrew.
## [1.37.0] - 2026-11-02
### Added
- Discord bots (#2079). A bot connects over Discord's Gateway, so a deployment
needs no public address for it. It answers direct messages, @mentions and
replies in a thread it opens on the question. It also answers `/ask` and
**Apps → Ask the agent** on any message. Answers stream by editing the
message in place, with text the guardrails have already screened.
Approvals and questions are buttons, or selects for more than 25 options.
`/link`, `/unlink`, `/agents`, `/new` and `/help` work as on the other
platforms. A thread the bot is brought into partway is read for its earlier
messages and files before it answers, and `read_channel_history` works there. Register one under **Channels → Add channel** with the bot token
and the Message Content Intent switched on. Explicitly approve server IDs in
the add/edit form, or pass `--discord-guild` to the CLI; an empty list permits
DMs only. Existing installations and removal/re-adds do not approve a server.
Console transcript access also requires Read Message History. `/ask` first
acknowledges privately, admits against the parent/thread key, rate-limits
link invitations and only then publishes the question. Signed attachment URL
queries are redacted from failure logs. A public bot, one anyone can add
to their own server, is refused until **Public Bot** is switched off; its
commands are offered only in servers it was added to. A Discord bot takes no
webhook, and setting one is refused. A bot in more than 2,500 servers stops and says
Discord requires sharding, which is not supported yet.
### Fixed
- A Microsoft Teams bot's form no longer offers a reaction to a question.
Teams never drew it, so the reaction chosen there was saved and ignored.
## [1.36.1] - 2026-11-02
### Fixed
- Hide message action rows on phones until the More button beside the user or agent is tapped, saving room in the transcript. Keep desktop hover actions. Release the full-screen file reader when its listing fails and move focus into an auto-opened reader, restoring it to the file on return.
- Move the phone Architect launcher into the header and reclaim its bottom clearance for lists and tables. Align the compact chat editor and actions to equal touch heights.
- Make phone chat more comfortable while writing: keep attach, message and send in a compact row, offer agent selection and voice under the plus menu, hide welcome suggestions while composing and bound completion menus to the visible height. Preserve draft text and stable send targets as focus moves. Do not automatically focus touch-keyboard input on arrival or when a reply finishes.
- Give agent and project instructions one compact toolbar, fold unused prompt variables, preserve preview when expanding Markdown, and align expanded-editor phone gutters. Keep phone text fields legible across authentication, files, integrations, tables and workflow forms while preserving desktop sizing. Keep floating App controls clear of the native status bar.
- Reduce oversized desktop and phone spacing across headers, cards, settings, navigation, template categories and empty states. Capability cards open settings through one target, with explanations available on demand. Enable profile saving only for changed values and reset the email field after staging verification.
- Keep phone dialog gutters consistent on all four edges, compact shared navigation and page headers, and move Context descriptions into the editor toolbar to leave more room for text.
- Allow development assets from the hostname configured by `PUBLIC_SITE_URL`, so a console opened over Wi-Fi can initialize its login form.
- Simplify phone navigation and editing: Inbox filters and MCP clients use selects, long settings navigation uses a section menu, secondary page commands fold away, project files open full screen and workflow step panels switch without losing edits. Keep administrative row actions visible on narrow screens and reduce dialog footer and run-summary height.
- Improve phone layouts across page actions, app controls, skill and context editors, and file readers. Mobile editors fold descriptions and file management away while writing; project and workspace files have a dedicated reader. Source/preview controls use one button. Apps use floating back and options buttons, keeping more space for their content. Expanded editors preserve drafts and variable completion. Reduce the chat composer's height, align painted source text with its input, and open navigation without focusing its close button.
## [1.36.0] - 2026-11-02
### Security
- The message of a turn a guardrail stopped is no longer replayed to the model in later turns' history. Each check reads only what is new in its own turn, so the message of a `guardrail_blocked` run was read back as history on the next turn, with the text that was typed and the head of each attached file (or the whole file for an agent without a workspace). A harmless follow-up could then get refused content past the input check. The history that web chat, the API, channels, the widget, workflows and a voice call's seed build now shows the model a short note in place of that message, whichever check stopped the turn, and a reply that quotes it quotes the note. A stopped turn also no longer keeps what its files added to the prompt. The person's own transcript still shows what they typed. The filter also applies to conversations from before the upgrade: migration `0248_drop_refused_turn_summaries` drops each stored conversation summary that reaches past such a message, so the next turn rebuilds its history from the transcript and pays for one new summary if it needs one; turns beyond the recent window that only the dropped summary recalled are no longer read back. The mark is kept on the message itself (`messages.guardrail_refused`, added by migration `0249_message_guardrail_refused`), so it holds after run retention deletes the run. The migration marks the messages of every `guardrail_blocked` run still stored; a message whose run retention deleted before the upgrade cannot be identified and stays unmarked. Search over past conversations (`conversation_search`) does not filter these messages yet.
## [1.35.5] - 2026-11-02
### Fixed
- A document deleted while it was still being indexed no longer leaves its chunks searchable. The delete removed nothing because the document had no vector id yet: its chunks were written, or still being written, and the ingest had not recorded them. The ingest now queues a retried job that removes the chunks it wrote when it finds the document deleted, and a delete that discovers the newly recorded vector id queues the same durable removal. Recording the embedding spend of such a document no longer fails the ingest on the deleted row, which had left the chunks in place and retried the job until it died: the spend is kept against no document. A sync no longer counts such a document as ingested. Clearing a default knowledge base mid-ingest was already covered ([#2565](https://github.com/vstorm-co/agenticos/issues/2565)).
## [1.35.4] - 2026-11-02
### Fixed
- The input guardrail no longer reads an attached picture's bytes. On a prompt with a picture it screened the prompt's whole representation, image data included, so PII redaction refused most pictures, a blocked keyword such as `png` matched the data, and a redaction ended the turn as `failed`. The edge now screens the prompt's text alone (a text file sent inline as text, and a link, where a match blocks because a link cannot be rewritten), a redaction rewrites that text and keeps the picture, and the check that runs before an attachment is written now predicts the edge for a turn with a picture too, so a blocked one no longer leaves its picture in the workspace. An inline text file is screened as the UTF-8 a model is sent, and one that declares another character set or is not valid UTF-8 blocks the turn instead of being screened as different text. The size limits of a resumed request count the text of all its prompt parts together (#2566).
## [1.35.3] - 2026-11-02
### Security
- A link in an agent's answer that leads to another site now opens in a new tab, whatever its address looks like. A link written without `https://` - `//evil.example`, `https:evil.example`, `HTTPS:/evil.example` - was rendered as an in-page link, so a click took the console's own tab to that site. The chat decides a link is off-site by where the browser resolves it against the console, and opens it in a new tab with `rel="noopener noreferrer"`. Console links, including the Architect's links that point at a control, still open in place.
## [1.35.2] - 2026-11-02
### Changed
- Run backend coverage once, shard frontend and E2E tests, reuse the production frontend build, and cache native builds. Build desktop release platforms in parallel and publish updater metadata only after every signed target is available.
- Reuse successful checks for proven release-only cuts, prepare release train PRs from the CLI, reuse unchanged browser images, and retain scans and SBOMs when images are retagged. Offer production deployment only after a stable release is published, while keeping manual deployments and rollback.
## [1.35.1] - 2026-11-02
### Fixed
- PyMuPDF ingestion skips embedded images when image description is off. With
descriptions on, shared images are extracted and described once per document,
while every referencing page keeps its description. Chunks no longer copy
embedded images, avoiding memory growth from repeated logos and diagrams in
large PDFs ([#2584](https://github.com/vstorm-co/agenticos/issues/2584)).
## [1.35.0] - 2026-11-02
### Changed
- **Planning cache and history migration:** Harness 0.64 returns framed plans with tool metadata and records a missing or changed visible plan as user-channel run history. It no longer inserts a planning cache breakpoint. Existing `planning.cache_ttl` values still load but are ignored: move custom retention to `cache` in the agent or model profile's model settings, for example `cache: "1h"`. Platform prompt caching remains enabled by default.
### Fixed
- Declare the Harness tool argument repair extra so dependency upgrades retain `json-repair` and agent startup does not fail when importing `RepairToolArguments`. Update Harness and its matching Pydantic AI and graph packages to the compatible releases, preserve plan metadata and step IDs in structured tool returns, and keep goal reminders from repeating user text. Dependency freshness runs the whole suite with the same bounded parallel runner as CI so validation finishes within its job limit.
## [1.34.3] - 2026-11-02
### Fixed
- CI, load tests and dependency freshness checks disable deployment diagnostics so ephemeral test installations and browser activity do not enter the live analytics collector.
- Parallel integration tests synchronize quota audit pool exhaustion and scope listener probes and connection termination to their own database, avoiding load-dependent pool timeouts and interference between pytest workers.
## [1.34.2] - 2026-11-01
### Fixed
- Documentation and `llms.txt` no longer say that nothing phones home or that a fresh install sends nothing anywhere. Deployment diagnostics are on by default, so the docs now state that prompts, conversations and documents stay in the deployment's own database, that diagnostics send the version, health, coarse usage counts and a pseudonymous activity signal, that the default collector is remote (`https://analytics-agenticos.testapp.ovh`), and how to turn them off with `DIAGNOSTICS_ENABLED=false`. The diagnostics collector is added to the lists of what leaves a deployment in the data protection and security pages, and the Polish, German and Spanish translations are updated to match.
## [1.34.1] - 2026-11-01
### Changed
- Update the GitHub Actions the workflows use: `tauri-apps/tauri-action` to 1.0.0, `actions/download-artifact` to 8.0.2 and `actions/upload-artifact` to 7.0.2, among others. CI and release behaviour are unchanged.
## [1.34.0] - 2026-11-01
### Added
- Workflow creation starts with a name, audience, trigger and optional description and tags, matching agent creation. A separate category gallery opens templates for review before creating their resources.
- Workflow forms have configurable appearance, an authenticated draft preview and direct test and public links. Test draft opens the form or chat surface for those triggers.
- **Review an automation once.** Prepare a private workflow and its table atomically with one MCP approval, then check its graph without executing actions. Run pages state the scope of test verification.
- **People, agents and document libraries in Tables.** Reference one or many organization members or accessible AI agents, choosing names with avatars. Save named Markdown templates per column, customize and reuse them, and choose an automatic default for new records.
- **Document blocks and pasted images.** Markdown table documents offer a searchable `/` block menu and accept clipboard images at the cursor. Images inherit table access, survive archiving and share the table storage quota, with a 5 MiB limit per image.
- **HTTP authentication from Vault.** Request, upload and download steps share a method-aware authentication form for Bearer, Basic Auth, header and query API keys. Create origin-bound credentials in place with the API origin prefilled, keep only their IDs in workflows, and configure custom authorization prefixes such as `Token`.
- **SMTP accounts for workflow email.** Add your own server, sender and login directly from the email step. Credentials stay encrypted together in Vault; workflows reference only the account ID. STARTTLS and implicit TLS verify certificates, access is checked at publication and runtime, and revoked accounts never fall back to another sender.
- **Sort records from every table view.** Add an explicit column/direction picker beside filters, including hidden sortable columns and system dates. The selected server-side order is shared by Table, Kanban and List and can be saved with the view.
- **Saved table presentation.** Reorder and hide columns, including system fields, choose compact or wrapped text and configure date and time formats independently for each saved view. These controls change presentation without changing table schemas or stored values.
- **One MCP interface for automations and records.** AgenticOS MCP now starts published workflows and reads, upserts or deletes table records against their revisions. Agents use the same approved tools as other MCP clients; existing capability grants remain compatible. Steps expose their primary HTTP, file, AI and filter controls and connect channel bots in place. New record writes preserve the actual person, agent, API key or workflow origin and show its avatar or icon separately from the authorizing member.
- **Workflow panes, app discovery and document media.** Configure steps between their input and output in a window-sized editor. Discover unconnected MCP catalog apps and use their individual tools, connect a mailbox from the email step, and set model temperature and reasoning effort directly. Kanban uses pointer previews and immediate lane moves with rollback on refusal. Markdown documents offer formatting controls, images and direct video playback.
- **Column defaults, choice colors and system properties.** Configure typed defaults and select colors in the console. New select defaults may name labels before option IDs exist. Every table shows immutable creation/update dates and actors from its record metadata, also included in console CSV exports.
- **Document templates and properties.** Rich-text columns offer editable default templates for notes, meetings and project briefs. New records apply the template automatically; existing documents can apply it after confirmation. Dates and author are shown above Markdown from authoritative record metadata, and custom frontmatter properties have their own controls.
- **Full-screen workspaces and ready templates.** Expand a table, an entire record or workflow run history without remounting editors. Catalogs fill the workspace and expand over the shell, cards align their metadata and actions, tables lose redundant frames and workflow import accepts a dropped file. Public API and Markdown notebook templates provision a private table and a valid draft automatically; later runs reuse it and upsert the example record.
- **Independent workflow starts.** Add different triggers to the same canvas, choose a start for a test, and run only its reachable branch. Publication retains each webhook or schedule registration; Active controls all of them. Existing single-entry workflows remain compatible.
- **Architect builds automations and tables.** Platform tools discover step schemas, create and revise drafts, test and inspect runs, publish reviewed workflows and manage typed table records. Bundled skills explain API integrations beyond the MCP gallery and callable workflow tools. Signing secrets are withheld from model results.
- **Simpler workflow editing.** Step configuration and data use compact cards, record fields follow table columns, and setup messages stay folded. Workflow metadata moves into Settings; notes gain an expanded editor, size presets and larger resize handles. Canvas menus have clear icon spacing.
- **Rich text columns in Tables.** Choose Markdown for notes with headings, task lists, tables, links and code, with source highlighting, preview and an expanded editor. Optional YAML frontmatter is preserved with the document and shown separately in preview. API writes, text queries, CSV round-trips and conversions to and from plain text keep the source intact.
- **A published page can show a workflow's log live.** `publish_artifact` takes a
second kind of binding, `"kind": "workflow_log"`: a workflow (id or exact name), an
optional step, outcomes, run and `include_test`, and either `lines` (the newest N, at
most 500) or `per_day` (7, 30 or 90 days in an IANA time zone) - the filters and limits
of `GET /workflows/{id}/logs` and `/logs/summary`. It is resolved at publish and frozen,
read with the page owner's access to the workflow after the owner's consent, worded in
the publish result, the consent dialog and the data change review (any change to it is a
widening), and `unavailable` when the owner can no longer view the workflow or the step
is gone. A page that reads a log cannot have a public link. Bindings published before
this are tables and need no change.
- **Read a workflow's log with an organization API key.** `GET /workflows/{id}/logs`,
`GET /workflows/{id}/logs/summary`, `GET /workflow-runs/{id}/logs` and
`GET /workflow-logs` are part of the public API, in `/public/openapi.json`, for building
a dashboard in Grafana, Metabase or a script. A key needs `workflows:view` and reads the
lines of public-origin runs, as the runs list does: runs started by keys or from outside
(webhook, form, channel, mail, GitHub), not those a member, schedule, table record, chat
or agent started. The alert rule routes stay session-only.
- **Alert people when a workflow's log crosses a threshold.** A rule on a workflow counts
the real-run lines its Quick Logs wrote that match chosen outcomes, optionally one step
and some message text, and tells its audience when at least N appear within 5, 15, 30 or
60 minutes, 4 or 24 hours - at most once per window, never for a test run. The audience
is `admins` (owners, admins and the deployment's app admins), the workflow's `owner` and
`chosen` members who still belong, delivered at the bell and by email per each person's
notification preferences (the new `workflow_log_alert` event) with a link to the Logs
page filtered to the rule's step and outcomes. A workflow's Logs page has an Alerts card
to add, pause and delete the rules; the list and summary take `outcome` repeated. `GET`/`POST /workflows/{id}/log-alerts`
and `PATCH`/`DELETE /workflows/{id}/log-alerts/{rule_id}` manage the rules: listed for
whoever may view the workflow, changed by whoever may edit it, with outcomes and step
checked against the workflow's logging steps. A per-minute worker job evaluates them.
- **A Workflow logs dashboard card.** It sits in the add-a-widget catalog, for whoever may
view workflows, and shows the newest lines the Quick Logs of the workflows they may view
wrote (real runs only) with how many lines the last 24 hours added and how many were
errors. A line links to its run and the workflow's name to its Logs page.
`GET /workflow-logs` serves it, gated on `workflows:view`; a key may call it too.
- **A workflow's log counted per day.** `GET /workflows/{id}/logs/summary` answers how many
lines the log gained each day over the last 7, 30 or 90 days, split by outcome, with days
counted in a given time zone, for building a dashboard on the log. It is gated like the
list, and a key may call it (`days` of 7, 30 or 90; `tz`, an IANA name, UTC by default;
step, outcome, run, search and test runs as in the list).
- **A mail action added below its trigger starts bound to it.** Adding Gmail **Create draft**
or **Send message** under a Gmail trigger binds `thread_id`, `in_reply_to` (from
`rfc_message_id`) and, for a send, `to` (from `sender`); Outlook's reply drafts bind
`messageId`, and the shared-mailbox reply draft and send bind `userId`, from the Outlook
trigger. They are
ordinary bindings, changeable, and one undo takes the step and them back together.
Nothing is bound without that trigger upstream.
- **A workflow editor can pick an organization MCP connection without `mcp:manage`.**
`GET /workflows/{id}/mcp-connections`, open to whoever may edit that workflow (by role
or by a grant on it), lists the organization's own servers, disabled ones included,
with only their name, label, catalog entry, tools and test time - never the URL,
credential or consent. The `mcp.call` panel and the step picker's Gmail and Outlook
actions read it, so publishing and choosing a step need the same right; adding or
testing a server still needs `mcp:manage`. The list is read again on focus. The
service icon beside a server in that picker now matches by catalog key or name only,
not by URL, which an editor does not see.
- **The step picker groups a service's trigger and MCP tools by app.** **Gmail** and
**Outlook** are groups under **Apps and the web**: the app's trigger, then one entry
per tool of each organization MCP connection to Google Workspace or Microsoft 365,
named **Create draft**, **Send message** and so on, or by the tool's own name for
the rest. Picking one adds an `mcp.call` set to that connection and tool; stored
workflows are untouched. Nothing is hidden: entries and cards carry an **MCP** badge
and the connection and tool name, search finds either name, and the step's settings
say it is an MCP tool call and link to the connection. With no connection the group
offers to connect the server. No API change.
- **A step can log its outcome with a Quick Log.** A step's `quick_log` setting
(`message`, and `outputs` for the ports that log; unset means all) writes one line
to the workflow's own log each time the step settles: its time, name, the port it
left by or `error`, status and a message that can read `{{step}}`, `{{outcome}}`,
the step's output fields and `{{error.code}}` / `{{error.message}}`. A reference
with no value renders empty and never changes the run; `error.details` is refused
at publish. Nothing is written for a skipped or switched-off step or one a retry
reuses. `GET /api/v1/workflows/{id}/logs` lists a workflow's lines (filters,
paging; test runs only with `include_test`) and
`GET /api/v1/workflow-runs/{id}/logs` a run's. Both routes are
part of the public API. The Logs page also filters by run: paste a run
id or type its first characters into **Run** (the route's `run`: 4 or more
characters of the id, anything else a 422), fill it from **Show only this run** on
a line, or open it from **See in Logs** on a run's page. Lines go with their run when retention removes it.
Migration `0238_workflow_log_entries.py` adds `workflow_log_entries`.
- **`human.approval` can offer the approver several ways to approve.** List up to
five **Ways to approve**, each an `id` and a button label, such as keep a draft or
send it now. The Approvals queue shows one button per choice in place of
**Approve**, with **Reject** beside them, and the step has an output port per
choice, in order, then `rejected`, and no `approved` port. The chosen `id` is
`choice` in the step's output, and the decided row shows its label.
`POST /api/v1/workflow-approvals/{id}` takes `choice`, which an approval of a step
with choices needs and any other decision refuses with `422`. A step with no
choices is unchanged. Migration `0236_workflow_approval_choices.py` adds
`choices` and `choice` to `workflow_approvals`, with nothing to backfill.
- **A connected mailbox is checked as often as you choose.** **Check for new mail
every** - 1, 5, 15, 30 or 60 minutes, a minute by default - is a setting of the
connected Gmail or Outlook mailbox, on its card in Triggers and on the Gmail and
Outlook trigger steps. It applies to every trigger and workflow on that mailbox,
because one read of the mailbox serves them all. Changing it needs `mcp:manage`:
`PUT /api/v1/mcp-connections/portals/{connection_id}/poll-interval`, which refuses
any other value with `422`. The portal catalog carries it as `poll_interval_minutes`.
Migration `0237_mailbox_poll_interval.py` adds the column; every existing mailbox
keeps its minute.
- Draw workflow steps by family: Start, AI, Flow, Data, Apps and Error each get
their own tile and a "Family · Kind" label, steps that can park the run say so in
a band, the minimap follows the families, and a step waiting for a person is rose
with an hourglass. **Simple** (Settings → Profile → Appearance, or the canvas
toolbar) keeps the neutral look, per browser. A selected step can be resized
by its right edge, bottom edge or corner, its text wrapping into the space, and
**Reset size** in its right-click menu undoes it.
- **Removed steps stay out of a workflow's Stats card.** A step taken out of the
workflow keeps its past runs, but its rows in **By step** and **Approvals** are
hidden until **Show removed steps** in **By step** brings them back.
- **Approval outcomes on a workflow's Stats card.** An **Approvals** section sums
up how people decided what the workflow asked them: approved as proposed, edited
with the median change (each edit's `edit_ratio` is measured once when it is
decided, by the `text.compare` scorer), rejected, expired and the time to decide,
per step and per day, over the same days as the run figures. The stats API carries
them in `approvals`. `GET /api/v1/workflow-approvals/stats` adds the totals and
the five workflows with the most requests across those you may view, and the
**Approval outcomes** dashboard card, in the catalog, shows them. No text and no
per-approver figure leaves an approval. Requests decided before this release have
no edit ratio and are shown as not measured.
- **`text.compare` scores how alike two texts are.** A data step that gives a score
from 0 to 1 by character edit ratio, word overlap or changed lines, with switches
to ignore case, whitespace, punctuation, and quoted mail and signatures.
Deterministic, no model and no cost; each text is at most 100,000 characters.
- **`html.parse` reads HTML into its text, links and CSS-selector matches.** A data
step for a mail body, an `http.request` body or a stored page: the readable text
as Markdown, every link once (script and `data:` links left out) and the elements
a selector picks, from HTML text or a file. Everything is bounded, the parse is
stopped after 20 seconds, and nothing is fetched or executed.
- **`ai.classify` can leave by `unsure` below a confidence.** With a
`min_confidence`, the model also states how sure it is of the category, from 0
to 1 (its own report, not a calibrated probability), and the step leaves by an
`unsure` port below it, as `decide.*` does. Steps without a minimum are
unchanged: same prompt, same ports, `confidence: null`.
- **Two self-hosted mail servers in the MCP catalog.** `google-workspace` is
`taylorwilsdon/google_workspace_mcp` (Gmail, Calendar, Drive and Sheets, over
Streamable HTTP with `MCP_ENABLE_OAUTH21`, using your own Google OAuth client);
`ms-365` is `softeria/ms-365-mcp-server --http` (Outlook mail and calendar, with
`--org-mode` for shared mailboxes and Teams). Each connection signs in as one
account.
- **A how-to, [answer mail with an approved draft](docs/howto/answer-mail-with-approved-draft.md).**
A mail trigger, a drafting step, an editable approval and an `mcp.call` that
leaves the approved text as a draft in the thread or sends it.
- **`mcp.call` can send an idempotency key.** **Idempotency key argument** names a
tool argument that the step fills with its stable operation key, the same on
every retry. The tool must declare it as text: publishing refuses an argument the
recorded schema lacks, and a run fails with `MCP_IDEMPOTENCY_ARGUMENT_UNDECLARED`
without calling. A keyed step counts as idempotent.
- **Workflows started from Outlook.** An **Outlook** trigger starts a run for each
new message in a folder of the organization's connected Microsoft 365 mailbox, or
of a shared mailbox, that fits its filter. The poll reads the folders the
workflows name and starts a new folder from when the workflow was published. A
workflow whose folder cannot be read is switched off, with
`mailbox_folder_unreadable` in the audit log. Migration
`0234_workflow_outlook_trigger.py`; its downgrade refuses while any `outlook`
exposure (switched off ones too) or a run it started exists, so unpublish the
workflow and delete its runs first. Both mail triggers take outside input.
- **Mail threads, HTML and attachments on both mail triggers.** A Gmail or Outlook
run gets `thread_id`, `rfc_message_id`, `in_reply_to`, `references`,
`received_at` and `html` (up to 20,000 characters), and the message's attachments
(a mailbox lists at most 20) stored as files of the run: the first 10 listed and
25 MiB per message, within the chat-upload size limit and
type allowlist and the storage quota. One left out carries a reason, a test run
fetches nothing, and a provider failure fails the step with
`MAIL_ATTACHMENT_UNREACHABLE`, retried.
- **`human.approval` can let the approver edit a proposal before approving it.**
Bind text such as a drafted reply to the step's new `proposal` input and turn on
`editable`; the Approvals tab shows an editor (`text` or `markdown`, under a
`proposal_label`) with **Restore original** and **Show changes**, and a decider the
step does not name sees it read-only. The approved step outputs `final`,
`original` and `edited`; a step that is not editable hands its proposal on as
`final` unchanged. `POST /api/v1/workflow-approvals/{id}` takes an optional
`final`, refused with `422` on a step that is not editable or with a rejection.
An edited `final` is stored without leading and trailing whitespace, and
`edited` ignores line endings, trailing spaces and blank space around the text. The audit entry records `editable`, `edited`
and the two lengths, never the text. A workflow that sends `final` through
`mcp.call` sets that step's `approval` to `none`. See
[the node reference](docs/reference/workflow-nodes.md#human-approval).
- **`OUTBOUND_PRIVATE_ALLOWLIST` lets an operator open hosts on the
deployment's own network.** An entry is an exact host, a `.suffix` (which does
not match the apex), an IP address or a CIDR range. Workflow `http.request`,
`http.download` and `http.upload` steps, the `git`, `web` and S3 sources,
the A2A client and MCP connections honour it, and only for a request chain whose
first URL needs it, so a public site's redirect, OAuth metadata, A2A card or
crawl cannot reach a listed host. A source on the private network, for example a
self-hosted MinIO, needs its host listed. Loopback, link-local, multicast and cloud
metadata addresses stay refused whatever is listed, including a listed name
that answers one wherever the name is resolved, an MCP connection's own URL
included (a listed name that does not resolve yet can still be saved), and a name
with one unlisted private answer. Startup refuses a malformed entry, one that reaches
those addresses and one that names the database, Redis or the API itself, by
name or address; `doctor` catches a range that covers a store's resolved
address. Every account of every organization can
reach every port on an admitted host, so list only services that check their own
credential. `agenticos cmd doctor` gains a `private network` line and the HIPAA
sheet a `private-network` control. `MCP_ALLOWED_HOSTS` is not an alias and
keeps its MCP-only reach, but it now goes through the same parser: suffix and
CIDR entries work there, one trailing dot is dropped, and a listed name that
answers a loopback or metadata address is refused where the name is resolved.
The HIPAA `private-network` control counts both lists. See
[the configuration reference](docs/configuration.md#project-settings).
- Bound cumulative inline workflow results per run and organization, including
loop-generated outputs, with compact counters and retained-history backfill.
Preserve fees and stop automatic retry when a result cannot be stored.
- Import pinned nested file references safely across retention, charge each eval
case against run limits, and narrow resumed agents to current workflow funds.
- Preserve canvas notes during paste, apply mixed note/step changes together and
retain newer test examples when older responses arrive later.
- Reserve workflow email deliveries against shared issuer, organization and
deployment allowances before sending; refuse delivery when Redis is unavailable.
Preserve webhook delivery tombstones after run retention, enforce public-link
expiry on existing content tokens and return typed datetime overflow failures.
- Require member consent when publishing or enabling unattended workflow triggers;
enforce current MCP visibility and tool allowlists at publish and dispatch.
- Bound public form request streams and DOCX XML extraction before materialization.
Keep private views usable after column retyping, save Kanban grouping, load more
cards per lane and timestamp table events against trigger activation's wall clock.
- Load complete skill/context choices for inline workflow agents, reject unusable
eval inputs and clean up partial PDF/sandbox file batches after failure.
- Preserve organization-key scopes on workflow sockets, including worker admission
and stream reauthorization; refuse keys accessing private runs or personal chats.
- Bound inline workflow outcomes to a configurable 10 MiB total and refuse Split out
expansion above 10,000 items or projected bytes before copying repeated fields.
Oversized terminal outcomes preserve fees and never automatically replay effects.
- **Organization-key access to Virtual Tables and workflow runs.** External
clients use the shared table routes with scoped organization keys, including
receipt-backed writes, revision checks and bounded column selection. Workflow
workers retain the key's admitted scopes, recheck its current authority before
every step and stop after revocation, expiry or deletion; key-started chains
cannot reach the issuer's personal state. Workflow authoring remains session-only.
- **A page can start a workflow, as the person viewing it, after they confirm.**
An agent declares up to five actions when it publishes - workflows its Workflows
capability binds that start from Manual or API request and that the person behind
the run may run - and the page's buttons call `agenticos.run` (`AO.run` in the page
kit). The console accepts the request only from the page's own frame and under its
nonce, lists only the actions the viewer may run on the version they are served, and
asks every time in a dialog titled with the workflow's own name that quotes the page's
label and shows each input value, with a delayed Run; one question is open at a time
and three declines stop the questions until the page is reopened. The run is the
viewer's - their access, budget and runs page - with a new `app` trigger and the page and version recorded on
it; the page reads back only its status, answer text, structured answer without files
and a short error. Public links, embeds, previews, history and impersonated sessions
get no actions. New `artifact_versions.actions`, `workflow_runs.source_artifact_id`
and `source_version_number` (migration `0221_artifact_actions`), the setting
`RATE_LIMIT_ARTIFACT_ACTIONS_PER_MINUTE` and the audit entry `artifact.action_started`.
(#1976) [Artifacts](docs/artifacts.md#actions) has the rules.
- **A page's public link and embeds can show live table data, behind two confirmations.**
An Owner or Admin turns on **Public pages with live data** in the organization's
settings (off by default, as themselves, audited); then the page's owner, or an Owner or
Admin for them, confirms its data for the link after a screen that names the queries and
who can reach them - anyone with the link, its password and expiry, each embedding site.
The confirmation is bound to the queries and that audience, and turning the link off,
removing its password, adding an embedding site, a new owner, a withdrawn member consent
or archiving clears it; replacing the key, changing the expiry or pin, and switching the
organization off do not. Every load re-checks the link's key, expiry, password, switch and
consents before reading: a replaced or removed key is a 404 at once, anything else renders the page
without data and without a reason. Visitors get the records as of load, with no refresh.
Reads are shared for 30 seconds in a byte-bounded cache in the API process, never in
Redis, and each page's real reads are capped per minute. Editors see why a consented
page shows nothing. New `organizations.public_live_data` and public data columns on
`artifacts` (migrations `0219_org_public_live_data`, `0220_artifact_public_data`), settings
`RATE_LIMIT_ARTIFACT_PUBLIC_DATA_PER_MINUTE` and `ARTIFACT_PUBLIC_DATA_CACHE_BYTES`, and
audit entries `organization.public_live_data_changed`, `artifact.public_data_consented`,
`artifact.public_data_withdrawn` and `artifact.public_data_voided`. No agent tool reaches
any of it. (#1975) [Artifacts](docs/artifacts.md#live-data-on-a-public-link) has the rules.
- **A published page can show live table data, shared on its owner's consent.**
An agent binds a page to **page queries** - a table, or a saved view whose filters
and sort are copied, with fields, filters, a sort and a limit - and the page's
`agenticos.onData` is handed the records, already in the page on load and again
on every refresh. Everyone who opens the page reads the same records with its
**owner's** access, so the data reaches anyone beyond the owner and the roles that
open every page only after the owner confirms it: **Confirm data** shows the queries in
words, every linked table they reach and who will read them, and the page's audience
keeps the last version that was consented to, or sees "This page isn't available yet",
until then. Anyone who can edit the page can stop sharing its data; the owner can
turn on **Share new versions automatically** for their own republishes, and give
a person or group **Can edit, including data**. A binding goes unavailable when the
owner leaves or loses access, or when a column it reads changes meaning: columns now
carry a read-only `revision`. The owner hands a page to another member with **Change
owner**, which asks the new owner to confirm its data again. Widening who opens a page
that reads data is the owner's call; anyone else files a request, answered in a
**Requests** section of the Share dialog, and an editor's republish that reads more
waits as a request with a **Review data change** panel. A member who opens a page they
cannot see can **Request access**. Agents get `share_artifact`, which only asks. New
`artifact_share_requests`, consent columns on `artifact_versions`, `artifacts.auto_consent`,
the `edit_data` grant level, the `artifact_share_requested` and `artifact_owner_changed`
notifications (migrations `0215_artifact_consent`, `0216_artifact_owner_changed`,
`0217_artifact_share_requests`, `0218_grant_edit_data`) and audit entries
`artifact.data_consented`, `artifact.data_withdrawn`, `artifact.auto_consent_changed`,
`artifact.owner_changed`, `artifact.share_requested`, `artifact.share_request_approved`,
`artifact.share_request_declined` and `artifact.edit_data_granted`. A public link or an
embed carries data only under the separate switch and consent described above. A page
takes up to 5 bindings, 1,000 records each and 4 MiB,
a 5 s deadline and 30 loads a minute per viewer, and a bound page is changed only by a run
acting for a member (a signed-in member, a linked channel sender or a schedule's creator).
The viewer's strip has Refresh and an auto-refresh each viewer chooses; cards, the
dashboard and the viewer mark live pages. `list_views` finds a view to start a query from.
(#1974) [Artifacts](docs/artifacts.md#live-data) has the rules.
- **A workflow run reads on the canvas.** Each step carries a pill on its
corner - Pending, Starting, Running with a ticking time, Waiting, Failed,
Needs attention, Skipped, Not reached, or the time a step that succeeded took -
the wire into a running step moves, a branch the run did not take fades,
and a failed step shows its error under its card. The editor gets a Stop
beside **Run**, and **Test step** a Stop of its own and a warning when the
tested step did not run. A run's page draws the same, still once the run
has ended.
- **Workflow editor additions.** Typing `{{` in a text parameter suggests
values from earlier steps, including the fields a test run saw inside a
payload, and placeholders are coloured, red once the box is left when one
names nothing. The **Input** pane picks any earlier step to read from.
Hovering a step's problem mark lists its first problems and clicking it
opens the step, whose dialog lists every problem, a field's leading to the
field. **View only** shows an editor the read-only editor, whose dialogs
now show every setting. `Delete` deletes the selection, and a dragged field
scrolls the form at its edge.
- **Archiving and restoring a published page.** Someone who may edit an
artifact archives it from **More actions** above it, after a dialog says that
the page, its versions and its link are kept, nobody can open it and its
public link is turned off. An archived page serves nothing: its view, its
live data, signed addresses minted earlier, the public link and the embed all
answer as for a missing page, and the agent's tools treat it as absent -
`publish_artifact` refuses the name with a message naming the archive. Its
editor sees when it was archived, with **Restore**; a reader is told it is not
available. Restoring leaves the public link off. New
`POST /api/v1/artifacts/{id}/archive` and `/unarchive` (audited as
`artifact.archived` and `artifact.unarchived`), `include_archived` on the
list, an **Archived included** filter and an **Archived** badge in the
console, and `artifacts.archived_at` (migration `0211_artifact_archive`).
- **A restored page version says what it was restored from.** Restoring a
kept version of an artifact still adds a new version with its bytes; that
version now records the number it came from, and the console's version list
shows it as `v4 · restored from v2`. A publish leaves it empty. New
`restored_from` on the version read and `artifact_versions.restored_from`
(migration `0212_artifact_restored_from`).
- **Tool-call approvals say what they will do in names.** A gated table
write is parked with its ids resolved, as the run's person, to the table and
record names that person may see, and the chat's approval card and the
Approvals page lead with a sentence naming them above the arguments. A capability declares the describers with `describers=` on
`register(...)`; one that fails or is slow parks the call without a sentence.
New `context` on `GET /approvals` rows, `GET /runs/{id}/parked` and the
`tool_approval_required` frame, and `tool_approvals.context` (migration
`0213_tool_approval_context`).
- **Archiving and restoring a table from the console.** A member who can edit
a Virtual Table archives it from **More actions** on its page, after a
dialog says that its records stay readable, nothing can change them and it
can be restored; what still uses the table is listed when that refuses the
archive. An archived table's page says so, with **Restore** for whoever may
edit it, through the new `POST /api/v1/tables/{id}/unarchive`.
`TableRead.can_restore` says who may. The catalog can list archived tables
too. A restore is refused while a live table holds the archived one's name.
- **A page kit an agent follows, and warnings when it does not.** Library
version 3 (`lib/agenticos-3.css`, `lib/agenticos-3.js`) keeps every class and
call of version 2 and forgives loose markup: a header's parts placed directly
in it, a table with no `<thead>`, text written straight into a table's wrap.
It adds loading, note, live, list and toolbar classes, draws icons a script
adds later, and `AO.records` draws bound records as a finished table. Every
Artifacts agent gets a short page contract in its instructions; the first
whole HTML page of a run offering an unloaded `artifact-pages` skill is sent
back once to load it; and each published HTML page is checked, with what looks
wrong listed in the result's `warning`. A warning never stops a publish.
- **Agents can list and preview their pages.** `list_artifacts` names this
agent's pages that the run's person may open, newest first, with each one's
version, bindings, visibility and whether this run may republish it; in a
group chat their private pages are left out. `preview_artifact` draws a page
as a viewer would, with its data read as that person, and returns a picture
and a report of its errors, console messages, policy refusals and the publish
warnings. The picture needs a browser the operator runs, named by the new
`ARTIFACT_RENDER_CDP_URL` and shipped as the opt-in `artifact-render` compose
profile on a network with no egress, and the `browser` extra; without them the
report comes alone. `agenticos cmd doctor` checks the renderer.
- **A Workflows card on the dashboard.** Real runs, failures and cost over the
dashboard's period across every workflow the reader can see, the five
busiest, and how many runs wait for a person now -
`GET /api/v1/workflows/summary`. The "?" on a workflow's runs page explains
its figures and its run list.
- **Evals for a model step.** A step a model answers has an **Evals** tab:
cases written from the input it was last tested with, each saying where in
the answer to look and whether it should contain, not contain or equal a
value. **Try** starts a test run of the step per case and marks each passed
or failed as its run ends, with what the answer said and what it cost.
Migration `0208_workflow_step_evals`.
- **Limits and figures for a workflow's runs.** A workflow's settings take how
many real runs may be under way at once (a start past it is refused with
`429`), the most one run may spend (the tighter of it and the version's
budget) and the most its runs may spend a calendar month, test runs included
(past it no run starts, with `402`). Its runs page leads with **How it ran**:
runs, success rate, typical and 95th-percentile time and cost over 7, 30 or
90 days, this month's spend against the budget, and cost and failures by
step - `GET /api/v1/workflows/{id}/stats`.
- **Workflows started from an email.** A **Gmail** trigger starts a run for
each new message in the organization's connected Gmail mailbox that fits its
subject, sender and label filters, read by the poll that already fires
agents' Gmail triggers. A message read twice runs once, and one the
organization had no room for is read again a minute later. The step shows
whether a mailbox is connected and connects one; a GitHub step shows the
same for its account. Migration `0207_workflow_gmail_trigger`. The sender
filter reads the address only (`@acme.com` is that domain, not its
subdomains), needs mail the sender's domain authenticated, and sent mail,
drafts, spam and the bin start nothing.
- **Workflows started from GitHub.** A **GitHub** trigger starts a run for
the issues, comments, pull requests, reviews, pushes, releases or Actions
runs of one repository it names, optionally only for some actions. With the
organization's GitHub account connected, publishing registers the hook on
the repository for those events and keeps it in step on every publish;
otherwise it shows the address and secret once, to paste. Deliveries are
checked against GitHub's signature, a redelivery answers with its first run,
and a `ping` or anything not named is skipped. Migration
`0206_workflow_github_trigger`.
- **Workflows started from a channel message.** A **Channel message** trigger
hands a Slack, Mattermost or Telegram bot's messages to a workflow: each one
the bot's agent would have answered, and that fits the trigger's chats and
words, starts a run as its publisher with the text, the sender and where to
answer. The rest still reach the bot's agent, and a bot's messages start one
workflow at most. Migration `0205_workflow_channel_trigger`.
- **Workflows started from a form.** A **Form** trigger gives a workflow a
public page with the fields it declares, its own title, description, button
and thanks. Anyone with the link fills it in without signing in, and each
answer that fits starts a run as the member who published it. **Trigger**
shows the link, **New link** replaces it, and pausing closes the page; each
form takes at most `RATE_LIMIT_FORM_SUBMISSIONS_PER_MINUTE` answers a minute,
and a hidden field turns scripts away. Migration `0204_workflow_form_trigger`.
- **Agents start workflows.** The **Workflows** capability gives an agent the
published workflows its spec names as tools: it reads the input each one
asks for, starts a run as the member it acts for and waits for the answer,
up to a limit set in the Builder. Each start is the API's own, so access,
input checks, budgets and quotas hold, and the runs page says **An agent**
started it. An agent running as a workflow's own step starts none. A run
with no member behind it (a widget, embed or hosted-page visitor, an unlinked
channel sender, an agent event trigger's delivery) starts none.
Migration `0203_workflow_run_from_agent`.
- **Import a CSV file again to update a table.** With an external id column mapped,
**Update records already here** changes the cells a row names on the record
holding its external id instead of refusing it, and the import counts what it
added and what it updated (`update_existing` on `POST .../records/batch`).
- **Table triggers on a record's change and deletion.** A workflow's **Table
record** trigger (formerly **New table record**) can start on records added,
changed or deleted, and a change only when one of the columns chosen for the
table changed. The run gets the record with its `event`, its values `before`
and the `changed` columns. Changes and deletions are queued only for a table a
trigger listens to. Migration `0202_table_trigger_events`.
- **Formula columns.** A table column can work a value out from the record's
other columns - `{Price} * {Quantity}`, `IF({Total} > 100, "large", "small")`,
`DAYS({Due}, TODAY())` - with arithmetic, comparisons and a dozen functions,
including what a rollup worked out. Renaming a column rewrites the formulas
that read it, and saving one checks it and says what is wrong. Formulas run in
a closed interpreter of their own: nothing in one is evaluated as Python.
- **Links, lookups and rollups between tables.** A `link` column holds records of
another table, picked by searching that table, and a record reads them back
named. A `lookup` shows one column of the linked records and a `rollup` counts
them or works out a sum, average, minimum or maximum - both worked out when the
record is read, so they always say what the linked records say now, and never
past what the reader may see. Writing a link checks every record exists in a
table the writer can see.
- **Email, link, phone and rating columns.** A table column can hold an email
address, an `http(s)` link, a phone number or a 1-5 rating, each checked as it
is written, typed into the field a phone keyboard expects and rated with
stars. Text converts to each when every value reads as one, and an import
reads and infers them. `contains` and `starts_with` take a piece of a value,
so `@example.com` finds the addresses at a domain.
- **MCP tool and email steps in workflows.** **Call an MCP tool** calls one tool
on one of the organization's MCP servers, picked with its service's mark and
then from the tools the server listed; by default a person approves any tool
the server does not mark read-only before it runs, through the same Approvals
inbox as **Ask for approval**. **Send an email** mails up to ten addresses, a
copy each, from the deployment's sender, and says when the provider only logs
mail rather than delivering it. A tool's arguments are one field each, from the
schema the server listed, since a binding can now fill one key of an open
object (`arguments/email`).
- **Model steps and a knowledge write.** **Ask a model** answers a prompt under
the step's instructions, as text or an object; **Classify** puts a text in one
of the step's categories and branches on it; **Extract data** pulls the fields
a schema names out of a text; **Summarize or translate** summarizes, translates
or rewrites one. Each runs as the step's own agent, so the step's cost cap, the
workflow's budget and the organization's limit apply and the run is in
Activity. **Add to knowledge** puts a text or a run file into collections
through the same upload a collection's page uses.
- **Configure an agent inside a workflow step.** An Agent step pins a catalog
agent or, with **Configure here**, defines its own - model, instructions,
capabilities with their knowledge, and MCP servers - in the Builder's own
editors. The agent is the workflow's: versioned with the graph, created on the
step's first run, republished when its spec changes, kept out of the catalog and
reached through the workflow's access. **Copy its configuration into this step**
and **Save as an agent** move between the two. `max_cost_usd` caps one execution
of the step. Migration `0201_workflow_agents`.
- **A workflow note can be tinted** grey, yellow, green, blue, purple or red
from the swatches a selected note shows; the graph keeps the colour.
- **A table column's type can change** to one its values read as: anything to
text, text to a number, a yes/no, a date or a single select (an option per
distinct value), a whole number to a number and back, a date to a date and
time, one choice to several and back. Saving rewrites every record's value
in the same change; a value that does not convert refuses it, naming how
many and one example, and something that uses the column refuses it as an
archive does. **Columns** offers only the types a column converts to.
- **Try a chat-triggered draft in a chat panel.** Open chat in the editor
runs the draft as a test with each message, opens the run on the canvas and
shows its answer; nothing said there reaches a real conversation (#1955).
- **Compare a version with the draft.** A version's preview draws both on one
canvas with every added, changed and removed step marked, and lists what
changed in each changed step (#1954).
- **Export and import a workflow, and automation templates.** The editor
downloads a draft as a `.workflow.json` file with no ids of the deployment and
no secret values; Import on the list makes a new draft from one and lists
every step and field to choose again. New workflows can start from Lead
intake, Slack alert on failure or Daily summary (#1953).
- **A code editor for the Python and JavaScript steps.** Highlighting in both
themes, Tab indentation, Enter that keeps the indentation, closing brackets
and quotes, and the keys of the bound `args` offered as they are typed; Esc
then Tab leaves it. It reuses highlight.js, already a dependency (#1952).
- **Import cURL, query authentication and paging on the HTTP request step.**
A pasted cURL fills the method, URL, headers and JSON body; a credential in
it is lifted out and offered to the vault, never kept in the step. A token can
go in a URL parameter, on every HTTP step. A `GET` pages by next URL, cursor or
page number, collecting each page's items, and stops at `max_pages` (#1951).
- **A new secret from a workflow step.** A step's secret field offers New
secret: the vault's form fixed to the kind the field takes, choosing the new
secret on save, so an HTTP credential or a decision key is added without
leaving the editor. Only the id reaches the graph (#1950).
- **A webhook's test URL, and a Respond to webhook step.** Listen for test event
on a draft's webhook trigger opens a test URL for two minutes; the one call to
it is pinned as the trigger's output and never starts a run. A graph holding
Respond to webhook answers its sender with that step's status, headers and
JSON body, waited for up to `WORKFLOW_WEBHOOK_RESPONSE_TIMEOUT_SECONDS`; a
graph without one answers `202` as before (#1949).
- **Transform steps for lists of objects.** Edit fields, Sort, Limit, Remove
duplicates, Aggregate, Split out, Summarize, Date & time and Crypto reshape data
without a code step. Each is pure and typed, most take and hand on `items`, and
an item missing a field is handled the same way by all of them (#1948).
- **Switch, Wait, Filter a list and Combine lists steps.** **Switch** takes the first
of many named rules that holds, or `otherwise`, and rejoins at a Merge. **Wait**
holds a run for a number of seconds or until a bound time on a durable timer that
survives a restart. **Filter a list** keeps the items a condition holds for, and
**Combine lists** appends two lists or merges them by position or by a key. Waits
park with the new `timer` reason (#1947).
- **Call another workflow as a step.** A **Called by a workflow** trigger with
typed fields makes a workflow others run, and the **Run a workflow** step starts
its published version with the bound input, waits for it and hands on its output
or error - or goes on at once. The called run is linked to the step; a call that
loops back into the chain or goes more than five deep is refused. Runs gain
`parent_node_run_id` and can be `triggered_by` `workflow_call` (#1946).
- **Workflow settings and error workflows.** A workflow's **Settings** name the
timezone its schedule's cron expression is read in, a default run deadline, an
error workflow, and how long runs and their files are kept, swept daily. A new
**On failure of a workflow** trigger makes an error workflow, started once for
each failed real run with the run, the failing step and the error, as the member
who chose it; its own failures start nothing. `PUT /workflows/{id}/settings` is
new, workflows gain `settings`, and runs can be `triggered_by`
`workflow_failed` (#1944, #1945).
- **A run history you can debug.** Runs filter by status, draft or published
version and what started them, a page at a time on the server, and a new
**Runs** page lists every workflow's. A run's page shows each step's Input and
Output from that run. **Retry from failed step** starts a run in which every
step that succeeded hands on its earlier output, so no write is made twice, and
**Debug in editor** pins a run's step data onto the draft. `POST
/workflow-runs/{id}/retry` is new, and runs gain `retry_of_run_id` (#1943).
- **Template fields that mix text with values from earlier steps.** A text field's
**Template** mode takes text such as `New lead: {{Form.payload.name}}`, with
**Insert a value…**, drops from the Input pane and a preview from the last test
run. Each placeholder is checked at publish like a binding and rendered when the
step runs, JSON for a list or an object; one with nothing behind it fails the
step with `INVALID_BINDING` naming it. Bindings gain a `template` source (#1938).
- **Map a workflow step's field by dragging it.** A column or a field of the step
dialog's Input pane dropped on a setting binds it to that field, and one that
does not fit is refused with the reason. Inside a free-form value the type the
run showed decides, and the source picker now offers free-form values to any
setting, with the path typed beneath (#1937).
- **See a workflow step's data, pin it and test the step alone.** The step dialog
shows what the step read and what it handed on in the last test run, as a table,
as JSON or as its fields with their types. Pinned data, typed in or kept from a
run, stands in for the step in test runs and is stripped at publish. **Test step**
runs only the step and what leads to it, the steps with known output handing it on
instead of running, and asks first for a step that writes. A node run read gains
`output`, `NodeInstance` gains `pinned_output`, and `POST /workflow-runs` takes
`step` (#1934, #1935, #1936).
- **Notes on the workflow canvas, and a canvas that is quicker to work.** A note
of markdown sits beside the steps, moved and resized freely and kept by versions
and copies. A selected connection's **+** puts a step into its middle, wired on
both sides; **Tidy up** arranges the steps left to right in one undoable edit; a
minimap, **Tab** for the step picker and a **?** shortcut sheet, none of which
fire while typing. The graph gains `notes` (#1940, #1941).
- **Name a workflow step, note it and switch it off.** A step's own name shows on
its card and in every binding list and problem, and must be unique in the graph; a
note is marked on the card; a switched-off step stays on the canvas, dimmed, and is
skipped when a run reaches it. Publishing refuses switching off the trigger or a
deciding step, and reading a step that is off. `NodeInstance` gains `label`,
`notes` and `disabled` (#1939).
- **Find, rename, switch and retire workflows from the console.** The list
searches by name, description and tag, filters by tag and sorts by last edit,
name or age, all kept in the address. The editor renames a workflow in place and
tags it, and a published one with a webhook, schedule or table trigger gets an
**Active** switch, shown on its card too. A card's menu archives (pausing the
trigger), restores and deletes. New `PATCH /workflows/{id}`,
`PUT .../active`, `POST .../archive`, `POST .../unarchive` and
`DELETE /workflows/{id}`; a workflow now has `tags` (#1942, #1956).
- **Import a CSV file into a table, and export one.** **Import** maps the file's
columns to the table's, reads each value in its column's type and sends the rows
200 at a time to a new `POST /tables/{id}/records/batch`, listing every row that
failed with its line and reason. **Export** saves the records on screen, in their
order and columns, from a new streaming `POST /tables/{id}/records/export` (#1961).
- **A table grid that scrolls through thousands of records, and says how many.**
The grid loads a hundred records at a time as it scrolls and draws only the rows
in view; the count of matching records shows beside the view tabs, from a new
`POST /tables/{id}/records/count` that counts up to 100,000 (#1964).
- **Manage a table's columns from its grid.** Each header opens a menu to sort by
the column, hide it in the view, rename it or archive it, and a **+** after the
last column adds one; a rename, an archive and an add each write the schema
version the Columns dialog would (#1963).
- **Search and filter a table's records, and keep it in a view.** A search box
finds text in any text column or select option label, **Filter** builds
conditions from the operators each column type supports, and **Save view** keeps
both, with the sort, in the view on screen. `RecordQuery` and a view's `config`
take the same `search` (#1962).
- **Add, edit and delete table records in the console.** **Add record** asks for
each live column in its own type and marks the ones that need a value; a cell
edits in place on a click, saving on Enter and leaving on Escape; ticked rows
delete together, each against its own revision, and the record panel deletes one.
A refused edit opens the record with the value kept beside a retry (#1958, #1959,
#1960).
- **Run a workflow from its editor, and watch it happen.** **Run** in the editor's
header, or `Ctrl`/`Cmd` + `Enter`, tests the draft at once - asking first for
the fields its trigger declares - and the run shows on the canvas as it goes:
each step's status, tries and error, with a bar that opens the run's page. The
trigger a person starts is now **Manual**, separate from **API request** (the
former Manual or API, whose graphs keep starting from the API); both take
typed input fields (#1932, #1933).
- **A workflow step that asks a person.** **Ask for approval** stops a run
until someone approves or rejects what it is about to do, then goes on by the
answer. The request shows its title and the details bound to it in the
Approvals tab, above the tool calls; named approvers are notified and are the
only ones who may decide it. A decision is final and audited, a request can
expire after a set time, and cancelling the run cancels it.
- **A JavaScript step.** **JavaScript in a sandbox** runs a script on Node as
the same durable job the Python sandbox step runs, on the organization's
sandbox host: it reads the bound values as `args`, reads and writes the run's
files, may `await`, and what it returns is the step's result.
- **Typed input for a workflow started by hand.** The **Manual or API** trigger
can declare **Input fields** - text, number, whole number, yes or no, date or
choice, each required or not. **Start a run** then asks for each by name in a
form, a run whose input does not fit is refused before it starts with the
fields that are wrong, and a binding to one is type-checked at publish.
- **Workflow steps that read what a table is.** **List tables**, **Describe a
table**, **Table exists?** and **Record exists?** let a workflow find a table,
read its columns, create one only the first time it runs, or branch on whether
a matching record is already there. The two questions leave by `yes` or `no`.
- **Workflow steps that talk in Slack, Mattermost and Telegram.** **Send a
message**, **Read messages**, **List people** and **Find channels** act as one
of the organization's channel bots, through the adapter its replies use, so a
workflow can post an alert, read a thread, look up who is in a channel or find
one by name. Acting as a bot needs `channels:manage`, checked at publish and on
every run, and the editor picks the bot from the organization's own.
- **Workflow steps that decide with TypeSafe's Jev.** **Yes or no**, **Choose
one** (of up to 255 options) and **Score** (against a rubric of 2 to 10
described levels) ask Jev a typed question about a bound text with a
TypeSafe key from the vault, and answer in one request with a confidence.
The answer can only be one the step allows, and below the step's confidence
floor it leaves by an **Unsure** port instead, so a doubtful case goes where
the workflow says. A merge may rejoin a decision's branches.
- **An agent can answer with data rather than prose.** The Builder's **Answer
format** turns an agent's answer into an object of named, typed fields - or
any JSON Schema, edited as JSON - stored as `output_schema` in the spec. The
model is asked for that shape through Pydantic AI's structured output, and an
answer that breaks the schema is sent back to be fixed before the run ends.
The run API returns the object as `structured`, the chat and the channels
show it as a JSON block, and an `agent.run` step hands it on or asks for a
shape of its own; a run parked on an approval resumes asking for the same
shape.
- **Building a workflow is a run of clicks.** Clicking a step in the palette
adds it after the selected step, or at the end of the flow in view, wired in
when the ports fit and clear of every other step; a starting step goes before
the current start and becomes it. A **+** beside each output searches the
steps that can come next and adds one there. The new step is selected and
scrolled into view, a trackpad or wheel pans the canvas while a pinch zooms,
and steps added inside a loop now show in its body at once instead of only
after a reload.
- **A table can run a workflow for every record added to it.** A workflow
that starts from a **New table record** trigger runs, once published, for
every record added to its table that matches the trigger's filters as it was
created - in the console, over the API, by an agent or by another workflow -
as the member who published it, with the whole record as its input. Only
records added while it is on start it. Each record is decided once per
trigger, and the table's **Triggers** pauses each one and shows every
decision without the record's values. A chain of runs writing into each
other's tables stops at the first trigger it already passed, and a column a
trigger filters on cannot be archived out from under it (#1785).
- **Workflows can fetch, read, convert and hand on files, and run Python.** A
file a step makes is stored as a file of its run and passed on as a `FileRef`,
and a step reads one only if its own run made it or was started with it, so an
id alone grants nothing. `http.download` and `http.upload` stream files over
HTTP under the same SSRF and credential rules as `http.request`, with the type
read from the bytes. `file.read`, `file.write`, `text.extract` (which names the
pages of a scan rather than returning them empty) and four `convert.*` steps
handle text, JSON, CSV, PDF and DOCX. `image.transform` crops, resizes and
converts images within the pixel limit, with their metadata removed.
`code.python.simple` runs a script in the Monty sandbox, and
`code.python.sandbox` runs full Python with files as a durable job on the
organization's sandbox host, reconnecting instead of restarting. `agent.run`
shows bound images to the agent as pictures, and a run's page lists its files
for download (#1791).
- **A workflow starts from a trigger on its canvas, and can answer in the
chat.** The palette's **Triggers** - **Manual or API**, **Chat message**,
**Webhook**, **Schedule** and **New table record** - are the first node of a
workflow, one per workflow, and **New workflow** starts from the one picked.
Publishing switches the trigger on and runs it as the publisher; the next
publish takes it over. A **webhook** gets an address and a signing secret,
shown once at that publish, and names each delivery with an `X-Delivery-Id`
so a retry never runs it twice; a **schedule** runs every so often, daily at
a time or on a cron expression, in UTC. The editor's **Trigger** sheet shows
the live one, pauses it and rotates a secret. `/api/v1/ws/workflow-runs`
starts or follows a run, resuming from a cursor after a dropped connection.
The chat's picker lists the workflows that start from a chat message: a
message starts a run, and its status card and answer land in the thread, even
if the chat was closed meanwhile (#1792).
- **The workflow editor, its runs and the tables pages look and work like the
rest of the console.** The editor fills the window: a palette grouped the way
a workflow reads, with loop steps offered only inside a loop and the debug
nodes gone; nodes drawn as cards that say what each step is set to do and
label every port (**true**/**false**, **Each item**/**Done**, a red **Error**);
and a properties panel with a policy section for retries, a time limit and
error routing, a real table picker, a path box for values with no fixed shape
and a JSON editor for free-form literals. History moved into a sheet. A
workflow's **Runs** page lists its runs and starts one by hand, and a run shows
its figures, its error, its output, every step it took and its graph coloured
by what each step did, loop iterations included - read from two new routes,
`GET /workflow-runs/{id}/nodes` and `GET /workflow-runs/{id}/graph`. Workflows
and tables list as cards, and a table's select values show as chips. The
editor, runs and tables are on the [screens page](docs/screens.md) in both
themes (#1790).
- **Workflows can loop over a list and handle their own errors.**
`control.foreach` runs its body once per item, in order and one at a time,
from `loop.item` to `loop.yield`, and hands on every result in input order.
The list is frozen when the loop starts, each iteration runs in its own
scope, and the next one is scheduled in the transaction that ends the last,
so a restart resumes the right iteration without repeating a confirmed
write; an approval inside an iteration resumes that iteration.
`item_error_policy` chooses between stopping at the first failed item and
collecting its error in place. Every node takes a `policy` with a timeout, a
retry schedule and `on_error: route`, which sends a failure out of the
node's `error` port to `error.handle`, whose branches match on error code.
`error.raise` fails a branch with an error the author defines. Revoked
access, a spent budget, a cancelled run and an uncertain effect are never
routed. Loops are bounded in items, stored size, nesting and total node runs
(`WORKFLOW_FOREACH_MAX_ITEMS`, `WORKFLOW_FOREACH_MAX_MANIFEST_BYTES`,
`WORKFLOW_FOREACH_MAX_DEPTH`, `WORKFLOW_RUN_MAX_NODE_RUNS`). Cancelling a run
now ends every node still live in it (#1790).
- **Agents and workflows can read and write Virtual Tables.** A new **Tables**
capability gives an agent eleven tools over the tables its binding grants,
with read, add, update and delete chosen per table in the Builder, and
`create_table` only when **Allow create** is on and the member holds
`tables:create`. A table or operation outside the grant is refused before
anything is read, and each call runs as the member's current membership.
Seven workflow nodes, `table.record.create`, `.upsert`, `.update`,
`.delete`, `.get`, `.query` and `table.create`, write through the same
service. A retried step or tool call replays its first write, and a table
or pinned column a live workflow uses cannot be archived. Creating a table
is now idempotent under an operation key; migration
`0188_table_create_receipts.py` (#1784).
- **Workflows can do real work: agents, knowledge, data, branches, HTTP and
notifications.** Nine nodes join the palette. `core.input` and `core.output`
carry a run's `input` and `output` (`POST /workflow-runs` takes `input`, and
the run returns what the graph answered). `agent.run` asks a published agent
at the exact version the step pins, parks on its approvals and resumes the
same run, and can require a JSON answer that matches a schema before
anything downstream runs. `knowledge.search` returns typed sources an agent
can cite. `data.map` and `logic.if` evaluate JMESPath limited to pure
functions, so a graph never executes code. `logic.if` sends a run down one
branch and skips the other, node by node, to the `logic.merge` that rejoins
them. `http.request` calls APIs through the SSRF-pinned client, and
`notification.send` notifies members who can see the workflow. Every node
is in the new [node reference](docs/reference/workflow-nodes.md).
Migrations `0186_workflow_run_io.py` and `0187_workflow_notification.py`
(#1789).
- **Restore a published workflow version to the draft.** **Restore to draft** in
a version's preview replaces the draft with that version's graph, after a
confirmation that unpublished draft changes are discarded. The version is not
changed and none is created until the draft is published. The restore is
guarded by `expected_revision` like a draft save, so it answers a conflict
rather than discarding someone else's edit, stops a queued autosave from
writing the old graph back, is refused for an archived workflow and without
`workflows:edit`, and is audited as `workflow.version_restored`.
`POST /api/v1/workflows/{id}/versions/{version_id}/restore` (#1915).
- **Workflow runs execute durably.** `POST /workflow-runs` starts a run of a
workflow's published version, or of its draft in `test` mode, and the nodes
run on Prefect workers one attempt at a time: each attempt commits `in_flight`
before its handler runs, its result commits together with the next node's
dispatch, a worker that dies mid-call is recovered without assuming either
outcome, and a node parked on an approval is woken when the approval is
decided or expires. Nodes report cost into the run, and a run whose version
carries a budget cap ends once it is spent - though publishing does not set a
version's cap yet, so no run has one today. A run can carry a deadline, is
rate-limited on start, and re-checks the person it acts as at every node.
Runs, their events and cancel have routes of their own; see
[the HTTP API](docs/api.md#running-a-workflow) and
[Permissions](docs/permissions.md#workflow-runs). Migration
`0184_workflow_runs.py`. (#1788)
- **Virtual Tables: typed records behind one service and an HTTP API.** A table is
metadata plus JSONB, never a physical SQL table, with immutable schema versions,
stable table, column and option ids, and nine column types (text, long text,
number, integer, boolean, date, datetime, single and multi select). Records carry
a revision: an update or delete must send `expected_revision` and a stale one is
a typed `REVISION_CONFLICT`. Upsert by external id is atomic, so concurrent
upserts create one record. Every record write commits its history row, its
created-event outbox row and its idempotency receipt with the change, and an
`Idempotency-Key` header makes a retry return the first answer. Access is
visibility plus grants like context files, with new `tables:view`, `tables:edit`
and `tables:create` permissions, and every route answers refusals in one typed
error envelope. Migration `0179_virtual_tables.py`; see
[Virtual Tables](docs/virtual-tables.md). (#1782)
- **Virtual Tables in the console: a catalog, table/kanban/list views, and saved
views.** `/tables` lists, searches and creates tables. A table's page edits its
columns and its sharing, and shows its records as a table, a kanban board
grouped by a single-select column, or a list. One record sheet edits a record
field by field. A write refused for a stale revision keeps the typed value
beside a "Reload and reapply" action, and writes to one record are sent one at
a time, each against the revision the last one returned. Saved views keep a
filter, sort and grouping per kind, private or shared, under
`/tables/{id}/views` (paged, per kind). Archiving a column is refused only by a
view the caller can both see and change; any other view drops the column when
read instead. Also a Tables dashboard card, a sidebar entry and onboarding stops.
Migration `0182_table_views.py`; see
[saved views](docs/virtual-tables.md#saved-views). (#1783)
- **Outlook mail can start an agent** (#1984). A Microsoft 365 mailbox connects
as a trigger the way Gmail does - an app registration stored in Vault as a
Microsoft OAuth app, a consent screen, nothing to paste - and is read once a
minute. A trigger watches a folder (the inbox, a folder a mail rule files into,
or a shared mailbox) and narrows by sender, subject, attachments, importance or
category; the run gets the message as text with its attachments listed. A
message read twice fires once, and Outlook variants of the email templates come
with it.
- **More of GitHub can start an agent.** Beside a new issue, a GitHub trigger now
fires on a pull request opened, ready or awaiting review, a comment that
mentions a phrase such as `@agent`, a failed workflow run, a published release
or a push, each a preset on both GitHub portals and narrowed by branch where it
applies. Issues, pull requests and comments fire only for the repository's own
members by default (`authors: anyone` lets everybody through), and never for a
bot or the account the trigger was connected with.
- **HubSpot and Zendesk webhooks fire agents.** Two new signed sources, each
verified by its provider's own scheme against the secret the provider issues:
HubSpot's v3 signature (and its v1 one for CRM subscriptions), narrowed by
event type and property, and Zendesk's, narrowed by event type.
- **Files and calendars start agents.** Four new portals, each its own consent
on the organization's existing Google or Microsoft app: Google Drive and
OneDrive & SharePoint fire on new or changed files (a file being edited at most
once in half an hour, the account's own edits never), and Google Calendar and
Outlook Calendar fire a set time before a meeting with somebody else on it -
15 minutes by default, 5 to 120, optionally only with outsiders - so an agent
can prepare a brief.
- **A schedule has a time zone.** A schedule set to a time of day is read in an
IANA zone and keeps its hour through daylight saving; a new one takes the
maker's account zone. The form picks it beside the time, the cadence line and
the dashboard's next fire name it, and the assistant's routine tools take it.
A schedule saved before is still read in UTC.
- **A generic webhook may sign the time.** With `X-Signature-Timestamp` the
signature covers `{timestamp}.{body}` and a delivery more than five minutes
off is refused, so a captured one cannot be replayed.
- **Workflow steps run in parallel branches.** Any step may send one port to several
steps, and those steps run at once; the new **Split** step (`logic.split`) names
its branches and takes them all. A step with several incoming connections runs
once every step leading to it has settled, if one connection is live, with no
Merge. **Merge** gains **Wait for**: `wait_for: one` (the branch that ran, the
default, so a stored empty config is unchanged) or `all`, which hands each branch
on under `branches` by its `branch_keys` name. A branch that fails with no error
route fails the run and withdraws its siblings' approvals, timers and parked
agent runs. A step that finishes after that is recorded as finished after the run
stopped, and a retry reuses it. There is no per-run cap: one run's branches may
use every workflow slot of a worker (`WORKER_WORKFLOW_CONCURRENCY`). (#1800)
[Workflows](docs/workflows.md#parallel-branches) has the rules.
- **A step that needs attention can be resolved on its run.** `POST
/workflow-runs/{id}/steps/{node_run_id}/rerun` takes `run_again`,
`use_error_route`, `fail_run` or `use_late_result`; the run page offers it as
**Resolve** to the person who started the run or an editor, and the choice is
audited. Treating a step as failed ends it with `STEP_MARKED_FAILED`. Migration
`0241_attempt_reservations.py` adds `node_attempts.reserved_usd` and `late_result`. (#1800)
- **Parallel steps share the run's budget.** A step that spends is handed what the cap
leaves after spend and what other steps in flight and called workflows hold, never
more than its own cap; a step whose siblings hold the rest waits and asks again
with a growing delay. (#1800)
### Changed
- **Document properties use table columns.** Remove the Markdown YAML-property editor and stop generating frontmatter in the notebook template. Keep automatic record metadata and preserve existing imported headers during body edits.
### Fixed
- Workers keep the internal AgenticOS MCP server available until agent and workflow jobs finish, so platform-bound agents can run outside the web API process.
- Workflow agent steps retain private conversation history and sandbox workspaces, including isolated test chats, without duplicating intermediate responses in the user chat.
- Bound public form proxy reads, release abandoned image uploads, retain archived agent identities and enforce principal and notification-channel limits.
- Workflow prompt visibility, agent picker width, catalog version pins, model creation permissions, notification channel labels and shared file inputs. New Run an agent steps use catalog agents; existing inline configurations remain executable.
- **Architect workflow construction.** Refreshing shipped Architects binds workflow and table skills, runtime guidance removes the obsolete workflow denial, required columns work when creating empty tables, schedule tests prepare their trigger input, planning returns step IDs immediately, and expected MCP refusals retain safe field errors in chat history.
- **Stable record navigation.** Selecting rows shows a floating action bar without shifting data. The record opener stays pinned at the start of wide tables. Every record panel shows creation and update times and authors, while full-page documents start in Write mode.
- **Run and document hierarchy.** Run statistics share aligned rows, with the start time beside the status. Watched runs trace moving pulses between active steps and highlight their borders. Record properties stay together above Markdown documents, even when new columns were appended later.
- **Canvas selection and shortcuts.** Left drag selects objects; Shift + left drag pans. Select all works within the current scope, and notes travel with copied, cut and pasted steps.
- **Workspace-aligned scrolling and fields.** Kanban fills the available workspace so horizontal scrolling stays at its bottom. JSON parameter editors place Data actions beside their labels, keeping Values, Sources and Artifacts full width.
- **Quieter canvas notes.** A single hover/focus menu groups editing, expanded view, color and size. Subtle rounded edges and one corner resize grip replace the full selection frame and scattered buttons.
- **Readable workflow overview.** The minimap draws connected miniature cards with family accents, rounded starts, selection outlines and a clear viewport boundary in both themes. Pan and zoom remain available.
- **MCP service logos in workflows.** The step picker, canvas and editor share the MCP catalog icon resolver, including baked logos and custom deployment icons. Unknown services use their own name monogram.
- Give Kanban lanes room below the toolbar and draw the drop highlight inside the lane so its top edge stays visible while dragging.
- Keep workflow step titles, rename fields and descriptions aligned without clipped focus borders or narrow placeholder-only name inputs.
- Align table-card footers, put quick add immediately after table rows and pin run-history pagination to the panel bottom. Keep run history and detail clear of floating controls using the standard page clearance. Remove the table workspace expansion toggle, simplify run details and give pasted JSON a dedicated import editor.
- Workflow run history fills the available workspace by default, without a separate expansion toggle.
- **Calmer workflow setup and roomier table forms.** Incomplete steps show one
expandable setup checklist; error styling appears after a test or publish,
while field messages still appear after leaving an empty required field.
Workflow parameters have more space and come first on small screens. Accounts,
API keys and missing trigger OAuth credentials can be added above the workflow,
using the existing account and vault forms. New tables lead with name and
columns, with description and visibility under More options. Table creation,
schema editing, records and CSV mapping keep their actions visible while their
fields scroll, with room for focus rings and stacked controls on narrow screens.
Table, Kanban and List use the console’s shared tabs without clipped labels.
- Align the Workflows and Tables catalogs with the console's shared grid layout,
neutral surfaces and responsive controls. Keep public page data settings reachable
from the organization's Budget and approvals tab, including for members whose
only settings grant is `org:settings`.
- Offer Push preferences for workflow notifications, log alerts, page ownership
changes and page requests, alongside their existing in-app and email controls.
## [1.33.2] - 2026-11-01
### Security
- Update the desktop app's `tauri-plugin-updater` to 2.14.1, which moves its `zip` dependency from 4.6.1 to 9.2.0 and closes three Dependabot alerts (one critical, one high, one medium). Two low and medium alerts on the mobile app's `rand` 0.7 and `glib` 0.18 remain: both are transitive through Tauri, have no compatible fix yet, and neither is compiled into the iOS or Android builds that ship.
## [1.33.1] - 2026-11-01
### Fixed
- Publish ready-to-install desktop packages without requiring Apple Developer credentials. macOS packages use ad-hoc signing by default; first launch requires approval in Privacy & Security. Developer ID signing and notarization remain opt-in, and updater signatures stay mandatory.
## [1.33.0] - 2026-10-31
### Added
- Optional host-owned Compose updater: administrators can prepare a published release, inspect backup and readiness progress, update immediately or schedule within seven days. The helper drains work, takes a final PostgreSQL/media/configuration backup, applies migrations and checks readiness before reopening admission. Single-host Linux/systemd deployments only; larger deployments can link their existing update pipeline.
- Deployment diagnostics with an hourly signed heartbeat, installation-scoped
user pseudonyms, foreground web/desktop/mobile presence and a read-only admin
status card. Reporting defaults to enabled even when an older `.env` omits
`DIAGNOSTICS_ENABLED`; set it to `false` to opt out. Reporting uses the Vstorm collector by default; operators can override its origins. No
prompts, conversations, files, keys, account names or emails are sent.
### Fixed
- Opening an action menu on a touchscreen no longer selects an item underneath
the opening gesture. Mouse and keyboard behavior stay unchanged.
## [1.32.0] - 2026-10-31
### Added
- `refresh-assistant [--org <id>] [--dry-run] [--replace-edited]` reports and
refreshes installed Architect instructions and its AgenticOS guide. New
instructions publish as a new agent version, preserving configuration and
history. Organization edits are skipped unless explicitly replaced; unrelated
pending draft changes block the refresh. After upgrading, run the command to
adopt updated templates in existing organizations (#2520).
### Fixed
- Update the locked pyasn1 parser to 0.6.5 to fix four ASN.1 decoding denial-of-service advisories.
- Refresh recognizes the stock desktop-era Architect from 1.31.x while preserving organization edits.
- Channel messages store only the sender's text. Author context is assembled
from erasable channel identities at dispatch, so the console,
copy, pin and shortcut actions do not expose JSON envelopes or platform IDs.
Account deletion removes those author labels from future model history while
preserving shared message bodies. Manifests omit request-only channel parts;
paused runs retain opaque author references instead of platform labels.
- Replay saved channel user turns through the current agent's input guardrails before model dispatch, preserving stored messages while withholding blocked values and redacting protected text.
- Editable channel reference values follow the configured input guardrails.
Protected values are redacted or withheld without treating fixed metadata
syntax or platform identifiers as the user's question.
- Rolling back the channel prompt migration restores the preceding release's
defaults while retaining custom additions, including bindings created after
upgrade.
- Bulk `refresh-assistant` runs skip organizations without an owner and continue
refreshing the remaining organizations. A targeted run still fails explicitly.
- Explicit `@slug` channel invocations retain saved conversation history, just
like default bot replies, so follow-up requests keep earlier results and App
references after the initial thread backfill.
- Channel replies retain each message's author, answer the current request without
reviving unrelated tasks, and explain how to revise a published App when its
original sandbox is unavailable. Channel defaults now come from the current deployment; a one-time
migration removes recognized stored copies while preserving custom additions.
Author metadata stays outside the actual prompt screened by input guardrails.
- Read-only MCP tools no longer require approval solely because a linked
member's run is in Mattermost, Slack, Teams or Telegram. Unlinked senders still
require approval for every MCP call. Writes and tools without a read-only hint
still require approval; an explicit all-tools policy continues to include reads.
## [1.31.3] - 2026-10-30
### Fixed
- A long document indexes against a local Ollama server. Its chunks now go to
`/embeddings` in requests of at most 64 instead of one oversized request.
## [1.31.2] - 2026-10-30
### Fixed
- Give frontend CI 45 minutes to complete coverage and its production build; align the operational timeout table in all four documentation languages with the current jobs.
## [1.31.1] - 2026-10-30
### Fixed
- Keep frontend test files out of the production Docker build context so desktop UI regression imports do not break the standalone console image. CI still checks and runs those tests in the full repository.
- Stop release preparation immediately when either updater signing key is missing.
## [1.31.0] - 2026-10-30
### Fixed
- Refuse oversized local writes before encoding, preserve pending native sign-ins across unrelated deep links, hide mobile task previews before background snapshots and serialize desktop updater-manifest publishing. Clear native notification bindings on automatic session loss as well as explicit sign-out.
- Revoke desktop local grants and screen control when changing connections or accounts; preview pairing before consuming codes, and stop command process trees on cancellation. Clear native phone notification previews on sign-out.
- Route local calls to one connection, select devices by connection recency, reject oversized local file reads, isolate folder commands from unrelated personal files and clear mobile notification/shortcut remnants when switching accounts or servers.
- Preserve accepted push deliveries when fan-out times out, bound APNs previews by encoded payload size, retain device registrations on configuration mismatches and include the iOS push entitlement in generated builds.
- Pin signed app release builds to the verified commit SHA instead of re-resolving a mutable release tag.
- Chain the desktop/mobile migrations after the latest channel-history migration so fresh installs and upgrades resolve a single Alembic head.
- Keep mobile CI builds active while requiring explicit opt-in for mobile release publishing; document self-build and self-installation until public distribution is available.
- Remember native browser consent across tabs in the same conversation and domain policy until the person closes its last tab or disconnects the device.
- Use explicit environment cards for Computer use and Web browser, with E2B’s official mark and clearer sandbox host configuration. Existing automatic computer configurations remain readable.
- Simplify Quick Ask to one new-chat action and compact inline history; show sidebar files as full-width rows and offer a dismissible desktop download reminder in browser navigation.
### Security
- Refuse cross-site pairing confirmation and require in-app review before an activity link can lead to an approval decision. Native presence alone never approves a tool.
- Bind native OAuth code redemption to an app-held S256 verifier so intercepting a custom-scheme callback cannot redeem its session.
- Require explicit account confirmation before a scanned pairing link replaces a device session. Previewing the account neither redeems nor extends the code.
- Anchor local file operations to an approved directory handle so concurrent symlink substitutions cannot redirect writes or previews outside the grant.
### Added
- Branded desktop installers: a guided macOS disk image and localized Windows setup for the current user. The macOS app bundles small and medium launcher widgets for Quick Ask, Chat, Inbox and Activity.
- Add direct dictation and live agent voice calls to Quick Ask, with shared captions, approvals and conversation history.
- Give Quick Ask independent conversation tabs, searchable recent chats with agent avatars and panel pinning.
- Show installed-version GitHub release notes after login, once per account on a device.
- Remember chat model, approval and local-tool preferences per account and organization; keep whole-computer consent per conversation.
- Highlight the sidebar console version with an update dot and release details when a newer stable AgenticOS version is available.
- Let desktop chats opt into local Computer use independently of agent capabilities and file access.
- Quick Ask accepts picked, pasted and dropped attachments, supports file-only
messages and can stay pinned above other applications.
- Mobile connection readiness for existing accounts, configurable biometric app
lock, named saved servers with session-preserving switching, and server-side
push preview privacy, conversation muting and expiring active-chat
suppression.
- Multiple named local desktop instances with separate Compose projects, ports,
volumes, networks, deployment keys and login cookies; interrupted setup can
resume without replacing its data. The local list starts and connects instances,
while menu controls target the connected managed installation.
- Docker Desktop installer downloads with progress on macOS, an explicit launch
action and detection of per-user Docker CLI installations. Setup focus is neutral
and choice buttons no longer receive an automatic focus outline.
- Centered desktop connection setup with a persistent native glass surface,
local-computer status card and immediate feedback while connecting or opening
the workspace. Readiness preloads the dashboard and respects reduced motion.
- Desktop defaults to the system theme and Glass look when no preference has
been saved; explicit user choices take precedence.
- Desktop connection readiness for new and existing accounts, with explicit macOS
permission requests, contextual repair links and a persistent status panel.
Notification preferences include hidden previews, per-conversation mute and
suppression for the focused conversation. A native Activity & Access menu opens
active work, stops app-owned conversations and revokes local access grants.
- Quick Ask resource mentions with keyboard selection and removal tracking, a
visible new-chat action that resets the conversation, and a bottom composer
with send, dismiss and console controls.
- **Computer** in the Builder’s workspace settings selects a paired desktop without
embedding personal paths or permissions in the spec. Project creation offers a
personal **Computer** folder alongside shared workspace choices.
- Desktop chat can opt into local browser and file tools without changing the agent
in the Builder. Whole-computer access asks once in a native dialog per conversation,
persists across restarts, and can be revoked in chat settings. It permits paths
outside a selected folder and does not automatically crawl or collect home files.
- A `launch` action in `computer_act` opens an application by name instead of
hunting for its icon, and a new `computer_apps` tool lists the names it takes.
A launch matches a name or id exactly and returns once the application's
window is up, or fails if none comes within ten seconds. It works on Linux
desktops: a sandbox's, E2B's and the computerd container, which opens it as
the desktop's account, never the one holding the token. Through the desktop
app the agent is told to use the computer's own launcher, and through another
computerd to fall back to it when `computer_apps` is refused. The
agent is also told to wait after a shortcut that opens a window before typing
into it.
- Browser connection cards with icons, independent per-chat desktop browser
overrides, an automatically opened browser side panel, and tools for up to
eight tabs. Visited-page cards retain the site icon, domain and article title
in conversation history.
Remote private sessions retain a final preview and encrypted reload checkpoints
for one hour; browser processes close after each run.
- Native desktop browser panels with conversation-scoped private tabs, exclusive
run leases and local takeover. Chromium remains available for vision and
language/time-zone emulation.
- **Local project folders in the desktop app.** Connect an approved folder when
creating a project or from its Files tab. The connection stays private to the
current account and organization on that computer; disconnecting it leaves
other chats and native folder grants intact. Local files can be previewed in
place, and new project chats inherit the folder and access mode with a visible
composer shortcut. Each chat can override its location; a regular new chat
clears the previous project and folder.
- **Local services and browser in the desktop app.** Approve loopback model and
MCP services, choose them per run and browse in a visible temporary Chromium
profile on the paired computer. Native folder grants bound local file previews.
- **Native distribution workflows.** Cross-platform app checks, signed desktop
updater assets, Android APK signing and optional TestFlight upload accompany
existing stable platform releases. Signing accounts are configured through CI.
- **An agent can use a computer.** The `computer_use` capability gives an
agent a whole desktop rather than a web page: `computer_screenshot` looks
and `computer_act` clicks, types, scrolls and drags; an agent's owner can
hold the actions alone for approval with `tool_approval`. The desktop is
either inside the agent's own sandbox, on the new `desktop` runtime (XFCE
and Firefox), so the shell, the files and the screen are one machine and
computer use needs no address or key of its own; or a `computerd` daemon
the operator runs on their own Linux desktop, a Mac's own screen or a
container (`deploy/computer/`, where the daemon and its token run as an
account the desktop cannot read), on a host that
`COMPUTER_DAEMON_ALLOWED_HOSTS` allows, reached with the daemon's token
from the organization's vault. The allowlist is checked at publish and
again whenever a run opens the daemon. Publish refuses a sandbox desktop on
an agent, an inline specialist or a pinned delegate without a sandbox
connection to run it in, or whose sandbox is on any runtime but `desktop`
or on Daytona. An approved
batch runs only on a screen still the shape it was approved against, and
`max_actions` counts across approvals; each run, and each delegation
to the same delegate, starts a session of its own, and a batch is refused
after a screenshot fails until one succeeds. The model's screenshots are not
kept: a parked run, its manifest and a compacted conversation hold a
sentence in their place, and the file each is taken through is removed from
the sandbox or the daemon's host once read. The chat draws the desktop live in a window under
the message, and `computer_save_screenshot` keeps a full-resolution
screenshot in the chat and the workspace, for a user who wants to see the
screen or a test that needs evidence (#2094).
- **The desktop app looks and behaves like an application** (#2305). On macOS
the console's sidebar holds the traffic lights and drags the window, the
window remembers its size and place, closing it keeps the app in the menu
bar, and the menu bar has File, Edit, View, Go (⌘1-⌘5, ⌘[ and ⌘]) and Window
menus. A tray menu does the same on Windows and Linux.
- **Styles for the console**: Glass, Graphite, Midnight and Paper beside the
standard look, each with a light and a dark side, under Profile, Appearance.
In the desktop app on macOS and Windows, Glass is drawn over the window's own
translucent material; in a browser it brings its own backdrop.
- **Blobby replaces the pixel pets**: a creature in the agents' avatar style -
one of a cast of six, the face of one of your agents, or a face of your own -
that says when an approval is waiting, something new is in your inbox or your
runs are in progress, and opens it on a click. Configured on a new Blobby tab
in Settings, shown only in the desktop app beside Desktop app (open at login,
keep running, the badge) and Shortcuts.
- **A first-run onboarding for the desktop app**: AgenticOS on this computer or
on your organization's server. On this computer the app checks for Docker,
sets up the published images with the console and the API on loopback only,
creates your organization and owner, and then starts, stops and updates the
stack from the menu bar. On a server it signs you in through the browser. A
short welcome in the console follows: blobby, the shortcuts, notifications.
- **Blobby can be resized**: pinch it, scroll over it with ⌘ held, pick a size
from its menu, or use the slider in Settings.
- **Pair a phone by QR** (#2097): Settings → Mobile app shows a code that
signs the AgenticOS app in as you. It works once, for a minute, and the
phone's session is opened only when it scans, under the phone's own name.
`POST /api/v1/auth/pairing-codes` and `/pairing-codes/redeem`.
- **The AgenticOS phone app** (#2097), first part: an iOS and Android app
(`mobile/`, Tauri 2) that signs in by scanning the console's QR or by typing
the address, keeps the console's session across restarts, and locks behind
Face ID, Touch ID or the fingerprint after five minutes away. The console
lays itself out under the phone's status bar. Push and widgets follow.
- **Live activities in the phone app** (#2097): on Android, your own running
runs sit in the notification shade with a running clock, and an approval
waiting for you comes up with Reject and Approve on it. A tap opens the run
or the queue. A decision made from the lock screen asks for Face ID or the
fingerprint first, then goes through the same request as the queue's buttons.
The iOS Dynamic Island half needs the Xcode project and follows.
- **Phone shortcuts** (#2097): long-press the AgenticOS icon on Android for
Voice call, Dictate, Chat and Approvals, or add the "Ask AgenticOS" tile to
Quick Settings. A call or dictation starts once the agent's readiness is
known, and only after the app's lock.
- **Share to AgenticOS** (#2097): on Android, any app's Share sheet offers
AgenticOS. Text, links, photos and files (up to 20 MB each) land in a new
message in the chat; what cannot be read is named in a notice. Nothing is
attached while the app is locked.
- **A home-screen widget** (#2097) on Android: approvals waiting for you and
your runs in flight, with the time they were counted; a tap opens the queue
or the runs. The counts are the console's, so they refresh while the app is
open; push will refresh them while it is closed.
- **Quick ask** (`⌥Space`, rebindable): a floating panel to ask any agent from
anywhere, with the answer streamed under the question and ⌘↩ to carry the
conversation into the console. On macOS it is a panel like Spotlight's: it
takes the keyboard without bringing the app, or the console window, forward.
- **Voice shortcuts in the desktop app** (#2305): hold `⌥⇧Space` to dictate a
question into quick ask with the selected agent's dictation, and let go to
have it written in; a voice call shortcut, off until you pick a combination,
brings the chat forward and calls the selected agent. The app now declares
its use of the microphone, which macOS requires before the console's
dictation or calls can record.
- **Quick ask knows what you were looking at** (#2305, macOS): the text
selected in the app in front, the files selected in Finder and the
clipboard sit under the question as chips. The selection and the files go
with the question unless you take them off; the clipboard only when you put
it on. Reading another app's selection needs the Accessibility permission,
which the panel offers to open.
- **Your devices name the app** (#2305, #2097): a session signed in through the
AgenticOS desktop or phone app shows as "AgenticOS for macOS 0.2.0" in Active
sessions, and revoking it there signs that app out at once. The console marks
the session you are using. `PUT /api/v1/sessions/current/app`; migration
`0171_session_app` adds two nullable columns to `sessions`.
- **Device management for the apps** (#2305, #2097): an organization can set
the server the desktop and Android apps connect to, lock it so the person
cannot point the app elsewhere, and on Android force the biometric lock on
or off. Keys `serverUrl`, `serverLocked` and (Android) `biometricLock` =
`person` | `on` | `off`: a configuration profile for the domain
`co.vstorm.agenticos` on macOS, `%ProgramData%\AgenticOS\managed.json` on
Windows, `/etc/agenticos/managed.json` on Linux, managed configurations on
Android. A policy that cannot be read is ignored rather than locking anybody
out.
- **Photos into the phone chat, like a messenger** (#2097, Android): the
composer's "+" opens the app's own sheet - Camera, Photos, Files and a strip
of your latest photos to tick - and opening the chat offers a photo taken in
the last few minutes ("Add the photo you just took?"). The app draws both, so
the server never sees the gallery: only the photos you tap reach the message.
Recent photos are asked for from the sheet, the first time it is opened.
- **A cleaner chat on the phone** (#2097): no bar over the conversation - the
menu, the conversation list and New chat float over it as round buttons, the
menu marked while the inbox has something unread. The composer's row keeps
`+`, the agent, the microphone and Send; `+` opens a sheet with Camera,
Photos and Files, then voice input and commands, then the call, the model and
approvals and the context used. In the Android app the page now keeps clear of
the status bar and the gesture bar as the phone measures them.
- **Pinned agents** (#2305, #2097): an agent's page offers Pin to Dock (Pin
to tray on Windows and Linux) in the desktop app - a new chat with it from
the Dock icon's right-click menu and the tray's "New Chat With", up to eight,
listed and unpinned under Settings → Desktop app - and Add to home screen in
the Android app, a shortcut wearing the agent's face. Both open
`/chat?with=<agent id>`, a new chat addressed to that agent.
- **Drop a file on blobby or the Dock icon** (#2305) to start a chat with it:
up to ten files of 20 MB each are attached to a new message in the console,
and any that cannot be carried over are named. Blobby says it will take a
file dragged over it. The app registers as an alternate viewer of any file,
so it is never what opens a file by default.
- **Gestures on the phone** (#2097): swipe a waiting approval right to approve
it or left to reject it, and pull a page down to read it again - in the phone
app and in AgenticOS installed to a touch screen - with a haptic tap when
letting go would act and when it has.
- **The apps work without a network** (#2097). The desktop and phone apps,
and AgenticOS added to a home screen, keep the conversation list, the 20
conversations opened last and the approvals queue on the device for seven
days, sealed with a key no script can read out and deleted on sign-out or a
switch of organization; a plain browser tab keeps nothing. Without a network
(or a server) the console shows that copy under a banner saying when it was
saved, and stays signed in. A message written offline waits above the
composer marked "Waiting for the network", survives closing the app, and
sends when the connection returns; one the server refuses comes back marked
"Not sent" with the reason, to send again or remove. The newest 20 files of
each kept conversation, up to 5 MB each, are kept too, so a photo in a thread
shows and an attachment opens without a network. The service worker now
also keeps the console's code, so the Android app and an installed PWA open
without a network (the iOS and macOS web views do not run it).
- **Notifications while the Android app is closed** (#2097), through ntfy
rather than Google's servers: Settings → Notifications in the app turns them
on with the ntfy app on the phone (against ntfy.sh or a company's own ntfy
server), sends a test, or turns them off. The server pushes to it as to a
browser; a push endpoint may now be any public https address, checked
against the deployment's SSRF policy when stored and at every send.
- **Push notifications in the browser** (#2097): Settings → Notifications turns
push on for this browser - or for AgenticOS added to a phone's home screen -
sends a test, and adds a Push column to the per-event choices, on by default
like email. Notifications arrive with AgenticOS closed. Nothing to configure:
the deployment's signing key is made on first use and kept in the vault.
`GET /api/v1/push/key`, `POST`/`DELETE /api/v1/push/subscriptions`,
`POST /api/v1/push/test`; migration `0172_web_push`; the console's CSP gains
`worker-src 'self'` for its service worker.
- **Native notifications** for new approvals, with Approve and Reject on the
notification, and for new inbox rows, plus a count on the Dock icon and
beside the tray icon.
- **The iPhone app** (#2097): the phone app now builds for iOS, with what an
iPhone draws outside the app. Live Activities show your running runs with a
clock and waiting approvals with Reject and Approve, on the lock screen and
in the Dynamic Island; a decision taken there waits for Face ID. Home- and
lock-screen widgets count approvals and runs, and a Pinned agents widget
opens a new chat with an agent pinned on its page (iOS lets no app place an
icon on the home screen). The app icon's long-press menu, Shortcuts, Siri,
the Action Button and Control Center start a voice call, dictation, a new
chat or the approvals. Share → AgenticOS takes text, links, photos and files
into a new message; the composer's Camera, Photos and Files open iOS's own
pickers, and opening the chat offers a photo taken a moment ago. Managed app
configuration (AppConfig) sets the same keys as on Android.
- **Notifications on an iPhone** (#2097), through Apple's push service with
the organization's own APNs key: an administrator adds the key file, its key
ID, the team ID and the app's bundle ID under Admin, Settings; it is sealed
in the vault and never shown again. Settings → Notifications in the iPhone
app turns push on, sends a test or turns it off, and a notification opens
its page through the app's lock. `GET`/`PUT`/`DELETE /api/v1/push/apns`
(setting it needs an app admin), `POST`/`DELETE /api/v1/push/apns/devices`;
`POST /api/v1/push/test` now reaches iPhones too; migration `0173_apns`.
- **Work on this computer** (#2305): in the desktop app a chat's settings
offer "Work on: Cloud / This computer". The person picks a folder in the
native dialog and how far a run may go there - read only, write in the
folder (sandboxed by Seatbelt on macOS and bubblewrap on Linux) or full
access, which asks before each command - and the agent's file and shell
tools work in it through the app, which refuses any folder or mode the
person did not grant. The choice is remembered per conversation. Link the
computer once under Settings → Desktop app; the tray says when an agent is
working there. A run waits up to ten minutes for the computer to connect,
saying so in the chat, and an operation that finds it gone mid-run waits up
to five minutes for it to come back.
- **Triggers that work on your computer** (#2305): a trigger that acts as its
creator can name a folder on their computer (`local_target`); each fire
works there through the desktop app. Only the creator sets it, and turning
acting-as-creator off clears it.
- **Computer use on your own screen** (#2305): the desktop `local` - and
`auto`, now the default - drives the person's own screen in a chat working on
this computer. The app asks before the first screenshot, frames the screen
while the agent holds it, and gives it back on Cmd/Ctrl+Alt+Esc. macOS asks
for Screen Recording and Accessibility.
- **Watch and take over a desktop** (#2305): every desktop a run works is
published to the live view a browse uses, so the chat and the console offer
Take over; the agent waits while the person holds it and is told to look
again after.
- **E2B** (#2305): a sandbox connection can be of kind `e2b`, on the
organization's own E2B key - never the process's `E2B_API_KEY` - with its
default runtime naming an E2B template. Computer use's desktop `e2b` opens an
E2B desktop of the run's own on the binding's key and kills it after; `auto`
takes it when a key is named.
- **More on the phone** (#2097): live activities for a voice call (with its
clock, and when the agent asks something on it) and for a question an agent
is waiting on; a pinned-agents widget on Android; the share of the monthly
cap left on both glance widgets; the dashboard's spend, failures and recent
conversations in the offline copy; pages that slide in the direction of
travel. The Devices list says which sign-ins receive push. In a browser that
can install the console, a strip offers to (on an iPhone it says how).
### Changed
- **Workflows and Tables follow the console's shared panel layout.** Catalog search stays visible while secondary filters fold away. Workflow creation separates triggers from templates, settings group advanced controls, and run history precedes live statistics. Step forms leave more room for parameters and disclose expected outputs on demand. Table, List and Kanban share one workspace; Kanban uses a unique grouping column automatically. Record forms and filters adapt to phones, record panels use shared focus handling, and failed catalog or record requests offer retry.
- Replace card Details sections with concise metadata and edit dates; move skill and context deletion into the editor menu beside Share.
- Order conversation agents by latest use, with full-size overlapping avatars and hidden older participants in the collapsed chat rail.
- **Breaking:** Remove the skill-level `enabled` switch and API field. Bound skills are available regardless of their former switch; remove unwanted bindings and publish affected agents before upgrading. Migration `0180_remove_skill_enabled` drops the retired state; downgrade restores all skills as enabled.
- Separate shared project uploads from personal Desktop folders, retain the selected Computer view, and brief agents, Architect and MCP clients on Desktop, Mobile and selected local execution resources.
- Simplify console headers, settings explanations, catalog filters and resource cards with progressive disclosure; add navigation icons and budget portraits, open desktop readiness from the account menu, and refine generated and starter-agent faces.
- Browser model requests omit obsolete element tables while retaining article
text and full stored results. DOM actions use the independent preview stream
with one final capture; readiness ignores unrelated background changes and
retries an initially empty document once. MCP tool catalogs stay unchanged.
- Browser panels open beside wide chats, resize by pointer or keyboard, and
expand to full screen without reopening their native tab. Narrow chats and
phones keep a full-screen view.
- Remote browser previews coalesce pending images and disconnect stalled viewers;
live-view images are no longer duplicated in the resumable chat stream.
- **Interactive browser navigation.** While holding a browser, edit its address,
move back or forward and reload within the agent's allowed domains. Direct
browser tools keep the preview streaming between calls. Input no longer waits
for a screenshot after every character, and navigation avoids duplicate fixed
pauses and URL-change timeouts when reopening the same address. Large-screen
resize requests stay within server limits so the first frame is not delayed.
- **Styles in the account menu.** Appearance now offers Standard, Glass, Graphite,
Midnight and Paper beside Light, Dark and System, with previews and the active
style on the trigger. Settings use larger previews and a selection tick;
Graphite, Midnight and Paper have softer surface borders in both color modes.
- **Desktop shortcuts in native menus.** Open AgenticOS has a configurable global
shortcut (`CmdOrCtrl+Shift+O`), and its menu entry, Quick Ask and Screenshot to
New Chat show their active bindings, including changes made in Settings.
- **Clearer desktop work location controls.** Cloud and This computer share a
segmented selector; folder access has a labelled dropdown and explanation,
followed by a full-width folder picker.
- **Switch servers from the console sidebar.** Change server opens the native
connection form directly, including when the sidebar is collapsed.
- **Link a desktop from the chat.** Choosing This computer under Work on now
offers native pairing and folder selection without a detour through Settings.
- **A more comfortable console on desktop and phone.** Search is labelled above
navigation, touch controls are larger, table headings and form feedback are
easier to read, and dashboard figures adapt to the widget's width. Dialogs fit
above the on-screen keyboard, side panels trap and restore focus, and Escape
clears a list search before dismissing its panel. Menus and notifications stay
within the available screen height. Streaming text and page/card entrances use
shorter motion without per-word blur.
### Fixed
- Reveal Quick Ask tab close buttons on hover or keyboard focus, keeping touch controls available and tab widths stable.
- Show uploaded organization avatars and chosen-color initials in the administration directory.
- Keep list pagination at the panel bottom and scroll paged administration table rows independently of headers and footer.
- Explain why Approve everything is unavailable and link authorized users to organization approval settings.
- Chat fills the desktop content area without the empty top strip; its list
header can drag the window. Browser and workspace choices appear before
Permissions, with conversation notifications kept below them.
- Skills and Context show agent usage and portraits directly on their cards.
Stronger foreground text, form labels and action contrast keep the console
readable, including over glass surfaces. Native and browser chat layouts share
their top inset so the conversation header is no longer clipped on desktop.
- Desktop project drops now reach the console instead of being consumed by the
native window. File rows target their containing folder; empty pane space
accepts root uploads and moves. Drop feedback no longer covers the file tree.
- Opening the agent picker no longer gives its first row a clipped focus outline;
keyboard navigation retains a visible inset indicator.
- Reduce the desktop heading gap while retaining a separate native drag strip. Keep file drag feedback within the project, preserve folder highlights across child rows, support uploading directly into folders and hover-to-expand, stabilize file actions, remove folder counters, and use distinct file-type icons across projects, chat, RAG and skill/context files.
- Refine console control spacing, keyboard focus, touch targets and anchored overlay motion; preserve action labels during saving, keep skill creation busy through uploads, localize calendar labels, and expose form requirements and progress values to assistive technology.
- Restore document previews and visible Add to an agent actions on Skills and Context cards; spread automatic avatar colors across a continuous clean hue range and preserve archived portrait colors.
- Desktop startup keeps the system theme and Glass defaults through hydration,
without briefly sending the server-rendered standard look to the native window.
- Desktop server switching lives in the account dropdown instead of a separate
sidebar button, including when the sidebar is collapsed.
- Local instance creation has its own compact, grouped setup step with one action
bar. Cancelling restores the instance overview; Blobby stays out of setup screens.
- Quick Ask renders the whole conversation, tool activity, approvals and queued
messages instead of only the last answer. Add stopping, attachment/source
previews and scrolling that lets the person read earlier turns.
- Automatic desktop attachment snapshots no longer ask to run an internal shell command.
- Preserve desktop sessions through temporary backend failures and window restarts
with a shared persistent console profile. Retry session checks on reconnect or
focus; revoked tokens still require sign-in. Keep private agent tabs isolated
and use app-scoped session cookie names when redeeming a pairing code.
- Reserve macOS window controls in the sign-in header and give Glass's drag strip
the same background as its content. Smooth desktop keyboard scrolling and mouse
wheel notches while respecting reduced motion and native trackpad input.
- Offer optional Screen Recording and Accessibility permissions in the initial
connection wizard, before choosing a server. Each is requested explicitly and
can be skipped; setup captures nothing and does not control the computer.
- Browser transcript cards no longer duplicate after clicks, rereads or returning
to a page. Each answer keeps one updated card per actual browser tab, live
and after reopening the conversation.
- **Notifications on phones.** Both bell controls open a full-width bottom sheet
with a visible close button and a scrollable inbox, keeping notifications
inside the screen when opened from the navigation drawer.
- Align mobile project actions, group secondary folder actions in More and collapse agent discovery filters behind a selection-preserving control. Give app preview toolbars consistent vertical padding and touch targets, contain Activity CSV exports, and keep Skills/Context actions clear of card content.
- Keep large chat file listings inside their own scrollable panel, with the title and close button visible and long filenames contained.
- **Readable computer-use environments.** The capability picker uses short
names for Automatic, E2B, Docker / Sandbox, Local and Remote computer, with
localized requirements below the current selection instead of paragraphs
inside the dropdown. Existing agent settings retain their meaning.
- **Activity controls stay still while opening a run.** Anchoring the transcript
scrolls only its own panel, keeping the close button in place on desktop and
phones instead of shifting the page during a click.
- **Recover from stalled phone connections.** An initial server load or native
sign-in return that has not completed after 30 seconds returns to the server
form with its saved address. Successful cached offline pages remain open;
completed or superseded attempts cancel their recovery wait.
- **Native sharing on phones.** The share inbox and attachment picker now use
separate native dispatchers, so opening the picker cannot replace the command
that receives content shared from another app.
- **Phone controls and keyboard layout.** Chat, agent cards, dashboard controls,
settings, avatar colors and sort chips have larger touch targets. Copy and tip
actions remain visible without hover. Sign-in fits system insets and the
keyboard, without a browser cookie banner in native apps. Viewport updates
coalesce per frame and undo late iOS page pans after keyboard animations.
- **Keep a native folder selection when chat settings close.** Pairing and folder
approval now finish for the original chat even if the settings panel closes
while a native dialog is open, instead of dropping the choice and using Cloud.
- **Native controls above opened apps.** The macOS app viewer reserves a title-bar
row, keeping the traffic lights clear of the back button and app title while
leaving browser viewers edge to edge.
- **Clickable desktop page actions and panel controls.** The window drag area
now has its own row outside the scrolling content, so it cannot cover New agent,
close buttons, tabs or other controls near the top of the window. The web
assistant stays at the desktop console’s edge instead of covering card actions.
- **Start a fresh chat from Blobby.** New Chat in the desktop menus and the
Blobby button now reset the active conversation, even while `/chat` is open.
- **Honor the chat's local workspace selection.** Choosing This computer opens
the native folder picker immediately. The access selector reflects the approved
mode, and local settings follow a new conversation even with its settings closed.
- **Keep the desktop running when switching servers.** Blobby and Quick ask now
navigate their existing windows to the selected server instead of destroying
and immediately recreating native windows.
- **One language across desktop windows.** Blobby and quick ask follow the
signed-in account on launch and when the console language changes.
- Push subscriptions linked to a device session stop receiving deliveries when
that session is revoked, expired or belongs to a different account.
- **Changing a sandbox's runtime opens a new workspace.** A container's image
is chosen when it is created, and the workspace's key did not include the
runtime, so an agent moved to another runtime kept attaching to its old
container. The key includes the runtime now. Naming no runtime and naming
`workbench`, the shipped default, keep the key they had. A workspace already
open on any other runtime starts empty once after the upgrade; the old one
stays listed and readable.
- **The Android app shows the AgenticOS icon**, not Tauri's default: the
generated launcher icons had never been copied into the Android project.
- **The desktop app opens on the console, not on the sign-in form.** It
opened the server's root, which sends everybody to the form, so a person
with a perfectly good session was asked to sign in on every launch.
- **A tool whose arguments are models can be held for approval.** The gate
stored the validated arguments as they were, so a call carrying a Pydantic
model failed to park with a serialization error instead of asking. They
are stored as JSON now.
- **A tool call's stored result no longer holds a picture's bytes.** A tool
that answered with an image, such as `web_fetch` on a picture, was
recorded as the image's Python representation, bytes and all, in the run's
history and the chat's tool row. The row says which kind of picture it
was instead.
## [1.30.0] - 2026-10-30
### Added
- A new agent starts on the organization's model when the organization has
exactly one model an agent can run on: a chat model with a key, or a
self-hosted one saved without a key, that publish accepts (#2483). This
applies to **New agent**, `POST /agents` without a `model_profile_id`,
templates, copies and promoted specialists. The model is written into the
draft, so the agent publishes without opening **Model**, and the draft counts
as using the model. With no model or several, the draft has no model as
before. A model on a ChatGPT sign-in is never chosen for somebody, and
neither is a model that falls back to one; the Architect no longer chooses
either for its first publish (#2545). See
[The model a new agent starts on](docs/models.md#the-model-a-new-agent-starts-on).
### Changed
- Publish's refusal of an agent with no model now reads *No model selected -
pick one under Build > Model before publishing* and also marks
`model_profile_id` in `details.fields` (#2483). The Builder shows **Go to
Model** beside it, which opens the Model card on the Build tab.
### Fixed
- Architect highlighting follows locale-cookie redirects and skips controls
hidden by a responsive stylesheet.
- Deleting a knowledge base detaches its selected sync sources instead of silently
moving them into a same-named base. Queued syncs recheck their assignment;
CLI ingestion refuses names reserved for a pending collection drop.
- Interrupted attachments remain eligible after a completed turn without a
workspace or without using its sandbox. Only a turn that reaches attachment
setup in its workspace closes their restoration window.
- Clearing a shared default knowledge base also removes chunks committed before
their tracking rows settle, including unfiled CLI ingestion. Stale writes
after the clear are rejected before table creation, without affecting uploads
started afterwards.
- The Architect, the organization's assistant, is no longer published on a
model that runs on a ChatGPT sign-in (#2535). A sign-in is one person's
subscription: on the Architect, runs by members who could not see it in the
vault were refused, and runs by those who could, such as the organization's
owners and admins, spent it. The Architect now publishes on the first chat
model publish accepts that is not a sign-in, and with only a sign-in it waits
for another model, as a new agent does (#2483). A sign-in somebody picked in
its draft, or a model that falls back to one (#2545), stays there, but is
published only when somebody who may change the organization's settings
publishes it in the Builder. An Architect already published on a sign-in is
not changed: such a person moves it under **Build > Model** and publishes it.
See
[The model a new agent starts on](docs/models.md#the-model-a-new-agent-starts-on).
- Knowledge bases that share a collection name and a vector tenant keep their
chunks apart. An app-scoped base and a personal base outside any organization,
or an organization's base and a member's personal base in it, no longer return,
count, replace or delete each other's chunks: every chunk records the knowledge
base it was ingested for, and every vector read and write is confined to the
base. An agent searches the bases it is bound to rather than whichever base of
that name resolves first; an agent bound to two bases that share a name
searches both without reaching unbound same-named bases. Resolving a collection name for an organization
with no base of its own falls back only to an app-scoped base, never to a
personal base outside any organization. A sync source writes into the
organization's oldest base of its collection name, as before; pointing one at
a collection now needs write access to that base, and adding one to another
base of the same name is refused. Deleting a base whose collection name another
base still holds - directly, by an organization purge or by an account deletion -
now also removes the chunks filed under it from the shared table, in the same
cleanup job that unlinks its files (#2537).
**Upgrade action:** migration `0180_stamp_rag_rows_by_base` files existing
chunks under their knowledge base from `rag_documents` and indexes the new key
on every `rag_<collection>` table. It rewrites every tracked chunk once, all in
one transaction, so on large deployments plan a maintenance window, keep free
disk for about the combined size of the `rag_<collection>` tables and their
indexes, and run `VACUUM ANALYZE` on them afterwards. A chunk it cannot
attribute to exactly one base - untracked, or tracked under no base or under
several - stays matched by its tenant as before, so a same-named app-scoped
base and personal base outside any organization still share those chunks.
`SELECT count(*) FROM rag_<collection> WHERE metadata->>'knowledge_base_id' IS
NULL` finds them; delete the documents they belong to and upload them again.
Where an organization has two bases of one name, a sync source shows and runs
only under the older one, which is where its documents have always been
written, and the newer base no longer finds that synced content in search.
Create the newer base under a name of its own to give it sources of its own.
- When the Architect points at a control on a tab that is not open, the tab now
switches and the control is highlighted. This includes a control that the
page keeps hidden in the document while its tab is closed: the Approvals,
Runs and Spend tabs on the Activity page and every tab on the organization
page. A link to another page no longer switches a tab on the page being left,
a tab switch leaves keyboard focus in the Architect's panel, and the scroll
respects a reduced-motion preference (#2536).
- A file attached to a chat turn that stopped before completing (failed,
cancelled, or stopped by a budget or the loop guard) is now written back to
`uploads/` by the same agent's next turn for that person in that
conversation, instead of staying missing until a new conversation and upload.
Only the person's own files are restored, until that agent completes a later
turn for them that looked for them. Files of a turn a guardrail blocked are
not restored, and on an agent with an input guardrail each file is screened
first: a file the guardrail refuses is not written back.
- An agent with `allow_dynamic` no longer fails for a caller who may not use some
ChatGPT sign-in in the organization - every API-key and widget run, and members
it is not shared with. A model the caller may not use is left off the
specialist's list of models with a warning, as a model with no key already was
(#2546).
- An upload or a sync still indexing a file for a knowledge base that is deleted
while another base keeps its collection name no longer writes chunks after the
cleanup job has removed the base's chunks. The write checks that the base
exists under a row lock that conflicts with the delete's, in the transaction
that inserts the chunks; the file fails at the index step, an upload is not
retried, and a connector sync continues with its other files. A local directory
sync queued for a base deleted before it runs now
ends with an error instead of writing its files into the deployment-wide
scope (#2561).
- A file attached to a turn that the input guardrail blocks is no longer written
to the agent's workspace. The input edge now screens the message and each
file's opening lines before the file is copied to `uploads/`, so a later turn
in a `conversation`-, `user`- or `agent`-scoped workspace cannot open it. The
blocked turn still ends as `guardrail_blocked`. A picture sent inline is still
written when the edge blocks the turn because of the picture's bytes (#2559).
- Dropping a collection (`DELETE /api/v1/rag/collections/{name}`) deletes only the
document rows and stored files of the knowledge base it resolved to. Before, it
deleted every document row under the collection name, with no organization or
base predicate, so a drop also removed the documents of another organization
whose base shared the name and queued their files for deletion. When another
base still holds the name, the shared vector table stays and the cleanup job
now removes the dropped base's chunks from it. A default base keeps its row and
takes uploads again, so the job removes only the chunks of the documents the
drop deleted; chunks with no document row are not removed from it. Document
rows filed under no base, from before documents recorded their base, go with
the drop too, with their files and chunks, when they are the dropped base's
organization's and no other base of that organization holds the name. Before,
a cleared default base kept listing and serving them (#2560).
- Deleting a knowledge base (`DELETE /api/v1/kb/{id}`) while another base still
holds its collection name deletes the unfiled document rows of its organization
too, with their files and chunks, unless another base of that organization holds
the name. Before, they stayed, and the organization's next base on the name
listed and served them again (#2560).
- `rag-drop` goes through the knowledge-base teardown. Before, it dropped the
vector table directly, with no reference check, lock or reservation, and left
the document rows behind, so it could destroy a table another knowledge base,
possibly another organization's, still used. It now clears the knowledge base
that holds the name, or drops a name no base holds with its document rows, and
a worker removes the table and the files after the command commits. A name
several knowledge bases hold is refused with their ids; pass
`--knowledge-base <id>` to clear one of them, and the table stays for the
others (#2560).
### Security
- Publishing or promoting a parent checks pinned delegates' reviewer, browser
step and follow-up sign-ins, even at the delegation depth bound and without
dynamic specialists.
- Publishing an agent on somebody else's ChatGPT sign-in is refused. Publish,
rollback, the Builder's draft check and promoting a version to an environment
now refuse a model a run can reach - the agent's own, a reviewer's, an inline
specialist's, the one an enabled web browser or follow-ups capability runs
on, a pinned delegate's and what that delegate reaches in turn, or one of the
first three fallbacks of any of them - when it runs on a ChatGPT sign-in the
person doing it cannot see in the vault. The refusal names the model field,
or the pin. Before, a builder could publish on a colleague's private sign-in,
directly or by pinning a delegate on it, and its owner's and the admins' runs
then spent that subscription. The rule is the one runs already follow: the
sign-in's owner, owners and admins, and anybody it was shared with may, and
an API key may not, whatever its issuer can see. Agents already published on
such a sign-in keep running, but republishing, rolling back to or promoting
that version now takes somebody who can see it (#2546).
- A specialist the model invents under `allow_dynamic` no longer runs on
somebody's ChatGPT sign-in the agent never named. Its list of models leaves out
a profile on a sign-in, and one whose first three fallbacks reach one, unless
the agent's spec names that exact profile. Before, the list offered every chat
model in the organization, so a run by the sign-in's owner, an owner or an
admin could spend that person's subscription on an agent nobody chose it for
(#2546).
- A run resumed after an approval resolves its delegates' and specialists'
models for the person whose run it is, as it already did for the agent's own
model. Before, they were resolved for the approver, so a resumed run could
spend the approver's ChatGPT sign-in, or lose its owner's (#2546).
- A link in an agent's answer that looks like a console page can no longer send
the console tab to another site. A path such as `/a/..//evil.example`
normalises to `//evil.example`, and the console opened that in place as if it
were one of its own pages. Such a link is now an ordinary link and stays on
the console. Answers can be shaped by content the agent reads, so this was a
phishing route.
## [1.29.2] - 2026-10-30
### Fixed
- Upgrade the sandbox client and `sandboxd` image together to 0.2.39. Runtime
images using `run_as_uid` now build on Debian and Ubuntu Python installations
without `ensurepip`; the library's built-in Node runtimes use Node 24 and
build with current npm packages.
## [1.29.1] - 2026-10-30
### Fixed
- Deliver model-generated photos on Mattermost, Slack, Teams and Telegram,
including after channel approval; report missing or invalid media instead of
silently posting only a success message. Ordinary workspace files still need
an explicit send action. Only media recorded as generated by the run can be
attached; a renamed MCP tool cannot forge that provenance.
- Preserve original timestamps and authors in channel thread context so old
relative-time requests are not presented as current events. Existing threads
refresh text context once on the next turn after migration, without
downloading their earlier files again.
## [1.29.0] - 2026-10-29
### Added
- Automatic channel context and conversation guidance across Mattermost, Slack,
Teams and Telegram: channel details, a bounded member snapshot, deployment
identity and precise organization versus personal MCP connection instructions.
Metadata is lower-trust conversation data, outside system instructions.
`{channel_members}` is the roster placeholder; `{member_list}` stays an alias.
Slack rosters use member IDs without per-person profile requests.
- An opt-in group mention switch per bot. Existing bots default to direct
invocations; Teams packages request conversation-message consent only when
enabled. Telegram text aliases require message delivery and its bot identity
is resolved before deciding whether a group message addresses it.
- Explicit `send_channel_file` actions on channel bot bindings. Grant the tool
per binding to let users request a workspace file; creating or editing a file
no longer posts it automatically. Existing bindings require enabling the new
action. The tool requires approval and reports platform failures.
- A separate production `browser` profile with proxy-only public web access.
Keep the isolated visual renderer for drawing; configure interactive browsing
with `BROWSER_SIGN_IN_CDP_URL=http://browser:9222`,
`BROWSER_EGRESS_PROXY=http://browser-egress:3128` and allowed CDP hosts for both.
Point each agent's browser capability at `http://browser:9222` and republish.
### Changed
- All MCP calls in chat apps now require explicit approval, including reads
through personal, organization and platform connections. Linking an account does not authorize publishing its private results
into a conversation. This applies to resumed and delegated calls too.
### Fixed
- Slack roster entries use native user references without profile fan-out;
Telegram bot identity refreshes within five minutes after a username change.
Capped Teams rosters report an unknown count rather than an exact 500.
- Channel history tools default to recent messages of the current channel and
support an explicit thread scope; automatic context backfill stays thread-only.
- Channel pictures render at twice the CSS resolution and reflow very wide
horizontal Mermaid flowcharts for readable PNG labels.
- Account connection instructions use plain `link` in a direct message, avoiding
native slash-command conflicts. Earlier thread files that require linking are
reported and retried after connection, rather than treated as absent forever.
- Chromium network failures no longer appear as domain allowlist refusals.
Production browsing also receives the configured browser locale and time zone.
- Approved channel file actions restore the original bot, channel and workspace
on resume, with current credentials and without borrowing the approver's account.
Exports apply workspace secret rules and check file size before reading bytes.
Attachment-attempt limits survive approval continuations.
- Teams generated pictures fit its inline image dimensions and payload limit.
Unsupported image formats and larger explicit files require personal-chat
file consent instead of being reported as delivered inline.
## [1.28.1] - 2026-10-28
### Fixed
- Channel visuals no longer disappear silently when their PNG cannot be rendered.
Replies name the missing attachment, and drawing tools no longer claim delivery
without confirmation. Published backend images include the rendering client;
production deployments can run the isolated `visual-render` service with
`VISUAL_RENDER_CDP_URL=http://visual-render:9222` and
`BROWSER_CDP_ALLOWED_HOSTS=["visual-render"]`.
## [1.28.0] - 2026-10-28
### Added
- More OpenRouter embedding models for knowledge bases: the three its EU
endpoint serves (`mistralai/mistral-embed-2312`,
`mistralai/codestral-embed-2505`, `google/gemini-embedding-2`) and
`google/gemini-embedding-001`. The Mistral models are not in the bundled price
snapshot, so their spend is recorded as partially priced.
### Fixed
- A knowledge base on a custom OpenRouter endpoint is offered only the
embedding models that endpoint serves. The EU endpoint serves none of
OpenAI's, so a collection created on the default model failed every upload
with "No endpoints found supporting your data region". Creating a collection
on a model its endpoint does not serve, or moving one to such an endpoint, is
now refused, and the editor says so before saving.
- An upload that fails because the embedding endpoint does not serve the model
says so, instead of pointing at the collection's key.
- Model pickers sort versions as numbers and keep a variant such as
OpenRouter's `:batch` beside its model. Plain string order put
`openai/gpt-5:batch` below every `gpt-5.6` model.
## [1.27.0] - 2026-10-27
### Added
- Show the running console build version in the sidebar footer, including the
collapsed rail and mobile navigation.
- Projects can choose a sandbox connection or stored files when created. Settings
show the connection used by their shared workspace and explain sharing and code
execution. Existing projects can transfer files between connections or stored
files through a verified background copy, with progress and write protection.
- Project file management: rename folders and files, move entries by drag and drop
or a folder picker, and edit UTF-8 text with revision and unsaved-change checks.
- Create separate model profiles for the same provider and model on different
endpoints, with automatic endpoint labels and an explicit choice to update the
shared profile instead.
- Configure custom OpenRouter endpoints for agent models and knowledge-base
embeddings, including the regional EU API. Native OpenRouter keys and cache
controls are retained. Model suggestions come from the chosen endpoint;
regional listing failures never fall back to the global catalog. Apply the
database migration for the optional embedding endpoint when upgrading. Upgrade
all API and worker processes before configuring regional endpoints; older
processes ignore the override.
- Set Context file mode and availability separately for each agent in the
Builder. Shared library editors keep content and descriptions; existing
agent versions retain their prior usage until an override is published.
- Let verified Mattermost participants rate answers and leave comments without
an AgenticOS account. Votes from unlinked participants use their channel identity; linking an
account merges its votes with web ratings so each person has one vote per
answer. Shared buttons stay available after the first vote. **API change:** a rating's
`user_id` can now be null for a channel participant. Apply the database migration
when upgrading; downgrading removes channel-authored votes.
### Changed
- Explain the sandbox’s POSIX shell, shared `/workspace` directory and per-command
process lifetime to agents, preventing Bash-only directory creation and writes
outside the shared project.
- Refine empty states, metadata badges and mobile settings across the console.
Knowledge search offers a clear starting point and permission-aware creation;
narrow integration panels keep their controls visible. Approval history uses
a compact queue status, member actions fit small screens, and urgent Inbox
badges remain legible in dark mode. Password-reset failures stay retryable
instead of claiming an email was sent.
- Keep chat model changes collapsed behind the current model summary. File-row
actions reveal on hover or keyboard focus without cutting filenames; long
project files scroll inside their preview. Inbox finding titles link to
their source and actions sit beside each finding.
- Prevent delayed conversation refreshes and failed read requests from restoring
already-read badges.
- Keep dashboard checklist loading in a stable slot. Resource lists fill the
page height; Routines drops the separate ideas panel. Chat keeps its animated
Files toggle visible, prefills model settings, enlarges agent portraits and
simplifies attachment cards.
- Refine console headers, neutral action buttons and sidebar glyphs. Skills and
context galleries use compact, consistently sized cards without nested panels.
People use photos or initials; organizations keep round, cropped avatars.
Local server controls show Ollama and LlamaIndex marks in both themes.
- Separate agent routines from personal connection watches in two Routines tabs.
Lead dashboard discovery with illustrated capabilities, show bucket values on
summary chart hover, and simplify project and agent widgets.
- Unify dashboard list rows, status indicators, shared-resource counts and
loading states across the widget catalog. Summary columns follow card width
in custom layouts. Briefing failures now offer Retry instead of appearing empty.
### Fixed
- Include the installed AgenticOS version in deployment, worker and per-agent
Logfire traces so production incidents can be matched to their release.
- Invalid metadata in agent-written skills no longer breaks turn completion.
Proposal writes use a savepoint and preserve the run’s status and spend (#2516).
- Changing a knowledge base embedding endpoint now requires access to its retained
vault key, including when resetting the endpoint to the provider default.
- Marking a chat as read preserves its initial conversation fetch, so the chosen
agent and a turn still running remain visible when reopening it.
- Ignore empty channel prompts after removing the bot mention, while preserving
attachment-only messages, so Anthropic does not reject an empty turn as prefill.
- Bound custom model catalog downloads, parsed fields and cached endpoints to
prevent an untrusted gateway from exhausting API process memory.
## [1.26.0] - 2026-10-27
### Added
- Change a model's key, endpoint, API, settings or name in place with
`PATCH /providers/model-profiles/{id}` (#2478). The profile keeps its id, so
every agent on it uses the change from its next run, with no republish. The
Builder's model panel saves a key, endpoint or API change on the model in use
as this edit, under **Update model**, and says that every agent on the model
switches with it. **Add model** stays for another provider or model. The edit
is gated on `connections:manage`, which therefore moves every agent on the
model. A new key, or a new endpoint for the stored key, must be a key the
caller can see in the organization's vault for the profile's provider. The
edit is audited as `model_profile.updated` with the changed field names only.
See
[Changing a profile's key or endpoint](docs/models.md#changing-a-profiles-key-or-endpoint).
### Changed
- Deleting a model profile that agents use is refused with `409 IN_USE`
(#2478). `details.agents` names each agent the caller can see and marks the
archived ones, and `details.hidden_agents` counts the rest. A profile counts as in use when an
agent's draft, served version or an environment's pinned version names it
anywhere as a JSON value, including reviewers, specialists and capability
settings, and archived agents count too. The check and the delete hold off
concurrent draft saves, publishes and promotions in the organization. The Builder
shows the refusal with the agent names. **Upgrade action:** a script that
deletes profiles must move the agents on them first, or edit the profile
instead.
- A model profile whose key was deleted from the vault is listed with
`missing_key: true` (#2478). Agent and chat model pickers no longer offer it,
the Builder marks it **no key** and says how to fix it, and publish refuses it
by name, and refuses a profile whose first three fallbacks include one. A
profile saved with no key on purpose (a self-hosted model, a gateway that
authenticates nothing) records that as `runs_without_key` and is not affected;
a gateway profile that had a key and lost it now reads as missing one. The
migration `0175_profile_runs_without_key` marks every existing keyless profile
with an endpoint as running without a key, so nothing that resolves today
stops.
- Creating a model profile now also requires that the caller can see its key in
the vault, the same rule as a capability's secret (#2478).
### Fixed
- The Builder's Endpoint field no longer shows the local example
`http://localhost:11434/v1` for a model that has a key (#2478). OpenAI is
marked `keyless` because OpenAI-compatible servers exist, and the field showed
the Ollama example as grey placeholder text, which read as an endpoint filled
in after a key was switched. The example now shows only when the endpoint is
required. A self-hosted model is no longer badged **no key** either.
- Document how to pin or roll back a release by hand without pairing its
backend with another release's sandbox service (#2484). The `sandboxd` image
is pinned in the compose file, so a host that sets `AGENTICOS_VERSION` by hand
checks out that release's tag as well; `scripts/deploy.sh` already does. An
install without a checkout, from `scripts/quickstart.sh`, downloads that
release's `docker-compose.yml` beside the pin.
- An API key added from the coding agent's card for Codex is stored as an
OpenAI key, so the Builder no longer offers it to Claude Code after a harness
switch, where it published and then failed at run time (#2485). Keys added for
Claude Code, or behind a gateway, are still stored as custom.
- An app-scoped collection and an organization's knowledge base with the same
name keep their documents apart. Through the app collection, members of
other organizations could list the organization's documents
(`GET /rag/documents`) and download, read or delete them (`/rag/documents/{id}`
and `/kb/{kb_id}/documents/{doc_id}`). The organization's sync sources were
also reachable through the app base's `/kb/{kb_id}/sync-sources/{source_id}`
routes. Those documents also counted toward the app collection in
`GET /rag/collections/{name}/info`, where they could hold `indexing_status`
at `indexing`. A document filed under the app base now belongs to the app
collection, whichever organization uploaded it. The organization's listing
and counts leave it out. The same held for a personal knowledge base outside
any organization that shares its name with an app collection: every member
of every organization could list and download its owner's documents through
the app collection. A document now belongs to the knowledge base it is filed
under, in listings, counts and per-document checks (#2486).
`GET /kb` counted documents by collection name, so each base reported the
other's `document_count`, `indexed_count` and `chunk_count`; each base now
counts its own. `GET /kb/{kb_id}/sync-sources` and `GET /rag/sync/logs`
listed a private base's sync sources and runs to a member who reads only the
app base of the same name, and `DELETE /rag/sync/{sync_id}` let a writer of
one base cancel a run feeding the other. A sync source and its runs now
belong to the base its sync writes under. A run with no sync source is still
matched by its collection name.
## [1.25.0] - 2026-10-27
### Changed
- Upgrade the backend dependency snapshot, including Pydantic AI 2.61 and
harness 0.61, and adapt tool retries, streamed errors and cache reminders to
the new message parts (#2476). The Thinking capability also exposes the SDK’s
new `max` effort level. Existing retry histories and checkpoints still
load without a database migration or republishing agents. **Upgrade action:**
drain or stop the old API and workers before starting the upgraded processes;
do not mix versions. Once a history contains the new retry parts, a code-only
rollback to the previous SDK cannot read it. See the
[retry-history upgrade boundary](docs/deploy.md#retry-history-upgrade).
## [1.24.0] - 2026-10-27
### Added
- Organization proactivity uses the Agent Builder's provider, model and vault-key
picker, including inline model-profile creation for members with
`connections:manage`. Budget managers can select existing profiles, and saving
the organization applies the choice to nightly suggestions and MCP watches.
## [1.23.0] - 2026-10-27
### Added
- `GET /agents/ceiling`, for a caller with `agents:edit`: the deployment's
agents-per-organization limit (`limit`, null for none) and whether a create
would hit it (`at_limit`). The organization's count against it (`held`) is
given only to a caller whose `agents:view` reaches every agent, since it
includes agents others cannot see (#2488).
- `GET /kb/{kb_id}/ingestion` says whether one knowledge base's documents are
still indexing, with `processing_count`, `indexed_count` and `failed_count`,
counted over the documents its page lists. It is part of the public API
(#2486).
### Fixed
- The coding agent's key picker offers only keys for the chosen harness - Anthropic
for Claude Code, OpenAI keys and ChatGPT sign-ins for Codex - plus `custom` keys
and the one already bound, and publish refuses a key stored for another
provider, naming the ones the harness takes. Claude Code behind `base_url` still
takes any key, the gateway's. Republishing an agent refused here means its key
was going to the wrong vendor and failing every task; rebind it, or store it as
`custom` if it is right. A capability can now map a config field's values to
the purposes its key may have (#2485). The picker respects endpoint defaults,
preserves sign-ins accepted by other capabilities and marks a retained key
that no longer fits after a harness change.
- Knowledge citations name a page only for sources that have pages, such as PDF,
presentations and paginated office formats. Markdown, text, `.docx`, HTML,
spreadsheets and images name only the document; a stored structural page 1 or
a header-like code comment is not a location. The rule applies when results
are shown, so existing collections need no re-ingestion. Knowledge search in
the console follows the same rule (#2489).
- Say an organization is at its agent limit before a create is attempted. At
the limit the Agents page disables **New agent** and template installs with
the reason, instead of refusing the create after the dialog is filled in, and
onboarding no longer offers to guide a create there. The server-side refusal
is unchanged (#2488).
- Keep known realtime voice, text-to-speech, transcription, image, video and
embedding models out of agent and chat model pickers. Profiles and provider
suggestions report `chat_capable`; saved profiles also update when a provider
listing arrives later. Publish, rollback, draft checks and test runs reject
incompatible primary, reviewer, specialist and capability models, including
the first three fallbacks the runner can use. Runs reject incompatible
conversation overrides before starting, skip incompatible fallbacks and avoid
inventing specialists on them. Architect chooses a chat model. Provider
aliases share their vendor's classifications; unknown models and custom
endpoints remain allowed. Stored specs still load; a version on an incompatible
model must be corrected before republishing or restoring it (#2487).
- Report a collection as `indexing` on `GET /rag/collections/{name}/info` while
any of its documents is still queued or being ingested, and `complete` only
once none is. The response adds `processing_count`, `indexed_count` and
`failed_count`; a failed document is counted there rather than holding the
collection at `indexing`. The knowledge base page shows its own state from
`GET /kb/{kb_id}/ingestion` and keeps refreshing until the whole batch has
settled (#2486).
- Pin `sandboxd` to `ghcr.io/vstorm-co/sandboxd:0.2.37`, the version of the
backend's `pydantic-ai-backend` client, in every compose file. A cached
`sandboxd:0.2` older than the client answered every command with a 404 that the
platform reported as a lost session. A sandbox service that does not serve a
route the client needs now fails the tool call with a version mismatch that
names the image to run, including legacy conflicts when attaching saved session
references. The conversation reopens its session by name on the next turn.
`agenticos cmd doctor` checks each sandbox connection's routes. To
upgrade, redeploy with `scripts/deploy.sh` or `make dev`, which pull the pinned
tag. `make prod` does not start the `sandbox` profile, so on a stack started
with it, pull and recreate `sandboxd` with `--profile sandbox` (#2484).
## [1.22.0] - 2026-10-26
### Added
- Architect recommends Projects for continuing research, writing, coding and
analysis, with a complete LLM wiki workflow for sources, linked notes, an index,
updates and verification. Platform MCP can find, inspect and create private
projects through the caller's existing permissions and approval flow. Architect runtime
guidance reaches existing installations without replacing customized instructions
or changing other agents and external MCP clients.
## [1.21.0] - 2026-10-26
### Added
- Independent light and dark controls in signed-in and public app viewers.
Start app frames with a light preference instead of inheriting the console
theme; preserve authored colors, page state and stored versions.
## [1.20.1] - 2026-10-26
### Fixed
- Explain why existing private provider keys or ChatGPT sign-ins cannot be
selected for organization speech to text, instead of implying the vault
has no credentials for the provider. Show provider icons and consistent masked
key hints in Voice calls and Dictation key selectors.
## [1.20.0] - 2026-10-26
### Added
- Organize organization settings into permission-aware tabs, with shareable
tab URLs and form drafts preserved when switching sections.
## [1.19.0] - 2026-10-26
### Changed
- Generate follow-up buttons only with an explicitly selected separate model,
after the answer is saved. Suggestions no longer block turn completion or the
next prompt; late results attach to their original answer. Channel buttons
are generated after the main reply is posted. Auxiliary requests retain
budget checks, privacy settings and independent cost accounting.
**Upgrade:** select **Model for next steps** in the Follow-ups capability to
enable suggestions. An empty profile now disables them; the main agent no
longer receives `suggest_next_steps`.
## [1.18.1] - 2026-10-26
### Fixed
- Show proactive runs with their own icon and filter in Activity and Dashboard.
Record their model requests, tool results and final answer for inspection,
and explain the fixed AgenticOS attribution beside organization settings.
## [1.18.0] - 2026-10-26
### Fixed
- A loop whose item fails, with parallel legs in its body, no longer starts the next
iteration while the legs of the failed one are still running: `collect` lets them
finish and `stop` cancels them. (#1800)
- Send a message answers inside the bound thread on Slack and Mattermost and in the
forum topic on Telegram, instead of at the top level; a channel or thread id the
platform cannot address fails with `CHANNEL_TARGET_INVALID` before sending. (#1800)
- The public form marks each answer the server refused (`details.problems` entries
carry `type`) and says when the form changed, could not be read, or was too long.
(#1800)
- The editor accepts a merge of an error-routing step's branches, as publish does;
the merge copy no longer speaks of an If only. (#1800)
- Renaming a Switch rule, classifier category, error branch, Split branch or approval
choice carries its wires, bindings, template references and quick log in one undoable
edit; a log alert on the old name is flagged. (#1800)
- Send a message added after a Channel message trigger starts as the trigger's bot
with `channel_id` and `thread_id` bound when the platforms match. (#1800)
- Google Workspace and Microsoft 365 tools are grouped by app (Calendar, Drive, Docs,
Sheets; Outlook Calendar, OneDrive, Excel); sign-in tools are not offered. (#1800)
- The `mcp.call` reference lists every failure code. (#1800)
- A branch, rule, category or choice named `error` on a step that routes its errors is
now refused, naming the clash and asking for another name, in the editor and at
publish; a saved workflow that already has one needs the rename before it
publishes again. The other clashes - `in`, `other`, `default`, `approved`,
`rejected`, `otherwise`, and `unsure` with a minimum confidence - were already
refused and now get the clearer message, on the entry. A `logic.merge` can also
take two ports of one branching step wired straight into it, such as
`ai.classify`'s `needs_reply` and `unsure`, which publish read as two edges from
one branch; it runs once, for the port taken. Two edges from the same port stay
refused.
- A `logic.merge` can rejoin `ai.classify`'s branches - `unsure` with a category,
or two categories - where publish refused it, although the step always leaves by
exactly one port. A node now declares `exclusive_branches` when it registers,
the node catalog carries it, and bot