google-adk 0.4.0__py3-none-any.whl → 0.5.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/active_streaming_tool.py +1 -0
- google/adk/agents/base_agent.py +27 -29
- google/adk/agents/callback_context.py +4 -4
- google/adk/agents/invocation_context.py +1 -0
- google/adk/agents/langgraph_agent.py +1 -0
- google/adk/agents/live_request_queue.py +1 -0
- google/adk/agents/llm_agent.py +51 -6
- google/adk/agents/run_config.py +4 -0
- google/adk/agents/transcription_entry.py +1 -0
- google/adk/artifacts/base_artifact_service.py +5 -10
- google/adk/artifacts/gcs_artifact_service.py +8 -8
- google/adk/artifacts/in_memory_artifact_service.py +5 -5
- google/adk/auth/auth_credential.py +4 -5
- google/adk/cli/browser/index.html +1 -1
- google/adk/cli/browser/{main-HWIBUY2R.js → main-ULN5R5I5.js} +40 -39
- google/adk/cli/cli_eval.py +13 -11
- google/adk/cli/cli_tools_click.py +8 -6
- google/adk/cli/fast_api.py +11 -11
- google/adk/cli/fast_api.py.orig +728 -0
- google/adk/evaluation/agent_evaluator.py +3 -3
- google/adk/evaluation/evaluation_constants.py +1 -0
- google/adk/evaluation/evaluation_generator.py +5 -5
- google/adk/evaluation/response_evaluator.py +1 -1
- google/adk/events/event.py +1 -0
- google/adk/events/event_actions.py +1 -0
- google/adk/examples/example.py +1 -0
- google/adk/flows/__init__.py +0 -1
- google/adk/flows/llm_flows/_code_execution.py +10 -10
- google/adk/flows/llm_flows/base_llm_flow.py +40 -15
- google/adk/flows/llm_flows/basic.py +3 -0
- google/adk/flows/llm_flows/functions.py +1 -1
- google/adk/flows/llm_flows/instructions.py +17 -6
- google/adk/memory/base_memory_service.py +4 -2
- google/adk/memory/in_memory_memory_service.py +2 -2
- google/adk/memory/vertex_ai_rag_memory_service.py +2 -2
- google/adk/models/anthropic_llm.py +20 -2
- google/adk/models/base_llm.py +45 -4
- google/adk/models/gemini_llm_connection.py +14 -1
- google/adk/models/google_llm.py +0 -42
- google/adk/models/lite_llm.py +17 -17
- google/adk/models/llm_request.py +1 -1
- google/adk/models/llm_response.py +1 -1
- google/adk/runners.py +5 -5
- google/adk/sessions/_session_util.py +14 -0
- google/adk/sessions/base_session_service.py +3 -0
- google/adk/sessions/database_session_service.py +7 -3
- google/adk/sessions/in_memory_session_service.py +3 -3
- google/adk/sessions/session.py +1 -0
- google/adk/tools/agent_tool.py +7 -4
- google/adk/tools/application_integration_tool/clients/connections_client.py +9 -25
- google/adk/tools/load_artifacts_tool.py +4 -4
- google/adk/tools/load_memory_tool.py +4 -2
- google/adk/tools/mcp_tool/conversion_utils.py +1 -1
- google/adk/tools/mcp_tool/mcp_session_manager.py +14 -0
- google/adk/tools/openapi_tool/common/common.py +2 -5
- google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +13 -3
- google/adk/tools/preload_memory_tool.py +1 -1
- google/adk/tools/tool_context.py +4 -4
- google/adk/version.py +1 -1
- {google_adk-0.4.0.dist-info → google_adk-0.5.0.dist-info}/METADATA +2 -2
- {google_adk-0.4.0.dist-info → google_adk-0.5.0.dist-info}/RECORD +64 -63
- {google_adk-0.4.0.dist-info → google_adk-0.5.0.dist-info}/WHEEL +0 -0
- {google_adk-0.4.0.dist-info → google_adk-0.5.0.dist-info}/entry_points.txt +0 -0
- {google_adk-0.4.0.dist-info → google_adk-0.5.0.dist-info}/licenses/LICENSE +0 -0
google/adk/models/google_llm.py
CHANGED
@@ -210,48 +210,6 @@ class Gemini(BaseLlm):
|
|
210
210
|
) as live_session:
|
211
211
|
yield GeminiLlmConnection(live_session)
|
212
212
|
|
213
|
-
def _maybe_append_user_content(self, llm_request: LlmRequest):
|
214
|
-
"""Appends a user content, so that model can continue to output.
|
215
|
-
|
216
|
-
Args:
|
217
|
-
llm_request: LlmRequest, the request to send to the Gemini model.
|
218
|
-
"""
|
219
|
-
# If no content is provided, append a user content to hint model response
|
220
|
-
# using system instruction.
|
221
|
-
if not llm_request.contents:
|
222
|
-
llm_request.contents.append(
|
223
|
-
types.Content(
|
224
|
-
role='user',
|
225
|
-
parts=[
|
226
|
-
types.Part(
|
227
|
-
text=(
|
228
|
-
'Handle the requests as specified in the System'
|
229
|
-
' Instruction.'
|
230
|
-
)
|
231
|
-
)
|
232
|
-
],
|
233
|
-
)
|
234
|
-
)
|
235
|
-
return
|
236
|
-
|
237
|
-
# Insert a user content to preserve user intent and to avoid empty
|
238
|
-
# model response.
|
239
|
-
if llm_request.contents[-1].role != 'user':
|
240
|
-
llm_request.contents.append(
|
241
|
-
types.Content(
|
242
|
-
role='user',
|
243
|
-
parts=[
|
244
|
-
types.Part(
|
245
|
-
text=(
|
246
|
-
'Continue processing previous requests as instructed.'
|
247
|
-
' Exit or provide a summary if no more outputs are'
|
248
|
-
' needed.'
|
249
|
-
)
|
250
|
-
)
|
251
|
-
],
|
252
|
-
)
|
253
|
-
)
|
254
|
-
|
255
213
|
|
256
214
|
def _build_function_declaration_log(
|
257
215
|
func_decl: types.FunctionDeclaration,
|
google/adk/models/lite_llm.py
CHANGED
@@ -172,19 +172,19 @@ def _content_to_message_param(
|
|
172
172
|
tool_calls = []
|
173
173
|
content_present = False
|
174
174
|
for part in content.parts:
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
)
|
175
|
+
if part.function_call:
|
176
|
+
tool_calls.append(
|
177
|
+
ChatCompletionMessageToolCall(
|
178
|
+
type="function",
|
179
|
+
id=part.function_call.id,
|
180
|
+
function=Function(
|
181
|
+
name=part.function_call.name,
|
182
|
+
arguments=part.function_call.args,
|
183
|
+
),
|
185
184
|
)
|
186
|
-
|
187
|
-
|
185
|
+
)
|
186
|
+
elif part.text or part.inline_data:
|
187
|
+
content_present = True
|
188
188
|
|
189
189
|
final_content = message_content if content_present else None
|
190
190
|
|
@@ -453,9 +453,9 @@ def _get_completion_inputs(
|
|
453
453
|
for content in llm_request.contents or []:
|
454
454
|
message_param_or_list = _content_to_message_param(content)
|
455
455
|
if isinstance(message_param_or_list, list):
|
456
|
-
|
457
|
-
elif message_param_or_list:
|
458
|
-
|
456
|
+
messages.extend(message_param_or_list)
|
457
|
+
elif message_param_or_list: # Ensure it's not None before appending
|
458
|
+
messages.append(message_param_or_list)
|
459
459
|
|
460
460
|
if llm_request.config.system_instruction:
|
461
461
|
messages.insert(
|
@@ -573,7 +573,6 @@ class LiteLlm(BaseLlm):
|
|
573
573
|
Attributes:
|
574
574
|
model: The name of the LiteLlm model.
|
575
575
|
llm_client: The LLM client to use for the model.
|
576
|
-
model_config: The model config.
|
577
576
|
"""
|
578
577
|
|
579
578
|
llm_client: LiteLLMClient = Field(default_factory=LiteLLMClient)
|
@@ -611,7 +610,8 @@ class LiteLlm(BaseLlm):
|
|
611
610
|
LlmResponse: The model response.
|
612
611
|
"""
|
613
612
|
|
614
|
-
|
613
|
+
self._maybe_append_user_content(llm_request)
|
614
|
+
logger.debug(_build_request_log(llm_request))
|
615
615
|
|
616
616
|
messages, tools = _get_completion_inputs(llm_request)
|
617
617
|
|
google/adk/models/llm_request.py
CHANGED
google/adk/runners.py
CHANGED
@@ -186,7 +186,7 @@ class Runner:
|
|
186
186
|
root_agent = self.agent
|
187
187
|
|
188
188
|
if new_message:
|
189
|
-
self._append_new_message_to_session(
|
189
|
+
await self._append_new_message_to_session(
|
190
190
|
session,
|
191
191
|
new_message,
|
192
192
|
invocation_context,
|
@@ -199,7 +199,7 @@ class Runner:
|
|
199
199
|
self.session_service.append_event(session=session, event=event)
|
200
200
|
yield event
|
201
201
|
|
202
|
-
def _append_new_message_to_session(
|
202
|
+
async def _append_new_message_to_session(
|
203
203
|
self,
|
204
204
|
session: Session,
|
205
205
|
new_message: types.Content,
|
@@ -225,7 +225,7 @@ class Runner:
|
|
225
225
|
if part.inline_data is None:
|
226
226
|
continue
|
227
227
|
file_name = f'artifact_{invocation_context.invocation_id}_{i}'
|
228
|
-
self.artifact_service.save_artifact(
|
228
|
+
await self.artifact_service.save_artifact(
|
229
229
|
app_name=self.app_name,
|
230
230
|
user_id=session.user_id,
|
231
231
|
session_id=session.id,
|
@@ -297,14 +297,14 @@ class Runner:
|
|
297
297
|
self.session_service.append_event(session=session, event=event)
|
298
298
|
yield event
|
299
299
|
|
300
|
-
def close_session(self, session: Session):
|
300
|
+
async def close_session(self, session: Session):
|
301
301
|
"""Closes a session and adds it to the memory service (experimental feature).
|
302
302
|
|
303
303
|
Args:
|
304
304
|
session: The session to close.
|
305
305
|
"""
|
306
306
|
if self.memory_service:
|
307
|
-
self.memory_service.add_session_to_memory(session)
|
307
|
+
await self.memory_service.add_session_to_memory(session)
|
308
308
|
self.session_service.close_session(session=session)
|
309
309
|
|
310
310
|
def _find_agent_to_run(
|
@@ -1,3 +1,17 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
1
15
|
"""Utility functions for session service."""
|
2
16
|
|
3
17
|
import base64
|
@@ -26,6 +26,7 @@ from .state import State
|
|
26
26
|
|
27
27
|
class GetSessionConfig(BaseModel):
|
28
28
|
"""The configuration of getting a session."""
|
29
|
+
|
29
30
|
num_recent_events: Optional[int] = None
|
30
31
|
after_timestamp: Optional[float] = None
|
31
32
|
|
@@ -35,11 +36,13 @@ class ListSessionsResponse(BaseModel):
|
|
35
36
|
|
36
37
|
The events and states are not set within each Session object.
|
37
38
|
"""
|
39
|
+
|
38
40
|
sessions: list[Session] = Field(default_factory=list)
|
39
41
|
|
40
42
|
|
41
43
|
class ListEventsResponse(BaseModel):
|
42
44
|
"""The response of listing events in a session."""
|
45
|
+
|
43
46
|
events: list[Event] = Field(default_factory=list)
|
44
47
|
next_page_token: Optional[str] = None
|
45
48
|
|
@@ -219,6 +219,7 @@ class StorageAppState(Base):
|
|
219
219
|
DateTime(), default=func.now(), onupdate=func.now()
|
220
220
|
)
|
221
221
|
|
222
|
+
|
222
223
|
class StorageUserState(Base):
|
223
224
|
"""Represents a user state stored in the database."""
|
224
225
|
|
@@ -483,9 +484,11 @@ class DatabaseSessionService(BaseSessionService):
|
|
483
484
|
|
484
485
|
if storage_session.update_time.timestamp() > session.last_update_time:
|
485
486
|
raise ValueError(
|
486
|
-
|
487
|
-
|
488
|
-
|
487
|
+
f"Session last_update_time "
|
488
|
+
f"{datetime.fromtimestamp(session.last_update_time):%Y-%m-%d %H:%M:%S} "
|
489
|
+
f"is later than the update_time in storage "
|
490
|
+
f"{storage_session.update_time:%Y-%m-%d %H:%M:%S}"
|
491
|
+
)
|
489
492
|
|
490
493
|
# Fetch states from storage
|
491
494
|
storage_app_state = sessionFactory.get(
|
@@ -562,6 +565,7 @@ class DatabaseSessionService(BaseSessionService):
|
|
562
565
|
) -> ListEventsResponse:
|
563
566
|
raise NotImplementedError()
|
564
567
|
|
568
|
+
|
565
569
|
def convert_event(event: StorageEvent) -> Event:
|
566
570
|
"""Converts a storage event to an event."""
|
567
571
|
return Event(
|
@@ -95,14 +95,14 @@ class InMemorySessionService(BaseSessionService):
|
|
95
95
|
copied_session.events = copied_session.events[
|
96
96
|
-config.num_recent_events :
|
97
97
|
]
|
98
|
-
|
99
|
-
i = len(
|
98
|
+
if config.after_timestamp:
|
99
|
+
i = len(copied_session.events) - 1
|
100
100
|
while i >= 0:
|
101
101
|
if copied_session.events[i].timestamp < config.after_timestamp:
|
102
102
|
break
|
103
103
|
i -= 1
|
104
104
|
if i >= 0:
|
105
|
-
copied_session.events = copied_session.events[i:]
|
105
|
+
copied_session.events = copied_session.events[i + 1:]
|
106
106
|
|
107
107
|
return self._merge_state(app_name, user_id, copied_session)
|
108
108
|
|
google/adk/sessions/session.py
CHANGED
google/adk/tools/agent_tool.py
CHANGED
@@ -146,18 +146,21 @@ class AgentTool(BaseTool):
|
|
146
146
|
|
147
147
|
if runner.artifact_service:
|
148
148
|
# Forward all artifacts to parent session.
|
149
|
-
|
149
|
+
artifact_names = await runner.artifact_service.list_artifact_keys(
|
150
150
|
app_name=session.app_name,
|
151
151
|
user_id=session.user_id,
|
152
152
|
session_id=session.id,
|
153
|
-
)
|
154
|
-
|
153
|
+
)
|
154
|
+
for artifact_name in artifact_names:
|
155
|
+
if artifact := await runner.artifact_service.load_artifact(
|
155
156
|
app_name=session.app_name,
|
156
157
|
user_id=session.user_id,
|
157
158
|
session_id=session.id,
|
158
159
|
filename=artifact_name,
|
159
160
|
):
|
160
|
-
tool_context.save_artifact(
|
161
|
+
await tool_context.save_artifact(
|
162
|
+
filename=artifact_name, artifact=artifact
|
163
|
+
)
|
161
164
|
|
162
165
|
if (
|
163
166
|
not last_event
|
@@ -312,9 +312,7 @@ class ConnectionsClient:
|
|
312
312
|
"content": {
|
313
313
|
"application/json": {
|
314
314
|
"schema": {
|
315
|
-
"$ref":
|
316
|
-
f"#/components/schemas/{action_display_name}_Request"
|
317
|
-
)
|
315
|
+
"$ref": f"#/components/schemas/{action_display_name}_Request"
|
318
316
|
}
|
319
317
|
}
|
320
318
|
}
|
@@ -325,9 +323,7 @@ class ConnectionsClient:
|
|
325
323
|
"content": {
|
326
324
|
"application/json": {
|
327
325
|
"schema": {
|
328
|
-
"$ref":
|
329
|
-
f"#/components/schemas/{action_display_name}_Response"
|
330
|
-
),
|
326
|
+
"$ref": f"#/components/schemas/{action_display_name}_Response",
|
331
327
|
}
|
332
328
|
}
|
333
329
|
},
|
@@ -346,11 +342,9 @@ class ConnectionsClient:
|
|
346
342
|
return {
|
347
343
|
"post": {
|
348
344
|
"summary": f"List {entity}",
|
349
|
-
"description":
|
350
|
-
f"""Returns the list of {entity} data. If the page token was available in the response, let users know there are more records available. Ask if the user wants to fetch the next page of results. When passing filter use the
|
345
|
+
"description": f"""Returns the list of {entity} data. If the page token was available in the response, let users know there are more records available. Ask if the user wants to fetch the next page of results. When passing filter use the
|
351
346
|
following format: `field_name1='value1' AND field_name2='value2'
|
352
|
-
`. {tool_instructions}"""
|
353
|
-
),
|
347
|
+
`. {tool_instructions}""",
|
354
348
|
"x-operation": "LIST_ENTITIES",
|
355
349
|
"x-entity": f"{entity}",
|
356
350
|
"operationId": f"{tool_name}_list_{entity}",
|
@@ -375,9 +369,7 @@ class ConnectionsClient:
|
|
375
369
|
f"Returns a list of {entity} of json"
|
376
370
|
f" schema: {schema_as_string}"
|
377
371
|
),
|
378
|
-
"$ref":
|
379
|
-
"#/components/schemas/execute-connector_Response"
|
380
|
-
),
|
372
|
+
"$ref": "#/components/schemas/execute-connector_Response",
|
381
373
|
}
|
382
374
|
}
|
383
375
|
},
|
@@ -421,9 +413,7 @@ class ConnectionsClient:
|
|
421
413
|
f"Returns {entity} of json schema:"
|
422
414
|
f" {schema_as_string}"
|
423
415
|
),
|
424
|
-
"$ref":
|
425
|
-
"#/components/schemas/execute-connector_Response"
|
426
|
-
),
|
416
|
+
"$ref": "#/components/schemas/execute-connector_Response",
|
427
417
|
}
|
428
418
|
}
|
429
419
|
},
|
@@ -460,9 +450,7 @@ class ConnectionsClient:
|
|
460
450
|
"content": {
|
461
451
|
"application/json": {
|
462
452
|
"schema": {
|
463
|
-
"$ref":
|
464
|
-
"#/components/schemas/execute-connector_Response"
|
465
|
-
)
|
453
|
+
"$ref": "#/components/schemas/execute-connector_Response"
|
466
454
|
}
|
467
455
|
}
|
468
456
|
},
|
@@ -499,9 +487,7 @@ class ConnectionsClient:
|
|
499
487
|
"content": {
|
500
488
|
"application/json": {
|
501
489
|
"schema": {
|
502
|
-
"$ref":
|
503
|
-
"#/components/schemas/execute-connector_Response"
|
504
|
-
)
|
490
|
+
"$ref": "#/components/schemas/execute-connector_Response"
|
505
491
|
}
|
506
492
|
}
|
507
493
|
},
|
@@ -538,9 +524,7 @@ class ConnectionsClient:
|
|
538
524
|
"content": {
|
539
525
|
"application/json": {
|
540
526
|
"schema": {
|
541
|
-
"$ref":
|
542
|
-
"#/components/schemas/execute-connector_Response"
|
543
|
-
)
|
527
|
+
"$ref": "#/components/schemas/execute-connector_Response"
|
544
528
|
}
|
545
529
|
}
|
546
530
|
},
|
@@ -69,14 +69,14 @@ class LoadArtifactsTool(BaseTool):
|
|
69
69
|
tool_context=tool_context,
|
70
70
|
llm_request=llm_request,
|
71
71
|
)
|
72
|
-
self._append_artifacts_to_llm_request(
|
72
|
+
await self._append_artifacts_to_llm_request(
|
73
73
|
tool_context=tool_context, llm_request=llm_request
|
74
74
|
)
|
75
75
|
|
76
|
-
def _append_artifacts_to_llm_request(
|
76
|
+
async def _append_artifacts_to_llm_request(
|
77
77
|
self, *, tool_context: ToolContext, llm_request: LlmRequest
|
78
78
|
):
|
79
|
-
artifact_names = tool_context.list_artifacts()
|
79
|
+
artifact_names = await tool_context.list_artifacts()
|
80
80
|
if not artifact_names:
|
81
81
|
return
|
82
82
|
|
@@ -96,7 +96,7 @@ class LoadArtifactsTool(BaseTool):
|
|
96
96
|
if function_response and function_response.name == 'load_artifacts':
|
97
97
|
artifact_names = function_response.response['artifact_names']
|
98
98
|
for artifact_name in artifact_names:
|
99
|
-
artifact = tool_context.load_artifact(artifact_name)
|
99
|
+
artifact = await tool_context.load_artifact(artifact_name)
|
100
100
|
llm_request.contents.append(
|
101
101
|
types.Content(
|
102
102
|
role='user',
|
@@ -27,7 +27,9 @@ if TYPE_CHECKING:
|
|
27
27
|
from ..models import LlmRequest
|
28
28
|
|
29
29
|
|
30
|
-
def load_memory(
|
30
|
+
async def load_memory(
|
31
|
+
query: str, tool_context: ToolContext
|
32
|
+
) -> 'list[MemoryResult]':
|
31
33
|
"""Loads the memory for the current user.
|
32
34
|
|
33
35
|
Args:
|
@@ -36,7 +38,7 @@ def load_memory(query: str, tool_context: ToolContext) -> 'list[MemoryResult]':
|
|
36
38
|
Returns:
|
37
39
|
A list of memory results.
|
38
40
|
"""
|
39
|
-
response = tool_context.search_memory(query)
|
41
|
+
response = await tool_context.search_memory(query)
|
40
42
|
return response.memories
|
41
43
|
|
42
44
|
|
@@ -22,7 +22,7 @@ def adk_to_mcp_tool_type(tool: BaseTool) -> mcp_types.Tool:
|
|
22
22
|
"""Convert a Tool in ADK into MCP tool type.
|
23
23
|
|
24
24
|
This function transforms an ADK tool definition into its equivalent
|
25
|
-
representation in the MCP (Model
|
25
|
+
representation in the MCP (Model Context Protocol) system.
|
26
26
|
|
27
27
|
Args:
|
28
28
|
tool: The ADK tool to convert. It should be an instance of a class derived
|
@@ -1,3 +1,17 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
1
15
|
from contextlib import AsyncExitStack
|
2
16
|
import functools
|
3
17
|
import sys
|
@@ -14,11 +14,7 @@
|
|
14
14
|
|
15
15
|
import keyword
|
16
16
|
import re
|
17
|
-
from typing import Any
|
18
|
-
from typing import Dict
|
19
|
-
from typing import List
|
20
|
-
from typing import Optional
|
21
|
-
from typing import Union
|
17
|
+
from typing import Any, Dict, List, Optional, Union
|
22
18
|
|
23
19
|
from fastapi.openapi.models import Response
|
24
20
|
from fastapi.openapi.models import Schema
|
@@ -100,6 +96,7 @@ class ApiParameter(BaseModel):
|
|
100
96
|
py_name: Optional[str] = ''
|
101
97
|
type_value: type[Any] = Field(default=None, init_var=False)
|
102
98
|
type_hint: str = Field(default=None, init_var=False)
|
99
|
+
required: bool = False
|
103
100
|
|
104
101
|
def model_post_init(self, _: Any):
|
105
102
|
self.py_name = (
|
@@ -17,9 +17,13 @@ from textwrap import dedent
|
|
17
17
|
from typing import Any, Dict, List, Optional, Union
|
18
18
|
|
19
19
|
from fastapi.encoders import jsonable_encoder
|
20
|
-
from fastapi.openapi.models import Operation
|
20
|
+
from fastapi.openapi.models import Operation
|
21
|
+
from fastapi.openapi.models import Parameter
|
22
|
+
from fastapi.openapi.models import Schema
|
21
23
|
|
22
|
-
from ..common.common import ApiParameter
|
24
|
+
from ..common.common import ApiParameter
|
25
|
+
from ..common.common import PydocHelper
|
26
|
+
from ..common.common import to_snake_case
|
23
27
|
|
24
28
|
|
25
29
|
class OperationParser:
|
@@ -76,6 +80,11 @@ class OperationParser:
|
|
76
80
|
description = param.description or ''
|
77
81
|
location = param.in_ or ''
|
78
82
|
schema = param.schema_ or {} # Use schema_ instead of .schema
|
83
|
+
schema.description = (
|
84
|
+
description if not schema.description else schema.description
|
85
|
+
)
|
86
|
+
# param.required can be None
|
87
|
+
required = param.required if param.required is not None else False
|
79
88
|
|
80
89
|
self.params.append(
|
81
90
|
ApiParameter(
|
@@ -83,6 +92,7 @@ class OperationParser:
|
|
83
92
|
param_location=location,
|
84
93
|
param_schema=schema,
|
85
94
|
description=description,
|
95
|
+
required=required,
|
86
96
|
)
|
87
97
|
)
|
88
98
|
|
@@ -230,7 +240,7 @@ class OperationParser:
|
|
230
240
|
}
|
231
241
|
return {
|
232
242
|
'properties': properties,
|
233
|
-
'required': [p.py_name for p in self.params],
|
243
|
+
'required': [p.py_name for p in self.params if p.required],
|
234
244
|
'title': f"{self.operation.operationId or 'unnamed'}_Arguments",
|
235
245
|
'type': 'object',
|
236
246
|
}
|
@@ -45,7 +45,7 @@ class PreloadMemoryTool(BaseTool):
|
|
45
45
|
if not parts or not parts[0].text:
|
46
46
|
return
|
47
47
|
query = parts[0].text
|
48
|
-
response = tool_context.search_memory(query)
|
48
|
+
response = await tool_context.search_memory(query)
|
49
49
|
if not response.memories:
|
50
50
|
return
|
51
51
|
memory_text = ''
|
google/adk/tools/tool_context.py
CHANGED
@@ -69,21 +69,21 @@ class ToolContext(CallbackContext):
|
|
69
69
|
def get_auth_response(self, auth_config: AuthConfig) -> AuthCredential:
|
70
70
|
return AuthHandler(auth_config).get_auth_response(self.state)
|
71
71
|
|
72
|
-
def list_artifacts(self) -> list[str]:
|
72
|
+
async def list_artifacts(self) -> list[str]:
|
73
73
|
"""Lists the filenames of the artifacts attached to the current session."""
|
74
74
|
if self._invocation_context.artifact_service is None:
|
75
75
|
raise ValueError('Artifact service is not initialized.')
|
76
|
-
return self._invocation_context.artifact_service.list_artifact_keys(
|
76
|
+
return await self._invocation_context.artifact_service.list_artifact_keys(
|
77
77
|
app_name=self._invocation_context.app_name,
|
78
78
|
user_id=self._invocation_context.user_id,
|
79
79
|
session_id=self._invocation_context.session.id,
|
80
80
|
)
|
81
81
|
|
82
|
-
def search_memory(self, query: str) ->
|
82
|
+
async def search_memory(self, query: str) -> SearchMemoryResponse:
|
83
83
|
"""Searches the memory of the current user."""
|
84
84
|
if self._invocation_context.memory_service is None:
|
85
85
|
raise ValueError('Memory service is not available.')
|
86
|
-
return self._invocation_context.memory_service.search_memory(
|
86
|
+
return await self._invocation_context.memory_service.search_memory(
|
87
87
|
app_name=self._invocation_context.app_name,
|
88
88
|
user_id=self._invocation_context.user_id,
|
89
89
|
query=query,
|
google/adk/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: google-adk
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.5.0
|
4
4
|
Summary: Agent Development Kit
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
6
6
|
Requires-Python: >=3.9
|
@@ -27,7 +27,7 @@ Requires-Dist: google-cloud-aiplatform>=1.87.0
|
|
27
27
|
Requires-Dist: google-cloud-secret-manager>=2.22.0
|
28
28
|
Requires-Dist: google-cloud-speech>=2.30.0
|
29
29
|
Requires-Dist: google-cloud-storage>=2.18.0, <3.0.0
|
30
|
-
Requires-Dist: google-genai>=1.
|
30
|
+
Requires-Dist: google-genai>=1.12.1
|
31
31
|
Requires-Dist: graphviz>=0.20.2
|
32
32
|
Requires-Dist: mcp>=1.5.0;python_version>='3.10'
|
33
33
|
Requires-Dist: opentelemetry-api>=1.31.0
|