google-adk 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. google/adk/agents/run_config.py +4 -0
  2. google/adk/auth/auth_preprocessor.py +19 -16
  3. google/adk/cli/agent_graph.py +31 -5
  4. google/adk/cli/browser/index.html +1 -1
  5. google/adk/cli/browser/{main-XUU6OGCC.js → main-CU22TRPI.js} +30 -30
  6. google/adk/cli/cli.py +8 -8
  7. google/adk/cli/cli_deploy.py +2 -4
  8. google/adk/cli/cli_tools_click.py +57 -12
  9. google/adk/cli/fast_api.py +19 -9
  10. google/adk/flows/llm_flows/contents.py +21 -1
  11. google/adk/flows/llm_flows/functions.py +3 -1
  12. google/adk/models/google_llm.py +0 -1
  13. google/adk/runners.py +13 -2
  14. google/adk/version.py +1 -1
  15. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/METADATA +4 -2
  16. google_adk-0.0.4.dist-info/RECORD +175 -0
  17. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/WHEEL +1 -1
  18. google/adk/cli/media_streamer/__init__.py +0 -19
  19. google/adk/cli/media_streamer/index.html +0 -228
  20. google/adk/tests/__init__.py +0 -14
  21. google/adk/tests/integration/.env.example +0 -10
  22. google/adk/tests/integration/__init__.py +0 -18
  23. google/adk/tests/integration/conftest.py +0 -119
  24. google/adk/tests/integration/fixture/__init__.py +0 -14
  25. google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
  26. google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
  27. google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
  28. google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
  29. google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
  30. google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
  31. google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
  32. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
  33. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
  34. google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
  35. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
  36. google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
  37. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
  38. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
  39. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
  40. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
  41. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
  42. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
  43. google/adk/tests/integration/fixture/flow_complex_spark/sample.debug.log +0 -243
  44. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
  45. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
  46. google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
  47. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
  48. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
  49. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
  50. google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
  51. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
  52. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
  53. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
  54. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
  55. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
  56. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
  57. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
  58. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
  59. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
  60. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
  61. google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
  62. google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
  63. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  64. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
  65. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
  66. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
  67. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
  68. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
  69. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
  70. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
  71. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
  72. google/adk/tests/integration/models/__init__.py +0 -14
  73. google/adk/tests/integration/models/test_google_llm.py +0 -65
  74. google/adk/tests/integration/test_callback.py +0 -70
  75. google/adk/tests/integration/test_context_variable.py +0 -67
  76. google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
  77. google/adk/tests/integration/test_multi_agent.py +0 -28
  78. google/adk/tests/integration/test_multi_turn.py +0 -42
  79. google/adk/tests/integration/test_single_agent.py +0 -23
  80. google/adk/tests/integration/test_sub_agent.py +0 -26
  81. google/adk/tests/integration/test_system_instruction.py +0 -177
  82. google/adk/tests/integration/test_tools.py +0 -287
  83. google/adk/tests/integration/test_with_test_file.py +0 -34
  84. google/adk/tests/integration/tools/__init__.py +0 -14
  85. google/adk/tests/integration/utils/__init__.py +0 -16
  86. google/adk/tests/integration/utils/asserts.py +0 -75
  87. google/adk/tests/integration/utils/test_runner.py +0 -97
  88. google/adk/tests/unittests/__init__.py +0 -14
  89. google/adk/tests/unittests/agents/__init__.py +0 -14
  90. google/adk/tests/unittests/agents/test_base_agent.py +0 -407
  91. google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
  92. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
  93. google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
  94. google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
  95. google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
  96. google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
  97. google/adk/tests/unittests/artifacts/__init__.py +0 -14
  98. google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
  99. google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
  100. google/adk/tests/unittests/conftest.py +0 -73
  101. google/adk/tests/unittests/fast_api/__init__.py +0 -14
  102. google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
  103. google/adk/tests/unittests/flows/__init__.py +0 -14
  104. google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
  105. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
  106. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
  107. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
  108. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
  109. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
  110. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
  111. google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
  112. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
  113. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
  114. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
  115. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
  116. google/adk/tests/unittests/models/__init__.py +0 -14
  117. google/adk/tests/unittests/models/test_google_llm.py +0 -224
  118. google/adk/tests/unittests/models/test_litellm.py +0 -804
  119. google/adk/tests/unittests/models/test_models.py +0 -60
  120. google/adk/tests/unittests/sessions/__init__.py +0 -14
  121. google/adk/tests/unittests/sessions/test_session_service.py +0 -227
  122. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
  123. google/adk/tests/unittests/streaming/__init__.py +0 -14
  124. google/adk/tests/unittests/streaming/test_streaming.py +0 -50
  125. google/adk/tests/unittests/tools/__init__.py +0 -14
  126. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
  127. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
  128. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
  129. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
  130. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
  131. google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
  132. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
  133. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
  134. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
  135. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
  136. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
  137. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
  138. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
  139. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
  140. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
  141. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
  142. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
  143. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
  144. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
  145. google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
  146. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
  147. google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
  148. google/adk/tests/unittests/tools/test_base_tool.py +0 -141
  149. google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
  150. google/adk/tests/unittests/utils.py +0 -304
  151. google_adk-0.0.2.dist-info/RECORD +0 -308
  152. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info}/entry_points.txt +0 -0
  153. {google_adk-0.0.2.dist-info → google_adk-0.0.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,138 +0,0 @@
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 typing import Any
16
- from typing import Optional
17
-
18
- from google.adk.agents.callback_context import CallbackContext
19
- from google.adk.agents.llm_agent import Agent
20
- from google.adk.models import LlmRequest
21
- from google.adk.models import LlmResponse
22
- from google.genai import types
23
- from pydantic import BaseModel
24
- import pytest
25
-
26
- from .. import utils
27
-
28
-
29
- class MockBeforeModelCallback(BaseModel):
30
- mock_response: str
31
-
32
- def __call__(
33
- self,
34
- callback_context: CallbackContext,
35
- llm_request: LlmRequest,
36
- ) -> LlmResponse:
37
- return LlmResponse(
38
- content=utils.ModelContent(
39
- [types.Part.from_text(text=self.mock_response)]
40
- )
41
- )
42
-
43
-
44
- class MockAfterModelCallback(BaseModel):
45
- mock_response: str
46
-
47
- def __call__(
48
- self,
49
- callback_context: CallbackContext,
50
- llm_response: LlmResponse,
51
- ) -> LlmResponse:
52
- return LlmResponse(
53
- content=utils.ModelContent(
54
- [types.Part.from_text(text=self.mock_response)]
55
- )
56
- )
57
-
58
-
59
- def noop_callback(**kwargs) -> Optional[LlmResponse]:
60
- pass
61
-
62
-
63
- @pytest.mark.asyncio
64
- async def test_before_model_callback():
65
- responses = ['model_response']
66
- mock_model = utils.MockModel.create(responses=responses)
67
- agent = Agent(
68
- name='root_agent',
69
- model=mock_model,
70
- before_model_callback=MockBeforeModelCallback(
71
- mock_response='before_model_callback'
72
- ),
73
- )
74
-
75
- runner = utils.TestInMemoryRunner(agent)
76
- assert utils.simplify_events(
77
- await runner.run_async_with_new_session('test')
78
- ) == [
79
- ('root_agent', 'before_model_callback'),
80
- ]
81
-
82
-
83
- @pytest.mark.asyncio
84
- async def test_before_model_callback_noop():
85
- responses = ['model_response']
86
- mock_model = utils.MockModel.create(responses=responses)
87
- agent = Agent(
88
- name='root_agent',
89
- model=mock_model,
90
- before_model_callback=noop_callback,
91
- )
92
-
93
- runner = utils.TestInMemoryRunner(agent)
94
- assert utils.simplify_events(
95
- await runner.run_async_with_new_session('test')
96
- ) == [
97
- ('root_agent', 'model_response'),
98
- ]
99
-
100
-
101
- @pytest.mark.asyncio
102
- async def test_before_model_callback_end():
103
- responses = ['model_response']
104
- mock_model = utils.MockModel.create(responses=responses)
105
- agent = Agent(
106
- name='root_agent',
107
- model=mock_model,
108
- before_model_callback=MockBeforeModelCallback(
109
- mock_response='before_model_callback',
110
- ),
111
- )
112
-
113
- runner = utils.TestInMemoryRunner(agent)
114
- assert utils.simplify_events(
115
- await runner.run_async_with_new_session('test')
116
- ) == [
117
- ('root_agent', 'before_model_callback'),
118
- ]
119
-
120
-
121
- @pytest.mark.asyncio
122
- async def test_after_model_callback():
123
- responses = ['model_response']
124
- mock_model = utils.MockModel.create(responses=responses)
125
- agent = Agent(
126
- name='root_agent',
127
- model=mock_model,
128
- after_model_callback=MockAfterModelCallback(
129
- mock_response='after_model_callback'
130
- ),
131
- )
132
-
133
- runner = utils.TestInMemoryRunner(agent)
134
- assert utils.simplify_events(
135
- await runner.run_async_with_new_session('test')
136
- ) == [
137
- ('root_agent', 'after_model_callback'),
138
- ]
@@ -1,231 +0,0 @@
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
- """Unit tests for canonical_xxx fields in LlmAgent."""
16
-
17
- from typing import Any
18
- from typing import Optional
19
-
20
- from google.adk.agents.callback_context import CallbackContext
21
- from google.adk.agents.invocation_context import InvocationContext
22
- from google.adk.agents.llm_agent import LlmAgent
23
- from google.adk.agents.loop_agent import LoopAgent
24
- from google.adk.agents.readonly_context import ReadonlyContext
25
- from google.adk.models.llm_request import LlmRequest
26
- from google.adk.models.registry import LLMRegistry
27
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
28
- from google.genai import types
29
- from pydantic import BaseModel
30
- import pytest
31
-
32
-
33
- def _create_readonly_context(
34
- agent: LlmAgent, state: Optional[dict[str, Any]] = None
35
- ) -> ReadonlyContext:
36
- session_service = InMemorySessionService()
37
- session = session_service.create_session(
38
- app_name='test_app', user_id='test_user', state=state
39
- )
40
- invocation_context = InvocationContext(
41
- invocation_id='test_id',
42
- agent=agent,
43
- session=session,
44
- session_service=session_service,
45
- )
46
- return ReadonlyContext(invocation_context)
47
-
48
-
49
- def test_canonical_model_empty():
50
- agent = LlmAgent(name='test_agent')
51
-
52
- with pytest.raises(ValueError):
53
- _ = agent.canonical_model
54
-
55
-
56
- def test_canonical_model_str():
57
- agent = LlmAgent(name='test_agent', model='gemini-pro')
58
-
59
- assert agent.canonical_model.model == 'gemini-pro'
60
-
61
-
62
- def test_canonical_model_llm():
63
- llm = LLMRegistry.new_llm('gemini-pro')
64
- agent = LlmAgent(name='test_agent', model=llm)
65
-
66
- assert agent.canonical_model == llm
67
-
68
-
69
- def test_canonical_model_inherit():
70
- sub_agent = LlmAgent(name='sub_agent')
71
- parent_agent = LlmAgent(
72
- name='parent_agent', model='gemini-pro', sub_agents=[sub_agent]
73
- )
74
-
75
- assert sub_agent.canonical_model == parent_agent.canonical_model
76
-
77
-
78
- def test_canonical_instruction_str():
79
- agent = LlmAgent(name='test_agent', instruction='instruction')
80
- ctx = _create_readonly_context(agent)
81
-
82
- assert agent.canonical_instruction(ctx) == 'instruction'
83
-
84
-
85
- def test_canonical_instruction():
86
- def _instruction_provider(ctx: ReadonlyContext) -> str:
87
- return f'instruction: {ctx.state["state_var"]}'
88
-
89
- agent = LlmAgent(name='test_agent', instruction=_instruction_provider)
90
- ctx = _create_readonly_context(agent, state={'state_var': 'state_value'})
91
-
92
- assert agent.canonical_instruction(ctx) == 'instruction: state_value'
93
-
94
-
95
- def test_canonical_global_instruction_str():
96
- agent = LlmAgent(name='test_agent', global_instruction='global instruction')
97
- ctx = _create_readonly_context(agent)
98
-
99
- assert agent.canonical_global_instruction(ctx) == 'global instruction'
100
-
101
-
102
- def test_canonical_global_instruction():
103
- def _global_instruction_provider(ctx: ReadonlyContext) -> str:
104
- return f'global instruction: {ctx.state["state_var"]}'
105
-
106
- agent = LlmAgent(
107
- name='test_agent', global_instruction=_global_instruction_provider
108
- )
109
- ctx = _create_readonly_context(agent, state={'state_var': 'state_value'})
110
-
111
- assert (
112
- agent.canonical_global_instruction(ctx)
113
- == 'global instruction: state_value'
114
- )
115
-
116
-
117
- def test_output_schema_will_disable_transfer(caplog: pytest.LogCaptureFixture):
118
- with caplog.at_level('WARNING'):
119
-
120
- class Schema(BaseModel):
121
- pass
122
-
123
- agent = LlmAgent(
124
- name='test_agent',
125
- output_schema=Schema,
126
- )
127
-
128
- # Transfer is automatically disabled
129
- assert agent.disallow_transfer_to_parent
130
- assert agent.disallow_transfer_to_peers
131
- assert (
132
- 'output_schema cannot co-exist with agent transfer configurations.'
133
- in caplog.text
134
- )
135
-
136
-
137
- def test_output_schema_with_sub_agents_will_throw():
138
- class Schema(BaseModel):
139
- pass
140
-
141
- sub_agent = LlmAgent(
142
- name='sub_agent',
143
- )
144
-
145
- with pytest.raises(ValueError):
146
- _ = LlmAgent(
147
- name='test_agent',
148
- output_schema=Schema,
149
- sub_agents=[sub_agent],
150
- )
151
-
152
-
153
- def test_output_schema_with_tools_will_throw():
154
- class Schema(BaseModel):
155
- pass
156
-
157
- def _a_tool():
158
- pass
159
-
160
- with pytest.raises(ValueError):
161
- _ = LlmAgent(
162
- name='test_agent',
163
- output_schema=Schema,
164
- tools=[_a_tool],
165
- )
166
-
167
-
168
- def test_before_model_callback():
169
- def _before_model_callback(
170
- callback_context: CallbackContext,
171
- llm_request: LlmRequest,
172
- ) -> None:
173
- return None
174
-
175
- agent = LlmAgent(
176
- name='test_agent', before_model_callback=_before_model_callback
177
- )
178
-
179
- # TODO: add more logic assertions later.
180
- assert agent.before_model_callback is not None
181
-
182
-
183
- def test_validate_generate_content_config_thinking_config_throw():
184
- with pytest.raises(ValueError):
185
- _ = LlmAgent(
186
- name='test_agent',
187
- generate_content_config=types.GenerateContentConfig(
188
- thinking_config=types.ThinkingConfig()
189
- ),
190
- )
191
-
192
-
193
- def test_validate_generate_content_config_tools_throw():
194
- with pytest.raises(ValueError):
195
- _ = LlmAgent(
196
- name='test_agent',
197
- generate_content_config=types.GenerateContentConfig(
198
- tools=[types.Tool(function_declarations=[])]
199
- ),
200
- )
201
-
202
-
203
- def test_validate_generate_content_config_system_instruction_throw():
204
- with pytest.raises(ValueError):
205
- _ = LlmAgent(
206
- name='test_agent',
207
- generate_content_config=types.GenerateContentConfig(
208
- system_instruction='system instruction'
209
- ),
210
- )
211
-
212
-
213
- def test_validate_generate_content_config_response_schema_throw():
214
- class Schema(BaseModel):
215
- pass
216
-
217
- with pytest.raises(ValueError):
218
- _ = LlmAgent(
219
- name='test_agent',
220
- generate_content_config=types.GenerateContentConfig(
221
- response_schema=Schema
222
- ),
223
- )
224
-
225
-
226
- def test_allow_transfer_by_default():
227
- sub_agent = LlmAgent(name='sub_agent')
228
- agent = LlmAgent(name='test_agent', sub_agents=[sub_agent])
229
-
230
- assert not agent.disallow_transfer_to_parent
231
- assert not agent.disallow_transfer_to_peers
@@ -1,136 +0,0 @@
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
- """Testings for the SequentialAgent."""
16
-
17
- from typing import AsyncGenerator
18
-
19
- from google.adk.agents.base_agent import BaseAgent
20
- from google.adk.agents.invocation_context import InvocationContext
21
- from google.adk.agents.loop_agent import LoopAgent
22
- from google.adk.events import Event
23
- from google.adk.events import EventActions
24
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
25
- from google.genai import types
26
- import pytest
27
- from typing_extensions import override
28
-
29
-
30
- class _TestingAgent(BaseAgent):
31
-
32
- @override
33
- async def _run_async_impl(
34
- self, ctx: InvocationContext
35
- ) -> AsyncGenerator[Event, None]:
36
- yield Event(
37
- author=self.name,
38
- invocation_id=ctx.invocation_id,
39
- content=types.Content(
40
- parts=[types.Part(text=f'Hello, async {self.name}!')]
41
- ),
42
- )
43
-
44
- @override
45
- async def _run_live_impl(
46
- self, ctx: InvocationContext
47
- ) -> AsyncGenerator[Event, None]:
48
- yield Event(
49
- author=self.name,
50
- invocation_id=ctx.invocation_id,
51
- content=types.Content(
52
- parts=[types.Part(text=f'Hello, live {self.name}!')]
53
- ),
54
- )
55
-
56
-
57
- class _TestingAgentWithEscalateAction(BaseAgent):
58
-
59
- @override
60
- async def _run_async_impl(
61
- self, ctx: InvocationContext
62
- ) -> AsyncGenerator[Event, None]:
63
- yield Event(
64
- author=self.name,
65
- invocation_id=ctx.invocation_id,
66
- content=types.Content(
67
- parts=[types.Part(text=f'Hello, async {self.name}!')]
68
- ),
69
- actions=EventActions(escalate=True),
70
- )
71
-
72
-
73
- def _create_parent_invocation_context(
74
- test_name: str, agent: BaseAgent
75
- ) -> InvocationContext:
76
- session_service = InMemorySessionService()
77
- session = session_service.create_session(
78
- app_name='test_app', user_id='test_user'
79
- )
80
- return InvocationContext(
81
- invocation_id=f'{test_name}_invocation_id',
82
- agent=agent,
83
- session=session,
84
- session_service=session_service,
85
- )
86
-
87
-
88
- @pytest.mark.asyncio
89
- async def test_run_async(request: pytest.FixtureRequest):
90
- agent = _TestingAgent(name=f'{request.function.__name__}_test_agent')
91
- loop_agent = LoopAgent(
92
- name=f'{request.function.__name__}_test_loop_agent',
93
- max_iterations=2,
94
- sub_agents=[
95
- agent,
96
- ],
97
- )
98
- parent_ctx = _create_parent_invocation_context(
99
- request.function.__name__, loop_agent
100
- )
101
- events = [e async for e in loop_agent.run_async(parent_ctx)]
102
-
103
- assert len(events) == 2
104
- assert events[0].author == agent.name
105
- assert events[1].author == agent.name
106
- assert events[0].content.parts[0].text == f'Hello, async {agent.name}!'
107
- assert events[1].content.parts[0].text == f'Hello, async {agent.name}!'
108
-
109
-
110
- @pytest.mark.asyncio
111
- async def test_run_async_with_escalate_action(request: pytest.FixtureRequest):
112
- non_escalating_agent = _TestingAgent(
113
- name=f'{request.function.__name__}_test_non_escalating_agent'
114
- )
115
- escalating_agent = _TestingAgentWithEscalateAction(
116
- name=f'{request.function.__name__}_test_escalating_agent'
117
- )
118
- loop_agent = LoopAgent(
119
- name=f'{request.function.__name__}_test_loop_agent',
120
- sub_agents=[non_escalating_agent, escalating_agent],
121
- )
122
- parent_ctx = _create_parent_invocation_context(
123
- request.function.__name__, loop_agent
124
- )
125
- events = [e async for e in loop_agent.run_async(parent_ctx)]
126
-
127
- # Only two events are generated because the sub escalating_agent escalates.
128
- assert len(events) == 2
129
- assert events[0].author == non_escalating_agent.name
130
- assert events[1].author == escalating_agent.name
131
- assert events[0].content.parts[0].text == (
132
- f'Hello, async {non_escalating_agent.name}!'
133
- )
134
- assert events[1].content.parts[0].text == (
135
- f'Hello, async {escalating_agent.name}!'
136
- )
@@ -1,92 +0,0 @@
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
- """Tests for the ParallelAgent."""
16
-
17
- import asyncio
18
- from typing import AsyncGenerator
19
-
20
- from google.adk.agents.base_agent import BaseAgent
21
- from google.adk.agents.invocation_context import InvocationContext
22
- from google.adk.agents.parallel_agent import ParallelAgent
23
- from google.adk.events import Event
24
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
25
- from google.genai import types
26
- import pytest
27
- from typing_extensions import override
28
-
29
-
30
- class _TestingAgent(BaseAgent):
31
-
32
- delay: float = 0
33
- """The delay before the agent generates an event."""
34
-
35
- @override
36
- async def _run_async_impl(
37
- self, ctx: InvocationContext
38
- ) -> AsyncGenerator[Event, None]:
39
- await asyncio.sleep(self.delay)
40
- yield Event(
41
- author=self.name,
42
- branch=ctx.branch,
43
- invocation_id=ctx.invocation_id,
44
- content=types.Content(
45
- parts=[types.Part(text=f'Hello, async {self.name}!')]
46
- ),
47
- )
48
-
49
-
50
- def _create_parent_invocation_context(
51
- test_name: str, agent: BaseAgent
52
- ) -> InvocationContext:
53
- session_service = InMemorySessionService()
54
- session = session_service.create_session(
55
- app_name='test_app', user_id='test_user'
56
- )
57
- return InvocationContext(
58
- invocation_id=f'{test_name}_invocation_id',
59
- agent=agent,
60
- session=session,
61
- session_service=session_service,
62
- )
63
-
64
-
65
- @pytest.mark.asyncio
66
- async def test_run_async(request: pytest.FixtureRequest):
67
- agent1 = _TestingAgent(
68
- name=f'{request.function.__name__}_test_agent_1',
69
- delay=0.5,
70
- )
71
- agent2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
72
- parallel_agent = ParallelAgent(
73
- name=f'{request.function.__name__}_test_parallel_agent',
74
- sub_agents=[
75
- agent1,
76
- agent2,
77
- ],
78
- )
79
- parent_ctx = _create_parent_invocation_context(
80
- request.function.__name__, parallel_agent
81
- )
82
- events = [e async for e in parallel_agent.run_async(parent_ctx)]
83
-
84
- assert len(events) == 2
85
- # agent2 generates an event first, then agent1. Because they run in parallel
86
- # and agent1 has a delay.
87
- assert events[0].author == agent2.name
88
- assert events[1].author == agent1.name
89
- assert events[0].branch.endswith(agent2.name)
90
- assert events[1].branch.endswith(agent1.name)
91
- assert events[0].content.parts[0].text == f'Hello, async {agent2.name}!'
92
- assert events[1].content.parts[0].text == f'Hello, async {agent1.name}!'
@@ -1,114 +0,0 @@
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
- """Testings for the SequentialAgent."""
16
-
17
- from typing import AsyncGenerator
18
-
19
- from google.adk.agents.base_agent import BaseAgent
20
- from google.adk.agents.invocation_context import InvocationContext
21
- from google.adk.agents.sequential_agent import SequentialAgent
22
- from google.adk.events import Event
23
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
24
- from google.genai import types
25
- import pytest
26
- from typing_extensions import override
27
-
28
-
29
- class _TestingAgent(BaseAgent):
30
-
31
- @override
32
- async def _run_async_impl(
33
- self, ctx: InvocationContext
34
- ) -> AsyncGenerator[Event, None]:
35
- yield Event(
36
- author=self.name,
37
- invocation_id=ctx.invocation_id,
38
- content=types.Content(
39
- parts=[types.Part(text=f'Hello, async {self.name}!')]
40
- ),
41
- )
42
-
43
- @override
44
- async def _run_live_impl(
45
- self, ctx: InvocationContext
46
- ) -> AsyncGenerator[Event, None]:
47
- yield Event(
48
- author=self.name,
49
- invocation_id=ctx.invocation_id,
50
- content=types.Content(
51
- parts=[types.Part(text=f'Hello, live {self.name}!')]
52
- ),
53
- )
54
-
55
-
56
- def _create_parent_invocation_context(
57
- test_name: str, agent: BaseAgent
58
- ) -> InvocationContext:
59
- session_service = InMemorySessionService()
60
- session = session_service.create_session(
61
- app_name='test_app', user_id='test_user'
62
- )
63
- return InvocationContext(
64
- invocation_id=f'{test_name}_invocation_id',
65
- agent=agent,
66
- session=session,
67
- session_service=session_service,
68
- )
69
-
70
-
71
- @pytest.mark.asyncio
72
- async def test_run_async(request: pytest.FixtureRequest):
73
- agent_1 = _TestingAgent(name=f'{request.function.__name__}_test_agent_1')
74
- agent_2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
75
- sequential_agent = SequentialAgent(
76
- name=f'{request.function.__name__}_test_agent',
77
- sub_agents=[
78
- agent_1,
79
- agent_2,
80
- ],
81
- )
82
- parent_ctx = _create_parent_invocation_context(
83
- request.function.__name__, sequential_agent
84
- )
85
- events = [e async for e in sequential_agent.run_async(parent_ctx)]
86
-
87
- assert len(events) == 2
88
- assert events[0].author == agent_1.name
89
- assert events[1].author == agent_2.name
90
- assert events[0].content.parts[0].text == f'Hello, async {agent_1.name}!'
91
- assert events[1].content.parts[0].text == f'Hello, async {agent_2.name}!'
92
-
93
-
94
- @pytest.mark.asyncio
95
- async def test_run_live(request: pytest.FixtureRequest):
96
- agent_1 = _TestingAgent(name=f'{request.function.__name__}_test_agent_1')
97
- agent_2 = _TestingAgent(name=f'{request.function.__name__}_test_agent_2')
98
- sequential_agent = SequentialAgent(
99
- name=f'{request.function.__name__}_test_agent',
100
- sub_agents=[
101
- agent_1,
102
- agent_2,
103
- ],
104
- )
105
- parent_ctx = _create_parent_invocation_context(
106
- request.function.__name__, sequential_agent
107
- )
108
- events = [e async for e in sequential_agent.run_live(parent_ctx)]
109
-
110
- assert len(events) == 2
111
- assert events[0].author == agent_1.name
112
- assert events[1].author == agent_2.name
113
- assert events[0].content.parts[0].text == f'Hello, live {agent_1.name}!'
114
- assert events[1].content.parts[0].text == f'Hello, live {agent_2.name}!'