Google's Agent Development Kit graduated twenty-six modules to stable in v2.14.0, and buried in the same release notes is the sentence that should change how you read a stability label: stable toolset and integration features are now always enabled, and the flags that disabled them no longer block them. Graduation was not a documentation change — it switched features on and removed the switch. Four other changes in that release alter what your agent actually does without touching a single signature, which is the general problem: in an agent framework, the version number guards the API and almost nothing that decides behaviour.
What the release says
ADK v2.14.0 is a substantial release, dated 2026-11-04 in the changelog header and posted on 7 November. The headline is maturity: the A2A integration is now stable; BaseEnvironment, LocalEnvironment, EnvironmentToolset, DaytonaEnvironment and E2BEnvironment are now stable; 26 auth, environment, app, CLI and cache modules graduated; 16 toolset and integration features were promoted, including Bigtable, Computer Use, Environment Simulation, GCS, the MCP agent server, Pub/Sub and Spanner. New on top of that: a TeamsRunner for Microsoft Teams, multi-run evaluation via adk eval --num_runs and --parallelism, and adk generate_agent_card to build an A2A agent card from the CLI.
Read the definition the notes actually give, though. Graduated APIs can be used "without experimental warnings." That is the whole promise. The release makes no broader API-compatibility guarantee, and it lists no deprecations — which is worth noticing in a release that graduates this much, because a stability label with no deprecation policy attached is a statement about log output rather than about your migration cost.
Graduation turned features on and took away the flag
Among the behaviour notes is this: stable toolset and integration features are always enabled, and disable flags no longer block them. Sit with what that means operationally. A team that had explicitly turned off, say, Computer Use or the MCP agent server — because it had not reviewed them, or because its threat model did not permit them — finds those features active after a minor-version upgrade, with the flag that expressed the decision now inert.
This is not sloppiness; it is the logical end of treating "experimental" as the thing a flag gates. If the flag's purpose was to keep immature code out of the default path, then maturity retires the flag. But the flag was doing a second job nobody wrote down: expressing a policy about what the agent may do. Those two jobs are only accidentally the same, and they separate exactly at graduation.
The consequence is that a feature's default state in an agent framework is a security control, and in this release that control moved by sixteen features at once. That is the subject of unpinned vendor defaults, and it is why a tool inventory has to be derived from the running system rather than from the config you wrote — see tool catalog lifecycle.
An "off" flag that only meant "not yet" was never a policy. If you need a capability to stay off after it matures, the control has to live somewhere the framework's maturity model cannot reach.
The four changes that move behaviour without moving an API
The release notes list three breaking changes in the conventional sense — enum tool arguments now arrive as enum members rather than raw strings, VertexAiSessionService.create_session restricts its extra keyword arguments to four names, and RunSkillScriptTool in environment mode no longer accepts a command string. Those are the ones a type checker or a test will catch. The interesting set is the one it will not.
Compaction fires earlier. Token-threshold compaction now counts tool outputs since the last model call, so it triggers sooner than before. Nothing in your code changed; what changed is the point at which your agent's context gets rewritten, which is to say what it remembers mid-task. If you had tuned a long-running agent against the old threshold, that tuning is now describing a different system — and compaction is one of the highest-leverage behaviours in a loop, as context compaction sets out.
Two extra events per response. Agents with an output_schema and a transfer target now use set_model_response on some models, adding two events per response. Every event-count assertion, every per-run cost attribution keyed on events, and every trace-volume projection shifts by a constant you did not choose.
Metric buckets moved. Histogram bucket bounds changed for several gen_ai metrics. Histogram percentiles are computed from bucket boundaries, so your p95 latency can move without your latency moving — and it will look like a regression or an improvement depending on where your real distribution sits relative to the new bounds. Anyone alerting on a latency percentile across this upgrade is comparing two different rulers; the measurement hazards are in measuring agent latency.
Rollback stopped being available. FirestoreSessionService now stores event payloads as JSON strings, and sessions written by this version cannot be read by 2.13.0 or earlier after a rollback. Separately, new PostgreSQL JSON columns are created as json rather than jsonb, and existing tables are not migrated — so a fresh deployment and an upgraded one now differ in their storage representation. A minor-version upgrade that writes a format the previous version cannot read is a one-way door, and it needs the ceremony of one: see rollout & versioning and, for the sessions in flight while you deploy, long-lived sessions and deploys.
A security fix shipped as an ergonomics change
The RunSkillScriptTool change deserves separating out. It no longer accepts a command string; it now takes args, short_options and positional_args, runs scripts from the skill directory, and permits only .py, .sh and .bash. The notes say this closes a prompt-injection hole.
That is a meaningful hardening — replacing a free-form command string with a structured argument list is exactly the right fix, because it removes the shell from the path a model's output can reach. It is also filed in the release notes as a breaking change rather than announced as a security advisory, with no CVE referenced. A team that reads only advisories learns nothing; a team that reads changelogs learns it as an API migration chore.
This is the recurring shape in agent tooling: the fix and the refactor are the same commit, so the security-relevant change arrives through the channel you skim. The underlying class of bug — a tool whose argument becomes a shell command — is prompt injection reaching an interpreter, and the structural remedy is the one applied here, discussed generally in tool schemas and contracts.
A2A going stable inside one SDK is not A2A going stable
The release marks the A2A integration stable and adds CLI generation of agent cards. Both are useful, and the distinction worth holding onto is that a client implementation's stability and a protocol's stability are different claims by different parties. An SDK promising not to change its A2A surface says nothing about whether the protocol's own revision cadence will require it to — which is the general problem in protocol revisions & deprecation windows, and why the protocol's own versioning matters more than your library's; the current shape is in the A2A v1 deep-dive and agent cards and discovery.
Note too what the stable environment classes commit you to: DaytonaEnvironment and E2BEnvironment graduating means the framework now has first-class, stable bindings to third-party sandbox vendors, and the e2b minimum moved to 2.29.5 in this release. Stability at the framework boundary does not propagate to the vendor behind it.
What to change this week
None of this is an argument against upgrading — the release is clearly a good one, and multi-run evaluation with --num_runs is a genuine improvement for anyone who has been comparing single-run scores. It is an argument about where to look.
- Diff your effective tool surface before and after, from the running agent. Not from your config. Sixteen features that were off because a flag said so may now be on, and the flag will not tell you. This is what feature flags for agents exists to prevent, and it only works if the control is yours.
- Move capability decisions out of the framework's maturity flags. If a tool must stay unavailable, enforce it where the framework cannot graduate it away: an allowlist you own, or the permission boundary around the agent rather than inside it.
- Re-baseline your latency percentiles on the new buckets. Draw a line in your dashboards at the upgrade and do not compare across it. Treat the first week's percentile shift as instrumentation, not performance, until proven otherwise.
- Test the rollback, not just the upgrade. Write a session on the new version and try to read it on the old one. If that fails — and on Firestore it will — your rollback plan is a restore plan, and those have different RTOs; see durable state & resumability.
- Re-run your evals before attributing any change to the model. An earlier compaction trigger and two extra events per response will both show up in output quality and cost. A model that looks different after a framework upgrade probably is not.
- Read changelogs as security feeds. The prompt-injection fix here arrived with no advisory. If your process only ingests CVEs, you are not watching the channel your agent framework actually uses.
The general lesson is the one the stability label obscures. A conventional library's behaviour is bounded by its API, so versioning its API versions its behaviour. An agent framework's behaviour also depends on when it compacts, which tools it exposes by default, what it injects into context and how it serialises state — none of which has a signature. Until frameworks version that surface explicitly, the upgrade note you need is the one about defaults, and it will be the line you skimmed.
FAQ
Should we skip this release?
No — it is a strong release, and the hardening in RunSkillScriptTool alone is a reason to take it. The point is to treat it as a behaviour change with a version number attached rather than a routine minor bump: diff the tool surface, re-baseline latency percentiles, and test the rollback before you need it.
What exactly does "stable" mean here?
By the release notes' own words, that graduated APIs can be used "without experimental warnings." No broader API-compatibility guarantee is stated, and the release lists no deprecations. So read it as a statement about log output and vendor confidence, not as a migration-cost promise.
Which change is most likely to bite us silently?
The disable flags no longer blocking stable features, because it changes what your agent can do and leaves your configuration file looking unchanged. After that, the earlier compaction trigger, because it alters what the agent remembers mid-task and will read as a model or prompt regression.
Can we roll back from 2.14.0?
Not cleanly on Firestore: sessions written by this version cannot be read by 2.13.0 or earlier after a rollback, because event payloads are now stored as JSON strings. Note separately that new PostgreSQL JSON columns are created as json rather than jsonb and existing tables are not migrated, so fresh and upgraded deployments diverge in storage representation.
Does A2A being stable in ADK mean A2A is stable?
No. Those are claims by different parties about different things — an SDK's surface versus a protocol's revision cadence. A stable client binding is useful and does not insulate you from a protocol revision.
Was the prompt-injection fix assigned a CVE?
The release notes reference none; the change is presented as a breaking change that closes a prompt-injection hole. That is the pattern worth planning around rather than criticising — in agent tooling, security fixes frequently ship inside ordinary changelog entries.
Further reading
On this wiki:
- Unpinned Vendor Defaults — when a default changes under you and nothing in your repo moved.
- Rollout & Versioning — upgrading an agent that holds state.
- Long-Lived Sessions & Deploys — the sessions in flight while you ship.
- Context Compaction — why the trigger point is a behaviour setting.
- Measuring Agent Latency — percentiles, buckets and rulers that move.
- Tool Schemas & Contracts — why a structured argument list beats a command string.
Sources:
- google/adk-python v2.14.0 release notes — every change quoted above.
- google/adk-python — the repository.
- google-adk 2.14.0 on PyPI — the published package.