solace-agent-mesh 1.6.1__py3-none-any.whl → 1.6.3__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 (124) hide show
  1. solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
  2. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +1 -1
  3. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +135 -31
  4. solace_agent_mesh/agent/adk/models/lite_llm.py +5 -0
  5. solace_agent_mesh/agent/adk/runner.py +10 -12
  6. solace_agent_mesh/agent/adk/services.py +53 -17
  7. solace_agent_mesh/agent/adk/setup.py +66 -38
  8. solace_agent_mesh/agent/protocol/event_handlers.py +243 -122
  9. solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
  10. solace_agent_mesh/agent/proxies/base/app.py +3 -2
  11. solace_agent_mesh/agent/sac/app.py +43 -2
  12. solace_agent_mesh/agent/sac/component.py +200 -72
  13. solace_agent_mesh/agent/sac/task_execution_context.py +35 -4
  14. solace_agent_mesh/agent/tools/tool_config_types.py +3 -0
  15. solace_agent_mesh/agent/utils/artifact_helpers.py +1 -1
  16. solace_agent_mesh/assets/docs/404.html +3 -3
  17. solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.js +1 -0
  18. solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +1 -0
  19. solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +1 -0
  20. solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +1 -0
  21. solace_agent_mesh/assets/docs/assets/js/94e8668d.3b883666.js +1 -0
  22. solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +1 -0
  23. solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/main.ed05b14d.js +2 -0
  25. solace_agent_mesh/assets/docs/assets/js/runtime~main.a8a75e0b.js +1 -0
  26. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +3 -3
  27. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +3 -3
  28. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +3 -3
  29. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +3 -3
  32. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +3 -3
  33. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +4 -25
  39. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +76 -0
  42. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +5 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +3 -3
  44. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +3 -3
  45. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +3 -3
  46. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +3 -3
  47. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +3 -3
  48. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +3 -3
  49. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +3 -3
  50. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +3 -3
  51. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +3 -3
  52. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +3 -3
  53. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +3 -3
  54. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +3 -3
  55. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +3 -3
  56. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +3 -3
  57. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +3 -3
  58. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +3 -3
  59. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
  60. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +3 -3
  61. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +23 -28
  62. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +3 -3
  63. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +3 -3
  64. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +3 -3
  65. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  66. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
  67. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +3 -6
  68. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +3 -3
  69. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +3 -3
  70. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +3 -3
  71. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +3 -3
  72. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
  73. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
  74. solace_agent_mesh/assets/docs/lunr-index-1761744323675.json +1 -0
  75. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  76. solace_agent_mesh/assets/docs/search-doc-1761744323675.json +1 -0
  77. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  78. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  79. solace_agent_mesh/cli/__init__.py +1 -1
  80. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-D4_RMYRh.js} +1 -1
  81. solace_agent_mesh/client/webui/frontend/static/assets/{client-CaY59VuC.js → client-UZ3qU6Bq.js} +1 -1
  82. solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +1 -0
  83. solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +342 -0
  84. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BEmvJSYz.js → vendor-DSqhjwq_.js} +1 -1
  85. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  86. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  87. solace_agent_mesh/common/a2a/events.py +2 -1
  88. solace_agent_mesh/common/sac/sam_component_base.py +24 -18
  89. solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
  90. solace_agent_mesh/gateway/base/component.py +12 -8
  91. solace_agent_mesh/gateway/http_sse/app.py +26 -0
  92. solace_agent_mesh/gateway/http_sse/component.py +158 -79
  93. solace_agent_mesh/gateway/http_sse/dependencies.py +83 -59
  94. solace_agent_mesh/gateway/http_sse/main.py +35 -11
  95. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +1 -1
  96. solace_agent_mesh/gateway/http_sse/routers/auth.py +103 -6
  97. solace_agent_mesh/gateway/http_sse/routers/config.py +1 -1
  98. solace_agent_mesh/gateway/http_sse/routers/sessions.py +1 -1
  99. solace_agent_mesh/gateway/http_sse/routers/sse.py +15 -5
  100. solace_agent_mesh/gateway/http_sse/routers/tasks.py +3 -3
  101. solace_agent_mesh/gateway/http_sse/routers/visualization.py +90 -8
  102. solace_agent_mesh/gateway/http_sse/services/session_service.py +1 -1
  103. solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
  104. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +16 -1
  105. solace_agent_mesh/gateway/http_sse/sse_manager.py +15 -6
  106. solace_agent_mesh/templates/logging_config_template.ini +2 -2
  107. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/METADATA +2 -2
  108. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/RECORD +112 -110
  109. solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
  110. solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
  111. solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
  112. solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
  113. solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
  114. solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
  115. solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
  116. solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
  117. solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
  118. solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
  119. solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
  120. solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
  121. /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.ed05b14d.js.LICENSE.txt} +0 -0
  122. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/WHEEL +0 -0
  123. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/entry_points.txt +0 -0
  124. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/licenses/LICENSE +0 -0
@@ -2,9 +2,9 @@
2
2
  Custom Solace AI Connector Component to host the FastAPI backend for the Web UI.
3
3
  """
4
4
 
5
- import logging
6
5
  import asyncio
7
6
  import json
7
+ import logging
8
8
  import queue
9
9
  import re
10
10
  import threading
@@ -15,22 +15,20 @@ from typing import Any
15
15
  import uvicorn
16
16
  from fastapi import FastAPI, UploadFile
17
17
  from fastapi import Request as FastAPIRequest
18
-
18
+ from solace_ai_connector.common.event import Event, EventType
19
19
  from solace_ai_connector.components.inputs_outputs.broker_input import BrokerInput
20
20
  from solace_ai_connector.flow.app import App as SACApp
21
- from solace_ai_connector.common.event import Event, EventType
22
21
 
23
22
  from ...common.agent_registry import AgentRegistry
24
23
  from ...core_a2a.service import CoreA2AService
25
24
  from ...gateway.base.component import BaseGatewayComponent
26
25
  from ...gateway.http_sse.session_manager import SessionManager
27
26
  from ...gateway.http_sse.sse_manager import SSEManager
28
- from .sse_event_buffer import SSEEventBuffer
27
+ from . import dependencies
29
28
  from .components import VisualizationForwarderComponent
30
29
  from .components.task_logger_forwarder import TaskLoggerForwarderComponent
31
- from .services.feedback_service import FeedbackService
32
30
  from .services.task_logger_service import TaskLoggerService
33
- from . import dependencies
31
+ from .sse_event_buffer import SSEEventBuffer
34
32
 
35
33
  log = logging.getLogger(__name__)
36
34
 
@@ -115,6 +113,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
115
113
  self.ssl_keyfile = self.get_config("ssl_keyfile", "")
116
114
  self.ssl_certfile = self.get_config("ssl_certfile", "")
117
115
  self.ssl_keyfile_password = self.get_config("ssl_keyfile_password", "")
116
+ self.model_config = self.get_config("model", None)
118
117
 
119
118
  log.info(
120
119
  "%s WebUI-specific configuration retrieved (Host: %s, Port: %d).",
@@ -146,11 +145,14 @@ class WebUIBackendComponent(BaseGatewayComponent):
146
145
  timer_id=self._sse_cleanup_timer_id,
147
146
  interval_ms=cleanup_interval_sec * 1000,
148
147
  )
149
-
148
+
150
149
  # Set up health check timer for agent registry
151
150
  from ...common.constants import HEALTH_CHECK_INTERVAL_SECONDS
151
+
152
152
  self.health_check_timer_id = f"agent_health_check_{self.gateway_id}"
153
- health_check_interval_seconds = self.get_config("agent_health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS)
153
+ health_check_interval_seconds = self.get_config(
154
+ "agent_health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS
155
+ )
154
156
  if health_check_interval_seconds > 0:
155
157
  log.info(
156
158
  "%s Scheduling agent health check every %d seconds.",
@@ -181,8 +183,9 @@ class WebUIBackendComponent(BaseGatewayComponent):
181
183
  else:
182
184
  # Memory storage or no explicit configuration - no persistence service needed
183
185
  self.database_url = None
184
-
185
- # Validate that features requiring database persistence are not enabled
186
+
187
+ # Validate that features requiring runtime database persistence are not enabled without database
188
+ if self.database_url is None:
186
189
  task_logging_config = self.get_config("task_logging", {})
187
190
  if task_logging_config.get("enabled", False):
188
191
  raise ValueError(
@@ -190,15 +193,17 @@ class WebUIBackendComponent(BaseGatewayComponent):
190
193
  "Either set session_service.type='sql' with a valid database_url, "
191
194
  "or disable task_logging.enabled."
192
195
  )
193
-
196
+
194
197
  feedback_config = self.get_config("feedback_publishing", {})
195
198
  if feedback_config.get("enabled", False):
196
199
  log.warning(
197
200
  "%s Feedback publishing is enabled but database persistence is not configured. "
198
201
  "Feedback will only be published to the broker, not stored locally.",
199
- self.log_identifier
202
+ self.log_identifier,
200
203
  )
201
204
 
205
+ platform_config = self.get_config("platform_service", {})
206
+ self.platform_database_url = platform_config.get("database_url")
202
207
  component_config = self.get_config("component_config", {})
203
208
  app_config = component_config.get("app_config", {})
204
209
 
@@ -241,27 +246,35 @@ class WebUIBackendComponent(BaseGatewayComponent):
241
246
  self._data_retention_timer_id = None
242
247
  data_retention_config = self.get_config("data_retention", {})
243
248
  if data_retention_config.get("enabled", True):
244
- log.info("%s Data retention is enabled. Initializing service and timer...", self.log_identifier)
245
-
249
+ log.info(
250
+ "%s Data retention is enabled. Initializing service and timer...",
251
+ self.log_identifier,
252
+ )
253
+
246
254
  # Import and initialize the DataRetentionService
247
255
  from .services.data_retention_service import DataRetentionService
248
-
256
+
249
257
  session_factory = None
250
258
  if self.database_url:
251
259
  # SessionLocal will be initialized later in setup_dependencies
252
260
  # We'll pass a lambda that returns SessionLocal when called
253
- session_factory = lambda: dependencies.SessionLocal() if dependencies.SessionLocal else None
254
-
261
+ session_factory = (
262
+ lambda: dependencies.SessionLocal()
263
+ if dependencies.SessionLocal
264
+ else None
265
+ )
266
+
255
267
  self.data_retention_service = DataRetentionService(
256
- session_factory=session_factory,
257
- config=data_retention_config
268
+ session_factory=session_factory, config=data_retention_config
258
269
  )
259
-
270
+
260
271
  # Create and start the cleanup timer
261
- cleanup_interval_hours = data_retention_config.get("cleanup_interval_hours", 24)
272
+ cleanup_interval_hours = data_retention_config.get(
273
+ "cleanup_interval_hours", 24
274
+ )
262
275
  cleanup_interval_ms = cleanup_interval_hours * 60 * 60 * 1000
263
276
  self._data_retention_timer_id = f"data_retention_cleanup_{self.gateway_id}"
264
-
277
+
265
278
  self.add_timer(
266
279
  delay_ms=cleanup_interval_ms,
267
280
  timer_id=self._data_retention_timer_id,
@@ -274,14 +287,16 @@ class WebUIBackendComponent(BaseGatewayComponent):
274
287
  cleanup_interval_hours,
275
288
  )
276
289
  else:
277
- log.info("%s Data retention is disabled via configuration.", self.log_identifier)
290
+ log.info(
291
+ "%s Data retention is disabled via configuration.", self.log_identifier
292
+ )
278
293
 
279
294
  log.info("%s Web UI Backend Component initialized.", self.log_identifier)
280
295
 
281
296
  def process_event(self, event: Event):
282
297
  if event.event_type == EventType.TIMER:
283
298
  timer_id = event.data.get("timer_id")
284
-
299
+
285
300
  if timer_id == self._sse_cleanup_timer_id:
286
301
  log.debug("%s SSE buffer cleanup timer triggered.", self.log_identifier)
287
302
  self.sse_event_buffer.cleanup_stale_buffers()
@@ -290,9 +305,11 @@ class WebUIBackendComponent(BaseGatewayComponent):
290
305
  log.debug("%s Agent health check timer triggered.", self.log_identifier)
291
306
  self._check_agent_health()
292
307
  return
293
-
308
+
294
309
  if timer_id == self._data_retention_timer_id:
295
- log.debug("%s Data retention cleanup timer triggered.", self.log_identifier)
310
+ log.debug(
311
+ "%s Data retention cleanup timer triggered.", self.log_identifier
312
+ )
296
313
  if self.data_retention_service:
297
314
  try:
298
315
  self.data_retention_service.cleanup_old_data()
@@ -386,7 +403,9 @@ class WebUIBackendComponent(BaseGatewayComponent):
386
403
  forwarder_cfg = {
387
404
  "component_class": VisualizationForwarderComponent,
388
405
  "component_name": f"{self.gateway_id}_viz_forwarder",
389
- "component_config": {"target_queue_ref": self._visualization_message_queue},
406
+ "component_config": {
407
+ "target_queue_ref": self._visualization_message_queue
408
+ },
390
409
  }
391
410
 
392
411
  flow_config = {
@@ -437,7 +456,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
437
456
  raise RuntimeError(
438
457
  "Visualization flow setup error: BrokerInput not found."
439
458
  )
440
- log.info(
459
+ log.debug(
441
460
  "%s Obtained reference to internal BrokerInput component.",
442
461
  log_id_prefix,
443
462
  )
@@ -883,7 +902,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
883
902
  Manages global subscription reference counts.
884
903
  """
885
904
  log_id_prefix = f"{self.log_identifier}[AddVizSub:{stream_id}]"
886
- log.info(
905
+ log.debug(
887
906
  "%s Attempting to add subscription to topic: %s", log_id_prefix, topic_str
888
907
  )
889
908
 
@@ -1164,7 +1183,12 @@ class WebUIBackendComponent(BaseGatewayComponent):
1164
1183
  log_id_prefix,
1165
1184
  username,
1166
1185
  )
1167
- return {"id": username, "name": username, "email": username, "user_info": user_info}
1186
+ return {
1187
+ "id": username,
1188
+ "name": username,
1189
+ "email": username,
1190
+ "user_info": user_info,
1191
+ }
1168
1192
 
1169
1193
  log.debug(
1170
1194
  "%s No authenticated user in request.state, falling back to SessionManager.",
@@ -1198,7 +1222,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
1198
1222
 
1199
1223
  self.fastapi_app = fastapi_app_instance
1200
1224
 
1201
- setup_dependencies(self, self.database_url)
1225
+ setup_dependencies(self, self.database_url, self.platform_database_url)
1202
1226
 
1203
1227
  # Instantiate services that depend on the database session factory.
1204
1228
  # This must be done *after* setup_dependencies has run.
@@ -1207,7 +1231,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
1207
1231
  self.task_logger_service = TaskLoggerService(
1208
1232
  session_factory=session_factory, config=task_logging_config
1209
1233
  )
1210
- log.info(
1234
+ log.debug(
1211
1235
  "%s Services dependent on database session factory have been initialized.",
1212
1236
  self.log_identifier,
1213
1237
  )
@@ -1238,14 +1262,14 @@ class WebUIBackendComponent(BaseGatewayComponent):
1238
1262
  )
1239
1263
  try:
1240
1264
  self.fastapi_event_loop = asyncio.get_running_loop()
1241
- log.info(
1265
+ log.debug(
1242
1266
  "%s [_start_listener] Captured FastAPI event loop via startup event: %s",
1243
1267
  self.log_identifier,
1244
1268
  self.fastapi_event_loop,
1245
1269
  )
1246
1270
 
1247
1271
  if self.fastapi_event_loop:
1248
- log.info(
1272
+ log.debug(
1249
1273
  "%s Ensuring visualization flow is running...",
1250
1274
  self.log_identifier,
1251
1275
  )
@@ -1255,7 +1279,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
1255
1279
  self._visualization_processor_task is None
1256
1280
  or self._visualization_processor_task.done()
1257
1281
  ):
1258
- log.info(
1282
+ log.debug(
1259
1283
  "%s Starting visualization message processor task.",
1260
1284
  self.log_identifier,
1261
1285
  )
@@ -1265,7 +1289,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
1265
1289
  )
1266
1290
  )
1267
1291
  else:
1268
- log.info(
1292
+ log.debug(
1269
1293
  "%s Visualization message processor task already running.",
1270
1294
  self.log_identifier,
1271
1295
  )
@@ -1297,7 +1321,9 @@ class WebUIBackendComponent(BaseGatewayComponent):
1297
1321
  self.log_identifier,
1298
1322
  )
1299
1323
  else:
1300
- log.info("%s Task logging is disabled.", self.log_identifier)
1324
+ log.info(
1325
+ "%s Task logging is disabled.", self.log_identifier
1326
+ )
1301
1327
  else:
1302
1328
  log.error(
1303
1329
  "%s FastAPI event loop not captured. Cannot start visualization processor.",
@@ -1313,24 +1339,36 @@ class WebUIBackendComponent(BaseGatewayComponent):
1313
1339
  self.stop_signal.set()
1314
1340
 
1315
1341
  try:
1316
- from solace_agent_mesh_enterprise.init_enterprise import start_enterprise_background_tasks
1317
- log.info("%s Starting enterprise background tasks...", self.log_identifier)
1342
+ from solace_agent_mesh_enterprise.init_enterprise import (
1343
+ start_enterprise_background_tasks,
1344
+ )
1345
+
1346
+ log.info(
1347
+ "%s Starting enterprise background tasks...",
1348
+ self.log_identifier,
1349
+ )
1318
1350
  await start_enterprise_background_tasks(self)
1319
- log.info("%s Enterprise background tasks started successfully", self.log_identifier)
1351
+ log.info(
1352
+ "%s Enterprise background tasks started successfully",
1353
+ self.log_identifier,
1354
+ )
1320
1355
  except ImportError:
1321
- log.debug("%s Enterprise package not available - skipping background tasks", self.log_identifier)
1356
+ log.debug(
1357
+ "%s Enterprise package not available - skipping background tasks",
1358
+ self.log_identifier,
1359
+ )
1322
1360
  except RuntimeError as enterprise_err:
1323
1361
  log.warning(
1324
1362
  "%s Enterprise background tasks disabled: %s - Community features will continue normally",
1325
1363
  self.log_identifier,
1326
- enterprise_err
1364
+ enterprise_err,
1327
1365
  )
1328
1366
  except Exception as enterprise_err:
1329
1367
  log.error(
1330
1368
  "%s Failed to start enterprise background tasks: %s - Community features will continue normally",
1331
1369
  self.log_identifier,
1332
1370
  enterprise_err,
1333
- exc_info=True
1371
+ exc_info=True,
1334
1372
  )
1335
1373
 
1336
1374
  @self.fastapi_app.on_event("shutdown")
@@ -1341,18 +1379,29 @@ class WebUIBackendComponent(BaseGatewayComponent):
1341
1379
  )
1342
1380
 
1343
1381
  try:
1344
- from solace_agent_mesh_enterprise.init_enterprise import stop_enterprise_background_tasks
1345
- log.info("%s Stopping enterprise background tasks...", self.log_identifier)
1382
+ from solace_agent_mesh_enterprise.init_enterprise import (
1383
+ stop_enterprise_background_tasks,
1384
+ )
1385
+
1386
+ log.info(
1387
+ "%s Stopping enterprise background tasks...",
1388
+ self.log_identifier,
1389
+ )
1346
1390
  await stop_enterprise_background_tasks()
1347
- log.info("%s Enterprise background tasks stopped", self.log_identifier)
1391
+ log.info(
1392
+ "%s Enterprise background tasks stopped", self.log_identifier
1393
+ )
1348
1394
  except ImportError:
1349
- log.debug("%s Enterprise package not available - no background tasks to stop", self.log_identifier)
1395
+ log.debug(
1396
+ "%s Enterprise package not available - no background tasks to stop",
1397
+ self.log_identifier,
1398
+ )
1350
1399
  except Exception as enterprise_err:
1351
1400
  log.error(
1352
1401
  "%s Failed to stop enterprise background tasks: %s",
1353
1402
  self.log_identifier,
1354
1403
  enterprise_err,
1355
- exc_info=True
1404
+ exc_info=True,
1356
1405
  )
1357
1406
 
1358
1407
  self.fastapi_thread = threading.Thread(
@@ -1417,18 +1466,18 @@ class WebUIBackendComponent(BaseGatewayComponent):
1417
1466
  def cleanup(self):
1418
1467
  """Gracefully shuts down the component and the FastAPI server."""
1419
1468
  log.info("%s Cleaning up Web UI Backend Component...", self.log_identifier)
1420
-
1469
+
1421
1470
  # Cancel timers
1422
1471
  self.cancel_timer(self._sse_cleanup_timer_id)
1423
1472
  if self._data_retention_timer_id:
1424
1473
  self.cancel_timer(self._data_retention_timer_id)
1425
1474
  log.info("%s Cancelled data retention cleanup timer.", self.log_identifier)
1426
-
1475
+
1427
1476
  # Clean up data retention service
1428
1477
  if self.data_retention_service:
1429
1478
  self.data_retention_service = None
1430
1479
  log.info("%s Data retention service cleaned up.", self.log_identifier)
1431
-
1480
+
1432
1481
  self.cancel_timer(self.health_check_timer_id)
1433
1482
  log.info("%s Cleaning up visualization resources...", self.log_identifier)
1434
1483
  if self._visualization_message_queue:
@@ -1445,7 +1494,10 @@ class WebUIBackendComponent(BaseGatewayComponent):
1445
1494
  )
1446
1495
  self._visualization_processor_task.cancel()
1447
1496
 
1448
- if self._task_logger_processor_task and not self._task_logger_processor_task.done():
1497
+ if (
1498
+ self._task_logger_processor_task
1499
+ and not self._task_logger_processor_task.done()
1500
+ ):
1449
1501
  log.info("%s Cancelling task logger processor task...", self.log_identifier)
1450
1502
  self._task_logger_processor_task.cancel()
1451
1503
 
@@ -1659,9 +1711,9 @@ class WebUIBackendComponent(BaseGatewayComponent):
1659
1711
  (summary_str[:100] + "...") if len(summary_str) > 100 else summary_str
1660
1712
  )
1661
1713
  except Exception:
1662
- details["payload_summary"][
1663
- "params_preview"
1664
- ] = "[Could not serialize payload]"
1714
+ details["payload_summary"]["params_preview"] = (
1715
+ "[Could not serialize payload]"
1716
+ )
1665
1717
 
1666
1718
  return details
1667
1719
 
@@ -1755,70 +1807,88 @@ class WebUIBackendComponent(BaseGatewayComponent):
1755
1807
 
1756
1808
  def get_agent_registry(self) -> AgentRegistry:
1757
1809
  return self.agent_registry
1758
-
1810
+
1759
1811
  def _check_agent_health(self):
1760
1812
  """
1761
1813
  Checks the health of peer agents and de-registers unresponsive ones.
1762
1814
  This is called periodically by the health check timer.
1763
1815
  Uses TTL-based expiration to determine if an agent is unresponsive.
1764
1816
  """
1765
-
1817
+
1766
1818
  log.debug("%s Performing agent health check...", self.log_identifier)
1767
-
1819
+
1768
1820
  # Get TTL from configuration or use default from constants
1769
- from ...common.constants import HEALTH_CHECK_TTL_SECONDS, HEALTH_CHECK_INTERVAL_SECONDS
1770
- ttl_seconds = self.get_config("agent_health_check_ttl_seconds", HEALTH_CHECK_TTL_SECONDS)
1771
- health_check_interval = self.get_config("agent_health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS)
1821
+ from ...common.constants import (
1822
+ HEALTH_CHECK_INTERVAL_SECONDS,
1823
+ HEALTH_CHECK_TTL_SECONDS,
1824
+ )
1825
+
1826
+ ttl_seconds = self.get_config(
1827
+ "agent_health_check_ttl_seconds", HEALTH_CHECK_TTL_SECONDS
1828
+ )
1829
+ health_check_interval = self.get_config(
1830
+ "agent_health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS
1831
+ )
1772
1832
 
1773
1833
  log.debug(
1774
1834
  "%s Health check configuration: interval=%d seconds, TTL=%d seconds",
1775
1835
  self.log_identifier,
1776
1836
  health_check_interval,
1777
- ttl_seconds
1837
+ ttl_seconds,
1778
1838
  )
1779
-
1839
+
1780
1840
  # Validate configuration values
1781
- if ttl_seconds <= 0 or health_check_interval <= 0 or ttl_seconds < health_check_interval:
1841
+ if (
1842
+ ttl_seconds <= 0
1843
+ or health_check_interval <= 0
1844
+ or ttl_seconds < health_check_interval
1845
+ ):
1782
1846
  log.error(
1783
1847
  "%s agent_health_check_ttl_seconds (%d) and agent_health_check_interval_seconds (%d) must be positive and TTL must be greater than interval.",
1784
1848
  self.log_identifier,
1785
1849
  ttl_seconds,
1786
- health_check_interval
1850
+ health_check_interval,
1787
1851
  )
1788
- raise ValueError(f"Invalid health check configuration. agent_health_check_ttl_seconds ({ttl_seconds}) and agent_health_check_interval_seconds ({health_check_interval}) must be positive and TTL must be greater than interval.")
1789
-
1852
+ raise ValueError(
1853
+ f"Invalid health check configuration. agent_health_check_ttl_seconds ({ttl_seconds}) and agent_health_check_interval_seconds ({health_check_interval}) must be positive and TTL must be greater than interval."
1854
+ )
1855
+
1790
1856
  # Get all agent names from the registry
1791
1857
  agent_names = self.agent_registry.get_agent_names()
1792
1858
  total_agents = len(agent_names)
1793
1859
  agents_to_deregister = []
1794
-
1795
- log.debug("%s Checking health of %d peer agents", self.log_identifier, total_agents)
1796
-
1860
+
1861
+ log.debug(
1862
+ "%s Checking health of %d peer agents", self.log_identifier, total_agents
1863
+ )
1864
+
1797
1865
  for agent_name in agent_names:
1798
1866
  # Check if the agent's TTL has expired
1799
- is_expired, time_since_last_seen = self.agent_registry.check_ttl_expired(agent_name, ttl_seconds)
1800
-
1867
+ is_expired, time_since_last_seen = self.agent_registry.check_ttl_expired(
1868
+ agent_name, ttl_seconds
1869
+ )
1870
+
1801
1871
  if is_expired:
1802
1872
  log.warning(
1803
1873
  "%s Agent '%s' TTL has expired. De-registering. Time since last seen: %d seconds (TTL: %d seconds)",
1804
1874
  self.log_identifier,
1805
1875
  agent_name,
1806
1876
  time_since_last_seen,
1807
- ttl_seconds
1877
+ ttl_seconds,
1808
1878
  )
1809
1879
  agents_to_deregister.append(agent_name)
1810
-
1880
+
1811
1881
  # De-register unresponsive agents
1812
1882
  for agent_name in agents_to_deregister:
1813
1883
  self._deregister_agent(agent_name)
1814
-
1815
- log.info(
1884
+
1885
+ log.debug(
1816
1886
  "%s Agent health check completed. Total agents: %d, De-registered: %d",
1817
1887
  self.log_identifier,
1818
1888
  total_agents,
1819
- len(agents_to_deregister)
1889
+ len(agents_to_deregister),
1820
1890
  )
1821
-
1891
+
1822
1892
  def _deregister_agent(self, agent_name: str):
1823
1893
  """
1824
1894
  De-registers an agent from the registry and publishes a de-registration event.
@@ -2052,6 +2122,15 @@ class WebUIBackendComponent(BaseGatewayComponent):
2052
2122
  )
2053
2123
  return
2054
2124
 
2125
+ try:
2126
+ from solace_agent_mesh_enterprise.auth.input_required import (
2127
+ handle_input_required_request,
2128
+ )
2129
+
2130
+ event_data = handle_input_required_request(event_data, sse_task_id, self)
2131
+ except ImportError:
2132
+ pass
2133
+
2055
2134
  log.debug(
2056
2135
  "%s Sending update for A2A Task ID %s to SSE Task ID %s. Final chunk: %s",
2057
2136
  log_id_prefix,
@@ -2073,7 +2152,7 @@ class WebUIBackendComponent(BaseGatewayComponent):
2073
2152
  await self.sse_manager.send_event(
2074
2153
  task_id=sse_task_id, event_data=sse_payload, event_type=sse_event_type
2075
2154
  )
2076
- log.info(
2155
+ log.debug(
2077
2156
  "%s Successfully sent %s via SSE for A2A Task ID %s.",
2078
2157
  log_id_prefix,
2079
2158
  sse_event_type,