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.
- google/adk/agents/base_agent.py +76 -30
- google/adk/agents/base_agent.py.orig +330 -0
- google/adk/agents/callback_context.py +0 -5
- google/adk/agents/llm_agent.py +122 -30
- google/adk/agents/loop_agent.py +1 -1
- google/adk/agents/parallel_agent.py +7 -0
- google/adk/agents/readonly_context.py +7 -1
- google/adk/agents/run_config.py +1 -1
- google/adk/agents/sequential_agent.py +31 -0
- google/adk/agents/transcription_entry.py +4 -2
- google/adk/artifacts/gcs_artifact_service.py +1 -1
- google/adk/artifacts/in_memory_artifact_service.py +1 -1
- google/adk/auth/auth_credential.py +6 -1
- google/adk/auth/auth_preprocessor.py +7 -1
- google/adk/auth/auth_tool.py +3 -4
- google/adk/cli/agent_graph.py +5 -5
- google/adk/cli/browser/index.html +2 -2
- google/adk/cli/browser/{main-ULN5R5I5.js → main-QOEMUXM4.js} +44 -45
- google/adk/cli/cli.py +7 -7
- google/adk/cli/cli_deploy.py +7 -2
- google/adk/cli/cli_eval.py +172 -99
- google/adk/cli/cli_tools_click.py +147 -64
- google/adk/cli/fast_api.py +330 -148
- google/adk/cli/fast_api.py.orig +174 -80
- google/adk/cli/utils/common.py +23 -0
- google/adk/cli/utils/evals.py +83 -1
- google/adk/cli/utils/logs.py +13 -5
- google/adk/code_executors/__init__.py +3 -1
- google/adk/code_executors/built_in_code_executor.py +52 -0
- google/adk/evaluation/__init__.py +1 -1
- google/adk/evaluation/agent_evaluator.py +168 -128
- google/adk/evaluation/eval_case.py +102 -0
- google/adk/evaluation/eval_set.py +37 -0
- google/adk/evaluation/eval_sets_manager.py +42 -0
- google/adk/evaluation/evaluation_generator.py +88 -113
- google/adk/evaluation/evaluator.py +56 -0
- google/adk/evaluation/local_eval_sets_manager.py +264 -0
- google/adk/evaluation/response_evaluator.py +106 -2
- google/adk/evaluation/trajectory_evaluator.py +83 -2
- google/adk/events/event.py +6 -1
- google/adk/events/event_actions.py +6 -1
- google/adk/examples/example_util.py +3 -2
- google/adk/flows/llm_flows/_code_execution.py +9 -1
- google/adk/flows/llm_flows/audio_transcriber.py +4 -3
- google/adk/flows/llm_flows/base_llm_flow.py +54 -15
- google/adk/flows/llm_flows/functions.py +9 -8
- google/adk/flows/llm_flows/instructions.py +13 -5
- google/adk/flows/llm_flows/single_flow.py +1 -1
- google/adk/memory/__init__.py +1 -1
- google/adk/memory/_utils.py +23 -0
- google/adk/memory/base_memory_service.py +23 -21
- google/adk/memory/base_memory_service.py.orig +76 -0
- google/adk/memory/in_memory_memory_service.py +57 -25
- google/adk/memory/memory_entry.py +37 -0
- google/adk/memory/vertex_ai_rag_memory_service.py +38 -15
- google/adk/models/anthropic_llm.py +16 -9
- google/adk/models/gemini_llm_connection.py +11 -11
- google/adk/models/google_llm.py +9 -2
- google/adk/models/google_llm.py.orig +305 -0
- google/adk/models/lite_llm.py +77 -21
- google/adk/models/llm_response.py +14 -2
- google/adk/models/registry.py +1 -1
- google/adk/runners.py +65 -41
- google/adk/sessions/__init__.py +1 -1
- google/adk/sessions/base_session_service.py +6 -33
- google/adk/sessions/database_session_service.py +58 -65
- google/adk/sessions/in_memory_session_service.py +106 -24
- google/adk/sessions/session.py +3 -0
- google/adk/sessions/vertex_ai_session_service.py +23 -45
- google/adk/telemetry.py +3 -0
- google/adk/tools/__init__.py +4 -7
- google/adk/tools/{built_in_code_execution_tool.py → _built_in_code_execution_tool.py} +11 -0
- google/adk/tools/_memory_entry_utils.py +30 -0
- google/adk/tools/agent_tool.py +9 -9
- google/adk/tools/apihub_tool/apihub_toolset.py +55 -74
- google/adk/tools/application_integration_tool/application_integration_toolset.py +107 -85
- google/adk/tools/application_integration_tool/clients/connections_client.py +20 -0
- google/adk/tools/application_integration_tool/clients/integration_client.py +6 -6
- google/adk/tools/application_integration_tool/integration_connector_tool.py +69 -26
- google/adk/tools/base_toolset.py +58 -0
- google/adk/tools/enterprise_search_tool.py +65 -0
- google/adk/tools/function_parameter_parse_util.py +2 -2
- google/adk/tools/google_api_tool/__init__.py +18 -70
- google/adk/tools/google_api_tool/google_api_tool.py +11 -5
- google/adk/tools/google_api_tool/google_api_toolset.py +126 -0
- google/adk/tools/google_api_tool/google_api_toolsets.py +102 -0
- google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +40 -42
- google/adk/tools/langchain_tool.py +96 -49
- google/adk/tools/load_memory_tool.py +14 -5
- google/adk/tools/mcp_tool/__init__.py +3 -2
- google/adk/tools/mcp_tool/mcp_session_manager.py +153 -16
- google/adk/tools/mcp_tool/mcp_session_manager.py.orig +322 -0
- google/adk/tools/mcp_tool/mcp_tool.py +12 -12
- google/adk/tools/mcp_tool/mcp_toolset.py +155 -195
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +32 -7
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +31 -31
- google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +1 -1
- google/adk/tools/preload_memory_tool.py +27 -18
- google/adk/tools/retrieval/__init__.py +1 -1
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +1 -1
- google/adk/tools/toolbox_toolset.py +79 -0
- google/adk/tools/transfer_to_agent_tool.py +0 -1
- google/adk/version.py +1 -1
- {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/METADATA +7 -5
- google_adk-1.0.0.dist-info/RECORD +195 -0
- google/adk/agents/remote_agent.py +0 -50
- google/adk/tools/google_api_tool/google_api_tool_set.py +0 -110
- google/adk/tools/google_api_tool/google_api_tool_sets.py +0 -112
- google/adk/tools/toolbox_tool.py +0 -46
- google_adk-0.5.0.dist-info/RECORD +0 -180
- {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/WHEEL +0 -0
- {google_adk-0.5.0.dist-info → google_adk-1.0.0.dist-info}/entry_points.txt +0 -0
- {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
|
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(
|
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
|
-
|
149
|
-
|
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.
|
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()
|
google/adk/sessions/session.py
CHANGED
@@ -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
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
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.
|
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(
|
google/adk/tools/__init__.py
CHANGED
@@ -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
|
-
|
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 .
|
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
|
+
)
|
google/adk/tools/agent_tool.py
CHANGED
@@ -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
|
-
|
172
|
+
merged_text
|
175
173
|
).model_dump(exclude_none=True)
|
176
174
|
else:
|
177
|
-
tool_result =
|
175
|
+
tool_result = '\n'.join(
|
176
|
+
[p.text for p in last_event.content.parts if p.text]
|
177
|
+
)
|
178
178
|
return tool_result
|