Skip to content

Commit 9352e83

Browse files
authored
Merge branch 'main' into a2a-url
2 parents 28082be + 5380352 commit 9352e83

File tree

30 files changed

+980
-205
lines changed

30 files changed

+980
-205
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: ADK Answering Agent for Discussions
2+
3+
on:
4+
discussion:
5+
types: [created]
6+
discussion_comment:
7+
types: [created]
8+
9+
jobs:
10+
agent-answer-questions:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: '3.11'
21+
22+
- name: Authenticate to Google Cloud
23+
id: auth
24+
uses: 'google-github-actions/auth@v2'
25+
with:
26+
credentials_json: '${{ secrets.ADK_GCP_SA_KEY }}'
27+
28+
- name: Install dependencies
29+
run: |
30+
python -m pip install --upgrade pip
31+
pip install google-adk
32+
33+
- name: Run Answering Script
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.ADK_TRIAGE_AGENT }}
36+
GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }}
37+
GOOGLE_CLOUD_LOCATION: ${{ secrets.GOOGLE_CLOUD_LOCATION }}
38+
VERTEXAI_DATASTORE_ID: ${{ secrets.VERTEXAI_DATASTORE_ID }}
39+
GOOGLE_GENAI_USE_VERTEXAI: 1
40+
OWNER: 'google'
41+
REPO: 'adk-python'
42+
INTERACTIVE: 0
43+
DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
44+
PYTHONPATH: contributing/samples
45+
run: python -m adk_answering_agent.main

contributing/samples/a2a_root/agent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
15+
from google.adk.agents.remote_a2a_agent import AGENT_CARD_WELL_KNOWN_PATH
1616
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
1717

1818
root_agent = RemoteA2aAgent(

contributing/samples/adk_answering_agent/agent.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ def add_label_to_discussion(
247247
* {APPROVAL_INSTRUCTION}
248248
* Your response should be based on the information you found in the document store. Do not invent
249249
information that is not in the document store. Do not invent citations which are not in the document store.
250+
* **Be Objective**: your answer should be based on the facts you found in the document store, do not be misled by user's assumptions or user's understanding of ADK.
250251
* If you can't find the answer or information in the document store, **do not** respond.
251252
* Include a bolded note (e.g. "Response from ADK Answering Agent") in your comment
252253
to indicate this comment was added by an ADK Answering Agent.

contributing/samples/live_bidi_streaming_multi_agent/agent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ def get_current_weather(location: str):
100100

101101
root_agent = Agent(
102102
# find supported models here: https://google.github.io/adk-docs/get-started/streaming/quickstart-streaming/
103-
# model='gemini-live-2.5-flash-preview-native-audio', # for Vertex project
104-
model="gemini-live-2.5-flash-preview", # for AI studio key
103+
model="gemini-2.0-flash-live-preview-04-09", # for Vertex project
104+
# model="gemini-live-2.5-flash-preview", # for AI studio key
105105
name="root_agent",
106106
instruction="""
107107
You are a helpful assistant that can check time, roll dice and check if numbers are prime.

contributing/samples/live_bidi_streaming_tools_agent/agent.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ def stop_streaming(function_name: str):
121121

122122

123123
root_agent = Agent(
124-
model="gemini-live-2.5-flash-preview",
124+
# find supported models here: https://google.github.io/adk-docs/get-started/streaming/quickstart-streaming/
125+
model="gemini-2.0-flash-live-preview-04-09", # for Vertex project
126+
# model="gemini-live-2.5-flash-preview", # for AI studio key
125127
name="video_streaming_agent",
126128
instruction="""
127129
You are a monitoring agent. You can do video monitoring and stock price monitoring

contributing/samples/live_tool_callbacks_agent/agent.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ async def after_tool_async_callback(
217217

218218
# Create the agent with tool callbacks
219219
root_agent = Agent(
220+
# find supported models here: https://google.github.io/adk-docs/get-started/streaming/quickstart-streaming/
220221
model="gemini-2.0-flash-live-preview-04-09", # for Vertex project
221-
# model="gemini-2.0-flash-live-001", # for AI studio key
222+
# model="gemini-live-2.5-flash-preview", # for AI studio key
222223
name="tool_callbacks_agent",
223224
description=(
224225
"Live streaming agent that demonstrates tool callbacks functionality. "

src/google/adk/agents/base_agent.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -504,20 +504,17 @@ def __set_parent_agent_for_sub_agents(self) -> BaseAgent:
504504
sub_agent.parent_agent = self
505505
return self
506506

507+
@final
507508
@classmethod
508-
@working_in_progress('BaseAgent.from_config is not ready for use.')
509509
def from_config(
510510
cls: Type[SelfAgent],
511511
config: BaseAgentConfig,
512512
config_abs_path: str,
513513
) -> SelfAgent:
514514
"""Creates an agent from a config.
515515
516-
This method converts fields in a config to the corresponding
517-
fields in an agent.
518-
519-
Child classes should re-implement this method to support loading from their
520-
custom config types.
516+
If sub-classes uses a custom agent config, override `_from_config_kwargs`
517+
method to return an updated kwargs for agent construstor.
521518
522519
Args:
523520
config: The config to create the agent from.
@@ -527,6 +524,40 @@ def from_config(
527524
Returns:
528525
The created agent.
529526
"""
527+
kwargs = cls.__create_kwargs(config, config_abs_path)
528+
kwargs = cls._parse_config(config, config_abs_path, kwargs)
529+
return cls(**kwargs)
530+
531+
@classmethod
532+
def _parse_config(
533+
cls: Type[SelfAgent],
534+
config: BaseAgentConfig,
535+
config_abs_path: str,
536+
kwargs: Dict[str, Any],
537+
) -> Dict[str, Any]:
538+
"""Parses the config and returns updated kwargs to construct the agent.
539+
540+
Sub-classes should override this method to use a custome agent config class.
541+
542+
Args:
543+
config: The config to parse.
544+
config_abs_path: The absolute path to the config file that contains the
545+
agent config.
546+
kwargs: The keyword arguments used for agent constructor.
547+
548+
Returns:
549+
The updated keyword arguments used for agent constructor.
550+
"""
551+
return kwargs
552+
553+
@classmethod
554+
def __create_kwargs(
555+
cls,
556+
config: BaseAgentConfig,
557+
config_abs_path: str,
558+
) -> Dict[str, Any]:
559+
"""Creates kwargs for the fields of BaseAgent."""
560+
530561
from .config_agent_utils import resolve_agent_reference
531562
from .config_agent_utils import resolve_callbacks
532563

@@ -549,4 +580,4 @@ def from_config(
549580
kwargs['after_agent_callback'] = resolve_callbacks(
550581
config.after_agent_callbacks
551582
)
552-
return cls(**kwargs)
583+
return kwargs

src/google/adk/agents/config_agent_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def _resolve_agent_class(agent_class: str) -> type[BaseAgent]:
6969
if "." not in agent_class_name:
7070
agent_class_name = f"google.adk.agents.{agent_class_name}"
7171

72-
agent_class = _resolve_fully_qualified_name(agent_class_name)
72+
agent_class = resolve_fully_qualified_name(agent_class_name)
7373
if inspect.isclass(agent_class) and issubclass(agent_class, BaseAgent):
7474
return agent_class
7575

@@ -103,8 +103,8 @@ def _load_config_from_path(config_path: str) -> AgentConfig:
103103
return AgentConfig.model_validate(config_data)
104104

105105

106-
@working_in_progress("_resolve_fully_qualified_name is not ready for use.")
107-
def _resolve_fully_qualified_name(name: str) -> Any:
106+
@working_in_progress("resolve_fully_qualified_name is not ready for use.")
107+
def resolve_fully_qualified_name(name: str) -> Any:
108108
try:
109109
module_path, obj_name = name.rsplit(".", 1)
110110
module = importlib.import_module(module_path)

src/google/adk/agents/invocation_context.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
from google.genai import types
2121
from pydantic import BaseModel
2222
from pydantic import ConfigDict
23+
from pydantic import Field
24+
from pydantic import PrivateAttr
2325

2426
from ..artifacts.base_artifact_service import BaseArtifactService
2527
from ..auth.credential_service.base_credential_service import BaseCredentialService
@@ -151,13 +153,18 @@ class InvocationContext(BaseModel):
151153
transcription_cache: Optional[list[TranscriptionEntry]] = None
152154
"""Caches necessary data, audio or contents, that are needed by transcription."""
153155

156+
live_session_resumption_handle: Optional[str] = None
157+
"""The handle for live session resumption."""
158+
154159
run_config: Optional[RunConfig] = None
155160
"""Configurations for live agents under this invocation."""
156161

157-
plugin_manager: PluginManager = PluginManager()
162+
plugin_manager: PluginManager = Field(default_factory=PluginManager)
158163
"""The manager for keeping track of plugins in this invocation."""
159164

160-
_invocation_cost_manager: _InvocationCostManager = _InvocationCostManager()
165+
_invocation_cost_manager: _InvocationCostManager = PrivateAttr(
166+
default_factory=_InvocationCostManager
167+
)
161168
"""A container to keep track of different kinds of costs incurred as a part
162169
of this invocation.
163170
"""

src/google/adk/agents/llm_agent.py

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import importlib
1818
import inspect
1919
import logging
20-
import os
2120
from typing import Any
2221
from typing import AsyncGenerator
2322
from typing import Awaitable
2423
from typing import Callable
2524
from typing import ClassVar
25+
from typing import Dict
2626
from typing import Literal
2727
from typing import Optional
2828
from typing import Type
@@ -38,8 +38,6 @@
3838

3939
from ..code_executors.base_code_executor import BaseCodeExecutor
4040
from ..events.event import Event
41-
from ..examples.base_example_provider import BaseExampleProvider
42-
from ..examples.example import Example
4341
from ..flows.llm_flows.auto_flow import AutoFlow
4442
from ..flows.llm_flows.base_llm_flow import BaseLlmFlow
4543
from ..flows.llm_flows.single_flow import SingleFlow
@@ -48,7 +46,6 @@
4846
from ..models.llm_response import LlmResponse
4947
from ..models.registry import LLMRegistry
5048
from ..planners.base_planner import BasePlanner
51-
from ..tools.agent_tool import AgentTool
5249
from ..tools.base_tool import BaseTool
5350
from ..tools.base_tool import ToolConfig
5451
from ..tools.base_toolset import BaseToolset
@@ -58,7 +55,6 @@
5855
from .base_agent import BaseAgent
5956
from .base_agent_config import BaseAgentConfig
6057
from .callback_context import CallbackContext
61-
from .common_configs import CodeConfig
6258
from .invocation_context import InvocationContext
6359
from .llm_agent_config import LlmAgentConfig
6460
from .readonly_context import ReadonlyContext
@@ -110,7 +106,6 @@
110106
]
111107

112108
ToolUnion: TypeAlias = Union[Callable, BaseTool, BaseToolset]
113-
ExamplesUnion = Union[list[Example], BaseExampleProvider]
114109

115110

116111
async def _convert_tool_union_to_tools(
@@ -589,53 +584,55 @@ def _resolve_tools(
589584

590585
return resolved_tools
591586

592-
@classmethod
593587
@override
594-
@working_in_progress('LlmAgent.from_config is not ready for use.')
595-
def from_config(
588+
@classmethod
589+
def _parse_config(
596590
cls: Type[LlmAgent],
597591
config: LlmAgentConfig,
598592
config_abs_path: str,
599-
) -> LlmAgent:
593+
kwargs: Dict[str, Any],
594+
) -> Dict[str, Any]:
600595
from .config_agent_utils import resolve_callbacks
601596
from .config_agent_utils import resolve_code_reference
602597

603-
agent = super().from_config(config, config_abs_path)
604598
if config.model:
605-
agent.model = config.model
599+
kwargs['model'] = config.model
606600
if config.instruction:
607-
agent.instruction = config.instruction
601+
kwargs['instruction'] = config.instruction
608602
if config.disallow_transfer_to_parent:
609-
agent.disallow_transfer_to_parent = config.disallow_transfer_to_parent
603+
kwargs['disallow_transfer_to_parent'] = config.disallow_transfer_to_parent
610604
if config.disallow_transfer_to_peers:
611-
agent.disallow_transfer_to_peers = config.disallow_transfer_to_peers
605+
kwargs['disallow_transfer_to_peers'] = config.disallow_transfer_to_peers
612606
if config.include_contents != 'default':
613-
agent.include_contents = config.include_contents
607+
kwargs['include_contents'] = config.include_contents
614608
if config.input_schema:
615-
agent.input_schema = resolve_code_reference(config.input_schema)
609+
kwargs['input_schema'] = resolve_code_reference(config.input_schema)
616610
if config.output_schema:
617-
agent.output_schema = resolve_code_reference(config.output_schema)
611+
kwargs['output_schema'] = resolve_code_reference(config.output_schema)
618612
if config.output_key:
619-
agent.output_key = config.output_key
613+
kwargs['output_key'] = config.output_key
620614
if config.tools:
621-
agent.tools = cls._resolve_tools(config.tools, config_abs_path)
615+
kwargs['tools'] = cls._resolve_tools(config.tools, config_abs_path)
622616
if config.before_model_callbacks:
623-
agent.before_model_callback = resolve_callbacks(
617+
kwargs['before_model_callback'] = resolve_callbacks(
624618
config.before_model_callbacks
625619
)
626620
if config.after_model_callbacks:
627-
agent.after_model_callback = resolve_callbacks(
621+
kwargs['after_model_callback'] = resolve_callbacks(
628622
config.after_model_callbacks
629623
)
630624
if config.before_tool_callbacks:
631-
agent.before_tool_callback = resolve_callbacks(
625+
kwargs['before_tool_callback'] = resolve_callbacks(
632626
config.before_tool_callbacks
633627
)
634628
if config.after_tool_callbacks:
635-
agent.after_tool_callback = resolve_callbacks(config.after_tool_callbacks)
629+
kwargs['after_tool_callback'] = resolve_callbacks(
630+
config.after_tool_callbacks
631+
)
636632
if config.generate_content_config:
637-
agent.generate_content_config = config.generate_content_config
638-
return agent
633+
kwargs['generate_content_config'] = config.generate_content_config
634+
635+
return kwargs
639636

640637

641638
Agent: TypeAlias = LlmAgent

0 commit comments

Comments
 (0)