| Version | Tag | Date | Notes |
|---|---|---|---|
| 2026.9.5 | v2026.9.5 | 2026-09-05 | A contributor-fix release: fourteen community PRs, one new pricing surface. Direct provider endpoints stop falling through to the _DEFAULT_PRICING placeholder — bare ids like deepseek-chat and date-stamped snapshots like claude-3-7-sonnet-20250219 failed the startswith prefix scan and were billed at $3.00/$15.00 per 1M tokens, up to a 21x error on a cheap model; native DeepSeek, Anthropic, Gemini and OpenAI rates now land with their prompt-cache read discounts, scoped to direct endpoints so aggregator routing and the static baseline are untouched (#842). Concurrency is the theme underneath: SessionStorage serializes every committing method on the shared SQLite connection and rolls back on exception or cancellation, where two coroutines could interleave inside one multi-statement transaction (#891); JobStore.transaction() rolls back on any BaseException instead of leaving uncommitted writes for a later caller to commit, with a task-bound reentrant lock serializing the scheduler's writers (#964); SessionWriteLock finally evicts, having retained one asyncio.Lock per session key for the life of the process (#966); and TaskRuntime keeps a session's routing envelope while it still has queued work, so a follow-up send no longer loses channel, account, recipient and thread (#930). Auto Pilot cascades across router tiers on a model timeout rather than retrying the same dead endpoint for six minutes (#860), the Discord adapter stops cancelling itself mid-reconnect from inside its own heartbeat task (#882), and the session FTS sanitizer keeps non-ASCII letters — café and 中文 searched for nothing while the transcripts were indexed correctly all along (#903). Rounding out: list_dir survives a dangling symlink (#844), agentos cost --export creates missing parent directories (#846), the gateway debounce buffer caps at 50 coalesced messages per session (#796), named artifact delivery falls back to a valid filename leaf instead of handing send_file a directory (#742), and robinhood-chain-stocks withholds price and holding value for a contract uiMultiplier() already disproved, rather than decorating a proven impersonator with the real company's live feed (#866). On the security side, code_exec gains an AST layer over its regex fast path: getattr(os, "rem" + "ove"), __import__("os").remove, exec/eval of a destructive string, wildcard and aliased imports all reached the host filesystem without passing the approval gate (#848). |
| 2026.9.4 | v2026.9.4 | 2026-09-04 | A contributor-fix release: seventeen community PRs, no new surface. The agentos config set path stops lying twice over — skills.config.<skill>.<key> now actually persists (the map was omitted from to_toml_dict() for rollback-compat, so the documented command could never create it), and the no---config env hint stops printing a fabricated AGENTOS_GATEWAY_ export and exiting 0 for keys that have no env binding. load_entries no longer dies on the first malformed line of the append-only decisions JSONL, taking cost-savings reports, session export and pipeline replay down with it; skips are counted and logged so a partial report says so. An MCP client disconnecting no longer unregisters a colliding tool another live client owns, background_process caps retained output at 1M characters while still draining the pipe, provider credit exhaustion classifies as INSUFFICIENT_CREDITS instead of tripping the circuit breaker on a billing fault, CLI JSON survives a non-UTF-8 terminal, memory-write refresh callbacks reach the running turn, and apply_patch records UpdateFile writes so patched files reach auto-publish. On the security side: invisible Unicode is normalised before intent-phrase matching, closing a prompt-injection bypass that a single soft hyphen opened; per-IP rate limiting now covers the Control UI api/* subtree it had been exempting wholesale; send_file checks size against each service's real ceiling before reading; search results carry provider origin; and the Robinhood chain skill rejects a file:// RPC URL. |
| 2026.9.3 | v2026.9.3 | 2026-09-03 | A rendering-and-hardening release. Skill output becomes a first-class artifact: exec_command now honours a publish_artifact path=… mime=application/vnd.agentos.<x>+json marker on a command's own output, so a skill that writes a chart or card payload gets it rendered without the model deciding to publish it — the decision the model routinely did not make, leaving the payload stranded in the workspace while the answer came back as a hand-written markdown table. Only the application/vnd.agentos. family auto-publishes, the marker must own its line, at most four publish per command, and workspace containment is unchanged. Alongside it, the Web chat gains inline card grids (application/vnd.agentos.cards+json): a responsive grid of record cards with a colour-coded status badge and per-field copy buttons, for the shape a markdown table handles badly — a 42-character contract address forces a table into horizontal scroll, while a card gives it its own line next to a copy button. Every payload string reaches the DOM through textContent and logo is restricted to http(s), because card fields carry attacker-controlled on-chain metadata; the subject mark is a locally drawn ticker monogram rather than a CDN logo, since the console CSP blocks those and fetching them would tell the CDN which tickers a user is researching. robinhood-rwa-addresses also stops trusting the token index: every genuine Stock Token is a proxy pointing at Robinhood's shared EIP-1967 beacon, so one batched JSON-RPC round-trip now settles each match as verified, not-deployed, not-a-stock-token or unverified — 47 of the 238 addresses the skill previously reported as verified have no contract deployed at all, and funds sent to one would be unrecoverable (#745 follow-up). Four security fixes land: the strict SSRF fetch guard enforces the cloud-metadata floor directly instead of inferring it from the private/link-local ranges, which let Alibaba Cloud's 100.100.100.200 (CGNAT space) through the strict guard while the permissive one blocked it, returning instance RAM role credentials into the transcript; the MCP SSE and Streamable HTTP transports connect through the same connect-time SSRF guard as the built-in HTTP tools, closing an MCP server entry pointed at 169.254.169.254 (#662); Slack webhooks now fail closed when no signing secret is configured, where event_callback payloads were ingested and slash commands enqueued from any unauthenticated POST (#674); and Slack signatures are verified over the raw request bytes rather than a UTF-8 decode/encode round-trip (#680). The destructive-intent hard block also covers the filesystem root — rm -rf / carries no sensitive prefix, so it fell through to the ordinary approval flow that /elevated bypass skips (#563). Correctness fixes round it out: cron schedules restricting both day-of-month and day-of-week follow the POSIX OR rule instead of ANDing them, restoring parity with the web UI's own preview (#660); channel HTTP retries cover every transient TimeoutException, survive an HTTP-date Retry-After, and hand back an exhausted rate limit instead of raising (#642, #599), with Telegram's own retry path matched (#651); MemorySyncManager re-enqueues a file whose indexing failed instead of losing it until the next edit (#638); email replies keep the thread root when only In-Reply-To is present (#620) and IMAP folder names containing spaces are quoted per RFC 3501 (#618); the agentos_queue_depth gauge decrements on task removal (#668); SubscriptionManager drops empty subscriber sets (#609); provider content-moderation blocks classify as POLICY_REFUSAL again (#629); OtlpTraceSink.flush() acquires the lock it always declared (#672); agentos sessions export sanitizes its default filename through _safe_archive_part (#678); the image tool names a redirect that carries no Location header (#616); the Environment view's path strip shortens Windows paths again (#590); and HTTP chat errors name the OpenAI-compatible provider that actually failed. |
| 2026.9.2 | v2026.9.2 | 2026-09-02 | A marketplace-routing and hardening release. Surplus Intelligence (surplus) joins as a runtime provider — a two-sided marketplace that routes each request to the cheapest healthy seller, configured like any other OpenAI-compatible provider with a buyer key (SURPLUS_API_KEY) against https://api.surplusintelligence.ai/v1, with the x402/USDC and MPP per-request payment protocols deliberately left unwired so nothing crypto-related enters the dependency tree. Because marketplace prices move with seller competition, its cost estimates come from the live public catalog (OpenRouter-shaped, USD per token, with a supported_features array) instead of a static table, refreshed on a TTL with a bounded negative cache; AGENTOS_SURPLUS_LIVE_PRICING=0 pins them. It ships its own router tier profile, because the OpenRouter tier table's namespaced ids are not what this marketplace serves. Alongside it, agentos cost savings finally reads back the SavingsTelemetry every turn has been writing to ~/.agentos/logs/decisions-*.jsonl — a summary and per-route breakdown with --json, --csv, date filters and a branded one-page --pdf, read straight off the decision log so it works with the gateway stopped, and honest about the number: only input tokens are priced and the comparison is against the most expensive configured tier, so the figure is a floor (#788). Four security fixes land: trusted-proxy auth now validates the real transport peer instead of testing whether the client-supplied X-Forwarded-For contained the proxy string, which let any peer spoof its way to full Control RPC access, with the check unified into one helper across the auth middleware, the rate limiter and the RPC layer (#568); cron webhook URLs go through the same cloud-metadata floor http_request uses, on create, update and delivery, closing a path that POSTed model output and tool results to AWS/GCP/Azure IMDS (#574); web_fetch streams its body against a hard 1 MiB ceiling rather than buffering an unbounded response into memory before the display cap runs (#502); and the exec approval cache tokenizes every rm in a compound command, where re.search used to stop at the first and let rm A; rm -rf / past the intent scan entirely (#512, #676). GET /api/approvals also loses its rate-limit exemption, moving into a dedicated per-IP bucket (AGENTOS_RATE_APPROVALS_MAX_REQUESTS, default 300/window) sized for the Web UI's 1.5s poll (#569), and the proxy names — AGENTOS_LLM_PROXY, HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY, AGENTOS_TRUST_ENV — join the env write denylist in any casing, so an agent can no longer route every model request through a proxy it picked and read the Authorization header off it (#550). Provider base_url values from onboarding.provider.configure are validated before reaching httpx (#551), and the SSRF guard's DNS-rebinding TOCTOU is closed by a validating network backend that connects to the address it checked (#516). Correctness fixes round it out: Gemini (#657) and Anthropic (#613) context-overflow errors classify as CONTEXT_OVERFLOW and take the compact-and-retry path instead of surfacing as bad requests; the email channel checks Reply-To against the sender allowlist and resolves recipients for agent-initiated sends (#598); OpenCAP's router tiers track its own catalog rather than a copy of Bankr's, with glm-5.3 on c2, five newly published models declared in the registry, and thinking_level reaching the wire for GLM ids; two GMGN wallet skills and robinhood-chain-stocks join the bundled set, and robinhood-rwa-addresses stops answering a company question with a community token that impersonates it (#745). |
| 2026.9.1 | v2026.9.1 | 2026-09-01 | A projects-and-observability release. Chat projects get concurrency-safe editing and a live UI: projects.update now writes only the fields passed (a rename holding a stale row no longer reverts a concurrent knowledge save), the Web UI sends the updatedAt it last read so a lost race returns a project.conflict error with the draft kept instead of clobbering, same-millisecond writes get distinct updated_at values, and a unique index on project names (V012) backstops the duplicate-name check under concurrent creates; the Projects page also listens to the gateway's projects.changed / sessions.changed broadcasts, so another client's create, rename, delete or session move shows up without pressing Refresh, and its loading and error states no longer masquerade as the "No projects yet" empty state. The projects_* agent tools are now scoped to the calling session — projects_list used to hand the model every project's knowledge text, projects_update accepted any project_id, and projects_move_session accepted arbitrary session keys, so one prompt-injected instruction in any member session could read all knowledge and overwrite another project's, text that then runs inside the system prompt of every member session of that project, every turn; cross-project management stays on the Web UI / CLI / RPC control plane. Project knowledge is also capped at 24,000 characters on write, matching the per-turn injection ceiling, instead of saving fine and then being silently truncated out of every turn. On the operability side, long-running gateways gain a Prometheus GET /metrics endpoint backed by thread-safe multi-dimensional counters, gauges and histograms wired to TaskRuntime, an OtlpTraceSink that exports TraceEvent records to any OpenTelemetry collector over HTTP/JSON, and a log-retention sweeper that prunes ~/.agentos/logs/** by TTL age and total disk budget (#367). Four security fixes land alongside: gateway token auth compares secrets with hmac.compare_digest through a shared fail-closed token_matches helper across all four token gates instead of short-circuiting == (#498); the sensitive-payload egress guard now percent-decodes and inspects URL userinfo, which httpx turns into an Authorization: Basic header on the wire, closing a credential-exfiltration path through http_request, web_fetch (every redirect hop) and the media image tool (#499); http_request streams its response and stops at a hard byte ceiling, so a chunked body with no (or a lying) content-length can no longer exhaust process memory before the 1 MB model-facing limit is applied (#508); and scheduler timeout_seconds is bounded to 1 second–24 hours on cron create and update, where <= 0 previously ran the handler with no wait at all and a huge value held a model turn open for years (#570). Correctness fixes round it out: router metadata no longer advertises a model the provider never ran — an explicit config.agents[].model, session pin or per-call override beats the Pilot Router's pick, so the decision is now demoted (routing_applied=false, tier kept as advice) and per-turn savings are priced from the model that actually ran (#586); the opencap and bankr provider kinds send the required x-api-key header; Gemini reasoning models keep their thought_signature across the turn loop, session sanitization and history deserialization, so tool calls stop failing with HTTP 400 (#519); and agentos upgrade kills the whole process tree on Windows with taskkill /T /F /PID rather than orphaning grandchildren that hold locks on the virtualenv (#536). |
| 2026.8.29 | v2026.8.29 | 2026-08-29 | An email-channel and hardening release. A mailbox is now a first-class channel (type = "email"): inbound over IMAP polling, outbound over SMTP with In-Reply-To/References so replies stay in the originating mail thread, and no platform app registration — just IMAP/SMTP credentials. One mail thread is one session, quoted history is stripped before the text reaches the model, HTML-only mail is flattened to text, and inbound attachments plus generated artifacts ride the shared attachment pipeline under the usual size limits. Access is a required fail-closed allowed_senders From-address allowlist (exact addresses or *@domain patterns); mail from the agent's own address and anything marked auto-generated (Auto-Submitted, X-Autoreply, List-Id, Precedence: bulk) is dropped so an autoresponder cannot start a mail loop (#369). Alongside it, a DM-shaped channel whose surface is itself threaded can now opt into one session per thread with metadata['dm_thread_scoped']; adapters that do not set it keep one session per peer, so Slack, Discord and Telegram DM keys are unchanged. On the security side, the git tools (git_status, git_diff, git_log, git_commit) now mask credentials at the single _run_git chokepoint before output reaches the model — a .env committed once used to keep reaching the model in cleartext through git_diff while read_file and grep_search already redacted — and the assignment redaction pass now anchors across diff markers, so +MY_SECRET=… is masked where previously only the vendor-prefixed shapes were caught. Finally, Slack sends and scheduler webhook deliveries survive a transient network blip: both now route through the same retry_request helper Discord uses (exponential backoff with jitter on 429 honouring Retry-After, on 500/502/503/504, connect errors and read timeouts), while fatal statuses such as 400/401 still fail on the first attempt (#469, #496). The Web UI also gains a browsable /memory view — curated-memory editor, knowledge-base document table, raw source explorer and semantic search — backed by multi-format document ingestion (PDF, DOCX, PPTX, Markdown, text, CSV, JSON/YAML, code) over <workspace>/knowledge_base/, memory.curated.* / memory.knowledge_base.* JSON-RPC methods and agentos memory ingest / agentos memory curated (#368). Two more memory-exhaustion holes are closed by streaming with a hard cap: the image tool's URL fetch (#506) and the GitHub skill-hub blob download, now bounded per blob and in total, failing closed rather than installing a truncated bundle (#510); execute_code output also runs through the same redaction shell.py already applied (#490). Correctness fixes round it out: past one-shot AT schedules are refused (#486), next_due_at accounts for backoff_until so a backing-off cron stops busy-spinning SQLite, MCP stdio reads with readexactly, Telegram entity offsets are sliced on the UTF-16 grid (#537), an exhausted provider failover chain raises a clear error (#488), Discord keeps dispatching after a reconnect, cancelling xAI sign-in stops its poll loop, and a genuine nested workspace/ folder is no longer stripped from a path (#538). |
| 2026.8.28 | v2026.8.28 | 2026-08-28 | A projects-and-scheduler release. Chat sessions can now be grouped into projects, and a project sits above agents rather than inside one: sessions of any agent can join the same project, with the project's agent field acting only as the default for "New chat in project". Each project carries a free-form knowledge text that is injected into the system prompt of every member session as an untrusted-wrapped Project Knowledge block, re-read each turn, so editing a project's knowledge lands on the very next turn of every session in it — no restart and no new session. The feature surfaces wherever a session does: a new Projects page in the Web UI (create, rename, edit knowledge, delete, "New chat in project", per-project session list), a project badge plus filter and "Move to project" on the Sessions page, moving the current session between projects from the chat header, project tiers in the chat session switcher, an agentos projects CLI group (list/create/show/update/delete/move), projects.* JSON-RPC methods with projectId on sessions.create/sessions.patch/sessions.list, and agent-facing projects_* tools with session_search scope=project for searching sibling transcripts. Existing databases migrate automatically (V011); old sessions come up project-less, and deleting a project detaches its sessions instead of deleting them (#495). Scheduler fixes bring the cron parser back in line with cron as it is written: day-of-week 7 is Sunday again (#478), a reversed range in a stepped field is refused up front instead of firing at surprise times (#480), month and day-of-week names are case-insensitive (#482), and the timezone alias on a legacy expression schedule is honored rather than silently falling back (#485). |
| 2026.8.27 | v2026.8.27 | 2026-08-27 | A budgets-and-hardening release. Spend budgets land as a new [budgets] config section that sets money ceilings per session, per UTC day, per agent, and per channel: a turn that starts at or above a hard limit is refused before any provider call with a budget_exceeded error naming the scope and the number, a matching *_warn threshold raises a one-shot budget_warning without stopping the turn, and ceilings are re-checked between iterations within a turn as well, so a single turn with a long tool loop cannot run past one. Spend persists to ~/.agentos/state/spend_ledger.db, so a ceiling survives a gateway restart and a runaway overnight loop cannot be reset by a crash-and-respawn; nothing is enforced until an operator sets a number, and UsageTracker.check_warning() is removed in favour of it. aero-stock-lp joins the Bankr skill hub, range-LPing Coinbase tokenized equities (NVDA, AAPL, GOOGL, META) and AERO/USDC on Aerodrome Slipstream (Base) and routing each position to whichever side pays more at this epoch, staked for AERO emissions or unstaked for trading fees; the Bankr user-skill allowlist is now empty, with stock-premium-lp-manager retired in its favour. Security: installing a skill from ClawHub no longer unpacks the downloaded zip unbounded — the download is streamed against a size ceiling and the archive is refused past an entry count, a per-entry size, and a total uncompressed size, with a hostile archive failing closed as "no bundle" rather than aborting a whole lockfile sync (#357); and read_file, read_spreadsheet, grep_search, edit_file's closest-match hint, and terminal output now mask credentials before they reach the model and the persisted transcript, which the sensitive-path denylist could not do under elevated-full mode (#355). Fixes: the Control UI bootstrap endpoint no longer leaks the absolute config file path to any website the operator visits (#351); auth.mode = "password" no longer admits the gateway unauthenticated, with auth.mode validated at load time and the middleware failing closed on any mode without an enforcement branch (#352); agentos chat, sessions, skills, and env now send the resolved gateway token and honour AGENTOS_GATEWAY_URL; and credential masking no longer rewrites ordinary source code. Removed: the dead onboard_agent wizard, the canvas and nodes built-ins, and the no-op profile-visibility helpers (#362), plus the agentos dist inventory entries for tools that were never in the wheel. |
| 2026.8.24 | v2026.8.24 | 2026-08-24 | A channels-security-and-cost release. Channel tool approvals become native interactive surfaces — Telegram inline keyboards, Slack Block Kit actions, and Discord message components render an Approve/Deny pair for a gated tool call instead of asking the operator to type a reply — and every click is authorized before it is honoured: the clicker must pass the channel's own access policy and be an admitted paired user, the approval is bound to the sessionKey that raised it so a click from another session is refused, and the surface is offered only in DMs, where the session key is PER_CHANNEL_PEER and the approver is unambiguous; Slack request signatures are now verified against the raw request body rather than a parsed form, so verification no longer depends on the ASGI body having survived a read (closes #364). Cost visibility lands as a usage ledger that records the cost of each turn and attributes it per tool and per skill through a ContextVar that follows the call into nested execution, a new agentos cost command that queries it with filters for session, model, tool, skill, and time range plus export, and a router cost_aware flag (on by default) that substitutes the cheapest tier capable of the request with image-only tiers filtered out before the comparison, so a text request is never routed to an image model (closes #366). Aeon (aeonfun/aeon) joins Robinhood, Bankr, and Capminal as a Partner Skills source in the Skills hub, and cron_default_mode — the default elevation posture for unattended cron jobs, shipped in 2026.8.21 — is now documented where it is set and where it is read (#413). Security fixes: the gateway no longer accepts an auth token from the query string, where it would be captured by proxy and server access logs, and the uvicorn access log is gated behind config.debug for the same reason (#350); rate limiting reads X-Forwarded-For only from a verified trusted proxy and bounds the per-client dict, so a spoofed header can neither bypass the limiter nor grow it without limit (#354); unhandled gateway exceptions are redacted before they reach the client, with detail shown only under debug (#353); and the browser tool refuses data: URLs, which could otherwise carry a page past the SSRF check and the domain allowlist, leaving about:blank the only permitted hostless target (#356). Also fixed: the usage cost fallback path declines query filters it cannot honour instead of silently dropping them and returning an empty result set. Removed: dead configuration keys that no code read — sandbox.network_default (#360), the memory daily-note keys (#405), and subagents.archive_after_minutes (#407). |
| 2026.8.23 | v2026.8.23 | 2026-08-23 | A browser-and-reliability release. A browser built-in drives a real browser from the agent, backed by the agent-browser CLI (Vercel Labs, Apache-2.0): navigate, read a page as an accessibility snapshot with element refs, click, type, fill, wait, run JavaScript, answer native dialogs, and screenshot — managed and headless by default, with attach mode driving the operator's own browser when they opt in. Policy is enforced in AgentOS rather than delegated to the engine: SSRF checks on navigate and on the post-redirect URL plus a private-page guard on reads so a JavaScript redirect cannot leak an intranet page into a later snapshot, file: refused while data:/about: pass, eval SSRF-pre-scanned in both modes with an opt-in restrict_evaluate denylist and a post-eval page-URL recheck, type/fill refusing credential-shaped text, and every payload the engine returns — snapshots, eval results, tab titles and URLs — crossing into the transcript inside the untrusted envelope and through credential redaction; the engine subprocess starts from a minimal environment, never os.environ, so the gateway token and provider keys are unreachable from it, an optional allowed_domains bounds navigation, and the tool sits in group:web so denying web denies it. Provider failover is now health-aware: a circuit breaker counts consecutive provider-health failures (overload / gateway 5xx, transport errors, rate limits) per provider id and skips a tripped provider for a cooldown window (default 60s, doubling per consecutive trip) with one half-open probe per window to re-close it, because failover used to be purely reactive and per-request — every turn during an outage paid the full timeout on the dead primary since ModelSelector reset to the primary each turn; breaker state is shared across per-turn selector clones, request-shaped failures (unknown model, bad request, context overflow, auth, billing) never trip it, an all-cooldown chain still uses the primary, and the state shows in agentos providers status, agentos doctor, and GET /api/system/status. Chart artifacts in the Web UI download as a rendered screenshot image instead of a raw JSON link. Fixes: skill dependency installs work for every kind a skill can declare — three code paths each carried their own idea of what install.kind meant, so the seven bundled gmgn skills (kind: npm) were uninstallable through both executors, and all three now read one vocabulary and one command builder in agentos/skills/install_kinds.py (brew, npm, go, uv, download, apt, with node an alias for npm), with apt and download staying hint-only and saying so; and a pinned turn no longer shows another turn's router-fx strip, because the route_pinned path swept only live strips and a settled strip from an earlier turn lingered above the composer. |
| 2026.8.21 | v2026.8.21 | 2026-08-21 | A channels-and-automation release. Inbound Telegram voice messages, audio files and round video notes are now transcribed before the turn is built, so the speech-to-text output becomes the message text instead of the bare [voice] placeholder that used to reach the agent with the audio stripped — the ElevenLabs STT call was factored into a shared helper and wired into channel ingestion, with a 120-second duration limit (configurable via max_voice_duration_s) and a 30 MB size limit checked before the download, a reply to the sender when either limit is hit or STT fails, and the message still delivered under its placeholder rather than dropped; group mention detection also admits replies that target the bot by id or username. agentos skills init <name> scaffolds a local custom skill that passes the publish gate on the first try — clean frontmatter, a body over the 20-character validation, scripts/run.py and its entrypoint mapping under --with-script, names validated so they cannot walk out of the target directory, and an existing file overwritten only with --force. Scheduled agent turns are elevated by default, running in bypass mode rather than needing a per-job opt-in, because an unattended turn that stops for an approval nobody is there to give does nothing: the new global cron_default_mode holds the default, the router resolves effective elevation from the handler_key in the cron envelope, reminders and system events and script runs stay strictly unelevated with an explicit --no-elevated honoured rather than rejected, elevated warnings log whether elevation came from config or the job, and the effective value shows on Web UI job cards and in cron list. Web content the agent reads is now wrapped in the same <untrusted source='…'> envelope the prompt teaches: web_fetch's bespoke <external-content> tag was invisible to the dispatch layer, so a tool-call marker planted in a fetched page got zero enforcement and now trips the refusal path, while only nested markers are escaped so the page stays readable, and http_request wraps its text body and preview with the fetched URL as source. The system prompt drops the drifting CLI quick reference, folds Workspace into Runtime, and leads Reply Guidelines with the answer. Fixes: section headings no longer render glued to the section above them — a right-trimming {% endif -%} was swallowing the separating blank line in every full-mode prompt shipped so far. |
| 2026.8.19 | v2026.8.19 | 2026-08-19 | A skills-and-scheduling release, all of it about what actually reaches the model. A cron job's script path may now contain {job_id}, which the scheduler substitutes with the created job's own id before the job is persisted, and the cron add result reports the resolved path as script_path — a job that keeps its files in a directory named after itself used to require staging the script elsewhere, adding the job against the staging path, moving the file and repointing the job, four steps during which a live job points at a path it will not keep. One add now does it, for a script job and for an agent_turn job's pre-run script, from the tool, the CLI and the RPC surface alike; a stored path that somehow still holds the placeholder refuses to run rather than creating a directory called {job_id}. Skills can pin a section with <!-- always --> on the line above a heading, so skill_view returns it wherever it sits in the file: over the read ceiling skill_view returns a skill's opening plus an index of the rest, which meant position in the file decided what a model read, and a rule written into a large skill's tail was never seen — senior-unilp-manager is 44k characters against a 10k ceiling, and two merged fixes had written their rules past the cut. Pinned sections come out of the same ceiling rather than adding to it, and skill_view.outlined now logs a pinned count. The transcript layer was cutting harder than the read ceiling: every tool result was persisted truncated to its first 2,000 characters, so a skill body read on one turn came back on the next as an opening that stops mid-sentence, and 40 of the 50 bundled skills are larger than that. A tool may now declare the ceiling its own results are persisted under, resolved at persist time so it follows a config change, and skill_view sets one from [skills].max_skill_view_chars; a tool that declares nothing keeps the 2,000 characters that suit volatile output. The core system prompt was rewritten and gated by surface — parallel tool batches and a verify-with-tools bias in Tool Call Style, a new Task Execution block with an anti-stuck escape hatch and an approval-denial boundary, irreversible-action confirmation and the <untrusted> envelope convention in Safety — while Reply Tags, Messaging, Reactions and Silent Replies render only for gateways that have a channel adapter or can receive internal system events, saving roughly 257 tokens per full-mode session without churning the cacheable base prompt. senior-unilp-manager was rewritten against all of this: monitors default to a script cron job rather than a full model turn on every tick, every file a monitor needs lives under ~/.agentos/scripts/senior-unilp-manager/<cron_id>/ so deleting the job means deleting the directory, and the section carrying those rules is pinned. Fixes: copying an assistant message in web chat no longer prepends the collapsible reasoning block. |
| 2026.8.17 | v2026.8.17 | 2026-08-17 | A scheduling-and-sessions release. The in-agent cron tool can finally edit a job instead of replacing it: action="update" patches in place keeping the job id, action="get" returns the full record (kind, tz, schedule, session target, delivery, tool policy, wake mode, timeout, script fields), add takes a clone_from that inherits every setting of the source and overrides only what is passed, and a name parameter means a job's display name no longer has to be its prompt. Replacing a job used to reset every setting the re-create did not name — an agent_turn fell back to reminder, a job pinned to Asia/Bangkok moved to UTC, its tool policy was dropped, and its output started landing in the current chat. Jobs carrying a script or tool_policy.elevated stay operator-only to clone or update. Cron jobs can also name where they announce: both add and update take a delivery object — mode (origin, channel, none), channel_name, channel_id, account_id, thread_id, best_effort — so "every weekday at 9, post the digest to the ops group" no longer has to be created in the chat that will receive it, and moving an existing job's announcement is an edit that keeps the job's id, run history, ws_topic and failure destination rather than a rebuild. The destination is validated when the job is saved, not when it fires, so an unconfigured channel name or a destination paired with a mode that cannot route to it is refused with an error naming the problem instead of silently falling back to the calling chat. Sessions can be renamed from every surface: a sessions.rename RPC, agentos sessions rename <id> "<name>" (--clear drops it), /rename <name> in CLI chat and channels, click-to-edit in the Web UI session list, Rename session in the Chat header ⋯ menu, and a session_rename tool so "call this one X" works as a prompt. agentos sessions list grows a Name column and a --search/-q filter matching name, key, subject or model, and the session switcher lists renamed sessions by name and searches them that way. Names normalize in one place — whitespace collapses, control characters drop, 120-character cap, empty clears back to the derived title — and no migration is required. Fixes: rescheduling a one-shot job onto a recurring expression no longer leaves delete_after_run set, so the edited job stops deleting itself after its first fire; converting a job away from agent_turn drops a stranded tool_policy.elevated; and a tool_policy sent alongside a kind change is validated against the new kind rather than the outgoing one. |
| 2026.8.15 | v2026.8.15 | 2026-08-15 | A search-and-Web-UI release. A built-in Tavily provider joins the web_search backends as a runtime provider like brave and duckduckgo — not a skill-only engine — so selecting tavily and setting TAVILY_API_KEY is all it takes; onboarding offers it alongside the other keyed providers and the key is redacted like every other credential. The Web UI now shows a "new release available" banner, closing the gap with the CLI: an updates.check RPC reports the running version, the latest version on PyPI and an up-to-date / outdated / offline status, and the console renders the banner only on outdated. The check reuses the CLI's cached PyPI state under its own webui slot, so the browser adds no PyPI traffic beyond the existing interval, and it stays silent when AGENTOS_NO_UPDATE_NOTICE=1 is set or updates.notify is off. Gmail/GitHub-style navigation chords land too — press g, then a destination key within 1.5s, and every sidebar view is reachable from the keyboard. Fixes: the per-message hover toolbar (copy / regenerate / edit) could not be clicked, because it sits outside the box carrying the :hover state and the 8px gutter margin dropped the hover before the pointer arrived; a transparent bridge now makes the hit region continuous. And x_search could hand one attempt a timeout slightly larger than its whole budget on a coarse clock, where two monotonic() reads fall in the same tick and the arithmetic rounds up — the per-attempt timeout is now capped on the total budget as well. |
| 2026.8.13 | v2026.8.13 | 2026-08-13 | A crypto-skill release. A bundled poolsdotfun-token-launcher skill launches a token on pools.fun through the PartyFactory on Robinhood Chain (4663) and manages the creator fees on the PartyLocker afterwards. A launch is one irreversible transaction: it CREATE2-deploys a fixed-supply ERC20 with no owner and no mint function, opens a SushiSwap V3 pool at the 1% fee tier, and mints the entire supply as a single-sided full-range position whose LP NFT goes to the locker permanently — the launcher never holds it. The chain and RPC endpoint are built in, so there is nothing to configure beyond POOLSFUN_PRIVATE_KEY. Reading and signing are separate scripts: pools_read.py quotes cost, opening price and pool state, simulates a launch and mines a launch salt from only a --from address, while pools_write.py is the only script that can sign — and the launch plan is hashed, so the transaction that broadcasts is provably the one that was quoted. PINATA_JWT is optional and needed only to attach a token image; it is deliberately not declared as a requirement so a launch without a logo still works where Pinata was never configured. Fixes: the launcher now finds a logo the user attached in chat. Attachments arrive in two shapes — staged to disk under a sha256 name, or inlined as base64 in the transcript — and the skill previously looked only at the media directory, so an inlined image was missed and a stale disk blob could be uploaded in its place; a find-image read command now resolves the image from the transcript first, materializes it, and warns when the only candidate predates the request. |
| 2026.8.12 | v2026.8.12 | 2026-08-12 | A model-control and reasoning release. The chat composer carries a route picker: one searchable list holding Auto, the text tiers your [agentos_router] config actually defines — labelled with the model each resolves to — and every model of the active provider, with /use <model-id> doing the same from a slash command on web, TUI and channels. The pin is read back from the gateway over a new router.hold.get RPC rather than mirrored in the browser, so a reload shows the pin really in force and a pin set from /c3 agrees with one set from the picker; with no Pilot Router configured the control is disabled rather than hidden. A directly-named model rides on the default tier, inheriting the thinking level and pricing baseline that live on a tier and not on a model id, and only models the active provider publishes can be pinned, since every turn runs through the single configured llm.provider. Breaking: a user's tier pin is now sticky — /c0…/c3 hold until /auto clears them instead of lapsing after ten idle minutes, so pin /c3 and forget and every later turn keeps paying for c3; image turns and the large-context floor still behave as before. While a pin is in force the router-fx strip is suppressed and the model's own router_control tool is withdrawn along with its target menu, since the user's choice already outranked it inside the router step. The Web UI also shows the model thinking: reasoning arrives as a typed ThinkingDeltaEvent from the Anthropic, OpenAI-compatible and Ollama providers — including models that emit <think> tags inline, split back out of the text stream as it arrives — and renders as a live collapsible block that folds when reply text starts, opening a fresh block per reasoning round, with history carrying a has_thinking flag and control_ui.show_thinking gating the surface. It is web-only by construction, riding a CONTROL_ONLY chat.thinking RPC that channel adapters never receive. Fixes: a hub skill whose SKILL.md renames itself no longer renders under "Your local skills" without source, version or Remove/Update buttons — lockfile entries now join by the install path they record rather than the manifest name, and existing installs heal themselves with no migration; OpenCAP and Bankr routes no longer report supports_reasoning=False for every model, which had silently no-oped a tier's thinking_level. |
| 2026.8.11 | v2026.8.11 | 2026-08-11 | An X-search and internationalization release. A built-in x_search tool searches X (Twitter) through xAI's server-side search on the Responses API, returning a synthesized answer with citations rather than the ranked pages a web search provider returns, so it is its own tool and not a web_search backend; it joins group:web — denying that group cuts the route to api.x.ai — is allowed for cron agents alongside web_fetch/web_search because it is read-only, never pays its schema on a provider call when no xAI credential is present, bounds retries against both a per-attempt and a whole-call deadline, refuses a base_url that is not HTTPS or that resolves to a metadata endpoint, and bills xAI directly rather than appearing in agentos cost. SuperGrok and X Premium+ subscribers can sign in with xAI OAuth instead of pasting an API key — the only way to spend a subscription on x_search, since xAI sells API credit and subscriptions separately: agentos auth login xai runs the device-code flow, tokens land in ~/.agentos/auth.json at 0600 and refresh themselves under a lock because xAI's refresh tokens are single-use, discovery and inference origins are pinned to HTTPS on x.ai/*.x.ai on both the login and refresh paths, a 403 on refresh is reported as a tier gate rather than a re-login prompt, and OAuth is preferred over XAI_API_KEY with credential_source naming which one ran. The Setup page drives the same login without blocking over a split start/poll pair and offers sign-out once signed in, with the device code never crossing to the browser. Every Web UI view now resolves its copy through the i18n seam — the shell and all sixteen views read from per-namespace catalogs, an I18N_MIGRATED ESLint ledger guards each migrated file, t() must be called at render time because a module-scope call freezes the locale at boot, catalogs register per namespace so view copy stays out of the entry chunk, numeric placeholders format through Intl.NumberFormat, and malformed locale tags are rejected at registration; the visible language is unchanged. Translation turns are capped at the cheapest tier by a deterministic translate-verb detector across fourteen languages, replacing difficulty scoring that drifted a tier in either direction purely on the language the request was written in. Streaming channels show the typing indicator again while the model is still thinking: Telegram and Discord type until the first chunk lands and drop the indicator the moment it does. |
| 2026.8.9 | v2026.8.9 | 2026-08-09 | A channels-and-internals release. Telegram replies now stream: AgentOS posts one message and edits it as the answer arrives, instead of holding a typing indicator for the whole run and then dropping the finished answer in at once. Edits are throttled to Telegram's stricter rate limit, answers past 4096 characters roll over into a follow-up message, and a burst of 429s degrades to a single final send with the full text intact; Slack, Discord, Telegram and Microsoft Teams now declare the streaming capability so the manifest and the Channels page reflect what the adapters actually do. The seven bundled GMGN skills declare category: crypto and file under AgentOS Crypto Skills, each card and detail dialog wearing the GMGN mark badged with that skill's own emoji — chosen on provenance.origin behind the same shipped/bundled gate as the group, so a local drop-in cannot mint it, and shipped with the client, so no card fetches a remote image. Skill names are unchanged. A model's price, context window, max output and image support are now declared once in agentos.model_registry, with the pricing table, the catalog's window fallbacks and the router tier defaults derived from it rather than restating it; because both lookup tables failed open in opposite directions, a forgotten entry used to produce a plausible wrong number instead of an error, and shipping a tier default whose model is not declared now fails at import. No prices or windows change. Shell workspace lockdown no longer misses a redirection whose operator has no whitespace around it — echo x>/etc/passwd and cat<in>/etc/x used to parse as having no write target, and the tee parser had the same anchor bug; descriptor duplications are blanked before the scan so 2>&1 is not read as a write to a file named 1. |
| 2026.8.7 | v2026.8.7 | 2026-08-07 | A Web UI release. Token price charts render inline in chat: an artifact published as application/vnd.agentos.chart+json draws as an interactive candlestick chart in the transcript instead of a download chip, with a readout strip carrying the hovered candle's time, OHLC, volume, and close-against-open as a signed percentage at the payload's own precision. It rides the existing artifact seam, so history replay redraws it with no separate path; lightweight-charts loads dynamically and never enters a chat that has no chart; charts are keyed by host and swept on session switch and "load earlier" rather than stranding a canvas and a ResizeObserver per rebuild; a click on the canvas pans instead of downloading the JSON; and payload strings, which are attacker-controlled on-chain metadata, reach the DOM only through textContent. Both gmgn-market and gmgn-token carry the converter, since the skill loader has no skill-to-skill dependency mechanism and deferring to a sibling meant the chart silently never appeared. Keyboard handling became one registry with a ? overlay that lists every binding — components declare a shortcut instead of attaching their own document listener, dialogs register themselves as layers rather than being matched by a stale hardcoded selector list, combos match on both e.key and e.code, and the New chat tooltip renders the right keycaps per platform. Agent settings → Router Tiers now picks tier models from a catalog instead of free text: the provider is a read-only chip because requests always go through llm.provider, the model cell is a combobox over the union of the live models.list catalog and the shipped router profiles so neither an offline install nor an uncatalogued provider produces a false warning, the image tier is offered only vision-capable models, and save warns without ever blocking. Switching from a cloud LLM provider back to a local one no longer disables the router or leaves it pinned to the cloud provider's tier profile — onboarding now remembers a per-provider profile and restores it on return, while install-wide router settings stay global and credentials are never copied. Gateway boot and agentos doctor warn when the bundled Control UI is older than the frontend sources in a checkout, advisory only and never gating readiness. |
| 2026.8.6 | v2026.8.6 | 2026-08-06 | A cron release: schedules can now run scripts, and the run history is finally readable. --job-kind script makes the script the job — stdout delivered verbatim, empty stdout a silent tick, non-zero exit a failed job — while --job-kind agent_turn --script runs the script first as a collector and skips the turn entirely when it prints nothing or ends with {"wakeAgent": false}, before the session is touched. Scripts resolve inside ~/.agentos/scripts/ with no escape via absolute paths, ~, .., or symlinks, and are exec'd as argv. The new bundled cron-watchers skill ships the three watchers everyone writes first (RSS/Atom, JSON endpoint, GitHub repo). Around that, the surface that reports what a job did was rebuilt: run output is stored whole instead of clipped at 500 chars (agentos cron output, cron.runOutput, and lazy fetch in the Web UI), a script job's output no longer vanishes into delivery skips written for agent turns, the "→ Chat" button is hidden when no chat exists rather than leading to "Could not load chat history", and the session reaper stops missing expired sessions on a busy store because list_sessions() only returned the 100 most recent. A bad delivery target is refused at save time — a session key is not a Telegram chat id — with a dropdown of paired chats offered instead of free text, the failure reason lands on the run record, and structlog events (every delivery.* warning among them) finally reach debug.log. Cron's tool refusals reach the model as messages it can self-correct from instead of "received an invalid argument". /reset now clears the conversation on screen on both web and CLI. senior-unilp-manager gains create-pool for hook-less v4 pools — hooks pinned to address(0), dynamic fees refused, odd tiers gated, and the uncorrectable starting price printed three ways before confirm — plus tick --alert-only, which lets a healthy ratchet cron stay quiet without silencing NEEDS_ATTENTION. |
| 2026.8.5 | v2026.8.5 | 2026-08-05 | A cron-reliability and web-UI release. A cron job no longer fails forever once the chat it was created from is gone: the web UI stamps originSessionKey onto every reminder job while forcing its target to isolated, and "New Chat" mints a session key client-side with no row, so a reminder created before the first message pointed at a session that never existed — the fire-time mirror then raised KeyError: Session not found, surfaced as forward_failed, and failed the run with no best_effort checkbox rendered for the none delivery mode it ran under. The mirror is opportunistic now and reports a distinct origin_gone status; genuine channel delivery failures still fail the run. Unknown cron tool profiles are rejected at write time instead of dying ~50 ms into every firing until the scheduler auto-paused the job — normalize_tool_profile raises listing the profiles that exist, the read direction stays tolerant so already-broken rows can still be listed and deleted, and the tool schema now names the valid profiles. In the web UI, cron cards stop spilling over the neighbouring column (an unbreakable session key has no break opportunity per UAX-14, and three boxes between the grid track and the text could not shrink), and a job's ID — the handle every agentos cron … command takes — is finally visible, shortened with a copy button. The Skills page gains Use / Use in chat buttons that pre-fill the chat composer with use skill <name> instead of making the operator retype it. senior-unilp-manager can arm an unattended take-profit ratchet on a one-sided Uniswap v4 position: at milestones measured against the original principal it exits, keeps the converted side as realized profit, and redeploys the remainder into a narrower range in a single modifyLiquidities (DECREASE → BURN → MINT → TAKE_PAIR, no SETTLE), authorized by an object the CLI structurally cannot construct. One live mandate per position is now enforced by scan, since mandate_id hashes the label and two labels armed two mandates to burn the same NFT. The combined unlock has not been rehearsed against a hooked pool; SKILL.md requires a dust rehearsal first. |
| 2026.8.3 | v2026.8.3 | 2026-08-03 | A packaging, skills, and upgrade-path release. agentos upgrade now installs the published release instead of delegating to uv tool upgrade, which re-resolved uv's directory receipt on checkout-backed installs and re-packaged whatever static/dist/ was on disk — so Python moved forward while the web UI silently did not; installing a checkout stays with scripts/install_source.sh, the only path that rebuilds the bundle first. A pip install use-agent-os no longer resolves open-ended: bounds now cover the rest of the base runtime and the consumer-facing extras, each cap at the first release its upstream may break in — the next major for a >=1.0 project, the next minor for a 0.x one — recomputed from uv.lock by tests/test_packaging/test_pyproject_invariants.py so a new dependency cannot ship unbounded by accident (#153). Shipped Pilot Router tier defaults resolved against static tables with no entry for them and both tables fail open without logging, so glm-4.7-flashx estimated at a generic $3/$15 and seven ids — including anthropic/claude-opus-5 — sized turns against generic limits; every tier default now carries an explicit pricing and catalog entry (#139). OpenCAP cost estimates no longer fall back to Bankr's rate sheet for the life of a process after one failed boot fetch — the price cache refreshes on a TTL, and a static-table estimate is logged once per model. Seven GMGN trading skills ship bundled under the new Trading category, driving the third-party gmgn-cli that AgentOS does not redistribute. A hub install can no longer silently shadow a bundled skill, skill_search_community answers with an installed_match block naming what a local skill is missing, and skill_view(name="agentos", section="Skills") resolves. Durable memory redaction moves onto the shared scanner (forced, since AGENTOS_REDACT_SECRETS=0 is an egress-only escape hatch), which also learned the ASIA/ABIA/ACCA AWS prefixes and quoted Authorization/x-api-key headers. |
| 2026.8.2.post1 | v2026.8.2.post1 | 2026-08-02 | A packaging fix for the 2026.8.2 release. The wheel guard allowed markdown only at a bundled skill's SKILL.md plus two force-included pptx references, so senior-unilp-manager's assets/v4-reference.md read as a forbidden entry and the tagged Windows release job failed for v2026.8.2 after the tag was already pushed — while a wheel that did build shipped SKILL.md links pointing at a file stripped from disk. agentos/skills/bundled/<skill>/assets/** is now allowed (references/ and stray top-level markdown stay forbidden) and a real-tree test over the bundled skills fails PR CI instead of the tagged release job. Cron prompt safety no longer rejects Unicode combining marks — Vietnamese and other scripts that need them pass again, while genuinely invisible marks stay blocked. |
| 2026.8.2 | v2026.8.2 | 2026-08-02 | A harness-reliability and skills release. edit_file no longer fails on text that differs from the file only in formatting — it falls back through indentation, whitespace, escaped-newline, smart-quote and block-similarity strategies and names the one that matched, while still refusing ambiguous matches. The progress watchdog now catches repeated successful calls, not just failures, so an agent re-reading the same file stops looking like progress. A turn that edits code and answers "done" without running anything is noticed and warned, and the system prompt names the developer tools that actually exist on the machine ([prompt] env_probe_enabled). Side-task LLM calls (document analysis, image description) run through one accounted auxiliary client configured at [auxiliary], so their cost shows up in agentos cost. Streaming replies survive gateways that send choices/tool_calls as explicit null, MCP tool schemas are sanitized at discovery so one malformed tool cannot fail a whole request, and provider error bodies are bounded and summarised instead of flowing whole into context. New bundled skill senior-unilp-manager reads and manages Uniswap v4 liquidity on Base and Robinhood Chain over stdlib-only JSON-RPC with a two-process PLAN_HASH confirm gate — now binding every calldata-affecting flag — and can find and mint into hook-less pools. skill_view resolves {baseDir}, a cron job may opt in to running shell-based skills (#184), and the Skills page groups Partner / AgentOS Normal / AgentOS Crypto skills with clearer status buckets. |
| 2026.7.31 | v2026.7.31 | 2026-07-31 | A security release for skills that call authenticated APIs. The outbound guard matched credential-ish names, so http_request refused every Authorization header and exec_command refused {"sellToken": …} and grep "token: " — while a real key pasted inline passed through; the guard now matches credential values and leaves names alone, the shell check runs only on commands that can reach the network, and a skill declaring metadata.requires.env gets those names forwarded into the sandbox so the value never enters the transcript (#165, #167). Command output is scanned for credentials before it reaches the model, AGENTOS_GATEWAY_TOKEN no longer leaks into child processes, and http_request refuses cloud metadata endpoints. Router tier defaults move up a generation across all gateway profiles — C1 to gpt-5.6-luna, C3 to claude-opus-5, with claude-opus-5 registered for its 1M context window and real pricing (#169) — and the Pilot Router docs describe the C0–C3 tiers (#170). |
| 2026.7.30 | v2026.7.30 | 2026-07-30 | A skills release. The agent can now tell which of its installed skills applies to a request: the prompt budget shortens descriptions to the longest length that fits instead of dropping every description at a cliff, names-only mode points at skill_list rather than one skill_view per skill, the block moves into the cacheable system prompt, and cron turns get skill_view/skill_list (#159). skill_view on a skill that is not installed now says the lookup worked and offers skill_search_community instead of reading as a broken tool (#162), and a skill over the new [skills].max_skill_view_chars (default 10 000) returns its opening sections plus an index instead of every byte — 43% fewer characters across a real install, 80–87% on the largest (#163). Capminal Skills are browsable and installable as a partner source (#144), runtime dependencies carry upper bounds (#153), and the Web UI skill grid and Installed chip are fixed (#135, #161, #121). |
| 2026.7.29 | v2026.7.29 | 2026-07-29 | Bankr skills published from bankr.bot — the ones under an author's wallet address rather than in BankrBot/skills — can be browsed and installed like any other hub skill; the SKILL.md is synthesized from the inline JSON payload, the skill is credited to its author instead of inheriting Bankr's brand, and only allowlisted skills install through the Bankr source (#150). SECURITY.md states that audit reports belong in the private advisory form rather than a PR, that there is no bug bounty program, and that researchers are credited in the release notes of the fix (#154). |
| 2026.7.28 | v2026.7.28 | 2026-07-28 | Web UI polish: Cmd/Ctrl+Shift+O starts a new chat from anywhere in the console, with the platform-appropriate hint on the New Chat tooltip (#131); the settings screen is called Agent Setup everywhere — route title, sidebar, heading, browser tab, and docs (#125). |
| 2026.7.27 | v2026.7.27 | 2026-07-27 | Environment variables are managed from AgentOS instead of by hand-editing ~/.agentos/.env — an Environment screen, agentos env list|get|set|unset, env.* RPC, a Set <VAR> action in the Skills dialog, and detection of credentials that already exist such as gh auth (#122, #127, #129). Every surface now gives the same answer about a skill: whether it is offered, and which of six reasons explains why not; Installed cards group by provenance, skills carry allowlisted publishers, and skills.max_skills_prompt_chars defaults to 24000 with the filesystem path dropped from the skills block (#130, #132). Curated memory stops fabricating profile facts and the background review wakes as designed (#128). Removed: the session-flush subsystem and the memory.flush_* / memory.repair_* config keys (#124). |
| 2026.7.26 | v2026.7.26 | 2026-07-26 | Breaking: channel roles and scoped tokens replaced by Control/Channel pairing surfaces with durable Telegram pairing and grant revalidation (#104); curated-memory durability pass — atomic turn captures, Windows write locks, non-destructive MEMORY.md migration, surfaced unreadable files (#106–#114); periodic memory-review nudge at [memory.nudge] (#108); non-destructive /new and /reset when flush is unavailable (#102, #117); OpenCAP LLM gateway provider (#63); Slack/Discord/Telegram slash-command and interaction fixes (#93–#101); Dream consolidation and the memory repair service removed (#116, #118). |
| 2026.7.25 | v2026.7.25 | 2026-07-25 | React Control UI is now the only verified production interface with settings/configuration transaction safety and hardened CSP; retired channel adapters and legacy UI removed; frontend settings, Bankr icons, session reset, collapsed sidebar, CLI onboarding prompt, and default openai/gpt-5.6-luna model fixes. |
| 2026.7.23 | v2026.7.23 | 2026-07-23 | Mouse drag selection and copy in the full-screen agentos chat transcript (#76); turn-lifetime waiting indicator and markdown streaming fixes that remove ghost panels in Windows PowerShell; reasoning-model think-block rendering; Telegram keeps its native command menu across gateway restarts (#74). |
| 2026.7.22.post1 | v2026.7.22.post1 | 2026-07-22 | agentos chat full-screen transcript mouse wheel scrolling is responsive on the first tick (larger wheel step plus follow-release compensation) (#69). |
| 2026.7.22 | v2026.7.22 | 2026-07-22 | Native slash-command menus for Telegram, Slack, and Discord (#45); Ollama multi-turn tool-call history fixes and a tools.enabled = false plain-text fallback mode (#44); channel slash commands render their RPC results instead of a generic acknowledgement; Telegram delivery retries transient connection failures; agentos chat input frame supports multiline input (#62). |
| 2026.7.20 | v2026.7.20 | 2026-07-20 | agentos chat CLI UX pass (#46/#47): assistant speaker label defaults to agentos and is configurable via AGENTOS_ASSISTANT_LABEL; session title in the bottom toolbar and startup panel; /c0–/c3 and /auto router-tier holds on both CLI surfaces; framed input box; full-screen chat transcript pane now the default. |
| 2026.7.19.post1 | v2026.7.19.post1 | 2026-07-19 | Remove legacy v4_phase3 router engine and model bundle; rename to Pilot Router; sync router docs |
| 2026.7.19 | v2026.7.19 | 2026-07-19 | AgentOS Pilot (pilot-v1) is now the default router strategy with force-migration off v4_phase3 (#26, #36); bundled agentos self-operation skill (#37); Bankr browse source limited to two skills with Update button, emoji avatar, brand-glyph logo, and null-description crash fix (#39). |
| 2026.7.18.post1 | v2026.7.18.post1 | 2026-07-18 | Release-hygiene re-cut: propagate the 2026.7.18 version across uv.lock, consistency/install tests, RELEASES.md, CHANGELOG.md, README install examples, and install.sh/install.ps1. No runtime code changes. |
| 2026.7.18 | v2026.7.18 | 2026-07-18 | Gateway: interactive auth provisioning on public bind, host/port CLI-only (#25); browser-threat hardening on loopback binds — CSWSH/DNS-rebinding guards (#24); rebrand to "Token-Efficient AI agent with on-device Pilot Router" |
| 2026.7.17.post1 | v2026.7.17.post1 | 2026-07-17 | session_status tool fix: resolve the calling session from the tool context instead of a SessionManager method that never existed |
| 2026.7.17 | v2026.7.17 | 2026-07-17 | Memory provider layer (mem0) + curated stores; v4_phase3 router bundle restored; Web UI transcript redesign; embedding-download redirect fix |
| 2026.7.15.post1 | v2026.7.15.post1 | 2026-07-15 | Partner-catalog skills system + Robinhood RWA address lookup skill (Bankr hub) |
| 2026.7.15 | v2026.7.15 | 2026-07-15 | Relicense to Apache-2.0 with NOTICE + OpenSquilla attribution; wheels ship license files |
| 2026.7.14.post1 | v2026.7.14.post1 | 2026-07-14 | PyPI distribution rename to use-agent-os; first PyPI release |
| 2026.7.14 | v2026.7.14 | 2026-07-14 | Release |
| 0.0.1 | v0.0.1 | 2026-07-05 | AgentOS baseline release |
Versions follow CalVer (YYYY.M.D). PEP 440 normalizes wheel filenames and drops
leading zeros, so tags must use the same non-padded form — tag v2026.7.15, not
v2026.07.15, or the wheel filename (use_agent_os-2026.7.15-py3-none-any.whl) will
not match the tag and the release smoke check fails.
Preview releases publish only versioned assets:
AgentOS-<version>-windows-x64-py312-recommended-portable.zipuse_agent_os-<version>-py3-none-any.whlSHA256SUMS
Non-preview releases additionally publish a version-independent alias for the
Windows portable zip /releases/latest/download/ URL:
AgentOS-windows-x64-portable.zip
GitHub source archives remain available for code review and developer
reference; source installs should use git clone plus Git LFS. Public
wheelhouse zips, macOS portable zips, and Linux portable zips are intentionally
not published for the 0.0.x line. macOS and Linux users install the same wheel
through the versioned uv tool install command documented in the README.
Python wheel filenames must remain versioned because installers validate the
version segment inside the wheel filename.
Preview releases are GitHub pre-releases. Their README install commands must use tag-pinned URLs such as:
https://github.com/use-agent-os/agent-os/releases/download/v0.0.1rc1/AgentOS-0.0.1rc1-windows-x64-py312-recommended-portable.ziphttps://github.com/use-agent-os/agent-os/releases/download/v0.0.1rc1/use_agent_os-0.0.1rc1-py3-none-any.whl
0.0.1 install commands use versioned wheel URLs because Python installers
validate wheel filenames. The Windows portable zip may use the
/releases/latest/download/ alias after the non-pre-release GitHub Release
exists. Fully pinned URLs remain available:
https://github.com/use-agent-os/agent-os/releases/download/v0.0.1/AgentOS-0.0.1-windows-x64-py312-recommended-portable.ziphttps://github.com/use-agent-os/agent-os/releases/download/v0.0.1/use_agent_os-0.0.1-py3-none-any.whl
-
Verify
git statusis clean. -
Update
CHANGELOG.md: move entries from[Unreleased]to the release section; reopen empty[Unreleased]. -
Bump
pyproject.tomlanduv.lockto the release version. -
git tag -a v0.0.1 -m "AgentOS 0.0.1" -
git push origin v0.0.1(this triggers.github/workflows/wheelhouse-release.yml) -
Wait for the Windows release workflow → review the draft GitHub Release. For non-preview releases, confirm it contains versioned assets, latest aliases,
SHA256SUMS, plus GitHub's generated source archives before publishing. -
Confirm the draft GitHub Release is not marked as a pre-release.
-
Publish the GitHub Release, then run the post-publish tag URL checks:
curl --fail --head --location https://github.com/use-agent-os/agent-os/releases/download/v0.0.1/AgentOS-0.0.1-windows-x64-py312-recommended-portable.zip curl --fail --head --location https://github.com/use-agent-os/agent-os/releases/download/v0.0.1/use_agent_os-0.0.1-py3-none-any.whl
-
Run the post-publish latest URL check:
curl --fail --head --location https://github.com/use-agent-os/agent-os/releases/latest/download/AgentOS-windows-x64-portable.zip
-
For subsequent previews: bump
pyproject.toml,uv.lock,CHANGELOG.md, and the tag to the next preview version, for example0.0.2rc1/v0.0.2rc1. Preview GitHub Releases must be marked as pre-releases and should use tag-pinned README URLs until the next non-preview release exists.
These checks cannot be fully proven by local artifact generation:
- The tag exists on GitHub and matches
pyproject.toml. - The release workflow can fetch hydrated Git LFS router assets.
- Preview GitHub Releases contain the versioned assets and
SHA256SUMSaftergh release upload --clobber. - Non-preview GitHub Releases contain the versioned assets, Windows latest alias, and
SHA256SUMSaftergh release upload --clobber. - After a non-preview GitHub Release is published, the latest Windows portable
URL resolves:
.../releases/latest/download/AgentOS-windows-x64-portable.zip. - After a preview GitHub Release is published, the tag-pinned release asset URLs resolve.
- Windows browser downloads may carry Mark-of-the-Web; SmartScreen, Smart App Control, enterprise policy, and unsigned binary reputation must be checked on a real Windows machine.
Release zips are distributed as built artifacts, so the package filename,
manifest, zip name, and tag should describe the same preview build. PEP 440
accepts 0.0.1rc1, while the public GitHub Release title can use the friendlier
name "AgentOS 0.0.1 Preview 1".