Repository navigation
v1.4.0 #175
antiv
announced in
Announcements
v1.4.0
#175
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Every deployment should upgrade: the built-in admin account was refused by
admin-only agents on a new installation, a disabled webhook trigger still ran,
and two pages could run script stored by a widget visitor or a widget key's
holder. The release also brings a fallback model for provider outages, a
Content-Security-Policy (Report-Only), the documentation inside the
dashboard with a help agent behind a ? button, and memory blocks that
honour their Read-only and Character Limit settings.
Migrations V034 to V036 apply on startup. V035 replaces a Tavily API key that
older seeds wrote into agents' MCP URLs with
${TAVILY_API_KEY}; set thatvariable if an agent uses Tavily.
Before upgrading:
requirements.lock(pip install -r requirements.lock); Dockerand CI already do.
requirements.txtis now only the list of directdependencies, and SQLAlchemy is pinned below 2.1.
MATE_ENV=production, the server exits at startup when it cannot reachthe database instead of serving an empty dashboard, and ADK's dev UI at
/dev-uiis off unlessADK_DEV_UI=true.value longer than its Character Limit is refused, whether the write comes
from an agent, the dashboard, the widget admin API, a trigger or a template
sync. An agent that relied on writing such a block now gets an error; untick
Read-only or raise the limit if that write is wanted.
http_callbackwithouta URL, or an email output without a recipient or
SMTP_HOSTis now a400.Existing triggers like that keep their config, but their runs are recorded
as errors instead of
ok.docker-compose.ymlnow loads.envinto the container, so every settingin it reaches MATE, and
DB_TYPEandARTIFACT_SERVICEcome from it(defaults
sqliteandlocal_folder; it used to forcesupabase).channels the agent has always answered only when mentioned.
python shared/migrate.py rollbackis removed; it failed for everymigration. Reverse a change with a new migration or restore a backup.
Added
docs/and is served at/dashboard/docswith search: user guides, developer guides, and a reference (configuration, HTTP API, tools, database) thatscripts/gen_docs.pygenerates from the code. CI fails when the reference is stale and warns when code covered by a guide changes without the guide. The feature guides fromdocuments/moved intodocs/; pages not yet re-checked against the code are marked as such. Seedocs/dev/documentation.md<base>rewrites, and lets only MATE frame the dashboard. The widget chat page takes itsframe-ancestorsfrom the widget key's allowed origins whenWIDGET_ORIGIN_STRICTis on, covering the same sites as the origin check, so once enforced it also stops a site that hides its referrer. It ships asContent-Security-Policy-Report-Only(CSP_MODE): nothing is blocked, and violations are logged once each through/csp-report.CSP_EXTRA_SOURCESadds hosts a deployment needs. Inline scripts are still allowed; removing them is the next step. Seedocs/dev/content-security-policy.md(Add a Content-Security-Policy header #124)fallback_modelon the agents API). A request whose model call fails because the provider is unavailable (a timeout, a connection failure, a 5xx or a 429) is re-run once on it, and the answer goes back without an error. Errors the request itself causes, such as a content-policy refusal or an oversized context, do not fall back, so a refusal cannot be used to get past the primary provider's filters. Guardrails and token logging apply to it as to any answer, usage logs book its tokens under the fallback model, and each fallback leaves a warning and anagent.model_fallbackaudit entry. The fallback is reached through the provider env vars, never the agent's own base URL and key. Works on both runtimes. Migration V034. Seedocs/user/fallback-model.md(feat: fallback model when the primary provider fails #41)docs/user/evals.md(feat: Suggest a fix can also change the memory blocks the agent read #136)AGENT_FRAMEWORK=langgraph, running an eval against a version, a suite run and "Check against suite" returned501. They now build the graph from the version's snapshot, with sub-agents from their current config, and run it against an in-memory checkpointer, as the ADK runtime does. The deployed graph, the LangGraph session tables and the configured artifact storage are untouched, and RBAC is skipped for the eval run on both runtimes. Seedocs/user/evals.md(feat: evals against a stored version on the LangGraph runtime #123)mate_help, a built-in agent that searches and reads MATE's documentation through the newdocstool and knows which page you are on. Admins get every section with links to the Documentation page; other users get the user guides only. Migration V036 creates it in its own MATE Help project, open to the admin and user roles, with no model set, so it uses the server's default until an admin picks one; it is only created when no agent of that name exists. Seedocs/user/help.md/health-/healthnow answers503with"database": "unavailable"when the database cannot be reached, so the DockerHEALTHCHECKand orchestrators notice. PostgreSQL and MySQL are retried at startup (DB_CONNECT_RETRIES, default 5, 3 s apart) for a database that starts after MATE, and withMATE_ENV=productionthe server exits if it still cannot connect (Fail loudly when the database cannot be reached #144)requirements.lock, compiled with uv for Python 3.11 on every platform, pins every package with hashes. Docker, CI and the Quick Start install from it, so rebuilding the same commit can no longer pick up a breaking release. The README says how to regenerate and upgrade it (Pin dependencies so a rebuild cannot pull a breaking release #143)Changed
/dev-uiis a debugging tool that shows admins every event, tool argument and session state, runs on the dashboard's origin, and needs'unsafe-eval'. WithMATE_ENV=productionit is no longer served unlessADK_DEV_UI=true; elsewhere nothing changes. The CSP only allowseval()there while it is served. The dashboard's Chat button already opens the Work Room, so nothing in the dashboard depends on itmigrate.py rollbackis removed - it looked forR<version>files no migration ships, in the wrong folder, so it failed for every migration. The CLI now says to write a reversing migration or restore a backup (Migration rollback is a no-op; 'create' writes a single dialect #156)Fixed
error_coderead_onlyortoo_longand a message an agent can act on. The dashboard's edit form now saves the Read-only, Character Limit and Preserve on migration fields it always sent, a trigger whose answer cannot be written to its block fails the run instead of dropping the answer, and template sync skips such blocks and lists them in the sync dialog. Importing agents with overwrite still replaces blocks directly (Memory blocks: Read-only and Character Limit are not enforced #153)http_callbackwithout a URL and an email output without a recipient orSMTP_HOSTwere saved without complaint, and their runs recorded asok. Create and update now answer400with the reason (update only checks when it changes the type, schedule or output, so rotating an older trigger's key still works), and such a run is recorded as an error with the agent's answer kept (Triggers report success when nothing was delivered or scheduled #151)docker-composedid not pass.envto the container, so LLM API keys and every setting not listed underenvironment:never reached MATE. It is loaded withenv_filenow (optional), and the explicit entries still win.DB_TYPEandARTIFACT_SERVICEare taken from.envinstead of being forced tosqliteandsupabase, andDB_PASSWORDis no longer required (docker-compose.yml overrides .env values and requires an unused DB_PASSWORD #159, docker-compose does not pass .env to the container, so LLM API keys never reach it #163). Thanks to @cestercianpythonfromPATHinstead of the interpreter running the auth server, so in a virtualenv it could start without MATE's dependencies. It usessys.executablenow (Agent server is started with 'python' from PATH instead of the running interpreter #155). Thanks to @cesterciancreate_all. V002's seed relied on a unique constraint theMemoryBlockmodel lacked, so when the ORM created the table first every insert failed; the model declares it, V002 adds it when missing, andcreate_allonly runs after migrations succeed (Migration V002__memory_blocks fails on a fresh PostgreSQL database #145). On tables made bycreate_all, which have no database-side defaults, V001 to V003 and V036 left NOT NULL timestamps and flags to the database and failed (V036 was even recorded as applied on SQLite without creating the agent); they set every such column themselves now, and the V001 and V003 agent seeds only insert missing agents instead of overwriting ones an admin may have editedmigrate.py createwrote a single dialect. It now writes the new file intosqlite/,postgresql/andmysql/, numbered after the highest version in any of them, andgen_docs.py --checkin CI fails while a version is missing from a dialect (Migration rollback is a no-op; 'create' writes a single dialect #156)postgresql://select psycopg 3, which is not installed, so the first image built after its release could not open the database and the dashboard silently showed nothing. SQLAlchemy is pinned to 2.0, and the sync engines namepostgresql+psycopg2://explicitlygoogle-genai; it called the oldgoogle-generativeaiAPI and now creates agenai.ClientNoneinto its script and stopped, and the API docs page called a function before defining itSecurity
<script>withjson.dumps, which leaves</script>intact. Whoever holds a widget's admin key could set a title that closed the script and ran their own on MATE's origin, the dashboard's, when an admin opened the widget preview. The config, agent name and key are rendered withtojsonnowuser_id, which an RBAC denial (and now a model fallback) records. A visitor could thus store script that ran when an admin opened the dashboard. The fields are escaped now, as on the Audit Logs pageAUTH_USERNAMEaccount administers the dashboard, but itsusersrow was created with only theuserrole, so on a new installation every admin-only agent refused it and no agent could write memory blocks for it. The row is now created withadminanduser, andadminis added to an existing row that lacks it (Built-in admin account is refused by admin-only agents on a new installation #152)is_enabledwas only checked for cron triggers, so a switched-off webhook trigger still ran when its URL was called with a valid key.POST /triggers/{id}/firenow answers409for a disabled trigger, after authentication and the signature check. Test-fire from the dashboard still runs it (Disabled webhook triggers still fire #150)${TAVILY_API_KEY}placeholder the MCP loader fills from the environment, and V035 swaps the key out of agents seeded with it/csp-reportand the widget allowlist were hardened - the anonymous report endpoint refuses bodies over 16 KB before reading them, ignores malformed fields instead of failing with a500, and logs at most 100 violations per 10 minutes. A non-string entry in a widget key's allowed origins no longer makes the chat page a500, and an unrecognisedADK_DEV_UIvalue no longer turns the dev UI on in production/\, which browsers read as//host, passed as a local link in the help panel; it is refused nowFull Changelog: v1.3.3...v1.4.0
This discussion was created from the release v1.4.0.
All reactions