google-adk 0.5.0__py3-none-any.whl → 1.0.0__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 (113) hide show
  1. google/adk/agents/base_agent.py +76 -30
  2. google/adk/agents/base_agent.py.orig +330 -0
  3. google/adk/agents/callback_context.py +0 -5
  4. google/adk/agents/llm_agent.py +122 -30
  5. google/adk/agents/loop_agent.py +1 -1
  6. google/adk/agents/parallel_agent.py +7 -0
  7. google/adk/agents/readonly_context.py +7 -1
  8. google/adk/agents/run_config.py +1 -1
  9. google/adk/agents/sequential_agent.py +31 -0
  10. google/adk/agents/transcription_entry.py +4 -2
  11. google/adk/artifacts/gcs_artifact_service.py +1 -1
  12. google/adk/artifacts/in_memory_artifact_service.py +1 -1
  13. google/adk/auth/auth_credential.py +6 -1
  14. google/adk/auth/auth_preprocessor.py +7 -1
  15. google/adk/auth/auth_tool.py +3 -4
  16. google/adk/cli/agent_graph.py +5 -5
  17. google/adk/cli/browser/index.html +2 -2
  18. google/adk/cli/browser/{main-ULN5R5I5.js → main-QOEMUXM4.js} +44 -45
  19. google/adk/cli/cli.py +7 -7
  20. google/adk/cli/cli_deploy.py +7 -2
  21. google/adk/cli/cli_eval.py +172 -99
  22. google/adk/cli/cli_tools_click.py +147 -64
  23. google/adk/cli/fast_api.py +330 -148
  24. google/adk/cli/fast_api.py.orig +174 -80
  25. google/adk/cli/utils/common.py +23 -0
  26. google/adk/cli/utils/evals.py +83 -1
  27. google/adk/cli/utils/logs.py +13 -5
  28. google/adk/code_executors/__init__.py +3 -1
  29. google/adk/code_executors/built_in_code_executor.py +52 -0
  30. google/adk/evaluation/__init__.py +1 -1
  31. google/adk/evaluation/agent_evaluator.py +168 -128
  32. google/adk/evaluation/eval_case.py +102 -0
  33. google/adk/evaluation/eval_set.py +37 -0
  34. google/adk/evaluation/eval_sets_manager.py +42 -0
  35. google/adk/evaluation/evaluation_generator.py +88 -113
  36. google/adk/evaluation/evaluator.py +56 -0
  37. google/adk/evaluation/local_eval_sets_manager.py +264 -0
  38. google/adk/evaluation/response_evaluator.py +106 -2
  39. google/adk/evaluation/trajectory_evaluator.py +83 -2
  40. google/adk/events/event.py +6 -1
  41. google/adk/events/event_actions.py +6 -1
  42. google/adk/examples/example_util.py +3 -2
  43. google/adk/flows/llm_flows/_code_execution.py +9 -1
  44. google/adk/flows/llm_flows/audio_transcriber.py +4 -3
  45. google/adk/flows/llm_flows/base_llm_flow.py +54 -15
  46. google/adk/flows/llm_flows/functions.py +9 -8
  47. google/adk/flows/llm_flows/instructions.py +13 -5
  48. google/adk/flows/llm_flows/single_flow.py +1 -1
  49. google/adk/memory/__init__.py +1 -1
  50. google/adk/memory/_utils.py +23 -0
  51. google/adk/memory/base_memory_service.py +23 -21
  52. google/adk/memory/base_memory_service.py.orig +76 -0
  53. google/adk/memory/in_memory_memory_service.py +57 -25
  54. google/adk/memory/memory_entry.py +37 -0
  55. google/adk/memory/vertex_ai_rag_memory_service.py +38 -15
  56. google/adk/models/anthropic_llm.py +16 -9
  57. google/adk/models/gemini_llm_connection.py +11 -11
  58. google/adk/models/google_llm.py +9 -2
  59. google/adk/models/google_llm.py.orig +305 -0
  60. google/adk/models/lite_llm.py +77 -21
  61. google/adk/models/llm_response.py +14 -2
  62. google/adk/models/registry.py +1 -1
  63. google/adk/runners.py +65 -41
  64. google/adk/sessions/__init__.py +1 -1
  65. google/adk/sessions/base_session_service.py +6 -33
  66. google/adk/sessions/database_session_service.py +58 -65
  67. google/adk/sessions/in_memory_session_service.py +106 -24
  68. google/adk/sessions/session.py +3 -0
  69. google/adk/sessions/vertex_ai_session_service.py +23 -45
  70. google/adk/telemetry.py +3 -0
  71. google/adk/tools/__init__.py +4 -7
  72. google/adk/tools/{built_in_code_execution_tool.py → _built_in_code_execution_tool.py} +11 -0
  73. google/adk/tools/_memory_entry_utils.py +30 -0
  74. google/adk/tools/agent_tool.py +9 -9
  75. google/adk/tools/apihub_tool/apihub_toolset.py +55 -74
  76. google/adk/tools/application_integration_tool/application_integration_toolset.py +107 -85
  77. google/adk/tools/application_integration_tool/clients/connections_client.py +20 -0
  78. google/adk/tools/application_integration_tool/clients/integration_client.py +6 -6
  79. google/adk/tools/application_integration_tool/integration_connector_tool.py +69 -26
  80. google/adk/tools/base_toolset.py +58 -0
  81. google/adk/tools/enterprise_search_tool.py +65 -0
  82. google/adk/tools/function_parameter_parse_util.py +2 -2
  83. google/adk/tools/google_api_tool/__init__.py +18 -70
  84. google/adk/tools/google_api_tool/google_api_tool.py +11 -5
  85. google/adk/tools/google_api_tool/google_api_toolset.py +126 -0
  86. google/adk/tools/google_api_tool/google_api_toolsets.py +102 -0
  87. google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +40 -42
  88. google/adk/tools/langchain_tool.py +96 -49
  89. google/adk/tools/load_memory_tool.py +14 -5
  90. google/adk/tools/mcp_tool/__init__.py +3 -2
  91. google/adk/tools/mcp_tool/mcp_session_manager.py +153 -16
  92. google/adk/tools/mcp_tool/mcp_session_manager.py.orig +322 -0
  93. google/adk/tools/mcp_tool/mcp_tool.py +12 -12
  94. google/adk/tools/mcp_tool/mcp_toolset.py +155 -195
  95. google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +32 -7
  96. google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +31 -31
  97. google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +1 -1
  98. google/adk/tools/preload_memory_tool.py +27 -18
  99. google/adk/tools/retrieval/__init__.py +1 -1
  100. google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +1 -1
  101. google/adk/tools/toolbox_toolset.py +79 -0
  102. google/adk/tools/transfer_to_agent_tool.py +0 -1
  103. google/adk/version.py +1 -1
  104. {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/METADATA +7 -5
  105. google_adk-1.0.0.dist-info/RECORD +195 -0
  106. google/adk/agents/remote_agent.py +0 -50
  107. google/adk/tools/google_api_tool/google_api_tool_set.py +0 -110
  108. google/adk/tools/google_api_tool/google_api_tool_sets.py +0 -112
  109. google/adk/tools/toolbox_tool.py +0 -46
  110. google_adk-0.5.0.dist-info/RECORD +0 -180
  111. {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/WHEEL +0 -0
  112. {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/entry_points.txt +0 -0
  113. {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import copy
16
+ import logging
16
17
  import time
17
18
  from typing import Any
18
19
  from typing import Optional
@@ -23,17 +24,19 @@ from typing_extensions import override
23
24
  from ..events.event import Event
24
25
  from .base_session_service import BaseSessionService
25
26
  from .base_session_service import GetSessionConfig
26
- from .base_session_service import ListEventsResponse
27
27
  from .base_session_service import ListSessionsResponse
28
28
  from .session import Session
29
29
  from .state import State
30
30
 
31
+ logger = logging.getLogger('google_adk.' + __name__)
32
+
31
33
 
32
34
  class InMemorySessionService(BaseSessionService):
33
35
  """An in-memory implementation of the session service."""
34
36
 
35
37
  def __init__(self):
36
- # A map from app name to a map from user ID to a map from session ID to session.
38
+ # A map from app name to a map from user ID to a map from session ID to
39
+ # session.
37
40
  self.sessions: dict[str, dict[str, dict[str, Session]]] = {}
38
41
  # A map from app name to a map from user ID to a map from key to the value.
39
42
  self.user_state: dict[str, dict[str, dict[str, Any]]] = {}
@@ -41,7 +44,38 @@ class InMemorySessionService(BaseSessionService):
41
44
  self.app_state: dict[str, dict[str, Any]] = {}
42
45
 
43
46
  @override
44
- def create_session(
47
+ async def create_session(
48
+ self,
49
+ *,
50
+ app_name: str,
51
+ user_id: str,
52
+ state: Optional[dict[str, Any]] = None,
53
+ session_id: Optional[str] = None,
54
+ ) -> Session:
55
+ return self._create_session_impl(
56
+ app_name=app_name,
57
+ user_id=user_id,
58
+ state=state,
59
+ session_id=session_id,
60
+ )
61
+
62
+ def create_session_sync(
63
+ self,
64
+ *,
65
+ app_name: str,
66
+ user_id: str,
67
+ state: Optional[dict[str, Any]] = None,
68
+ session_id: Optional[str] = None,
69
+ ) -> Session:
70
+ logger.warning('Deprecated. Please migrate to the async method.')
71
+ return self._create_session_impl(
72
+ app_name=app_name,
73
+ user_id=user_id,
74
+ state=state,
75
+ session_id=session_id,
76
+ )
77
+
78
+ def _create_session_impl(
45
79
  self,
46
80
  *,
47
81
  app_name: str,
@@ -72,14 +106,45 @@ class InMemorySessionService(BaseSessionService):
72
106
  return self._merge_state(app_name, user_id, copied_session)
73
107
 
74
108
  @override
75
- def get_session(
109
+ async def get_session(
76
110
  self,
77
111
  *,
78
112
  app_name: str,
79
113
  user_id: str,
80
114
  session_id: str,
81
115
  config: Optional[GetSessionConfig] = None,
82
- ) -> Session:
116
+ ) -> Optional[Session]:
117
+ return self._get_session_impl(
118
+ app_name=app_name,
119
+ user_id=user_id,
120
+ session_id=session_id,
121
+ config=config,
122
+ )
123
+
124
+ def get_session_sync(
125
+ self,
126
+ *,
127
+ app_name: str,
128
+ user_id: str,
129
+ session_id: str,
130
+ config: Optional[GetSessionConfig] = None,
131
+ ) -> Optional[Session]:
132
+ logger.warning('Deprecated. Please migrate to the async method.')
133
+ return self._get_session_impl(
134
+ app_name=app_name,
135
+ user_id=user_id,
136
+ session_id=session_id,
137
+ config=config,
138
+ )
139
+
140
+ def _get_session_impl(
141
+ self,
142
+ *,
143
+ app_name: str,
144
+ user_id: str,
145
+ session_id: str,
146
+ config: Optional[GetSessionConfig] = None,
147
+ ) -> Optional[Session]:
83
148
  if app_name not in self.sessions:
84
149
  return None
85
150
  if user_id not in self.sessions[app_name]:
@@ -102,11 +167,13 @@ class InMemorySessionService(BaseSessionService):
102
167
  break
103
168
  i -= 1
104
169
  if i >= 0:
105
- copied_session.events = copied_session.events[i + 1:]
170
+ copied_session.events = copied_session.events[i + 1 :]
106
171
 
107
172
  return self._merge_state(app_name, user_id, copied_session)
108
173
 
109
- def _merge_state(self, app_name: str, user_id: str, copied_session: Session):
174
+ def _merge_state(
175
+ self, app_name: str, user_id: str, copied_session: Session
176
+ ) -> Session:
110
177
  # Merge app state
111
178
  if app_name in self.app_state:
112
179
  for key in self.app_state[app_name].keys():
@@ -128,7 +195,18 @@ class InMemorySessionService(BaseSessionService):
128
195
  return copied_session
129
196
 
130
197
  @override
131
- def list_sessions(
198
+ async def list_sessions(
199
+ self, *, app_name: str, user_id: str
200
+ ) -> ListSessionsResponse:
201
+ return self._list_sessions_impl(app_name=app_name, user_id=user_id)
202
+
203
+ def list_sessions_sync(
204
+ self, *, app_name: str, user_id: str
205
+ ) -> ListSessionsResponse:
206
+ logger.warning('Deprecated. Please migrate to the async method.')
207
+ return self._list_sessions_impl(app_name=app_name, user_id=user_id)
208
+
209
+ def _list_sessions_impl(
132
210
  self, *, app_name: str, user_id: str
133
211
  ) -> ListSessionsResponse:
134
212
  empty_response = ListSessionsResponse()
@@ -145,12 +223,26 @@ class InMemorySessionService(BaseSessionService):
145
223
  sessions_without_events.append(copied_session)
146
224
  return ListSessionsResponse(sessions=sessions_without_events)
147
225
 
148
- @override
149
- def delete_session(
226
+ async def delete_session(
227
+ self, *, app_name: str, user_id: str, session_id: str
228
+ ) -> None:
229
+ self._delete_session_impl(
230
+ app_name=app_name, user_id=user_id, session_id=session_id
231
+ )
232
+
233
+ def delete_session_sync(
234
+ self, *, app_name: str, user_id: str, session_id: str
235
+ ) -> None:
236
+ logger.warning('Deprecated. Please migrate to the async method.')
237
+ self._delete_session_impl(
238
+ app_name=app_name, user_id=user_id, session_id=session_id
239
+ )
240
+
241
+ def _delete_session_impl(
150
242
  self, *, app_name: str, user_id: str, session_id: str
151
243
  ) -> None:
152
244
  if (
153
- self.get_session(
245
+ self._get_session_impl(
154
246
  app_name=app_name, user_id=user_id, session_id=session_id
155
247
  )
156
248
  is None
@@ -160,9 +252,9 @@ class InMemorySessionService(BaseSessionService):
160
252
  self.sessions[app_name][user_id].pop(session_id)
161
253
 
162
254
  @override
163
- def append_event(self, session: Session, event: Event) -> Event:
255
+ async def append_event(self, session: Session, event: Event) -> Event:
164
256
  # Update the in-memory session.
165
- super().append_event(session=session, event=event)
257
+ await super().append_event(session=session, event=event)
166
258
  session.last_update_time = event.timestamp
167
259
 
168
260
  # Update the storage session
@@ -189,18 +281,8 @@ class InMemorySessionService(BaseSessionService):
189
281
  ] = event.actions.state_delta[key]
190
282
 
191
283
  storage_session = self.sessions[app_name][user_id].get(session_id)
192
- super().append_event(session=storage_session, event=event)
284
+ await super().append_event(session=storage_session, event=event)
193
285
 
194
286
  storage_session.last_update_time = event.timestamp
195
287
 
196
288
  return event
197
-
198
- @override
199
- def list_events(
200
- self,
201
- *,
202
- app_name: str,
203
- user_id: str,
204
- session_id: str,
205
- ) -> ListEventsResponse:
206
- raise NotImplementedError()
@@ -14,6 +14,7 @@
14
14
 
15
15
  from typing import Any
16
16
 
17
+ from pydantic import alias_generators
17
18
  from pydantic import BaseModel
18
19
  from pydantic import ConfigDict
19
20
  from pydantic import Field
@@ -37,6 +38,8 @@ class Session(BaseModel):
37
38
  model_config = ConfigDict(
38
39
  extra='forbid',
39
40
  arbitrary_types_allowed=True,
41
+ alias_generator=alias_generators.to_camel,
42
+ populate_by_name=True,
40
43
  )
41
44
  """The pydantic model config."""
42
45
 
@@ -14,7 +14,8 @@
14
14
  import logging
15
15
  import re
16
16
  import time
17
- from typing import Any, Optional
17
+ from typing import Any
18
+ from typing import Optional
18
19
 
19
20
  from dateutil import parser
20
21
  from google import genai
@@ -25,13 +26,11 @@ from ..events.event_actions import EventActions
25
26
  from . import _session_util
26
27
  from .base_session_service import BaseSessionService
27
28
  from .base_session_service import GetSessionConfig
28
- from .base_session_service import ListEventsResponse
29
29
  from .base_session_service import ListSessionsResponse
30
30
  from .session import Session
31
31
 
32
-
33
32
  isoparse = parser.isoparse
34
- logger = logging.getLogger(__name__)
33
+ logger = logging.getLogger('google_adk.' + __name__)
35
34
 
36
35
 
37
36
  class VertexAiSessionService(BaseSessionService):
@@ -49,7 +48,7 @@ class VertexAiSessionService(BaseSessionService):
49
48
  self.api_client = client._api_client
50
49
 
51
50
  @override
52
- def create_session(
51
+ async def create_session(
53
52
  self,
54
53
  *,
55
54
  app_name: str,
@@ -57,13 +56,19 @@ class VertexAiSessionService(BaseSessionService):
57
56
  state: Optional[dict[str, Any]] = None,
58
57
  session_id: Optional[str] = None,
59
58
  ) -> Session:
59
+ if session_id:
60
+ raise ValueError(
61
+ 'User-provided Session id is not supported for'
62
+ ' VertexAISessionService.'
63
+ )
64
+
60
65
  reasoning_engine_id = _parse_reasoning_engine_id(app_name)
61
66
 
62
67
  session_json_dict = {'user_id': user_id}
63
68
  if state:
64
69
  session_json_dict['session_state'] = state
65
70
 
66
- api_response = self.api_client.request(
71
+ api_response = await self.api_client.async_request(
67
72
  http_method='POST',
68
73
  path=f'reasoningEngines/{reasoning_engine_id}/sessions',
69
74
  request_dict=session_json_dict,
@@ -75,7 +80,7 @@ class VertexAiSessionService(BaseSessionService):
75
80
 
76
81
  max_retry_attempt = 5
77
82
  while max_retry_attempt >= 0:
78
- lro_response = self.api_client.request(
83
+ lro_response = await self.api_client.async_request(
79
84
  http_method='GET',
80
85
  path=f'operations/{operation_id}',
81
86
  request_dict={},
@@ -88,7 +93,7 @@ class VertexAiSessionService(BaseSessionService):
88
93
  max_retry_attempt -= 1
89
94
 
90
95
  # Get session resource
91
- get_session_api_response = self.api_client.request(
96
+ get_session_api_response = await self.api_client.async_request(
92
97
  http_method='GET',
93
98
  path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
94
99
  request_dict={},
@@ -107,18 +112,18 @@ class VertexAiSessionService(BaseSessionService):
107
112
  return session
108
113
 
109
114
  @override
110
- def get_session(
115
+ async def get_session(
111
116
  self,
112
117
  *,
113
118
  app_name: str,
114
119
  user_id: str,
115
120
  session_id: str,
116
121
  config: Optional[GetSessionConfig] = None,
117
- ) -> Session:
122
+ ) -> Optional[Session]:
118
123
  reasoning_engine_id = _parse_reasoning_engine_id(app_name)
119
124
 
120
125
  # Get session resource
121
- get_session_api_response = self.api_client.request(
126
+ get_session_api_response = await self.api_client.async_request(
122
127
  http_method='GET',
123
128
  path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
124
129
  request_dict={},
@@ -136,7 +141,7 @@ class VertexAiSessionService(BaseSessionService):
136
141
  last_update_time=update_timestamp,
137
142
  )
138
143
 
139
- list_events_api_response = self.api_client.request(
144
+ list_events_api_response = await self.api_client.async_request(
140
145
  http_method='GET',
141
146
  path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
142
147
  request_dict={},
@@ -170,7 +175,7 @@ class VertexAiSessionService(BaseSessionService):
170
175
  return session
171
176
 
172
177
  @override
173
- def list_sessions(
178
+ async def list_sessions(
174
179
  self, *, app_name: str, user_id: str
175
180
  ) -> ListSessionsResponse:
176
181
  reasoning_engine_id = _parse_reasoning_engine_id(app_name)
@@ -197,50 +202,23 @@ class VertexAiSessionService(BaseSessionService):
197
202
  sessions.append(session)
198
203
  return ListSessionsResponse(sessions=sessions)
199
204
 
200
- def delete_session(
205
+ async def delete_session(
201
206
  self, *, app_name: str, user_id: str, session_id: str
202
207
  ) -> None:
203
208
  reasoning_engine_id = _parse_reasoning_engine_id(app_name)
204
- self.api_client.request(
209
+ await self.api_client.async_request(
205
210
  http_method='DELETE',
206
211
  path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}',
207
212
  request_dict={},
208
213
  )
209
214
 
210
215
  @override
211
- def list_events(
212
- self,
213
- *,
214
- app_name: str,
215
- user_id: str,
216
- session_id: str,
217
- ) -> ListEventsResponse:
218
- reasoning_engine_id = _parse_reasoning_engine_id(app_name)
219
- api_response = self.api_client.request(
220
- http_method='GET',
221
- path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session_id}/events',
222
- request_dict={},
223
- )
224
-
225
- logger.info(f'List events response {api_response}')
226
-
227
- # Handles empty response case
228
- if api_response.get('httpHeaders', None):
229
- return ListEventsResponse()
230
-
231
- session_events = api_response['sessionEvents']
232
-
233
- return ListEventsResponse(
234
- events=[_from_api_event(event) for event in session_events]
235
- )
236
-
237
- @override
238
- def append_event(self, session: Session, event: Event) -> Event:
216
+ async def append_event(self, session: Session, event: Event) -> Event:
239
217
  # Update the in-memory session.
240
- super().append_event(session=session, event=event)
218
+ await super().append_event(session=session, event=event)
241
219
 
242
220
  reasoning_engine_id = _parse_reasoning_engine_id(session.app_name)
243
- self.api_client.request(
221
+ await self.api_client.async_request(
244
222
  http_method='POST',
245
223
  path=f'reasoningEngines/{reasoning_engine_id}/sessions/{session.id}:appendEvent',
246
224
  request_dict=_convert_event_to_json(event),
google/adk/telemetry.py CHANGED
@@ -111,6 +111,9 @@ def trace_call_llm(
111
111
  span.set_attribute(
112
112
  'gcp.vertex.agent.invocation_id', invocation_context.invocation_id
113
113
  )
114
+ span.set_attribute(
115
+ 'gcp.vertex.agent.session_id', invocation_context.session.id
116
+ )
114
117
  span.set_attribute('gcp.vertex.agent.event_id', event_id)
115
118
  # Consider removing once GenAI SDK provides a way to record this info.
116
119
  span.set_attribute(
@@ -11,31 +11,28 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- # pylint: disable=g-bad-import-order
15
- from .base_tool import BaseTool
14
+
16
15
 
17
16
  from ..auth.auth_tool import AuthToolArguments
18
17
  from .apihub_tool.apihub_toolset import APIHubToolset
19
- from .built_in_code_execution_tool import built_in_code_execution
20
- from .google_search_tool import google_search
21
- from .vertex_ai_search_tool import VertexAiSearchTool
18
+ from .base_tool import BaseTool
22
19
  from .example_tool import ExampleTool
23
20
  from .exit_loop_tool import exit_loop
24
21
  from .function_tool import FunctionTool
25
22
  from .get_user_choice_tool import get_user_choice_tool as get_user_choice
23
+ from .google_search_tool import google_search
26
24
  from .load_artifacts_tool import load_artifacts_tool as load_artifacts
27
25
  from .load_memory_tool import load_memory_tool as load_memory
28
26
  from .long_running_tool import LongRunningFunctionTool
29
27
  from .preload_memory_tool import preload_memory_tool as preload_memory
30
28
  from .tool_context import ToolContext
31
29
  from .transfer_to_agent_tool import transfer_to_agent
32
-
30
+ from .vertex_ai_search_tool import VertexAiSearchTool
33
31
 
34
32
  __all__ = [
35
33
  'APIHubToolset',
36
34
  'AuthToolArguments',
37
35
  'BaseTool',
38
- 'built_in_code_execution',
39
36
  'google_search',
40
37
  'VertexAiSearchTool',
41
38
  'ExampleTool',
@@ -14,8 +14,10 @@
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import logging
17
18
  from typing import TYPE_CHECKING
18
19
 
20
+ from deprecated import deprecated
19
21
  from google.genai import types
20
22
  from typing_extensions import override
21
23
 
@@ -25,7 +27,12 @@ from .tool_context import ToolContext
25
27
  if TYPE_CHECKING:
26
28
  from ..models import LlmRequest
27
29
 
30
+ logger = logging.getLogger('google_adk.' + __name__)
28
31
 
32
+
33
+ @deprecated(
34
+ 'No longer supported. Please use the new BuiltInCodeExecutor instead.'
35
+ )
29
36
  class BuiltInCodeExecutionTool(BaseTool):
30
37
  """A built-in code execution tool that is automatically invoked by Gemini 2 models.
31
38
 
@@ -44,6 +51,10 @@ class BuiltInCodeExecutionTool(BaseTool):
44
51
  tool_context: ToolContext,
45
52
  llm_request: LlmRequest,
46
53
  ) -> None:
54
+ logger.warning(
55
+ 'BuiltInCodeExecutionTool is deprecated and will be removed in 1.1.0.'
56
+ ' Please use the new BuiltInCodeExecutor instead.'
57
+ )
47
58
  if llm_request.model and llm_request.model.startswith('gemini-2'):
48
59
  llm_request.config = llm_request.config or types.GenerateContentConfig()
49
60
  llm_request.config.tools = llm_request.config.tools or []
@@ -0,0 +1,30 @@
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
+
16
+ from __future__ import annotations
17
+
18
+ from typing import TYPE_CHECKING
19
+
20
+ if TYPE_CHECKING:
21
+ from ..memory.memory_entry import MemoryEntry
22
+
23
+
24
+ def extract_text(memory: MemoryEntry, splitter: str = ' ') -> str:
25
+ """Extracts the text from the memory entry."""
26
+ if not memory.content.parts:
27
+ return ''
28
+ return splitter.join(
29
+ [part.text for part in memory.content.parts if part.text]
30
+ )
@@ -129,7 +129,7 @@ class AgentTool(BaseTool):
129
129
  session_service=InMemorySessionService(),
130
130
  memory_service=InMemoryMemoryService(),
131
131
  )
132
- session = runner.session_service.create_session(
132
+ session = await runner.session_service.create_session(
133
133
  app_name=self.agent.name,
134
134
  user_id='tmp_user',
135
135
  state=tool_context.state.to_dict(),
@@ -162,17 +162,17 @@ class AgentTool(BaseTool):
162
162
  filename=artifact_name, artifact=artifact
163
163
  )
164
164
 
165
- if (
166
- not last_event
167
- or not last_event.content
168
- or not last_event.content.parts
169
- or not last_event.content.parts[0].text
170
- ):
165
+ if not last_event or not last_event.content or not last_event.content.parts:
171
166
  return ''
172
167
  if isinstance(self.agent, LlmAgent) and self.agent.output_schema:
168
+ merged_text = '\n'.join(
169
+ [p.text for p in last_event.content.parts if p.text]
170
+ )
173
171
  tool_result = self.agent.output_schema.model_validate_json(
174
- last_event.content.parts[0].text
172
+ merged_text
175
173
  ).model_dump(exclude_none=True)
176
174
  else:
177
- tool_result = last_event.content.parts[0].text
175
+ tool_result = '\n'.join(
176
+ [p.text for p in last_event.content.parts if p.text]
177
+ )
178
178
  return tool_result