Recent development · Practical technical guide · 18 October 2026

google-adk 2.12.0 shipped on 13 October 2026. What require_confirmation on @node and FunctionNode does, how the Model Armor plugin now screens tool output through after_tool_callback, the new runtime service account for Agent Engine deploys, how to read the 40 percent claim, and what to re-test.

What shipped

The google-adk 2.12.0 release was published on GitHub on 13 October 2026 at 16:35 UTC and on PyPI seven minutes later; the previous release, 2.11.0, was 2 October, and the package requires Python 3.11 or newer with Python 3.15 now supported. The release notes name five highlights: a 40 percent cut in time to first model request in long sessions, tool-output screening through after_tool_callback, human confirmation before workflow nodes through require_confirmation, custom service accounts for Agent Engine deployments, and Python 3.15 support. Behind them are roughly thirty features and well over a hundred fixes. This article reads the five highlights against their commits and the ADK documentation, because two of the headlines mean something more specific than they sound.

Confirmation gates on workflow nodes

ADK has had tool confirmation since Python 1.14: wrapping a function in FunctionTool with require_confirmation set to true pauses the tool for a yes or no answer, and the documentation marks the feature experimental. What 2.12.0 adds, in the commit of 12 October, is the same semantics for workflow graph nodes. The parameter is accepted by the node decorator, the node and build_node helpers, and FunctionNode, and it takes either a boolean or a predicate, sync or async, that receives the bound arguments of the function. When it is set, the decorator defaults rerun_on_resume to true; FunctionNode requires it and raises a WorkflowConfigurationError otherwise. At runtime the workflow pauses with a request-input interrupt named after the node path; an approval runs the function exactly once, and a rejection skips it and emits a result stating that the tool call is rejected.

Example shapes from the adk-agent-builder reference in commit 988fd1a; the predicate form receives the bound arguments, plus ctx or node_input if declared.

from google.adk.workflows import node   # import path per the 2.12.0 skill reference; check your install

@node(require_confirmation=True)
def delete_file(path: str) -> str:
    return f"Deleted {path}"

@node(require_confirmation=lambda amount: amount > 1000)
def transfer_funds(amount: int) -> str:
    return f"Transferred {amount}"

The predicate form is the interesting one for architecture: it puts the approval threshold in code next to the node rather than in a prompt, which is the same principle as the pivot approval in agent-proposed saga plans. A related fix in the same release, from 8 October, makes a confirmed tool run once per approval even when the confirmation response arrives again in a later user event, such as a client retry or a resubmitted form. If you built your own deduplication around confirmations, re-test it against the new behaviour.

Tool output screening with Model Armor

The headline about after_tool_callback is easy to misread. The callback itself is not new: the callbacks reference lists after_tool_callback on LlmAgent with the signature tool, args, tool_context and tool_response, next to before_tool_callback and on_tool_error_callback. The 2.12.0 change, in the commit of 6 October, is that the ModelArmorPlugin now implements it. The plugin previously screened user input and model output against Google Cloud Model Armor templates; it now also screens tool output, governed by its own template name, splitting oversized text into overlapping chunks and skipping raw bytes and non-text media. A blocked tool output is replaced by a plain error dictionary returned to the model, and, unlike blocked input and model output, it does not carry the model_armor_blocked marker in custom metadata, so application code that detects blocks by that marker will not see tool blocks. The commit also tightens a rule: a MATCH_FOUND verdict is now blocked even when the invocation result was not SUCCESS and blocking on screening failure is disabled.

The reason to care is that tool results are the main indirect prompt injection surface: a web page, a document or a database row flows into the context through a tool. Screening that path with the same policy as user input closes a gap that many deployments left open.

Runtime service accounts for Agent Engine deploys

The deployment highlight is a small change with a large security effect. The commit of 8 October adds a service_account setting to the Agent Engine deployment path: it can be given as an argument to the deploy command, resolved from the GOOGLE_CLOUD_SERVICE_ACCOUNT environment variable, or read from the service_account field of the agent platform configuration file, with the explicit argument overriding the file. The code validates that the value looks like a service account email and maps it to the runtime identity of the deployed agent, which the commit distinguishes from the build service account used by Cloud Build. Until now agents deployed this way ran with the platform default identity; a dedicated account per agent lets you grant exactly the permissions its tools need, which is the least-privilege shape described in workload identity for LLM applications.

The performance claim, read precisely

Measurement in the commitBeforeAfter
First model request after 50 turns64 ms36 ms
First model request after 150 turns200 ms122 ms
Whole 158-turn run65.6 s56.1 s
Import ADK in a new process1.22 s0.97 s
New process to first model request3.07 s3.09 s

The commit of 7 October explains the mechanism: InMemorySessionService deep-copied the entire session on every read, and importing ADK eagerly loaded OpenTelemetry, authentication and the LLM flow modules. The change copies only the returned events on get_session and none on list_sessions, speeds up Event and Session copies, and defers imports until first use. The benchmark, as stated in the commit, used a no-op model and instant tools and measured ADK overhead only, with garbage collection disabled for the first two rows. Read it accordingly: the gain is in framework overhead on long in-memory sessions, which matters for evaluation harnesses and tests more than for production agents whose latency is dominated by the model. New-process start to first request did not improve. None of these numbers were reproduced for this article.

Other changes worth a re-test

ChangeWhy it may affect you
Sibling tool tasks are cancelled when a child-originated cancellation occursParallel tool batches no longer leave orphaned tasks; timing-dependent tests may change
Mutating dev endpoints and built-in agents restricted to loopback by default; 403 on non-loopbackDevelopment servers bound to an interface for remote access need an explicit setting
OAuth2 secrets kept out of run, run_sse, run_live and session endpointsClients that read credentials from those responses stop working, by design
The 25-round tool cap for agents with both output_schema and tools is revertedLong tool loops are possible again; keep your own step budget
Compaction skips instead of failing when summarisation errors or cannot shrink the requestContext growth may continue silently; watch token metrics
A2A part converter supports tool_call and tool_response; namespaced mode for forwarded A2A context idsInterop between ADK agents and other A2A agents changes shape
adk run gains a state_file option; migration to google-cloud-aiplatform 2.2Dependency bumps in constrained environments

Upgrade checklist

  1. Pin google-adk 2.12.0 explicitly and run the full evaluation suite before and after; the loopback and secret-handling changes are the ones most likely to surface in integration tests.
  2. If you use workflow graphs, decide which nodes need require_confirmation and whether a predicate on the arguments expresses the policy better than a boolean.
  3. If you use the Model Armor plugin, set the tool-output template and update any code that relies on the model_armor_blocked marker to also handle the error dictionary that blocked tool outputs return.
  4. Create a dedicated service account per Agent Engine deployment and set it through the configuration file so it is reviewed with the code.
  5. Re-test parallel tool cancellation and any custom deduplication of confirmations.

What is not verified here

The documentation site had not yet published a page for node-level confirmation when this was written; the description above comes from the release notes, the commit and the skill reference it updated, and import paths should be checked against the installed package. The benchmark numbers are quoted from the commit and were not reproduced. A report in the TypeScript port about confirmation on workflow tool nodes was not examined and does not concern the Python release.

Use require_confirmation predicates on workflow nodes, enable tool-output screening, deploy with a dedicated service account, and treat the 40 percent figure as framework overhead on long in-memory sessions.