google-adk 0.0.3__py3-none-any.whl → 0.0.5__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 (185) hide show
  1. google/adk/agents/run_config.py +4 -0
  2. google/adk/auth/auth_preprocessor.py +19 -16
  3. google/adk/cli/browser/index.html +1 -1
  4. google/adk/cli/browser/{main-SY2WYYGV.js → main-SLIAU2JL.js} +46 -30
  5. google/adk/cli/cli.py +8 -8
  6. google/adk/cli/cli_deploy.py +2 -4
  7. google/adk/cli/cli_tools_click.py +6 -6
  8. google/adk/flows/llm_flows/base_llm_flow.py +1 -1
  9. google/adk/flows/llm_flows/contents.py +21 -1
  10. google/adk/flows/llm_flows/functions.py +3 -1
  11. google/adk/models/google_llm.py +0 -1
  12. google/adk/runners.py +13 -2
  13. google/adk/version.py +1 -1
  14. {google_adk-0.0.3.dist-info → google_adk-0.0.5.dist-info}/METADATA +4 -2
  15. google_adk-0.0.5.dist-info/RECORD +175 -0
  16. {google_adk-0.0.3.dist-info → google_adk-0.0.5.dist-info}/WHEEL +1 -1
  17. google_adk-0.0.5.dist-info/licenses/LICENSE +202 -0
  18. google/adk/._version.py +0 -0
  19. google/adk/docs/Makefile +0 -20
  20. google/adk/docs/build/doctrees/google-adk.doctree +0 -0
  21. google/adk/docs/build/html/_sources/google-adk.rst.txt +0 -98
  22. google/adk/docs/build/html/_sources/index.rst.txt +0 -7
  23. google/adk/docs/build/html/_static/autodoc_pydantic.css +0 -27
  24. google/adk/docs/build/html/_static/basic.css +0 -925
  25. google/adk/docs/build/html/_static/debug.css +0 -85
  26. google/adk/docs/build/html/_static/doctools.js +0 -156
  27. google/adk/docs/build/html/_static/documentation_options.js +0 -29
  28. google/adk/docs/build/html/_static/file.png +0 -0
  29. google/adk/docs/build/html/_static/language_data.js +0 -199
  30. google/adk/docs/build/html/_static/minus.png +0 -0
  31. google/adk/docs/build/html/_static/plus.png +0 -0
  32. google/adk/docs/build/html/_static/pygments.css +0 -274
  33. google/adk/docs/build/html/_static/scripts/furo-extensions.js +0 -16
  34. google/adk/docs/build/html/_static/scripts/furo.js +0 -19
  35. google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +0 -7
  36. google/adk/docs/build/html/_static/scripts/furo.js.map +0 -1
  37. google/adk/docs/build/html/_static/searchtools.js +0 -620
  38. google/adk/docs/build/html/_static/skeleton.css +0 -312
  39. google/adk/docs/build/html/_static/sphinx_highlight.js +0 -170
  40. google/adk/docs/build/html/_static/styles/furo-extensions.css +0 -18
  41. google/adk/docs/build/html/_static/styles/furo-extensions.css.map +0 -1
  42. google/adk/docs/build/html/_static/styles/furo.css +0 -18
  43. google/adk/docs/build/html/_static/styles/furo.css.map +0 -1
  44. google/adk/docs/build/html/genindex.html +0 -861
  45. google/adk/docs/build/html/google-adk.html +0 -5461
  46. google/adk/docs/build/html/index.html +0 -567
  47. google/adk/docs/build/html/objects.inv +0 -0
  48. google/adk/docs/build/html/py-modindex.html +0 -373
  49. google/adk/docs/build/html/search.html +0 -333
  50. google/adk/docs/build/html/searchindex.js +0 -17
  51. google/adk/docs/source/conf.py +0 -133
  52. google/adk/docs/source/google-adk.rst +0 -98
  53. google/adk/docs/source/index.rst +0 -7
  54. google/adk/tests/__init__.py +0 -14
  55. google/adk/tests/integration/.env.example +0 -10
  56. google/adk/tests/integration/__init__.py +0 -18
  57. google/adk/tests/integration/conftest.py +0 -119
  58. google/adk/tests/integration/fixture/__init__.py +0 -14
  59. google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
  60. google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
  61. google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
  62. google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
  63. google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
  64. google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
  65. google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
  66. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
  67. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
  68. google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
  69. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
  70. google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
  71. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
  72. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
  73. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
  74. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
  75. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
  76. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
  77. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
  78. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
  79. google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
  80. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
  81. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
  82. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
  83. google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
  84. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
  85. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
  86. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
  87. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
  88. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
  89. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
  90. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
  91. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
  92. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
  93. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
  94. google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
  95. google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
  96. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  97. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
  98. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
  99. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
  100. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
  101. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
  102. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
  103. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
  104. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
  105. google/adk/tests/integration/models/__init__.py +0 -14
  106. google/adk/tests/integration/models/test_google_llm.py +0 -65
  107. google/adk/tests/integration/test_callback.py +0 -70
  108. google/adk/tests/integration/test_context_variable.py +0 -67
  109. google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
  110. google/adk/tests/integration/test_multi_agent.py +0 -28
  111. google/adk/tests/integration/test_multi_turn.py +0 -42
  112. google/adk/tests/integration/test_single_agent.py +0 -23
  113. google/adk/tests/integration/test_sub_agent.py +0 -26
  114. google/adk/tests/integration/test_system_instruction.py +0 -177
  115. google/adk/tests/integration/test_tools.py +0 -287
  116. google/adk/tests/integration/test_with_test_file.py +0 -34
  117. google/adk/tests/integration/tools/__init__.py +0 -14
  118. google/adk/tests/integration/utils/__init__.py +0 -16
  119. google/adk/tests/integration/utils/asserts.py +0 -75
  120. google/adk/tests/integration/utils/test_runner.py +0 -97
  121. google/adk/tests/unittests/__init__.py +0 -14
  122. google/adk/tests/unittests/agents/__init__.py +0 -14
  123. google/adk/tests/unittests/agents/test_base_agent.py +0 -407
  124. google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
  125. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
  126. google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
  127. google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
  128. google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
  129. google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
  130. google/adk/tests/unittests/artifacts/__init__.py +0 -14
  131. google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
  132. google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
  133. google/adk/tests/unittests/conftest.py +0 -73
  134. google/adk/tests/unittests/fast_api/__init__.py +0 -14
  135. google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
  136. google/adk/tests/unittests/flows/__init__.py +0 -14
  137. google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
  138. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
  139. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
  140. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
  141. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
  142. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
  143. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
  144. google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
  145. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
  146. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
  147. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
  148. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
  149. google/adk/tests/unittests/models/__init__.py +0 -14
  150. google/adk/tests/unittests/models/test_google_llm.py +0 -224
  151. google/adk/tests/unittests/models/test_litellm.py +0 -804
  152. google/adk/tests/unittests/models/test_models.py +0 -60
  153. google/adk/tests/unittests/sessions/__init__.py +0 -14
  154. google/adk/tests/unittests/sessions/test_session_service.py +0 -227
  155. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
  156. google/adk/tests/unittests/streaming/__init__.py +0 -14
  157. google/adk/tests/unittests/streaming/test_streaming.py +0 -50
  158. google/adk/tests/unittests/tools/__init__.py +0 -14
  159. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
  160. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
  161. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
  162. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
  163. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
  164. google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
  165. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
  166. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
  167. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
  168. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
  169. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
  170. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
  171. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
  172. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
  173. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
  174. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
  175. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
  176. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
  177. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
  178. google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
  179. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
  180. google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
  181. google/adk/tests/unittests/tools/test_base_tool.py +0 -141
  182. google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
  183. google/adk/tests/unittests/utils.py +0 -304
  184. google_adk-0.0.3.dist-info/RECORD +0 -340
  185. {google_adk-0.0.3.dist-info → google_adk-0.0.5.dist-info}/entry_points.txt +0 -0
@@ -1,201 +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 Optional
16
- from unittest.mock import MagicMock
17
-
18
- from google.adk.agents.invocation_context import InvocationContext
19
- from google.adk.agents.llm_agent import LlmAgent
20
- from google.adk.auth.auth_credential import AuthCredential
21
- from google.adk.auth.auth_credential import AuthCredentialTypes
22
- from google.adk.auth.auth_credential import HttpAuth
23
- from google.adk.auth.auth_credential import HttpCredentials
24
- from google.adk.auth.auth_credential import OAuth2Auth
25
- from google.adk.auth.auth_schemes import AuthScheme
26
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
27
- from google.adk.sessions.session import Session
28
- from google.adk.tools.openapi_tool.auth.auth_helpers import openid_dict_to_scheme_credential
29
- from google.adk.tools.openapi_tool.auth.auth_helpers import token_to_scheme_credential
30
- from google.adk.tools.openapi_tool.auth.credential_exchangers.auto_auth_credential_exchanger import OAuth2CredentialExchanger
31
- from google.adk.tools.openapi_tool.openapi_spec_parser.tool_auth_handler import ToolAuthHandler
32
- from google.adk.tools.openapi_tool.openapi_spec_parser.tool_auth_handler import ToolContextCredentialStore
33
- from google.adk.tools.tool_context import ToolContext
34
- import pytest
35
-
36
-
37
- # Helper function to create a mock ToolContext
38
- def create_mock_tool_context():
39
- return ToolContext(
40
- function_call_id='test-fc-id',
41
- invocation_context=InvocationContext(
42
- agent=LlmAgent(name='test'),
43
- session=Session(app_name='test', user_id='123', id='123'),
44
- invocation_id='123',
45
- session_service=InMemorySessionService(),
46
- ),
47
- )
48
-
49
-
50
- # Test cases for OpenID Connect
51
- class MockOpenIdConnectCredentialExchanger(OAuth2CredentialExchanger):
52
-
53
- def __init__(
54
- self, expected_scheme, expected_credential, expected_access_token
55
- ):
56
- self.expected_scheme = expected_scheme
57
- self.expected_credential = expected_credential
58
- self.expected_access_token = expected_access_token
59
-
60
- def exchange_credential(
61
- self,
62
- auth_scheme: AuthScheme,
63
- auth_credential: Optional[AuthCredential] = None,
64
- ) -> AuthCredential:
65
- if auth_credential.oauth2 and (
66
- auth_credential.oauth2.auth_response_uri
67
- or auth_credential.oauth2.auth_code
68
- ):
69
- auth_code = (
70
- auth_credential.oauth2.auth_response_uri
71
- if auth_credential.oauth2.auth_response_uri
72
- else auth_credential.oauth2.auth_code
73
- )
74
- # Simulate the token exchange
75
- updated_credential = AuthCredential(
76
- auth_type=AuthCredentialTypes.HTTP, # Store as a bearer token
77
- http=HttpAuth(
78
- scheme='bearer',
79
- credentials=HttpCredentials(
80
- token=auth_code + self.expected_access_token
81
- ),
82
- ),
83
- )
84
- return updated_credential
85
-
86
- # simulate the case of getting auth_uri
87
- return None
88
-
89
-
90
- def get_mock_openid_scheme_credential():
91
- config_dict = {
92
- 'authorization_endpoint': 'test.com',
93
- 'token_endpoint': 'test.com',
94
- }
95
- scopes = ['test_scope']
96
- credential_dict = {
97
- 'client_id': '123',
98
- 'client_secret': '456',
99
- 'redirect_uri': 'test.com',
100
- }
101
- return openid_dict_to_scheme_credential(config_dict, scopes, credential_dict)
102
-
103
-
104
- # Fixture for the OpenID Connect security scheme
105
- @pytest.fixture
106
- def openid_connect_scheme():
107
- scheme, _ = get_mock_openid_scheme_credential()
108
- return scheme
109
-
110
-
111
- # Fixture for a base OpenID Connect credential
112
- @pytest.fixture
113
- def openid_connect_credential():
114
- _, credential = get_mock_openid_scheme_credential()
115
- return credential
116
-
117
-
118
- def test_openid_connect_no_auth_response(
119
- openid_connect_scheme, openid_connect_credential
120
- ):
121
- # Setup Mock exchanger
122
- mock_exchanger = MockOpenIdConnectCredentialExchanger(
123
- openid_connect_scheme, openid_connect_credential, None
124
- )
125
- tool_context = create_mock_tool_context()
126
- credential_store = ToolContextCredentialStore(tool_context=tool_context)
127
- handler = ToolAuthHandler(
128
- tool_context,
129
- openid_connect_scheme,
130
- openid_connect_credential,
131
- credential_exchanger=mock_exchanger,
132
- credential_store=credential_store,
133
- )
134
- result = handler.prepare_auth_credentials()
135
- assert result.state == 'pending'
136
- assert result.auth_credential == openid_connect_credential
137
-
138
-
139
- def test_openid_connect_with_auth_response(
140
- openid_connect_scheme, openid_connect_credential, monkeypatch
141
- ):
142
- mock_exchanger = MockOpenIdConnectCredentialExchanger(
143
- openid_connect_scheme,
144
- openid_connect_credential,
145
- 'test_access_token',
146
- )
147
- tool_context = create_mock_tool_context()
148
-
149
- mock_auth_handler = MagicMock()
150
- mock_auth_handler.get_auth_response.return_value = AuthCredential(
151
- auth_type=AuthCredentialTypes.OPEN_ID_CONNECT,
152
- oauth2=OAuth2Auth(auth_response_uri='test_auth_response_uri'),
153
- )
154
- mock_auth_handler_path = 'google.adk.tools.tool_context.AuthHandler'
155
- monkeypatch.setattr(
156
- mock_auth_handler_path, lambda *args, **kwargs: mock_auth_handler
157
- )
158
-
159
- credential_store = ToolContextCredentialStore(tool_context=tool_context)
160
- handler = ToolAuthHandler(
161
- tool_context,
162
- openid_connect_scheme,
163
- openid_connect_credential,
164
- credential_exchanger=mock_exchanger,
165
- credential_store=credential_store,
166
- )
167
- result = handler.prepare_auth_credentials()
168
- assert result.state == 'done'
169
- assert result.auth_credential.auth_type == AuthCredentialTypes.HTTP
170
- assert 'test_access_token' in result.auth_credential.http.credentials.token
171
- # Verify that the credential was stored:
172
- stored_credential = credential_store.get_credential(
173
- openid_connect_scheme, openid_connect_credential
174
- )
175
- assert stored_credential == result.auth_credential
176
- mock_auth_handler.get_auth_response.assert_called_once()
177
-
178
-
179
- def test_openid_connect_existing_token(
180
- openid_connect_scheme, openid_connect_credential
181
- ):
182
- _, existing_credential = token_to_scheme_credential(
183
- 'oauth2Token', 'header', 'bearer', '123123123'
184
- )
185
- tool_context = create_mock_tool_context()
186
- # Store the credential to simulate existing credential
187
- credential_store = ToolContextCredentialStore(tool_context=tool_context)
188
- key = credential_store.get_credential_key(
189
- openid_connect_scheme, openid_connect_credential
190
- )
191
- credential_store.store_credential(key, existing_credential)
192
-
193
- handler = ToolAuthHandler(
194
- tool_context,
195
- openid_connect_scheme,
196
- openid_connect_credential,
197
- credential_store=credential_store,
198
- )
199
- result = handler.prepare_auth_credentials()
200
- assert result.state == 'done'
201
- assert result.auth_credential == existing_credential
@@ -1,14 +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
-
@@ -1,147 +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 google.adk.agents import Agent
16
- from google.adk.tools.function_tool import FunctionTool
17
- from google.adk.tools.retrieval.vertex_ai_rag_retrieval import VertexAiRagRetrieval
18
- from google.genai import types
19
-
20
- from ... import utils
21
-
22
-
23
- def noop_tool(x: str) -> str:
24
- return x
25
-
26
-
27
- def test_vertex_rag_retrieval_for_gemini_1_x():
28
- responses = [
29
- 'response1',
30
- ]
31
- mockModel = utils.MockModel.create(responses=responses)
32
- mockModel.model = 'gemini-1.5-pro'
33
-
34
- # Calls the first time.
35
- agent = Agent(
36
- name='root_agent',
37
- model=mockModel,
38
- tools=[
39
- VertexAiRagRetrieval(
40
- name='rag_retrieval',
41
- description='rag_retrieval',
42
- rag_corpora=[
43
- 'projects/123456789/locations/us-central1/ragCorpora/1234567890'
44
- ],
45
- )
46
- ],
47
- )
48
- runner = utils.InMemoryRunner(agent)
49
- events = runner.run('test1')
50
-
51
- # Asserts the requests.
52
- assert len(mockModel.requests) == 1
53
- assert utils.simplify_contents(mockModel.requests[0].contents) == [
54
- ('user', 'test1'),
55
- ]
56
- assert len(mockModel.requests[0].config.tools) == 1
57
- assert (
58
- mockModel.requests[0].config.tools[0].function_declarations[0].name
59
- == 'rag_retrieval'
60
- )
61
- assert mockModel.requests[0].tools_dict['rag_retrieval'] is not None
62
-
63
-
64
- def test_vertex_rag_retrieval_for_gemini_1_x_with_another_function_tool():
65
- responses = [
66
- 'response1',
67
- ]
68
- mockModel = utils.MockModel.create(responses=responses)
69
- mockModel.model = 'gemini-1.5-pro'
70
-
71
- # Calls the first time.
72
- agent = Agent(
73
- name='root_agent',
74
- model=mockModel,
75
- tools=[
76
- VertexAiRagRetrieval(
77
- name='rag_retrieval',
78
- description='rag_retrieval',
79
- rag_corpora=[
80
- 'projects/123456789/locations/us-central1/ragCorpora/1234567890'
81
- ],
82
- ),
83
- FunctionTool(func=noop_tool),
84
- ],
85
- )
86
- runner = utils.InMemoryRunner(agent)
87
- events = runner.run('test1')
88
-
89
- # Asserts the requests.
90
- assert len(mockModel.requests) == 1
91
- assert utils.simplify_contents(mockModel.requests[0].contents) == [
92
- ('user', 'test1'),
93
- ]
94
- assert len(mockModel.requests[0].config.tools[0].function_declarations) == 2
95
- assert (
96
- mockModel.requests[0].config.tools[0].function_declarations[0].name
97
- == 'rag_retrieval'
98
- )
99
- assert (
100
- mockModel.requests[0].config.tools[0].function_declarations[1].name
101
- == 'noop_tool'
102
- )
103
- assert mockModel.requests[0].tools_dict['rag_retrieval'] is not None
104
-
105
-
106
- def test_vertex_rag_retrieval_for_gemini_2_x():
107
- responses = [
108
- 'response1',
109
- ]
110
- mockModel = utils.MockModel.create(responses=responses)
111
- mockModel.model = 'gemini-2.0-flash'
112
-
113
- # Calls the first time.
114
- agent = Agent(
115
- name='root_agent',
116
- model=mockModel,
117
- tools=[
118
- VertexAiRagRetrieval(
119
- name='rag_retrieval',
120
- description='rag_retrieval',
121
- rag_corpora=[
122
- 'projects/123456789/locations/us-central1/ragCorpora/1234567890'
123
- ],
124
- )
125
- ],
126
- )
127
- runner = utils.InMemoryRunner(agent)
128
- events = runner.run('test1')
129
-
130
- # Asserts the requests.
131
- assert len(mockModel.requests) == 1
132
- assert utils.simplify_contents(mockModel.requests[0].contents) == [
133
- ('user', 'test1'),
134
- ]
135
- assert len(mockModel.requests[0].config.tools) == 1
136
- assert mockModel.requests[0].config.tools == [
137
- types.Tool(
138
- retrieval=types.Retrieval(
139
- vertex_rag_store=types.VertexRagStore(
140
- rag_corpora=[
141
- 'projects/123456789/locations/us-central1/ragCorpora/1234567890'
142
- ]
143
- )
144
- )
145
- )
146
- ]
147
- assert 'rag_retrieval' not in mockModel.requests[0].tools_dict
@@ -1,167 +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 google.adk.agents import Agent
16
- from google.adk.agents.callback_context import CallbackContext
17
- from google.adk.tools.agent_tool import AgentTool
18
- from google.genai.types import Part
19
- from pydantic import BaseModel
20
- import pytest
21
- from pytest import mark
22
-
23
- from .. import utils
24
-
25
- pytestmark = pytest.mark.skip(
26
- reason='Skipping until tool.func evaluations are fixed (async)'
27
- )
28
-
29
-
30
- function_call_custom = Part.from_function_call(
31
- name='tool_agent', args={'custom_input': 'test1'}
32
- )
33
-
34
- function_call_no_schema = Part.from_function_call(
35
- name='tool_agent', args={'request': 'test1'}
36
- )
37
-
38
- function_response_custom = Part.from_function_response(
39
- name='tool_agent', response={'custom_output': 'response1'}
40
- )
41
-
42
- function_response_no_schema = Part.from_function_response(
43
- name='tool_agent', response={'result': 'response1'}
44
- )
45
-
46
-
47
- def change_state_callback(callback_context: CallbackContext):
48
- callback_context.state['state_1'] = 'changed_value'
49
- print('change_state_callback: ', callback_context.state)
50
-
51
-
52
- def test_no_schema():
53
- mock_model = utils.MockModel.create(
54
- responses=[
55
- function_call_no_schema,
56
- 'response1',
57
- 'response2',
58
- ]
59
- )
60
-
61
- tool_agent = Agent(
62
- name='tool_agent',
63
- model=mock_model,
64
- )
65
-
66
- root_agent = Agent(
67
- name='root_agent',
68
- model=mock_model,
69
- tools=[AgentTool(agent=tool_agent)],
70
- )
71
-
72
- runner = utils.InMemoryRunner(root_agent)
73
-
74
- assert utils.simplify_events(runner.run('test1')) == [
75
- ('root_agent', function_call_no_schema),
76
- ('root_agent', function_response_no_schema),
77
- ('root_agent', 'response2'),
78
- ]
79
-
80
-
81
- def test_update_state():
82
- """The agent tool can read and change parent state."""
83
-
84
- mock_model = utils.MockModel.create(
85
- responses=[
86
- function_call_no_schema,
87
- '{"custom_output": "response1"}',
88
- 'response2',
89
- ]
90
- )
91
-
92
- tool_agent = Agent(
93
- name='tool_agent',
94
- model=mock_model,
95
- instruction='input: {state_1}',
96
- before_agent_callback=change_state_callback,
97
- )
98
-
99
- root_agent = Agent(
100
- name='root_agent',
101
- model=mock_model,
102
- tools=[AgentTool(agent=tool_agent)],
103
- )
104
-
105
- runner = utils.InMemoryRunner(root_agent)
106
- runner.session.state['state_1'] = 'state1_value'
107
-
108
- runner.run('test1')
109
- assert (
110
- 'input: changed_value' in mock_model.requests[1].config.system_instruction
111
- )
112
- assert runner.session.state['state_1'] == 'changed_value'
113
-
114
-
115
- @mark.parametrize(
116
- 'env_variables',
117
- [
118
- 'GOOGLE_AI',
119
- # TODO(wanyif): re-enable after fix.
120
- # 'VERTEX',
121
- ],
122
- indirect=True,
123
- )
124
- def test_custom_schema():
125
- class CustomInput(BaseModel):
126
- custom_input: str
127
-
128
- class CustomOutput(BaseModel):
129
- custom_output: str
130
-
131
- mock_model = utils.MockModel.create(
132
- responses=[
133
- function_call_custom,
134
- '{"custom_output": "response1"}',
135
- 'response2',
136
- ]
137
- )
138
-
139
- tool_agent = Agent(
140
- name='tool_agent',
141
- model=mock_model,
142
- input_schema=CustomInput,
143
- output_schema=CustomOutput,
144
- output_key='tool_output',
145
- )
146
-
147
- root_agent = Agent(
148
- name='root_agent',
149
- model=mock_model,
150
- tools=[AgentTool(agent=tool_agent)],
151
- )
152
-
153
- runner = utils.InMemoryRunner(root_agent)
154
- runner.session.state['state_1'] = 'state1_value'
155
-
156
- assert utils.simplify_events(runner.run('test1')) == [
157
- ('root_agent', function_call_custom),
158
- ('root_agent', function_response_custom),
159
- ('root_agent', 'response2'),
160
- ]
161
-
162
- assert runner.session.state['tool_output'] == {'custom_output': 'response1'}
163
-
164
- assert len(mock_model.requests) == 3
165
- # The second request is the tool agent request.
166
- assert mock_model.requests[1].config.response_schema == CustomOutput
167
- assert mock_model.requests[1].config.response_mime_type == 'application/json'
@@ -1,141 +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 Optional
16
-
17
- from google.adk.agents.invocation_context import InvocationContext
18
- from google.adk.agents.sequential_agent import SequentialAgent
19
- from google.adk.models.llm_request import LlmRequest
20
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
21
- from google.adk.tools.base_tool import BaseTool
22
- from google.adk.tools.tool_context import ToolContext
23
- from google.genai import types
24
- import pytest
25
-
26
-
27
- class _TestingTool(BaseTool):
28
-
29
- def __init__(
30
- self,
31
- declaration: Optional[types.FunctionDeclaration] = None,
32
- ):
33
- super().__init__(name='test_tool', description='test_description')
34
- self.declaration = declaration
35
-
36
- def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
37
- return self.declaration
38
-
39
-
40
- def _create_tool_context() -> ToolContext:
41
- session_service = InMemorySessionService()
42
- session = session_service.create_session(
43
- app_name='test_app', user_id='test_user'
44
- )
45
- agent = SequentialAgent(name='test_agent')
46
- invocation_context = InvocationContext(
47
- invocation_id='invocation_id',
48
- agent=agent,
49
- session=session,
50
- session_service=session_service,
51
- )
52
- return ToolContext(invocation_context)
53
-
54
-
55
- @pytest.mark.asyncio
56
- async def test_process_llm_request_no_declaration():
57
- tool = _TestingTool()
58
- tool_context = _create_tool_context()
59
- llm_request = LlmRequest()
60
-
61
- await tool.process_llm_request(
62
- tool_context=tool_context, llm_request=llm_request
63
- )
64
-
65
- assert llm_request.config is None
66
-
67
-
68
- @pytest.mark.asyncio
69
- async def test_process_llm_request_with_declaration():
70
- declaration = types.FunctionDeclaration(
71
- name='test_tool',
72
- description='test_description',
73
- parameters=types.Schema(
74
- type=types.Type.STRING,
75
- title='param_1',
76
- ),
77
- )
78
- tool = _TestingTool(declaration)
79
- llm_request = LlmRequest()
80
- tool_context = _create_tool_context()
81
-
82
- await tool.process_llm_request(
83
- tool_context=tool_context, llm_request=llm_request
84
- )
85
-
86
- assert llm_request.config.tools[0].function_declarations == [declaration]
87
-
88
-
89
- @pytest.mark.asyncio
90
- async def test_process_llm_request_with_builtin_tool():
91
- declaration = types.FunctionDeclaration(
92
- name='test_tool',
93
- description='test_description',
94
- parameters=types.Schema(
95
- type=types.Type.STRING,
96
- title='param_1',
97
- ),
98
- )
99
- tool = _TestingTool(declaration)
100
- llm_request = LlmRequest(
101
- config=types.GenerateContentConfig(
102
- tools=[types.Tool(google_search=types.GoogleSearch())]
103
- )
104
- )
105
- tool_context = _create_tool_context()
106
-
107
- await tool.process_llm_request(
108
- tool_context=tool_context, llm_request=llm_request
109
- )
110
-
111
- # function_declaration is added to another types.Tool without builtin tool.
112
- assert llm_request.config.tools[1].function_declarations == [declaration]
113
-
114
-
115
- @pytest.mark.asyncio
116
- async def test_process_llm_request_with_builtin_tool_and_another_declaration():
117
- declaration = types.FunctionDeclaration(
118
- name='test_tool',
119
- description='test_description',
120
- parameters=types.Schema(
121
- type=types.Type.STRING,
122
- title='param_1',
123
- ),
124
- )
125
- tool = _TestingTool(declaration)
126
- llm_request = LlmRequest(
127
- config=types.GenerateContentConfig(
128
- tools=[
129
- types.Tool(google_search=types.GoogleSearch()),
130
- types.Tool(function_declarations=[types.FunctionDeclaration()]),
131
- ]
132
- )
133
- )
134
- tool_context = _create_tool_context()
135
-
136
- await tool.process_llm_request(
137
- tool_context=tool_context, llm_request=llm_request
138
- )
139
-
140
- # function_declaration is added to existing types.Tool with function_declaration.
141
- assert llm_request.config.tools[1].function_declarations[1] == declaration