solace-agent-mesh 1.0.5__py3-none-any.whl → 1.0.7__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.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
- solace_agent_mesh/agent/adk/{filesystem_artifact_service.py → artifacts/filesystem_artifact_service.py} +14 -15
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +440 -0
- solace_agent_mesh/agent/adk/callbacks.py +123 -159
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +316 -0
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +414 -0
- solace_agent_mesh/agent/adk/mcp_content_processor.py +665 -0
- solace_agent_mesh/agent/adk/services.py +35 -1
- solace_agent_mesh/agent/adk/setup.py +85 -45
- solace_agent_mesh/agent/adk/tool_wrapper.py +19 -3
- solace_agent_mesh/agent/protocol/event_handlers.py +1 -1
- solace_agent_mesh/agent/sac/app.py +67 -0
- solace_agent_mesh/agent/sac/component.py +14 -86
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/04989206.b9dfe831.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/0e682baa.b3bbde9a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1023fc19.364235d5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1523c6b4.1b0ec6f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/166ab619.e8f3a7c7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/21ceee5f.3bf39250.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3d406171.7d02a73b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.8ccb9901.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/442a8107.b3159bb2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4c2787c2.fc6804f2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5b4258a4.0d080cd9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/75384d09.ccd480c4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/768e31b0.8b51cd70.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/945fb41e.c63791d1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{9eff14a2.036c35ea.js → 9eff14a2.472b0310.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/a3a92b25.4b7fa6a2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.76376d7c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ae4415af.7a2f0bbf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/b7006a3a.73a79653.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/beecea0d.ae31f6a7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c2c06897.587b4af5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{cd3d4052.ca6eed8c.js → cd3d4052.b6535013.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f897a61a.0aa29dbb.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.d79f063b.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.6415ad00.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +28 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +34 -5
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +7 -7
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +35 -16
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +17 -11
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +35 -23
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/lunr-index-1756146501924.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1756146501924.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +1 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +67 -10
- solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +2 -2
- solace_agent_mesh/cli/commands/eval_cmd.py +8 -2
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +20 -2
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +25 -1
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +45 -1
- solace_agent_mesh/cli/utils.py +21 -12
- solace_agent_mesh/client/webui/frontend/static/assets/main-BucUdn9m.js +673 -0
- solace_agent_mesh/client/webui/frontend/static/index.html +1 -1
- solace_agent_mesh/common/a2a_protocol.py +1 -1
- solace_agent_mesh/common/utils/initializer.py +4 -6
- solace_agent_mesh/common/utils/mime_helpers.py +60 -1
- solace_agent_mesh/config_portal/backend/server.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-xSu2leR8.js → _index-MqsrTd6g.js} +9 -9
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-950eb3be.js → manifest-28271392.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +1 -1
- solace_agent_mesh/core_a2a/service.py +1 -1
- solace_agent_mesh/evaluation/run.py +149 -15
- solace_agent_mesh/evaluation/summary_builder.py +5 -3
- solace_agent_mesh/gateway/http_sse/dependencies.py +1 -1
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +1 -1
- solace_agent_mesh/gateway/http_sse/services/task_service.py +1 -1
- solace_agent_mesh/llm_detail.txt +2 -2
- solace_agent_mesh/templates/agent_template.yaml +1 -1
- solace_agent_mesh/templates/plugin_agent_config_template.yaml +3 -3
- solace_agent_mesh/templates/plugin_readme_template.md +1 -1
- solace_agent_mesh/templates/shared_config.yaml +8 -1
- {solace_agent_mesh-1.0.5.dist-info → solace_agent_mesh-1.0.7.dist-info}/METADATA +5 -2
- {solace_agent_mesh-1.0.5.dist-info → solace_agent_mesh-1.0.7.dist-info}/RECORD +114 -109
- solace_agent_mesh/assets/docs/assets/js/04989206.da8246cd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/0e682baa.79f0ab22.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1023fc19.8e6d174c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1523c6b4.91c7bc01.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/166ab619.7d97ccaf.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/21ceee5f.614fa8dd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3d406171.9b081d5f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.36090198.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/442a8107.5ba94b65.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/4c2787c2.66ee00e9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5b4258a4.bda20761.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/75384d09.c3991823.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/768e31b0.a12673db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/945fb41e.74d728aa.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a3a92b25.26ca071f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.a6b84da6.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ae4415af.96189a93.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/b7006a3a.38c0cf3d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/bb2ef573.56931473.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c2c06897.63b76e9e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5aff74ab.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f897a61a.862b0514.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.946fa17b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.aa687c82.js +0 -1
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +0 -17
- solace_agent_mesh/assets/docs/lunr-index-1755275703209.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1755275703209.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DzKPMTRs.js +0 -673
- /solace_agent_mesh/assets/docs/assets/js/{main.946fa17b.js.LICENSE.txt → main.d79f063b.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.5.dist-info → solace_agent_mesh-1.0.7.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.5.dist-info → solace_agent_mesh-1.0.7.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.0.5.dist-info → solace_agent_mesh-1.0.7.dist-info}/licenses/LICENSE +0 -0
|
@@ -27,7 +27,8 @@ from google.adk.memory import (
|
|
|
27
27
|
VertexAiRagMemoryService,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
from .filesystem_artifact_service import FilesystemArtifactService
|
|
30
|
+
from .artifacts.filesystem_artifact_service import FilesystemArtifactService
|
|
31
|
+
from .artifacts.s3_artifact_service import S3ArtifactService
|
|
31
32
|
|
|
32
33
|
try:
|
|
33
34
|
from sam_test_infrastructure.artifact_service.service import (
|
|
@@ -254,6 +255,39 @@ def initialize_artifact_service(component) -> BaseArtifactService:
|
|
|
254
255
|
e,
|
|
255
256
|
)
|
|
256
257
|
raise
|
|
258
|
+
elif service_type == "s3":
|
|
259
|
+
bucket_name = config.get("bucket_name")
|
|
260
|
+
if not bucket_name or not bucket_name.strip():
|
|
261
|
+
raise ValueError(
|
|
262
|
+
f"{component.log_identifier} 'bucket_name' is required and cannot be empty for S3 artifact service."
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
try:
|
|
266
|
+
s3_config = {}
|
|
267
|
+
|
|
268
|
+
for key, value in config.items():
|
|
269
|
+
if key not in ["type", "bucket_name", "artifact_scope"]:
|
|
270
|
+
s3_config[key] = value
|
|
271
|
+
|
|
272
|
+
if "endpoint_url" not in s3_config:
|
|
273
|
+
s3_config["endpoint_url"] = "https://s3.amazonaws.com"
|
|
274
|
+
|
|
275
|
+
aws_access_key_id = config.get("aws_access_key_id") or os.environ.get("AWS_ACCESS_KEY_ID")
|
|
276
|
+
aws_secret_access_key = config.get("aws_secret_access_key") or os.environ.get("AWS_SECRET_ACCESS_KEY")
|
|
277
|
+
|
|
278
|
+
if aws_access_key_id:
|
|
279
|
+
s3_config["aws_access_key_id"] = aws_access_key_id
|
|
280
|
+
if aws_secret_access_key:
|
|
281
|
+
s3_config["aws_secret_access_key"] = aws_secret_access_key
|
|
282
|
+
|
|
283
|
+
concrete_service = S3ArtifactService(bucket_name=bucket_name, **s3_config)
|
|
284
|
+
except Exception as e:
|
|
285
|
+
log.error(
|
|
286
|
+
"%s Failed to initialize S3ArtifactService: %s",
|
|
287
|
+
component.log_identifier,
|
|
288
|
+
e,
|
|
289
|
+
)
|
|
290
|
+
raise
|
|
257
291
|
elif service_type == "test_in_memory":
|
|
258
292
|
if TestInMemoryArtifactService is None:
|
|
259
293
|
log.error(
|
|
@@ -10,6 +10,7 @@ from solace_ai_connector.common.utils import import_module
|
|
|
10
10
|
|
|
11
11
|
from .app_llm_agent import AppLlmAgent
|
|
12
12
|
from .tool_wrapper import ADKToolWrapper
|
|
13
|
+
from .embed_resolving_mcp_toolset import EmbedResolvingMCPToolset
|
|
13
14
|
from google.adk.runners import Runner
|
|
14
15
|
from google.adk.models import BaseLlm
|
|
15
16
|
from google.adk.tools import BaseTool, ToolContext
|
|
@@ -18,7 +19,10 @@ from google.adk.agents.callback_context import CallbackContext
|
|
|
18
19
|
from google.adk.models.llm_request import LlmRequest
|
|
19
20
|
from google.adk.models.llm_response import LlmResponse
|
|
20
21
|
from google.adk.tools.mcp_tool import MCPToolset
|
|
21
|
-
from google.adk.tools.mcp_tool.mcp_session_manager import
|
|
22
|
+
from google.adk.tools.mcp_tool.mcp_session_manager import (
|
|
23
|
+
SseServerParams,
|
|
24
|
+
StdioConnectionParams,
|
|
25
|
+
)
|
|
22
26
|
|
|
23
27
|
from mcp import StdioServerParameters
|
|
24
28
|
|
|
@@ -55,11 +59,27 @@ async def load_adk_tools(
|
|
|
55
59
|
loaded_tool_names: Set[str] = set()
|
|
56
60
|
tools_config = component.get_config("tools", [])
|
|
57
61
|
|
|
62
|
+
def _check_and_register_tool_name(name: str, source: str):
|
|
63
|
+
"""Checks for duplicate tool names and raises ValueError if found."""
|
|
64
|
+
if name in loaded_tool_names:
|
|
65
|
+
raise ValueError(
|
|
66
|
+
f"Configuration Error: Duplicate tool name '{name}' found from source '{source}'. "
|
|
67
|
+
"This name is already in use. Please resolve the conflict by renaming or "
|
|
68
|
+
"disabling one of the tools in your agent's configuration."
|
|
69
|
+
)
|
|
70
|
+
loaded_tool_names.add(name)
|
|
71
|
+
|
|
58
72
|
if not tools_config:
|
|
59
73
|
log.info(
|
|
60
74
|
"%s No explicit tools configured in 'tools' list.", component.log_identifier
|
|
61
75
|
)
|
|
62
76
|
else:
|
|
77
|
+
log.debug(
|
|
78
|
+
"%s Processing %d tool configurations: %s",
|
|
79
|
+
component.log_identifier,
|
|
80
|
+
len(tools_config),
|
|
81
|
+
[tc.get("tool_type") for tc in tools_config],
|
|
82
|
+
)
|
|
63
83
|
log.info(
|
|
64
84
|
"%s Loading tools from 'tools' list configuration...",
|
|
65
85
|
component.log_identifier,
|
|
@@ -91,6 +111,7 @@ async def load_adk_tools(
|
|
|
91
111
|
func,
|
|
92
112
|
specific_tool_config,
|
|
93
113
|
function_name,
|
|
114
|
+
origin="python",
|
|
94
115
|
raw_string_args=tool_config.get("raw_string_args", []),
|
|
95
116
|
)
|
|
96
117
|
|
|
@@ -101,34 +122,23 @@ async def load_adk_tools(
|
|
|
101
122
|
if tool_description:
|
|
102
123
|
tool_callable.__doc__ = tool_description
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
log.debug(
|
|
115
|
-
"%s Python tool '%s' already loaded. Skipping duplicate.",
|
|
116
|
-
component.log_identifier,
|
|
117
|
-
function_name,
|
|
118
|
-
)
|
|
125
|
+
_check_and_register_tool_name(
|
|
126
|
+
function_name, f"python:{module_name}"
|
|
127
|
+
)
|
|
128
|
+
loaded_tools.append(tool_callable)
|
|
129
|
+
log.info(
|
|
130
|
+
"%s Loaded Python tool: %s from %s.",
|
|
131
|
+
component.log_identifier,
|
|
132
|
+
function_name,
|
|
133
|
+
module_name,
|
|
134
|
+
)
|
|
119
135
|
|
|
120
136
|
elif tool_type == "builtin":
|
|
121
137
|
tool_name = tool_config.get("tool_name")
|
|
122
138
|
if not tool_name:
|
|
123
139
|
raise ValueError("'tool_name' required for builtin tool.")
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
log.debug(
|
|
127
|
-
"%s Tool '%s' already loaded. Skipping duplicate.",
|
|
128
|
-
component.log_identifier,
|
|
129
|
-
tool_name,
|
|
130
|
-
)
|
|
131
|
-
continue
|
|
141
|
+
_check_and_register_tool_name(tool_name, "builtin")
|
|
132
142
|
|
|
133
143
|
sam_tool_def = tool_registry.get_tool_by_name(tool_name)
|
|
134
144
|
if sam_tool_def:
|
|
@@ -137,11 +147,11 @@ async def load_adk_tools(
|
|
|
137
147
|
sam_tool_def.implementation,
|
|
138
148
|
specific_tool_config,
|
|
139
149
|
sam_tool_def.name,
|
|
150
|
+
origin="builtin",
|
|
140
151
|
raw_string_args=sam_tool_def.raw_string_args,
|
|
141
152
|
)
|
|
142
153
|
loaded_tools.append(tool_callable)
|
|
143
154
|
enabled_builtin_tools.append(sam_tool_def)
|
|
144
|
-
loaded_tool_names.add(sam_tool_def.name)
|
|
145
155
|
log.info(
|
|
146
156
|
"%s Loaded SAM built-in tool: %s",
|
|
147
157
|
component.log_identifier,
|
|
@@ -151,8 +161,8 @@ async def load_adk_tools(
|
|
|
151
161
|
|
|
152
162
|
adk_tool = getattr(adk_tools_module, tool_name, None)
|
|
153
163
|
if adk_tool and isinstance(adk_tool, (BaseTool, Callable)):
|
|
164
|
+
adk_tool.origin = "adk_builtin"
|
|
154
165
|
loaded_tools.append(adk_tool)
|
|
155
|
-
loaded_tool_names.add(tool_name)
|
|
156
166
|
log.info(
|
|
157
167
|
"%s Loaded ADK built-in tool: %s",
|
|
158
168
|
component.log_identifier,
|
|
@@ -211,20 +221,22 @@ async def load_adk_tools(
|
|
|
211
221
|
|
|
212
222
|
group_tool_count = 0
|
|
213
223
|
for tool_def in tools_in_group:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
_check_and_register_tool_name(
|
|
225
|
+
tool_def.name, f"builtin-group:{group_name}"
|
|
226
|
+
)
|
|
227
|
+
specific_tool_config = tool_config.get("tool_configs", {}).get(
|
|
228
|
+
tool_def.name
|
|
229
|
+
)
|
|
230
|
+
tool_callable = ADKToolWrapper(
|
|
231
|
+
tool_def.implementation,
|
|
232
|
+
specific_tool_config,
|
|
233
|
+
tool_def.name,
|
|
234
|
+
origin="builtin",
|
|
235
|
+
raw_string_args=tool_def.raw_string_args,
|
|
236
|
+
)
|
|
237
|
+
loaded_tools.append(tool_callable)
|
|
238
|
+
enabled_builtin_tools.append(tool_def)
|
|
239
|
+
group_tool_count += 1
|
|
228
240
|
log.info(
|
|
229
241
|
"Loaded %d tools from built-in group: %s",
|
|
230
242
|
group_tool_count,
|
|
@@ -249,7 +261,6 @@ async def load_adk_tools(
|
|
|
249
261
|
}
|
|
250
262
|
connection_args["timeout"] = connection_args.get("timeout", 30)
|
|
251
263
|
|
|
252
|
-
|
|
253
264
|
environment_variables = tool_config.get("environment_variables")
|
|
254
265
|
env_param = {}
|
|
255
266
|
if connection_type == "stdio" and environment_variables:
|
|
@@ -292,9 +303,9 @@ async def load_adk_tools(
|
|
|
292
303
|
**final_connection_args,
|
|
293
304
|
env=env_param if env_param else None,
|
|
294
305
|
),
|
|
295
|
-
timeout=connection_args.get("timeout")
|
|
306
|
+
timeout=connection_args.get("timeout"),
|
|
296
307
|
)
|
|
297
|
-
|
|
308
|
+
|
|
298
309
|
elif connection_type == "sse":
|
|
299
310
|
connection_params = SseServerParams(**connection_args)
|
|
300
311
|
else:
|
|
@@ -310,10 +321,37 @@ async def load_adk_tools(
|
|
|
310
321
|
tool_name,
|
|
311
322
|
)
|
|
312
323
|
|
|
313
|
-
mcp_toolset_instance =
|
|
324
|
+
mcp_toolset_instance = EmbedResolvingMCPToolset(
|
|
314
325
|
connection_params=connection_params,
|
|
315
326
|
tool_filter=tool_filter_list,
|
|
327
|
+
tool_config=tool_config,
|
|
316
328
|
)
|
|
329
|
+
mcp_toolset_instance.origin = "mcp"
|
|
330
|
+
|
|
331
|
+
# Check for duplicates from the MCP server
|
|
332
|
+
try:
|
|
333
|
+
mcp_tools = await mcp_toolset_instance.get_tools()
|
|
334
|
+
log.debug(
|
|
335
|
+
"%s Successfully discovered %d tools from MCP server: %s",
|
|
336
|
+
component.log_identifier,
|
|
337
|
+
len(mcp_tools),
|
|
338
|
+
[tool.name for tool in mcp_tools],
|
|
339
|
+
)
|
|
340
|
+
for mcp_tool in mcp_tools:
|
|
341
|
+
log.debug(
|
|
342
|
+
"%s Registering MCP tool: %s",
|
|
343
|
+
component.log_identifier,
|
|
344
|
+
mcp_tool.name,
|
|
345
|
+
)
|
|
346
|
+
_check_and_register_tool_name(mcp_tool.name, "mcp")
|
|
347
|
+
except Exception as e:
|
|
348
|
+
log.error(
|
|
349
|
+
"%s Failed to discover tools from MCP server: %s",
|
|
350
|
+
component.log_identifier,
|
|
351
|
+
str(e),
|
|
352
|
+
)
|
|
353
|
+
raise
|
|
354
|
+
|
|
317
355
|
loaded_tools.append(mcp_toolset_instance)
|
|
318
356
|
log.info(
|
|
319
357
|
"%s Initialized MCPToolset (filter: %s) for server: %s",
|
|
@@ -344,7 +382,9 @@ async def load_adk_tools(
|
|
|
344
382
|
internal_tool_names.append("_continue_generation")
|
|
345
383
|
|
|
346
384
|
for tool_name in internal_tool_names:
|
|
347
|
-
|
|
385
|
+
try:
|
|
386
|
+
_check_and_register_tool_name(tool_name, "internal")
|
|
387
|
+
except ValueError:
|
|
348
388
|
log.debug(
|
|
349
389
|
"%s Internal tool '%s' was already loaded explicitly. Skipping implicit load.",
|
|
350
390
|
component.log_identifier,
|
|
@@ -359,13 +399,13 @@ async def load_adk_tools(
|
|
|
359
399
|
tool_def.implementation,
|
|
360
400
|
None, # No specific config for internal tools
|
|
361
401
|
tool_def.name,
|
|
402
|
+
origin="internal",
|
|
362
403
|
)
|
|
363
404
|
|
|
364
405
|
tool_callable.__doc__ = tool_def.description
|
|
365
406
|
|
|
366
407
|
loaded_tools.append(tool_callable)
|
|
367
408
|
enabled_builtin_tools.append(tool_def)
|
|
368
|
-
loaded_tool_names.add(tool_def.name)
|
|
369
409
|
log.info(
|
|
370
410
|
"%s Implicitly loaded internal framework tool: %s",
|
|
371
411
|
component.log_identifier,
|
|
@@ -13,6 +13,7 @@ from ...common.utils.embeds import (
|
|
|
13
13
|
resolve_embeds_in_string,
|
|
14
14
|
evaluate_embed,
|
|
15
15
|
EARLY_EMBED_TYPES,
|
|
16
|
+
LATE_EMBED_TYPES,
|
|
16
17
|
EMBED_DELIMITER_OPEN,
|
|
17
18
|
)
|
|
18
19
|
|
|
@@ -31,15 +32,30 @@ class ADKToolWrapper:
|
|
|
31
32
|
original_func: Callable,
|
|
32
33
|
tool_config: Optional[Dict],
|
|
33
34
|
tool_name: str,
|
|
35
|
+
origin: str,
|
|
34
36
|
raw_string_args: Optional[List[str]] = None,
|
|
35
37
|
):
|
|
36
38
|
self._original_func = original_func
|
|
37
39
|
self._tool_config = tool_config or {}
|
|
38
40
|
self._tool_name = tool_name
|
|
41
|
+
self.origin = origin
|
|
39
42
|
self._raw_string_args = set(raw_string_args) if raw_string_args else set()
|
|
40
43
|
self._is_async = inspect.iscoroutinefunction(original_func)
|
|
41
44
|
|
|
42
|
-
functools.update_wrapper
|
|
45
|
+
# Ensure __name__ attribute is always set before functools.update_wrapper
|
|
46
|
+
self.__name__ = tool_name
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
functools.update_wrapper(self, original_func)
|
|
50
|
+
except AttributeError as e:
|
|
51
|
+
log.debug(
|
|
52
|
+
"Could not fully update wrapper for tool '%s': %s. Using fallback attributes.",
|
|
53
|
+
self._tool_name,
|
|
54
|
+
e,
|
|
55
|
+
)
|
|
56
|
+
# Ensure essential attributes are set even if update_wrapper fails
|
|
57
|
+
self.__name__ = tool_name
|
|
58
|
+
self.__doc__ = getattr(original_func, "__doc__", None)
|
|
43
59
|
|
|
44
60
|
try:
|
|
45
61
|
self.__code__ = original_func.__code__
|
|
@@ -78,7 +94,7 @@ class ADKToolWrapper:
|
|
|
78
94
|
text=arg,
|
|
79
95
|
context=context_for_embeds,
|
|
80
96
|
resolver_func=evaluate_embed,
|
|
81
|
-
types_to_resolve=EARLY_EMBED_TYPES,
|
|
97
|
+
types_to_resolve=EARLY_EMBED_TYPES.union(LATE_EMBED_TYPES),
|
|
82
98
|
log_identifier=log_identifier,
|
|
83
99
|
config=self._tool_config,
|
|
84
100
|
)
|
|
@@ -99,7 +115,7 @@ class ADKToolWrapper:
|
|
|
99
115
|
text=value,
|
|
100
116
|
context=context_for_embeds,
|
|
101
117
|
resolver_func=evaluate_embed,
|
|
102
|
-
types_to_resolve=EARLY_EMBED_TYPES,
|
|
118
|
+
types_to_resolve=EARLY_EMBED_TYPES.union(LATE_EMBED_TYPES),
|
|
103
119
|
log_identifier=log_identifier,
|
|
104
120
|
config=self._tool_config,
|
|
105
121
|
)
|
|
@@ -253,7 +253,7 @@ async def handle_a2a_request(component, message: SolaceMessage):
|
|
|
253
253
|
logical_task_id,
|
|
254
254
|
)
|
|
255
255
|
|
|
256
|
-
peer_sub_tasks = task_context.
|
|
256
|
+
peer_sub_tasks = task_context.active_peer_sub_tasks
|
|
257
257
|
if peer_sub_tasks:
|
|
258
258
|
for sub_task_info in peer_sub_tasks:
|
|
259
259
|
sub_task_id = sub_task_info.get("sub_task_id")
|
|
@@ -302,6 +302,73 @@ class SamAgentApp(App):
|
|
|
302
302
|
},
|
|
303
303
|
},
|
|
304
304
|
},
|
|
305
|
+
# --- MCP Intelligent Processing Config ---
|
|
306
|
+
{
|
|
307
|
+
"name": "mcp_intelligent_processing",
|
|
308
|
+
"required": False,
|
|
309
|
+
"type": "object",
|
|
310
|
+
"default": {},
|
|
311
|
+
"description": "Configuration for intelligent processing of MCP tool responses into typed artifacts.",
|
|
312
|
+
"properties": {
|
|
313
|
+
"enable_intelligent_processing": {
|
|
314
|
+
"type": "boolean",
|
|
315
|
+
"required": False,
|
|
316
|
+
"default": True,
|
|
317
|
+
"description": "Enable intelligent content-aware processing of MCP responses. When disabled, falls back to raw JSON saving.",
|
|
318
|
+
},
|
|
319
|
+
"enable_text_format_detection": {
|
|
320
|
+
"type": "boolean",
|
|
321
|
+
"required": False,
|
|
322
|
+
"default": True,
|
|
323
|
+
"description": "Enable detection and parsing of structured text formats (CSV, JSON, YAML) within text content.",
|
|
324
|
+
},
|
|
325
|
+
"enable_content_parsing": {
|
|
326
|
+
"type": "boolean",
|
|
327
|
+
"required": False,
|
|
328
|
+
"default": True,
|
|
329
|
+
"description": "Enable parsing and validation of detected content formats for enhanced metadata.",
|
|
330
|
+
},
|
|
331
|
+
"fallback_to_raw_on_error": {
|
|
332
|
+
"type": "boolean",
|
|
333
|
+
"required": False,
|
|
334
|
+
"default": True,
|
|
335
|
+
"description": "Fall back to raw JSON saving if intelligent processing fails.",
|
|
336
|
+
},
|
|
337
|
+
"save_raw_alongside_intelligent": {
|
|
338
|
+
"type": "boolean",
|
|
339
|
+
"required": False,
|
|
340
|
+
"default": False,
|
|
341
|
+
"description": "Save both intelligent artifacts and raw JSON response for debugging/comparison.",
|
|
342
|
+
},
|
|
343
|
+
"max_content_items": {
|
|
344
|
+
"type": "integer",
|
|
345
|
+
"required": False,
|
|
346
|
+
"default": 50,
|
|
347
|
+
"description": "Maximum number of content items to process from a single MCP response.",
|
|
348
|
+
},
|
|
349
|
+
"max_single_item_size_mb": {
|
|
350
|
+
"type": "integer",
|
|
351
|
+
"required": False,
|
|
352
|
+
"default": 100,
|
|
353
|
+
"description": "Maximum size in MB for a single content item before skipping intelligent processing.",
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
# --- MCP Tool Response Thresholds ---
|
|
358
|
+
{
|
|
359
|
+
"name": "mcp_tool_response_save_threshold_bytes",
|
|
360
|
+
"required": False,
|
|
361
|
+
"type": "integer",
|
|
362
|
+
"default": 2048,
|
|
363
|
+
"description": "Threshold in bytes above which MCP tool responses are saved as artifacts.",
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
"name": "mcp_tool_llm_return_max_bytes",
|
|
367
|
+
"required": False,
|
|
368
|
+
"type": "integer",
|
|
369
|
+
"default": 4096,
|
|
370
|
+
"description": "Maximum size in bytes of MCP tool response content returned directly to the LLM.",
|
|
371
|
+
},
|
|
305
372
|
# --- Artifact Handling ---
|
|
306
373
|
{
|
|
307
374
|
"name": "artifact_handling_mode",
|
|
@@ -1042,35 +1042,30 @@ class SamAgentComponent(ComponentBase):
|
|
|
1042
1042
|
|
|
1043
1043
|
for func_decl in original_tool.function_declarations:
|
|
1044
1044
|
func_decl_name = func_decl.name
|
|
1045
|
-
|
|
1046
|
-
|
|
1045
|
+
tool_object = llm_request.tools_dict.get(func_decl_name)
|
|
1046
|
+
origin = getattr(tool_object, "origin", "unknown")
|
|
1047
1047
|
|
|
1048
1048
|
feature_descriptor = {
|
|
1049
1049
|
"feature_type": "tool_function",
|
|
1050
1050
|
"function_name": func_decl_name,
|
|
1051
|
-
"tool_source":
|
|
1052
|
-
"tool_metadata":
|
|
1051
|
+
"tool_source": origin,
|
|
1052
|
+
"tool_metadata": {"function_name": func_decl_name},
|
|
1053
1053
|
}
|
|
1054
1054
|
|
|
1055
|
-
if
|
|
1055
|
+
if origin == "peer_agent":
|
|
1056
1056
|
peer_name = func_decl_name.replace(PEER_TOOL_PREFIX, "", 1)
|
|
1057
1057
|
feature_descriptor["tool_metadata"]["peer_agent_name"] = peer_name
|
|
1058
|
-
|
|
1059
|
-
tool_matched_for_capability_lookup = True
|
|
1060
|
-
|
|
1061
|
-
if not tool_matched_for_capability_lookup:
|
|
1058
|
+
elif origin == "builtin":
|
|
1062
1059
|
tool_def = tool_registry.get_tool_by_name(func_decl_name)
|
|
1063
1060
|
if tool_def:
|
|
1064
1061
|
feature_descriptor["tool_metadata"][
|
|
1065
1062
|
"tool_category"
|
|
1066
1063
|
] = tool_def.category
|
|
1067
|
-
feature_descriptor["tool_metadata"][
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
if not tool_matched_for_capability_lookup:
|
|
1064
|
+
feature_descriptor["tool_metadata"][
|
|
1065
|
+
"required_scopes"
|
|
1066
|
+
] = tool_def.required_scopes
|
|
1067
|
+
elif origin in ["python", "mcp", "adk_builtin"]:
|
|
1068
|
+
# Find the explicit config for this tool to pass to the resolver
|
|
1074
1069
|
for tool_cfg in explicit_tools_config:
|
|
1075
1070
|
cfg_tool_type = tool_cfg.get("tool_type")
|
|
1076
1071
|
cfg_tool_name = tool_cfg.get("tool_name")
|
|
@@ -1082,24 +1077,11 @@ class SamAgentComponent(ComponentBase):
|
|
|
1082
1077
|
cfg_tool_type in ["builtin", "mcp"]
|
|
1083
1078
|
and cfg_tool_name == func_decl_name
|
|
1084
1079
|
):
|
|
1085
|
-
feature_descriptor["tool_metadata"][
|
|
1086
|
-
"tool_type"
|
|
1087
|
-
] = cfg_tool_type
|
|
1088
1080
|
feature_descriptor["tool_metadata"][
|
|
1089
1081
|
"tool_config"
|
|
1090
1082
|
] = tool_cfg
|
|
1091
|
-
tool_source_for_log = f"Explicitly configured tool ({cfg_tool_type}: {cfg_tool_name or cfg_func_name})"
|
|
1092
|
-
tool_matched_for_capability_lookup = True
|
|
1093
1083
|
break
|
|
1094
1084
|
|
|
1095
|
-
if not tool_matched_for_capability_lookup:
|
|
1096
|
-
log.debug(
|
|
1097
|
-
"%s FunctionDeclaration '%s' not found in any known configuration for capability checking. Assuming feature is available.",
|
|
1098
|
-
log_id_prefix,
|
|
1099
|
-
func_decl_name,
|
|
1100
|
-
)
|
|
1101
|
-
tool_source_for_log = "Unmatched/Implicit FunctionDeclaration"
|
|
1102
|
-
|
|
1103
1085
|
context = {
|
|
1104
1086
|
"agent_context": self.get_agent_context(),
|
|
1105
1087
|
"filter_phase": "pre_llm",
|
|
@@ -1116,14 +1098,14 @@ class SamAgentComponent(ComponentBase):
|
|
|
1116
1098
|
"%s FunctionDeclaration '%s' (Source: %s) permitted.",
|
|
1117
1099
|
log_id_prefix,
|
|
1118
1100
|
func_decl_name,
|
|
1119
|
-
|
|
1101
|
+
origin,
|
|
1120
1102
|
)
|
|
1121
1103
|
else:
|
|
1122
1104
|
log.info(
|
|
1123
1105
|
"%s FunctionDeclaration '%s' (Source: %s) FILTERED OUT due to configuration restrictions.",
|
|
1124
1106
|
log_id_prefix,
|
|
1125
1107
|
func_decl_name,
|
|
1126
|
-
|
|
1108
|
+
origin,
|
|
1127
1109
|
)
|
|
1128
1110
|
|
|
1129
1111
|
if permitted_declarations_for_this_tool:
|
|
@@ -1132,7 +1114,7 @@ class SamAgentComponent(ComponentBase):
|
|
|
1132
1114
|
|
|
1133
1115
|
final_filtered_genai_tools.append(scoped_tool)
|
|
1134
1116
|
log.debug(
|
|
1135
|
-
"%s Keeping genai.Tool
|
|
1117
|
+
"%s Keeping genai.Tool as it has %d permitted FunctionDeclaration(s).",
|
|
1136
1118
|
log_id_prefix,
|
|
1137
1119
|
len(permitted_declarations_for_this_tool),
|
|
1138
1120
|
)
|
|
@@ -1169,60 +1151,6 @@ class SamAgentComponent(ComponentBase):
|
|
|
1169
1151
|
|
|
1170
1152
|
return None
|
|
1171
1153
|
|
|
1172
|
-
def _determine_tool_source(self, function_name: str) -> str:
|
|
1173
|
-
"""Determine the source/type of a tool function."""
|
|
1174
|
-
if function_name.startswith("peer_"):
|
|
1175
|
-
return "peer_agent"
|
|
1176
|
-
|
|
1177
|
-
tool_def = tool_registry.get_tool_by_name(function_name)
|
|
1178
|
-
if tool_def:
|
|
1179
|
-
category_map = {
|
|
1180
|
-
"artifact_management": "builtin_artifact",
|
|
1181
|
-
"data_analysis": "builtin_data",
|
|
1182
|
-
}
|
|
1183
|
-
return category_map.get(tool_def.category, "builtin_other")
|
|
1184
|
-
|
|
1185
|
-
return "explicit_tool"
|
|
1186
|
-
|
|
1187
|
-
def _get_tool_metadata(self, function_name: str) -> Dict[str, Any]:
|
|
1188
|
-
"""Get metadata for a tool function."""
|
|
1189
|
-
metadata = {"function_name": function_name}
|
|
1190
|
-
|
|
1191
|
-
if function_name.startswith("peer_"):
|
|
1192
|
-
peer_name = function_name.replace("peer_", "", 1)
|
|
1193
|
-
metadata.update(
|
|
1194
|
-
{"peer_agent_name": peer_name, "operation_type": "delegation"}
|
|
1195
|
-
)
|
|
1196
|
-
return metadata
|
|
1197
|
-
|
|
1198
|
-
tool_def = tool_registry.get_tool_by_name(function_name)
|
|
1199
|
-
if tool_def:
|
|
1200
|
-
metadata.update(
|
|
1201
|
-
{
|
|
1202
|
-
"tool_category": tool_def.category,
|
|
1203
|
-
"required_scopes": tool_def.required_scopes,
|
|
1204
|
-
"builtin_tool": True,
|
|
1205
|
-
}
|
|
1206
|
-
)
|
|
1207
|
-
return metadata
|
|
1208
|
-
|
|
1209
|
-
explicit_tools_config = self.get_config("tools", [])
|
|
1210
|
-
for tool_cfg in explicit_tools_config:
|
|
1211
|
-
cfg_tool_name = tool_cfg.get("tool_name")
|
|
1212
|
-
cfg_func_name = tool_cfg.get("function_name")
|
|
1213
|
-
if (
|
|
1214
|
-
tool_cfg.get("tool_type") == "python" and cfg_func_name == function_name
|
|
1215
|
-
) or (
|
|
1216
|
-
tool_cfg.get("tool_type") in ["builtin", "mcp"]
|
|
1217
|
-
and cfg_tool_name == function_name
|
|
1218
|
-
):
|
|
1219
|
-
metadata.update(
|
|
1220
|
-
{"tool_type": tool_cfg.get("tool_type"), "tool_config": tool_cfg}
|
|
1221
|
-
)
|
|
1222
|
-
break
|
|
1223
|
-
|
|
1224
|
-
return metadata
|
|
1225
|
-
|
|
1226
1154
|
def get_agent_context(self) -> Dict[str, Any]:
|
|
1227
1155
|
"""Get agent context for middleware calls."""
|
|
1228
1156
|
return {
|