Release v0.23.0#2374
Conversation
|
Verdict: Approve ✅ This is the v0.23.0 release PR — version bump plus the release-notes page and nav wiring. I verified the mechanical parts a release depends on and they all line up: the version is bumped consistently everywhere, the Lemonade 11.0.0 pin matches what the notes claim, the release-notes validator passes clean, and the new page is wired into the docs navigation. The notes themselves read clearly and flag the beta/first-ship caveats honestly. Nothing blocking. 🔍 Technical detailsVerification performed
Issues
🟢 Minor (nit, optional): the frontmatter Strengths
|
GAIA v0.23.0 Release Notes
GAIA v0.23.0 is a large release built around making the Agent UI a real application instead of a developer tool with a browser front end. It can now install and update itself, walk a new user through hardware checks and model download on first launch, and run every agent as an isolated process supervised by a background daemon instead of code loaded into the UI. The email agent grows a full-autonomy mode that decides what to handle silently and what to ask about, and Outlook support extends to work and school accounts with a zero-setup sign-in flow. Underneath, every agent now shares one model and one context size so switching between them is instant, Lemonade Server moves to 11.0.0, and a dedicated security-audit pipeline replaces a general weekly pass with deterministic scanning plus reasoning over CWE-specific classes.
Why upgrade:
- Install and update from inside the app — the Agent UI can install itself, pull updates from a real feed, and open
- The email agent can run your inbox for you (beta) — turn on autonomy and it files low-signal mail silently, always asks before anything destructive, and gets less chatty over time as it earns your trust — correct it once and it goes back to asking.
- Outlook now works for work and school accounts — sign in with a short device code, no Azure app registration required.
- Agents run as their own processes — each agent is a daemon-supervised sidecar instead of code living inside the Agent UI, so a scheduled job or a long chat outlives closing the window.
- Switching agents is instant — every agent now shares one model and context size, so the Lemonade-side cold reload that used to cost seconds on every switch is gone.
- A dedicated security audit — deterministic scanning plus a reasoning pass over specific vulnerability classes, feeding CVSS-scored findings into GitHub's private code-scanning tab instead of a public issue.
**Email autonomy is beta.** It only auto-executes reversible actions, each with undo, and the confirmation floor for anything destructive (send, forward, permanent delete, RSVP, quarantine) never relaxes — not even for a fully-trusted sender. It's genuinely useful, but it's new this release: watch what it does for the first few days rather than trusting it blind, and report anything that looks wrong. **This release moves a lot of the platform onto a new foundation.** Agents now run under an always-on `gaia` daemon, and the desktop app installs and updates itself in place. Both are built and tested, but this is the first release they ship in and they're still settling — so if a sidecar gets stuck or an in-app update doesn't apply cleanly, restarting the daemon (`gaia daemon stop`) or reinstalling the app are the fallbacks. Please report anything that looks off.gaia://links from the website; a first-run wizard checks your hardware and downloads a model before you ever open a terminal.Breaking Changes
Closing the Agent UI no longer stops the email agent
Sidecar agents (currently email) are now supervised by the always-on
gaiadaemon, not the Agent UI backend process. Before, closing the UI killed the email sidecar along with it. Now the sidecar keeps running — so a scheduled briefing or a long-running job survives the window closing — and you stop it explicitly:gaia daemon stop-agent emailorgaia daemon stop(PR #2144).Hub agent packages moved to an agent-first layout
Hub packages used to be split by language first —
hub/agents/python/email/andhub/agents/npm/agent-email/for the same agent. They're now grouped by agent first:hub/agents/<id>/{python,npm}/(e.g.hub/agents/email/python/,hub/agents/email/npm/). The published wheel name (gaia-agent-email) and npm package name (@amd-gaia/agent-email) are unchanged — only the on-disk source paths moved. If you have local scripts, forks, or docs referencing the oldhub/agents/python/<id>/orhub/agents/npm/<id>/paths, update them tohub/agents/<id>/<lang>/(PR #2060).gaia agent init --layout hubwas added afterward so scaffolding a new agent produces the correct layout in one command (PR #2295).What's New
Install, update, and onboard without a terminal — Agent UI
The Agent UI shell had three install/update paths that either didn't exist or were dead stubs. Clicking install on a Hub agent used to hit an IPC handler that threw "not yet implemented"; now it drives the real backend install runtime with streaming progress, so importing an agent from the Hub actually works. Auto-update moved off a hard-wired GitHub Releases check onto a configurable R2 feed with a mutable channel pointer, and an app with no feed configured says so loudly instead of silently checking a dead URL. The website's "Open in GAIA" button now has somewhere to land: the app registers the
gaia://protocol and handlesgaia://hub/install/<id>deep links on all three desktop platforms (PR #2196).None of that helps if a new user doesn't know where to start, so first launch on a fresh machine now opens a wizard: it scans your hardware and gates on real capability (RAM, disk, NPU, GPU) instead of finding out at runtime, downloads the recommended model with visible progress and retry instead of swallowing a failed download, and offers to connect an account (Google, for email triage) before you ever reach chat (PR #2204). The in-app Hub itself is reorganized into Apps, Components, and Agents lanes, and every install now goes through a trust gate — anything that isn't AMD-verified requires an explicit override tick before it will install (PR #2201).
The email agent can decide for itself — full autonomy (beta)
Until now the email agent only ever acted when you asked it to. Turn on autonomy and it triages and files low-signal mail on its own, on an earn-trust gradient: cautious the first day, and progressively quieter for senders and categories that have proven themselves — correct it once and it's back to asking immediately. It never silently sends, forwards, permanently deletes, quarantines, or RSVPs; those always wait for your confirmation regardless of how much trust a sender has earned. Every auto-executed action is reversible and comes with undo (PR #2363):
Outlook for work and school accounts —
gaia connectorsThe Microsoft connector was pinned to personal Outlook.com accounts only, so a work or school (Microsoft 365 / Entra ID) account was rejected before a token was even issued — and connecting required registering your own Azure app. It now defaults to the tenant that accepts both personal and work/school accounts, and adds a zero-setup device-code sign-in: enter a short code at a URL, no Azure registration, no redirect URI. Available from the CLI (
gaia connectors connect microsoft --device) and as a "Sign in with a code" button on the Microsoft tile in the Agent UI. A related Windows-only fix means Outlook's longer refresh tokens no longer fail to save to Credential Manager (PR #2364).Agents run as isolated, daemon-supervised processes
Agents used to run as code loaded directly into whatever hosted them — the email agent's sidecar lived and died with the Agent UI backend, and every future agent would have needed to reinvent that lifecycle plumbing. Now the always-on
gaiadaemon owns agent supervision: the UI,gaia emailon the CLI, andgaia apiare all thin clients of the same daemon-managed sidecar, so they share one running instance instead of each spawning their own. A killed daemon reaps its orphaned sidecars on the next start instead of leaking processes (PR #2144).Behind that one architectural move:
gaia emailandgaia apinow both relay through the daemon instead of running the email agent in-process (PRs #2191, #2205), chat streams over a proper SSE reverse proxy (PR #2188), a host-owned broker serializes model loads across agents so two sidecars can no longer race-evict each other's model out from under them (PR #2194), a per-agent-scoped custody API keeps one agent from ever reading another's memory or sessions (PR #2197), scheduled jobs (briefings, sends, snoozes) move onto one daemon-owned clock so they keep firing after the process that used to own them closes (PR #2199), OAuth tokens forward from the daemon to a sidecar as short-lived access tokens rather than the sidecar holding your refresh token (PR #2203), and existing~/.gaiasessions and memory migrate into the new layout automatically, once, without data loss (PR #2200).Every agent shares one model — instant switching
Agents that left their model unset used to default to a different model than chat and email, so moving between agents forced Lemonade to unload and cold-reload — measured at 7.9 seconds on a warm server. Every agent now resolves to Gemma-4-E4B at one context size per device profile, so the resident model is simply reused: three consecutive agent switches measured 0.00s each with the same
llama-serverprocess still running (PR #2284).Lemonade Server 11.0.0
The pinned Lemonade Server moves 10.10.0 → 11.0.0 (PR #2130). This doesn't move existing installs — a machine already on a 10.x that clears every profile's minimum is left alone — but it fixes a version-check bug found while crossing the major boundary: GAIA compared Lemonade's major version for equality, so every 10.x install was about to start seeing a false "version mismatch" warning on every run, the exact opposite of what
gaia initreported. The check is now a floor (10.2.0), not an equality check, so a newer server is never flagged as wrong.A dedicated security audit
The weekly audit's single general security pass sampled a large repository in one go and missed a real path-traversal bug in hub archive extraction because it read an existing
# noqacomment as a settled decision rather than re-checking it. A dedicated security-audit workflow replaces that: deterministic semgrep scanning across the whole tree feeds a private GitHub code-scanning tab, and a reasoning pass runs three specific lenses — path/injection sinks, authorization gate-asymmetry, and a from-scratch re-review of every existing suppression comment — over an explicit worklist instead of a sampled one. Findings are scored with real CVSS 4.0 arithmetic against a reviewed vector, not a guessed severity number (PR #2346).Alongside the new audit, this release also closes out a batch of security hardening found by earlier passes: the file-read sandbox now actually enforces
--allowed-paths(PR #2344), hub archive extraction is hardened against path traversal (PR #2342), the MCP bridge binds to loopback instead of all interfaces (PR #2246), the API's CORS policy no longer allows a wildcard origin with credentials (PR #2238), SQL is parameterized and sensitive values are redacted from logs (PR #2239), API errors no longer leak stack traces (PR #2236), and exposed routes are rate-limited (PR #2237). A new lint gate requires every future security suppression to be reviewed in an allowlist instead of silently accepted (PR #2343).Agent Hub / infrastructure
A hub-installed wheel agent could be installed successfully and still fail to import in a fresh process, because installation only patched the installing process's own
sys.path. That's now fixed generically for every wheel agent, andgaia initcan install the chat agent from the Hub catalog when it's missing (PR #2373). This is infrastructure, not a finished user path: chat's own publish to the Hub catalog is a separate, still-pending step, so a plainpip install amd-gaiastill doesn't give you a workinggaia chatyet — that milestone stays open until the publish lands and is verified end to end.Elsewhere in the Hub: agent packages are catalogued with a manifest type discriminator so an app, component, or agent can be told apart before install (PR #2183), and file-based custom agents now report their real health in the UI instead of always showing "error" (PR #2277).
Agents propose their own next steps
The base
Agentclass gained the hooks its autonomy work is built on:on_heartbeat/propose, letting an agent surface an approval-gated suggestion for something it thinks should happen next, instead of only ever reacting to a prompt. The email autonomy engine above is the first concrete consumer (PR #2187).Bug Fixes
gaia agent initscaffolding put files in the wrong place after the hub layout move (PR #2295) —--outputhad no way to produce the new agent-first layout, and could even set the agent's id to the literal string"python".amd_gpu/nvidia_gpunow returning as lists broke hardware capability checks.gaia initoutput ate bracketed text (PR #2340) — Rich markup parsing swallowed tokens like[some-model]from status lines instead of printing them.default_deviceeverywhere.$orderbytriggered Microsoft Graph'sInefficientFilterrejection on some threads._ensure_model_loadednow raises loudly instead of swallowing the error.amd-gaia[agents]extra could downgrade the core wheel (PR #2262) — pip's resolver could pull in an older core package than the one already installed.Contributors
Thanks to the community member who contributed to this release:
Full Changelog
106 commits since v0.22.0:
5f624706— fix(hub): importable CLI wheel agents + chat distribution via gaia init (fix(hub): importable CLI wheel agents + chat distribution via gaia init #2373)3ad39e60— fix(sidecar): actionable user-mode binary error ([Bug]: Unable to use the email agent on version 0.22 #2347) (fix(sidecar): actionable user-mode binary error (#2347) #2357)bfc0f5b8— fix(lemonade): recognize grouped amd_gpu/nvidia_gpu device keys in validation (fix(lemonade): recognize grouped amd_gpu/nvidia_gpu device keys in validation #2368)0553c8b0— feat(email): full autonomy — earn-trust engine, learning loop, scheduled driver (feat(email): full autonomy — earn-trust engine, learning loop, scheduled driver #2363)0284300b— feat(connectors): support work/school Outlook + zero-setup device-code sign-in (feat(connectors): support work/school Outlook + zero-setup device-code sign-in #2364)1aaba5cc— feat(lint): require security suppressions to be reviewed in an allowlist (feat(lint): require security suppressions to be reviewed in an allowlist #2343)19b1a4c5— test(daemon): de-flake sidecar stop test on the pid-liveness check (test(daemon): de-flake sidecar stop test on the pid-liveness check #2349)174e9d0c— refactor(chat): extract ProfileSpec, honest manifest, lazy RAG — one class → separable profiles (chat: ProfileSpec refactor — one 2,258-line class serving three registry ids #2323) (refactor(chat): extract ProfileSpec, honest manifest, lazy RAG — one class → separable profiles (#2323) #2362)57f970b0— chore(audit): drop the security dimension from the weekly audit (chore(audit): drop the security dimension from the weekly audit #2348)23181040— feat(security): proactive Claude security-audit workflow + CVSS/SARIF tooling (feat(security): proactive Claude security-audit workflow + CVSS/SARIF tooling #2346)d605caec— fix(security): enforce --allowed-paths sandbox on file read tools (fix(security): enforce --allowed-paths sandbox on file read tools #2344)1c8a91c9— fix(security): remove pre-existing bandit HIGH findings and enable the HIGH gate (fix(security): remove pre-existing bandit HIGH findings and enable the HIGH gate #2350)4b5c16b7— ci(labeler): add tui/daemon/sidecar auto-label rules (ci(labeler): add tui/daemon/sidecar auto-label rules #2356)a905b057— chore(deps): bump the github-actions group with 2 updates (chore(deps): bump the github-actions group with 2 updates #2341)b3f793af— fix(routing): default unknown language to TypeScript, not a process kill (fix(routing): default unknown language to TypeScript, not a process kill #2337)48286dbd— fix(init): stop Rich eating bracketed tokens in gaia init output (fix(init): stop Rich eating bracketed tokens in gaia init output #2340)638a7643— docs(skills): add porting-agent-to-hub — the legacy-agent port flow (docs(skills): add porting-agent-to-hub — the legacy-agent port flow #2338)d2c00b55— fix(hub): harden agent-archive extraction against path traversal (fix(hub): harden agent-archive extraction against path traversal #2342)a4417656— fix(ci): repair the startup-failing GAIA CLI aggregate workflow (fix(ci): repair the startup-failing GAIA CLI aggregate workflow #2307)0835a250— fix(ci): make the weekly eval and runner heartbeat monitor actually run (fix(ci): make the weekly eval and runner heartbeat monitor actually run #2306)977c158f— fix(cli): add --layout hub to gaia agent init for the agent-first hub tree (fix(cli): add --layout hub to gaia agent init for the agent-first hub tree #2295)558a73e6— chore(deps): bump the github-actions group with 3 updates (chore(deps): bump the github-actions group with 3 updates #2294)f8bff000— chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in the root-npm-dependencies group (chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in the root-npm-dependencies group #2292)fb179e32— ci(eval): gate the Gemma-4-E4B consolidation on agent evals (ci(eval): gate the Gemma-4-E4B consolidation on agent evals #2283)6b2aa2db— chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in /src/gaia/apps/jira/webui in the jira-app-dependencies group (chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in /src/gaia/apps/jira/webui in the jira-app-dependencies group #2291)5837bdac— chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in /src/gaia/apps/example/webui in the example-app-dependencies group (chore(deps-dev): bump electron from 43.1.0 to 43.1.1 in /src/gaia/apps/example/webui in the example-app-dependencies group #2290)3ce4f790— test(agents): stub live Lemonade probe in context-overflow tests (test(agents): stub live Lemonade probe in context-overflow tests #2288)1886a92f— chore(deps): bump electron from 43.1.0 to 43.1.1 in /hub/agents/emr/python/gaia_agent_emr/dashboard/electron in the emr-dashboard-dependencies group (chore(deps): bump electron from 43.1.0 to 43.1.1 in /hub/agents/emr/python/gaia_agent_emr/dashboard/electron in the emr-dashboard-dependencies group #2289)0a308449— feat(agents): consolidate every agent onto Gemma-4-E4B at one context size (feat(agents): consolidate every agent onto Gemma-4-E4B at one context size #2284)4392e06a— chore(deps-dev): bump the agent-ui-dependencies group in /src/gaia/apps/webui with 3 updates (chore(deps-dev): bump the agent-ui-dependencies group in /src/gaia/apps/webui with 3 updates #2293)d9b11ec7— refactor(hub): agent-first layout — hub/agents/<id>/<lang> (refactor(hub): agent-first layout — hub/agents/<id>/<lang> #2060)5f15b333— feat(daemon): broker-wire the remaining direct model-load surfaces (feat(daemon): broker-wire the remaining direct model-load surfaces #2286)3affe149— fix(ui): detect GPU from real Lemonade payload shapes (fix(ui): detect GPU from real Lemonade payload shapes #2285)4f888b78— fix(hub): report file-based custom agents' real health, not always 'error' (fix(hub): report file-based custom agents' real health, not always 'error' #2277)36c29873— fix(cli): detect GPU on all platforms and honour default_device (fix(cli): detect GPU on all platforms and honour default_device #2244)6c6f8a34— test(audit): coverage for schedule CLI, perf-vis, VLM extraction, PDF gen/export; fix silent table-row loss (test(audit): coverage for schedule CLI, perf-vis, VLM extraction, PDF gen/export; fix silent table-row loss #2259)2425afe8— fix(builder): surface model-not-found (404) instead of a generic placeholder (fix(builder): surface model-not-found (404) instead of a generic placeholder #2245)3a0eebe7— ci(hub): wire nine hub package test suites into CI; fix .cjs docs-link guard gap (ci(hub): wire nine hub package test suites into CI; fix .cjs docs-link guard gap #2258)3e82ca61— docs(connectors): correct the client_id_hash claim in the OAuth runbook (docs(connectors): correct the client_id_hash claim in the OAuth runbook #2264)9f7dca84— fix(ci): fix Lemonade startup and bash-on-PATH in the doc walkthrough (fix(ci): fix Lemonade startup and bash-on-PATH in the doc walkthrough #2281)53f4b529— fix(daemon): owner-only DACL for the Windows launch secret (fix(daemon): Windows DACL for the V2-3 launch-secret file (chmod 0600 is inert on NTFS) #2250) (fix(daemon): owner-only DACL for the Windows launch secret (#2250) #2282)ee8825fa— fix(security): require allowed_dir in compute_file_hash (fix(security): require allowed_dir in compute_file_hash #2280)46fb7687— spec(factory): define the dogfooding loop — Claudia as live validation runtime (spec(factory): define the dogfooding loop — Claudia as live validation runtime #2234)1a679f02— feat(ui): always-available OAuth client field in Settings (feat(connectors): first-party OAuth clients — Connect Google/Outlook works out of the box in the Agent UI #2104 interim) (feat(ui): always-available OAuth client field in Settings (#2104 interim) #2265)45c796b1— test(jira): unit tests for JiraAgent HTTP boundary and config discovery (JiraAgent (1184 lines) has zero tests anywhere — no package tests/ dir, no repo-level coverage, no CI #1991) (test(jira): unit tests for JiraAgent HTTP boundary and config discovery (#1991) #2263)bed702eb— feat(ci): execution-based weekly doc walkthrough (feat(ci): execution-based weekly doc walkthrough #2278)f8f309e6— fix(ui): stop silently accepting unimplemented agent_mode 'autonomous' (fix(ui): stop silently accepting unimplemented agent_mode 'autonomous' #2257)3b0938ed— fix(ci): weekly audit cross-links the prior parent instead of auto-closing it (fix(ci): weekly audit cross-links the prior parent instead of auto-closing it #2254)78306480— test(audit): risk-bearing coverage — jira, trust-gate, flag-precedence, gaia init --profile npu fails with status 400 (missing user. prefix for model name) #1655 boundaries (test(audit): risk-bearing coverage — jira, trust-gate, flag-precedence, #1655 boundaries #2253)1aa39ca2— fix(observability): real system-metrics polling + real rollbackAction (fix(observability): real system-metrics polling + real rollbackAction #2251)384b3ca8— fix(security): bind MCP bridge to loopback, not all interfaces (fix(security): bind MCP bridge to loopback, not all interfaces #2246)037f4370— fix(cli): implement/gate stubbed api-status, eval flags, schedule --skill (fix(cli): implement/gate stubbed api-status, eval flags, schedule --skill #2247)2b6ed53e— fix(security): rate-limit exposed routes, harden JS ReDoS/XSS/cleartext-logging (fix(security): rate-limit exposed routes, harden JS ReDoS/XSS/cleartext-logging #2237)6c6b3baf— fix(packaging): stop the amd-gaia[agents] extra from downgrading the core wheel (fix(packaging): stop the amd-gaia[agents] extra from downgrading the core wheel #2262)8744a51a— fix(security): validate user-influenced file paths (py/path-injection) (fix(security): validate user-influenced file paths (py/path-injection) #2252)c921fa7b— feat(email): quality + robustness batch (feat(email): register briefing + task tools in the agent loop — NL requests silently degrade to prescan #2110/feat(email): triage misfiles time-sensitive commitments as informational/archive — add deadline/commitment detection #2113/fix(email): tool robustness — triage_inbox outruns the 180s tool timeout; search passes literal user phrases to Gmail #2114/chore(email): answer-quality cleanup — raw render fences as final answers, LaTeX artifacts, Connectors/Connections naming drift #2115/feat(email): map Google's API-not-enabled 403 to an actionable error naming the enable URL #2116) (feat(email): quality + robustness batch (#2110/#2113/#2114/#2115/#2116) #2192)b9391ec2— fix(security): parameterize SQL, redact sensitive logs, harden ReDoS regexes (fix(security): parameterize SQL, redact sensitive logs, harden ReDoS regexes #2239)09e0bac4— fix(security): stop leaking stack traces at API boundaries + least-privilege workflow permissions (fix(security): stop leaking stack traces at API boundaries + least-privilege workflow permissions #2236)3df5a3db— fix(security): tighten API CORS — no wildcard origin with credentials (fix(security): tighten API CORS — no wildcard origin with credentials #2238)a3db04ef— feat(connectors): OAuth forward-out to sidecars (V2-14) (feat(connectors): OAuth forward-out to sidecars (V2-14) #2203)e0886cbf— refactor(daemon): reconcile the clocks into one daemon-owned scheduler (V2-15) (refactor(daemon): reconcile the clocks into one daemon-owned scheduler (V2-15) #2199)15459153— feat(daemon): /host/v1 custody API v1 with per-agent scoping (V2-12) (feat(daemon): /host/v1 custody API v1 with per-agent scoping (V2-12) #2197)e226d584— feat(webui): group session sidebar by agent + session-state polish (feat(webui): group session sidebar by agent + session-state polish #2193)6e48cb22— feat(daemon): host-owned model-slot broker serializes loads (V2-11) (feat(daemon): host-owned model-slot broker serializes loads (V2-11) #2194)c42bb354— fix(website): correct hub install command and clarify agent availability (fix(website): correct hub install command and clarify agent availability #2207)2f18de85— fix(tests): align email CLI dispatch test with feat(cli): gaia email attaches to the daemon — thin client (V2-8) #2191 thin-client contract (fix(tests): align email CLI dispatch test with #2191 thin-client contract #2209)a2ad4eff— fix(tests): repair stale gaia.ui.email_sidecar.manager import after refactor(daemon): daemon-supervised agent sidecars (V2-6) #2144 (fix(tests): repair stale gaia.ui.email_sidecar.manager import after #2144 #2208)2b89643c— fix(webui): repair broken main — AgentHubView imported deleted AgentHubGrid (fix(webui): repair broken main — AgentHubView imported deleted AgentHubGrid #2206)68773d46— test(eval): sidecar eval harness + distributed-seams suite (V2-19) (test(eval): sidecar eval harness + distributed-seams suite (V2-19) #2202)d7cffc72— feat(agent-ui): first-run onboarding wizard — hardware pre-flight, in-app model download, connect-on-install (feat(agent-ui): first-run onboarding wizard — hardware pre-flight, in-app model download, connect-on-install #2204)5bc7d325— feat(electron): in-app install, R2 auto-update feed, gaia:// deep links (feat(electron): in-app install, R2 auto-update feed, gaia:// deep links #2196)eb6b34bf— feat(daemon): one-time versioned migration of ~/.gaia state (V2-13) (feat(daemon): one-time versioned migration of ~/.gaia state (V2-13) #2200)73b8f98c— refactor(api): remove the last in-process email mount; relay via daemon (refactor(api): [api] extra still auto-mounts gaia_agent_email in-process — last in-process mount post-#1896 #2176) (refactor(api): remove the last in-process email mount; relay via daemon (#2176) #2205)e4ea0e33— feat(connectors): grant the mailbox to the email agent in the same connect flow (feat(connectors): grant the mailbox to the email agent in the same connect flow #2195)2bf405db— feat(webui): in-app Hub page with catalog lanes + install trust gate (feat(webui): in-app Hub page with catalog lanes + install trust gate #2201)459efba9— feat(api): relay /v1/<agent>/query through the daemon (V2-17) (feat(api): relay /v1/<agent>/query through the daemon (V2-17) #2198)ada5b95a— feat(cli): gaia email attaches to the daemon — thin client (V2-8) (feat(cli): gaia email attaches to the daemon — thin client (V2-8) #2191)a49d257d— fix(webui): reachable Agent Hub + installed-agent discovery and per-session picker (fix(webui): reachable Agent Hub + installed-agent discovery and per-session picker #2190)7c98b51a— docs(connectors): rewrite the Google client-ID walkthrough for the current console (docs(connectors): rewrite the Google client-ID walkthrough for the current console #2189)a94a8126— feat(daemon): deliver sidecar launch secret via 0600 file, not bare env (feat(daemon): deliver sidecar launch secret via 0600 file, not bare env (V2-3) #2149) (feat(daemon): deliver sidecar launch secret via 0600 file, not bare env (#2149) #2186)5601e2a5— feat(daemon): streaming SSE reverse-proxy for agent routes (feat(daemon): streaming SSE reverse-proxy for agent routes (V2-7) #2150) (feat(daemon): streaming SSE reverse-proxy for agent routes (#2150) #2188)1465bc73— feat(agents): proactive lifecycle hooks with approval-gated proposals (L7.4 — Base-Agent lifecycle hooks (on_first_run / on_heartbeat / propose) #1484) (feat(agents): proactive lifecycle hooks with approval-gated proposals (#1484) #2187)2c4ff395— test(chat): mirror the amd-gaia floor guard from fix(email): raise amd-gaia floor to match get_embedding_model_for_device (#2112) #2169; harden version parsing (test(chat): mirror the amd-gaia floor guard from #2169; harden version parsing #2184)2271278c— fix(llm): make swallowed model-load failures loud in _ensure_model_loaded (fix(llm): make swallowed model-load failures loud in _ensure_model_loaded #2185)2e0294f9— feat(hub): add multi-component type discriminator to the manifest (Hub: add multi-componenttypediscriminator to the manifest (both validators) #1716) (feat(hub): add multi-component type discriminator to the manifest (#1716) #2183)b78b71d1— test(chat): guard the amd-gaia dependency floor against fix(email): amd-gaia dependency floor (>=0.20.0) is below the code's real requirement — fresh installs ImportError #2112 regression (test(chat): guard the amd-gaia dependency floor against #2112 regression #2174)33caec54— refactor(ui): extract _best_effort_cancel helper for the relay cancel paths (refactor(ui): extract _best_effort_cancel helper for the relay cancel paths #2173)ba58e31a— feat(email): fast dev-iteration loop for the email agent SDK (feat(email): fast dev-iteration loop for the email agent SDK #2083)f79c4177— fix(webui): pin explicitly-set session titles — stop auto-retitle churn (fix(webui): auto-retitler overwrites explicitly-set session titles on every reply #2165) (fix(webui): pin explicitly-set session titles — stop auto-retitle churn (#2165) #2171)ae741690— fix(email): error on an explicitly-targeted unconnected mailbox instead of substituting (fix(email): 'check my Outlook' silently serves Gmail data instead of a not-connected error #2164) (fix(email): error on an explicitly-targeted unconnected mailbox instead of substituting (#2164) #2172)4dafa091— fix(email): normalize date operators in search_messages (fix(email): search passes non-ISO date operators to Gmail silently → false 'no messages' answers #2161) (fix(email): normalize date operators in search_messages (#2161) #2170)dd2fa328— fix(email): raise amd-gaia floor to match get_embedding_model_for_device (fix(email): amd-gaia dependency floor (>=0.20.0) is below the code's real requirement — fresh installs ImportError #2112) (fix(email): raise amd-gaia floor to match get_embedding_model_for_device (#2112) #2169)011b6e3c— fix(email): default calendar list to a forward window when range args are absent (fix(email): calendar list without an explicit range returns ancient recurring instances, narrated as 'this week' #2162) (fix(email): default calendar list to a forward window when range args are absent (#2162) #2168)ed7d2969— fix(ui): propagate cancel to the email sidecar on relay timeout/crash (fix(ui): email /query relay leaks the sidecar generation on read-timeout — cancel only fires on user-stop #2158) (fix(ui): propagate cancel to the email sidecar on relay timeout/crash (#2158) #2167)d8daf66d— fix(agent): abort in-flight streaming generation on Agent-UI Stop (fix(agent): abort in-flight streaming generation on Agent-UI Stop #2166)c907f6c4— feat(memory): adaptive, review-gated onboarding conversation (feat: Phase 1 — implement spec'd run_bootstrap_conversation() (adaptive onboarding) #1955) (feat(memory): adaptive, review-gated onboarding conversation (#1955) #2143)def5e979— fix(ui): stop blaming Lemonade for cancelled/empty chat turns (fix(ui): stop blaming Lemonade for cancelled/empty chat turns #2141)553cb541— fix(email): consolidate Agent UI pre-scan across every connected mailbox (fix(email): consolidate Agent UI pre-scan across every connected mailbox #2129)5446af2c— fix(agent-email): drop $orderby from Outlook get_thread to avoid Graph InefficientFilter (fix(agent-email): drop $orderby from Outlook get_thread to avoid Graph InefficientFilter #2140)8ba66f4d— fix(email): REST triage honors the LLM's is_spam verdict (fix(email): REST triage honors the LLM's is_spam verdict #2125)aa44c2c8— refactor(daemon): daemon-supervised agent sidecars (V2-6) (refactor(daemon): daemon-supervised agent sidecars (V2-6) #2144)ac3cc4cd— fix(eval): fail the briefing eval loudly on a zero-case/zero-judged run (fix(eval): fail the briefing eval loudly on a zero-case/zero-judged run #2123)c9566b19— chore(deps): bump Lemonade Server to v11.0.0 (chore(deps): bump Lemonade Server to v11.0.0 #2130)47c1142a— feat(ui): route email chat through the sidecar /v1/email/query loop (V2-10) (feat(ui): route email chat through the sidecar /v1/email/query loop (V2-10) #2136)b340427d— docs(skill): correct the release skill against what v0.22.0 actually did (docs(skill): correct the release skill against what v0.22.0 actually did #2133)9f1ece0f— feat(webui): render→component map + generic render primitives (V2-9) (feat(webui): render→component map + generic render primitives (V2-9) #2131)Full Changelog: v0.22.0...v0.23.0
Release checklist
util/validate_release_notes.py docs/releases/v0.23.0.mdx --tag v0.23.0passescd docs && npx mintlify validatepasses (v0.23.0 parses clean)src/gaia/version.py→0.23.0src/gaia/apps/webui/package.json→0.23.0src/gaia/apps/webui/package-lock.json→0.23.0docs/docs.json→v0.23.0 · Lemonade 11.0.0v0.22.0..HEAD) represented in the notes