Skip to content

Commit 91b4511

Browse files
committed
release v0.4.0 at 2026-06-10 17:09:22 UTC
1 parent 6d9c525 commit 91b4511

15 files changed

Lines changed: 117 additions & 238 deletions

File tree

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "google-agents-cli",
3-
"version": "0.3.1",
3+
"version": "0.4.0",
44
"description": "Scaffold, develop, evaluate, and deploy AI agents with Google ADK. Bundles 7 skills for the agent development lifecycle.",
55
"author": { "name": "Google LLC" },
66
"homepage": "https://github.com/google/agents-cli",

RELEASE_NOTES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.4.0] - 2026-06-10
6+
- Scaffolded Python templates now use **ADK 2.0 GA**. New `adk`, `adk_a2a`, and `agentic_rag` projects pin `google-adk[gcp]>=2.0.0,<3.0.0`; the `[gcp]` extra restores the OpenTelemetry GCP exporters and bundles the BigQuery client, so the separate `[bigquery-analytics]` extra is no longer needed. Cloud SQL sessions on Cloud Run and GKE keep working under 2.0. The bundled ADK coding skill and its reference docs were refreshed for 2.0.
7+
- https://github.com/google/agents-cli/issues/24
8+
- Agent Runtime deploys no longer overwrite a user-supplied `AGENT_VERSION` (or `NUM_WORKERS`) passed via `--update-env-vars`, matching Cloud Run behavior. The "version not found" warning now names the `pyproject.toml` field to set.
9+
- Fixed a stale `deployment/terraform/dev/` path in the Cloud Trace observability guide so it matches the current `single-project` terraform layout.
10+
511
## [0.3.1] - 2026-06-04
612
- `eval generate` now works on ADK 2.x projects that use built-in tools such as `VertexAiSearchTool`. Raised the `google-cloud-aiplatform` floor to 1.156.0, which carries the SDK fix.
713
- https://github.com/google/agents-cli/issues/27

docs/src/guide/observability/bq-agent-analytics.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ Compared to the always-on [Cloud Trace telemetry](cloud-trace.md), this plugin p
2626
## Prerequisites
2727

2828
* Agent project generated with an **ADK-based** template (e.g., `adk`, `adk_a2a`, `agentic_rag`).
29-
* `google-adk` version `>=1.21.0` (added automatically when you enable the plugin).
3029
* A Google Cloud project with BigQuery API and BigQuery Storage API enabled (typically handled by Terraform).
3130

3231
---
@@ -42,10 +41,7 @@ agents-cli create my-agent \
4241
--bq-analytics
4342
```
4443

45-
This flag:
46-
47-
1. Includes the plugin initialization code in `app/agent.py` and configures environment variables in Terraform.
48-
2. Adds the `google-adk[bigquery-analytics]>=1.21.0` dependency to your project.
44+
This flag includes the plugin initialization code in `app/agent.py` and configures environment variables in Terraform.
4945

5046
---
5147

docs/src/guide/observability/cloud-trace.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ agents-cli playground
6363

6464
## Disable Prompt-Response Logging in Deployments
6565

66-
To disable it in a deployed environment, edit `deployment/terraform/[dev/]service.tf`:
66+
To disable it in a deployed environment, edit `deployment/terraform/single-project/service.tf`:
6767

6868
```hcl
6969
env {
@@ -75,8 +75,8 @@ env {
7575
Then apply:
7676

7777
```bash
78-
cd deployment/terraform
79-
terraform apply -var-file=vars/dev.tfvars
78+
cd deployment/terraform/single-project
79+
terraform apply -var-file=vars/env.tfvars
8080
```
8181

8282
---

docs/src/guide/project-structure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ name = "my-agent"
9898
version = "0.0.1"
9999
requires-python = ">=3.11"
100100
dependencies = [
101-
"google-adk>=1.15.0,<2.0.0",
101+
"google-adk[gcp]>=2.0.0,<3.0.0",
102102
# ... other dependencies
103103
]
104104
```

gemini-extension.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "google-agents-cli",
3-
"version": "0.3.1",
3+
"version": "0.4.0",
44
"description": "Scaffold, develop, evaluate, and deploy AI agents with Google ADK. Bundles 7 skills for the agent development lifecycle."
55
}

skills/google-agents-cli-adk-code/SKILL.md

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ description: >
1212
metadata:
1313
author: Google
1414
license: Apache-2.0
15-
version: 0.3.1
15+
version: 0.4.0
1616
requires:
1717
bins:
1818
- agents-cli
@@ -36,87 +36,33 @@ Do NOT write agent code until a project is scaffolded.
3636
3737
## Quick Reference — Most Common Patterns
3838

39-
### Agent Creation
40-
4139
```python
4240
from google.adk.agents import Agent
4341

44-
root_agent = Agent(
45-
name="my_agent",
46-
model="gemini-flash-latest",
47-
instruction="You are a helpful assistant that ...",
48-
tools=[my_tool],
49-
)
50-
```
51-
52-
> **NEVER change an existing agent's `model=` value unless the user explicitly asks.** If a Gemini model returns a 404, it's almost always a `GOOGLE_CLOUD_LOCATION` issue — run the listing command to verify availability before changing anything. For model docs, fetch `https://adk.dev/agents/models/google-gemini/index.md`.
53-
> ```bash
54-
> uv run --with google-genai python -c "
55-
> from google import genai
56-
> client = genai.Client(vertexai=True, location='global')
57-
> for m in client.models.list(): print(m.name)
58-
> "
59-
> ```
60-
61-
### Basic Tool
62-
63-
```python
64-
from google.adk.tools import FunctionTool
65-
6642
def get_weather(city: str) -> dict:
6743
"""Get current weather for a city."""
6844
return {"city": city, "temp": "22°C", "condition": "sunny"}
6945

70-
weather_tool = FunctionTool(func=get_weather)
71-
```
72-
73-
> **ADK built-in tool imports:** Import the tool instance, not the module.
74-
> ```python
75-
> from google.adk.tools.load_web_page import load_web_page # CORRECT
76-
> from google.adk.tools import load_web_page # WRONG
77-
> ```
78-
79-
### Simple Callback
80-
81-
```python
82-
from google.adk.agents.callback_context import CallbackContext
83-
84-
async def initialize_state(callback_context: CallbackContext) -> None:
85-
state = callback_context.state
86-
if "history" not in state:
87-
state["history"] = []
88-
8946
root_agent = Agent(
9047
name="my_agent",
9148
model="gemini-flash-latest",
92-
instruction="...",
93-
before_agent_callback=initialize_state,
49+
instruction="You are a helpful assistant that ...",
50+
tools=[get_weather],
9451
)
9552
```
96-
---
97-
98-
## Reference Files
99-
100-
| File | When to read |
101-
|------|-------------|
102-
| `references/adk-python.md` | ADK Python API — agents, tools, callbacks, plugins, state, artifacts, context caching, session rewind |
103-
| `references/adk-2.0.md` | **ADK 2.0 Workflow API (experimental pre-GA, opt-in)** — graph-based workflows, nodes, edges, HITL, parallel processing |
10453

105-
### ADK 2.0 Workflows — Opt-in
54+
---
10655

107-
> **The Workflow API is experimental, pre-GA (ADK 2.0).** Do NOT recommend it by default.
108-
>
109-
> **Before suggesting workflow patterns**, explain the following to the user and ask if they want to proceed:
110-
>
111-
> 1. **What it is**: ADK 2.0 introduces a graph-based Workflow API — nodes (functions, LLM agents, tools) connected by edges with conditional routing, fan-out/fan-in parallelism, and human-in-the-loop interrupts.
112-
> 2. **When it helps**: Complex multi-step pipelines needing deterministic control flow, parallel processing of list items, structured approval gates, or retry logic — cases where SequentialAgent/ParallelAgent/LoopAgent feel limiting.
113-
> 3. **Risks**: Pre-GA — APIs may change before GA. Requires `google-adk >= 2.0.0` and **Python >= 3.11**. Incompatible with Live Streaming. Scaffolded projects need `pyproject.toml` changes before upgrade — see the reference file for step-by-step instructions.
114-
>
115-
> **Only read `references/adk-2.0.md` after the user explicitly opts in.** If they decline or are unsure, use the standard ADK 1.x orchestration patterns from `references/adk-python.md` (SequentialAgent, ParallelAgent, LoopAgent, BaseAgent).
56+
## References
11657

117-
## ADK Documentation
58+
The first two are cheatsheets for common patterns; for broad or deep knowledge, go to the source (docs index or installed package).
11859

119-
For the ADK docs index (titles and URLs for fetching documentation pages), use `curl https://adk.dev/llms.txt`.
60+
| Reference | When to read |
61+
|------|-------------|
62+
| `references/adk-python.md` | Core ADK API: `Agent`, tools, callbacks, plugins, state, artifacts, multi-agent systems, `SequentialAgent` / `ParallelAgent` / `LoopAgent`, custom `BaseAgent`. Default for most agents. |
63+
| `references/adk-workflows.md` | Graph-based Workflow API (ADK 2.0): nodes, edges, fan-out/fan-in, HITL, parallel processing. Use when you need explicit graph topology. |
64+
| `curl https://adk.dev/llms.txt` | Docs index (every page title + URL). Fetch it, then `WebFetch` the specific page for anything beyond the cheatsheets. |
65+
| Installed ADK package | Exact signatures and symbols — inspect the source (see "Inspecting ADK Source Code" in `references/adk-python.md`). |
12066

12167
## Related Skills
12268

skills/google-agents-cli-adk-code/references/adk-python.md

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ Rules:
136136

137137
Workflow agents provide deterministic control flow without LLM orchestration.
138138

139+
> These are `BaseAgent`-family composites (`SequentialAgent`, `ParallelAgent`, `LoopAgent`). For the new graph-based Workflow API introduced in ADK 2.0, see `references/adk-workflows.md`.
140+
139141
### SequentialAgent
140142

141143
Executes sub-agents in order. State changes propagate to subsequent agents.
@@ -229,6 +231,25 @@ For a production LoopAgent with EscalationChecker, BuiltInPlanner, and grounding
229231
)
230232
```
231233

234+
4. **Task Delegation (ADK 2.0)**: Set `mode` on a sub-agent for structured, schema-typed delegation — the coordinator gets a `request_task_{name}` tool; the sub-agent returns typed output via the auto-injected `finish_task` tool.
235+
```python
236+
from pydantic import BaseModel
237+
238+
class ResearchOutput(BaseModel):
239+
summary: str
240+
241+
researcher = Agent(
242+
name="researcher",
243+
model="gemini-flash-latest",
244+
mode="task", # 'chat' (default) | 'task' | 'single_turn'
245+
output_schema=ResearchOutput,
246+
description="Researches a topic.", # required for delegation
247+
instruction="Research the topic, then call finish_task.",
248+
)
249+
coordinator = Agent(name="coordinator", model="gemini-flash-latest", sub_agents=[researcher])
250+
```
251+
Modes: `task` (multi-turn, structured I/O) · `single_turn` (autonomous, no user turn). Sub-agents need a `description`; default I/O schemas (`goal`/`background` in, `result` out) are used if none set. Disabled inside graph `Workflow`s.
252+
232253
---
233254

234255
## 5. Building Custom Agents (`BaseAgent`)
@@ -407,6 +428,23 @@ def needs_approval(amount: float, **kwargs) -> bool:
407428
transfer_tool = FunctionTool(transfer_money, require_confirmation=needs_approval)
408429
```
409430

431+
### Human-in-the-Loop (pause & resume)
432+
433+
Pause a run to ask the user something, then resume. This is a general runtime feature (not workflow-specific). Enable resumption at the app level:
434+
435+
```python
436+
from google.adk.apps import App, ResumabilityConfig
437+
438+
app = App(name="my_app", root_agent=root_agent,
439+
resumability_config=ResumabilityConfig(is_resumable=True))
440+
```
441+
442+
- **Let the model ask:** add the built-in `request_input` tool (`from google.adk.tools import request_input`) to `tools=` — the model calls it when it needs clarification.
443+
- **Approval gate inside a tool:** `tool_context.request_confirmation(hint="Approve this transfer?")`, or `FunctionTool(fn, require_confirmation=...)` (above).
444+
- **Custom long-running tool:** wrap a function with `LongRunningFunctionTool(fn)` to pause until an external result arrives.
445+
446+
The user's reply is read from `ctx.resume_inputs` (available on `ToolContext` and `CallbackContext`). Inside graph workflows the same mechanism is node-based — see `adk-workflows.md` §7.
447+
410448
### Tool Authentication
411449

412450
| Auth Type | Pattern |
@@ -560,7 +598,7 @@ memory_service = InMemoryMemoryService()
560598
# Add session to memory after conversation
561599
await memory_service.add_session_to_memory(session)
562600
# Search later
563-
results = await memory_service.search_memory(app_name, user_id, "query")
601+
results = await memory_service.search_memory(app_name=app_name, user_id=user_id, query="query")
564602
```
565603

566604
#### Memory Bank (Long-term Memory)
@@ -612,7 +650,8 @@ app = App(
612650
Prevent context overflow on long sessions by summarizing older events in a sliding window:
613651

614652
```python
615-
from google.adk.apps import App, EventsCompactionConfig
653+
from google.adk.apps import App
654+
from google.adk.apps.app import EventsCompactionConfig
616655
from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
617656
from google.adk.models import Gemini
618657

@@ -650,31 +689,34 @@ app = App(name="my_custom_agent", root_agent=root_agent)
650689
from google.adk.agents.callback_context import CallbackContext
651690
from google.adk.models.llm_request import LlmRequest
652691
from google.adk.models.llm_response import LlmResponse
692+
from google.adk.tools import BaseTool, ToolContext
653693
from google.genai import types as genai_types
654694

695+
# Callbacks are invoked by keyword — parameter names must match exactly.
696+
655697
# Agent lifecycle
656-
async def before_agent_callback(ctx: CallbackContext) -> None:
657-
ctx.state["started"] = True
698+
async def before_agent_callback(callback_context: CallbackContext) -> None:
699+
callback_context.state["started"] = True
658700

659-
async def after_agent_callback(ctx: CallbackContext) -> genai_types.Content | None:
701+
async def after_agent_callback(callback_context: CallbackContext) -> genai_types.Content | None:
660702
# Return None to continue, or Content to override
661703
return None
662704

663705
# Model interaction
664-
async def before_model_callback(ctx: CallbackContext, request: LlmRequest) -> LlmResponse | None:
706+
async def before_model_callback(callback_context: CallbackContext, llm_request: LlmRequest) -> LlmResponse | None:
665707
# Return None to continue, or LlmResponse to skip model call
666708
return None
667709

668-
async def after_model_callback(ctx: CallbackContext, response: LlmResponse) -> LlmResponse | None:
710+
async def after_model_callback(callback_context: CallbackContext, llm_response: LlmResponse) -> LlmResponse | None:
669711
# Return None to continue, or modified LlmResponse
670712
return None
671713

672714
# Tool execution
673-
async def before_tool_callback(ctx: CallbackContext, tool_name: str, args: dict) -> dict | None:
715+
async def before_tool_callback(tool: BaseTool, args: dict, tool_context: ToolContext) -> dict | None:
674716
# Return None to continue, or dict to skip tool and use as result
675717
return None
676718

677-
async def after_tool_callback(ctx: CallbackContext, tool_name: str, result: dict) -> dict | None:
719+
async def after_tool_callback(tool: BaseTool, args: dict, tool_context: ToolContext, tool_response: dict) -> dict | None:
678720
# Return None to continue, or modified dict
679721
return None
680722
```
@@ -683,9 +725,9 @@ async def after_tool_callback(ctx: CallbackContext, tool_name: str, result: dict
683725

684726
```python
685727
# Initialize state before agent runs
686-
async def init_state(ctx: CallbackContext) -> None:
687-
if "preferences" not in ctx.state:
688-
ctx.state["preferences"] = {}
728+
async def init_state(callback_context: CallbackContext) -> None:
729+
if "preferences" not in callback_context.state:
730+
callback_context.state["preferences"] = {}
689731

690732
agent = Agent(before_agent_callback=init_state, ...)
691733
```
@@ -856,7 +898,7 @@ google/adk/
856898
├── tools/ # Tool implementations (FunctionTool, google_search, etc.)
857899
├── sessions/ # Session services (InMemory, Database, VertexAI)
858900
├── memory/ # Memory services
859-
├── runners/ # Runner and execution engine
901+
├── runners.py # Runner and execution engine
860902
├── events/ # Event types and actions
861903
├── models/ # Model integrations (Gemini, LiteLLM, etc.)
862904
├── code_executors/ # Code execution (BuiltInCodeExecutor, etc.)

0 commit comments

Comments
 (0)