solace-agent-mesh 1.0.9__py3-none-any.whl → 1.3.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.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
- solace_agent_mesh/agent/adk/callbacks.py +165 -104
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
- solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
- solace_agent_mesh/agent/adk/runner.py +25 -17
- solace_agent_mesh/agent/adk/services.py +3 -3
- solace_agent_mesh/agent/adk/setup.py +11 -0
- solace_agent_mesh/agent/adk/stream_parser.py +8 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
- solace_agent_mesh/agent/agent_llm.txt +355 -18
- solace_agent_mesh/agent/protocol/event_handlers.py +460 -317
- solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
- solace_agent_mesh/agent/sac/app.py +2 -2
- solace_agent_mesh/agent/sac/component.py +211 -517
- solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
- solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
- solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
- solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
- solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
- solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.08d30374.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
- 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 +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +105 -0
- solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
- 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 +4 -4
- 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 +4 -4
- 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 +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
- 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 +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
- 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 +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
- 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 +4 -4
- 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-1757433031159.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1757433031159.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/agent_cmd.py +125 -48
- solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
- solace_agent_mesh/cli/commands/run_cmd.py +5 -3
- solace_agent_mesh/cli/utils.py +68 -12
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-vY5eu2lI.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-BeBkzgWW.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bjys1KQs.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CE0AeXyK.js +395 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
- solace_agent_mesh/common/a2a/__init__.py +213 -0
- solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
- solace_agent_mesh/common/a2a/artifact.py +328 -0
- solace_agent_mesh/common/a2a/events.py +183 -0
- solace_agent_mesh/common/a2a/message.py +307 -0
- solace_agent_mesh/common/a2a/protocol.py +513 -0
- solace_agent_mesh/common/a2a/task.py +127 -0
- solace_agent_mesh/common/a2a/translation.py +653 -0
- solace_agent_mesh/common/a2a/types.py +54 -0
- solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
- solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
- solace_agent_mesh/common/agent_registry.py +1 -1
- solace_agent_mesh/common/common_llm.txt +192 -70
- solace_agent_mesh/common/data_parts.py +99 -0
- solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
- solace_agent_mesh/common/sac/__init__.py +0 -0
- solace_agent_mesh/common/sac/sac_llm.txt +71 -0
- solace_agent_mesh/common/sac/sam_component_base.py +252 -0
- solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
- solace_agent_mesh/common/services/services_llm.txt +206 -26
- solace_agent_mesh/common/utils/artifact_utils.py +29 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
- solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
- solace_agent_mesh/common/utils/utils_llm.txt +323 -42
- solace_agent_mesh/config_portal/backend/common.py +2 -2
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
- solace_agent_mesh/core_a2a/service.py +20 -44
- solace_agent_mesh/evaluation/message_organizer.py +35 -56
- solace_agent_mesh/evaluation/run.py +26 -5
- solace_agent_mesh/evaluation/subscriber.py +35 -10
- solace_agent_mesh/evaluation/summary_builder.py +27 -34
- solace_agent_mesh/gateway/base/app.py +27 -1
- solace_agent_mesh/gateway/base/base_llm.txt +177 -72
- solace_agent_mesh/gateway/base/component.py +294 -523
- solace_agent_mesh/gateway/gateway_llm.txt +299 -58
- solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
- solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
- solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
- solace_agent_mesh/gateway/http_sse/app.py +31 -1
- solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
- solace_agent_mesh/gateway/http_sse/component.py +371 -236
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
- solace_agent_mesh/gateway/http_sse/dependencies.py +142 -39
- solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
- solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
- solace_agent_mesh/gateway/http_sse/main.py +293 -91
- solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +137 -56
- solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +199 -171
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
- solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
- solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
- solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
- solace_agent_mesh/templates/gateway_component_template.py +149 -98
- solace_agent_mesh/templates/shared_config.yaml +4 -5
- solace_agent_mesh/templates/webui.yaml +8 -10
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/METADATA +9 -6
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/RECORD +197 -141
- solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.3d0e7879.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.05d19492.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1757091012487.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1757091012487.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
- solace_agent_mesh/client/webui/frontend/static/assets/main-D0FnP_W4.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-Do32sFPX.js +0 -708
- solace_agent_mesh/common/a2a_protocol.py +0 -564
- solace_agent_mesh/common/client/__init__.py +0 -4
- solace_agent_mesh/common/client/card_resolver.py +0 -21
- solace_agent_mesh/common/client/client.py +0 -85
- solace_agent_mesh/common/client/client_llm.txt +0 -133
- solace_agent_mesh/common/server/__init__.py +0 -4
- solace_agent_mesh/common/server/server.py +0 -122
- solace_agent_mesh/common/server/server_llm.txt +0 -169
- solace_agent_mesh/common/server/task_manager.py +0 -291
- solace_agent_mesh/common/server/utils.py +0 -28
- solace_agent_mesh/common/types.py +0 -411
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -80
- solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
- /solace_agent_mesh/assets/docs/assets/js/{main.3d0e7879.js.LICENSE.txt → main.08d30374.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,7 @@ Manages the asynchronous execution of the ADK Runner.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import uuid
|
|
6
7
|
from google.adk.agents.invocation_context import LlmCallsLimitExceededError
|
|
7
8
|
|
|
8
9
|
|
|
@@ -22,7 +23,7 @@ from google.genai import types as adk_types
|
|
|
22
23
|
from google.adk.events import Event as ADKEvent
|
|
23
24
|
from google.adk.events.event_actions import EventActions
|
|
24
25
|
|
|
25
|
-
from ...common
|
|
26
|
+
from ...common import a2a
|
|
26
27
|
|
|
27
28
|
if TYPE_CHECKING:
|
|
28
29
|
from ..sac.component import SamAgentComponent
|
|
@@ -72,22 +73,25 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
72
73
|
|
|
73
74
|
if adk_session and component.session_service:
|
|
74
75
|
context_setting_invocation_id = logical_task_id
|
|
75
|
-
|
|
76
|
-
invocation_id=context_setting_invocation_id,
|
|
77
|
-
author="A2A_Host_System",
|
|
78
|
-
content=adk_types.Content(
|
|
79
|
-
parts=[
|
|
80
|
-
adk_types.Part(text="Initializing A2A context for task run.")
|
|
81
|
-
]
|
|
82
|
-
),
|
|
83
|
-
actions=EventActions(state_delta={"a2a_context": a2a_context}),
|
|
84
|
-
branch=None,
|
|
85
|
-
)
|
|
76
|
+
original_message = a2a_context.pop("original_solace_message", None)
|
|
86
77
|
try:
|
|
78
|
+
context_setting_event = ADKEvent(
|
|
79
|
+
invocation_id=context_setting_invocation_id,
|
|
80
|
+
author="A2A_Host_System",
|
|
81
|
+
content=adk_types.Content(
|
|
82
|
+
parts=[
|
|
83
|
+
adk_types.Part(
|
|
84
|
+
text="Initializing A2A context for task run."
|
|
85
|
+
)
|
|
86
|
+
]
|
|
87
|
+
),
|
|
88
|
+
actions=EventActions(state_delta={"a2a_context": a2a_context}),
|
|
89
|
+
branch=None,
|
|
90
|
+
)
|
|
87
91
|
await component.session_service.append_event(
|
|
88
92
|
session=adk_session, event=context_setting_event
|
|
89
93
|
)
|
|
90
|
-
log.
|
|
94
|
+
log.debug(
|
|
91
95
|
"%s Appended context-setting event to ADK session %s (via component.session_service) for task %s.",
|
|
92
96
|
component.log_identifier,
|
|
93
97
|
adk_session.id,
|
|
@@ -95,12 +99,15 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
95
99
|
)
|
|
96
100
|
except Exception as e_append:
|
|
97
101
|
log.error(
|
|
98
|
-
"%s Failed to append context-setting event for task %s: %s.
|
|
102
|
+
"%s Failed to append context-setting event for task %s: %s.",
|
|
99
103
|
component.log_identifier,
|
|
100
104
|
logical_task_id,
|
|
101
105
|
e_append,
|
|
102
106
|
exc_info=True,
|
|
103
107
|
)
|
|
108
|
+
finally:
|
|
109
|
+
if original_message:
|
|
110
|
+
a2a_context["original_solace_message"] = original_message
|
|
104
111
|
else:
|
|
105
112
|
log.warning(
|
|
106
113
|
"%s Could not inject a2a_context into ADK session state via event for task %s (session or session_service invalid). Tool scope filtering might not work.",
|
|
@@ -156,13 +163,14 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
156
163
|
task_id_for_peer = sub_task_id.replace(
|
|
157
164
|
component.CORRELATION_DATA_PREFIX, "", 1
|
|
158
165
|
)
|
|
159
|
-
|
|
160
|
-
|
|
166
|
+
peer_cancel_request = a2a.create_cancel_task_request(
|
|
167
|
+
task_id=task_id_for_peer
|
|
168
|
+
)
|
|
161
169
|
peer_cancel_user_props = {"clientId": component.agent_name}
|
|
162
170
|
peer_request_topic = component._get_agent_request_topic(
|
|
163
171
|
target_peer_agent_name
|
|
164
172
|
)
|
|
165
|
-
component.
|
|
173
|
+
component.publish_a2a_message(
|
|
166
174
|
payload=peer_cancel_request.model_dump(exclude_none=True),
|
|
167
175
|
topic=peer_request_topic,
|
|
168
176
|
user_properties=peer_cancel_user_props,
|
|
@@ -174,11 +174,11 @@ def initialize_session_service(component) -> BaseSessionService:
|
|
|
174
174
|
|
|
175
175
|
if service_type == "memory":
|
|
176
176
|
return InMemorySessionService()
|
|
177
|
-
elif service_type == "
|
|
178
|
-
db_url = config.get("
|
|
177
|
+
elif service_type == "sql":
|
|
178
|
+
db_url = config.get("database_url")
|
|
179
179
|
if not db_url:
|
|
180
180
|
raise ValueError(
|
|
181
|
-
f"{component.log_identifier} '
|
|
181
|
+
f"{component.log_identifier} 'database_url' is required for sql session service."
|
|
182
182
|
)
|
|
183
183
|
try:
|
|
184
184
|
return DatabaseSessionService(db_url=db_url)
|
|
@@ -619,6 +619,10 @@ def initialize_adk_agent(
|
|
|
619
619
|
track_artifacts_cb_with_component = functools.partial(
|
|
620
620
|
adk_callbacks.track_produced_artifacts_callback, host_component=component
|
|
621
621
|
)
|
|
622
|
+
notify_tool_result_cb_with_component = functools.partial(
|
|
623
|
+
adk_callbacks.notify_tool_execution_result_callback,
|
|
624
|
+
host_component=component,
|
|
625
|
+
)
|
|
622
626
|
|
|
623
627
|
async def chained_after_tool_callback(
|
|
624
628
|
tool: BaseTool,
|
|
@@ -634,6 +638,13 @@ def initialize_adk_agent(
|
|
|
634
638
|
)
|
|
635
639
|
|
|
636
640
|
try:
|
|
641
|
+
# First, notify the UI about the raw result.
|
|
642
|
+
# This is a fire-and-forget notification that does not modify the response.
|
|
643
|
+
notify_tool_result_cb_with_component(
|
|
644
|
+
tool, args, tool_context, tool_response
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
# Now, proceed with the existing chain that modifies the response for the LLM.
|
|
637
648
|
processed_by_large_handler = await large_response_cb_with_component(
|
|
638
649
|
tool, args, tool_context, tool_response
|
|
639
650
|
)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
A stateful stream parser for identifying and extracting fenced artifact blocks
|
|
3
3
|
from an LLM's text stream.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import re
|
|
6
7
|
from enum import Enum, auto
|
|
7
8
|
from dataclasses import dataclass, field
|
|
@@ -46,6 +47,7 @@ class BlockProgressedEvent(ParserEvent):
|
|
|
46
47
|
"""Emitted periodically while content is being buffered for a block."""
|
|
47
48
|
|
|
48
49
|
buffered_size: int
|
|
50
|
+
chunk: str
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
@dataclass
|
|
@@ -210,5 +212,10 @@ class FencedBlockStreamParser:
|
|
|
210
212
|
if (
|
|
211
213
|
current_size - self._last_progress_update_size
|
|
212
214
|
) >= self._progress_update_interval:
|
|
213
|
-
|
|
215
|
+
new_chunk = self._artifact_buffer[
|
|
216
|
+
self._last_progress_update_size : current_size
|
|
217
|
+
]
|
|
218
|
+
events.append(
|
|
219
|
+
BlockProgressedEvent(buffered_size=current_size, chunk=new_chunk)
|
|
220
|
+
)
|
|
214
221
|
self._last_progress_update_size = current_size
|
|
@@ -5,7 +5,7 @@ Defines the ADKToolWrapper, a consolidated wrapper for ADK tools.
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import functools
|
|
7
7
|
import inspect
|
|
8
|
-
from typing import Callable, Dict, List, Optional
|
|
8
|
+
from typing import Callable, Dict, List, Optional, Literal
|
|
9
9
|
|
|
10
10
|
from solace_ai_connector.common.log import log
|
|
11
11
|
|
|
@@ -34,14 +34,21 @@ class ADKToolWrapper:
|
|
|
34
34
|
tool_name: str,
|
|
35
35
|
origin: str,
|
|
36
36
|
raw_string_args: Optional[List[str]] = None,
|
|
37
|
+
resolution_type: Literal["early", "all"] = "all",
|
|
37
38
|
):
|
|
38
39
|
self._original_func = original_func
|
|
39
40
|
self._tool_config = tool_config or {}
|
|
40
41
|
self._tool_name = tool_name
|
|
42
|
+
self._resolution_type = resolution_type
|
|
41
43
|
self.origin = origin
|
|
42
44
|
self._raw_string_args = set(raw_string_args) if raw_string_args else set()
|
|
43
45
|
self._is_async = inspect.iscoroutinefunction(original_func)
|
|
44
46
|
|
|
47
|
+
self._types_to_resolve = EARLY_EMBED_TYPES
|
|
48
|
+
|
|
49
|
+
if self._resolution_type == "all":
|
|
50
|
+
self._types_to_resolve = EARLY_EMBED_TYPES.union(LATE_EMBED_TYPES)
|
|
51
|
+
|
|
45
52
|
# Ensure __name__ attribute is always set before functools.update_wrapper
|
|
46
53
|
self.__name__ = tool_name
|
|
47
54
|
|
|
@@ -94,7 +101,7 @@ class ADKToolWrapper:
|
|
|
94
101
|
text=arg,
|
|
95
102
|
context=context_for_embeds,
|
|
96
103
|
resolver_func=evaluate_embed,
|
|
97
|
-
types_to_resolve=
|
|
104
|
+
types_to_resolve=self._types_to_resolve,
|
|
98
105
|
log_identifier=log_identifier,
|
|
99
106
|
config=self._tool_config,
|
|
100
107
|
)
|
|
@@ -115,7 +122,7 @@ class ADKToolWrapper:
|
|
|
115
122
|
text=value,
|
|
116
123
|
context=context_for_embeds,
|
|
117
124
|
resolver_func=evaluate_embed,
|
|
118
|
-
types_to_resolve=
|
|
125
|
+
types_to_resolve=self._types_to_resolve,
|
|
119
126
|
log_identifier=log_identifier,
|
|
120
127
|
config=self._tool_config,
|
|
121
128
|
)
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
# DEVELOPER GUIDE for agent directory
|
|
2
2
|
|
|
3
3
|
## Quick Summary
|
|
4
4
|
The `agent` directory provides a comprehensive framework for hosting Google ADK (Agent Development Kit) agents within the Solace AI Connector ecosystem. It bridges ADK agents with the A2A (Agent-to-Agent) protocol over Solace messaging, enabling distributed agent communication, task delegation, and rich tool functionality.
|
|
5
5
|
|
|
6
6
|
The architecture is modular, consisting of several key components:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
- **`sac/` (Solace AI Connector):** The main entry point, providing the `SamAgentApp` and `SamAgentComponent` to host the agent and manage its lifecycle and communication over the Solace event mesh.
|
|
8
|
+
- **`adk/` (Agent Development Kit):** The core integration layer with Google's ADK. It defines the custom `AppLlmAgent`, manages asynchronous task execution, and provides a rich set of callbacks to augment agent behavior.
|
|
9
|
+
- **`tools/`:** A comprehensive and extensible library of tools available to the agent, covering data analysis, artifact management, web requests, multimedia processing, and inter-agent communication.
|
|
10
|
+
- **`protocol/`:** The underlying implementation of the A2A (Agent-to-Agent) communication protocol, handling message routing and event processing.
|
|
11
|
+
- **`utils/`:** A collection of helper modules for common tasks like artifact management, configuration parsing, and context handling.
|
|
12
|
+
- **`testing/`:** Utilities to aid in debugging and testing custom agent implementations.
|
|
13
13
|
|
|
14
14
|
These components work together to create a robust environment where an ADK agent can be configured with specific instructions and tools, communicate with other agents, and execute complex tasks in a distributed, event-driven manner.
|
|
15
15
|
|
|
16
16
|
## Files and Subdirectories Overview
|
|
17
17
|
- **Direct files:**
|
|
18
|
-
- `__init__.py`:
|
|
18
|
+
- `__init__.py`: Standard Python package initializer that marks the `agent` directory as a Python package
|
|
19
|
+
- `agent_llm.txt`: Documentation file containing comprehensive developer guide content
|
|
19
20
|
- **Subdirectories:**
|
|
20
|
-
- `adk/`: Provides the core integration layer with Google's ADK, including custom agents, services, and callbacks
|
|
21
|
-
- `protocol/`: Implements the A2A protocol event handlers for message routing and agent communication
|
|
22
|
-
- `sac/`: Contains the Solace AI Connector app and component implementations for hosting ADK agents
|
|
23
|
-
- `testing/`: Provides utilities for testing the A2A framework and debugging agent behavior
|
|
24
|
-
- `tools/`: A comprehensive, registry-based tool library for AI agents
|
|
25
|
-
- `utils/`: Contains helper utilities for configuration, context handling, and artifact management
|
|
21
|
+
- `adk/`: Provides the core integration layer with Google's ADK, including custom agents, services, and callbacks
|
|
22
|
+
- `protocol/`: Implements the A2A protocol event handlers for message routing and agent communication
|
|
23
|
+
- `sac/`: Contains the Solace AI Connector app and component implementations for hosting ADK agents
|
|
24
|
+
- `testing/`: Provides utilities for testing the A2A framework and debugging agent behavior
|
|
25
|
+
- `tools/`: A comprehensive, registry-based tool library for AI agents
|
|
26
|
+
- `utils/`: Contains helper utilities for configuration, context handling, and artifact management
|
|
26
27
|
|
|
27
28
|
## Developer API Reference
|
|
28
29
|
|
|
@@ -30,12 +31,348 @@ These components work together to create a robust environment where an ADK agent
|
|
|
30
31
|
|
|
31
32
|
#### __init__.py
|
|
32
33
|
**Purpose:** Standard Python package initializer. It allows the `agent` directory to be treated as a package.
|
|
33
|
-
**Import:** `import agent`
|
|
34
|
+
**Import:** `import solace_agent_mesh.agent`
|
|
34
35
|
|
|
35
|
-
**Classes/Functions/Constants:** [None]
|
|
36
|
+
**Classes/Functions/Constants:** [None - empty file]
|
|
37
|
+
|
|
38
|
+
#### agent_llm.txt
|
|
39
|
+
**Purpose:** Documentation file containing comprehensive developer guide content
|
|
40
|
+
**Import:** Not applicable - this is a documentation file, not a code module
|
|
41
|
+
|
|
42
|
+
**Classes/Functions/Constants:** [None - documentation file]
|
|
36
43
|
|
|
37
44
|
### Subdirectory APIs
|
|
38
45
|
|
|
39
46
|
#### adk/
|
|
40
|
-
**Purpose:** Provides the core integration layer between the Solace AI Connector and Google's ADK
|
|
41
|
-
**Key Exports:** `
|
|
47
|
+
**Purpose:** Provides the core integration layer between the Solace AI Connector and Google's ADK
|
|
48
|
+
**Key Exports:** `AppLlmAgent`, `initialize_adk_agent`, `initialize_adk_runner`, `load_adk_tools`, `FilesystemArtifactService`, `LiteLlm`
|
|
49
|
+
**Import Examples:**
|
|
50
|
+
```python
|
|
51
|
+
from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
|
|
52
|
+
from solace_agent_mesh.agent.adk.app_llm_agent import AppLlmAgent
|
|
53
|
+
from solace_agent_mesh.agent.adk.filesystem_artifact_service import FilesystemArtifactService
|
|
54
|
+
from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
|
|
55
|
+
from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### protocol/
|
|
59
|
+
**Purpose:** Implements the core logic for Agent-to-Agent (A2A) communication protocol
|
|
60
|
+
**Key Exports:** `process_event`, `handle_a2a_request`, `handle_agent_card_message`, `publish_agent_card`
|
|
61
|
+
**Import Examples:**
|
|
62
|
+
```python
|
|
63
|
+
from solace_agent_mesh.agent.protocol.event_handlers import process_event, publish_agent_card
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### sac/
|
|
67
|
+
**Purpose:** Provides the Solace AI Connector app and component implementations for hosting ADK agents
|
|
68
|
+
**Key Exports:** `SamAgentApp`, `SamAgentComponent`, `TaskExecutionContext`
|
|
69
|
+
**Import Examples:**
|
|
70
|
+
```python
|
|
71
|
+
from solace_agent_mesh.agent.sac.app import SamAgentApp
|
|
72
|
+
from solace_agent_mesh.agent.sac.component import SamAgentComponent
|
|
73
|
+
from solace_agent_mesh.agent.sac.task_execution_context import TaskExecutionContext
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### testing/
|
|
77
|
+
**Purpose:** Provides utilities for testing the A2A framework and debugging agent behavior
|
|
78
|
+
**Key Exports:** `pretty_print_event_history`
|
|
79
|
+
**Import Examples:**
|
|
80
|
+
```python
|
|
81
|
+
from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### tools/
|
|
85
|
+
**Purpose:** A comprehensive, registry-based tool library for AI agents
|
|
86
|
+
**Key Exports:** `tool_registry`, `BuiltinTool`, `PeerAgentTool`, and various tool functions
|
|
87
|
+
**Import Examples:**
|
|
88
|
+
```python
|
|
89
|
+
from solace_agent_mesh.agent.tools.registry import tool_registry
|
|
90
|
+
from solace_agent_mesh.agent.tools.peer_agent_tool import PeerAgentTool
|
|
91
|
+
from solace_agent_mesh.agent.tools.audio_tools import text_to_speech
|
|
92
|
+
from solace_agent_mesh.agent.tools.builtin_artifact_tools import list_artifacts, load_artifact
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### utils/
|
|
96
|
+
**Purpose:** Contains helper utilities for configuration, context handling, and artifact management
|
|
97
|
+
**Key Exports:** `save_artifact_with_metadata`, `load_artifact_content_or_metadata`, `resolve_instruction_provider`
|
|
98
|
+
**Import Examples:**
|
|
99
|
+
```python
|
|
100
|
+
from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata, load_artifact_content_or_metadata
|
|
101
|
+
from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider
|
|
102
|
+
from solace_agent_mesh.agent.utils.context_helpers import get_session_from_callback_context
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Complete Usage Guide
|
|
106
|
+
|
|
107
|
+
### 1. Basic Agent Setup and Configuration
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
# Import the main SAC components
|
|
111
|
+
from solace_agent_mesh.agent.sac.app import SamAgentApp
|
|
112
|
+
from solace_agent_mesh.agent.sac.component import SamAgentComponent
|
|
113
|
+
|
|
114
|
+
# The agent is typically configured via YAML and instantiated by the SAC framework
|
|
115
|
+
# Example agent-config.yaml:
|
|
116
|
+
"""
|
|
117
|
+
app:
|
|
118
|
+
class_name: solace_agent_mesh.agent.sac.app.SamAgentApp
|
|
119
|
+
app_config:
|
|
120
|
+
namespace: "my-org/production"
|
|
121
|
+
agent_name: "customer-support-agent"
|
|
122
|
+
model: "gemini-1.5-pro-latest"
|
|
123
|
+
tools:
|
|
124
|
+
- tool_type: "builtin"
|
|
125
|
+
tool_name: "text_to_speech"
|
|
126
|
+
- tool_type: "builtin"
|
|
127
|
+
tool_name: "list_artifacts"
|
|
128
|
+
agent_card:
|
|
129
|
+
description: "An agent that can answer questions about customer accounts."
|
|
130
|
+
session_service:
|
|
131
|
+
type: "memory"
|
|
132
|
+
artifact_service:
|
|
133
|
+
type: "filesystem"
|
|
134
|
+
base_path: "/tmp/artifacts"
|
|
135
|
+
"""
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 2. Working with ADK Components
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
|
|
142
|
+
from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service
|
|
143
|
+
from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
|
|
144
|
+
|
|
145
|
+
async def setup_adk_agent(component):
|
|
146
|
+
# Initialize services
|
|
147
|
+
session_service = initialize_session_service(component)
|
|
148
|
+
artifact_service = initialize_artifact_service(component)
|
|
149
|
+
|
|
150
|
+
# Load tools
|
|
151
|
+
loaded_tools, builtin_tools = await load_adk_tools(component)
|
|
152
|
+
|
|
153
|
+
# Initialize agent with LLM
|
|
154
|
+
agent = initialize_adk_agent(component, loaded_tools, builtin_tools)
|
|
155
|
+
|
|
156
|
+
# Initialize runner
|
|
157
|
+
runner = initialize_adk_runner(component)
|
|
158
|
+
|
|
159
|
+
return agent, runner
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 3. Custom Tool Development
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from solace_agent_mesh.agent.tools.registry import tool_registry
|
|
166
|
+
from solace_agent_mesh.agent.tools.tool_definition import BuiltinTool
|
|
167
|
+
from google.adk.tools import ToolContext
|
|
168
|
+
|
|
169
|
+
# Define a custom tool function
|
|
170
|
+
async def my_custom_tool(
|
|
171
|
+
query: str,
|
|
172
|
+
tool_context: ToolContext = None,
|
|
173
|
+
tool_config: dict = None
|
|
174
|
+
) -> dict:
|
|
175
|
+
"""A custom tool that processes queries."""
|
|
176
|
+
# Access the host component
|
|
177
|
+
host_component = tool_context._invocation_context.agent.host_component
|
|
178
|
+
|
|
179
|
+
# Use agent state
|
|
180
|
+
db_connection = host_component.get_agent_specific_state('db_connection')
|
|
181
|
+
|
|
182
|
+
# Process the query
|
|
183
|
+
result = await process_query(query, db_connection)
|
|
184
|
+
|
|
185
|
+
return {"result": result, "status": "success"}
|
|
186
|
+
|
|
187
|
+
# Register the tool
|
|
188
|
+
custom_tool = BuiltinTool(
|
|
189
|
+
name="my_custom_tool",
|
|
190
|
+
description="Processes custom queries",
|
|
191
|
+
function=my_custom_tool,
|
|
192
|
+
category="custom"
|
|
193
|
+
)
|
|
194
|
+
tool_registry.register(custom_tool)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 4. Artifact Management
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
from solace_agent_mesh.agent.utils.artifact_helpers import (
|
|
201
|
+
save_artifact_with_metadata,
|
|
202
|
+
load_artifact_content_or_metadata,
|
|
203
|
+
get_artifact_info_list
|
|
204
|
+
)
|
|
205
|
+
from datetime import datetime, timezone
|
|
206
|
+
|
|
207
|
+
async def artifact_operations(component, artifact_service):
|
|
208
|
+
# Save an artifact with metadata
|
|
209
|
+
content = b"Hello, world!"
|
|
210
|
+
result = await save_artifact_with_metadata(
|
|
211
|
+
artifact_service=artifact_service,
|
|
212
|
+
app_name=component.get_config()["app_name"],
|
|
213
|
+
user_id="user123",
|
|
214
|
+
session_id="session456",
|
|
215
|
+
filename="greeting.txt",
|
|
216
|
+
content_bytes=content,
|
|
217
|
+
mime_type="text/plain",
|
|
218
|
+
metadata_dict={"source": "custom_tool", "description": "A greeting"},
|
|
219
|
+
timestamp=datetime.now(timezone.utc)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Load the artifact
|
|
223
|
+
loaded = await load_artifact_content_or_metadata(
|
|
224
|
+
artifact_service=artifact_service,
|
|
225
|
+
app_name=component.get_config()["app_name"],
|
|
226
|
+
user_id="user123",
|
|
227
|
+
session_id="session456",
|
|
228
|
+
filename="greeting.txt",
|
|
229
|
+
version="latest"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# List all artifacts
|
|
233
|
+
artifacts = await get_artifact_info_list(
|
|
234
|
+
artifact_service=artifact_service,
|
|
235
|
+
app_name=component.get_config()["app_name"],
|
|
236
|
+
user_id="user123",
|
|
237
|
+
session_id="session456"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
return artifacts
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 5. Inter-Agent Communication
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
from solace_agent_mesh.agent.tools.peer_agent_tool import PeerAgentTool
|
|
247
|
+
|
|
248
|
+
# Create a peer agent tool (typically done automatically by the framework)
|
|
249
|
+
peer_tool = PeerAgentTool("data_analyst_agent", host_component)
|
|
250
|
+
|
|
251
|
+
# The LLM can then use this tool to delegate tasks:
|
|
252
|
+
# "Please use the data_analyst_agent to analyze the sales data in report.csv"
|
|
253
|
+
|
|
254
|
+
# The framework handles the A2A protocol communication automatically
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 6. Audio and Multimedia Tools
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
from solace_agent_mesh.agent.tools.audio_tools import text_to_speech, multi_speaker_text_to_speech
|
|
261
|
+
from solace_agent_mesh.agent.tools.image_tools import create_image_from_description, describe_image
|
|
262
|
+
|
|
263
|
+
async def multimedia_example(tool_context):
|
|
264
|
+
# Generate speech from text
|
|
265
|
+
tts_result = await text_to_speech(
|
|
266
|
+
text="Welcome to our service!",
|
|
267
|
+
output_filename="welcome.mp3",
|
|
268
|
+
gender="female",
|
|
269
|
+
tone="friendly",
|
|
270
|
+
tool_context=tool_context
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
# Create a multi-speaker conversation
|
|
274
|
+
conversation_result = await multi_speaker_text_to_speech(
|
|
275
|
+
conversation_text="Alice: Hello there!\nBob: Hi Alice, how are you?",
|
|
276
|
+
speaker_configs=[
|
|
277
|
+
{"name": "Alice", "gender": "female", "tone": "bright"},
|
|
278
|
+
{"name": "Bob", "gender": "male", "tone": "warm"}
|
|
279
|
+
],
|
|
280
|
+
tool_context=tool_context
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
# Generate an image
|
|
284
|
+
image_result = await create_image_from_description(
|
|
285
|
+
image_description="A futuristic cityscape at sunset",
|
|
286
|
+
output_filename="cityscape.png",
|
|
287
|
+
tool_context=tool_context
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
return tts_result, conversation_result, image_result
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### 7. Testing and Debugging
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history
|
|
297
|
+
from solace_agent_mesh.agent.adk.invocation_monitor import InvocationMonitor
|
|
298
|
+
|
|
299
|
+
# Debug event history in tests
|
|
300
|
+
def test_agent_behavior():
|
|
301
|
+
event_history = [
|
|
302
|
+
{"result": {"status": {"state": "EXECUTING"}}},
|
|
303
|
+
{"result": {"status": {"state": "COMPLETED"}}}
|
|
304
|
+
]
|
|
305
|
+
|
|
306
|
+
# Print formatted event history for debugging
|
|
307
|
+
pretty_print_event_history(event_history)
|
|
308
|
+
|
|
309
|
+
# Monitor agent invocations
|
|
310
|
+
monitor = InvocationMonitor()
|
|
311
|
+
monitor.log_message_event("incoming", "agent/request", {"task": "analyze data"})
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 8. Configuration and Context Handling
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider
|
|
318
|
+
from solace_agent_mesh.agent.utils.context_helpers import get_session_from_callback_context
|
|
319
|
+
|
|
320
|
+
# Resolve dynamic instructions
|
|
321
|
+
def setup_agent_instructions(component):
|
|
322
|
+
# Static instruction
|
|
323
|
+
static_instruction = resolve_instruction_provider(
|
|
324
|
+
component,
|
|
325
|
+
"You are a helpful customer service agent."
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
# Dynamic instruction function
|
|
329
|
+
def dynamic_instruction(context):
|
|
330
|
+
return f"You are assisting user {context.user_id} in session {context.session_id}"
|
|
331
|
+
|
|
332
|
+
dynamic_provider = resolve_instruction_provider(component, dynamic_instruction)
|
|
333
|
+
|
|
334
|
+
return static_instruction, dynamic_provider
|
|
335
|
+
|
|
336
|
+
# Safe context extraction in tools
|
|
337
|
+
def my_tool_with_context(tool_context):
|
|
338
|
+
session = get_session_from_callback_context(tool_context)
|
|
339
|
+
original_session_id = get_original_session_id(tool_context._invocation_context)
|
|
340
|
+
|
|
341
|
+
return {"session_id": original_session_id, "session_data": session}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### 9. Complete Agent Implementation Example
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
from solace_agent_mesh.agent.sac.app import SamAgentApp
|
|
348
|
+
from solace_agent_mesh.agent.sac.component import SamAgentComponent
|
|
349
|
+
from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
|
|
350
|
+
from solace_agent_mesh.agent.tools.registry import tool_registry
|
|
351
|
+
from solace_agent_mesh.agent.tools.tool_definition import BuiltinTool
|
|
352
|
+
|
|
353
|
+
# Custom initialization function
|
|
354
|
+
def initialize_my_agent(host_component: SamAgentComponent, config: dict):
|
|
355
|
+
"""Custom initialization function for the agent."""
|
|
356
|
+
# Store custom state
|
|
357
|
+
host_component.set_agent_specific_state('custom_data', config.get('custom_data'))
|
|
358
|
+
|
|
359
|
+
# Set dynamic system instruction
|
|
360
|
+
def dynamic_instruction(context):
|
|
361
|
+
return f"You are a specialized agent for user {context.user_id}"
|
|
362
|
+
|
|
363
|
+
host_component.set_agent_system_instruction_callback(dynamic_instruction)
|
|
364
|
+
|
|
365
|
+
# Custom tool
|
|
366
|
+
async def my_business_tool(
|
|
367
|
+
query: str,
|
|
368
|
+
tool_context = None,
|
|
369
|
+
tool_config: dict = None
|
|
370
|
+
) -> dict:
|
|
371
|
+
"""Custom business logic tool."""
|
|
372
|
+
host_component = tool_context._invocation_context.agent.host_component
|
|
373
|
+
custom_data = host_component.get_agent_specific_state('custom_data')
|
|
374
|
+
|
|
375
|
+
# Process business logic
|
|
376
|
+
result =
|
|
377
|
+
|
|
378
|
+
# content_hash: 7e177b117b6361dbdd3eaeaa246c2173ac9cfaada01eb78219f2b8cd8b13d816
|