solace-agent-mesh 1.4.12__py3-none-any.whl → 1.5.1__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 (359) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +3 -4
  2. solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
  3. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
  4. solace_agent_mesh/agent/adk/callbacks.py +56 -5
  5. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +3 -1
  6. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +2 -1
  7. solace_agent_mesh/agent/adk/mcp_content_processor.py +2 -1
  8. solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
  9. solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
  10. solace_agent_mesh/agent/adk/runner.py +3 -1
  11. solace_agent_mesh/agent/adk/services.py +4 -1
  12. solace_agent_mesh/agent/adk/setup.py +3 -1
  13. solace_agent_mesh/agent/adk/tool_wrapper.py +2 -2
  14. solace_agent_mesh/agent/agent_llm.txt +1 -1
  15. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  16. solace_agent_mesh/agent/protocol/event_handlers.py +4 -14
  17. solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
  18. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  19. solace_agent_mesh/agent/sac/app.py +3 -1
  20. solace_agent_mesh/agent/sac/component.py +55 -22
  21. solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
  22. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  23. solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
  24. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  25. solace_agent_mesh/agent/tools/audio_tools.py +2 -1
  26. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +3 -1
  27. solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +3 -1
  28. solace_agent_mesh/agent/tools/dynamic_tool.py +2 -1
  29. solace_agent_mesh/agent/tools/general_agent_tools.py +2 -1
  30. solace_agent_mesh/agent/tools/image_tools.py +2 -1
  31. solace_agent_mesh/agent/tools/peer_agent_tool.py +2 -1
  32. solace_agent_mesh/agent/tools/registry.py +3 -1
  33. solace_agent_mesh/agent/tools/test_tools.py +2 -1
  34. solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
  35. solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
  36. solace_agent_mesh/agent/tools/web_tools.py +2 -1
  37. solace_agent_mesh/agent/utils/artifact_helpers.py +3 -1
  38. solace_agent_mesh/agent/utils/config_parser.py +3 -1
  39. solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
  40. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  41. solace_agent_mesh/assets/docs/404.html +3 -3
  42. solace_agent_mesh/assets/docs/assets/js/{b7006a3a.73a79653.js → 032c2d61.f3d37824.js} +1 -1
  43. solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
  44. solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +1 -0
  45. solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
  46. solace_agent_mesh/assets/docs/assets/js/{2334.622a6395.js → 2334.1cf50a20.js} +1 -1
  47. solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +1 -0
  48. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
  49. solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
  50. solace_agent_mesh/assets/docs/assets/js/{3624.b524e433.js → 3624.0eaa1fd0.js} +1 -1
  51. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
  52. solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +1 -0
  53. solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +1 -0
  54. solace_agent_mesh/assets/docs/assets/js/509e993c.4c7a1a6d.js +1 -0
  55. solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +1 -0
  56. solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +1 -0
  57. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.e49689dd.js +1 -0
  58. solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
  59. solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +1 -0
  60. solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +1 -0
  61. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.39d5851d.js +1 -0
  62. solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +1 -0
  63. solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.js +1 -0
  64. solace_agent_mesh/assets/docs/assets/js/71da7b71.804d6567.js +1 -0
  65. solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
  66. solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
  67. solace_agent_mesh/assets/docs/assets/js/77cf947d.64c9bd6c.js +1 -0
  68. solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +1 -0
  69. solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +1 -0
  70. solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +1 -0
  71. solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js → 8591.5d015485.js} +2 -2
  72. solace_agent_mesh/assets/docs/assets/js/{8731.49e930c2.js → 8731.6c1dbf0c.js} +1 -1
  73. solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
  74. solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +1 -0
  75. solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +1 -0
  76. solace_agent_mesh/assets/docs/assets/js/9e9d0a82.dd810042.js +1 -0
  77. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +1 -0
  78. solace_agent_mesh/assets/docs/assets/js/ad71b5ed.60668e9e.js +1 -0
  79. solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
  80. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +1 -0
  81. solace_agent_mesh/assets/docs/assets/js/da0b5bad.9d369087.js +1 -0
  82. solace_agent_mesh/assets/docs/assets/js/db924877.cbc66f02.js +1 -0
  83. solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +1 -0
  84. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +1 -0
  85. solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
  86. solace_agent_mesh/assets/docs/assets/js/de915948.139b4b9c.js +1 -0
  87. solace_agent_mesh/assets/docs/assets/js/e3d9abda.2b916f9e.js +1 -0
  88. solace_agent_mesh/assets/docs/assets/js/e6f9706b.582a78ca.js +1 -0
  89. solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +1 -0
  90. solace_agent_mesh/assets/docs/assets/js/f284c35a.5766a13d.js +1 -0
  91. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.9c0297a6.js +1 -0
  92. solace_agent_mesh/assets/docs/assets/js/main.bd3c34f3.js +2 -0
  93. solace_agent_mesh/assets/docs/assets/js/runtime~main.18dc45dd.js +1 -0
  94. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +143 -0
  95. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/artifact-management/index.html +7 -7
  96. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/audio-tools/index.html +7 -7
  97. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/data-analysis-tools/index.html +8 -8
  98. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/embeds/index.html +6 -6
  99. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/index.html +11 -11
  100. solace_agent_mesh/assets/docs/docs/documentation/{concepts → components}/cli/index.html +25 -25
  101. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +91 -0
  102. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
  103. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
  104. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
  105. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +104 -0
  106. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +57 -0
  107. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
  108. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +59 -0
  109. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-agents/index.html +113 -152
  110. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-gateways/index.html +9 -9
  111. solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/creating-python-tools/index.html +12 -12
  112. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
  113. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +32 -0
  114. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
  115. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/bedrock-agents/index.html +25 -25
  116. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/custom-agent/index.html +13 -13
  117. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/event-mesh-gateway/index.html +11 -11
  118. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mcp-integration/index.html +10 -10
  119. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mongodb-integration/index.html +13 -13
  120. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rag-integration/index.html +13 -13
  121. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rest-gateway/index.html +10 -10
  122. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
  123. solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/sql-database/index.html +14 -14
  124. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +33 -0
  125. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +83 -0
  126. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +222 -0
  127. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +161 -0
  128. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
  129. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +53 -0
  130. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +35 -100
  131. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
  132. solace_agent_mesh/assets/docs/docs/documentation/{getting-started → installing-and-configuring}/configurations/index.html +56 -50
  133. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
  134. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +76 -0
  135. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +63 -0
  136. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
  137. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
  138. solace_agent_mesh/assets/docs/docs/documentation/{Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html → migrations/a2a-upgrade/a2a-technical-migration-map/index.html} +10 -11
  139. solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
  140. solace_agent_mesh/assets/docs/lunr-index-1760121512891.json +1 -0
  141. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  142. solace_agent_mesh/assets/docs/search-doc-1760121512891.json +1 -0
  143. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  144. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  145. solace_agent_mesh/cli/__init__.py +1 -1
  146. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
  147. solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
  148. solace_agent_mesh/client/webui/frontend/static/assets/main-2nd1gbaH.js +339 -0
  149. solace_agent_mesh/client/webui/frontend/static/assets/main-DoKXctCM.css +1 -0
  150. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
  151. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  152. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  153. solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
  154. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  155. solace_agent_mesh/common/a2a/artifact.py +2 -1
  156. solace_agent_mesh/common/a2a/protocol.py +3 -2
  157. solace_agent_mesh/common/a2a/translation.py +3 -1
  158. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
  159. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  160. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
  161. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
  162. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
  163. solace_agent_mesh/common/common_llm.txt +24 -39
  164. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  165. solace_agent_mesh/common/data_parts.py +9 -1
  166. solace_agent_mesh/common/middleware/config_resolver.py +3 -1
  167. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  168. solace_agent_mesh/common/middleware/registry.py +3 -1
  169. solace_agent_mesh/common/sac/sac_llm.txt +1 -1
  170. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  171. solace_agent_mesh/common/sac/sam_component_base.py +2 -1
  172. solace_agent_mesh/common/sam_events/event_service.py +3 -2
  173. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  174. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  175. solace_agent_mesh/common/services/employee_service.py +3 -1
  176. solace_agent_mesh/common/services/identity_service.py +2 -1
  177. solace_agent_mesh/common/services/providers/local_file_identity_service.py +2 -1
  178. solace_agent_mesh/common/services/services_llm.txt +57 -6
  179. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  180. solace_agent_mesh/common/utils/artifact_utils.py +3 -1
  181. solace_agent_mesh/common/utils/asyncio_macos_fix.py +3 -1
  182. solace_agent_mesh/common/utils/embeds/converter.py +3 -1
  183. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
  184. solace_agent_mesh/common/utils/embeds/evaluators.py +2 -1
  185. solace_agent_mesh/common/utils/embeds/modifiers.py +3 -2
  186. solace_agent_mesh/common/utils/embeds/resolver.py +2 -1
  187. solace_agent_mesh/common/utils/initializer.py +3 -1
  188. solace_agent_mesh/common/utils/message_utils.py +2 -1
  189. solace_agent_mesh/common/utils/push_notification_auth.py +3 -2
  190. solace_agent_mesh/common/utils/utils_llm.txt +75 -87
  191. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  192. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  193. solace_agent_mesh/core_a2a/service.py +2 -2
  194. solace_agent_mesh/gateway/base/app.py +3 -2
  195. solace_agent_mesh/gateway/base/base_llm.txt +1 -1
  196. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  197. solace_agent_mesh/gateway/base/component.py +3 -1
  198. solace_agent_mesh/gateway/base/task_context.py +2 -1
  199. solace_agent_mesh/gateway/gateway_llm.txt +242 -235
  200. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  201. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
  202. solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
  203. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  204. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
  205. solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
  206. solace_agent_mesh/gateway/http_sse/app.py +150 -3
  207. solace_agent_mesh/gateway/http_sse/component.py +372 -61
  208. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
  209. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
  210. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +4 -2
  211. solace_agent_mesh/gateway/http_sse/dependencies.py +119 -27
  212. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
  213. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  214. solace_agent_mesh/gateway/http_sse/main.py +149 -42
  215. solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
  216. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
  217. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
  218. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  219. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
  220. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  221. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
  222. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
  223. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  224. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
  225. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
  226. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
  227. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  228. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  229. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
  230. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
  231. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  232. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
  233. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
  234. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
  235. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
  236. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +3 -2
  237. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +3 -3
  238. solace_agent_mesh/gateway/http_sse/routers/auth.py +3 -1
  239. solace_agent_mesh/gateway/http_sse/routers/config.py +29 -6
  240. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
  241. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
  242. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
  243. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
  244. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  245. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
  246. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
  247. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
  248. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  249. solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
  250. solace_agent_mesh/gateway/http_sse/routers/people.py +3 -1
  251. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
  252. solace_agent_mesh/gateway/http_sse/routers/sessions.py +223 -41
  253. solace_agent_mesh/gateway/http_sse/routers/sse.py +3 -2
  254. solace_agent_mesh/gateway/http_sse/routers/tasks.py +170 -43
  255. solace_agent_mesh/gateway/http_sse/routers/users.py +3 -1
  256. solace_agent_mesh/gateway/http_sse/routers/visualization.py +2 -1
  257. solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +3 -1
  258. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +273 -0
  259. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +242 -0
  260. solace_agent_mesh/gateway/http_sse/services/people_service.py +2 -82
  261. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
  262. solace_agent_mesh/gateway/http_sse/services/session_service.py +154 -85
  263. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +318 -0
  264. solace_agent_mesh/gateway/http_sse/services/task_service.py +3 -2
  265. solace_agent_mesh/gateway/http_sse/session_manager.py +2 -1
  266. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
  267. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
  268. solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
  269. solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +2 -1
  270. solace_agent_mesh/gateway/http_sse/sse_manager.py +2 -2
  271. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  272. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
  273. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  274. solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
  275. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  276. solace_agent_mesh/templates/gateway_app_template.py +4 -2
  277. solace_agent_mesh/templates/gateway_component_template.py +3 -1
  278. solace_agent_mesh/templates/logging_config_template.ini +22 -45
  279. solace_agent_mesh/templates/plugin_tools_template.py +2 -2
  280. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/METADATA +2 -2
  281. solace_agent_mesh-1.5.1.dist-info/RECORD +504 -0
  282. solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
  283. solace_agent_mesh/assets/docs/assets/images/sac-flows-80d5b603c6aafd33e87945680ce0abf3.png +0 -0
  284. solace_agent_mesh/assets/docs/assets/images/sac_parts_of_a_component-cb3d0424b1d0c17734c5435cca6b4082.png +0 -0
  285. solace_agent_mesh/assets/docs/assets/js/04989206.a248f00c.js +0 -1
  286. solace_agent_mesh/assets/docs/assets/js/0e682baa.d54b8668.js +0 -1
  287. solace_agent_mesh/assets/docs/assets/js/1023fc19.8a8a9309.js +0 -1
  288. solace_agent_mesh/assets/docs/assets/js/1523c6b4.2645ef68.js +0 -1
  289. solace_agent_mesh/assets/docs/assets/js/166ab619.e27886d9.js +0 -1
  290. solace_agent_mesh/assets/docs/assets/js/1c6e87d2.e056b7e0.js +0 -1
  291. solace_agent_mesh/assets/docs/assets/js/21ceee5f.3bf39250.js +0 -1
  292. solace_agent_mesh/assets/docs/assets/js/2a9cab12.2afaee76.js +0 -1
  293. solace_agent_mesh/assets/docs/assets/js/332e10b5.f7629851.js +0 -1
  294. solace_agent_mesh/assets/docs/assets/js/3d406171.5560fdf9.js +0 -1
  295. solace_agent_mesh/assets/docs/assets/js/42b3f8d8.508ae8db.js +0 -1
  296. solace_agent_mesh/assets/docs/assets/js/442a8107.b5c2532a.js +0 -1
  297. solace_agent_mesh/assets/docs/assets/js/453a82a6.3c6bb61d.js +0 -1
  298. solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
  299. solace_agent_mesh/assets/docs/assets/js/4c2787c2.c1290a40.js +0 -1
  300. solace_agent_mesh/assets/docs/assets/js/55f47984.bcd00a86.js +0 -1
  301. solace_agent_mesh/assets/docs/assets/js/5b4258a4.fdfd2325.js +0 -1
  302. solace_agent_mesh/assets/docs/assets/js/664b740a.ba305a89.js +0 -1
  303. solace_agent_mesh/assets/docs/assets/js/75384d09.c19e8b51.js +0 -1
  304. solace_agent_mesh/assets/docs/assets/js/768e31b0.9abcdc48.js +0 -1
  305. solace_agent_mesh/assets/docs/assets/js/85387663.be2bc838.js +0 -1
  306. solace_agent_mesh/assets/docs/assets/js/945fb41e.16e00776.js +0 -1
  307. solace_agent_mesh/assets/docs/assets/js/9a09e75d.92de8cf5.js +0 -1
  308. solace_agent_mesh/assets/docs/assets/js/9eff14a2.d62aad71.js +0 -1
  309. solace_agent_mesh/assets/docs/assets/js/a12a4955.25fbed32.js +0 -1
  310. solace_agent_mesh/assets/docs/assets/js/a3a92b25.af35e313.js +0 -1
  311. solace_agent_mesh/assets/docs/assets/js/aba87c2f.4ddf32f2.js +0 -1
  312. solace_agent_mesh/assets/docs/assets/js/ae0e903d.5fe5203f.js +0 -1
  313. solace_agent_mesh/assets/docs/assets/js/ae4415af.16cc58d3.js +0 -1
  314. solace_agent_mesh/assets/docs/assets/js/bac0be12.17de4316.js +0 -1
  315. solace_agent_mesh/assets/docs/assets/js/c2c06897.87cb1f47.js +0 -1
  316. solace_agent_mesh/assets/docs/assets/js/c835a94d.ce21f0bf.js +0 -1
  317. solace_agent_mesh/assets/docs/assets/js/cc969b05.feef7dcc.js +0 -1
  318. solace_agent_mesh/assets/docs/assets/js/cd3d4052.a19e7d78.js +0 -1
  319. solace_agent_mesh/assets/docs/assets/js/ced92a13.fb92e7ca.js +0 -1
  320. solace_agent_mesh/assets/docs/assets/js/cee5d587.47904f5e.js +0 -1
  321. solace_agent_mesh/assets/docs/assets/js/d6a81ee7.829198f1.js +0 -1
  322. solace_agent_mesh/assets/docs/assets/js/f284c35a.ed8dd236.js +0 -1
  323. solace_agent_mesh/assets/docs/assets/js/f897a61a.126663fe.js +0 -1
  324. solace_agent_mesh/assets/docs/assets/js/fbfa3e75.e144b16c.js +0 -1
  325. solace_agent_mesh/assets/docs/assets/js/main.f67fc9f4.js +0 -2
  326. solace_agent_mesh/assets/docs/assets/js/runtime~main.40527046.js +0 -1
  327. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +0 -46
  328. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +0 -201
  329. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +0 -25
  330. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +0 -105
  331. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +0 -144
  332. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +0 -91
  333. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +0 -91
  334. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +0 -55
  335. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +0 -111
  336. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +0 -77
  337. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +0 -48
  338. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +0 -54
  339. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +0 -45
  340. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +0 -49
  341. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +0 -76
  342. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +0 -73
  343. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +0 -72
  344. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +0 -54
  345. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +0 -69
  346. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +0 -59
  347. solace_agent_mesh/assets/docs/lunr-index-1759936913198.json +0 -1
  348. solace_agent_mesh/assets/docs/search-doc-1759936913198.json +0 -1
  349. solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
  350. solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
  351. solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
  352. solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
  353. solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
  354. solace_agent_mesh-1.4.12.dist-info/RECORD +0 -448
  355. /solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js.LICENSE.txt → 8591.5d015485.js.LICENSE.txt} +0 -0
  356. /solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js.LICENSE.txt → main.bd3c34f3.js.LICENSE.txt} +0 -0
  357. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/WHEEL +0 -0
  358. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/entry_points.txt +0 -0
  359. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import os
2
3
  from pathlib import Path
3
4
  from typing import TYPE_CHECKING
@@ -14,7 +15,6 @@ from fastapi import status
14
15
  from fastapi.exceptions import RequestValidationError
15
16
  from fastapi.middleware.cors import CORSMiddleware
16
17
  from fastapi.responses import JSONResponse
17
- from solace_ai_connector.common.log import log
18
18
  from starlette.middleware.sessions import SessionMiddleware
19
19
  from starlette.staticfiles import StaticFiles
20
20
 
@@ -29,6 +29,7 @@ from ...gateway.http_sse.routers import (
29
29
  sse,
30
30
  tasks,
31
31
  visualization,
32
+ feedback,
32
33
  )
33
34
  from .routers.sessions import router as session_router
34
35
  from .routers.tasks import router as task_router
@@ -37,12 +38,17 @@ from .routers.users import router as user_router
37
38
  if TYPE_CHECKING:
38
39
  from gateway.http_sse.component import WebUIBackendComponent
39
40
 
41
+ log = logging.getLogger(__name__)
42
+
40
43
  app = FastAPI(
41
44
  title="A2A Web UI Backend",
42
45
  version="1.0.0", # Updated to reflect simplified architecture
43
46
  description="Backend API and SSE server for the A2A Web UI, hosted by Solace AI Connector.",
44
47
  )
45
48
 
49
+ # Global flag to track if dependencies have been initialized
50
+ _dependencies_initialized = False
51
+
46
52
 
47
53
  def _extract_access_token(request: FastAPIRequest) -> str:
48
54
  auth_header = request.headers.get("Authorization")
@@ -62,7 +68,9 @@ def _extract_access_token(request: FastAPIRequest) -> str:
62
68
  return None
63
69
 
64
70
 
65
- async def _validate_token(auth_service_url: str, auth_provider: str, access_token: str) -> bool:
71
+ async def _validate_token(
72
+ auth_service_url: str, auth_provider: str, access_token: str
73
+ ) -> bool:
66
74
  async with httpx.AsyncClient() as client:
67
75
  validation_response = await client.post(
68
76
  f"{auth_service_url}/is_token_valid",
@@ -72,7 +80,9 @@ async def _validate_token(auth_service_url: str, auth_provider: str, access_toke
72
80
  return validation_response.status_code == 200
73
81
 
74
82
 
75
- async def _get_user_info(auth_service_url: str, auth_provider: str, access_token: str) -> dict:
83
+ async def _get_user_info(
84
+ auth_service_url: str, auth_provider: str, access_token: str
85
+ ) -> dict:
76
86
  async with httpx.AsyncClient() as client:
77
87
  userinfo_response = await client.get(
78
88
  f"{auth_service_url}/user_info?provider={auth_provider}",
@@ -100,7 +110,9 @@ def _extract_user_identifier(user_info: dict) -> str:
100
110
  )
101
111
 
102
112
  if user_identifier and user_identifier.lower() == "unknown":
103
- log.warning("AuthMiddleware: IDP returned 'Unknown' as user identifier. Using fallback.")
113
+ log.warning(
114
+ "AuthMiddleware: IDP returned 'Unknown' as user identifier. Using fallback."
115
+ )
104
116
  return "sam_dev_user"
105
117
 
106
118
  return user_identifier
@@ -124,7 +136,9 @@ def _extract_user_details(user_info: dict, user_identifier: str) -> tuple:
124
136
  return email_from_auth, display_name
125
137
 
126
138
 
127
- async def _create_user_state_without_identity_service(user_identifier: str, email_from_auth: str, display_name: str) -> dict:
139
+ async def _create_user_state_without_identity_service(
140
+ user_identifier: str, email_from_auth: str, display_name: str
141
+ ) -> dict:
128
142
  final_user_id = user_identifier or email_from_auth or "sam_dev_user"
129
143
  if not final_user_id or final_user_id.lower() in ["unknown", "null", "none", ""]:
130
144
  final_user_id = "sam_dev_user"
@@ -146,7 +160,13 @@ async def _create_user_state_without_identity_service(user_identifier: str, emai
146
160
  }
147
161
 
148
162
 
149
- async def _create_user_state_with_identity_service(identity_service, user_identifier: str, email_from_auth: str, display_name: str, user_info: dict) -> dict:
163
+ async def _create_user_state_with_identity_service(
164
+ identity_service,
165
+ user_identifier: str,
166
+ email_from_auth: str,
167
+ display_name: str,
168
+ user_info: dict,
169
+ ) -> dict:
150
170
  lookup_value = email_from_auth if "@" in email_from_auth else user_identifier
151
171
  user_profile = await identity_service.get_user_profile(
152
172
  {identity_service.lookup_key: lookup_value, "user_info": user_info}
@@ -186,24 +206,35 @@ def _create_auth_middleware(component):
186
206
  return
187
207
 
188
208
  skip_paths = [
189
- "/api/v1/config", "/api/v1/auth/callback", "/api/v1/auth/login",
190
- "/api/v1/auth/refresh", "/api/v1/csrf-token", "/health",
209
+ "/api/v1/config",
210
+ "/api/v1/auth/callback",
211
+ "/api/v1/auth/login",
212
+ "/api/v1/auth/refresh",
213
+ "/api/v1/csrf-token",
214
+ "/health",
191
215
  ]
192
216
 
193
217
  if any(request.url.path.startswith(path) for path in skip_paths):
194
218
  await self.app(scope, receive, send)
195
219
  return
196
220
 
197
- use_auth = dependencies.api_config and dependencies.api_config.get("frontend_use_authorization")
221
+ use_auth = dependencies.api_config and dependencies.api_config.get(
222
+ "frontend_use_authorization"
223
+ )
198
224
 
199
225
  if use_auth:
200
226
  await self._handle_authenticated_request(request, scope, receive, send)
201
227
  else:
202
228
  request.state.user = {
203
- "id": "sam_dev_user", "name": "Sam Dev User", "email": "sam@dev.local",
204
- "authenticated": True, "auth_method": "development",
229
+ "id": "sam_dev_user",
230
+ "name": "Sam Dev User",
231
+ "email": "sam@dev.local",
232
+ "authenticated": True,
233
+ "auth_method": "development",
205
234
  }
206
- log.debug("AuthMiddleware: Set development user state with id: sam_dev_user")
235
+ log.debug(
236
+ "AuthMiddleware: Set development user state with id: sam_dev_user"
237
+ )
207
238
 
208
239
  await self.app(scope, receive, send)
209
240
 
@@ -214,13 +245,18 @@ def _create_auth_middleware(component):
214
245
  log.warning("AuthMiddleware: No access token found. Returning 401.")
215
246
  response = JSONResponse(
216
247
  status_code=status.HTTP_401_UNAUTHORIZED,
217
- content={"detail": "Not authenticated", "error_type": "authentication_required"},
248
+ content={
249
+ "detail": "Not authenticated",
250
+ "error_type": "authentication_required",
251
+ },
218
252
  )
219
253
  await response(scope, receive, send)
220
254
  return
221
255
 
222
256
  try:
223
- auth_service_url = dependencies.api_config.get("external_auth_service_url")
257
+ auth_service_url = dependencies.api_config.get(
258
+ "external_auth_service_url"
259
+ )
224
260
  auth_provider = dependencies.api_config.get("external_auth_provider")
225
261
 
226
262
  if not auth_service_url:
@@ -232,47 +268,85 @@ def _create_auth_middleware(component):
232
268
  await response(scope, receive, send)
233
269
  return
234
270
 
235
- if not await _validate_token(auth_service_url, auth_provider, access_token):
271
+ if not await _validate_token(
272
+ auth_service_url, auth_provider, access_token
273
+ ):
236
274
  log.warning("AuthMiddleware: Token validation failed")
237
275
  response = JSONResponse(
238
276
  status_code=status.HTTP_401_UNAUTHORIZED,
239
- content={"detail": "Invalid token", "error_type": "invalid_token"},
277
+ content={
278
+ "detail": "Invalid token",
279
+ "error_type": "invalid_token",
280
+ },
240
281
  )
241
282
  await response(scope, receive, send)
242
283
  return
243
284
 
244
- user_info = await _get_user_info(auth_service_url, auth_provider, access_token)
285
+ user_info = await _get_user_info(
286
+ auth_service_url, auth_provider, access_token
287
+ )
245
288
  if not user_info:
246
- log.warning("AuthMiddleware: Failed to get user info from external auth service")
289
+ log.warning(
290
+ "AuthMiddleware: Failed to get user info from external auth service"
291
+ )
247
292
  response = JSONResponse(
248
293
  status_code=status.HTTP_401_UNAUTHORIZED,
249
- content={"detail": "Could not retrieve user info from auth provider", "error_type": "user_info_failed"},
294
+ content={
295
+ "detail": "Could not retrieve user info from auth provider",
296
+ "error_type": "user_info_failed",
297
+ },
250
298
  )
251
299
  await response(scope, receive, send)
252
300
  return
253
301
 
254
302
  user_identifier = _extract_user_identifier(user_info)
255
- if not user_identifier or user_identifier.lower() in ["null", "none", ""]:
256
- log.error("AuthMiddleware: No valid user identifier from OAuth provider")
303
+ if not user_identifier or user_identifier.lower() in [
304
+ "null",
305
+ "none",
306
+ "",
307
+ ]:
308
+ log.error(
309
+ "AuthMiddleware: No valid user identifier from OAuth provider"
310
+ )
257
311
  response = JSONResponse(
258
312
  status_code=status.HTTP_401_UNAUTHORIZED,
259
- content={"detail": "OAuth provider returned no valid user identifier", "error_type": "invalid_user_identifier_from_provider"},
313
+ content={
314
+ "detail": "OAuth provider returned no valid user identifier",
315
+ "error_type": "invalid_user_identifier_from_provider",
316
+ },
260
317
  )
261
318
  await response(scope, receive, send)
262
319
  return
263
320
 
264
- email_from_auth, display_name = _extract_user_details(user_info, user_identifier)
321
+ email_from_auth, display_name = _extract_user_details(
322
+ user_info, user_identifier
323
+ )
265
324
 
266
325
  identity_service = self.component.identity_service
267
326
  if not identity_service:
268
- request.state.user = await _create_user_state_without_identity_service(user_identifier, email_from_auth, display_name)
327
+ request.state.user = (
328
+ await _create_user_state_without_identity_service(
329
+ user_identifier, email_from_auth, display_name
330
+ )
331
+ )
269
332
  else:
270
- user_state = await _create_user_state_with_identity_service(identity_service, user_identifier, email_from_auth, display_name, user_info)
333
+ user_state = await _create_user_state_with_identity_service(
334
+ identity_service,
335
+ user_identifier,
336
+ email_from_auth,
337
+ display_name,
338
+ user_info,
339
+ )
271
340
  if not user_state:
272
- log.error("AuthMiddleware: User authenticated but not found in internal IdentityService")
341
+ log.error(
342
+ "AuthMiddleware: User authenticated but not found in internal IdentityService"
343
+ )
273
344
  response = JSONResponse(
274
345
  status_code=status.HTTP_403_FORBIDDEN,
275
- content={"detail": "User not authorized for this application", "error_type": "not_authorized"},
346
+ content={
347
+ "detail": "User not authorized for this application",
348
+ "error_type": "not_authorized",
349
+ },
276
350
  )
277
351
  await response(scope, receive, send)
278
352
  return
@@ -287,10 +361,14 @@ def _create_auth_middleware(component):
287
361
  await response(scope, receive, send)
288
362
  return
289
363
  except Exception as exc:
290
- log.error("An unexpected error occurred during token validation: %s", exc)
364
+ log.error(
365
+ "An unexpected error occurred during token validation: %s", exc
366
+ )
291
367
  response = JSONResponse(
292
368
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
293
- content={"detail": "An internal error occurred during authentication"},
369
+ content={
370
+ "detail": "An internal error occurred during authentication"
371
+ },
294
372
  )
295
373
  await response(scope, receive, send)
296
374
  return
@@ -343,10 +421,14 @@ def _run_community_migrations(database_url: str) -> None:
343
421
  except Exception as migration_error:
344
422
  log.error("Community migration failed: %s", migration_error)
345
423
  log.error("Check database connectivity and permissions")
346
- raise RuntimeError(f"Community database migration failed: {migration_error}") from migration_error
424
+ raise RuntimeError(
425
+ f"Community database migration failed: {migration_error}"
426
+ ) from migration_error
347
427
 
348
428
 
349
- def _run_enterprise_migrations(component: "WebUIBackendComponent", database_url: str) -> None:
429
+ def _run_enterprise_migrations(
430
+ component: "WebUIBackendComponent", database_url: str
431
+ ) -> None:
350
432
  """
351
433
  Run migrations for enterprise features like advanced analytics, audit logs, etc.
352
434
  This is optional and only runs if the enterprise package is available.
@@ -420,7 +502,15 @@ def setup_dependencies(component: "WebUIBackendComponent", database_url: str = N
420
502
  backward compatibility with existing API contracts.
421
503
 
422
504
  If database_url is None, runs in compatibility mode with in-memory sessions.
505
+
506
+ This function is idempotent and safe to call multiple times.
423
507
  """
508
+ global _dependencies_initialized
509
+
510
+ if _dependencies_initialized:
511
+ log.debug("[setup_dependencies] Dependencies already initialized, skipping")
512
+ return
513
+
424
514
  dependencies.set_component_instance(component)
425
515
 
426
516
  if database_url:
@@ -441,6 +531,9 @@ def setup_dependencies(component: "WebUIBackendComponent", database_url: str = N
441
531
  _setup_routers()
442
532
  _setup_static_files()
443
533
 
534
+ _dependencies_initialized = True
535
+ log.info("[setup_dependencies] Dependencies initialization complete")
536
+
444
537
 
445
538
  def _setup_middleware(component: "WebUIBackendComponent") -> None:
446
539
  allowed_origins = component.get_cors_origins()
@@ -467,39 +560,50 @@ def _setup_routers() -> None:
467
560
 
468
561
  app.include_router(session_router, prefix=api_prefix, tags=["Sessions"])
469
562
  app.include_router(user_router, prefix=f"{api_prefix}/users", tags=["Users"])
470
- app.include_router(task_router, prefix=f"{api_prefix}/tasks", tags=["Tasks"])
471
563
  app.include_router(config.router, prefix=api_prefix, tags=["Config"])
472
564
  app.include_router(agent_cards.router, prefix=api_prefix, tags=["Agent Cards"])
473
- app.include_router(tasks.router, prefix=api_prefix, tags=["A2A Messages"])
565
+ app.include_router(tasks.router, prefix=api_prefix, tags=["Tasks"])
474
566
  app.include_router(sse.router, prefix=f"{api_prefix}/sse", tags=["SSE"])
475
- app.include_router(artifacts.router, prefix=f"{api_prefix}/artifacts", tags=["Artifacts"])
476
- app.include_router(visualization.router, prefix=f"{api_prefix}/visualization", tags=["Visualization"])
567
+ app.include_router(
568
+ artifacts.router, prefix=f"{api_prefix}/artifacts", tags=["Artifacts"]
569
+ )
570
+ app.include_router(
571
+ visualization.router,
572
+ prefix=f"{api_prefix}/visualization",
573
+ tags=["Visualization"],
574
+ )
477
575
  app.include_router(people.router, prefix=api_prefix, tags=["People"])
478
576
  app.include_router(auth.router, prefix=api_prefix, tags=["Auth"])
577
+ app.include_router(feedback.router, prefix=api_prefix, tags=["Feedback"])
479
578
  log.info("Legacy routers mounted for endpoints not yet migrated")
480
579
 
481
580
  # Register shared exception handlers from community repo
482
581
  from .shared.exception_handlers import register_exception_handlers
582
+
483
583
  register_exception_handlers(app)
484
584
  log.info("Registered shared exception handlers from community repo")
485
585
 
486
586
  # Mount enterprise routers if available
487
587
  try:
488
- from solace_agent_mesh_enterprise.webui_backend.routers import get_enterprise_routers
588
+ from solace_agent_mesh_enterprise.webui_backend.routers import (
589
+ get_enterprise_routers,
590
+ )
489
591
 
490
592
  enterprise_routers = get_enterprise_routers()
491
593
  for router_config in enterprise_routers:
492
594
  app.include_router(
493
595
  router_config["router"],
494
596
  prefix=router_config["prefix"],
495
- tags=router_config["tags"]
597
+ tags=router_config["tags"],
496
598
  )
497
599
  log.info("Mounted %d enterprise routers", len(enterprise_routers))
498
600
 
499
601
  except ImportError:
500
602
  log.debug("No enterprise package detected - skipping enterprise routers")
501
603
  except ModuleNotFoundError:
502
- log.debug("Enterprise module not found - skipping enterprise routers and exception handlers")
604
+ log.debug(
605
+ "Enterprise module not found - skipping enterprise routers and exception handlers"
606
+ )
503
607
  except Exception as e:
504
608
  log.warning("Failed to load enterprise routers and exception handlers: %s", e)
505
609
 
@@ -535,7 +639,7 @@ async def http_exception_handler(request: FastAPIRequest, exc: HTTPException):
535
639
  Returns JSON-RPC format for tasks/SSE endpoints, REST format for others.
536
640
  """
537
641
  log.warning(
538
- "HTTP Exception: Status=%s, Detail=%s, Request: %s %s",
642
+ "HTTP Exception Handler triggered: Status=%s, Detail=%s, Request: %s %s",
539
643
  exc.status_code,
540
644
  exc.detail,
541
645
  request.method,
@@ -594,7 +698,7 @@ async def validation_exception_handler(
594
698
  Handles Pydantic validation errors with format detection.
595
699
  """
596
700
  log.warning(
597
- "Request Validation Error: %s, Request: %s %s",
701
+ "Validation Exception Handler triggered: %s, Request: %s %s",
598
702
  exc.errors(),
599
703
  request.method,
600
704
  request.url,
@@ -603,7 +707,7 @@ async def validation_exception_handler(
603
707
  message="Invalid request parameters", data=exc.errors(), request_id=None
604
708
  )
605
709
  return JSONResponse(
606
- status_code=status.HTTP_400_BAD_REQUEST,
710
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
607
711
  content=response.model_dump(exclude_none=True),
608
712
  )
609
713
 
@@ -614,7 +718,10 @@ async def generic_exception_handler(request: FastAPIRequest, exc: Exception):
614
718
  Handles any other unexpected exceptions with format detection.
615
719
  """
616
720
  log.exception(
617
- "Unhandled Exception: %s, Request: %s %s", exc, request.method, request.url
721
+ "Generic Exception Handler triggered: %s, Request: %s %s",
722
+ exc,
723
+ request.method,
724
+ request.url,
618
725
  )
619
726
  error_obj = a2a.create_internal_error(
620
727
  message="An unexpected server error occurred: %s" % type(exc).__name__
@@ -3,35 +3,26 @@ Repository layer containing all data access logic organized by entity type.
3
3
  """
4
4
 
5
5
  # Interfaces
6
- from .interfaces import IMessageRepository, ISessionRepository
6
+ from .interfaces import ISessionRepository
7
7
 
8
8
  # Implementations
9
- from .message_repository import MessageRepository
10
9
  from .session_repository import SessionRepository
11
10
 
12
11
  # Entities (re-exported for convenience)
13
12
  from .entities.session import Session
14
- from .entities.message import Message
15
- from .entities.session_history import SessionHistory
16
13
 
17
14
  # Models (re-exported for convenience)
18
15
  from .models.base import Base
19
16
  from .models.session_model import SessionModel
20
- from .models.message_model import MessageModel
21
17
 
22
18
  __all__ = [
23
19
  # Interfaces
24
- "IMessageRepository",
25
20
  "ISessionRepository",
26
21
  # Implementations
27
- "MessageRepository",
28
22
  "SessionRepository",
29
23
  # Entities
30
- "Message",
31
- "Session",
32
- "SessionHistory",
24
+ "Session",
33
25
  # Models
34
26
  "Base",
35
- "MessageModel",
36
27
  "SessionModel",
37
- ]
28
+ ]
@@ -0,0 +1,103 @@
1
+ """
2
+ ChatTask repository implementation using SQLAlchemy.
3
+ """
4
+
5
+ from typing import List, Optional
6
+
7
+ from sqlalchemy.orm import Session as DBSession
8
+
9
+ from ..shared import now_epoch_ms
10
+ from ..shared.types import SessionId, UserId
11
+ from .entities import ChatTask
12
+ from .interfaces import IChatTaskRepository
13
+ from .models import ChatTaskModel
14
+
15
+
16
+ class ChatTaskRepository(IChatTaskRepository):
17
+ """SQLAlchemy implementation of chat task repository."""
18
+
19
+ def __init__(self, db: DBSession):
20
+ self.db = db
21
+
22
+ def save(self, task: ChatTask) -> ChatTask:
23
+ """Save or update a chat task (upsert)."""
24
+ existing = self.db.query(ChatTaskModel).filter(
25
+ ChatTaskModel.id == task.id
26
+ ).first()
27
+
28
+ if existing:
29
+ # Update existing task - store strings directly
30
+ existing.user_message = task.user_message
31
+ existing.message_bubbles = task.message_bubbles # Already a string
32
+ existing.task_metadata = task.task_metadata # Already a string
33
+ existing.updated_time = now_epoch_ms()
34
+ else:
35
+ # Create new task - store strings directly
36
+ model = ChatTaskModel(
37
+ id=task.id,
38
+ session_id=task.session_id,
39
+ user_id=task.user_id,
40
+ user_message=task.user_message,
41
+ message_bubbles=task.message_bubbles, # Already a string
42
+ task_metadata=task.task_metadata, # Already a string
43
+ created_time=task.created_time,
44
+ updated_time=task.updated_time
45
+ )
46
+ self.db.add(model)
47
+
48
+ self.db.commit()
49
+
50
+ # Reload to get updated values
51
+ model = self.db.query(ChatTaskModel).filter(
52
+ ChatTaskModel.id == task.id
53
+ ).first()
54
+
55
+ return self._model_to_entity(model)
56
+
57
+ def find_by_session(
58
+ self,
59
+ session_id: SessionId,
60
+ user_id: UserId
61
+ ) -> List[ChatTask]:
62
+ """Find all tasks for a session."""
63
+ models = self.db.query(ChatTaskModel).filter(
64
+ ChatTaskModel.session_id == session_id,
65
+ ChatTaskModel.user_id == user_id
66
+ ).order_by(ChatTaskModel.created_time.asc()).all()
67
+
68
+ return [self._model_to_entity(m) for m in models]
69
+
70
+ def find_by_id(
71
+ self,
72
+ task_id: str,
73
+ user_id: UserId
74
+ ) -> Optional[ChatTask]:
75
+ """Find a specific task."""
76
+ model = self.db.query(ChatTaskModel).filter(
77
+ ChatTaskModel.id == task_id,
78
+ ChatTaskModel.user_id == user_id
79
+ ).first()
80
+
81
+ return self._model_to_entity(model) if model else None
82
+
83
+ def delete_by_session(self, session_id: SessionId) -> bool:
84
+ """Delete all tasks for a session."""
85
+ result = self.db.query(ChatTaskModel).filter(
86
+ ChatTaskModel.session_id == session_id
87
+ ).delete()
88
+ self.db.commit()
89
+ return result > 0
90
+
91
+ def _model_to_entity(self, model: ChatTaskModel) -> ChatTask:
92
+ """Convert SQLAlchemy model to domain entity."""
93
+ # No deserialization - just pass strings through
94
+ return ChatTask(
95
+ id=model.id,
96
+ session_id=model.session_id,
97
+ user_id=model.user_id,
98
+ user_message=model.user_message,
99
+ message_bubbles=model.message_bubbles, # String (opaque)
100
+ task_metadata=model.task_metadata, # String (opaque)
101
+ created_time=model.created_time,
102
+ updated_time=model.updated_time
103
+ )
@@ -2,8 +2,10 @@
2
2
  Domain entities for the repository layer.
3
3
  """
4
4
 
5
- from .message import Message
5
+ from .chat_task import ChatTask
6
+ from .feedback import Feedback
6
7
  from .session import Session
7
- from .session_history import SessionHistory
8
+ from .task import Task
9
+ from .task_event import TaskEvent
8
10
 
9
- __all__ = ["Message", "Session", "SessionHistory"]
11
+ __all__ = ["ChatTask", "Feedback", "Session", "Task", "TaskEvent"]
@@ -0,0 +1,75 @@
1
+ """
2
+ ChatTask domain entity.
3
+ """
4
+
5
+ import json
6
+ from typing import Any, Dict, Optional
7
+
8
+ from pydantic import BaseModel, ConfigDict, field_validator
9
+
10
+
11
+ class ChatTask(BaseModel):
12
+ """ChatTask domain entity with business logic."""
13
+
14
+ model_config = ConfigDict(from_attributes=True)
15
+
16
+ id: str
17
+ session_id: str
18
+ user_id: str
19
+ user_message: Optional[str] = None
20
+ message_bubbles: str # JSON string (opaque to backend)
21
+ task_metadata: Optional[str] = None # JSON string (opaque to backend)
22
+ created_time: int
23
+ updated_time: Optional[int] = None
24
+
25
+ @field_validator("message_bubbles")
26
+ @classmethod
27
+ def validate_message_bubbles(cls, v: str) -> str:
28
+ """Validate that message_bubbles is a non-empty JSON string."""
29
+ if not v or not v.strip():
30
+ raise ValueError("message_bubbles cannot be empty")
31
+
32
+ # Validate it's valid JSON (but don't validate structure)
33
+ try:
34
+ parsed = json.loads(v)
35
+ if not isinstance(parsed, list) or len(parsed) == 0:
36
+ raise ValueError("message_bubbles must be a non-empty JSON array")
37
+ except json.JSONDecodeError as e:
38
+ raise ValueError(f"message_bubbles must be valid JSON: {e}")
39
+
40
+ return v
41
+
42
+ @field_validator("task_metadata")
43
+ @classmethod
44
+ def validate_task_metadata(cls, v: Optional[str]) -> Optional[str]:
45
+ """Validate that task_metadata is valid JSON if provided."""
46
+ if v is None or not v.strip():
47
+ return None
48
+
49
+ # Validate it's valid JSON (but don't validate structure)
50
+ try:
51
+ json.loads(v)
52
+ except json.JSONDecodeError as e:
53
+ raise ValueError(f"task_metadata must be valid JSON: {e}")
54
+
55
+ return v
56
+
57
+ def add_feedback(self, feedback_type: str, feedback_text: Optional[str] = None) -> None:
58
+ """Add or update feedback for this task."""
59
+ # Parse metadata, update, re-serialize
60
+ metadata = json.loads(self.task_metadata) if self.task_metadata else {}
61
+
62
+ metadata["feedback"] = {
63
+ "type": feedback_type,
64
+ "text": feedback_text,
65
+ "submitted": True
66
+ }
67
+
68
+ self.task_metadata = json.dumps(metadata)
69
+
70
+ def get_feedback(self) -> Optional[Dict[str, Any]]:
71
+ """Get feedback for this task."""
72
+ if self.task_metadata:
73
+ metadata = json.loads(self.task_metadata)
74
+ return metadata.get("feedback")
75
+ return None