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
|
@@ -7,11 +7,11 @@ import asyncio
|
|
|
7
7
|
import functools
|
|
8
8
|
import threading
|
|
9
9
|
import concurrent.futures
|
|
10
|
+
import uuid
|
|
10
11
|
import fnmatch
|
|
11
12
|
import base64
|
|
12
13
|
from datetime import datetime, timezone
|
|
13
14
|
import json
|
|
14
|
-
from solace_ai_connector.components.component_base import ComponentBase
|
|
15
15
|
from solace_ai_connector.common.message import (
|
|
16
16
|
Message as SolaceMessage,
|
|
17
17
|
)
|
|
@@ -37,39 +37,20 @@ from google.adk.agents.callback_context import CallbackContext
|
|
|
37
37
|
from google.adk.models.llm_request import LlmRequest
|
|
38
38
|
from google.genai import types as adk_types
|
|
39
39
|
from google.adk.tools.mcp_tool import MCPToolset
|
|
40
|
-
from
|
|
40
|
+
from a2a.types import (
|
|
41
41
|
AgentCard,
|
|
42
|
-
Task,
|
|
43
|
-
TaskStatus,
|
|
44
|
-
TaskState,
|
|
45
|
-
Message as A2AMessage,
|
|
46
|
-
TextPart,
|
|
47
|
-
FilePart,
|
|
48
|
-
DataPart,
|
|
49
|
-
FileContent,
|
|
50
42
|
Artifact as A2AArtifact,
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
Message as A2AMessage,
|
|
44
|
+
MessageSendParams,
|
|
45
|
+
SendMessageRequest,
|
|
46
|
+
TaskState,
|
|
47
|
+
TaskStatus,
|
|
53
48
|
TaskStatusUpdateEvent,
|
|
54
|
-
TaskArtifactUpdateEvent,
|
|
55
|
-
SendTaskRequest,
|
|
56
|
-
CancelTaskRequest,
|
|
57
|
-
TaskIdParams,
|
|
58
|
-
)
|
|
59
|
-
from ...common.a2a_protocol import (
|
|
60
|
-
get_a2a_base_topic,
|
|
61
|
-
get_discovery_topic,
|
|
62
|
-
get_agent_request_topic,
|
|
63
|
-
get_agent_response_topic,
|
|
64
|
-
get_client_response_topic,
|
|
65
|
-
get_peer_agent_status_topic,
|
|
66
|
-
format_and_route_adk_event,
|
|
67
|
-
get_gateway_status_topic,
|
|
68
49
|
)
|
|
50
|
+
from ...common import a2a
|
|
51
|
+
from ...common.data_parts import AgentProgressUpdateData
|
|
52
|
+
from ...common.a2a.translation import format_and_route_adk_event
|
|
69
53
|
from ...agent.utils.config_parser import resolve_instruction_provider
|
|
70
|
-
from ...agent.utils.artifact_helpers import (
|
|
71
|
-
get_latest_artifact_version,
|
|
72
|
-
)
|
|
73
54
|
from ...agent.adk.services import (
|
|
74
55
|
initialize_session_service,
|
|
75
56
|
initialize_artifact_service,
|
|
@@ -94,8 +75,7 @@ from ...agent.adk.invocation_monitor import InvocationMonitor
|
|
|
94
75
|
from ...common.middleware.registry import MiddlewareRegistry
|
|
95
76
|
from ...common.constants import DEFAULT_COMMUNICATION_TIMEOUT
|
|
96
77
|
from ...agent.tools.registry import tool_registry
|
|
97
|
-
from ...common.
|
|
98
|
-
from ...common.exceptions import MessageSizeExceededError
|
|
78
|
+
from ...common.sac.sam_component_base import SamComponentBase
|
|
99
79
|
|
|
100
80
|
if TYPE_CHECKING:
|
|
101
81
|
from .task_execution_context import TaskExecutionContext
|
|
@@ -123,7 +103,7 @@ info = {
|
|
|
123
103
|
InstructionProvider = Callable[[ReadonlyContext], str]
|
|
124
104
|
|
|
125
105
|
|
|
126
|
-
class SamAgentComponent(
|
|
106
|
+
class SamAgentComponent(SamComponentBase):
|
|
127
107
|
"""
|
|
128
108
|
A Solace AI Connector component that hosts a Google ADK agent,
|
|
129
109
|
communicating via the A2A protocol over Solace.
|
|
@@ -257,8 +237,6 @@ class SamAgentComponent(ComponentBase):
|
|
|
257
237
|
self.agent_card_tool_manifest: List[Dict[str, Any]] = []
|
|
258
238
|
self.peer_agents: Dict[str, Any] = {}
|
|
259
239
|
self._card_publish_timer_id: str = f"publish_card_{self.agent_name}"
|
|
260
|
-
self._async_loop = None
|
|
261
|
-
self._async_thread = None
|
|
262
240
|
self._async_init_future = None
|
|
263
241
|
self.peer_response_queues: Dict[str, asyncio.Queue] = {}
|
|
264
242
|
self.peer_response_queue_lock = threading.Lock()
|
|
@@ -416,40 +394,11 @@ class SamAgentComponent(ComponentBase):
|
|
|
416
394
|
raise RuntimeError(
|
|
417
395
|
f"Failed to initialize synchronous ADK services: {service_err}"
|
|
418
396
|
) from service_err
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
)
|
|
423
|
-
self._async_loop = asyncio.new_event_loop()
|
|
397
|
+
|
|
398
|
+
# Async init is now handled by the base class `run` method.
|
|
399
|
+
# We still need a future to signal completion from the async thread.
|
|
424
400
|
self._async_init_future = concurrent.futures.Future()
|
|
425
|
-
|
|
426
|
-
target=self._start_async_loop, daemon=True
|
|
427
|
-
)
|
|
428
|
-
self._async_thread.start()
|
|
429
|
-
init_coro_future = asyncio.run_coroutine_threadsafe(
|
|
430
|
-
self._perform_async_init(), self._async_loop
|
|
431
|
-
)
|
|
432
|
-
log.info(
|
|
433
|
-
"%s Waiting for async initialization to complete...",
|
|
434
|
-
self.log_identifier,
|
|
435
|
-
)
|
|
436
|
-
try:
|
|
437
|
-
init_coro_future.result(timeout=60)
|
|
438
|
-
self._async_init_future.result(timeout=1)
|
|
439
|
-
log.info(
|
|
440
|
-
"%s Async initialization completed successfully.",
|
|
441
|
-
self.log_identifier,
|
|
442
|
-
)
|
|
443
|
-
except Exception as init_err:
|
|
444
|
-
log.error(
|
|
445
|
-
"%s Async initialization failed during __init__: %s",
|
|
446
|
-
self.log_identifier,
|
|
447
|
-
init_err,
|
|
448
|
-
)
|
|
449
|
-
self.cleanup()
|
|
450
|
-
raise RuntimeError(
|
|
451
|
-
f"Failed to initialize component asynchronously: {init_err}"
|
|
452
|
-
) from init_err
|
|
401
|
+
|
|
453
402
|
publish_interval_sec = self.agent_card_publishing_config.get(
|
|
454
403
|
"interval_seconds"
|
|
455
404
|
)
|
|
@@ -798,11 +747,12 @@ class SamAgentComponent(ComponentBase):
|
|
|
798
747
|
sub_task_id,
|
|
799
748
|
)
|
|
800
749
|
task_id_for_peer = sub_task_id.replace(CORRELATION_DATA_PREFIX, "", 1)
|
|
801
|
-
|
|
802
|
-
|
|
750
|
+
cancel_request = a2a.create_cancel_task_request(
|
|
751
|
+
task_id=task_id_for_peer
|
|
752
|
+
)
|
|
803
753
|
user_props = {"clientId": self.agent_name}
|
|
804
754
|
peer_topic = self._get_agent_request_topic(peer_agent_name)
|
|
805
|
-
self.
|
|
755
|
+
self.publish_a2a_message(
|
|
806
756
|
payload=cancel_request.model_dump(exclude_none=True),
|
|
807
757
|
topic=peer_topic,
|
|
808
758
|
user_properties=user_props,
|
|
@@ -1286,17 +1236,17 @@ class SamAgentComponent(ComponentBase):
|
|
|
1286
1236
|
return
|
|
1287
1237
|
|
|
1288
1238
|
try:
|
|
1289
|
-
a2a_message =
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
timestamp=datetime.now(timezone.utc),
|
|
1239
|
+
a2a_message = a2a.create_agent_text_message(
|
|
1240
|
+
text=text_content,
|
|
1241
|
+
task_id=logical_task_id,
|
|
1242
|
+
context_id=a2a_context.get("contextId"),
|
|
1294
1243
|
)
|
|
1295
1244
|
event_metadata = {"agent_name": self.agent_name}
|
|
1296
|
-
status_update_event =
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1245
|
+
status_update_event = a2a.create_status_update(
|
|
1246
|
+
task_id=logical_task_id,
|
|
1247
|
+
context_id=a2a_context.get("contextId"),
|
|
1248
|
+
message=a2a_message,
|
|
1249
|
+
is_final=is_stream_terminating_content,
|
|
1300
1250
|
metadata=event_metadata,
|
|
1301
1251
|
)
|
|
1302
1252
|
|
|
@@ -1339,25 +1289,13 @@ class SamAgentComponent(ComponentBase):
|
|
|
1339
1289
|
return
|
|
1340
1290
|
|
|
1341
1291
|
try:
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
a2a_message = A2AMessage(role="agent", parts=[signal_data_part])
|
|
1350
|
-
task_status = TaskStatus(
|
|
1351
|
-
state=TaskState.WORKING,
|
|
1352
|
-
message=a2a_message,
|
|
1353
|
-
timestamp=datetime.now(timezone.utc),
|
|
1354
|
-
)
|
|
1355
|
-
event_metadata = {"agent_name": self.agent_name}
|
|
1356
|
-
status_update_event = TaskStatusUpdateEvent(
|
|
1357
|
-
id=logical_task_id,
|
|
1358
|
-
status=task_status,
|
|
1359
|
-
final=False,
|
|
1360
|
-
metadata=event_metadata,
|
|
1292
|
+
progress_data = AgentProgressUpdateData(status_text=status_text)
|
|
1293
|
+
status_update_event = a2a.create_data_signal_event(
|
|
1294
|
+
task_id=logical_task_id,
|
|
1295
|
+
context_id=a2a_context.get("contextId"),
|
|
1296
|
+
signal_data=progress_data,
|
|
1297
|
+
agent_name=self.agent_name,
|
|
1298
|
+
part_metadata={"source_embed_type": "status_update"},
|
|
1361
1299
|
)
|
|
1362
1300
|
|
|
1363
1301
|
await self._publish_status_update_with_buffer_flush(
|
|
@@ -1514,16 +1452,27 @@ class SamAgentComponent(ComponentBase):
|
|
|
1514
1452
|
)
|
|
1515
1453
|
|
|
1516
1454
|
try:
|
|
1517
|
-
rpc_response =
|
|
1518
|
-
|
|
1455
|
+
rpc_response = a2a.create_success_response(
|
|
1456
|
+
result=status_update_event, request_id=jsonrpc_request_id
|
|
1519
1457
|
)
|
|
1520
1458
|
payload_to_publish = rpc_response.model_dump(exclude_none=True)
|
|
1521
1459
|
|
|
1522
|
-
target_topic = a2a_context.get(
|
|
1460
|
+
target_topic = a2a_context.get(
|
|
1461
|
+
"statusTopic"
|
|
1462
|
+
) or a2a.get_gateway_status_topic(
|
|
1523
1463
|
self.namespace, self.get_gateway_id(), logical_task_id
|
|
1524
1464
|
)
|
|
1525
1465
|
|
|
1526
|
-
|
|
1466
|
+
# Construct user_properties to ensure ownership can be determined by gateways
|
|
1467
|
+
user_properties = {
|
|
1468
|
+
"a2aUserConfig": a2a_context.get("a2a_user_config"),
|
|
1469
|
+
"clientId": a2a_context.get("client_id"),
|
|
1470
|
+
"delegating_agent_name": self.get_config("agent_name"),
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
self._publish_a2a_event(
|
|
1474
|
+
payload_to_publish, target_topic, a2a_context, user_properties
|
|
1475
|
+
)
|
|
1527
1476
|
|
|
1528
1477
|
log.info(
|
|
1529
1478
|
"%s Published %s status update to %s.",
|
|
@@ -1541,121 +1490,6 @@ class SamAgentComponent(ComponentBase):
|
|
|
1541
1490
|
)
|
|
1542
1491
|
raise
|
|
1543
1492
|
|
|
1544
|
-
async def _translate_adk_part_to_a2a_filepart(
|
|
1545
|
-
self,
|
|
1546
|
-
adk_part: adk_types.Part,
|
|
1547
|
-
filename: str,
|
|
1548
|
-
a2a_context: Dict,
|
|
1549
|
-
version: Optional[int] = None,
|
|
1550
|
-
) -> Optional[FilePart]:
|
|
1551
|
-
"""
|
|
1552
|
-
Translates a loaded ADK Part (with inline_data) to an A2A FilePart
|
|
1553
|
-
based on the configured artifact_handling_mode.
|
|
1554
|
-
If version is not provided, it will be resolved to the latest.
|
|
1555
|
-
"""
|
|
1556
|
-
if self.artifact_handling_mode == "ignore":
|
|
1557
|
-
log.debug(
|
|
1558
|
-
"%s Artifact handling mode is 'ignore'. Skipping translation for '%s'.",
|
|
1559
|
-
self.log_identifier,
|
|
1560
|
-
filename,
|
|
1561
|
-
)
|
|
1562
|
-
return None
|
|
1563
|
-
|
|
1564
|
-
if not adk_part or not adk_part.inline_data:
|
|
1565
|
-
log.warning(
|
|
1566
|
-
"%s Cannot translate artifact '%s': ADK Part is missing or has no inline_data.",
|
|
1567
|
-
self.log_identifier,
|
|
1568
|
-
filename,
|
|
1569
|
-
)
|
|
1570
|
-
return None
|
|
1571
|
-
|
|
1572
|
-
resolved_version = version
|
|
1573
|
-
if resolved_version is None:
|
|
1574
|
-
try:
|
|
1575
|
-
resolved_version = await get_latest_artifact_version(
|
|
1576
|
-
artifact_service=self.artifact_service,
|
|
1577
|
-
app_name=self.get_config("agent_name"),
|
|
1578
|
-
user_id=a2a_context.get("user_id"),
|
|
1579
|
-
session_id=a2a_context.get("session_id"),
|
|
1580
|
-
filename=filename,
|
|
1581
|
-
)
|
|
1582
|
-
if resolved_version is None:
|
|
1583
|
-
log.error(
|
|
1584
|
-
"%s Could not resolve latest version for artifact '%s'.",
|
|
1585
|
-
self.log_identifier,
|
|
1586
|
-
filename,
|
|
1587
|
-
)
|
|
1588
|
-
return None
|
|
1589
|
-
except Exception as e:
|
|
1590
|
-
log.exception(
|
|
1591
|
-
"%s Failed to resolve latest version for artifact '%s': %s",
|
|
1592
|
-
self.log_identifier,
|
|
1593
|
-
filename,
|
|
1594
|
-
e,
|
|
1595
|
-
)
|
|
1596
|
-
return None
|
|
1597
|
-
|
|
1598
|
-
mime_type = adk_part.inline_data.mime_type
|
|
1599
|
-
data_bytes = adk_part.inline_data.data
|
|
1600
|
-
file_content: Optional[FileContent] = None
|
|
1601
|
-
|
|
1602
|
-
try:
|
|
1603
|
-
if self.artifact_handling_mode == "embed":
|
|
1604
|
-
encoded_bytes = base64.b64encode(data_bytes).decode("utf-8")
|
|
1605
|
-
file_content = FileContent(
|
|
1606
|
-
name=filename, mimeType=mime_type, bytes=encoded_bytes
|
|
1607
|
-
)
|
|
1608
|
-
log.debug(
|
|
1609
|
-
"%s Embedding artifact '%s' (size: %d bytes) for A2A message.",
|
|
1610
|
-
self.log_identifier,
|
|
1611
|
-
filename,
|
|
1612
|
-
len(data_bytes),
|
|
1613
|
-
)
|
|
1614
|
-
|
|
1615
|
-
elif self.artifact_handling_mode == "reference":
|
|
1616
|
-
adk_app_name = self.get_config("agent_name")
|
|
1617
|
-
user_id = a2a_context.get("user_id")
|
|
1618
|
-
original_session_id = a2a_context.get("session_id")
|
|
1619
|
-
|
|
1620
|
-
if not all([adk_app_name, user_id, original_session_id]):
|
|
1621
|
-
log.error(
|
|
1622
|
-
"%s Cannot create artifact reference URI: missing context (app_name, user_id, or session_id).",
|
|
1623
|
-
self.log_identifier,
|
|
1624
|
-
)
|
|
1625
|
-
return None
|
|
1626
|
-
|
|
1627
|
-
artifact_uri = f"artifact://{adk_app_name}/{user_id}/{original_session_id}/{filename}?version={resolved_version}"
|
|
1628
|
-
|
|
1629
|
-
log.info(
|
|
1630
|
-
"%s Creating reference URI for artifact: %s",
|
|
1631
|
-
self.log_identifier,
|
|
1632
|
-
artifact_uri,
|
|
1633
|
-
)
|
|
1634
|
-
file_content = FileContent(
|
|
1635
|
-
name=filename, mimeType=mime_type, uri=artifact_uri
|
|
1636
|
-
)
|
|
1637
|
-
|
|
1638
|
-
if file_content:
|
|
1639
|
-
return FilePart(file=file_content)
|
|
1640
|
-
else:
|
|
1641
|
-
log.warning(
|
|
1642
|
-
"%s No FileContent created for artifact '%s' despite mode '%s'.",
|
|
1643
|
-
self.log_identifier,
|
|
1644
|
-
filename,
|
|
1645
|
-
self.artifact_handling_mode,
|
|
1646
|
-
)
|
|
1647
|
-
return None
|
|
1648
|
-
|
|
1649
|
-
except Exception as e:
|
|
1650
|
-
log.exception(
|
|
1651
|
-
"%s Error translating artifact '%s' to A2A FilePart (mode: %s): %s",
|
|
1652
|
-
self.log_identifier,
|
|
1653
|
-
filename,
|
|
1654
|
-
self.artifact_handling_mode,
|
|
1655
|
-
e,
|
|
1656
|
-
)
|
|
1657
|
-
return None
|
|
1658
|
-
|
|
1659
1493
|
async def _filter_text_from_final_streaming_event(
|
|
1660
1494
|
self, adk_event: ADKEvent, a2a_context: Dict
|
|
1661
1495
|
) -> ADKEvent:
|
|
@@ -1972,7 +1806,7 @@ class SamAgentComponent(ComponentBase):
|
|
|
1972
1806
|
namespace = self.get_config("namespace")
|
|
1973
1807
|
gateway_id = self.get_gateway_id()
|
|
1974
1808
|
|
|
1975
|
-
artifact_topic = peer_status_topic or get_gateway_status_topic(
|
|
1809
|
+
artifact_topic = peer_status_topic or a2a.get_gateway_status_topic(
|
|
1976
1810
|
namespace, gateway_id, logical_task_id
|
|
1977
1811
|
)
|
|
1978
1812
|
|
|
@@ -2012,18 +1846,36 @@ class SamAgentComponent(ComponentBase):
|
|
|
2012
1846
|
)
|
|
2013
1847
|
continue
|
|
2014
1848
|
|
|
2015
|
-
a2a_file_part = await
|
|
2016
|
-
loaded_adk_part,
|
|
1849
|
+
a2a_file_part = await a2a.translate_adk_part_to_a2a_filepart(
|
|
1850
|
+
adk_part=loaded_adk_part,
|
|
1851
|
+
filename=filename,
|
|
1852
|
+
a2a_context=a2a_context,
|
|
1853
|
+
artifact_service=self.artifact_service,
|
|
1854
|
+
artifact_handling_mode=self.artifact_handling_mode,
|
|
1855
|
+
adk_app_name=self.get_config("agent_name"),
|
|
1856
|
+
log_identifier=self.log_identifier,
|
|
1857
|
+
version=version,
|
|
2017
1858
|
)
|
|
2018
1859
|
|
|
2019
1860
|
if a2a_file_part:
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
1861
|
+
a2a_message = a2a.create_agent_parts_message(
|
|
1862
|
+
parts=[a2a_file_part],
|
|
1863
|
+
task_id=logical_task_id,
|
|
1864
|
+
context_id=original_session_id,
|
|
2023
1865
|
)
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
1866
|
+
task_status = a2a.create_task_status(
|
|
1867
|
+
state=TaskState.working, message=a2a_message
|
|
1868
|
+
)
|
|
1869
|
+
status_update_event = TaskStatusUpdateEvent(
|
|
1870
|
+
task_id=logical_task_id,
|
|
1871
|
+
context_id=original_session_id,
|
|
1872
|
+
status=task_status,
|
|
1873
|
+
final=False,
|
|
1874
|
+
kind="status-update",
|
|
1875
|
+
)
|
|
1876
|
+
artifact_payload = a2a.create_success_response(
|
|
1877
|
+
result=status_update_event,
|
|
1878
|
+
request_id=a2a_context.get("jsonrpc_request_id"),
|
|
2027
1879
|
).model_dump(exclude_none=True)
|
|
2028
1880
|
|
|
2029
1881
|
self._publish_a2a_event(
|
|
@@ -2031,7 +1883,7 @@ class SamAgentComponent(ComponentBase):
|
|
|
2031
1883
|
)
|
|
2032
1884
|
|
|
2033
1885
|
log.info(
|
|
2034
|
-
"%s Published
|
|
1886
|
+
"%s Published TaskStatusUpdateEvent with FilePart for '%s' to %s",
|
|
2035
1887
|
log_id,
|
|
2036
1888
|
filename,
|
|
2037
1889
|
artifact_topic,
|
|
@@ -2052,53 +1904,51 @@ class SamAgentComponent(ComponentBase):
|
|
|
2052
1904
|
e,
|
|
2053
1905
|
)
|
|
2054
1906
|
|
|
2055
|
-
def _format_final_task_status(
|
|
1907
|
+
def _format_final_task_status(
|
|
1908
|
+
self, last_event: Optional[ADKEvent], override_text: Optional[str] = None
|
|
1909
|
+
) -> TaskStatus:
|
|
2056
1910
|
"""Helper to format the final TaskStatus based on the last ADK event."""
|
|
2057
1911
|
log.debug(
|
|
2058
1912
|
"%s Formatting final task status from last ADK event %s",
|
|
2059
1913
|
self.log_identifier,
|
|
2060
|
-
last_event.id,
|
|
1914
|
+
last_event.id if last_event else "None",
|
|
2061
1915
|
)
|
|
2062
|
-
a2a_state = TaskState.
|
|
1916
|
+
a2a_state = TaskState.completed
|
|
2063
1917
|
a2a_parts = []
|
|
2064
1918
|
|
|
2065
|
-
if
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
DataPart(
|
|
2075
|
-
data=response_data,
|
|
2076
|
-
metadata={"tool_name": part.function_response.name},
|
|
2077
|
-
)
|
|
2078
|
-
)
|
|
2079
|
-
else:
|
|
2080
|
-
a2a_parts.append(
|
|
2081
|
-
TextPart(
|
|
2082
|
-
text=f"Tool {part.function_response.name} result: {str(response_data)}"
|
|
2083
|
-
)
|
|
2084
|
-
)
|
|
2085
|
-
except Exception:
|
|
2086
|
-
a2a_parts.append(
|
|
2087
|
-
TextPart(
|
|
2088
|
-
text=f"[Tool {part.function_response.name} result omitted]"
|
|
1919
|
+
if override_text is not None:
|
|
1920
|
+
a2a_parts.append(a2a.create_text_part(text=override_text))
|
|
1921
|
+
# Add non-text parts from the last event
|
|
1922
|
+
if last_event and last_event.content and last_event.content.parts:
|
|
1923
|
+
for part in last_event.content.parts:
|
|
1924
|
+
if part.text is None:
|
|
1925
|
+
if part.function_response:
|
|
1926
|
+
a2a_parts.extend(
|
|
1927
|
+
a2a.translate_adk_function_response_to_a2a_parts(part)
|
|
2089
1928
|
)
|
|
1929
|
+
else:
|
|
1930
|
+
# Original logic
|
|
1931
|
+
if last_event and last_event.content and last_event.content.parts:
|
|
1932
|
+
for part in last_event.content.parts:
|
|
1933
|
+
if part.text:
|
|
1934
|
+
a2a_parts.append(a2a.create_text_part(text=part.text))
|
|
1935
|
+
elif part.function_response:
|
|
1936
|
+
a2a_parts.extend(
|
|
1937
|
+
a2a.translate_adk_function_response_to_a2a_parts(part)
|
|
2090
1938
|
)
|
|
2091
1939
|
|
|
2092
|
-
|
|
1940
|
+
if last_event and last_event.actions:
|
|
2093
1941
|
if last_event.actions.requested_auth_configs:
|
|
2094
|
-
a2a_state = TaskState.
|
|
2095
|
-
a2a_parts.append(
|
|
1942
|
+
a2a_state = TaskState.input_required
|
|
1943
|
+
a2a_parts.append(
|
|
1944
|
+
a2a.create_text_part(text="[Agent requires input/authentication]")
|
|
1945
|
+
)
|
|
2096
1946
|
|
|
2097
1947
|
if not a2a_parts:
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
return
|
|
1948
|
+
a2a_message = a2a.create_agent_text_message(text="")
|
|
1949
|
+
else:
|
|
1950
|
+
a2a_message = a2a.create_agent_parts_message(parts=a2a_parts)
|
|
1951
|
+
return a2a.create_task_status(state=a2a_state, message=a2a_message)
|
|
2102
1952
|
|
|
2103
1953
|
async def finalize_task_success(self, a2a_context: Dict):
|
|
2104
1954
|
"""
|
|
@@ -2156,55 +2006,16 @@ class SamAgentComponent(ComponentBase):
|
|
|
2156
2006
|
logical_task_id,
|
|
2157
2007
|
len(aggregated_text.encode("utf-8")),
|
|
2158
2008
|
)
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
if aggregated_text:
|
|
2162
|
-
final_a2a_parts.append(TextPart(text=aggregated_text))
|
|
2163
|
-
|
|
2164
|
-
if last_event and last_event.content and last_event.content.parts:
|
|
2165
|
-
for part in last_event.content.parts:
|
|
2166
|
-
if part.text is None:
|
|
2167
|
-
if part.function_response:
|
|
2168
|
-
try:
|
|
2169
|
-
response_data = part.function_response.response
|
|
2170
|
-
if isinstance(response_data, dict):
|
|
2171
|
-
final_a2a_parts.append(
|
|
2172
|
-
DataPart(
|
|
2173
|
-
data=response_data,
|
|
2174
|
-
metadata={
|
|
2175
|
-
"tool_name": part.function_response.name
|
|
2176
|
-
},
|
|
2177
|
-
)
|
|
2178
|
-
)
|
|
2179
|
-
else:
|
|
2180
|
-
final_a2a_parts.append(
|
|
2181
|
-
TextPart(
|
|
2182
|
-
text=f"Tool {part.function_response.name} result: {str(response_data)}"
|
|
2183
|
-
)
|
|
2184
|
-
)
|
|
2185
|
-
except Exception:
|
|
2186
|
-
final_a2a_parts.append(
|
|
2187
|
-
TextPart(
|
|
2188
|
-
text=f"[Tool {part.function_response.name} result omitted]"
|
|
2189
|
-
)
|
|
2190
|
-
)
|
|
2191
|
-
|
|
2192
|
-
if not final_a2a_parts:
|
|
2193
|
-
final_a2a_parts.append(TextPart(text=""))
|
|
2194
|
-
|
|
2195
|
-
final_status = TaskStatus(
|
|
2196
|
-
state=TaskState.COMPLETED,
|
|
2197
|
-
message=A2AMessage(role="agent", parts=final_a2a_parts),
|
|
2009
|
+
final_status = self._format_final_task_status(
|
|
2010
|
+
last_event, override_text=aggregated_text
|
|
2198
2011
|
)
|
|
2199
2012
|
else:
|
|
2200
2013
|
if last_event:
|
|
2201
2014
|
final_status = self._format_final_task_status(last_event)
|
|
2202
2015
|
else:
|
|
2203
|
-
final_status =
|
|
2204
|
-
state=TaskState.
|
|
2205
|
-
message=
|
|
2206
|
-
role="agent", parts=[TextPart(text="Task completed.")]
|
|
2207
|
-
),
|
|
2016
|
+
final_status = a2a.create_task_status(
|
|
2017
|
+
state=TaskState.completed,
|
|
2018
|
+
message=a2a.create_agent_text_message(text="Task completed."),
|
|
2208
2019
|
)
|
|
2209
2020
|
|
|
2210
2021
|
final_a2a_artifacts: List[A2AArtifact] = []
|
|
@@ -2224,16 +2035,18 @@ class SamAgentComponent(ComponentBase):
|
|
|
2224
2035
|
len(task_context.produced_artifacts),
|
|
2225
2036
|
)
|
|
2226
2037
|
|
|
2227
|
-
final_task =
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2038
|
+
final_task = a2a.create_final_task(
|
|
2039
|
+
task_id=logical_task_id,
|
|
2040
|
+
context_id=original_session_id,
|
|
2041
|
+
final_status=final_status,
|
|
2231
2042
|
artifacts=(final_a2a_artifacts if final_a2a_artifacts else None),
|
|
2232
2043
|
metadata=final_task_metadata,
|
|
2233
2044
|
)
|
|
2234
|
-
final_response =
|
|
2045
|
+
final_response = a2a.create_success_response(
|
|
2046
|
+
result=final_task, request_id=jsonrpc_request_id
|
|
2047
|
+
)
|
|
2235
2048
|
a2a_payload = final_response.model_dump(exclude_none=True)
|
|
2236
|
-
target_topic = peer_reply_topic or get_client_response_topic(
|
|
2049
|
+
target_topic = peer_reply_topic or a2a.get_client_response_topic(
|
|
2237
2050
|
namespace, client_id
|
|
2238
2051
|
)
|
|
2239
2052
|
|
|
@@ -2300,17 +2113,15 @@ class SamAgentComponent(ComponentBase):
|
|
|
2300
2113
|
client_id = a2a_context.get("client_id")
|
|
2301
2114
|
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
2302
2115
|
namespace = self.get_config("namespace")
|
|
2303
|
-
error_response =
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
)
|
|
2310
|
-
target_topic = peer_reply_topic or get_client_response_topic(
|
|
2116
|
+
error_response = a2a.create_internal_error_response(
|
|
2117
|
+
message=f"Failed to finalize successful task: {e}",
|
|
2118
|
+
request_id=jsonrpc_request_id,
|
|
2119
|
+
data={"taskId": logical_task_id},
|
|
2120
|
+
)
|
|
2121
|
+
target_topic = peer_reply_topic or a2a.get_client_response_topic(
|
|
2311
2122
|
namespace, client_id
|
|
2312
2123
|
)
|
|
2313
|
-
self.
|
|
2124
|
+
self.publish_a2a_message(
|
|
2314
2125
|
error_response.model_dump(exclude_none=True), target_topic
|
|
2315
2126
|
)
|
|
2316
2127
|
except Exception as report_err:
|
|
@@ -2340,23 +2151,24 @@ class SamAgentComponent(ComponentBase):
|
|
|
2340
2151
|
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
2341
2152
|
namespace = self.get_config("namespace")
|
|
2342
2153
|
|
|
2343
|
-
canceled_status =
|
|
2344
|
-
state=TaskState.
|
|
2345
|
-
message=
|
|
2346
|
-
|
|
2347
|
-
parts=[TextPart(text="Task cancelled by request.")],
|
|
2154
|
+
canceled_status = a2a.create_task_status(
|
|
2155
|
+
state=TaskState.canceled,
|
|
2156
|
+
message=a2a.create_agent_text_message(
|
|
2157
|
+
text="Task cancelled by request."
|
|
2348
2158
|
),
|
|
2349
2159
|
)
|
|
2350
2160
|
agent_name = self.get_config("agent_name")
|
|
2351
|
-
final_task =
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2161
|
+
final_task = a2a.create_final_task(
|
|
2162
|
+
task_id=logical_task_id,
|
|
2163
|
+
context_id=a2a_context.get("contextId"),
|
|
2164
|
+
final_status=canceled_status,
|
|
2355
2165
|
metadata={"agent_name": agent_name},
|
|
2356
2166
|
)
|
|
2357
|
-
final_response =
|
|
2167
|
+
final_response = a2a.create_success_response(
|
|
2168
|
+
result=final_task, request_id=jsonrpc_request_id
|
|
2169
|
+
)
|
|
2358
2170
|
a2a_payload = final_response.model_dump(exclude_none=True)
|
|
2359
|
-
target_topic = peer_reply_topic or get_client_response_topic(
|
|
2171
|
+
target_topic = peer_reply_topic or a2a.get_client_response_topic(
|
|
2360
2172
|
namespace, client_id
|
|
2361
2173
|
)
|
|
2362
2174
|
|
|
@@ -2416,7 +2228,7 @@ class SamAgentComponent(ComponentBase):
|
|
|
2416
2228
|
)
|
|
2417
2229
|
try:
|
|
2418
2230
|
# Create the status update event
|
|
2419
|
-
tool_error_data_part =
|
|
2231
|
+
tool_error_data_part = a2a.create_data_part(
|
|
2420
2232
|
data={
|
|
2421
2233
|
"a2a_signal_type": "tool_execution_error",
|
|
2422
2234
|
"error_message": str(exception),
|
|
@@ -2424,17 +2236,16 @@ class SamAgentComponent(ComponentBase):
|
|
|
2424
2236
|
}
|
|
2425
2237
|
)
|
|
2426
2238
|
|
|
2427
|
-
status_message =
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
timestamp=datetime.now(timezone.utc),
|
|
2239
|
+
status_message = a2a.create_agent_parts_message(
|
|
2240
|
+
parts=[tool_error_data_part],
|
|
2241
|
+
task_id=logical_task_id,
|
|
2242
|
+
context_id=a2a_context.get("contextId"),
|
|
2432
2243
|
)
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2244
|
+
status_update_event = a2a.create_status_update(
|
|
2245
|
+
task_id=logical_task_id,
|
|
2246
|
+
context_id=a2a_context.get("contextId"),
|
|
2247
|
+
message=status_message,
|
|
2248
|
+
is_final=False,
|
|
2438
2249
|
metadata={"agent_name": self.get_config("agent_name")},
|
|
2439
2250
|
)
|
|
2440
2251
|
|
|
@@ -2554,15 +2365,14 @@ class SamAgentComponent(ComponentBase):
|
|
|
2554
2365
|
"Otherwise, you can start a new topic."
|
|
2555
2366
|
)
|
|
2556
2367
|
|
|
2557
|
-
|
|
2368
|
+
final_response = a2a.create_internal_error_response(
|
|
2558
2369
|
message=limit_message_text,
|
|
2370
|
+
request_id=jsonrpc_request_id,
|
|
2559
2371
|
data={"taskId": logical_task_id, "reason": "llm_call_limit_reached"},
|
|
2560
2372
|
)
|
|
2561
|
-
|
|
2562
|
-
final_response = JSONRPCResponse(id=jsonrpc_request_id, error=error_payload)
|
|
2563
2373
|
a2a_payload = final_response.model_dump(exclude_none=True)
|
|
2564
2374
|
|
|
2565
|
-
target_topic = peer_reply_topic or get_client_response_topic(
|
|
2375
|
+
target_topic = peer_reply_topic or a2a.get_client_response_topic(
|
|
2566
2376
|
namespace, client_id
|
|
2567
2377
|
)
|
|
2568
2378
|
|
|
@@ -2631,28 +2441,25 @@ class SamAgentComponent(ComponentBase):
|
|
|
2631
2441
|
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
2632
2442
|
namespace = self.get_config("namespace")
|
|
2633
2443
|
|
|
2634
|
-
failed_status =
|
|
2635
|
-
state=TaskState.
|
|
2636
|
-
message=
|
|
2637
|
-
|
|
2638
|
-
parts=[
|
|
2639
|
-
TextPart(
|
|
2640
|
-
text="An unexpected error occurred during tool execution. Please try your request again. If the problem persists, contact an administrator."
|
|
2641
|
-
)
|
|
2642
|
-
],
|
|
2444
|
+
failed_status = a2a.create_task_status(
|
|
2445
|
+
state=TaskState.failed,
|
|
2446
|
+
message=a2a.create_agent_text_message(
|
|
2447
|
+
text="An unexpected error occurred during tool execution. Please try your request again. If the problem persists, contact an administrator."
|
|
2643
2448
|
),
|
|
2644
2449
|
)
|
|
2645
2450
|
|
|
2646
|
-
final_task =
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2451
|
+
final_task = a2a.create_final_task(
|
|
2452
|
+
task_id=logical_task_id,
|
|
2453
|
+
context_id=a2a_context.get("contextId"),
|
|
2454
|
+
final_status=failed_status,
|
|
2650
2455
|
metadata={"agent_name": self.get_config("agent_name")},
|
|
2651
2456
|
)
|
|
2652
2457
|
|
|
2653
|
-
final_response =
|
|
2458
|
+
final_response = a2a.create_success_response(
|
|
2459
|
+
result=final_task, request_id=jsonrpc_request_id
|
|
2460
|
+
)
|
|
2654
2461
|
a2a_payload = final_response.model_dump(exclude_none=True)
|
|
2655
|
-
target_topic = peer_reply_topic or get_client_response_topic(
|
|
2462
|
+
target_topic = peer_reply_topic or a2a.get_client_response_topic(
|
|
2656
2463
|
namespace, client_id
|
|
2657
2464
|
)
|
|
2658
2465
|
|
|
@@ -2871,21 +2678,21 @@ class SamAgentComponent(ComponentBase):
|
|
|
2871
2678
|
|
|
2872
2679
|
def _get_a2a_base_topic(self) -> str:
|
|
2873
2680
|
"""Returns the base topic prefix using helper."""
|
|
2874
|
-
return get_a2a_base_topic(self.namespace)
|
|
2681
|
+
return a2a.get_a2a_base_topic(self.namespace)
|
|
2875
2682
|
|
|
2876
2683
|
def _get_discovery_topic(self) -> str:
|
|
2877
2684
|
"""Returns the discovery topic using helper."""
|
|
2878
|
-
return get_discovery_topic(self.namespace)
|
|
2685
|
+
return a2a.get_discovery_topic(self.namespace)
|
|
2879
2686
|
|
|
2880
2687
|
def _get_agent_request_topic(self, agent_id: str) -> str:
|
|
2881
2688
|
"""Returns the agent request topic using helper."""
|
|
2882
|
-
return get_agent_request_topic(self.namespace, agent_id)
|
|
2689
|
+
return a2a.get_agent_request_topic(self.namespace, agent_id)
|
|
2883
2690
|
|
|
2884
2691
|
def _get_agent_response_topic(
|
|
2885
2692
|
self, delegating_agent_name: str, sub_task_id: str
|
|
2886
2693
|
) -> str:
|
|
2887
2694
|
"""Returns the agent response topic using helper."""
|
|
2888
|
-
return get_agent_response_topic(
|
|
2695
|
+
return a2a.get_agent_response_topic(
|
|
2889
2696
|
self.namespace, delegating_agent_name, sub_task_id
|
|
2890
2697
|
)
|
|
2891
2698
|
|
|
@@ -2893,92 +2700,41 @@ class SamAgentComponent(ComponentBase):
|
|
|
2893
2700
|
self, delegating_agent_name: str, sub_task_id: str
|
|
2894
2701
|
) -> str:
|
|
2895
2702
|
"""Returns the peer agent status topic using helper."""
|
|
2896
|
-
return get_peer_agent_status_topic(
|
|
2703
|
+
return a2a.get_peer_agent_status_topic(
|
|
2897
2704
|
self.namespace, delegating_agent_name, sub_task_id
|
|
2898
2705
|
)
|
|
2899
2706
|
|
|
2900
2707
|
def _get_client_response_topic(self, client_id: str) -> str:
|
|
2901
2708
|
"""Returns the client response topic using helper."""
|
|
2902
|
-
return get_client_response_topic(self.namespace, client_id)
|
|
2709
|
+
return a2a.get_client_response_topic(self.namespace, client_id)
|
|
2903
2710
|
|
|
2904
|
-
def
|
|
2905
|
-
self,
|
|
2711
|
+
def _publish_a2a_event(
|
|
2712
|
+
self,
|
|
2713
|
+
payload: Dict,
|
|
2714
|
+
topic: str,
|
|
2715
|
+
a2a_context: Dict,
|
|
2716
|
+
user_properties_override: Optional[Dict] = None,
|
|
2906
2717
|
):
|
|
2907
|
-
"""Helper to publish A2A messages via the SAC App."""
|
|
2908
|
-
try:
|
|
2909
|
-
max_size_bytes = self.max_message_size_bytes
|
|
2910
|
-
|
|
2911
|
-
# Validate message size
|
|
2912
|
-
is_valid, actual_size = validate_message_size(
|
|
2913
|
-
payload, max_size_bytes, self.log_identifier
|
|
2914
|
-
)
|
|
2915
|
-
|
|
2916
|
-
if not is_valid:
|
|
2917
|
-
error_msg = (
|
|
2918
|
-
f"Message size validation failed: payload size ({actual_size} bytes) "
|
|
2919
|
-
f"exceeds maximum allowed size ({max_size_bytes} bytes)"
|
|
2920
|
-
)
|
|
2921
|
-
log.error("%s %s", self.log_identifier, error_msg)
|
|
2922
|
-
raise MessageSizeExceededError(actual_size, max_size_bytes, error_msg)
|
|
2923
|
-
|
|
2924
|
-
# Debug logging to show message size when publishing
|
|
2925
|
-
log.debug(
|
|
2926
|
-
"%s Publishing message to topic %s (size: %d bytes)",
|
|
2927
|
-
self.log_identifier,
|
|
2928
|
-
topic,
|
|
2929
|
-
actual_size,
|
|
2930
|
-
)
|
|
2931
|
-
|
|
2932
|
-
app = self.get_app()
|
|
2933
|
-
if app:
|
|
2934
|
-
if self.invocation_monitor:
|
|
2935
|
-
self.invocation_monitor.log_message_event(
|
|
2936
|
-
direction="PUBLISHED",
|
|
2937
|
-
topic=topic,
|
|
2938
|
-
payload=payload,
|
|
2939
|
-
component_identifier=self.log_identifier,
|
|
2940
|
-
)
|
|
2941
|
-
app.send_message(
|
|
2942
|
-
payload=payload, topic=topic, user_properties=user_properties
|
|
2943
|
-
)
|
|
2944
|
-
else:
|
|
2945
|
-
log.error(
|
|
2946
|
-
"%s Cannot publish message: Not running within a SAC App context.",
|
|
2947
|
-
self.log_identifier,
|
|
2948
|
-
)
|
|
2949
|
-
except MessageSizeExceededError:
|
|
2950
|
-
# Re-raise MessageSizeExceededError without wrapping
|
|
2951
|
-
raise
|
|
2952
|
-
except Exception as e:
|
|
2953
|
-
log.exception(
|
|
2954
|
-
"%s Failed to publish A2A message to topic %s: %s",
|
|
2955
|
-
self.log_identifier,
|
|
2956
|
-
topic,
|
|
2957
|
-
e,
|
|
2958
|
-
)
|
|
2959
|
-
raise
|
|
2960
|
-
|
|
2961
|
-
def _publish_a2a_event(self, payload: Dict, topic: str, a2a_context: Dict):
|
|
2962
2718
|
"""
|
|
2963
2719
|
Centralized helper to publish an A2A event, ensuring user properties
|
|
2964
|
-
are consistently attached from the a2a_context.
|
|
2720
|
+
are consistently attached from the a2a_context or an override.
|
|
2965
2721
|
"""
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2722
|
+
if user_properties_override is not None:
|
|
2723
|
+
user_properties = user_properties_override
|
|
2724
|
+
else:
|
|
2725
|
+
user_properties = {}
|
|
2726
|
+
if a2a_context.get("a2a_user_config"):
|
|
2727
|
+
user_properties["a2aUserConfig"] = a2a_context["a2a_user_config"]
|
|
2969
2728
|
|
|
2970
|
-
self.
|
|
2729
|
+
self.publish_a2a_message(payload, topic, user_properties)
|
|
2971
2730
|
|
|
2972
2731
|
def submit_a2a_task(
|
|
2973
2732
|
self,
|
|
2974
2733
|
target_agent_name: str,
|
|
2975
2734
|
a2a_message: A2AMessage,
|
|
2976
|
-
original_session_id: str,
|
|
2977
|
-
main_logical_task_id: str,
|
|
2978
2735
|
user_id: str,
|
|
2979
2736
|
user_config: Dict[str, Any],
|
|
2980
2737
|
sub_task_id: str,
|
|
2981
|
-
function_call_id: Optional[str] = None,
|
|
2982
2738
|
) -> str:
|
|
2983
2739
|
"""
|
|
2984
2740
|
Submits a task to a peer agent in a non-blocking way.
|
|
@@ -2987,25 +2743,18 @@ class SamAgentComponent(ComponentBase):
|
|
|
2987
2743
|
log_identifier_helper = (
|
|
2988
2744
|
f"{self.log_identifier}[SubmitA2ATask:{target_agent_name}]"
|
|
2989
2745
|
)
|
|
2746
|
+
main_task_id = a2a_message.metadata.get("parentTaskId", "unknown_parent")
|
|
2990
2747
|
log.debug(
|
|
2991
2748
|
"%s Submitting non-blocking task for main task %s",
|
|
2992
2749
|
log_identifier_helper,
|
|
2993
|
-
|
|
2750
|
+
main_task_id,
|
|
2994
2751
|
)
|
|
2995
2752
|
|
|
2996
2753
|
peer_request_topic = self._get_agent_request_topic(target_agent_name)
|
|
2997
2754
|
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
"message": a2a_message.model_dump(exclude_none=True),
|
|
3002
|
-
"metadata": {
|
|
3003
|
-
"sessionBehavior": "RUN_BASED",
|
|
3004
|
-
"parentTaskId": main_logical_task_id,
|
|
3005
|
-
"function_call_id": function_call_id,
|
|
3006
|
-
},
|
|
3007
|
-
}
|
|
3008
|
-
a2a_request = SendTaskRequest(params=a2a_request_params)
|
|
2755
|
+
# Create a compliant SendMessageRequest
|
|
2756
|
+
send_params = MessageSendParams(message=a2a_message)
|
|
2757
|
+
a2a_request = SendMessageRequest(id=sub_task_id, params=send_params)
|
|
3009
2758
|
|
|
3010
2759
|
delegating_agent_name = self.get_config("agent_name")
|
|
3011
2760
|
reply_to_topic = self._get_agent_response_topic(
|
|
@@ -3025,8 +2774,8 @@ class SamAgentComponent(ComponentBase):
|
|
|
3025
2774
|
if isinstance(user_config, dict):
|
|
3026
2775
|
user_properties["a2aUserConfig"] = user_config
|
|
3027
2776
|
|
|
3028
|
-
self.
|
|
3029
|
-
payload=a2a_request.model_dump(exclude_none=True),
|
|
2777
|
+
self.publish_a2a_message(
|
|
2778
|
+
payload=a2a_request.model_dump(by_alias=True, exclude_none=True),
|
|
3030
2779
|
topic=peer_request_topic,
|
|
3031
2780
|
user_properties=user_properties,
|
|
3032
2781
|
)
|
|
@@ -3072,25 +2821,6 @@ class SamAgentComponent(ComponentBase):
|
|
|
3072
2821
|
exc_info=e,
|
|
3073
2822
|
)
|
|
3074
2823
|
|
|
3075
|
-
def _start_async_loop(self):
|
|
3076
|
-
"""Target method for the dedicated async thread."""
|
|
3077
|
-
log.info("%s Dedicated async thread started.", self.log_identifier)
|
|
3078
|
-
try:
|
|
3079
|
-
asyncio.set_event_loop(self._async_loop)
|
|
3080
|
-
self._async_loop.run_forever()
|
|
3081
|
-
except Exception as e:
|
|
3082
|
-
log.exception(
|
|
3083
|
-
"%s Exception in dedicated async thread loop: %s",
|
|
3084
|
-
self.log_identifier,
|
|
3085
|
-
e,
|
|
3086
|
-
)
|
|
3087
|
-
if self._async_init_future and not self._async_init_future.done():
|
|
3088
|
-
self._async_init_future.set_exception(e)
|
|
3089
|
-
finally:
|
|
3090
|
-
log.info("%s Dedicated async thread loop finishing.", self.log_identifier)
|
|
3091
|
-
if self._async_loop.is_running():
|
|
3092
|
-
self._async_loop.call_soon_threadsafe(self._async_loop.stop)
|
|
3093
|
-
|
|
3094
2824
|
async def _perform_async_init(self):
|
|
3095
2825
|
"""Coroutine executed on the dedicated loop to perform async initialization."""
|
|
3096
2826
|
try:
|
|
@@ -3249,58 +2979,8 @@ class SamAgentComponent(ComponentBase):
|
|
|
3249
2979
|
im_clean_e,
|
|
3250
2980
|
)
|
|
3251
2981
|
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
"%s Performing async cleanup via dedicated thread...",
|
|
3255
|
-
self.log_identifier,
|
|
3256
|
-
)
|
|
3257
|
-
|
|
3258
|
-
async def _perform_async_cleanup():
|
|
3259
|
-
log.debug("%s Entering async cleanup coroutine...", self.log_identifier)
|
|
3260
|
-
pass
|
|
3261
|
-
|
|
3262
|
-
try:
|
|
3263
|
-
cleanup_future = asyncio.run_coroutine_threadsafe(
|
|
3264
|
-
_perform_async_cleanup(), self._async_loop
|
|
3265
|
-
)
|
|
3266
|
-
cleanup_future.result(timeout=30)
|
|
3267
|
-
log.info("%s Async cleanup completed.", self.log_identifier)
|
|
3268
|
-
except Exception as e:
|
|
3269
|
-
log.exception(
|
|
3270
|
-
"%s Error during async cleanup: %s", self.log_identifier, e
|
|
3271
|
-
)
|
|
3272
|
-
finally:
|
|
3273
|
-
if self._async_loop and self._async_loop.is_running():
|
|
3274
|
-
log.info(
|
|
3275
|
-
"%s Cleanup: Stopping dedicated async loop...",
|
|
3276
|
-
self.log_identifier,
|
|
3277
|
-
)
|
|
3278
|
-
self._async_loop.call_soon_threadsafe(self._async_loop.stop)
|
|
3279
|
-
else:
|
|
3280
|
-
log.info(
|
|
3281
|
-
"%s Cleanup: Dedicated async loop is None or not running, no need to stop.",
|
|
3282
|
-
self.log_identifier,
|
|
3283
|
-
)
|
|
3284
|
-
if self._async_thread and self._async_thread.is_alive():
|
|
3285
|
-
log.info(
|
|
3286
|
-
"%s Cleanup: Joining dedicated async thread...",
|
|
3287
|
-
self.log_identifier,
|
|
3288
|
-
)
|
|
3289
|
-
self._async_thread.join(timeout=5)
|
|
3290
|
-
if self._async_thread.is_alive():
|
|
3291
|
-
log.warning(
|
|
3292
|
-
"%s Dedicated async thread did not exit cleanly.",
|
|
3293
|
-
self.log_identifier,
|
|
3294
|
-
)
|
|
3295
|
-
log.info(
|
|
3296
|
-
"%s Dedicated async thread stopped and joined.", self.log_identifier
|
|
3297
|
-
)
|
|
3298
|
-
else:
|
|
3299
|
-
log.info(
|
|
3300
|
-
"%s Dedicated async loop not running, skipping async cleanup.",
|
|
3301
|
-
self.log_identifier,
|
|
3302
|
-
)
|
|
3303
|
-
|
|
2982
|
+
# The base class cleanup() will handle stopping the async loop and joining the thread.
|
|
2983
|
+
# We just need to cancel any active tasks before that happens.
|
|
3304
2984
|
with self.active_tasks_lock:
|
|
3305
2985
|
if self._async_loop and self._async_loop.is_running():
|
|
3306
2986
|
for task_context in self.active_tasks.values():
|
|
@@ -3458,3 +3138,17 @@ class SamAgentComponent(ComponentBase):
|
|
|
3458
3138
|
"%s Error during embed resolution: %s", method_context_log_identifier, e
|
|
3459
3139
|
)
|
|
3460
3140
|
return raw_text, [], ""
|
|
3141
|
+
|
|
3142
|
+
async def _async_setup_and_run(self) -> None:
|
|
3143
|
+
"""
|
|
3144
|
+
Main async logic for the agent component.
|
|
3145
|
+
This is called by the base class's `_run_async_operations`.
|
|
3146
|
+
"""
|
|
3147
|
+
await self._perform_async_init()
|
|
3148
|
+
|
|
3149
|
+
def _pre_async_cleanup(self) -> None:
|
|
3150
|
+
"""
|
|
3151
|
+
Pre-cleanup actions for the agent component.
|
|
3152
|
+
Called by the base class before stopping the async loop.
|
|
3153
|
+
"""
|
|
3154
|
+
pass
|