Skip to content

Commit 8ddbda4

Browse files
authored
Merge branch 'main' into feature/support-single-agent-transcription
2 parents 69d24dd + 3814d8b commit 8ddbda4

29 files changed

+1301
-126
lines changed

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,20 @@ Thumbs.db
9898
*.bak
9999
*.tmp
100100
*.temp
101+
102+
# AI Coding Tools - Project-specific configs
103+
# Developers should symlink or copy AGENTS.md and add their own overrides locally
104+
.claude/
105+
CLAUDE.md
106+
.cursor/
107+
.cursorrules
108+
.cursorignore
109+
.windsurfrules
110+
.aider*
111+
.continue/
112+
.codeium/
113+
.githubnext/
114+
.roo/
115+
.rooignore
116+
.bolt/
117+
.v0/

contributing/samples/adk_agent_builder_assistant/agent_builder_assistant.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
from google.adk.tools import FunctionTool
2727
from google.genai import types
2828

29-
from .sub_agents.adk_knowledge_agent import create_adk_knowledge_agent
3029
from .sub_agents.google_search_agent import create_google_search_agent
3130
from .sub_agents.url_context_agent import create_url_context_agent
3231
from .tools.cleanup_unused_files import cleanup_unused_files
3332
from .tools.delete_files import delete_files
3433
from .tools.explore_project import explore_project
3534
from .tools.read_config_files import read_config_files
3635
from .tools.read_files import read_files
36+
from .tools.search_adk_knowledge import search_adk_knowledge
3737
from .tools.search_adk_source import search_adk_source
3838
from .tools.write_config_files import write_config_files
3939
from .tools.write_files import write_files
@@ -69,11 +69,9 @@ def create_agent(
6969
# - Maintains compatibility with existing ADK tool ecosystem
7070

7171
# Built-in ADK tools wrapped as sub-agents
72-
adk_knowledge_agent = create_adk_knowledge_agent()
7372
google_search_agent = create_google_search_agent()
7473
url_context_agent = create_url_context_agent()
7574
agent_tools = [
76-
AgentTool(adk_knowledge_agent),
7775
AgentTool(google_search_agent),
7876
AgentTool(url_context_agent),
7977
]
@@ -99,6 +97,8 @@ def create_agent(
9997
FunctionTool(cleanup_unused_files),
10098
# ADK source code search (regex-based)
10199
FunctionTool(search_adk_source), # Search ADK source with regex
100+
# ADK knowledge search
101+
FunctionTool(search_adk_knowledge), # Search ADK knowledge base
102102
]
103103

104104
# Combine all tools

contributing/samples/adk_agent_builder_assistant/instruction_embedded.template

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ tools:
272272

273273
### ADK Knowledge and Research Tools
274274

275-
**Default research tool**: Use `adk_knowledge_agent` first for ADK concepts, APIs,
275+
**Default research tool**: Use `search_adk_knowledge` first for ADK concepts, APIs,
276276
examples, and troubleshooting. Switch to the tools below only when the
277-
knowledge agent lacks the needed information.
277+
knowledge base lacks the needed information.
278278

279279
- `search_adk_source`: Regex search across ADK source for classes, methods, and
280280
signatures; follow up with `read_files` for full context.
@@ -287,7 +287,7 @@ need agent-type clarification, want best practices, hit errors, express
287287
uncertainty about architecture, or you otherwise need authoritative guidance.
288288

289289
**Recommended research sequence** (stop once you have enough information):
290-
1. `adk_knowledge_agent`
290+
1. `search_adk_knowledge`
291291
2. `search_adk_source` → `read_files`
292292
3. `google_search_agent`
293293
4. `url_context_agent`

contributing/samples/adk_agent_builder_assistant/sub_agents/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414

1515
"""Sub-agents for Agent Builder Assistant."""
1616

17-
from .adk_knowledge_agent import create_adk_knowledge_agent
1817
from .google_search_agent import create_google_search_agent
1918
from .url_context_agent import create_url_context_agent
2019

2120
__all__ = [
22-
'create_adk_knowledge_agent',
2321
'create_google_search_agent',
2422
'create_url_context_agent',
2523
]

contributing/samples/adk_agent_builder_assistant/sub_agents/adk_knowledge_agent.py

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""ADK knowledge search tool."""
16+
17+
from typing import Any
18+
import uuid
19+
20+
import requests
21+
22+
KNOWLEDGE_SERVICE_APP_URL = "https://adk-agent-builder-knowledge-service-654646711756.us-central1.run.app"
23+
KNOWLEDGE_SERVICE_APP_NAME = "adk_knowledge_agent"
24+
KNOWLEDGE_SERVICE_APP_USER_NAME = "agent_builder_assistant"
25+
26+
HEADERS = {
27+
"Content-Type": "application/json",
28+
"Accept": "application/json",
29+
}
30+
31+
32+
def search_adk_knowledge(
33+
query: str,
34+
) -> dict[str, Any]:
35+
"""Searches ADK knowledge base for relevant information.
36+
37+
Args:
38+
query: The query to search in ADK knowledge base.
39+
40+
Returns:
41+
A dict with status and the response from the knowledge service.
42+
"""
43+
# Create a new session
44+
session_id = uuid.uuid4()
45+
create_session_url = f"{KNOWLEDGE_SERVICE_APP_URL}/apps/{KNOWLEDGE_SERVICE_APP_NAME}/users/{KNOWLEDGE_SERVICE_APP_USER_NAME}/sessions/{session_id}"
46+
47+
try:
48+
create_session_response = post_request(
49+
create_session_url,
50+
{},
51+
)
52+
except requests.exceptions.RequestException as e:
53+
return error_response(f"Failed to create session: {e}")
54+
session_id = create_session_response["id"]
55+
56+
# Search ADK knowledge base
57+
search_url = f"{KNOWLEDGE_SERVICE_APP_URL}/run"
58+
try:
59+
search_response = post_request(
60+
search_url,
61+
{
62+
"app_name": KNOWLEDGE_SERVICE_APP_NAME,
63+
"user_id": KNOWLEDGE_SERVICE_APP_USER_NAME,
64+
"session_id": session_id,
65+
"new_message": {"role": "user", "parts": [{"text": query}]},
66+
},
67+
)
68+
except requests.exceptions.RequestException as e:
69+
return error_response(f"Failed to search ADK knowledge base: {e}")
70+
return {
71+
"status": "success",
72+
"response": search_response,
73+
}
74+
75+
76+
def error_response(error_message: str) -> dict[str, Any]:
77+
"""Returns an error response."""
78+
return {"status": "error", "error_message": error_message}
79+
80+
81+
def post_request(url: str, payload: dict[str, Any]) -> dict[str, Any]:
82+
"""Executes a POST request."""
83+
response = requests.post(url, headers=HEADERS, json=payload, timeout=60)
84+
response.raise_for_status()
85+
return response.json()

contributing/samples/bigquery/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ distributed via the `google.adk.tools.bigquery` module. These tools include:
2121

2222
Fetches metadata about a BigQuery table.
2323

24+
5. `get_job_info`
25+
Fetches metadata about a BigQuery job.
26+
2427
5. `execute_sql`
2528

2629
Runs or dry-runs a SQL query in BigQuery.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# JSON Passing Agent
2+
3+
This sample demonstrates how to pass structured JSON data between agents. The example uses a pizza ordering scenario where one agent takes the order and passes it to another agent for confirmation.
4+
5+
## How to run
6+
7+
1. Run the agent:
8+
```bash
9+
adk run .
10+
```
11+
12+
2. Talk to the agent:
13+
```
14+
I want to order a pizza
15+
```
16+
17+
## Example conversation
18+
```
19+
[user]: I'd like a large pizza with pepperoni and mushrooms on a thin crust.
20+
[order_intake_agent]: (tool call to get available sizes, crusts, toppings)
21+
[order_intake_agent]: (returns a PizzaOrder JSON)
22+
[order_confirmation_agent]: (tool call to calculate_price)
23+
[order_confirmation_agent]: You ordered a large thin crust pizza with pepperoni and mushrooms. The total price is $15.00.
24+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from . import agent
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from google.adk import Agent
16+
from google.adk.agents import sequential_agent
17+
from google.adk.tools import tool_context
18+
from pydantic import BaseModel
19+
20+
SequentialAgent = sequential_agent.SequentialAgent
21+
ToolContext = tool_context.ToolContext
22+
23+
24+
# 1. Define the data structure for the pizza order.
25+
class PizzaOrder(BaseModel):
26+
"""A data class to hold the details of a pizza order."""
27+
28+
size: str
29+
crust: str
30+
toppings: list[str]
31+
32+
33+
# 2. Define tools for the order intake agent.
34+
def get_available_sizes() -> list[str]:
35+
"""Returns the available pizza sizes."""
36+
return ['small', 'medium', 'large']
37+
38+
39+
def get_available_crusts() -> list[str]:
40+
"""Returns the available pizza crusts."""
41+
return ['thin', 'thick', 'stuffed']
42+
43+
44+
def get_available_toppings() -> list[str]:
45+
"""Returns the available pizza toppings."""
46+
return ['pepperoni', 'mushrooms', 'onions', 'sausage', 'bacon', 'pineapple']
47+
48+
49+
# 3. Define the order intake agent.
50+
# This agent's job is to interact with the user to fill out a PizzaOrder object.
51+
# It uses the output_schema to structure its response as a JSON object that
52+
# conforms to the PizzaOrder model.
53+
order_intake_agent = Agent(
54+
name='order_intake_agent',
55+
model='gemini-2.5-flash',
56+
instruction=(
57+
"You are a pizza order intake agent. Your goal is to get the user's"
58+
' pizza order. Use the available tools to find out what sizes, crusts,'
59+
' and toppings are available. Once you have all the information,'
60+
' provide it in the requested format. Your output MUST be a JSON object'
61+
' that conforms to the PizzaOrder schema and nothing else.'
62+
),
63+
output_key='pizza_order',
64+
output_schema=PizzaOrder,
65+
tools=[get_available_sizes, get_available_crusts, get_available_toppings],
66+
)
67+
68+
69+
# 4. Define a tool for the order confirmation agent.
70+
def calculate_price(tool_context: ToolContext) -> str:
71+
"""Calculates the price of a pizza order and returns a descriptive string."""
72+
order_dict = tool_context.state.get('pizza_order')
73+
if not order_dict:
74+
return "I can't find an order to calculate the price for."
75+
76+
order = PizzaOrder.model_validate(order_dict)
77+
78+
price = 0.0
79+
if order.size == 'small':
80+
price += 8.0
81+
elif order.size == 'medium':
82+
price += 10.0
83+
elif order.size == 'large':
84+
price += 12.0
85+
86+
if order.crust == 'stuffed':
87+
price += 2.0
88+
89+
price += len(order.toppings) * 1.5
90+
return f'The total price for your order is ${price:.2f}.'
91+
92+
93+
# 5. Define the order confirmation agent.
94+
# This agent reads the PizzaOrder object from the session state (placed there by
95+
# the order_intake_agent) and confirms the order with the user.
96+
order_confirmation_agent = Agent(
97+
name='order_confirmation_agent',
98+
model='gemini-2.5-flash',
99+
instruction=(
100+
'Confirm the pizza order with the user. The order is in the state'
101+
' variable `pizza_order`. First, use the `calculate_price` tool to get'
102+
' the price. Then, summarize the order details from {pizza_order} and'
103+
' include the price in your summary. For example: "You ordered a large'
104+
' thin crust pizza with pepperoni and mushrooms. The total price is'
105+
' $15.00."'
106+
),
107+
tools=[calculate_price],
108+
)
109+
110+
# 6. Define the root agent as a sequential agent.
111+
# This agent directs the conversation by running its sub-agents in order.
112+
root_agent = SequentialAgent(
113+
name='pizza_ordering_agent',
114+
sub_agents=[
115+
order_intake_agent,
116+
order_confirmation_agent,
117+
],
118+
description=(
119+
'This agent is used to order pizza. It will ask the user for their'
120+
' pizza order and then confirm the order with the user.'
121+
),
122+
)

0 commit comments

Comments
 (0)