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,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