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.

Files changed (220) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
  2. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  3. solace_agent_mesh/agent/adk/callbacks.py +165 -104
  4. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
  5. solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
  6. solace_agent_mesh/agent/adk/runner.py +25 -17
  7. solace_agent_mesh/agent/adk/services.py +3 -3
  8. solace_agent_mesh/agent/adk/setup.py +11 -0
  9. solace_agent_mesh/agent/adk/stream_parser.py +8 -1
  10. solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
  11. solace_agent_mesh/agent/agent_llm.txt +355 -18
  12. solace_agent_mesh/agent/protocol/event_handlers.py +460 -317
  13. solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
  14. solace_agent_mesh/agent/sac/app.py +2 -2
  15. solace_agent_mesh/agent/sac/component.py +211 -517
  16. solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
  17. solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
  18. solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
  19. solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
  20. solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
  21. solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
  22. solace_agent_mesh/assets/docs/404.html +3 -3
  23. solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
  25. solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/main.08d30374.js +2 -0
  28. solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
  29. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  38. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
  43. 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
  44. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +4 -4
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  64. solace_agent_mesh/assets/docs/lunr-index-1757433031159.json +1 -0
  65. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  66. solace_agent_mesh/assets/docs/search-doc-1757433031159.json +1 -0
  67. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  68. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  69. solace_agent_mesh/cli/__init__.py +1 -1
  70. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +125 -48
  71. solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
  72. solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
  73. solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
  74. solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
  75. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
  76. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
  77. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
  78. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
  79. solace_agent_mesh/cli/commands/run_cmd.py +5 -3
  80. solace_agent_mesh/cli/utils.py +68 -12
  81. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-vY5eu2lI.js +1 -0
  82. solace_agent_mesh/client/webui/frontend/static/assets/client-BeBkzgWW.js +25 -0
  83. solace_agent_mesh/client/webui/frontend/static/assets/main-Bjys1KQs.js +339 -0
  84. solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
  85. solace_agent_mesh/client/webui/frontend/static/assets/vendor-CE0AeXyK.js +395 -0
  86. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
  87. solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
  88. solace_agent_mesh/common/a2a/__init__.py +213 -0
  89. solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
  90. solace_agent_mesh/common/a2a/artifact.py +328 -0
  91. solace_agent_mesh/common/a2a/events.py +183 -0
  92. solace_agent_mesh/common/a2a/message.py +307 -0
  93. solace_agent_mesh/common/a2a/protocol.py +513 -0
  94. solace_agent_mesh/common/a2a/task.py +127 -0
  95. solace_agent_mesh/common/a2a/translation.py +653 -0
  96. solace_agent_mesh/common/a2a/types.py +54 -0
  97. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  98. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
  99. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  100. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
  101. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
  102. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
  103. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  104. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
  105. solace_agent_mesh/common/agent_registry.py +1 -1
  106. solace_agent_mesh/common/common_llm.txt +192 -70
  107. solace_agent_mesh/common/data_parts.py +99 -0
  108. solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
  109. solace_agent_mesh/common/sac/__init__.py +0 -0
  110. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  111. solace_agent_mesh/common/sac/sam_component_base.py +252 -0
  112. solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
  113. solace_agent_mesh/common/services/services_llm.txt +206 -26
  114. solace_agent_mesh/common/utils/artifact_utils.py +29 -0
  115. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
  116. solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
  117. solace_agent_mesh/common/utils/utils_llm.txt +323 -42
  118. solace_agent_mesh/config_portal/backend/common.py +2 -2
  119. solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +1 -1
  120. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
  121. solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
  122. solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
  123. solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
  124. solace_agent_mesh/core_a2a/service.py +20 -44
  125. solace_agent_mesh/evaluation/message_organizer.py +35 -56
  126. solace_agent_mesh/evaluation/run.py +26 -5
  127. solace_agent_mesh/evaluation/subscriber.py +35 -10
  128. solace_agent_mesh/evaluation/summary_builder.py +27 -34
  129. solace_agent_mesh/gateway/base/app.py +27 -1
  130. solace_agent_mesh/gateway/base/base_llm.txt +177 -72
  131. solace_agent_mesh/gateway/base/component.py +294 -523
  132. solace_agent_mesh/gateway/gateway_llm.txt +299 -58
  133. solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
  134. solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
  135. solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
  136. solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
  137. solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
  138. solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
  139. solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
  140. solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
  141. solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
  142. solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
  143. solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
  144. solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
  145. solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
  146. solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
  147. solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
  148. solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
  149. solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
  150. solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
  151. solace_agent_mesh/gateway/http_sse/app.py +31 -1
  152. solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
  153. solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
  154. solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
  155. solace_agent_mesh/gateway/http_sse/component.py +371 -236
  156. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
  157. solace_agent_mesh/gateway/http_sse/dependencies.py +142 -39
  158. solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
  159. solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
  160. solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
  161. solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
  162. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
  163. solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
  164. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
  165. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
  166. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
  167. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
  168. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
  169. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
  170. solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
  171. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
  172. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
  173. solace_agent_mesh/gateway/http_sse/main.py +293 -91
  174. solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
  175. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +137 -56
  176. solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
  177. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
  178. solace_agent_mesh/gateway/http_sse/routers/tasks.py +199 -171
  179. solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
  180. solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
  181. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
  182. solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
  183. solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
  184. solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
  185. solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
  186. solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
  187. solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
  188. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  189. solace_agent_mesh/templates/gateway_component_template.py +149 -98
  190. solace_agent_mesh/templates/shared_config.yaml +4 -5
  191. solace_agent_mesh/templates/webui.yaml +8 -10
  192. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/METADATA +9 -6
  193. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/RECORD +197 -141
  194. solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
  195. solace_agent_mesh/assets/docs/assets/js/main.3d0e7879.js +0 -2
  196. solace_agent_mesh/assets/docs/assets/js/runtime~main.05d19492.js +0 -1
  197. solace_agent_mesh/assets/docs/lunr-index-1757091012487.json +0 -1
  198. solace_agent_mesh/assets/docs/search-doc-1757091012487.json +0 -1
  199. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
  200. solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
  201. solace_agent_mesh/client/webui/frontend/static/assets/main-D0FnP_W4.css +0 -1
  202. solace_agent_mesh/client/webui/frontend/static/assets/main-Do32sFPX.js +0 -708
  203. solace_agent_mesh/common/a2a_protocol.py +0 -564
  204. solace_agent_mesh/common/client/__init__.py +0 -4
  205. solace_agent_mesh/common/client/card_resolver.py +0 -21
  206. solace_agent_mesh/common/client/client.py +0 -85
  207. solace_agent_mesh/common/client/client_llm.txt +0 -133
  208. solace_agent_mesh/common/server/__init__.py +0 -4
  209. solace_agent_mesh/common/server/server.py +0 -122
  210. solace_agent_mesh/common/server/server_llm.txt +0 -169
  211. solace_agent_mesh/common/server/task_manager.py +0 -291
  212. solace_agent_mesh/common/server/utils.py +0 -28
  213. solace_agent_mesh/common/types.py +0 -411
  214. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
  215. solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -80
  216. solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
  217. /solace_agent_mesh/assets/docs/assets/js/{main.3d0e7879.js.LICENSE.txt → main.08d30374.js.LICENSE.txt} +0 -0
  218. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/WHEEL +0 -0
  219. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/entry_points.txt +0 -0
  220. {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -2,13 +2,11 @@
2
2
  Solace Agent Mesh Component class for the __GATEWAY_NAME_PASCAL_CASE__ Gateway.
3
3
  """
4
4
 
5
- import asyncio # If needed for async operations with external system
6
5
  from typing import Any, Dict, List, Optional, Tuple, Union
7
6
 
8
7
  from solace_ai_connector.common.log import log
9
8
  from solace_agent_mesh.gateway.base.component import BaseGatewayComponent
10
- from solace_agent_mesh.common.types import (
11
- Part as A2APart,
9
+ from a2a.types import (
12
10
  TextPart,
13
11
  FilePart, # If handling files
14
12
  DataPart, # If handling structured data
@@ -16,10 +14,9 @@ from solace_agent_mesh.common.types import (
16
14
  TaskStatusUpdateEvent,
17
15
  TaskArtifactUpdateEvent,
18
16
  JSONRPCError,
19
- FileContent, # Added for FilePart example
20
17
  )
21
-
22
- # from solace_agent_mesh.core_a2a.service import CoreA2AService # If direct interaction needed
18
+ from ...common import a2a
19
+ from ...common.a2a import ContentPart
23
20
 
24
21
  info = {
25
22
  "class_name": "__GATEWAY_NAME_PASCAL_CASE__GatewayComponent",
@@ -28,14 +25,9 @@ info = {
28
25
  "Handles communication between the __GATEWAY_NAME_SNAKE_CASE__ system and the A2A agent ecosystem."
29
26
  ),
30
27
  "config_parameters": [], # Defined by __GATEWAY_NAME_PASCAL_CASE__GatewayApp
31
- "input_schema": {
32
- "type": "object",
33
- "description": "Not typically used directly by GDK; component reacts to external events or A2A control messages.",
34
- },
35
- "output_schema": {
36
- "type": "object",
37
- "description": "Not typically used directly by GDK; component publishes results to external system or A2A.",
38
- },
28
+ # Not needed for gateway components
29
+ "input_schema": {},
30
+ "output_schema": {},
39
31
  }
40
32
 
41
33
 
@@ -101,13 +93,30 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
101
93
  # try:
102
94
  # # new_events = await self.external_client.get_new_events() # Or sync equivalent
103
95
  # # for event_data in new_events:
104
- # # # Process each event: authenticate, translate, submit A2A task
105
- # # # This often involves calling other GDK methods or internal helpers
106
- # # authenticated_user = await self._authenticate_external_user(event_data)
107
- # # if authenticated_user:
108
- # # target_agent, parts, context = await self._translate_external_input(event_data, authenticated_user)
109
- # # if target_agent and parts:
110
- # # await self.submit_a2a_task(target_agent, parts, context, authenticated_user)
96
+ # # # 1. Authenticate the user and enrich their profile.
97
+ # # user_identity = await self.authenticate_and_enrich_user(event_data)
98
+ # # if not user_identity:
99
+ # # log.warning("%s Authentication failed for event, skipping.", log_id_prefix)
100
+ # # continue
101
+ # #
102
+ # # # 2. Translate the external event into an A2A task.
103
+ # # try:
104
+ # # target_agent, parts, context = await self._translate_external_input(event_data)
105
+ # # except ValueError as e:
106
+ # # log.error("%s Translation failed for event: %s", log_id_prefix, e)
107
+ # # # Optionally, send an error back to the user in the external system here.
108
+ # # continue
109
+ # #
110
+ # # # 3. Submit the A2A task.
111
+ # # if target_agent and parts:
112
+ # # await self.submit_a2a_task(
113
+ # # target_agent_name=target_agent,
114
+ # # a2a_parts=parts,
115
+ # # external_request_context=context,
116
+ # # user_identity=user_identity,
117
+ # # is_streaming=True # Or False, depending on gateway needs
118
+ # # )
119
+ # #
111
120
  # # await asyncio.sleep(self.get_config("polling_interval_seconds", 60))
112
121
  # pass # Placeholder
113
122
  # except asyncio.CancelledError:
@@ -150,65 +159,85 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
150
159
  "%s __GATEWAY_NAME_SNAKE_CASE__ listener shutdown initiated.", log_id_prefix
151
160
  )
152
161
 
153
- async def _authenticate_external_user(
154
- self, external_event_data: Any # Type hint with actual external event data type
155
- ) -> Optional[str]:
162
+ async def _extract_initial_claims(
163
+ self, external_event_data: Any
164
+ ) -> Optional[Dict[str, Any]]:
156
165
  """
157
- GDK Hook: Authenticates the user or system from the external event data.
158
- - Implement logic based on your gateway's authentication mechanism (e.g., API key, token, signature).
159
- - Use configurations retrieved in __init__ (e.g., self.service_api_key).
160
- - Return a unique user/system identifier (string) on success, or None on failure.
161
- This identifier will be used for A2A authorization (scope checking).
166
+ GDK Hook: Extracts the primary identity claims from a platform-specific event.
167
+ This method MUST be implemented by derived gateway components.
168
+
169
+ The base class's `authenticate_and_enrich_user` method will call this,
170
+ and then (if configured) pass the result to an Identity Service for enrichment.
171
+
172
+ Args:
173
+ external_event_data: Raw event data from the external platform
174
+ (e.g., FastAPIRequest, Slack event dictionary).
175
+
176
+ Returns:
177
+ A dictionary of initial claims, which MUST include an 'id' key.
178
+ Example: {"id": "user@example.com", "source": "api_key"}
179
+ Return None if authentication fails.
162
180
  """
163
- log_id_prefix = f"{self.log_identifier}[AuthenticateUser]"
164
- # log.debug("%s Authenticating external event: %s", log_id_prefix, external_event_data)
181
+ log_id_prefix = f"{self.log_identifier}[ExtractClaims]"
182
+ # log.debug("%s Extracting initial claims from external event: %s", log_id_prefix, external_event_data)
165
183
 
166
- # --- Implement Authentication Logic Here ---
184
+ # --- Implement Claims Extraction Logic Here ---
167
185
  # Example: Check an API key from headers or payload
168
186
  # provided_key = external_event_data.get("headers", {}).get("X-API-Key")
169
- # if provided_key and provided_key == self.service_api_key:
170
- # user_identity = external_event_data.get("user_id_field", "default_system_user")
171
- # log.info("%s Authentication successful for user: %s", log_id_prefix, user_identity)
172
- # return user_identity
187
+ # if provided_key and provided_key == self.get_config("service_api_key"):
188
+ # user_id = external_event_data.get("user_id_field", "default_system_user")
189
+ # log.info("%s Authentication successful for user: %s", log_id_prefix, user_id)
190
+ # return {"id": user_id, "source": "api_key"}
173
191
  # else:
174
192
  # log.warning("%s Authentication failed: API key mismatch or missing.", log_id_prefix)
175
193
  # return None
176
194
 
177
- # If no authentication is needed for this gateway:
178
- # return "anonymous___GATEWAY_NAME_SNAKE_CASE___user"
195
+ # If no authentication is needed for this gateway, you can use a default identity
196
+ # from the configuration. The base class handles this logic if `force_user_identity`
197
+ # or `default_user_identity` are set, but you can implement it here if needed.
198
+ # return {"id": "anonymous___GATEWAY_NAME_SNAKE_CASE___user", "source": "anonymous"}
179
199
 
180
- log.warning(
181
- "%s _authenticate_external_user not fully implemented.", log_id_prefix
182
- )
183
- return "placeholder_user_identity" # Replace with actual logic
200
+ log.warning("%s _extract_initial_claims not fully implemented.", log_id_prefix)
201
+ return {
202
+ "id": "placeholder_user_identity",
203
+ "source": "placeholder",
204
+ } # Replace with actual logic
184
205
 
185
206
  async def _translate_external_input(
186
- self, external_event_data: Any, authenticated_user_identity: str
187
- ) -> Tuple[Optional[str], List[A2APart], Dict[str, Any]]:
207
+ self, external_event_data: Any
208
+ ) -> Tuple[str, List[ContentPart], Dict[str, Any]]:
188
209
  """
189
- GDK Hook: Translates the incoming external event/request into an A2A task.
190
- - `external_event_data`: The raw data from the external system.
191
- - `authenticated_user_identity`: The identity returned by _authenticate_external_user.
192
-
193
- Returns a tuple:
194
- - `target_agent_name` (str | None): Name of the A2A agent to route the task to. None if translation fails.
195
- - `a2a_parts` (List[A2APart]): List of A2A Parts (TextPart, FilePart, DataPart) for the task.
196
- - `external_request_context` (Dict[str, Any]): Dictionary to store any context needed later
197
- (e.g., for _send_final_response_to_external, like original request ID, reply-to address).
210
+ GDK Hook: Translates the incoming external event/request into A2A task parameters.
211
+ This method is called *after* `authenticate_and_enrich_user`. The gateway's
212
+ event processing logic (e.g., a polling loop or request handler) is responsible
213
+ for calling `authenticate_and_enrich_user` first, and then passing the raw
214
+ event data to this method.
215
+
216
+ Args:
217
+ external_event_data: The raw data from the external system.
218
+
219
+ Returns:
220
+ A tuple:
221
+ - `target_agent_name` (str): Name of the A2A agent to route the task to.
222
+ - `a2a_parts` (List[ContentPart]): List of A2A Parts for the task.
223
+ - `external_request_context` (Dict[str, Any]): Dictionary to store any context
224
+ needed later (e.g., for _send_final_response_to_external).
225
+
226
+ Raises:
227
+ ValueError: If translation fails (e.g., target agent cannot be determined).
198
228
  """
199
229
  log_id_prefix = f"{self.log_identifier}[TranslateInput]"
200
230
  # log.debug("%s Translating external event: %s", log_id_prefix, external_event_data)
201
231
 
202
- a2a_parts: List[A2APart] = []
232
+ a2a_parts: List[ContentPart] = []
203
233
  target_agent_name: Optional[str] = (
204
234
  None # Determine this based on event data or config
205
235
  )
236
+ # This context is stored and passed back to the `_send_*_to_external` methods.
237
+ # It should contain any information needed to route the response back to the
238
+ # original requester in the external system.
206
239
  external_request_context: Dict[str, Any] = {
207
- "user_id_for_a2a": authenticated_user_identity,
208
- "app_name_for_artifacts": self.gateway_id, # For artifact service context
209
- "user_id_for_artifacts": authenticated_user_identity,
210
240
  "a2a_session_id": f"__GATEWAY_NAME_SNAKE_CASE__-session-{self.generate_uuid()}", # Example session ID
211
- # Add any other relevant context from external_event_data needed for response handling
212
241
  # "original_request_id": external_event_data.get("id"),
213
242
  }
214
243
 
@@ -227,23 +256,24 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
227
256
  # - Extract text:
228
257
  # text_content = external_event_data.get("message_text", "")
229
258
  # if text_content:
230
- # a2a_parts.append(TextPart(text=text_content))
259
+ # a2a_parts.append(a2a.create_text_part(text=text_content))
231
260
  # - Handle files (if any): Download, save to artifact service, create FilePart with URI.
232
- # (Requires self.shared_artifact_service to be configured and available)
261
+ # (Requires self.shared_artifact_service to be configured and available).
262
+ # The `user_identity` dict is available in the calling context (e.g., polling loop).
233
263
  # # if "file_url" in external_event_data and self.shared_artifact_service:
234
264
  # # file_bytes = await download_file(external_event_data["file_url"])
235
265
  # # file_name = external_event_data.get("file_name", "attachment.dat")
236
266
  # # mime_type = external_event_data.get("mime_type", "application/octet-stream")
237
267
  # # artifact_uri = await self.save_to_artifact_service(
238
268
  # # file_bytes, file_name, mime_type,
239
- # # authenticated_user_identity, external_request_context["a2a_session_id"]
269
+ # # user_identity, external_request_context["a2a_session_id"]
240
270
  # # )
241
271
  # # if artifact_uri:
242
- # # a2a_parts.append(FilePart(file=FileContent(name=file_name, mimeType=mime_type, uri=artifact_uri)))
272
+ # # a2a_parts.append(a2a.create_file_part_from_uri(uri=artifact_uri, name=file_name, mime_type=mime_type))
243
273
  # - Handle structured data:
244
274
  # # structured_data = external_event_data.get("data_payload")
245
275
  # # if structured_data:
246
- # # a2a_parts.append(DataPart(data=structured_data, metadata={"source": "__GATEWAY_NAME_SNAKE_CASE__"}))
276
+ # # a2a_parts.append(a2a.create_data_part(data=structured_data, metadata={"source": "__GATEWAY_NAME_SNAKE_CASE__"}))
247
277
 
248
278
  # Example: Simple text passthrough
249
279
  raw_text = str(
@@ -251,18 +281,18 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
251
281
  "text_input_field", "Default text from __GATEWAY_NAME_SNAKE_CASE__"
252
282
  )
253
283
  )
254
- a2a_parts.append(TextPart(text=raw_text))
284
+ a2a_parts.append(a2a.create_text_part(text=raw_text))
255
285
 
256
286
  if not target_agent_name:
257
287
  log.error("%s Could not determine target_agent_name.", log_id_prefix)
258
- return None, [], {} # Indicate translation failure
288
+ raise ValueError("Could not determine target agent for the request.")
259
289
 
260
290
  if not a2a_parts:
261
291
  log.warning(
262
292
  "%s No A2A parts created from external event. Task might be empty.",
263
293
  log_id_prefix,
264
294
  )
265
- # Depending on requirements, you might want to return None, [], {} here too.
295
+ # Depending on requirements, you might want to raise ValueError here too.
266
296
 
267
297
  log.info(
268
298
  "%s Translation complete. Target: %s, Parts: %d",
@@ -281,33 +311,33 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
281
311
  - `task_data`: The final A2A Task object (contains status, results, etc.).
282
312
  """
283
313
  log_id_prefix = f"{self.log_identifier}[SendFinalResponse]"
284
- # log.debug("%s Sending final response for task %s. Context: %s", log_id_prefix, task_data.id, external_request_context)
314
+ task_id = a2a.get_task_id(task_data)
315
+ # log.debug("%s Sending final response for task %s. Context: %s", log_id_prefix, task_id, external_request_context)
285
316
 
286
317
  # --- Implement Logic to Send Response to External System ---
287
- # 1. Extract relevant information from task_data:
288
- # - task_data.status.state (e.g., TaskState.COMPLETED, TaskState.FAILED)
289
- # - task_data.status.message.parts (usually TextPart for final agent response)
290
- # - task_data.artifacts (if agent produced artifacts)
318
+ # 1. Extract relevant information from task_data using the `a2a` facade:
319
+ # from a2a.types import TaskState
320
+ # task_status = a2a.get_task_status(task_data) # e.g., TaskState.completed
321
+ # artifacts = a2a.get_task_artifacts(task_data)
322
+ # response_text = a2a.get_text_from_message(task_data.status.message) if task_data.status and task_data.status.message else ""
291
323
 
292
324
  # 2. Format the response according to the external system's requirements.
293
- # response_text = "Task completed."
294
- # if task_data.status and task_data.status.message and task_data.status.message.parts:
295
- # for part in task_data.status.message.parts:
296
- # if isinstance(part, TextPart):
297
- # response_text = part.text
298
- # break
299
- # if task_data.status and task_data.status.state == TaskState.FAILED:
300
- # response_text = f"Task failed: {response_text}"
325
+ # if task_status == TaskState.failed:
326
+ # final_message = f"Task failed: {response_text}"
327
+ # elif task_status == TaskState.canceled:
328
+ # final_message = "Task was canceled."
329
+ # else:
330
+ # final_message = response_text
301
331
 
302
332
  # 3. Use information from external_request_context to send the response
303
333
  # (e.g., reply-to address, original request ID).
304
334
  # # original_request_id = external_request_context.get("original_request_id")
305
- # # await self.external_client.send_reply(original_request_id, response_text)
335
+ # # await self.external_client.send_reply(original_request_id, final_message)
306
336
 
307
337
  log.warning(
308
338
  "%s _send_final_response_to_external not fully implemented for task %s.",
309
339
  log_id_prefix,
310
- task_data.id,
340
+ task_id,
311
341
  )
312
342
 
313
343
  async def _send_error_to_external(
@@ -321,17 +351,19 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
321
351
  - `error_data`: A JSONRPCError object.
322
352
  """
323
353
  log_id_prefix = f"{self.log_identifier}[SendError]"
324
- # log.warning("%s Sending error to external system. Error: %s. Context: %s", log_id_prefix, error_data.message, external_request_context)
354
+ error_message = a2a.get_error_message(error_data)
355
+ error_code = a2a.get_error_code(error_data)
356
+ # log.warning("%s Sending error to external system. Error: %s. Context: %s", log_id_prefix, error_message, external_request_context)
325
357
 
326
358
  # --- Implement Logic to Send Error to External System ---
327
- # error_message_to_send = f"A2A Error: {error_data.message} (Code: {error_data.code})"
359
+ # error_message_to_send = f"A2A Error: {error_message} (Code: {error_code})"
328
360
  # # original_request_id = external_request_context.get("original_request_id")
329
361
  # # await self.external_client.send_error_reply(original_request_id, error_message_to_send)
330
362
 
331
363
  log.warning(
332
364
  "%s _send_error_to_external not fully implemented. Error: %s",
333
365
  log_id_prefix,
334
- error_data.message,
366
+ error_message,
335
367
  )
336
368
 
337
369
  async def _send_update_to_external(
@@ -347,27 +379,41 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
347
379
  - `is_final_chunk_of_update`: True if this is the last part of a streamed TextPart from TaskStatusUpdateEvent.
348
380
  """
349
381
  log_id_prefix = f"{self.log_identifier}[SendUpdate]"
350
- # task_id = event_data.id
382
+ task_id = event_data.task_id
351
383
  # log.debug("%s Received A2A update for task %s. Type: %s. FinalChunk: %s",
352
384
  # log_id_prefix, task_id, type(event_data).__name__, is_final_chunk_of_update)
353
385
 
354
386
  # --- Implement Logic to Send Intermediate Update (if supported) ---
355
387
  # if isinstance(event_data, TaskStatusUpdateEvent):
356
- # if event_data.status and event_data.status.message and event_data.status.message.parts:
357
- # for part in event_data.status.message.parts:
358
- # if isinstance(part, TextPart):
359
- # # Send part.text to external system
360
- # pass
361
- # elif isinstance(part, DataPart) and part.data.get("a2a_signal_type") == "agent_status_message":
362
- # # Send agent status signal text part.data.get("text")
388
+ # message = a2a.get_message_from_status_update(event_data)
389
+ # if message:
390
+ # # Get text content
391
+ # text_content = a2a.get_text_from_message(message)
392
+ # if text_content:
393
+ # # Send text_content to external system
394
+ # pass
395
+ #
396
+ # # Check for specific status signals (DataParts)
397
+ # data_parts = a2a.get_data_parts_from_message(message)
398
+ # for part in data_parts:
399
+ # data = a2a.get_data_from_data_part(part)
400
+ # if data.get("type") == "agent_progress_update":
401
+ # status_text = data.get("status_text")
402
+ # # Send status_text to external system
363
403
  # pass
404
+ #
364
405
  # elif isinstance(event_data, TaskArtifactUpdateEvent):
365
- # # Handle artifact updates (e.g., notify external system of new artifact URI)
366
- # pass
406
+ # artifact = a2a.get_artifact_from_artifact_update(event_data)
407
+ # if artifact:
408
+ # # Handle artifact updates (e.g., notify external system of new artifact URI)
409
+ # pass
367
410
 
368
411
  # Default: Log that this gateway does not handle intermediate updates.
369
- # log.debug("%s __GATEWAY_NAME_PASCAL_CASE__ Gateway does not process intermediate updates. Update for task %s ignored.",
370
- # log_id_prefix, task_id)
412
+ log.debug(
413
+ "%s __GATEWAY_NAME_PASCAL_CASE__ Gateway does not process intermediate updates. Update for task %s ignored.",
414
+ log_id_prefix,
415
+ task_id,
416
+ )
371
417
  pass # No-op by default
372
418
 
373
419
  # --- Optional: Helper methods for your gateway ---
@@ -376,15 +422,20 @@ class __GATEWAY_NAME_PASCAL_CASE__GatewayComponent(BaseGatewayComponent):
376
422
 
377
423
  return str(uuid.uuid4())
378
424
 
379
- # async def save_to_artifact_service(self, content_bytes: bytes, filename: str, mime_type: str, user_id: str, session_id: str) -> Optional[str]:
425
+ # async def save_to_artifact_service(self, content_bytes: bytes, filename: str, mime_type: str, user_identity: Dict[str, Any], session_id: str) -> Optional[str]:
380
426
  # """Helper to save content to the shared artifact service."""
381
427
  # if not self.shared_artifact_service:
382
428
  # log.error("%s Artifact service not available. Cannot save file: %s", self.log_identifier, filename)
383
429
  # return None
384
430
  # try:
385
- # from src.solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata # Adjust import
431
+ # from ...agent.utils.artifact_helpers import save_artifact_with_metadata # Adjust import
386
432
  # from datetime import datetime, timezone
387
433
 
434
+ # user_id = user_identity.get("id")
435
+ # if not user_id:
436
+ # log.error("%s Cannot save artifact, user_id not found in user_identity.", self.log_identifier)
437
+ # return None
438
+
388
439
  # save_result = await save_artifact_with_metadata(
389
440
  # artifact_service=self.shared_artifact_service,
390
441
  # app_name=self.gateway_id, # from BaseGatewayComponent
@@ -6,8 +6,7 @@ shared_config:
6
6
  broker_password: ${SOLACE_BROKER_PASSWORD, default}
7
7
  broker_vpn: ${SOLACE_BROKER_VPN, default}
8
8
  temporary_queue: ${USE_TEMPORARY_QUEUES, true}
9
- # Ensure high enough limits if many agents are running
10
- # max_connection_retries: -1 # Retry forever
9
+
11
10
 
12
11
  - models:
13
12
  planning: &planning_model
@@ -57,13 +56,13 @@ shared_config:
57
56
  - services:
58
57
  # Default session service configuration
59
58
  session_service: &default_session_service
60
- type: "__DEFAULT_SESSION_SERVICE_TYPE__"
61
- default_behavior: "__DEFAULT_SESSION_SERVICE_BEHAVIOR__"
59
+ type: "memory"
60
+ default_behavior: "PERSISTENT"
62
61
 
63
62
  # Default artifact service configuration
64
63
  artifact_service: &default_artifact_service
65
64
  type: "__DEFAULT_ARTIFACT_SERVICE_TYPE__"
66
- __DEFAULT_ARTIFACT_SERVICE_BASE_PATH_LINE__
65
+ # __DEFAULT_ARTIFACT_SERVICE_BASE_PATH_LINE__
67
66
  artifact_scope: __DEFAULT_ARTIFACT_SERVICE_SCOPE__
68
67
 
69
68
  # Default data tools configuration
@@ -1,11 +1,11 @@
1
- # Solace Agent Mesh WebUI Gateway Configuration
1
+
2
2
 
3
3
  log:
4
4
  stdout_log_level: INFO
5
5
  log_file_level: DEBUG
6
6
  log_file: webui_app.log
7
7
 
8
- # Shared SAM config
8
+
9
9
  !include ../shared_config.yaml
10
10
 
11
11
  apps:
@@ -21,14 +21,13 @@ apps:
21
21
  session_secret_key: ${SESSION_SECRET_KEY}
22
22
 
23
23
  artifact_service: *default_artifact_service
24
-
24
+ session_service: __SESSION_SERVICE__
25
25
  gateway_id: ${WEBUI_GATEWAY_ID}
26
26
  fastapi_host: ${FASTAPI_HOST}
27
27
  fastapi_port: ${FASTAPI_PORT}
28
- cors_allowed_origins: # List of allowed origins for CORS
29
- - "http://localhost:3000" # Example: Allow local React dev server
28
+ cors_allowed_origins:
29
+ - "http://localhost:3000"
30
30
  - "http://127.0.0.1:3000"
31
- # Add other origins as needed, or use ["*"] for wide open (less secure)
32
31
 
33
32
  enable_embed_resolution: ${ENABLE_EMBED_RESOLUTION} # Enable late-stage resolution
34
33
  gateway_artifact_content_limit_bytes: ${GATEWAY_ARTIFACT_LIMIT_BYTES, 10000000} # Max size for late-stage embeds
@@ -47,7 +46,6 @@ apps:
47
46
  Format responses to the user in Markdown using appropriate formatting.
48
47
 
49
48
  # --- Frontend Config Passthrough ---
50
- frontend_welcome_message: >
51
- __FRONTEND_WELCOME_MESSAGE__
52
- frontend_bot_name: __FRONTEND_BOT_NAME__
53
- frontend_collect_feedback: __FRONTEND_COLLECT_FEEDBACK__
49
+ frontend_welcome_message: ${FRONTEND_WELCOME_MESSAGE}
50
+ frontend_bot_name: ${FRONTEND_BOT_NAME}
51
+ frontend_collect_feedback: ${FRONTEND_COLLECT_FEEDBACK}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: solace-agent-mesh
3
- Version: 1.0.9
3
+ Version: 1.3.0
4
4
  Summary: Solace Agent Mesh is an open-source framework for building event-driven, multi-agent AI systems where specialized agents collaborate on complex tasks.
5
5
  Project-URL: Homepage, https://github.com/SolaceLabs/solace-agent-mesh
6
6
  Project-URL: Repository, https://github.com/SolaceLabs/solace-agent-mesh
@@ -214,6 +214,8 @@ Classifier: Programming Language :: Python :: 3.11
214
214
  Classifier: Programming Language :: Python :: 3.13
215
215
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
216
216
  Requires-Python: >=3.10.16
217
+ Requires-Dist: a2a-sdk[http-server]>=0.3.1
218
+ Requires-Dist: alembic>=1.13.1
217
219
  Requires-Dist: asteval>=1.0.6
218
220
  Requires-Dist: asteval~=1.0.0
219
221
  Requires-Dist: beautifulsoup4>=4.12.0
@@ -249,6 +251,7 @@ Requires-Dist: python-multipart>=0.0.7
249
251
  Requires-Dist: pyyaml>=6.0
250
252
  Requires-Dist: rouge~=1.0.1
251
253
  Requires-Dist: solace-ai-connector~=1.1.8
254
+ Requires-Dist: sqlalchemy>=2.0
252
255
  Requires-Dist: sse-starlette>=1.6
253
256
  Requires-Dist: toml~=0.10.2
254
257
  Requires-Dist: uvicorn[standard]>=0.20
@@ -256,12 +259,12 @@ Provides-Extra: cli
256
259
  Requires-Dist: click>=8.0; extra == 'cli'
257
260
  Requires-Dist: prompt-toolkit>=3.0; extra == 'cli'
258
261
  Requires-Dist: rich>=13.0; extra == 'cli'
259
- Provides-Extra: database
260
- Requires-Dist: sqlalchemy>=2.0; extra == 'database'
261
262
  Provides-Extra: employee-tools
262
263
  Requires-Dist: holidays>=0.24; extra == 'employee-tools'
263
264
  Provides-Extra: gcs
264
265
  Requires-Dist: google-cloud-storage>=2.0; extra == 'gcs'
266
+ Provides-Extra: postgresql
267
+ Requires-Dist: psycopg2-binary>=2.9.0; extra == 'postgresql'
265
268
  Provides-Extra: s3
266
269
  Requires-Dist: boto3<2.0,>=1.35.0; extra == 's3'
267
270
  Provides-Extra: vertex
@@ -367,7 +370,7 @@ If no previous version exists, install the latest version with:
367
370
  ```bash
368
371
  pip3 install solace-agent-mesh
369
372
  ```
370
- #### 4. Initialize the new project via a GUI interface
373
+ #### 4. Initialize the new project via a GUI tool
371
374
  ```bash
372
375
  sam init --gui
373
376
  ```
@@ -377,7 +380,7 @@ Note: This initialization UI runs on port 5002
377
380
  sam run
378
381
  ```
379
382
  #### 6. Verify SAM is running
380
- Open the Web UI at [http://localhost:8000](http://localhost:8000) for the chat inteface and ask a question
383
+ Open the Web UI at [http://localhost:8000](http://localhost:8000) for the chat interface and ask a question
381
384
 
382
385
  ### 🔧 Customize SAM
383
386
 
@@ -424,7 +427,7 @@ Want to go further? Here are some hands-on tutorials to help you get started:
424
427
 
425
428
  | 🔧 Integration | ⏱️ Est. Time | 📘 Tutorial |
426
429
  |----------------|--------------|-------------|
427
- | 🌤️ **Weather Agent**<br>Learn how to build an agent that gives Solace Agent Mesh the ability to access real-time weather information. | **~15 min** | [Weather Agent Plugin](https://solacelabs.github.io/solace-agent-mesh/docs/documentation/tutorials/custom-agent) |
430
+ | 🌤️ **Weather Agent**<br>Learn how to build an agent that gives Solace Agent Mesh the ability to access real-time weather information. | **~15 min** | [Weather Agent Plugin](https://solacelabs.github.io/solace-agent-mesh/docs/documentation/tutorials/custom-agent) |
428
431
  | 🗃️ **SQL Database Integration**<br>Enable Solace Agent Mesh to answer company-specific questions using a sample coffee company database.| **~10–15 min** | [SQL Database Tutorial](https://solacelabs.github.io/solace-agent-mesh/docs/documentation/tutorials/sql-database) |
429
432
  | 🧠 **MCP Integration**<br>Integrating a Model Context Protocol (MCP) Servers into Solace Agent Mesh. | **~10–15 min** | [MCP Integration Tutorial](https://solacelabs.github.io/solace-agent-mesh/docs/documentation/tutorials/mcp-integration) |
430
433
  | 💬 **Slack Integration**<br>Chat with Solace Agent Mesh directly from Slack. | **~20–30 min** | [Slack Integration Tutorial](https://solacelabs.github.io/solace-agent-mesh/docs/documentation/tutorials/slack-integration) |