Highlights
v2.7.0 adds Anthropic Claude as a first-party model, search-gated tool discovery for large tool catalogs, an experimental classifier API for workflow routing, and a per-invocation budget on model calls. It also switches telemetry to the OpenTelemetry GenAI semantic conventions by default, which is a breaking change for anyone consuming ADK traces.
- Anthropic Claude models (experimental):
model/anthropicmodelimplementsmodel.LLMover the Anthropic Messages API and Vertex AI, with streaming, tool calling, image and PDF input, extended and adaptive thinking, structured output and prompt caching. Seeexamples/anthropic. (#1866) - Search-gated tool discovery:
tool/toolsearchwraps anytool.Toolsetso the model starts with asearch_toolstool plus a configured core set, and the tools it finds are declared from the next model step on. This keeps a large MCP catalog out of every request. Seeexamples/toolsearch. (#1734, #1735) - Classifiers (experimental):
exp/classifierdefines aClassifierthat answers typed Choice, Binary and Score questions with probabilities. It ships with a client for TypeSafe's Jev decision models (exp/classifier/typesafe), anLLMClassifierbacked by anymodel.LLM, and a workflowNodethat routes on the answer, matching adk-python'sClassifierNode. (#2003, #2005, #2035) - Model-call budget:
RunConfig.MaxLLMCallsbounds the model calls one invocation may make, 500 by default, and ends the run withagent.ErrLLMCallsLimitExceededwhen the budget is spent. Matches adk-python'smax_llm_calls. This changes behavior for existing users, see below. (#1412) - Telemetry: traces follow OpenTelemetry GenAI semantic conventions v2 by default, as adk-python does. This is breaking for telemetry consumers, see below. (#1635)
- OpenAI-compatible models: images and files in
InlineDataandFileDataparts are sent on both the Responses and Chat Completions endpoints (#1543). A response schema title that is not a valid format name falls back toadk_responseinstead of a 400 from the API (#1912). AGenerateContentConfigfield that a newer genai adds is refused withErrUnsupportedConfigFieldinstead of being dropped silently (#1922). - Gemini built-in tools:
geminitool.GoogleMaps,geminitool.UrlContextandgeminitool.EnterpriseWebSearch. (#2026) - MCP: with
Config.Authset, each user gets their own MCP session, so servers that bind a session to the user who opened it stop answering other users with 403 (#1755). MCP HTTP requests identify ADK inUser-AgentandX-Goog-Api-Client, as model calls already do (#1862). - Auth fix: credentials from
auth.ADC()andauth.ServiceAccount()failed every token mint withcontext canceledon local gcloud ADC and impersonated service accounts. Services on GCE or with a key file were not affected. (#1904) - Tool auth groundwork:
tool/toolauthadds adk-python's auth data model and wire format foradk_request_credential, so requests, replies and credential keys agree with adk-python and ADK Web. Nothing uses it yet. (#2032) - Reliability:
- Workflow joins resume with completed predecessors restored instead of rerunning them. (#1572)
LoopAgentstops on context cancellation.WithAgentTimeoutandWithAgentCancelwork on tool and callback contexts instead of returning nil. (#1810, #1604)- Artifacts saved in agent and model callbacks are recorded in
ArtifactDelta.OutputKeyis saved when a before-agent callback short-circuits. (#1878, #1800, #1963) - Optional instruction placeholders such as
{key?}and{artifact.name?}surface infrastructure errors instead of rendering an empty string. This changes behavior, see below. (#1748) - Vertex AI sessions persist live transcriptions. In-memory memory search skips thought parts. (#1964, #1975)
- Streaming function tools preserve consumer panics.
agenttoolkeeps code-execution output in sub-agent results. Running an agent withoutRunreturns an error instead of doing nothing. (#1961, #1860, #1850) launcher.Config.TelemetryOptionshonorsWithOtelToCloud. Live reconnect matches close code 1008 by type, not by error text. (#1968, #1993)
- CLI:
adkgo deploy agentengine --mem_deployno longer defaults Memory Bank to gemini-2.5-flash, which Vertex AI stopped serving to new projects. Memory Bank applies its own default model unless--mem_modelis set. (#1902) - Agent Analytics plugin (
plugin/agentanalytics, its own module and tag): aligned with adk-python's schema and event vocabulary, with rich session, HITL, A2A and workflow events, GCS offloading of multimodal content, opt-in exactly-once delivery, drop statistics, hierarchical span ids with latency and time-to-first-token, and 25 pre-built per-event BigQuery views. (#1786, #1787, #1788, #1789, #1790, #1791 and follow-up fixes)
Breaking changes
- Telemetry schema: ADK now emits the OpenTelemetry GenAI semantic conventions v2. The legacy log events are replaced by one
gen_ai.client.inference.operation.detailsevent per model call, message content on spans is a structured value rather than a JSON string,execute_toolrecords arguments and results only when span content capture is on (undergen_ai.tool.call.*), and an LLM-agent root gets a newinvoke_workflowparent span. SetADK_TELEMETRY_SCHEMA_VERSION_OPT_IN=otel_semconv_1_36to restore the previous format, supported until at least March 31, 2027. (#1635) - Model calls are capped at 500 per invocation: a run that makes more than 500 model calls now ends with an error wrapping
agent.ErrLLMCallsLimitExceeded. Raise the cap withRunConfig.MaxLLMCallsorADK_MAX_LLM_CALLS, or setMaxLLMCallsto-1for no limit. Unlike adk-python,0means the default, not unlimited. (#1412) - Optional instruction placeholders propagate errors:
{key?}and{artifact.name?}render empty only when the key or artifact is missing (session.ErrStateKeyNotExist,fs.ErrNotExist). Any other error from the session or artifact service now fails the run. A customartifact.Servicemust wrapfs.ErrNotExistfor missing files, and anagenttoolsub-agent with an optional artifact placeholder now errors when the root runner has no artifact service. (#1748) - Go 1.26.10 is required:
go.modmoves from 1.26.6 to 1.26.10. (#1916) - Agent Analytics plugin defaults: the default table name is
agent_eventsinstead ofevents, existing tables are upgraded additively on startup unlessDisableSchemaUpgradeis set, the per-event views are created on startup unlessDisableCreateViewsis set, and granular event types (STATE_DELTA,AGENT_TRANSFER,HITL_*,NODE_OUTPUT, …) replace the genericEVENTrow. These apply when the plugin module is next tagged, not to the corev2.7.0tag. (#1786, #1788, #1791)
Smaller behavior changes:
geminitool.GoogleSearchreturns an error on a non-Gemini model, and on a Gemini 1.x model combined with other tools. (#2026)launcher: passingtelemetry.WithOtelToCloud(true)inTelemetryOptionsnow exports to Google Cloud and needs credentials at startup, where it used to start with export silently off. (#1968)openaimodel: a config field added by a genai release newer than v1.74.0 is refused withErrUnsupportedConfigField. Configs valid today are unaffected. (#1922)mcptoolsetwithConfig.Authopens one session per distinct credential, closes sessions idle for 10 minutes, and caps the pool at 64. WithoutAuthnothing changes. (#1755)LoopAgentyields the context error once and stops when its context is cancelled, where it used to keep looping if no pass yielded an event. (#1810)- An agent callback that saves an artifact and returns nil now yields one event carrying the
ArtifactDelta, where it yielded none. (#1878) - The in-memory memory service no longer stores or matches thought parts, and an event with only thought text is not stored. (#1975)
- Deprecated:
artifact.SaveRequest.Version.Savehas never read it. (#1985)
All changes
What's Changed
- feat(tool): add search-gated tool discovery by @wolo-lab in #1734
- docs(examples/toolsearch): add a tool search sample by @wolo-lab in #1735
- fix(agent): report an error when an agent without Run is run by @wolo-lab in #1850
- docs(artifact): fix service references in doc comments by @ktsoator in #1775
- feat(agentanalytics): align schema, event vocabulary, redaction, and core contract with adk-python by @haiyuan-eng-google in #1786
- fix(loopagent): stop on context cancellation by @anzal1 in #1810
- feat(runner): bound model calls per invocation with RunConfig.MaxLLMCalls by @venkat-uk in #1412
- fix(llminternal): prevent silent context degradation by propagating systemic state failures by @karthik-0306 in #1748
- test(model/gemini): pin the last citation and accepting AutomaticContinuation by @baptmont in #1825
- test(llminternal): match isResumable's doc and test table to the errors it sees by @harshitwandhare in #1750
- docs(loopagent): say the context is checked before each pass by @anzal1 in #1861
- refactor(workflow): remove redundant goroutine in scheduleRetry by @moodbased in #1849
- docs(compaction): list the GenerateContentConfig fields the summarizer uses by @karolpiotrowicz in #1828
- fix(agenttool): preserve code output in sub-agent results by @ktsoator in #1860
- feat(mcptoolset): identify ADK in the User-Agent of MCP HTTP requests by @wolo-lab in #1862
- fix(mcptoolset): stop using context.Background() in connectionRefresher.Close by @wolo-lab in #1844
- feat(model/openaimodel): support image/file input via genai InlineData/FileData parts by @tonydzi in #1543
- feat(agentanalytics): add concurrency-safe trace manager, latency_ms, and streaming TTFT by @haiyuan-eng-google in #1787
- fix(llminternal): record model callback artifact saves on the event by @Vivek1106-04 in #1800
- fix(agent): record artifact-only deltas from before/after agent callbacks by @anzal1 in #1878
- fix(workflow): restore completed predecessors when resuming joins by @lucky798213 in #1572
- fix(agent): make WithAgentTimeout work on tool and callback contexts by @jaideeppyne in #1604
- test(model/gemini): pin that MAX_TOKENS after CONTINUATION is not resumed by @beiryu in #1872
- chore(deps): bump the go-minor-patch group with 2 updates by @dependabot[bot] in #1901
- chore(deps): bump golang.org/x/net to v0.60.0 in agentanalytics by @wojtas000 in #1908
- feat(telemetry)!: default to experimental GenAI semconv, with ADK_TELEMETRY_SCHEMA_VERSION_OPT_IN=otel_semconv_1_36 rollback by @RKest in #1635
- fix(adkgo/deploy): stop defaulting Memory Bank to gemini-2.5-flash by @wojtas000 in #1902
- feat(agentanalytics): emit rich session/HITL/A2A/workflow events and classify tool_origin by @haiyuan-eng-google in #1788
- Upgrading go to 1.26.10 by @kdroste-google in #1916
- fix(agentanalytics): redact credentials when a value ends in a key name by @haiyuan-eng-google in #1863
- feat(agentanalytics): add race-free GCS multimodal offloading and ObjectRef support by @haiyuan-eng-google in #1789
- chore(v2): update Go version requirements in documentation by @ktsoator in #1926
- fix(agentanalytics): preserve live spans when tasks resume by @jabrailkhalil in #1910
- fix(agentanalytics): never mark workflow agents taskDelegated by @haiyuan-eng-google in #1935
- feat(agentanalytics): pause GCS uploads after batch timeout and preserve run-end flush budget by @haiyuan-eng-google in #1936
- feat(agentanalytics): add DropStats, ExactlyOnceDelivery, and schema setup hardening by @haiyuan-eng-google in #1790
- fix(agentanalytics): preserve invocation spans for late callbacks by @jabrailkhalil in #1911
- fix(agentanalytics): ExactlyOnceDelivery and DropStats follow-ups from #1790 by @haiyuan-eng-google in #1943
- feat(agentanalytics): add pre-built per-event BigQuery analytics views by @haiyuan-eng-google in #1791
- chore(deps): bump the go-minor-patch group with 3 updates by @dependabot[bot] in #1969
- fix(agentanalytics): log a deferred GCS retry only when it is requeued by @leilei3167 in #1941
- fix(session/vertexai): persist live transcriptions by @DisturbedCrow in #1964
- fix(agentanalytics): pause stalled run-end uploads across batches by @ktsoator in #1947
- fix(llmagent): save output_key when a before-agent callback short-circuits by @anzal1 in #1963
- fix(functiontool): preserve streaming consumer panics by @jabrailkhalil in #1961
- fix(launcher): honor WithOtelToCloud in launcher.Config.TelemetryOptions by @Saurav-Gupta-9741 in #1968
- fix(memory): skip thought parts in in-memory search and preloaded memories by @Vivek1106-04 in #1975
- chore(deps): bump the go_modules group across 1 directory with 2 updates by @dependabot[bot] in #1934
- fix(auth): keep the init context alive so token sources can refresh by @wojtas000 in #1904
- fix(openaimodel): use adk_response when the schema title is not a valid format name by @wojtas000 in #1912
- fix(openaimodel): refuse config fields genai adds before they are supported by @wojtas000 in #1922
- fix(ci): stop every CI run from building with an empty Go cache by @baptmont in #1972
- fix(agentanalytics): report the right terminal row in more failure cases by @haiyuan-eng-google in #1952
- feat(model/anthropicmodel): add Anthropic Claude model support by @ScottMansfield in #1866
- docs(artifact): deprecate SaveRequest.Version by @wojtas000 in #1985
- fix(agentanalytics): cap deferred retry upload budget and pause on shorter run-end stalls by @haiyuan-eng-google in #1955
- fix(llminternal): match close code 1008 by type in isResumable by @wojtas000 in #1993
- fix(agentanalytics): tidy span bookkeeping, comments and tests by @haiyuan-eng-google in #1953
- fix(agentanalytics): release deferred upload reservations on append or Close panic by @haiyuan-eng-google in #1954
- fix(mcptoolset): give each user its own MCP session with Config.Auth by @Vivek1106-04 in #1755
- feat(exp): add classifier interface and TypeSafe Jev decision model client by @rafal-glowinski in #2003
- Added google_maps, url_contex + gemini guards by @kdroste-google in #2026
- feat(exp): add workflow routing Node for classifiers by @rafal-glowinski in #2005
- feat(exp): add LLMClassifier backed by model.LLM by @rafal-glowinski in #2035
- feat(toolauth): add adk-python's auth data model and wire format by @jjsasha63 in #2032
- Update version.go by @baptmont in #2031
New Contributors
- @haiyuan-eng-google made their first contribution in #1786
- @venkat-uk made their first contribution in #1412
- @tonydzi made their first contribution in #1543
- @jaideeppyne made their first contribution in #1604
- @beiryu made their first contribution in #1872
- @DisturbedCrow made their first contribution in #1964
- @Saurav-Gupta-9741 made their first contribution in #1968
- @ScottMansfield made their first contribution in #1866
- @rafal-glowinski made their first contribution in #2003
Full Changelog: v2.6.0...v2.7.0
New Contributors
- @haiyuan-eng-google made their first contribution in #1786
- @venkat-uk made their first contribution in #1412
- @tonydzi made their first contribution in #1543
- @jaideeppyne made their first contribution in #1604
- @beiryu made their first contribution in #1872
- @DisturbedCrow made their first contribution in #1964
- @Saurav-Gupta-9741 made their first contribution in #1968
- @ScottMansfield made their first contribution in #1866
- @rafal-glowinski made their first contribution in #2003