google-adk 1.6.1__py3-none-any.whl → 1.8.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/a2a/converters/event_converter.py +5 -85
- google/adk/a2a/converters/request_converter.py +1 -2
- google/adk/a2a/executor/a2a_agent_executor.py +45 -16
- google/adk/a2a/logs/log_utils.py +1 -2
- google/adk/a2a/utils/__init__.py +0 -0
- google/adk/a2a/utils/agent_card_builder.py +544 -0
- google/adk/a2a/utils/agent_to_a2a.py +118 -0
- google/adk/agents/__init__.py +5 -0
- google/adk/agents/agent_config.py +46 -0
- google/adk/agents/base_agent.py +239 -41
- google/adk/agents/callback_context.py +41 -0
- google/adk/agents/common_configs.py +79 -0
- google/adk/agents/config_agent_utils.py +184 -0
- google/adk/agents/config_schemas/AgentConfig.json +566 -0
- google/adk/agents/invocation_context.py +5 -1
- google/adk/agents/live_request_queue.py +15 -0
- google/adk/agents/llm_agent.py +201 -9
- google/adk/agents/loop_agent.py +35 -1
- google/adk/agents/parallel_agent.py +24 -3
- google/adk/agents/remote_a2a_agent.py +17 -5
- google/adk/agents/sequential_agent.py +22 -1
- google/adk/artifacts/gcs_artifact_service.py +110 -20
- google/adk/auth/auth_handler.py +3 -3
- google/adk/auth/credential_manager.py +23 -23
- google/adk/auth/credential_service/base_credential_service.py +6 -6
- google/adk/auth/credential_service/in_memory_credential_service.py +10 -8
- google/adk/auth/credential_service/session_state_credential_service.py +8 -8
- google/adk/auth/exchanger/oauth2_credential_exchanger.py +3 -3
- google/adk/auth/oauth2_credential_util.py +2 -2
- google/adk/auth/refresher/oauth2_credential_refresher.py +4 -4
- google/adk/cli/agent_graph.py +3 -1
- google/adk/cli/browser/index.html +2 -2
- google/adk/cli/browser/main-W7QZBYAR.js +3914 -0
- google/adk/cli/browser/polyfills-B6TNHZQ6.js +17 -0
- google/adk/cli/cli_eval.py +87 -12
- google/adk/cli/cli_tools_click.py +143 -82
- google/adk/cli/fast_api.py +150 -69
- google/adk/cli/utils/agent_loader.py +35 -1
- google/adk/code_executors/base_code_executor.py +14 -19
- google/adk/code_executors/built_in_code_executor.py +4 -1
- google/adk/evaluation/base_eval_service.py +46 -2
- google/adk/evaluation/eval_metrics.py +4 -0
- google/adk/evaluation/eval_sets_manager.py +5 -1
- google/adk/evaluation/evaluation_generator.py +1 -1
- google/adk/evaluation/final_response_match_v2.py +2 -2
- google/adk/evaluation/gcs_eval_sets_manager.py +2 -1
- google/adk/evaluation/in_memory_eval_sets_manager.py +151 -0
- google/adk/evaluation/local_eval_service.py +389 -0
- google/adk/evaluation/local_eval_set_results_manager.py +2 -2
- google/adk/evaluation/local_eval_sets_manager.py +24 -9
- google/adk/evaluation/metric_evaluator_registry.py +16 -6
- google/adk/evaluation/vertex_ai_eval_facade.py +7 -1
- google/adk/events/event.py +7 -2
- google/adk/flows/llm_flows/auto_flow.py +6 -11
- google/adk/flows/llm_flows/base_llm_flow.py +66 -29
- google/adk/flows/llm_flows/contents.py +16 -10
- google/adk/flows/llm_flows/functions.py +89 -52
- google/adk/memory/in_memory_memory_service.py +21 -15
- google/adk/memory/vertex_ai_memory_bank_service.py +12 -10
- google/adk/models/anthropic_llm.py +46 -6
- google/adk/models/base_llm_connection.py +2 -0
- google/adk/models/gemini_llm_connection.py +17 -6
- google/adk/models/google_llm.py +46 -11
- google/adk/models/lite_llm.py +52 -22
- google/adk/plugins/__init__.py +17 -0
- google/adk/plugins/base_plugin.py +317 -0
- google/adk/plugins/plugin_manager.py +265 -0
- google/adk/runners.py +122 -18
- google/adk/sessions/database_session_service.py +51 -52
- google/adk/sessions/vertex_ai_session_service.py +27 -12
- google/adk/tools/__init__.py +2 -0
- google/adk/tools/_automatic_function_calling_util.py +20 -2
- google/adk/tools/agent_tool.py +15 -3
- google/adk/tools/apihub_tool/apihub_toolset.py +38 -39
- google/adk/tools/application_integration_tool/application_integration_toolset.py +35 -37
- google/adk/tools/application_integration_tool/integration_connector_tool.py +2 -3
- google/adk/tools/base_tool.py +9 -9
- google/adk/tools/base_toolset.py +29 -5
- google/adk/tools/bigquery/__init__.py +3 -3
- google/adk/tools/bigquery/metadata_tool.py +2 -0
- google/adk/tools/bigquery/query_tool.py +15 -1
- google/adk/tools/computer_use/__init__.py +13 -0
- google/adk/tools/computer_use/base_computer.py +265 -0
- google/adk/tools/computer_use/computer_use_tool.py +166 -0
- google/adk/tools/computer_use/computer_use_toolset.py +220 -0
- google/adk/tools/enterprise_search_tool.py +4 -2
- google/adk/tools/exit_loop_tool.py +1 -0
- google/adk/tools/google_api_tool/google_api_tool.py +16 -1
- google/adk/tools/google_api_tool/google_api_toolset.py +9 -7
- google/adk/tools/google_api_tool/google_api_toolsets.py +41 -20
- google/adk/tools/google_search_tool.py +4 -2
- google/adk/tools/langchain_tool.py +16 -6
- google/adk/tools/long_running_tool.py +21 -0
- google/adk/tools/mcp_tool/mcp_toolset.py +27 -28
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +5 -0
- google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +8 -8
- google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +4 -6
- google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +3 -2
- google/adk/tools/tool_context.py +0 -10
- google/adk/tools/url_context_tool.py +4 -2
- google/adk/tools/vertex_ai_search_tool.py +4 -2
- google/adk/utils/model_name_utils.py +90 -0
- google/adk/version.py +1 -1
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/METADATA +3 -2
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/RECORD +108 -91
- google/adk/cli/browser/main-RXDVX3K6.js +0 -3914
- google/adk/cli/browser/polyfills-FFHMD2TL.js +0 -17
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/WHEEL +0 -0
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/entry_points.txt +0 -0
- {google_adk-1.6.1.dist-info → google_adk-1.8.0.dist-info}/licenses/LICENSE +0 -0
google/adk/tools/agent_tool.py
CHANGED
@@ -23,15 +23,12 @@ from typing_extensions import override
|
|
23
23
|
|
24
24
|
from . import _automatic_function_calling_util
|
25
25
|
from ..memory.in_memory_memory_service import InMemoryMemoryService
|
26
|
-
from ..runners import Runner
|
27
|
-
from ..sessions.in_memory_session_service import InMemorySessionService
|
28
26
|
from ._forwarding_artifact_service import ForwardingArtifactService
|
29
27
|
from .base_tool import BaseTool
|
30
28
|
from .tool_context import ToolContext
|
31
29
|
|
32
30
|
if TYPE_CHECKING:
|
33
31
|
from ..agents.base_agent import BaseAgent
|
34
|
-
from ..agents.llm_agent import LlmAgent
|
35
32
|
|
36
33
|
|
37
34
|
class AgentTool(BaseTool):
|
@@ -61,6 +58,7 @@ class AgentTool(BaseTool):
|
|
61
58
|
@override
|
62
59
|
def _get_declaration(self) -> types.FunctionDeclaration:
|
63
60
|
from ..agents.llm_agent import LlmAgent
|
61
|
+
from ..utils.variant_utils import GoogleLLMVariant
|
64
62
|
|
65
63
|
if isinstance(self.agent, LlmAgent) and self.agent.input_schema:
|
66
64
|
result = _automatic_function_calling_util.build_function_declaration(
|
@@ -80,6 +78,17 @@ class AgentTool(BaseTool):
|
|
80
78
|
description=self.agent.description,
|
81
79
|
name=self.name,
|
82
80
|
)
|
81
|
+
|
82
|
+
# Set response schema for non-GEMINI_API variants
|
83
|
+
if self._api_variant != GoogleLLMVariant.GEMINI_API:
|
84
|
+
# Determine response type based on agent's output schema
|
85
|
+
if isinstance(self.agent, LlmAgent) and self.agent.output_schema:
|
86
|
+
# Agent has structured output schema - response is an object
|
87
|
+
result.response = types.Schema(type=types.Type.OBJECT)
|
88
|
+
else:
|
89
|
+
# Agent returns text - response is a string
|
90
|
+
result.response = types.Schema(type=types.Type.STRING)
|
91
|
+
|
83
92
|
result.name = self.name
|
84
93
|
return result
|
85
94
|
|
@@ -91,6 +100,8 @@ class AgentTool(BaseTool):
|
|
91
100
|
tool_context: ToolContext,
|
92
101
|
) -> Any:
|
93
102
|
from ..agents.llm_agent import LlmAgent
|
103
|
+
from ..runners import Runner
|
104
|
+
from ..sessions.in_memory_session_service import InMemorySessionService
|
94
105
|
|
95
106
|
if self.skip_summarization:
|
96
107
|
tool_context.actions.skip_summarization = True
|
@@ -116,6 +127,7 @@ class AgentTool(BaseTool):
|
|
116
127
|
artifact_service=ForwardingArtifactService(tool_context),
|
117
128
|
session_service=InMemorySessionService(),
|
118
129
|
memory_service=InMemoryMemoryService(),
|
130
|
+
credential_service=tool_context._invocation_context.credential_service,
|
119
131
|
)
|
120
132
|
session = await runner.session_service.create_session(
|
121
133
|
app_name=self.agent.name,
|
@@ -35,27 +35,25 @@ from .clients.apihub_client import APIHubClient
|
|
35
35
|
class APIHubToolset(BaseToolset):
|
36
36
|
"""APIHubTool generates tools from a given API Hub resource.
|
37
37
|
|
38
|
-
Examples
|
38
|
+
Examples::
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
)
|
47
|
-
|
48
|
-
# Get all available tools
|
49
|
-
agent = LlmAgent(tools=apihub_toolset)
|
40
|
+
apihub_toolset = APIHubToolset(
|
41
|
+
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
42
|
+
service_account_json="...",
|
43
|
+
tool_filter=lambda tool, ctx=None: tool.name in ('my_tool',
|
44
|
+
'my_other_tool')
|
45
|
+
)
|
50
46
|
|
51
|
-
|
47
|
+
# Get all available tools
|
48
|
+
agent = LlmAgent(tools=apihub_toolset)
|
52
49
|
|
53
50
|
**apihub_resource_name** is the resource name from API Hub. It must include
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
API name, and can optionally include API version and spec name.
|
52
|
+
|
53
|
+
- If apihub_resource_name includes a spec resource name, the content of that
|
54
|
+
spec will be used for generating the tools.
|
55
|
+
- If apihub_resource_name includes only an api or a version name, the
|
56
|
+
first spec of the first version of that API will be used.
|
59
57
|
"""
|
60
58
|
|
61
59
|
def __init__(
|
@@ -78,44 +76,45 @@ class APIHubToolset(BaseToolset):
|
|
78
76
|
):
|
79
77
|
"""Initializes the APIHubTool with the given parameters.
|
80
78
|
|
81
|
-
Examples
|
82
|
-
```
|
83
|
-
apihub_toolset = APIHubToolset(
|
84
|
-
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
85
|
-
service_account_json="...",
|
86
|
-
)
|
79
|
+
Examples::
|
87
80
|
|
88
|
-
|
89
|
-
|
81
|
+
apihub_toolset = APIHubToolset(
|
82
|
+
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
83
|
+
service_account_json="...",
|
84
|
+
)
|
90
85
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
86
|
+
# Get all available tools
|
87
|
+
agent = LlmAgent(tools=[apihub_toolset])
|
88
|
+
|
89
|
+
apihub_toolset = APIHubToolset(
|
90
|
+
apihub_resource_name="projects/test-project/locations/us-central1/apis/test-api",
|
91
|
+
service_account_json="...",
|
92
|
+
tool_filter = ['my_tool']
|
93
|
+
)
|
94
|
+
# Get a specific tool
|
95
|
+
agent = LlmAgent(tools=[
|
96
|
+
...,
|
97
|
+
apihub_toolset,
|
98
|
+
])
|
102
99
|
|
103
100
|
**apihub_resource_name** is the resource name from API Hub. It must include
|
104
101
|
API name, and can optionally include API version and spec name.
|
102
|
+
|
105
103
|
- If apihub_resource_name includes a spec resource name, the content of that
|
106
104
|
spec will be used for generating the tools.
|
107
105
|
- If apihub_resource_name includes only an api or a version name, the
|
108
106
|
first spec of the first version of that API will be used.
|
109
107
|
|
110
108
|
Example:
|
109
|
+
|
111
110
|
* projects/xxx/locations/us-central1/apis/apiname/...
|
112
111
|
* https://console.cloud.google.com/apigee/api-hub/apis/apiname?project=xxx
|
113
112
|
|
114
113
|
Args:
|
115
114
|
apihub_resource_name: The resource name of the API in API Hub.
|
116
|
-
Example:
|
117
|
-
access_token: Google Access token. Generate with gcloud cli
|
118
|
-
auth print-access-token
|
115
|
+
Example: ``projects/test-project/locations/us-central1/apis/test-api``.
|
116
|
+
access_token: Google Access token. Generate with gcloud cli
|
117
|
+
``gcloud auth auth print-access-token``. Used for fetching API Specs from API Hub.
|
119
118
|
service_account_json: The service account config as a json string.
|
120
119
|
Required if not using default service credential. It is used for
|
121
120
|
creating the API Hub client and fetching the API Specs from API Hub.
|
@@ -12,6 +12,8 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
import logging
|
16
18
|
from typing import List
|
17
19
|
from typing import Optional
|
@@ -42,43 +44,39 @@ logger = logging.getLogger("google_adk." + __name__)
|
|
42
44
|
# TODO(cheliu): Apply a common toolset interface
|
43
45
|
class ApplicationIntegrationToolset(BaseToolset):
|
44
46
|
"""ApplicationIntegrationToolset generates tools from a given Application
|
45
|
-
|
46
47
|
Integration or Integration Connector resource.
|
47
|
-
Example Usage:
|
48
|
-
```
|
49
|
-
# Get all available tools for an integration with api trigger
|
50
|
-
application_integration_toolset = ApplicationIntegrationToolset(
|
51
48
|
|
52
|
-
|
53
|
-
location="us-central1"
|
54
|
-
integration="test-integration",
|
55
|
-
triggers=["api_trigger/test_trigger"],
|
56
|
-
service_account_credentials={...},
|
57
|
-
)
|
49
|
+
Example Usage::
|
58
50
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
51
|
+
# Get all available tools for an integration with api trigger
|
52
|
+
application_integration_toolset = ApplicationIntegrationToolset(
|
53
|
+
project="test-project",
|
54
|
+
location="us-central1"
|
55
|
+
integration="test-integration",
|
56
|
+
triggers=["api_trigger/test_trigger"],
|
57
|
+
service_account_credentials={...},
|
58
|
+
)
|
59
|
+
|
60
|
+
# Get all available tools for a connection using entity operations and
|
61
|
+
# actions
|
62
|
+
# Note: Find the list of supported entity operations and actions for a
|
63
|
+
# connection using integration connector apis:
|
64
|
+
# https://cloud.google.com/integration-connectors/docs/reference/rest/v1/projects.locations.connections.connectionSchemaMetadata
|
65
|
+
application_integration_toolset = ApplicationIntegrationToolset(
|
66
|
+
project="test-project",
|
67
|
+
location="us-central1"
|
68
|
+
connection="test-connection",
|
69
|
+
entity_operations=["EntityId1": ["LIST","CREATE"], "EntityId2": []],
|
70
|
+
#empty list for actions means all operations on the entity are supported
|
71
|
+
actions=["action1"],
|
72
|
+
service_account_credentials={...},
|
73
|
+
)
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
```
|
75
|
+
# Feed the toolset to agent
|
76
|
+
agent = LlmAgent(tools=[
|
77
|
+
...,
|
78
|
+
application_integration_toolset,
|
79
|
+
])
|
82
80
|
"""
|
83
81
|
|
84
82
|
def __init__(
|
@@ -122,11 +120,11 @@ class ApplicationIntegrationToolset(BaseToolset):
|
|
122
120
|
|
123
121
|
Raises:
|
124
122
|
ValueError: If none of the following conditions are met:
|
125
|
-
|
126
|
-
|
127
|
-
|
123
|
+
- ``integration`` is provided.
|
124
|
+
- ``connection`` is provided and at least one of ``entity_operations``
|
125
|
+
or ``actions`` is provided.
|
128
126
|
Exception: If there is an error during the initialization of the
|
129
|
-
|
127
|
+
integration or connection client.
|
130
128
|
"""
|
131
129
|
super().__init__(tool_filter=tool_filter)
|
132
130
|
self.project = project
|
@@ -45,13 +45,12 @@ class IntegrationConnectorTool(BaseTool):
|
|
45
45
|
* Generates request params and body
|
46
46
|
* Attaches auth credentials to API call.
|
47
47
|
|
48
|
-
Example
|
49
|
-
|
48
|
+
Example::
|
49
|
+
|
50
50
|
# Each API operation in the spec will be turned into its own tool
|
51
51
|
# Name of the tool is the operationId of that operation, in snake case
|
52
52
|
operations = OperationGenerator().parse(openapi_spec_dict)
|
53
53
|
tool = [RestApiTool.from_parsed_operation(o) for o in operations]
|
54
|
-
```
|
55
54
|
"""
|
56
55
|
|
57
56
|
EXCLUDE_FIELDS = [
|
google/adk/tools/base_tool.py
CHANGED
@@ -49,11 +49,11 @@ class BaseTool(ABC):
|
|
49
49
|
def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
|
50
50
|
"""Gets the OpenAPI specification of this tool in the form of a FunctionDeclaration.
|
51
51
|
|
52
|
-
NOTE
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
NOTE:
|
53
|
+
- Required if subclass uses the default implementation of
|
54
|
+
`process_llm_request` to add function declaration to LLM request.
|
55
|
+
- Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
|
56
|
+
Gemini.
|
57
57
|
|
58
58
|
Returns:
|
59
59
|
The FunctionDeclaration of this tool, or None if it doesn't need to be
|
@@ -66,10 +66,10 @@ class BaseTool(ABC):
|
|
66
66
|
) -> Any:
|
67
67
|
"""Runs the tool with the given arguments and context.
|
68
68
|
|
69
|
-
NOTE
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
NOTE:
|
70
|
+
- Required if this tool needs to run at the client side.
|
71
|
+
- Otherwise, can be skipped, e.g. for a built-in GoogleSearch tool for
|
72
|
+
Gemini.
|
73
73
|
|
74
74
|
Args:
|
75
75
|
args: The LLM-filled arguments.
|
google/adk/tools/base_toolset.py
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
15
16
|
|
16
17
|
from abc import ABC
|
17
18
|
from abc import abstractmethod
|
@@ -19,11 +20,16 @@ from typing import List
|
|
19
20
|
from typing import Optional
|
20
21
|
from typing import Protocol
|
21
22
|
from typing import runtime_checkable
|
23
|
+
from typing import TYPE_CHECKING
|
22
24
|
from typing import Union
|
23
25
|
|
24
26
|
from ..agents.readonly_context import ReadonlyContext
|
25
27
|
from .base_tool import BaseTool
|
26
28
|
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
from ..models.llm_request import LlmRequest
|
31
|
+
from .tool_context import ToolContext
|
32
|
+
|
27
33
|
|
28
34
|
@runtime_checkable
|
29
35
|
class ToolPredicate(Protocol):
|
@@ -64,7 +70,7 @@ class BaseToolset(ABC):
|
|
64
70
|
"""Return all tools in the toolset based on the provided context.
|
65
71
|
|
66
72
|
Args:
|
67
|
-
|
73
|
+
readonly_context (ReadonlyContext, optional): Context used to filter tools
|
68
74
|
available to the agent. If None, all tools in the toolset are returned.
|
69
75
|
|
70
76
|
Returns:
|
@@ -75,10 +81,11 @@ class BaseToolset(ABC):
|
|
75
81
|
async def close(self) -> None:
|
76
82
|
"""Performs cleanup and releases resources held by the toolset.
|
77
83
|
|
78
|
-
NOTE:
|
79
|
-
|
80
|
-
|
81
|
-
|
84
|
+
NOTE:
|
85
|
+
This method is invoked, for example, at the end of an agent server's
|
86
|
+
lifecycle or when the toolset is no longer needed. Implementations
|
87
|
+
should ensure that any open connections, files, or other managed
|
88
|
+
resources are properly released to prevent leaks.
|
82
89
|
"""
|
83
90
|
|
84
91
|
def _is_tool_selected(
|
@@ -94,3 +101,20 @@ class BaseToolset(ABC):
|
|
94
101
|
return tool.name in self.tool_filter
|
95
102
|
|
96
103
|
return False
|
104
|
+
|
105
|
+
async def process_llm_request(
|
106
|
+
self, *, tool_context: ToolContext, llm_request: LlmRequest
|
107
|
+
) -> None:
|
108
|
+
"""Processes the outgoing LLM request for this toolset. This method will be
|
109
|
+
called before each tool processes the llm request.
|
110
|
+
|
111
|
+
Use cases:
|
112
|
+
- Instead of let each tool process the llm request, we can let the toolset
|
113
|
+
process the llm request. e.g. ComputerUseToolset can add computer use
|
114
|
+
tool to the llm request.
|
115
|
+
|
116
|
+
Args:
|
117
|
+
tool_context: The context of the tool.
|
118
|
+
llm_request: The outgoing LLM request, mutable this method.
|
119
|
+
"""
|
120
|
+
pass
|
@@ -20,11 +20,11 @@ definition. The rationales to have customized tool are:
|
|
20
20
|
|
21
21
|
1. BigQuery APIs have functions overlaps and LLM can't tell what tool to use
|
22
22
|
2. BigQuery APIs have a lot of parameters with some rarely used, which are not
|
23
|
-
|
23
|
+
LLM-friendly
|
24
24
|
3. We want to provide more high-level tools like forecasting, RAG, segmentation,
|
25
|
-
|
25
|
+
etc.
|
26
26
|
4. We want to provide extra access guardrails in those tools. For example,
|
27
|
-
|
27
|
+
execute_sql can't arbitrarily mutate existing data.
|
28
28
|
"""
|
29
29
|
|
30
30
|
from .bigquery_credentials import BigQueryCredentialsConfig
|
@@ -12,7 +12,10 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
from __future__ import annotations
|
16
|
+
|
15
17
|
import functools
|
18
|
+
import json
|
16
19
|
import types
|
17
20
|
from typing import Callable
|
18
21
|
|
@@ -159,7 +162,18 @@ def execute_sql(
|
|
159
162
|
project=project_id,
|
160
163
|
max_results=MAX_DOWNLOADED_QUERY_RESULT_ROWS,
|
161
164
|
)
|
162
|
-
rows = [
|
165
|
+
rows = []
|
166
|
+
for row in row_iterator:
|
167
|
+
row_values = {}
|
168
|
+
for key, val in row.items():
|
169
|
+
try:
|
170
|
+
# if the json serialization of the value succeeds, use it as is
|
171
|
+
json.dumps(val)
|
172
|
+
except:
|
173
|
+
val = str(val)
|
174
|
+
row_values[key] = val
|
175
|
+
rows.append(row_values)
|
176
|
+
|
163
177
|
result = {"status": "SUCCESS", "rows": rows}
|
164
178
|
if (
|
165
179
|
MAX_DOWNLOADED_QUERY_RESULT_ROWS is not None
|
@@ -0,0 +1,13 @@
|
|
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.
|