google-adk 0.0.3__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 (184) 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-CU22TRPI.js} +30 -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/contents.py +21 -1
  9. google/adk/flows/llm_flows/functions.py +3 -1
  10. google/adk/models/google_llm.py +0 -1
  11. google/adk/runners.py +13 -2
  12. google/adk/version.py +1 -1
  13. {google_adk-0.0.3.dist-info → google_adk-0.0.4.dist-info}/METADATA +4 -2
  14. google_adk-0.0.4.dist-info/RECORD +175 -0
  15. {google_adk-0.0.3.dist-info → google_adk-0.0.4.dist-info}/WHEEL +1 -1
  16. google_adk-0.0.4.dist-info/licenses/LICENSE +202 -0
  17. google/adk/._version.py +0 -0
  18. google/adk/docs/Makefile +0 -20
  19. google/adk/docs/build/doctrees/google-adk.doctree +0 -0
  20. google/adk/docs/build/html/_sources/google-adk.rst.txt +0 -98
  21. google/adk/docs/build/html/_sources/index.rst.txt +0 -7
  22. google/adk/docs/build/html/_static/autodoc_pydantic.css +0 -27
  23. google/adk/docs/build/html/_static/basic.css +0 -925
  24. google/adk/docs/build/html/_static/debug.css +0 -85
  25. google/adk/docs/build/html/_static/doctools.js +0 -156
  26. google/adk/docs/build/html/_static/documentation_options.js +0 -29
  27. google/adk/docs/build/html/_static/file.png +0 -0
  28. google/adk/docs/build/html/_static/language_data.js +0 -199
  29. google/adk/docs/build/html/_static/minus.png +0 -0
  30. google/adk/docs/build/html/_static/plus.png +0 -0
  31. google/adk/docs/build/html/_static/pygments.css +0 -274
  32. google/adk/docs/build/html/_static/scripts/furo-extensions.js +0 -16
  33. google/adk/docs/build/html/_static/scripts/furo.js +0 -19
  34. google/adk/docs/build/html/_static/scripts/furo.js.LICENSE.txt +0 -7
  35. google/adk/docs/build/html/_static/scripts/furo.js.map +0 -1
  36. google/adk/docs/build/html/_static/searchtools.js +0 -620
  37. google/adk/docs/build/html/_static/skeleton.css +0 -312
  38. google/adk/docs/build/html/_static/sphinx_highlight.js +0 -170
  39. google/adk/docs/build/html/_static/styles/furo-extensions.css +0 -18
  40. google/adk/docs/build/html/_static/styles/furo-extensions.css.map +0 -1
  41. google/adk/docs/build/html/_static/styles/furo.css +0 -18
  42. google/adk/docs/build/html/_static/styles/furo.css.map +0 -1
  43. google/adk/docs/build/html/genindex.html +0 -861
  44. google/adk/docs/build/html/google-adk.html +0 -5461
  45. google/adk/docs/build/html/index.html +0 -567
  46. google/adk/docs/build/html/objects.inv +0 -0
  47. google/adk/docs/build/html/py-modindex.html +0 -373
  48. google/adk/docs/build/html/search.html +0 -333
  49. google/adk/docs/build/html/searchindex.js +0 -17
  50. google/adk/docs/source/conf.py +0 -133
  51. google/adk/docs/source/google-adk.rst +0 -98
  52. google/adk/docs/source/index.rst +0 -7
  53. google/adk/tests/__init__.py +0 -14
  54. google/adk/tests/integration/.env.example +0 -10
  55. google/adk/tests/integration/__init__.py +0 -18
  56. google/adk/tests/integration/conftest.py +0 -119
  57. google/adk/tests/integration/fixture/__init__.py +0 -14
  58. google/adk/tests/integration/fixture/agent_with_config/__init__.py +0 -15
  59. google/adk/tests/integration/fixture/agent_with_config/agent.py +0 -88
  60. google/adk/tests/integration/fixture/callback_agent/__init__.py +0 -15
  61. google/adk/tests/integration/fixture/callback_agent/agent.py +0 -105
  62. google/adk/tests/integration/fixture/context_update_test/OWNERS +0 -1
  63. google/adk/tests/integration/fixture/context_update_test/__init__.py +0 -15
  64. google/adk/tests/integration/fixture/context_update_test/agent.py +0 -43
  65. google/adk/tests/integration/fixture/context_update_test/successful_test.session.json +0 -582
  66. google/adk/tests/integration/fixture/context_variable_agent/__init__.py +0 -15
  67. google/adk/tests/integration/fixture/context_variable_agent/agent.py +0 -115
  68. google/adk/tests/integration/fixture/customer_support_ma/__init__.py +0 -15
  69. google/adk/tests/integration/fixture/customer_support_ma/agent.py +0 -172
  70. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/__init__.py +0 -15
  71. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/agent.py +0 -338
  72. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/order_query.test.json +0 -69
  73. google/adk/tests/integration/fixture/ecommerce_customer_service_agent/test_config.json +0 -6
  74. google/adk/tests/integration/fixture/flow_complex_spark/__init__.py +0 -15
  75. google/adk/tests/integration/fixture/flow_complex_spark/agent.py +0 -182
  76. google/adk/tests/integration/fixture/flow_complex_spark/sample.session.json +0 -190
  77. google/adk/tests/integration/fixture/hello_world_agent/__init__.py +0 -15
  78. google/adk/tests/integration/fixture/hello_world_agent/agent.py +0 -95
  79. google/adk/tests/integration/fixture/hello_world_agent/roll_die.test.json +0 -24
  80. google/adk/tests/integration/fixture/hello_world_agent/test_config.json +0 -6
  81. google/adk/tests/integration/fixture/home_automation_agent/__init__.py +0 -15
  82. google/adk/tests/integration/fixture/home_automation_agent/agent.py +0 -304
  83. google/adk/tests/integration/fixture/home_automation_agent/simple_test.test.json +0 -5
  84. google/adk/tests/integration/fixture/home_automation_agent/simple_test2.test.json +0 -5
  85. google/adk/tests/integration/fixture/home_automation_agent/test_config.json +0 -5
  86. google/adk/tests/integration/fixture/home_automation_agent/test_files/dependent_tool_calls.test.json +0 -18
  87. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/eval_data.test.json +0 -17
  88. google/adk/tests/integration/fixture/home_automation_agent/test_files/memorizing_past_events/test_config.json +0 -6
  89. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_multi_turn_conversation.test.json +0 -18
  90. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test.test.json +0 -17
  91. google/adk/tests/integration/fixture/home_automation_agent/test_files/simple_test2.test.json +0 -5
  92. google/adk/tests/integration/fixture/home_automation_agent/test_files/test_config.json +0 -5
  93. google/adk/tests/integration/fixture/tool_agent/__init__.py +0 -15
  94. google/adk/tests/integration/fixture/tool_agent/agent.py +0 -218
  95. google/adk/tests/integration/fixture/tool_agent/files/Agent_test_plan.pdf +0 -0
  96. google/adk/tests/integration/fixture/trip_planner_agent/__init__.py +0 -15
  97. google/adk/tests/integration/fixture/trip_planner_agent/agent.py +0 -110
  98. google/adk/tests/integration/fixture/trip_planner_agent/initial.session.json +0 -13
  99. google/adk/tests/integration/fixture/trip_planner_agent/test_config.json +0 -5
  100. google/adk/tests/integration/fixture/trip_planner_agent/test_files/initial.session.json +0 -13
  101. google/adk/tests/integration/fixture/trip_planner_agent/test_files/test_config.json +0 -5
  102. google/adk/tests/integration/fixture/trip_planner_agent/test_files/trip_inquiry_sub_agent.test.json +0 -7
  103. google/adk/tests/integration/fixture/trip_planner_agent/trip_inquiry.test.json +0 -19
  104. google/adk/tests/integration/models/__init__.py +0 -14
  105. google/adk/tests/integration/models/test_google_llm.py +0 -65
  106. google/adk/tests/integration/test_callback.py +0 -70
  107. google/adk/tests/integration/test_context_variable.py +0 -67
  108. google/adk/tests/integration/test_evalute_agent_in_fixture.py +0 -76
  109. google/adk/tests/integration/test_multi_agent.py +0 -28
  110. google/adk/tests/integration/test_multi_turn.py +0 -42
  111. google/adk/tests/integration/test_single_agent.py +0 -23
  112. google/adk/tests/integration/test_sub_agent.py +0 -26
  113. google/adk/tests/integration/test_system_instruction.py +0 -177
  114. google/adk/tests/integration/test_tools.py +0 -287
  115. google/adk/tests/integration/test_with_test_file.py +0 -34
  116. google/adk/tests/integration/tools/__init__.py +0 -14
  117. google/adk/tests/integration/utils/__init__.py +0 -16
  118. google/adk/tests/integration/utils/asserts.py +0 -75
  119. google/adk/tests/integration/utils/test_runner.py +0 -97
  120. google/adk/tests/unittests/__init__.py +0 -14
  121. google/adk/tests/unittests/agents/__init__.py +0 -14
  122. google/adk/tests/unittests/agents/test_base_agent.py +0 -407
  123. google/adk/tests/unittests/agents/test_langgraph_agent.py +0 -191
  124. google/adk/tests/unittests/agents/test_llm_agent_callbacks.py +0 -138
  125. google/adk/tests/unittests/agents/test_llm_agent_fields.py +0 -231
  126. google/adk/tests/unittests/agents/test_loop_agent.py +0 -136
  127. google/adk/tests/unittests/agents/test_parallel_agent.py +0 -92
  128. google/adk/tests/unittests/agents/test_sequential_agent.py +0 -114
  129. google/adk/tests/unittests/artifacts/__init__.py +0 -14
  130. google/adk/tests/unittests/artifacts/test_artifact_service.py +0 -276
  131. google/adk/tests/unittests/auth/test_auth_handler.py +0 -575
  132. google/adk/tests/unittests/conftest.py +0 -73
  133. google/adk/tests/unittests/fast_api/__init__.py +0 -14
  134. google/adk/tests/unittests/fast_api/test_fast_api.py +0 -269
  135. google/adk/tests/unittests/flows/__init__.py +0 -14
  136. google/adk/tests/unittests/flows/llm_flows/__init__.py +0 -14
  137. google/adk/tests/unittests/flows/llm_flows/_test_examples.py +0 -142
  138. google/adk/tests/unittests/flows/llm_flows/test_agent_transfer.py +0 -311
  139. google/adk/tests/unittests/flows/llm_flows/test_functions_long_running.py +0 -244
  140. google/adk/tests/unittests/flows/llm_flows/test_functions_request_euc.py +0 -346
  141. google/adk/tests/unittests/flows/llm_flows/test_functions_sequential.py +0 -93
  142. google/adk/tests/unittests/flows/llm_flows/test_functions_simple.py +0 -258
  143. google/adk/tests/unittests/flows/llm_flows/test_identity.py +0 -66
  144. google/adk/tests/unittests/flows/llm_flows/test_instructions.py +0 -164
  145. google/adk/tests/unittests/flows/llm_flows/test_model_callbacks.py +0 -142
  146. google/adk/tests/unittests/flows/llm_flows/test_other_configs.py +0 -46
  147. google/adk/tests/unittests/flows/llm_flows/test_tool_callbacks.py +0 -269
  148. google/adk/tests/unittests/models/__init__.py +0 -14
  149. google/adk/tests/unittests/models/test_google_llm.py +0 -224
  150. google/adk/tests/unittests/models/test_litellm.py +0 -804
  151. google/adk/tests/unittests/models/test_models.py +0 -60
  152. google/adk/tests/unittests/sessions/__init__.py +0 -14
  153. google/adk/tests/unittests/sessions/test_session_service.py +0 -227
  154. google/adk/tests/unittests/sessions/test_vertex_ai_session_service.py +0 -246
  155. google/adk/tests/unittests/streaming/__init__.py +0 -14
  156. google/adk/tests/unittests/streaming/test_streaming.py +0 -50
  157. google/adk/tests/unittests/tools/__init__.py +0 -14
  158. google/adk/tests/unittests/tools/apihub_tool/clients/test_apihub_client.py +0 -499
  159. google/adk/tests/unittests/tools/apihub_tool/test_apihub_toolset.py +0 -204
  160. google/adk/tests/unittests/tools/application_integration_tool/clients/test_connections_client.py +0 -600
  161. google/adk/tests/unittests/tools/application_integration_tool/clients/test_integration_client.py +0 -630
  162. google/adk/tests/unittests/tools/application_integration_tool/test_application_integration_toolset.py +0 -345
  163. google/adk/tests/unittests/tools/google_api_tool/__init__.py +0 -13
  164. google/adk/tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py +0 -657
  165. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_auto_auth_credential_exchanger.py +0 -145
  166. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_base_auth_credential_exchanger.py +0 -68
  167. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_oauth2_exchanger.py +0 -153
  168. google/adk/tests/unittests/tools/openapi_tool/auth/credential_exchangers/test_service_account_exchanger.py +0 -196
  169. google/adk/tests/unittests/tools/openapi_tool/auth/test_auth_helper.py +0 -573
  170. google/adk/tests/unittests/tools/openapi_tool/common/test_common.py +0 -436
  171. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test.yaml +0 -1367
  172. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_spec_parser.py +0 -628
  173. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_openapi_toolset.py +0 -139
  174. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_operation_parser.py +0 -406
  175. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_rest_api_tool.py +0 -966
  176. google/adk/tests/unittests/tools/openapi_tool/openapi_spec_parser/test_tool_auth_handler.py +0 -201
  177. google/adk/tests/unittests/tools/retrieval/__init__.py +0 -14
  178. google/adk/tests/unittests/tools/retrieval/test_vertex_ai_rag_retrieval.py +0 -147
  179. google/adk/tests/unittests/tools/test_agent_tool.py +0 -167
  180. google/adk/tests/unittests/tools/test_base_tool.py +0 -141
  181. google/adk/tests/unittests/tools/test_build_function_declaration.py +0 -277
  182. google/adk/tests/unittests/utils.py +0 -304
  183. google_adk-0.0.3.dist-info/RECORD +0 -340
  184. {google_adk-0.0.3.dist-info → google_adk-0.0.4.dist-info}/entry_points.txt +0 -0
@@ -1,277 +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 Dict
16
- from typing import List
17
-
18
- from google.adk.tools import _automatic_function_calling_util
19
- from google.adk.tools.agent_tool import ToolContext
20
- from google.adk.tools.langchain_tool import LangchainTool
21
- # TODO: crewai requires python 3.10 as minimum
22
- # from crewai_tools import FileReadTool
23
- from langchain_community.tools import ShellTool
24
- from pydantic import BaseModel
25
- import pytest
26
-
27
-
28
- def test_unsupported_variant():
29
- def simple_function(input_str: str) -> str:
30
- return {'result': input_str}
31
-
32
- with pytest.raises(ValueError):
33
- _automatic_function_calling_util.build_function_declaration(
34
- func=simple_function, variant='Unsupported'
35
- )
36
-
37
-
38
- def test_string_input():
39
- def simple_function(input_str: str) -> str:
40
- return {'result': input_str}
41
-
42
- function_decl = _automatic_function_calling_util.build_function_declaration(
43
- func=simple_function
44
- )
45
-
46
- assert function_decl.name == 'simple_function'
47
- assert function_decl.parameters.type == 'OBJECT'
48
- assert function_decl.parameters.properties['input_str'].type == 'STRING'
49
-
50
-
51
- def test_int_input():
52
- def simple_function(input_str: int) -> str:
53
- return {'result': input_str}
54
-
55
- function_decl = _automatic_function_calling_util.build_function_declaration(
56
- func=simple_function
57
- )
58
-
59
- assert function_decl.name == 'simple_function'
60
- assert function_decl.parameters.type == 'OBJECT'
61
- assert function_decl.parameters.properties['input_str'].type == 'INTEGER'
62
-
63
-
64
- def test_float_input():
65
- def simple_function(input_str: float) -> str:
66
- return {'result': input_str}
67
-
68
- function_decl = _automatic_function_calling_util.build_function_declaration(
69
- func=simple_function
70
- )
71
-
72
- assert function_decl.name == 'simple_function'
73
- assert function_decl.parameters.type == 'OBJECT'
74
- assert function_decl.parameters.properties['input_str'].type == 'NUMBER'
75
-
76
-
77
- def test_bool_input():
78
- def simple_function(input_str: bool) -> str:
79
- return {'result': input_str}
80
-
81
- function_decl = _automatic_function_calling_util.build_function_declaration(
82
- func=simple_function
83
- )
84
-
85
- assert function_decl.name == 'simple_function'
86
- assert function_decl.parameters.type == 'OBJECT'
87
- assert function_decl.parameters.properties['input_str'].type == 'BOOLEAN'
88
-
89
-
90
- def test_array_input():
91
- def simple_function(input_str: List[str]) -> str:
92
- return {'result': input_str}
93
-
94
- function_decl = _automatic_function_calling_util.build_function_declaration(
95
- func=simple_function
96
- )
97
-
98
- assert function_decl.name == 'simple_function'
99
- assert function_decl.parameters.type == 'OBJECT'
100
- assert function_decl.parameters.properties['input_str'].type == 'ARRAY'
101
-
102
-
103
- def test_dict_input():
104
- def simple_function(input_str: Dict[str, str]) -> str:
105
- return {'result': input_str}
106
-
107
- function_decl = _automatic_function_calling_util.build_function_declaration(
108
- func=simple_function
109
- )
110
-
111
- assert function_decl.name == 'simple_function'
112
- assert function_decl.parameters.type == 'OBJECT'
113
- assert function_decl.parameters.properties['input_str'].type == 'OBJECT'
114
-
115
-
116
- def test_basemodel_input():
117
- class CustomInput(BaseModel):
118
- input_str: str
119
-
120
- def simple_function(input: CustomInput) -> str:
121
- return {'result': input}
122
-
123
- function_decl = _automatic_function_calling_util.build_function_declaration(
124
- func=simple_function
125
- )
126
-
127
- assert function_decl.name == 'simple_function'
128
- assert function_decl.parameters.type == 'OBJECT'
129
- assert function_decl.parameters.properties['input'].type == 'OBJECT'
130
- assert (
131
- function_decl.parameters.properties['input'].properties['input_str'].type
132
- == 'STRING'
133
- )
134
-
135
-
136
- def test_toolcontext_ignored():
137
- def simple_function(input_str: str, tool_context: ToolContext) -> str:
138
- return {'result': input_str}
139
-
140
- function_decl = _automatic_function_calling_util.build_function_declaration(
141
- func=simple_function, ignore_params=['tool_context']
142
- )
143
-
144
- assert function_decl.name == 'simple_function'
145
- assert function_decl.parameters.type == 'OBJECT'
146
- assert function_decl.parameters.properties['input_str'].type == 'STRING'
147
- assert 'tool_context' not in function_decl.parameters.properties
148
-
149
-
150
- def test_basemodel():
151
- class SimpleFunction(BaseModel):
152
- input_str: str
153
- custom_input: int
154
-
155
- function_decl = _automatic_function_calling_util.build_function_declaration(
156
- func=SimpleFunction, ignore_params=['custom_input']
157
- )
158
-
159
- assert function_decl.name == 'SimpleFunction'
160
- assert function_decl.parameters.type == 'OBJECT'
161
- assert function_decl.parameters.properties['input_str'].type == 'STRING'
162
- assert 'custom_input' not in function_decl.parameters.properties
163
-
164
-
165
- def test_nested_basemodel_input():
166
- class ChildInput(BaseModel):
167
- input_str: str
168
-
169
- class CustomInput(BaseModel):
170
- child: ChildInput
171
-
172
- def simple_function(input: CustomInput) -> str:
173
- return {'result': input}
174
-
175
- function_decl = _automatic_function_calling_util.build_function_declaration(
176
- func=simple_function
177
- )
178
-
179
- assert function_decl.name == 'simple_function'
180
- assert function_decl.parameters.type == 'OBJECT'
181
- assert function_decl.parameters.properties['input'].type == 'OBJECT'
182
- assert (
183
- function_decl.parameters.properties['input'].properties['child'].type
184
- == 'OBJECT'
185
- )
186
- assert (
187
- function_decl.parameters.properties['input']
188
- .properties['child']
189
- .properties['input_str']
190
- .type
191
- == 'STRING'
192
- )
193
-
194
-
195
- def test_basemodel_with_nested_basemodel():
196
- class ChildInput(BaseModel):
197
- input_str: str
198
-
199
- class CustomInput(BaseModel):
200
- child: ChildInput
201
-
202
- function_decl = _automatic_function_calling_util.build_function_declaration(
203
- func=CustomInput, ignore_params=['custom_input']
204
- )
205
-
206
- assert function_decl.name == 'CustomInput'
207
- assert function_decl.parameters.type == 'OBJECT'
208
- assert function_decl.parameters.properties['child'].type == 'OBJECT'
209
- assert (
210
- function_decl.parameters.properties['child'].properties['input_str'].type
211
- == 'STRING'
212
- )
213
- assert 'custom_input' not in function_decl.parameters.properties
214
-
215
-
216
- def test_list():
217
- def simple_function(
218
- input_str: List[str], input_dir: List[Dict[str, str]]
219
- ) -> str:
220
- return {'result': input_str}
221
-
222
- function_decl = _automatic_function_calling_util.build_function_declaration(
223
- func=simple_function
224
- )
225
-
226
- assert function_decl.name == 'simple_function'
227
- assert function_decl.parameters.type == 'OBJECT'
228
- assert function_decl.parameters.properties['input_str'].type == 'ARRAY'
229
- assert function_decl.parameters.properties['input_str'].items.type == 'STRING'
230
- assert function_decl.parameters.properties['input_dir'].type == 'ARRAY'
231
- assert function_decl.parameters.properties['input_dir'].items.type == 'OBJECT'
232
-
233
-
234
- def test_basemodel_list():
235
- class ChildInput(BaseModel):
236
- input_str: str
237
-
238
- class CustomInput(BaseModel):
239
- child: ChildInput
240
-
241
- def simple_function(input_str: List[CustomInput]) -> str:
242
- return {'result': input_str}
243
-
244
- function_decl = _automatic_function_calling_util.build_function_declaration(
245
- func=simple_function
246
- )
247
-
248
- assert function_decl.name == 'simple_function'
249
- assert function_decl.parameters.type == 'OBJECT'
250
- assert function_decl.parameters.properties['input_str'].type == 'ARRAY'
251
- assert function_decl.parameters.properties['input_str'].items.type == 'OBJECT'
252
- assert (
253
- function_decl.parameters.properties['input_str']
254
- .items.properties['child']
255
- .type
256
- == 'OBJECT'
257
- )
258
- assert (
259
- function_decl.parameters.properties['input_str']
260
- .items.properties['child']
261
- .properties['input_str']
262
- .type
263
- == 'STRING'
264
- )
265
-
266
-
267
- # TODO: comment out this test for now as crewai requires python 3.10 as minimum
268
- # def test_crewai_tool():
269
- # docs_tool = CrewaiTool(
270
- # name='direcotry_read_tool',
271
- # description='use this to find files for you.',
272
- # tool=FileReadTool(),
273
- # )
274
- # function_decl = docs_tool.get_declaration()
275
- # assert function_decl.name == 'direcotry_read_tool'
276
- # assert function_decl.parameters.type == 'OBJECT'
277
- # assert function_decl.parameters.properties['file_path'].type == 'STRING'
@@ -1,304 +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
- import asyncio
16
- import contextlib
17
- from typing import AsyncGenerator
18
- from typing import Generator
19
- from typing import Union
20
-
21
- from google.adk.agents.invocation_context import InvocationContext
22
- from google.adk.agents.live_request_queue import LiveRequestQueue
23
- from google.adk.agents.llm_agent import Agent
24
- from google.adk.agents.llm_agent import LlmAgent
25
- from google.adk.agents.run_config import RunConfig
26
- from google.adk.artifacts import InMemoryArtifactService
27
- from google.adk.events.event import Event
28
- from google.adk.memory.in_memory_memory_service import InMemoryMemoryService
29
- from google.adk.models.base_llm import BaseLlm
30
- from google.adk.models.base_llm_connection import BaseLlmConnection
31
- from google.adk.models.llm_request import LlmRequest
32
- from google.adk.models.llm_response import LlmResponse
33
- from google.adk.runners import InMemoryRunner as AfInMemoryRunner
34
- from google.adk.runners import Runner
35
- from google.adk.sessions.in_memory_session_service import InMemorySessionService
36
- from google.adk.sessions.session import Session
37
- from google.genai import types
38
- from google.genai.types import Part
39
- from typing_extensions import override
40
-
41
-
42
- class UserContent(types.Content):
43
-
44
- def __init__(self, text_or_part: str):
45
- parts = [
46
- types.Part.from_text(text=text_or_part)
47
- if isinstance(text_or_part, str)
48
- else text_or_part
49
- ]
50
- super().__init__(role='user', parts=parts)
51
-
52
-
53
- class ModelContent(types.Content):
54
-
55
- def __init__(self, parts: list[types.Part]):
56
- super().__init__(role='model', parts=parts)
57
-
58
-
59
- def create_invocation_context(agent: Agent, user_content: str = ''):
60
- invocation_id = 'test_id'
61
- artifact_service = InMemoryArtifactService()
62
- session_service = InMemorySessionService()
63
- memory_service = InMemoryMemoryService()
64
- invocation_context = InvocationContext(
65
- artifact_service=artifact_service,
66
- session_service=session_service,
67
- memory_service=memory_service,
68
- invocation_id=invocation_id,
69
- agent=agent,
70
- session=session_service.create_session(
71
- app_name='test_app', user_id='test_user'
72
- ),
73
- user_content=types.Content(
74
- role='user', parts=[types.Part.from_text(text=user_content)]
75
- ),
76
- run_config=RunConfig(),
77
- )
78
- if user_content:
79
- append_user_content(
80
- invocation_context, [types.Part.from_text(text=user_content)]
81
- )
82
- return invocation_context
83
-
84
-
85
- def append_user_content(
86
- invocation_context: InvocationContext, parts: list[types.Part]
87
- ) -> Event:
88
- session = invocation_context.session
89
- event = Event(
90
- invocation_id=invocation_context.invocation_id,
91
- author='user',
92
- content=types.Content(role='user', parts=parts),
93
- )
94
- session.events.append(event)
95
- return event
96
-
97
-
98
- # Extracts the contents from the events and transform them into a list of
99
- # (author, simplified_content) tuples.
100
- def simplify_events(events: list[Event]) -> list[(str, types.Part)]:
101
- return [(event.author, simplify_content(event.content)) for event in events]
102
-
103
-
104
- # Simplifies the contents into a list of (author, simplified_content) tuples.
105
- def simplify_contents(contents: list[types.Content]) -> list[(str, types.Part)]:
106
- return [(content.role, simplify_content(content)) for content in contents]
107
-
108
-
109
- # Simplifies the content so it's easier to assert.
110
- # - If there is only one part, return part
111
- # - If the only part is pure text, return stripped_text
112
- # - If there are multiple parts, return parts
113
- # - remove function_call_id if it exists
114
- def simplify_content(
115
- content: types.Content,
116
- ) -> Union[str, types.Part, list[types.Part]]:
117
- for part in content.parts:
118
- if part.function_call and part.function_call.id:
119
- part.function_call.id = None
120
- if part.function_response and part.function_response.id:
121
- part.function_response.id = None
122
- if len(content.parts) == 1:
123
- if content.parts[0].text:
124
- return content.parts[0].text.strip()
125
- else:
126
- return content.parts[0]
127
- return content.parts
128
-
129
-
130
- def get_user_content(message: types.ContentUnion) -> types.Content:
131
- return message if isinstance(message, types.Content) else UserContent(message)
132
-
133
-
134
- class TestInMemoryRunner(AfInMemoryRunner):
135
- """InMemoryRunner that is tailored for tests, features async run method.
136
-
137
- app_name is hardcoded as InMemoryRunner in the parent class.
138
- """
139
-
140
- async def run_async_with_new_session(
141
- self, new_message: types.ContentUnion
142
- ) -> list[Event]:
143
-
144
- session = self.session_service.create_session(
145
- app_name='InMemoryRunner', user_id='test_user'
146
- )
147
- collected_events = []
148
-
149
- async for event in self.run_async(
150
- user_id=session.user_id,
151
- session_id=session.id,
152
- new_message=get_user_content(new_message),
153
- ):
154
- collected_events.append(event)
155
-
156
- return collected_events
157
-
158
-
159
- class InMemoryRunner:
160
- """InMemoryRunner that is tailored for tests."""
161
-
162
- def __init__(
163
- self,
164
- root_agent: Union[Agent, LlmAgent],
165
- response_modalities: list[str] = None,
166
- ):
167
- self.root_agent = root_agent
168
- self.runner = Runner(
169
- app_name='test_app',
170
- agent=root_agent,
171
- artifact_service=InMemoryArtifactService(),
172
- session_service=InMemorySessionService(),
173
- memory_service=InMemoryMemoryService(),
174
- )
175
- self.session_id = self.runner.session_service.create_session(
176
- app_name='test_app', user_id='test_user'
177
- ).id
178
-
179
- @property
180
- def session(self) -> Session:
181
- return self.runner.session_service.get_session(
182
- app_name='test_app', user_id='test_user', session_id=self.session_id
183
- )
184
-
185
- def run(self, new_message: types.ContentUnion) -> list[Event]:
186
- return list(
187
- self.runner.run(
188
- user_id=self.session.user_id,
189
- session_id=self.session.id,
190
- new_message=get_user_content(new_message),
191
- )
192
- )
193
-
194
- def run_live(self, live_request_queue: LiveRequestQueue) -> list[Event]:
195
- collected_responses = []
196
-
197
- async def consume_responses():
198
- run_res = self.runner.run_live(
199
- session=self.session,
200
- live_request_queue=live_request_queue,
201
- )
202
-
203
- async for response in run_res:
204
- collected_responses.append(response)
205
- # When we have enough response, we should return
206
- if len(collected_responses) >= 1:
207
- return
208
-
209
- try:
210
- asyncio.run(consume_responses())
211
- except asyncio.TimeoutError:
212
- print('Returning any partial results collected so far.')
213
-
214
- return collected_responses
215
-
216
-
217
- class MockModel(BaseLlm):
218
- model: str = 'mock'
219
-
220
- requests: list[LlmRequest] = []
221
- responses: list[LlmResponse]
222
- response_index: int = -1
223
-
224
- @classmethod
225
- def create(
226
- cls,
227
- responses: Union[
228
- list[types.Part], list[LlmResponse], list[str], list[list[types.Part]]
229
- ],
230
- ):
231
- if not responses:
232
- return cls(responses=[])
233
- elif isinstance(responses[0], LlmResponse):
234
- # reponses is list[LlmResponse]
235
- return cls(responses=responses)
236
- else:
237
- responses = [
238
- LlmResponse(content=ModelContent(item))
239
- if isinstance(item, list) and isinstance(item[0], types.Part)
240
- # responses is list[list[Part]]
241
- else LlmResponse(
242
- content=ModelContent(
243
- # responses is list[str] or list[Part]
244
- [Part(text=item) if isinstance(item, str) else item]
245
- )
246
- )
247
- for item in responses
248
- if item
249
- ]
250
-
251
- return cls(responses=responses)
252
-
253
- @staticmethod
254
- def supported_models() -> list[str]:
255
- return ['mock']
256
-
257
- def generate_content(
258
- self, llm_request: LlmRequest, stream: bool = False
259
- ) -> Generator[LlmResponse, None, None]:
260
- # Increasement of the index has to happen before the yield.
261
- self.response_index += 1
262
- self.requests.append(llm_request)
263
- # yield LlmResponse(content=self.responses[self.response_index])
264
- yield self.responses[self.response_index]
265
-
266
- @override
267
- async def generate_content_async(
268
- self, llm_request: LlmRequest, stream: bool = False
269
- ) -> AsyncGenerator[LlmResponse, None]:
270
- # Increasement of the index has to happen before the yield.
271
- self.response_index += 1
272
- self.requests.append(llm_request)
273
- yield self.responses[self.response_index]
274
-
275
- @contextlib.asynccontextmanager
276
- async def connect(self, llm_request: LlmRequest) -> BaseLlmConnection:
277
- """Creates a live connection to the LLM."""
278
- yield MockLlmConnection(self.responses)
279
-
280
-
281
- class MockLlmConnection(BaseLlmConnection):
282
-
283
- def __init__(self, llm_responses: list[LlmResponse]):
284
- self.llm_responses = llm_responses
285
-
286
- async def send_history(self, history: list[types.Content]):
287
- pass
288
-
289
- async def send_content(self, content: types.Content):
290
- pass
291
-
292
- async def send(self, data):
293
- pass
294
-
295
- async def send_realtime(self, blob: types.Blob):
296
- pass
297
-
298
- async def receive(self) -> AsyncGenerator[LlmResponse, None]:
299
- """Yield each of the pre-defined LlmResponses."""
300
- for response in self.llm_responses:
301
- yield response
302
-
303
- async def close(self):
304
- pass