solace-agent-mesh 1.0.1__py3-none-any.whl → 1.0.2__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/__init__.py +5 -0
- solace_agent_mesh/agent/adk/callbacks.py +23 -1
- solace_agent_mesh/agent/adk/filesystem_artifact_service.py +2 -2
- solace_agent_mesh/agent/adk/runner.py +10 -6
- solace_agent_mesh/agent/adk/services.py +1 -1
- solace_agent_mesh/agent/protocol/event_handlers.py +14 -39
- solace_agent_mesh/agent/sac/component.py +145 -37
- solace_agent_mesh/agent/sac/task_execution_context.py +15 -6
- solace_agent_mesh/agent/tools/general_agent_tools.py +4 -2
- solace_agent_mesh/agent/tools/peer_agent_tool.py +6 -5
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.a8c5ce5a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f897a61a.f8c53b0f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{main.7ed3319f.js → main.c6286d7c.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/{runtime~main.d9520ae2.js → runtime~main.d5133813.js} +1 -1
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +21 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1754075282978.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1754075282978.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +8 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +20 -0
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +2 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-D11Lmy9p.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{main-An0a5j5k.js → main-Gfk3BYn5.js} +96 -96
- solace_agent_mesh/client/webui/frontend/static/index.html +2 -2
- solace_agent_mesh/common/utils/initializer.py +51 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +2 -1
- solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +6 -2
- solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +1 -5
- solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +1 -0
- solace_agent_mesh/config_portal/backend/server.py +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-DNxCwAGB.js → _index-_7yox_eh.js} +25 -25
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d2b54a97.js → manifest-e5c3acfe.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +9 -3
- solace_agent_mesh/templates/gateway_component_template.py +75 -44
- solace_agent_mesh/templates/logging_config_template.ini +64 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.2.dist-info}/METADATA +2 -2
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.2.dist-info}/RECORD +77 -75
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.23bccffb.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f897a61a.2c2e152c.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1753813536522.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1753813536522.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bu5-4Bac.css +0 -1
- /solace_agent_mesh/assets/docs/assets/js/{main.7ed3319f.js.LICENSE.txt → main.c6286d7c.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.2.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.2.dist-info}/licenses/LICENSE +0 -0
solace_agent_mesh/__init__.py
CHANGED
|
@@ -785,6 +785,26 @@ It can span multiple lines.
|
|
|
785
785
|
|
|
786
786
|
The system will automatically save the content and give you a confirmation in the next turn."""
|
|
787
787
|
|
|
788
|
+
def _generate_artifact_creation_instruction() -> str:
|
|
789
|
+
return """
|
|
790
|
+
**Creating Text-Based Artifacts:**
|
|
791
|
+
|
|
792
|
+
**When to Create Text-based Artifacts:**
|
|
793
|
+
Create an artifact when the content provides value as a standalone file:
|
|
794
|
+
- Content with special formatting (HTML, Markdown, CSS, structured markup) that requires proper rendering
|
|
795
|
+
- Content explicitly intended for use outside this conversation (reports, emails, presentations, reference documents)
|
|
796
|
+
- Structured reference content users will save or follow (schedules, guides, templates)
|
|
797
|
+
- Content that will be edited, expanded, or reused
|
|
798
|
+
- Substantial text documents
|
|
799
|
+
- Technical documentation meant as reference material
|
|
800
|
+
|
|
801
|
+
**When NOT to Create Text-based Artifacts:**
|
|
802
|
+
- Simple answers, explanations, or conversational responses
|
|
803
|
+
- Brief advice, opinions, or quick information
|
|
804
|
+
- Short lists, summaries, or single paragraphs
|
|
805
|
+
- Temporary content only relevant to the immediate conversation
|
|
806
|
+
- Basic explanations that don't require reference material
|
|
807
|
+
"""
|
|
788
808
|
|
|
789
809
|
def _generate_embed_instruction(
|
|
790
810
|
include_artifact_content: bool,
|
|
@@ -918,7 +938,7 @@ When faced with a complex goal or request that involves multiple steps, data ret
|
|
|
918
938
|
Simple, direct requests like 'create an image of a dog' or 'write an email to thank my boss' do not require a plan.
|
|
919
939
|
|
|
920
940
|
If a plan is created:
|
|
921
|
-
1. It should be a terse, hierarchical list describing the steps needed.
|
|
941
|
+
1. It should be a terse, hierarchical list describing the steps needed, with each checkbox item on its own line.
|
|
922
942
|
2. Use '☐' (empty checkbox emoji) for pending items and '☑' (checked checkbox emoji) for completed items.
|
|
923
943
|
3. If the plan changes significantly during execution, restate the updated plan.
|
|
924
944
|
4. As items are completed, update the plan to check them off.
|
|
@@ -926,6 +946,8 @@ If a plan is created:
|
|
|
926
946
|
"""
|
|
927
947
|
injected_instructions.append(planning_instruction)
|
|
928
948
|
log.debug("%s Added hardcoded planning instructions.", log_identifier)
|
|
949
|
+
artifact_creation_instruction = _generate_artifact_creation_instruction()
|
|
950
|
+
injected_instructions.append(artifact_creation_instruction)
|
|
929
951
|
fenced_artifact_instruction = _generate_fenced_artifact_instruction()
|
|
930
952
|
injected_instructions.append(fenced_artifact_instruction)
|
|
931
953
|
|
|
@@ -371,11 +371,11 @@ class FilesystemArtifactService(BaseArtifactService):
|
|
|
371
371
|
sorted_versions = sorted(versions)
|
|
372
372
|
logger.debug("%sFound versions: %s", log_prefix, sorted_versions)
|
|
373
373
|
return sorted_versions
|
|
374
|
-
|
|
374
|
+
|
|
375
375
|
def _normalize_filename_unicode(self, filename: str) -> str:
|
|
376
376
|
"""
|
|
377
377
|
Normalizes Unicode characters in a filename to their standard form.
|
|
378
378
|
Specifically targets compatibility characters like non-breaking spaces (\u202f)
|
|
379
379
|
and converts them to their regular ASCII equivalents (a standard space).
|
|
380
380
|
"""
|
|
381
|
-
return unicodedata.normalize(
|
|
381
|
+
return unicodedata.normalize("NFKC", filename)
|
|
@@ -132,7 +132,7 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
132
132
|
logical_task_id,
|
|
133
133
|
tce,
|
|
134
134
|
)
|
|
135
|
-
sub_tasks_to_cancel = task_context.
|
|
135
|
+
sub_tasks_to_cancel = task_context.active_peer_sub_tasks if task_context else {}
|
|
136
136
|
|
|
137
137
|
if sub_tasks_to_cancel:
|
|
138
138
|
log.info(
|
|
@@ -141,18 +141,22 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
141
141
|
len(sub_tasks_to_cancel),
|
|
142
142
|
logical_task_id,
|
|
143
143
|
)
|
|
144
|
-
for sub_task_info in sub_tasks_to_cancel:
|
|
144
|
+
for sub_task_id, sub_task_info in sub_tasks_to_cancel.items():
|
|
145
145
|
try:
|
|
146
|
-
sub_task_id = sub_task_info.get("sub_task_id")
|
|
147
146
|
target_peer_agent_name = sub_task_info.get("peer_agent_name")
|
|
148
147
|
if not sub_task_id or not target_peer_agent_name:
|
|
149
148
|
log.warning(
|
|
150
|
-
"%s Incomplete sub-task info found, cannot cancel: %s",
|
|
149
|
+
"%s Incomplete sub-task info found for sub-task %s, cannot cancel: %s",
|
|
151
150
|
component.log_identifier,
|
|
151
|
+
sub_task_id,
|
|
152
152
|
sub_task_info,
|
|
153
153
|
)
|
|
154
154
|
continue
|
|
155
|
-
|
|
155
|
+
|
|
156
|
+
task_id_for_peer = sub_task_id.replace(
|
|
157
|
+
component.CORRELATION_DATA_PREFIX, "", 1
|
|
158
|
+
)
|
|
159
|
+
peer_cancel_params = TaskIdParams(id=task_id_for_peer)
|
|
156
160
|
peer_cancel_request = CancelTaskRequest(params=peer_cancel_params)
|
|
157
161
|
peer_cancel_user_props = {"clientId": component.agent_name}
|
|
158
162
|
peer_request_topic = component._get_agent_request_topic(
|
|
@@ -167,7 +171,7 @@ async def run_adk_async_task_thread_wrapper(
|
|
|
167
171
|
log.error(
|
|
168
172
|
"%s Failed to send CancelTaskRequest for sub-task %s: %s",
|
|
169
173
|
component.log_identifier,
|
|
170
|
-
|
|
174
|
+
sub_task_id,
|
|
171
175
|
e_peer_cancel,
|
|
172
176
|
exc_info=True,
|
|
173
177
|
)
|
|
@@ -28,7 +28,7 @@ from google.adk.memory import (
|
|
|
28
28
|
from .filesystem_artifact_service import FilesystemArtifactService
|
|
29
29
|
|
|
30
30
|
try:
|
|
31
|
-
from
|
|
31
|
+
from sam_test_infrastructure.artifact_service.service import (
|
|
32
32
|
TestInMemoryArtifactService,
|
|
33
33
|
)
|
|
34
34
|
except ImportError:
|
|
@@ -248,7 +248,7 @@ async def process_event(component, event: Event):
|
|
|
248
248
|
elif topic.startswith(agent_response_sub_prefix) or topic.startswith(
|
|
249
249
|
agent_status_sub_prefix
|
|
250
250
|
):
|
|
251
|
-
handle_a2a_response(component, message)
|
|
251
|
+
await handle_a2a_response(component, message)
|
|
252
252
|
else:
|
|
253
253
|
log.warning(
|
|
254
254
|
"%s Received message on unhandled topic: %s",
|
|
@@ -264,31 +264,8 @@ async def process_event(component, event: Event):
|
|
|
264
264
|
if timer_data.get("timer_id") == component._card_publish_timer_id:
|
|
265
265
|
publish_agent_card(component)
|
|
266
266
|
elif event.event_type == EventType.CACHE_EXPIRY:
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
"%s Received cache expiry event: %s",
|
|
270
|
-
component.log_identifier,
|
|
271
|
-
cache_data,
|
|
272
|
-
)
|
|
273
|
-
sub_task_id = cache_data.get("key")
|
|
274
|
-
if sub_task_id and sub_task_id.startswith(
|
|
275
|
-
component.CORRELATION_DATA_PREFIX
|
|
276
|
-
):
|
|
277
|
-
expired_data = cache_data.get("expired_data")
|
|
278
|
-
if expired_data:
|
|
279
|
-
await component._handle_peer_timeout(sub_task_id, expired_data)
|
|
280
|
-
else:
|
|
281
|
-
log.error(
|
|
282
|
-
"%s Missing expired_data in cache expiry event for sub-task %s. Cannot process timeout.",
|
|
283
|
-
component.log_identifier,
|
|
284
|
-
sub_task_id,
|
|
285
|
-
)
|
|
286
|
-
else:
|
|
287
|
-
log.debug(
|
|
288
|
-
"%s Cache expiry for key '%s' is not a peer sub-task timeout.",
|
|
289
|
-
component.log_identifier,
|
|
290
|
-
sub_task_id,
|
|
291
|
-
)
|
|
267
|
+
# Delegate cache expiry handling to the component itself.
|
|
268
|
+
await component.handle_cache_expiry_event(event.data)
|
|
292
269
|
else:
|
|
293
270
|
log.warning(
|
|
294
271
|
"%s Received unknown event type: %s",
|
|
@@ -854,10 +831,9 @@ def handle_agent_card_message(component, message: SolaceMessage):
|
|
|
854
831
|
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
855
832
|
|
|
856
833
|
|
|
857
|
-
def handle_a2a_response(component, message: SolaceMessage):
|
|
834
|
+
async def handle_a2a_response(component, message: SolaceMessage):
|
|
858
835
|
"""Handles incoming responses/status updates from peer agents."""
|
|
859
836
|
sub_task_id = None
|
|
860
|
-
agent_name = component.get_config("agent_name")
|
|
861
837
|
payload_to_queue = None
|
|
862
838
|
is_final_response = False
|
|
863
839
|
|
|
@@ -932,10 +908,8 @@ def handle_a2a_response(component, message: SolaceMessage):
|
|
|
932
908
|
component.log_identifier,
|
|
933
909
|
sub_task_id,
|
|
934
910
|
)
|
|
935
|
-
correlation_data = (
|
|
936
|
-
|
|
937
|
-
sub_task_id
|
|
938
|
-
)
|
|
911
|
+
correlation_data = await component._get_correlation_data_for_sub_task(
|
|
912
|
+
sub_task_id
|
|
939
913
|
)
|
|
940
914
|
if not correlation_data:
|
|
941
915
|
log.warning(
|
|
@@ -1227,7 +1201,12 @@ def handle_a2a_response(component, message: SolaceMessage):
|
|
|
1227
1201
|
"error": f"Failed to parse response from peer: {parse_error}",
|
|
1228
1202
|
"code": "PEER_PARSE_ERROR",
|
|
1229
1203
|
}
|
|
1230
|
-
|
|
1204
|
+
# Print out the stack trace for debugging
|
|
1205
|
+
log.exception(
|
|
1206
|
+
"%s Exception stack trace: %s",
|
|
1207
|
+
component.log_identifier,
|
|
1208
|
+
parse_error,
|
|
1209
|
+
)
|
|
1231
1210
|
|
|
1232
1211
|
if not is_final_response:
|
|
1233
1212
|
# This is an intermediate status update for monitoring.
|
|
@@ -1240,13 +1219,9 @@ def handle_a2a_response(component, message: SolaceMessage):
|
|
|
1240
1219
|
message.call_acknowledgements()
|
|
1241
1220
|
return
|
|
1242
1221
|
|
|
1243
|
-
correlation_data = component.
|
|
1222
|
+
correlation_data = await component._claim_peer_sub_task_completion(sub_task_id)
|
|
1244
1223
|
if not correlation_data:
|
|
1245
|
-
|
|
1246
|
-
"%s No correlation data found for sub-task %s. Cannot process response. Ignoring.",
|
|
1247
|
-
component.log_identifier,
|
|
1248
|
-
sub_task_id,
|
|
1249
|
-
)
|
|
1224
|
+
# The helper method logs the reason (timeout, already claimed, etc.)
|
|
1250
1225
|
message.call_acknowledgements()
|
|
1251
1226
|
return
|
|
1252
1227
|
|
|
@@ -53,6 +53,8 @@ from ...common.types import (
|
|
|
53
53
|
TaskStatusUpdateEvent,
|
|
54
54
|
TaskArtifactUpdateEvent,
|
|
55
55
|
SendTaskRequest,
|
|
56
|
+
CancelTaskRequest,
|
|
57
|
+
TaskIdParams,
|
|
56
58
|
)
|
|
57
59
|
from ...common.a2a_protocol import (
|
|
58
60
|
get_a2a_base_topic,
|
|
@@ -536,49 +538,123 @@ class SamAgentComponent(ComponentBase):
|
|
|
536
538
|
if timer_data.get("timer_id") == self._card_publish_timer_id:
|
|
537
539
|
publish_agent_card(self)
|
|
538
540
|
|
|
539
|
-
def handle_cache_expiry_event(self, cache_data: Dict[str, Any]):
|
|
540
|
-
"""
|
|
541
|
+
async def handle_cache_expiry_event(self, cache_data: Dict[str, Any]):
|
|
542
|
+
"""
|
|
543
|
+
Handles cache expiry events for peer timeouts by calling the atomic claim helper.
|
|
544
|
+
"""
|
|
541
545
|
log.debug("%s Received cache expiry event: %s", self.log_identifier, cache_data)
|
|
542
|
-
|
|
543
|
-
|
|
546
|
+
sub_task_id = cache_data.get("key")
|
|
547
|
+
logical_task_id = cache_data.get("expired_data")
|
|
548
|
+
|
|
549
|
+
if not (
|
|
550
|
+
sub_task_id
|
|
551
|
+
and sub_task_id.startswith(CORRELATION_DATA_PREFIX)
|
|
552
|
+
and logical_task_id
|
|
553
|
+
):
|
|
554
|
+
log.debug(
|
|
555
|
+
"%s Cache expiry for key '%s' is not a peer sub-task timeout or is missing data.",
|
|
556
|
+
self.log_identifier,
|
|
557
|
+
sub_task_id,
|
|
558
|
+
)
|
|
559
|
+
return
|
|
560
|
+
|
|
561
|
+
correlation_data = await self._claim_peer_sub_task_completion(
|
|
562
|
+
sub_task_id=sub_task_id, logical_task_id_from_event=logical_task_id
|
|
563
|
+
)
|
|
544
564
|
|
|
545
|
-
if
|
|
546
|
-
sub_task_id = expired_key
|
|
565
|
+
if correlation_data:
|
|
547
566
|
log.warning(
|
|
548
|
-
"%s Detected timeout for sub-task
|
|
567
|
+
"%s Detected timeout for sub-task %s (Main Task: %s). Claimed successfully.",
|
|
549
568
|
self.log_identifier,
|
|
550
569
|
sub_task_id,
|
|
570
|
+
logical_task_id,
|
|
551
571
|
)
|
|
552
|
-
|
|
553
|
-
try:
|
|
554
|
-
original_task_context = expired_data.get("original_task_context")
|
|
555
|
-
if original_task_context:
|
|
556
|
-
self._handle_peer_timeout(sub_task_id, expired_data)
|
|
557
|
-
else:
|
|
558
|
-
log.error(
|
|
559
|
-
"%s Missing 'original_task_context' in expired cache data for sub-task %s. Cannot process timeout.",
|
|
560
|
-
self.log_identifier,
|
|
561
|
-
sub_task_id,
|
|
562
|
-
)
|
|
563
|
-
except Exception as e:
|
|
564
|
-
log.exception(
|
|
565
|
-
"%s Error handling peer timeout for sub-task %s: %s",
|
|
566
|
-
self.log_identifier,
|
|
567
|
-
sub_task_id,
|
|
568
|
-
e,
|
|
569
|
-
)
|
|
570
|
-
else:
|
|
571
|
-
log.error(
|
|
572
|
-
"%s Missing expired_data in cache expiry event for sub-task %s. Cannot process timeout.",
|
|
573
|
-
self.log_identifier,
|
|
574
|
-
sub_task_id,
|
|
575
|
-
)
|
|
572
|
+
await self._handle_peer_timeout(sub_task_id, correlation_data)
|
|
576
573
|
else:
|
|
577
|
-
log.
|
|
578
|
-
"%s
|
|
574
|
+
log.info(
|
|
575
|
+
"%s Ignoring timeout event for sub-task %s as it was already completed.",
|
|
576
|
+
self.log_identifier,
|
|
577
|
+
sub_task_id,
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
async def _get_correlation_data_for_sub_task(
|
|
581
|
+
self, sub_task_id: str
|
|
582
|
+
) -> Optional[Dict[str, Any]]:
|
|
583
|
+
"""
|
|
584
|
+
Non-destructively retrieves correlation data for a sub-task.
|
|
585
|
+
Used for intermediate events where the sub-task should remain active.
|
|
586
|
+
"""
|
|
587
|
+
logical_task_id = self.cache_service.get_data(sub_task_id)
|
|
588
|
+
if not logical_task_id:
|
|
589
|
+
log.warning(
|
|
590
|
+
"%s No cache entry for sub-task %s. Cannot get correlation data.",
|
|
591
|
+
self.log_identifier,
|
|
592
|
+
sub_task_id,
|
|
593
|
+
)
|
|
594
|
+
return None
|
|
595
|
+
|
|
596
|
+
with self.active_tasks_lock:
|
|
597
|
+
task_context = self.active_tasks.get(logical_task_id)
|
|
598
|
+
|
|
599
|
+
if not task_context:
|
|
600
|
+
log.error(
|
|
601
|
+
"%s TaskExecutionContext not found for task %s, but cache entry existed for sub-task %s. This may indicate a cleanup issue.",
|
|
579
602
|
self.log_identifier,
|
|
580
|
-
|
|
603
|
+
logical_task_id,
|
|
604
|
+
sub_task_id,
|
|
605
|
+
)
|
|
606
|
+
return None
|
|
607
|
+
|
|
608
|
+
with task_context.lock:
|
|
609
|
+
return task_context.active_peer_sub_tasks.get(sub_task_id)
|
|
610
|
+
|
|
611
|
+
async def _claim_peer_sub_task_completion(
|
|
612
|
+
self, sub_task_id: str, logical_task_id_from_event: Optional[str] = None
|
|
613
|
+
) -> Optional[Dict[str, Any]]:
|
|
614
|
+
"""
|
|
615
|
+
Atomically claims a sub-task as complete, preventing race conditions.
|
|
616
|
+
This is a destructive operation that removes state.
|
|
617
|
+
|
|
618
|
+
Args:
|
|
619
|
+
sub_task_id: The ID of the sub-task to claim.
|
|
620
|
+
logical_task_id_from_event: The parent task ID, if provided by the event (e.g., a timeout).
|
|
621
|
+
If not provided, it will be looked up from the cache.
|
|
622
|
+
"""
|
|
623
|
+
log_id = f"{self.log_identifier}[ClaimSubTask:{sub_task_id}]"
|
|
624
|
+
logical_task_id = logical_task_id_from_event
|
|
625
|
+
|
|
626
|
+
if not logical_task_id:
|
|
627
|
+
logical_task_id = self.cache_service.get_data(sub_task_id)
|
|
628
|
+
if not logical_task_id:
|
|
629
|
+
log.warning(
|
|
630
|
+
"%s No cache entry found. Task has likely timed out and been cleaned up. Cannot claim.",
|
|
631
|
+
log_id,
|
|
632
|
+
)
|
|
633
|
+
return None
|
|
634
|
+
|
|
635
|
+
with self.active_tasks_lock:
|
|
636
|
+
task_context = self.active_tasks.get(logical_task_id)
|
|
637
|
+
|
|
638
|
+
if not task_context:
|
|
639
|
+
log.error(
|
|
640
|
+
"%s TaskExecutionContext not found for task %s. Cleaning up stale cache entry.",
|
|
641
|
+
log_id,
|
|
642
|
+
logical_task_id,
|
|
581
643
|
)
|
|
644
|
+
self.cache_service.remove_data(sub_task_id)
|
|
645
|
+
return None
|
|
646
|
+
|
|
647
|
+
correlation_data = task_context.claim_sub_task_completion(sub_task_id)
|
|
648
|
+
|
|
649
|
+
if correlation_data:
|
|
650
|
+
# If we successfully claimed the task, remove the timeout tracker from the cache.
|
|
651
|
+
self.cache_service.remove_data(sub_task_id)
|
|
652
|
+
log.info("%s Successfully claimed completion.", log_id)
|
|
653
|
+
return correlation_data
|
|
654
|
+
else:
|
|
655
|
+
# This means the task was already claimed by a competing event (e.g., timeout vs. response).
|
|
656
|
+
log.warning("%s Failed to claim; it was already completed.", log_id)
|
|
657
|
+
return None
|
|
582
658
|
|
|
583
659
|
async def _retrigger_agent_with_peer_responses(
|
|
584
660
|
self,
|
|
@@ -686,8 +762,9 @@ class SamAgentComponent(ComponentBase):
|
|
|
686
762
|
correlation_data: Dict[str, Any],
|
|
687
763
|
):
|
|
688
764
|
"""
|
|
689
|
-
Handles the timeout of a peer agent task
|
|
690
|
-
|
|
765
|
+
Handles the timeout of a peer agent task. It sends a cancellation request
|
|
766
|
+
to the peer, updates the local completion counter, and potentially
|
|
767
|
+
re-triggers the runner if all parallel tasks are now complete.
|
|
691
768
|
"""
|
|
692
769
|
logical_task_id = correlation_data.get("logical_task_id")
|
|
693
770
|
invocation_id = correlation_data.get("invocation_id")
|
|
@@ -700,6 +777,36 @@ class SamAgentComponent(ComponentBase):
|
|
|
700
777
|
invocation_id,
|
|
701
778
|
)
|
|
702
779
|
|
|
780
|
+
# Proactively send a cancellation request to the peer agent.
|
|
781
|
+
peer_agent_name = correlation_data.get("peer_agent_name")
|
|
782
|
+
if peer_agent_name:
|
|
783
|
+
try:
|
|
784
|
+
log.info(
|
|
785
|
+
"%s Sending CancelTaskRequest to peer '%s' for timed-out sub-task %s.",
|
|
786
|
+
log_retrigger,
|
|
787
|
+
peer_agent_name,
|
|
788
|
+
sub_task_id,
|
|
789
|
+
)
|
|
790
|
+
task_id_for_peer = sub_task_id.replace(CORRELATION_DATA_PREFIX, "", 1)
|
|
791
|
+
cancel_params = TaskIdParams(id=task_id_for_peer)
|
|
792
|
+
cancel_request = CancelTaskRequest(params=cancel_params)
|
|
793
|
+
user_props = {"clientId": self.agent_name}
|
|
794
|
+
peer_topic = self._get_agent_request_topic(peer_agent_name)
|
|
795
|
+
self._publish_a2a_message(
|
|
796
|
+
payload=cancel_request.model_dump(exclude_none=True),
|
|
797
|
+
topic=peer_topic,
|
|
798
|
+
user_properties=user_props,
|
|
799
|
+
)
|
|
800
|
+
except Exception as e:
|
|
801
|
+
log.error(
|
|
802
|
+
"%s Failed to send CancelTaskRequest to peer '%s' for sub-task %s: %s",
|
|
803
|
+
log_retrigger,
|
|
804
|
+
peer_agent_name,
|
|
805
|
+
sub_task_id,
|
|
806
|
+
e,
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
# Process the timeout locally.
|
|
703
810
|
with self.active_tasks_lock:
|
|
704
811
|
task_context = self.active_tasks.get(logical_task_id)
|
|
705
812
|
|
|
@@ -1841,7 +1948,8 @@ class SamAgentComponent(ComponentBase):
|
|
|
1841
1948
|
len(unprocessed_tail.encode("utf-8")),
|
|
1842
1949
|
)
|
|
1843
1950
|
else:
|
|
1844
|
-
|
|
1951
|
+
if unprocessed_tail is not None and unprocessed_tail != "":
|
|
1952
|
+
resolved_text = resolved_text + unprocessed_tail
|
|
1845
1953
|
|
|
1846
1954
|
if signals_found:
|
|
1847
1955
|
log.info(
|
|
@@ -27,7 +27,7 @@ class TaskExecutionContext:
|
|
|
27
27
|
self.cancellation_event: asyncio.Event = asyncio.Event()
|
|
28
28
|
self.streaming_buffer: str = ""
|
|
29
29
|
self.run_based_response_buffer: str = ""
|
|
30
|
-
self.
|
|
30
|
+
self.active_peer_sub_tasks: Dict[str, Dict[str, Any]] = {}
|
|
31
31
|
self.parallel_tool_calls: Dict[str, Dict[str, Any]] = {}
|
|
32
32
|
self.produced_artifacts: List[Dict[str, Any]] = []
|
|
33
33
|
self.artifact_signals_to_return: List[Dict[str, Any]] = []
|
|
@@ -64,12 +64,21 @@ class TaskExecutionContext:
|
|
|
64
64
|
with self.lock:
|
|
65
65
|
self.run_based_response_buffer += text
|
|
66
66
|
|
|
67
|
-
def register_peer_sub_task(
|
|
68
|
-
|
|
67
|
+
def register_peer_sub_task(
|
|
68
|
+
self, sub_task_id: str, correlation_data: Dict[str, Any]
|
|
69
|
+
) -> None:
|
|
70
|
+
"""Adds a new peer sub-task's correlation data to the tracking dictionary."""
|
|
69
71
|
with self.lock:
|
|
70
|
-
self.
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
self.active_peer_sub_tasks[sub_task_id] = correlation_data
|
|
73
|
+
|
|
74
|
+
def claim_sub_task_completion(self, sub_task_id: str) -> Optional[Dict[str, Any]]:
|
|
75
|
+
"""
|
|
76
|
+
Atomically retrieves and removes a sub-task's correlation data.
|
|
77
|
+
This is the core atomic operation to prevent race conditions.
|
|
78
|
+
Returns the correlation data if the claim is successful, otherwise None.
|
|
79
|
+
"""
|
|
80
|
+
with self.lock:
|
|
81
|
+
return self.active_peer_sub_tasks.pop(sub_task_id, None)
|
|
73
82
|
|
|
74
83
|
def register_parallel_call_sent(self, invocation_id: str) -> None:
|
|
75
84
|
"""
|
|
@@ -397,7 +397,8 @@ async def mermaid_diagram_generator(
|
|
|
397
397
|
"message": "Failed to render Mermaid diagram. No image data returned.",
|
|
398
398
|
}
|
|
399
399
|
try:
|
|
400
|
-
|
|
400
|
+
scale = max(2, len(mermaid_syntax.splitlines()) // 10)
|
|
401
|
+
image_data = await _convert_svg_to_png_with_playwright(svg_image_data.decode("utf-8"), scale)
|
|
401
402
|
except Exception as e:
|
|
402
403
|
log.error(
|
|
403
404
|
"%s Failed to convert SVG to PNG with Playwright: %s",
|
|
@@ -410,8 +411,9 @@ async def mermaid_diagram_generator(
|
|
|
410
411
|
}
|
|
411
412
|
|
|
412
413
|
log.debug(
|
|
413
|
-
"%s Mermaid diagram rendered successfully, image_data length: %d bytes",
|
|
414
|
+
"%s Mermaid diagram rendered successfully with scale %d, image_data length: %d bytes",
|
|
414
415
|
log_identifier,
|
|
416
|
+
scale,
|
|
415
417
|
len(image_data),
|
|
416
418
|
)
|
|
417
419
|
|
|
@@ -243,13 +243,18 @@ class PeerAgentTool(BaseTool):
|
|
|
243
243
|
"adk_function_call_id": tool_context.function_call_id,
|
|
244
244
|
"original_task_context": original_task_context,
|
|
245
245
|
"peer_tool_name": self.name,
|
|
246
|
+
"peer_agent_name": self.target_agent_name,
|
|
246
247
|
"logical_task_id": main_logical_task_id,
|
|
247
248
|
"invocation_id": invocation_id,
|
|
248
249
|
}
|
|
249
250
|
|
|
251
|
+
# Register the sub-task's state within the parent task's context.
|
|
252
|
+
task_context_obj.register_peer_sub_task(sub_task_id, correlation_data)
|
|
253
|
+
|
|
254
|
+
# Add a simple mapping to the cache for timeout tracking.
|
|
250
255
|
self.host_component.cache_service.add_data(
|
|
251
256
|
key=sub_task_id,
|
|
252
|
-
value=
|
|
257
|
+
value=main_logical_task_id,
|
|
253
258
|
expiry=timeout_sec,
|
|
254
259
|
component=self.host_component,
|
|
255
260
|
)
|
|
@@ -264,10 +269,6 @@ class PeerAgentTool(BaseTool):
|
|
|
264
269
|
sub_task_id=sub_task_id,
|
|
265
270
|
function_call_id=tool_context.function_call_id,
|
|
266
271
|
)
|
|
267
|
-
|
|
268
|
-
task_context_obj.register_peer_sub_task(
|
|
269
|
-
sub_task_id=sub_task_id, peer_agent_name=self.target_agent_name
|
|
270
|
-
)
|
|
271
272
|
log.info(
|
|
272
273
|
"%s Registered active peer sub-task %s for main task %s.",
|
|
273
274
|
log_identifier,
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="generator" content="Docusaurus v3.8.1">
|
|
6
6
|
<title data-rh="true">Page Not Found | Solace Agent Mesh</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://solacelabs.github.io/solace-agent-mesh/img/logo.png"><meta data-rh="true" name="twitter:image" content="https://solacelabs.github.io/solace-agent-mesh/img/logo.png"><meta data-rh="true" property="og:url" content="https://solacelabs.github.io/solace-agent-mesh/404.html"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docusaurus_tag" content="default"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docsearch:docusaurus_tag" content="default"><meta data-rh="true" property="og:title" content="Page Not Found | Solace Agent Mesh"><link data-rh="true" rel="icon" href="/solace-agent-mesh/img/logo.png"><link data-rh="true" rel="canonical" href="https://solacelabs.github.io/solace-agent-mesh/404.html"><link data-rh="true" rel="alternate" href="https://solacelabs.github.io/solace-agent-mesh/404.html" hreflang="en"><link data-rh="true" rel="alternate" href="https://solacelabs.github.io/solace-agent-mesh/404.html" hreflang="x-default"><link rel="stylesheet" href="/solace-agent-mesh/assets/css/styles.906a1503.css">
|
|
7
|
-
<script src="/solace-agent-mesh/assets/js/runtime~main.
|
|
8
|
-
<script src="/solace-agent-mesh/assets/js/main.
|
|
7
|
+
<script src="/solace-agent-mesh/assets/js/runtime~main.d5133813.js" defer="defer"></script>
|
|
8
|
+
<script src="/solace-agent-mesh/assets/js/main.c6286d7c.js" defer="defer"></script>
|
|
9
9
|
</head>
|
|
10
10
|
<body class="navigation-with-keyboard">
|
|
11
11
|
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><defs>
|
|
12
12
|
<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
|
|
13
13
|
</defs></svg>
|
|
14
|
-
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><link rel="preload" as="image" href="/solace-agent-mesh/img/logo.png"><link rel="preload" as="image" href="/solace-agent-mesh/img/solace-logo.png"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/solace-agent-mesh/docs/documentation/getting-started/introduction"><div class="navbar__logo"><img src="/solace-agent-mesh/img/logo.png" alt="Solace Agent Mesh Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/solace-agent-mesh/img/logo.png" alt="Solace Agent Mesh Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">Solace Agent Mesh</b></a><a class="navbar__item navbar__link" href="/solace-agent-mesh/docs/documentation/getting-started/introduction">Documentation</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://github.com/SolaceLabs/solace-agent-mesh/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_Bca1"><div class="navbar__search"><span aria-label="expand searchbar" role="button" class="search-icon" tabindex="0"></span><input id="search_input_react" type="search" placeholder="Loading..." aria-label="Search" class="navbar__search-input search-bar" disabled=""></div></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><main class="container margin-vert--xl"><div class="row"><div class="col col--6 col--offset-3"><h1 class="hero__title">Page Not Found</h1><p>We could not find what you were looking for.</p><p>Please contact the owner of the site that linked you to the original URL and let them know their link is broken.</p></div></div></main></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Solace Agent Mesh</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/solace-agent-mesh/docs/documentation/getting-started/introduction">Documentation</a></li><li class="footer__item"><a href="https://github.com/SolaceLabs/solace-agent-mesh/" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Official Plugins<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Company</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://solace.com/products/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Products<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/contact/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Contact<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/support/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Support<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/legal/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Privacy and Legal<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://www.linkedin.com/company/solacedotcom/" target="_blank" rel="noopener noreferrer" class="footer__link-item">LinkedIn<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/SolaceLabs" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://www.youtube.com/SolaceSystems" target="_blank" rel="noopener noreferrer" class="footer__link-item">YouTube<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://twitter.com/solacedotcom" target="_blank" rel="noopener noreferrer" class="footer__link-item">X<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><img src="/solace-agent-mesh/img/solace-logo.png" alt="Solace Logo" class="footer__logo themedComponent_mlkZ themedComponent--light_NVdE" width="10%" height="10%"><img src="/solace-agent-mesh/img/solace-logo.png" alt="Solace Logo" class="footer__logo themedComponent_mlkZ themedComponent--dark_xIcU" width="10%" height="10%"></div><div class="footer__copyright">Solace Agent Mesh. Copyright © 2025 Solace. Version: 1.0.
|
|
14
|
+
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><link rel="preload" as="image" href="/solace-agent-mesh/img/logo.png"><link rel="preload" as="image" href="/solace-agent-mesh/img/solace-logo.png"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/solace-agent-mesh/docs/documentation/getting-started/introduction"><div class="navbar__logo"><img src="/solace-agent-mesh/img/logo.png" alt="Solace Agent Mesh Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/solace-agent-mesh/img/logo.png" alt="Solace Agent Mesh Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">Solace Agent Mesh</b></a><a class="navbar__item navbar__link" href="/solace-agent-mesh/docs/documentation/getting-started/introduction">Documentation</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><a href="https://github.com/SolaceLabs/solace-agent-mesh/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div><div class="navbarSearchContainer_Bca1"><div class="navbar__search"><span aria-label="expand searchbar" role="button" class="search-icon" tabindex="0"></span><input id="search_input_react" type="search" placeholder="Loading..." aria-label="Search" class="navbar__search-input search-bar" disabled=""></div></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><main class="container margin-vert--xl"><div class="row"><div class="col col--6 col--offset-3"><h1 class="hero__title">Page Not Found</h1><p>We could not find what you were looking for.</p><p>Please contact the owner of the site that linked you to the original URL and let them know their link is broken.</p></div></div></main></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Solace Agent Mesh</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/solace-agent-mesh/docs/documentation/getting-started/introduction">Documentation</a></li><li class="footer__item"><a href="https://github.com/SolaceLabs/solace-agent-mesh/" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Official Plugins<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Company</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://solace.com/products/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Products<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/contact/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Contact<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/support/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Support<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://solace.com/legal/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Privacy and Legal<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://www.linkedin.com/company/solacedotcom/" target="_blank" rel="noopener noreferrer" class="footer__link-item">LinkedIn<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/SolaceLabs" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://www.youtube.com/SolaceSystems" target="_blank" rel="noopener noreferrer" class="footer__link-item">YouTube<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://twitter.com/solacedotcom" target="_blank" rel="noopener noreferrer" class="footer__link-item">X<svg width="13.5" height="13.5" aria-hidden="true" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><img src="/solace-agent-mesh/img/solace-logo.png" alt="Solace Logo" class="footer__logo themedComponent_mlkZ themedComponent--light_NVdE" width="10%" height="10%"><img src="/solace-agent-mesh/img/solace-logo.png" alt="Solace Logo" class="footer__logo themedComponent_mlkZ themedComponent--dark_xIcU" width="10%" height="10%"></div><div class="footer__copyright">Solace Agent Mesh. Copyright © 2025 Solace. Version: 1.0.2</div></div></div></footer></div>
|
|
15
15
|
</body>
|
|
16
16
|
</html>
|