solace-agent-mesh 1.6.1__py3-none-any.whl → 1.13.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (481) hide show
  1. solace_agent_mesh/agent/adk/alembic/README +74 -0
  2. solace_agent_mesh/agent/adk/alembic/env.py +77 -0
  3. solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
  4. solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
  5. solace_agent_mesh/agent/adk/alembic.ini +112 -0
  6. solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
  7. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +165 -1
  8. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
  9. solace_agent_mesh/agent/adk/callbacks.py +852 -109
  10. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +234 -36
  11. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
  12. solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
  13. solace_agent_mesh/agent/adk/models/lite_llm.py +77 -21
  14. solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
  15. solace_agent_mesh/agent/adk/runner.py +85 -20
  16. solace_agent_mesh/agent/adk/schema_migration.py +88 -0
  17. solace_agent_mesh/agent/adk/services.py +94 -18
  18. solace_agent_mesh/agent/adk/setup.py +281 -65
  19. solace_agent_mesh/agent/adk/stream_parser.py +231 -37
  20. solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
  21. solace_agent_mesh/agent/protocol/event_handlers.py +472 -137
  22. solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
  23. solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
  24. solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
  25. solace_agent_mesh/agent/proxies/base/app.py +3 -2
  26. solace_agent_mesh/agent/proxies/base/component.py +188 -22
  27. solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
  28. solace_agent_mesh/agent/sac/app.py +91 -3
  29. solace_agent_mesh/agent/sac/component.py +591 -157
  30. solace_agent_mesh/agent/sac/patch_adk.py +8 -16
  31. solace_agent_mesh/agent/sac/task_execution_context.py +146 -4
  32. solace_agent_mesh/agent/tools/__init__.py +3 -0
  33. solace_agent_mesh/agent/tools/audio_tools.py +3 -3
  34. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +710 -171
  35. solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
  36. solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
  37. solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
  38. solace_agent_mesh/agent/tools/time_tools.py +126 -0
  39. solace_agent_mesh/agent/tools/tool_config_types.py +57 -2
  40. solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
  41. solace_agent_mesh/agent/tools/web_tools.py +125 -17
  42. solace_agent_mesh/agent/utils/artifact_helpers.py +248 -6
  43. solace_agent_mesh/agent/utils/context_helpers.py +17 -0
  44. solace_agent_mesh/assets/docs/404.html +6 -6
  45. solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
  46. solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
  47. solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
  48. solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
  49. solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
  50. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
  51. solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
  52. solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
  53. solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
  54. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
  55. solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
  56. solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
  57. solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
  58. solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
  59. solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
  60. solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
  61. solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
  62. solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
  63. solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
  64. solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
  65. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
  66. solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
  67. solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
  68. solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
  69. solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
  70. solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
  71. solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
  72. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
  73. solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
  74. solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
  75. solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
  76. solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
  77. solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
  78. solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
  79. solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
  80. solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
  81. solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
  82. solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
  83. solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
  84. solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
  85. solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
  86. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
  87. solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
  88. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
  89. solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
  90. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
  91. solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
  92. solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
  93. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
  94. solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
  95. solace_agent_mesh/assets/docs/assets/js/e04b235d.06d23db6.js +1 -0
  96. solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
  97. solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
  98. solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
  99. solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
  100. solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
  101. solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
  102. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
  103. solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
  104. solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
  105. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
  106. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
  107. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
  108. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
  109. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +82 -68
  110. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
  111. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
  112. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
  113. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
  114. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
  115. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
  116. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
  117. solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
  118. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
  119. solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
  120. solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
  121. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
  122. solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
  123. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -49
  124. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -30
  125. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
  126. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
  127. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
  128. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +90 -0
  129. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -16
  130. solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
  131. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
  132. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +162 -171
  133. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
  134. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
  135. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
  136. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
  137. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
  138. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
  139. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
  140. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
  141. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
  142. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
  143. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
  144. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
  145. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
  146. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
  147. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
  148. solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
  149. solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
  150. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +23 -19
  151. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
  152. solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
  153. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +112 -87
  154. solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
  155. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +87 -64
  156. solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
  157. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +44 -44
  158. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -37
  159. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
  160. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
  161. solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
  162. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +311 -0
  163. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +39 -42
  164. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
  165. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
  166. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
  167. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
  168. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
  169. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
  170. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +42 -42
  171. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
  172. solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
  173. solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
  174. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  175. solace_agent_mesh/assets/docs/search-doc-1768329217460.json +1 -0
  176. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  177. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  178. solace_agent_mesh/cli/__init__.py +1 -1
  179. solace_agent_mesh/cli/commands/add_cmd/__init__.py +3 -1
  180. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
  181. solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
  182. solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
  183. solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
  184. solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
  185. solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
  186. solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
  187. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
  188. solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
  189. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
  190. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
  191. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
  192. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
  193. solace_agent_mesh/cli/commands/run_cmd.py +64 -49
  194. solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
  195. solace_agent_mesh/cli/main.py +15 -0
  196. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-KnKMP_vb.js} +1 -1
  197. solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
  198. solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
  199. solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
  200. solace_agent_mesh/client/webui/frontend/static/assets/vendor-CGk8Suyh.js +565 -0
  201. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  202. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  203. solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
  204. solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
  205. solace_agent_mesh/common/a2a/events.py +2 -1
  206. solace_agent_mesh/common/a2a/protocol.py +5 -0
  207. solace_agent_mesh/common/a2a/types.py +2 -1
  208. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
  209. solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
  210. solace_agent_mesh/common/agent_registry.py +38 -11
  211. solace_agent_mesh/common/data_parts.py +144 -4
  212. solace_agent_mesh/common/error_handlers.py +83 -0
  213. solace_agent_mesh/common/exceptions.py +24 -0
  214. solace_agent_mesh/common/oauth/__init__.py +17 -0
  215. solace_agent_mesh/common/oauth/oauth_client.py +408 -0
  216. solace_agent_mesh/common/oauth/utils.py +50 -0
  217. solace_agent_mesh/common/rag_dto.py +156 -0
  218. solace_agent_mesh/common/sac/sam_component_base.py +97 -19
  219. solace_agent_mesh/common/sam_events/event_service.py +2 -2
  220. solace_agent_mesh/common/services/employee_service.py +1 -1
  221. solace_agent_mesh/common/utils/embeds/constants.py +1 -0
  222. solace_agent_mesh/common/utils/embeds/converter.py +1 -8
  223. solace_agent_mesh/common/utils/embeds/modifiers.py +4 -28
  224. solace_agent_mesh/common/utils/embeds/resolver.py +152 -31
  225. solace_agent_mesh/common/utils/embeds/types.py +9 -0
  226. solace_agent_mesh/common/utils/log_formatters.py +20 -0
  227. solace_agent_mesh/common/utils/mime_helpers.py +12 -5
  228. solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
  229. solace_agent_mesh/common/utils/rbac_utils.py +69 -0
  230. solace_agent_mesh/common/utils/templates/__init__.py +8 -0
  231. solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
  232. solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
  233. solace_agent_mesh/config_portal/backend/common.py +12 -0
  234. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
  235. solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
  236. solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
  237. solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
  238. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
  239. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
  240. solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
  241. solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
  242. solace_agent_mesh/core_a2a/service.py +3 -2
  243. solace_agent_mesh/gateway/adapter/__init__.py +1 -0
  244. solace_agent_mesh/gateway/adapter/base.py +170 -0
  245. solace_agent_mesh/gateway/adapter/types.py +230 -0
  246. solace_agent_mesh/gateway/base/app.py +39 -2
  247. solace_agent_mesh/gateway/base/auth_interface.py +103 -0
  248. solace_agent_mesh/gateway/base/component.py +1027 -151
  249. solace_agent_mesh/gateway/generic/__init__.py +1 -0
  250. solace_agent_mesh/gateway/generic/app.py +50 -0
  251. solace_agent_mesh/gateway/generic/component.py +894 -0
  252. solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
  253. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
  254. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
  255. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
  256. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
  257. solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
  258. solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
  259. solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
  260. solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
  261. solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
  262. solace_agent_mesh/gateway/http_sse/app.py +40 -11
  263. solace_agent_mesh/gateway/http_sse/component.py +285 -160
  264. solace_agent_mesh/gateway/http_sse/dependencies.py +149 -114
  265. solace_agent_mesh/gateway/http_sse/main.py +68 -450
  266. solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
  267. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
  268. solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
  269. solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
  270. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +26 -3
  271. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
  272. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
  273. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +114 -6
  274. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +13 -0
  275. solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
  276. solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
  277. solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
  278. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +8 -2
  279. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
  280. solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
  281. solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
  282. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +177 -11
  283. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
  284. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
  285. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +256 -58
  286. solace_agent_mesh/gateway/http_sse/routers/auth.py +168 -134
  287. solace_agent_mesh/gateway/http_sse/routers/config.py +302 -8
  288. solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
  289. solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
  290. solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
  291. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +14 -1
  292. solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
  293. solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
  294. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +5 -2
  295. solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
  296. solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
  297. solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
  298. solace_agent_mesh/gateway/http_sse/routers/projects.py +768 -0
  299. solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
  300. solace_agent_mesh/gateway/http_sse/routers/sessions.py +167 -7
  301. solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
  302. solace_agent_mesh/gateway/http_sse/routers/sse.py +131 -8
  303. solace_agent_mesh/gateway/http_sse/routers/tasks.py +670 -18
  304. solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
  305. solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
  306. solace_agent_mesh/gateway/http_sse/routers/visualization.py +92 -9
  307. solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
  308. solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
  309. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
  310. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
  311. solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
  312. solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
  313. solace_agent_mesh/gateway/http_sse/services/session_service.py +361 -12
  314. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
  315. solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
  316. solace_agent_mesh/gateway/http_sse/sse_manager.py +286 -166
  317. solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
  318. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
  319. solace_agent_mesh/services/__init__.py +0 -0
  320. solace_agent_mesh/services/platform/__init__.py +29 -0
  321. solace_agent_mesh/services/platform/alembic/env.py +85 -0
  322. solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
  323. solace_agent_mesh/services/platform/alembic.ini +109 -0
  324. solace_agent_mesh/services/platform/api/__init__.py +3 -0
  325. solace_agent_mesh/services/platform/api/dependencies.py +154 -0
  326. solace_agent_mesh/services/platform/api/main.py +314 -0
  327. solace_agent_mesh/services/platform/api/middleware.py +51 -0
  328. solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
  329. solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
  330. solace_agent_mesh/services/platform/app.py +215 -0
  331. solace_agent_mesh/services/platform/component.py +777 -0
  332. solace_agent_mesh/shared/__init__.py +14 -0
  333. solace_agent_mesh/shared/api/__init__.py +42 -0
  334. solace_agent_mesh/shared/auth/__init__.py +26 -0
  335. solace_agent_mesh/shared/auth/dependencies.py +204 -0
  336. solace_agent_mesh/shared/auth/middleware.py +347 -0
  337. solace_agent_mesh/shared/database/__init__.py +20 -0
  338. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
  339. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
  340. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
  341. solace_agent_mesh/shared/exceptions/__init__.py +36 -0
  342. solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +19 -5
  343. solace_agent_mesh/shared/utils/__init__.py +21 -0
  344. solace_agent_mesh/templates/logging_config_template.yaml +48 -0
  345. solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
  346. solace_agent_mesh/templates/platform.yaml +49 -0
  347. solace_agent_mesh/templates/plugin_readme_template.md +3 -25
  348. solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
  349. solace_agent_mesh/templates/proxy_template.yaml +62 -0
  350. solace_agent_mesh/templates/webui.yaml +148 -6
  351. solace_agent_mesh/tools/web_search/__init__.py +18 -0
  352. solace_agent_mesh/tools/web_search/base.py +84 -0
  353. solace_agent_mesh/tools/web_search/google_search.py +247 -0
  354. solace_agent_mesh/tools/web_search/models.py +99 -0
  355. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +31 -12
  356. solace_agent_mesh-1.13.2.dist-info/RECORD +591 -0
  357. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
  358. solace_agent_mesh/agent/adk/adk_llm.txt +0 -232
  359. solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
  360. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
  361. solace_agent_mesh/agent/adk/models/models_llm.txt +0 -142
  362. solace_agent_mesh/agent/agent_llm.txt +0 -378
  363. solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
  364. solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
  365. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
  366. solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
  367. solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
  368. solace_agent_mesh/agent/testing/testing_llm.txt +0 -57
  369. solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
  370. solace_agent_mesh/agent/tools/tools_llm.txt +0 -263
  371. solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -274
  372. solace_agent_mesh/agent/utils/utils_llm.txt +0 -138
  373. solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
  374. solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
  375. solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
  376. solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
  377. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
  378. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +0 -1
  379. solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
  380. solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
  381. solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
  382. solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
  383. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
  384. solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
  385. solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
  386. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
  387. solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
  388. solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
  389. solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
  390. solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
  391. solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
  392. solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
  393. solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
  394. solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
  395. solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
  396. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +0 -1
  397. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
  398. solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
  399. solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
  400. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
  401. solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
  402. solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
  403. solace_agent_mesh/assets/docs/assets/js/e6f9706b.e74a984d.js +0 -1
  404. solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
  405. solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
  406. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
  407. solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
  408. solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
  409. solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
  410. solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
  411. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
  412. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
  413. solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
  414. solace_agent_mesh/client/webui/frontend/static/assets/client-CaY59VuC.js +0 -25
  415. solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
  416. solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
  417. solace_agent_mesh/client/webui/frontend/static/assets/vendor-BEmvJSYz.js +0 -405
  418. solace_agent_mesh/common/a2a/a2a_llm.txt +0 -182
  419. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
  420. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -407
  421. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
  422. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -313
  423. solace_agent_mesh/common/common_llm.txt +0 -251
  424. solace_agent_mesh/common/common_llm_detail.txt +0 -2562
  425. solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
  426. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
  427. solace_agent_mesh/common/sac/sac_llm.txt +0 -71
  428. solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
  429. solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
  430. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
  431. solace_agent_mesh/common/services/providers/providers_llm.txt +0 -80
  432. solace_agent_mesh/common/services/services_llm.txt +0 -363
  433. solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
  434. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
  435. solace_agent_mesh/common/utils/utils_llm.txt +0 -336
  436. solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
  437. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
  438. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
  439. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
  440. solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
  441. solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
  442. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
  443. solace_agent_mesh/gateway/base/base_llm.txt +0 -224
  444. solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
  445. solace_agent_mesh/gateway/gateway_llm.txt +0 -373
  446. solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
  447. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -295
  448. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -155
  449. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
  450. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
  451. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
  452. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -263
  453. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -266
  454. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -340
  455. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -346
  456. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -83
  457. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -107
  458. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -314
  459. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -297
  460. solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
  461. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -285
  462. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
  463. solace_agent_mesh/llm.txt +0 -228
  464. solace_agent_mesh/llm_detail.txt +0 -2835
  465. solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
  466. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
  467. solace_agent_mesh/templates/logging_config_template.ini +0 -45
  468. solace_agent_mesh/templates/templates_llm.txt +0 -147
  469. solace_agent_mesh-1.6.1.dist-info/RECORD +0 -525
  470. /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
  471. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
  472. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
  473. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
  474. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
  475. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
  476. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
  477. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
  478. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
  479. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
  480. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
  481. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
@@ -3,6 +3,7 @@ Service for logging A2A tasks and events to the database.
3
3
  """
4
4
 
5
5
  import copy
6
+ import json
6
7
  import logging
7
8
  import uuid
8
9
  from typing import Any, Callable, Dict, Union
@@ -20,7 +21,7 @@ from sqlalchemy.orm import Session as DBSession
20
21
  from ....common import a2a
21
22
  from ..repository.entities import Task, TaskEvent
22
23
  from ..repository.task_repository import TaskRepository
23
- from ..shared import now_epoch_ms
24
+ from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
24
25
 
25
26
  log = logging.getLogger(__name__)
26
27
 
@@ -97,33 +98,83 @@ class TaskLoggerService:
97
98
  # Check for existing task or create a new one
98
99
  task = repo.find_by_id(db, task_id)
99
100
  if not task:
101
+ # Extract parent_task_id and background execution metadata
102
+ parent_task_id = None
103
+ background_execution_enabled = False
104
+ max_execution_time_ms = None
105
+
106
+ log.info(
107
+ f"{self.log_identifier} Creating new task {task_id}: direction={direction}, "
108
+ f"parsed_event_type={type(parsed_event).__name__}"
109
+ )
110
+
111
+ if direction == "request" and isinstance(parsed_event, A2ARequest):
112
+ message = a2a.get_message_from_send_request(parsed_event)
113
+ log.info(f"{self.log_identifier} Message extracted: {message is not None}")
114
+
115
+ if message:
116
+ log.info(f"{self.log_identifier} Message metadata: {message.metadata}")
117
+
118
+ if message.metadata:
119
+ parent_task_id = message.metadata.get("parentTaskId")
120
+ background_execution_enabled = message.metadata.get("backgroundExecutionEnabled", False)
121
+ # Default to 1 hour (3600000ms) if background execution is enabled but no timeout specified
122
+ max_execution_time_ms = message.metadata.get("maxExecutionTimeMs")
123
+ if background_execution_enabled and max_execution_time_ms is None:
124
+ max_execution_time_ms = 3600000 # 1 hour default
125
+ else:
126
+ log.warning(
127
+ f"{self.log_identifier} Message has no metadata for task {task_id}"
128
+ )
129
+ else:
130
+ log.warning(
131
+ f"{self.log_identifier} Could not extract message from request for task {task_id}"
132
+ )
133
+
100
134
  if direction == "request":
101
135
  initial_text = self._extract_initial_text(parsed_event)
136
+ current_time = now_epoch_ms()
102
137
  new_task = Task(
103
138
  id=task_id,
104
139
  user_id=user_id or "unknown",
105
- start_time=now_epoch_ms(),
140
+ parent_task_id=parent_task_id,
141
+ start_time=current_time,
106
142
  initial_request_text=(
107
143
  initial_text[:1024] if initial_text else None
108
144
  ), # Truncate
145
+ execution_mode="background" if background_execution_enabled else "foreground",
146
+ last_activity_time=current_time,
147
+ background_execution_enabled=background_execution_enabled,
148
+ max_execution_time_ms=max_execution_time_ms,
109
149
  )
110
150
  repo.save_task(db, new_task)
111
151
  log.info(
112
152
  f"{self.log_identifier} Created new task record for ID: {task_id}"
153
+ + (f" with parent: {parent_task_id}" if parent_task_id else "")
154
+ + (f" (background execution enabled)" if background_execution_enabled else "")
113
155
  )
114
156
  else:
115
157
  # We received an event for a task we haven't seen the start of.
116
158
  # This can happen if the logger starts mid-conversation. Create a placeholder.
159
+ current_time = now_epoch_ms()
117
160
  placeholder_task = Task(
118
161
  id=task_id,
119
162
  user_id=user_id or "unknown",
120
- start_time=now_epoch_ms(),
163
+ parent_task_id=parent_task_id,
164
+ start_time=current_time,
121
165
  initial_request_text="[Task started before logger was active]",
166
+ execution_mode="foreground",
167
+ last_activity_time=current_time,
168
+ background_execution_enabled=False,
122
169
  )
123
170
  repo.save_task(db, placeholder_task)
124
171
  log.info(
125
172
  f"{self.log_identifier} Created placeholder task record for ID: {task_id}"
126
173
  )
174
+ else:
175
+ # Update last activity time for existing task
176
+ task.last_activity_time = now_epoch_ms()
177
+ repo.save_task(db, task)
127
178
 
128
179
  # Create and save the event using the sanitized raw payload
129
180
  task_event = TaskEvent(
@@ -142,8 +193,10 @@ class TaskLoggerService:
142
193
  if final_status:
143
194
  task_to_update = repo.find_by_id(db, task_id)
144
195
  if task_to_update:
145
- task_to_update.end_time = now_epoch_ms()
196
+ current_time = now_epoch_ms()
197
+ task_to_update.end_time = current_time
146
198
  task_to_update.status = final_status
199
+ task_to_update.last_activity_time = current_time
147
200
 
148
201
  # Extract and store token usage if present
149
202
  if isinstance(parsed_event, A2ATask) and parsed_event.metadata:
@@ -164,6 +217,21 @@ class TaskLoggerService:
164
217
  log.info(
165
218
  f"{self.log_identifier} Finalized task record for ID: {task_id} with status: {final_status}"
166
219
  )
220
+
221
+ # For background tasks, save chat messages when task completes
222
+ # Only save for top-level tasks (no parent_task_id) to avoid duplicates
223
+ # Sub-tasks (delegated by orchestrator) have parent_task_id set and contain system prompts
224
+ if task_to_update.background_execution_enabled and not task_to_update.parent_task_id:
225
+ self._save_chat_messages_for_background_task(db, task_id, task_to_update, repo)
226
+
227
+ # Note: The frontend will detect task completion through:
228
+ # 1. SSE final_response event (if connected to that task)
229
+ # 2. Session list refresh triggered by the ChatProvider
230
+ # 3. Database status check when loading sessions
231
+ log.info(
232
+ f"{self.log_identifier} Background task {task_id} completed and chat messages saved"
233
+ )
234
+
167
235
  db.commit()
168
236
  except Exception as e:
169
237
  log.exception(
@@ -188,6 +256,9 @@ class TaskLoggerService:
188
256
  # Ignore discovery messages
189
257
  if "/discovery/agentcards" in topic:
190
258
  return None
259
+ # Ignore trust manager trust card messages
260
+ if "/trust/" in topic:
261
+ return None
191
262
 
192
263
  try:
193
264
  # Check if it's a response (has 'result' or 'error')
@@ -316,3 +387,282 @@ class TaskLoggerService:
316
387
 
317
388
  walk_and_sanitize(new_payload)
318
389
  return new_payload
390
+
391
+ def _save_chat_messages_for_background_task(
392
+ self, db: DBSession, task_id: str, task: Task, repo: TaskRepository
393
+ ) -> None:
394
+ """
395
+ Save chat messages for a completed background task by reconstructing them from task events.
396
+ This ensures chat history is available when users return to a session after a background task completes.
397
+ Uses upsert to avoid duplicates.
398
+ """
399
+ try:
400
+ # Get all events for this task
401
+ task_with_events = repo.find_by_id_with_events(db, task_id)
402
+ if not task_with_events:
403
+ log.warning(
404
+ f"{self.log_identifier} Could not find task {task_id} with events for chat message saving"
405
+ )
406
+ return
407
+
408
+ _, events = task_with_events
409
+
410
+ # Extract session_id and user_id from the task's initial request
411
+ session_id = None
412
+ user_id = task.user_id
413
+ agent_name = None
414
+ user_message_text = task.initial_request_text
415
+
416
+ # Parse events to extract session context and reconstruct messages
417
+ message_bubbles = []
418
+ artifacts = [] # Track artifacts - only from final task response to avoid duplicates
419
+ rag_data = [] # Track RAG metadata from tool results
420
+
421
+ for event in events:
422
+ try:
423
+ payload = event.payload
424
+
425
+ # Extract session_id from the first request event
426
+ if event.direction == "request" and not session_id:
427
+ if "params" in payload and isinstance(payload["params"], dict):
428
+ message = payload["params"].get("message", {})
429
+ if isinstance(message, dict):
430
+ session_id = message.get("contextId")
431
+ # Extract agent name from metadata
432
+ metadata = message.get("metadata", {})
433
+ if isinstance(metadata, dict):
434
+ agent_name = metadata.get("agent_name")
435
+
436
+ # Add user message bubble
437
+ parts = message.get("parts", [])
438
+
439
+ # Filter out the gateway timestamp part (first part if it starts with "Request received by gateway")
440
+ filtered_parts = []
441
+ for i, part in enumerate(parts):
442
+ if part.get("kind") == "text":
443
+ text = part.get("text", "")
444
+ # Skip the first part if it's the gateway timestamp
445
+ if i == 0 and text.startswith("Request received by gateway at:"):
446
+ continue
447
+ filtered_parts.append(part)
448
+ else:
449
+ filtered_parts.append(part)
450
+
451
+ text_parts = [p.get("text", "") for p in filtered_parts if p.get("kind") == "text"]
452
+ combined_text = "".join(text_parts)
453
+
454
+ if combined_text or any(p.get("kind") == "file" for p in filtered_parts):
455
+ message_bubbles.append({
456
+ "id": f"msg-{uuid.uuid4()}",
457
+ "type": "user",
458
+ "text": combined_text,
459
+ "parts": filtered_parts,
460
+ })
461
+
462
+ # Collect RAG metadata from status events (but NOT artifacts to avoid duplicates)
463
+ elif event.direction == "status":
464
+ if "result" in payload:
465
+ result = payload["result"]
466
+ # Only extract RAG metadata, skip artifact collection from status events
467
+ # Artifacts will be collected from the final task response only
468
+
469
+ # Extract RAG metadata from tool_result data parts
470
+ status = result.get("status", {})
471
+ if isinstance(status, dict):
472
+ message = status.get("message", {})
473
+ if isinstance(message, dict):
474
+ parts = message.get("parts", [])
475
+ for part in parts:
476
+ if isinstance(part, dict) and part.get("kind") == "data":
477
+ data = part.get("data", {})
478
+ if isinstance(data, dict) and data.get("type") == "tool_result":
479
+ result_data = data.get("result_data", {})
480
+ if isinstance(result_data, dict) and "rag_metadata" in result_data:
481
+ rag_metadata = result_data["rag_metadata"]
482
+ if isinstance(rag_metadata, dict):
483
+ # Add taskId to the RAG metadata
484
+ rag_metadata["taskId"] = task_id
485
+ rag_data.append(rag_metadata)
486
+ log.info(
487
+ f"{self.log_identifier} Extracted RAG metadata for task {task_id}: "
488
+ f"searchType={rag_metadata.get('searchType')}, "
489
+ f"sources_count={len(rag_metadata.get('sources', []))}"
490
+ )
491
+
492
+ # Extract agent response messages - only from final task response
493
+ elif event.direction == "response":
494
+ if "result" in payload:
495
+ result = payload["result"]
496
+
497
+ # Only process final task response (kind="task")
498
+ if isinstance(result, dict) and result.get("kind") == "task":
499
+ # Extract artifacts from task metadata
500
+ metadata = result.get("metadata", {})
501
+ if isinstance(metadata, dict):
502
+ # Try both 'produced_artifacts' and 'artifact_manifest'
503
+ artifact_list = metadata.get("produced_artifacts") or metadata.get("artifact_manifest", [])
504
+ if isinstance(artifact_list, list):
505
+ for artifact_info in artifact_list:
506
+ if isinstance(artifact_info, dict):
507
+ # Handle both 'name' and 'filename' keys
508
+ artifact_name = artifact_info.get("name") or artifact_info.get("filename")
509
+ # Skip web_content_ artifacts (temporary files from deep research)
510
+ if artifact_name and not artifact_name.startswith("web_content_"):
511
+ artifacts.append({
512
+ "kind": "artifact",
513
+ "status": "completed",
514
+ "name": artifact_name,
515
+ "file": {
516
+ "name": artifact_name,
517
+ "mime_type": artifact_info.get("mime_type"),
518
+ "uri": f"artifact://{session_id}/{artifact_name}" if session_id else f"artifact://unknown/{artifact_name}"
519
+ }
520
+ })
521
+
522
+ # Final task object - extract the complete message
523
+ status = result.get("status", {})
524
+ if isinstance(status, dict):
525
+ message = status.get("message", {})
526
+ if isinstance(message, dict):
527
+ parts = message.get("parts", [])
528
+
529
+ # Extract RAG metadata from tool_result data parts in final response
530
+ for part in parts:
531
+ if isinstance(part, dict) and part.get("kind") == "data":
532
+ data = part.get("data", {})
533
+ if isinstance(data, dict) and data.get("type") == "tool_result":
534
+ result_data = data.get("result_data", {})
535
+ if isinstance(result_data, dict) and "rag_metadata" in result_data:
536
+ rag_metadata = result_data["rag_metadata"]
537
+ if isinstance(rag_metadata, dict):
538
+ # Add taskId to the RAG metadata
539
+ rag_metadata["taskId"] = task_id
540
+ # Avoid duplicates
541
+ if rag_metadata not in rag_data:
542
+ rag_data.append(rag_metadata)
543
+ log.info(
544
+ f"{self.log_identifier} Extracted RAG metadata from final response for task {task_id}: "
545
+ f"searchType={rag_metadata.get('searchType')}, "
546
+ f"sources_count={len(rag_metadata.get('sources', []))}"
547
+ )
548
+
549
+ # Filter out data parts (status updates, tool invocations, etc.)
550
+ content_parts = [p for p in parts if p.get("kind") != "data"]
551
+
552
+ if content_parts or artifacts:
553
+ text_parts = [p.get("text", "") for p in content_parts if p.get("kind") == "text"]
554
+ combined_text = "".join(text_parts).strip()
555
+
556
+ # Check if artifact markers are already in the text
557
+ # (they might be included in the final response text parts)
558
+ import re
559
+ existing_markers = set()
560
+ marker_pattern = r'«artifact_return:([^»]+)»'
561
+ for match in re.finditer(marker_pattern, combined_text):
562
+ # Normalize the artifact name (strip version suffix)
563
+ artifact_ref = match.group(1)
564
+ if ':' in artifact_ref:
565
+ base_name = artifact_ref.rsplit(':', 1)[0]
566
+ try:
567
+ int(artifact_ref.rsplit(':', 1)[1])
568
+ # Add the base name (without version) to existing markers
569
+ # so we don't add a duplicate marker later
570
+ existing_markers.add(base_name)
571
+ except ValueError:
572
+ # Not a version number, treat the whole thing as the artifact name
573
+ existing_markers.add(artifact_ref)
574
+ else:
575
+ existing_markers.add(artifact_ref)
576
+
577
+ # Only add artifact markers if they're not already present
578
+ for artifact in artifacts:
579
+ artifact_name = artifact['name']
580
+ if artifact_name not in existing_markers:
581
+ combined_text += f"«artifact_return:{artifact_name}»"
582
+ log.info(
583
+ f"{self.log_identifier} Adding artifact marker for {artifact_name}"
584
+ )
585
+ else:
586
+ log.info(
587
+ f"{self.log_identifier} Skipping duplicate artifact marker for {artifact_name} (already in text)"
588
+ )
589
+
590
+ message_bubbles.append({
591
+ "id": f"msg-{uuid.uuid4()}",
592
+ "type": "agent",
593
+ "text": combined_text,
594
+ "parts": content_parts, # Only content parts, no artifacts
595
+ })
596
+
597
+ except Exception as e:
598
+ log.warning(
599
+ f"{self.log_identifier} Error parsing event for chat message reconstruction: {e}"
600
+ )
601
+ continue
602
+
603
+ # Only save if we have a session_id and at least one message
604
+ if not session_id:
605
+ log.warning(
606
+ f"{self.log_identifier} Could not extract session_id for task {task_id}, skipping chat message save"
607
+ )
608
+ return
609
+
610
+ if not message_bubbles:
611
+ log.warning(
612
+ f"{self.log_identifier} No message bubbles reconstructed for task {task_id}, skipping chat message save"
613
+ )
614
+ return
615
+
616
+ # Import here to avoid circular dependency
617
+ from ..repository.chat_task_repository import ChatTaskRepository
618
+ from ..repository.entities import ChatTask
619
+ from ..repository.session_repository import SessionRepository
620
+
621
+ # Check if the session exists in this database
622
+ session_repo = SessionRepository()
623
+ if not session_repo.exists(db, session_id):
624
+ log.debug(
625
+ f"{self.log_identifier} Session {session_id} not found in webui_gateway database "
626
+ f"Skipping chat message save for task {task_id}"
627
+ )
628
+ return
629
+
630
+ # Build task metadata including RAG data if present
631
+ task_metadata_dict = {
632
+ "schema_version": 1,
633
+ "status": task.status,
634
+ "agent_name": agent_name,
635
+ }
636
+
637
+ # Include RAG data if we found any
638
+ if rag_data:
639
+ task_metadata_dict["rag_data"] = rag_data
640
+ log.info(
641
+ f"{self.log_identifier} Including {len(rag_data)} RAG data entries in task metadata for {task_id}"
642
+ )
643
+
644
+ # Create and save the chat task
645
+ chat_task = ChatTask(
646
+ id=task_id,
647
+ session_id=session_id,
648
+ user_id=user_id,
649
+ user_message=user_message_text,
650
+ message_bubbles=json.dumps(message_bubbles),
651
+ task_metadata=json.dumps(task_metadata_dict),
652
+ created_time=task.start_time,
653
+ updated_time=task.end_time,
654
+ )
655
+
656
+ chat_task_repo = ChatTaskRepository()
657
+ chat_task_repo.save(db, chat_task)
658
+
659
+ log.info(
660
+ f"{self.log_identifier} Saved chat messages for background task {task_id} "
661
+ f"(session: {session_id}, {len(message_bubbles)} message bubbles)"
662
+ )
663
+
664
+ except Exception as e:
665
+ log.error(
666
+ f"{self.log_identifier} Failed to save chat messages for background task {task_id}: {e}",
667
+ exc_info=True
668
+ )
@@ -35,10 +35,10 @@ class SessionManager:
35
35
  self.force_user_identity = app_config.get("force_user_identity")
36
36
  self.use_authorization = app_config.get("frontend_use_authorization", False)
37
37
  self._temp_code_cache = {}
38
- log.info("[SessionManager] Initialized.")
38
+ log.info("Initialized SessionManager")
39
39
  if self.force_user_identity:
40
40
  log.warning(
41
- f"[SessionManager] Forcing user identity to: {self.force_user_identity}"
41
+ f"Forcing user identity to: {self.force_user_identity}"
42
42
  )
43
43
 
44
44
  def _get_or_create_client_id(self, request: Request) -> str | None:
@@ -54,19 +54,19 @@ class SessionManager:
54
54
  user_id = request.state.user.get("id")
55
55
  if user_id:
56
56
  log.debug(
57
- "[SessionManager] Using authenticated user ID from request.state: %s",
57
+ "Using authenticated user ID from request.state: %s",
58
58
  user_id,
59
59
  )
60
60
  return user_id
61
61
  else:
62
62
  log.warning(
63
- "[SessionManager] request.state.user exists but has no 'id' field. Falling back to other methods."
63
+ "request.state.user exists but has no 'id' field. Falling back to other methods."
64
64
  )
65
65
 
66
66
  user_id = self.get_user_id(request)
67
67
  if user_id:
68
68
  log.debug(
69
- "[SessionManager] Using authenticated user_id from session as A2A Client ID: %s",
69
+ "Using authenticated user_id from session as A2A Client ID: %s",
70
70
  user_id,
71
71
  )
72
72
  return user_id
@@ -74,7 +74,7 @@ class SessionManager:
74
74
  client_id = request.session.get(SESSION_KEY_CLIENT_ID)
75
75
  if client_id:
76
76
  log.debug(
77
- "[SessionManager] Using existing A2A Client ID: %s for web session.",
77
+ "Using existing A2A Client ID: %s for web session.",
78
78
  client_id,
79
79
  )
80
80
  return client_id
@@ -82,14 +82,14 @@ class SessionManager:
82
82
  if not self.use_authorization:
83
83
  client_id = "sam_dev_user"
84
84
  log.info(
85
- "[SessionManager] No authenticated user and auth is disabled, using client ID: %s for web session.",
85
+ "No authenticated user and auth is disabled, using client ID: %s for web session.",
86
86
  client_id,
87
87
  )
88
88
  request.session[SESSION_KEY_CLIENT_ID] = client_id
89
89
  return client_id
90
90
 
91
91
  log.warning(
92
- "[SessionManager] Could not determine client ID and authorization is enabled."
92
+ "Could not determine client ID and authorization is enabled."
93
93
  )
94
94
  return None
95
95
 
@@ -106,7 +106,7 @@ class SessionManager:
106
106
  Returns None if no session has been started for the current agent in this web session.
107
107
  """
108
108
  session_id = request.session.get(SESSION_KEY_SESSION_ID)
109
- log.debug("[SessionManager] Retrieving A2A Session ID: %s", session_id)
109
+ log.debug("Retrieving A2A Session ID: %s", session_id)
110
110
  return session_id
111
111
 
112
112
  def start_new_a2a_session(self, request: Request) -> str:
@@ -123,7 +123,7 @@ class SessionManager:
123
123
  new_session_id = f"web-session-{uuid.uuid4().hex}"
124
124
  request.session[SESSION_KEY_SESSION_ID] = new_session_id
125
125
  log.info(
126
- "[SessionManager] Started new A2A Session ID: %s for Client ID: %s",
126
+ "Started new A2A Session ID: %s for Client ID: %s",
127
127
  new_session_id,
128
128
  client_id,
129
129
  )
@@ -142,7 +142,7 @@ class SessionManager:
142
142
  )
143
143
  new_session_id = f"web-session-{uuid.uuid4().hex}"
144
144
  log.info(
145
- "[SessionManager] Generated new A2A Session ID: %s for Client ID: %s (not stored in cookies)",
145
+ "Generated new A2A Session ID: %s for Client ID: %s (not stored in cookies)",
146
146
  new_session_id,
147
147
  client_id,
148
148
  )
@@ -157,7 +157,7 @@ class SessionManager:
157
157
  if not session_id:
158
158
  session_id = self.start_new_a2a_session(request)
159
159
  log.info(
160
- "[SessionManager] No A2A Session ID found, created new one via ensure_a2a_session: %s",
160
+ "No A2A Session ID found, created new one via ensure_a2a_session: %s",
161
161
  session_id,
162
162
  )
163
163
  return session_id
@@ -171,7 +171,7 @@ class SessionManager:
171
171
  request.session[SESSION_KEY_ACCESS_TOKEN] = access_token
172
172
  if refresh_token:
173
173
  request.session[SESSION_KEY_REFRESH_TOKEN] = refresh_token
174
- log.info("[SessionManager] Stored auth tokens directly in session.")
174
+ log.info("Stored auth tokens directly in session.")
175
175
 
176
176
  def get_access_token(self, request: Request) -> str | None:
177
177
  """
@@ -191,14 +191,14 @@ class SessionManager:
191
191
  """
192
192
  request.session.pop(SESSION_KEY_ACCESS_TOKEN, None)
193
193
  request.session.pop(SESSION_KEY_REFRESH_TOKEN, None)
194
- log.info("[SessionManager] Cleared auth tokens from session")
194
+ log.info("Cleared auth tokens from session")
195
195
 
196
196
  def store_user_id(self, request: Request, user_id: str) -> None:
197
197
  """
198
198
  Stores the user ID in the web session.
199
199
  """
200
200
  request.session[SESSION_KEY_USER_ID] = user_id
201
- log.info("[SessionManager] Stored user ID in session: %s", user_id)
201
+ log.info("Stored user ID in session: %s", user_id)
202
202
 
203
203
  def get_user_id(self, request: Request) -> str | None:
204
204
  """