solace-agent-mesh 1.11.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.
Files changed (624) hide show
  1. solace_agent_mesh/__init__.py +0 -0
  2. solace_agent_mesh/agent/__init__.py +0 -0
  3. solace_agent_mesh/agent/adk/__init__.py +0 -0
  4. solace_agent_mesh/agent/adk/adk_llm.txt +226 -0
  5. solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
  6. solace_agent_mesh/agent/adk/alembic/README +74 -0
  7. solace_agent_mesh/agent/adk/alembic/env.py +77 -0
  8. solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
  9. solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
  10. solace_agent_mesh/agent/adk/alembic.ini +112 -0
  11. solace_agent_mesh/agent/adk/app_llm_agent.py +52 -0
  12. solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
  13. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  14. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +545 -0
  15. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +609 -0
  16. solace_agent_mesh/agent/adk/callbacks.py +2318 -0
  17. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +406 -0
  18. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +415 -0
  19. solace_agent_mesh/agent/adk/mcp_content_processor.py +666 -0
  20. solace_agent_mesh/agent/adk/models/lite_llm.py +1026 -0
  21. solace_agent_mesh/agent/adk/models/models_llm.txt +189 -0
  22. solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +132 -0
  23. solace_agent_mesh/agent/adk/runner.py +390 -0
  24. solace_agent_mesh/agent/adk/schema_migration.py +88 -0
  25. solace_agent_mesh/agent/adk/services.py +468 -0
  26. solace_agent_mesh/agent/adk/setup.py +1325 -0
  27. solace_agent_mesh/agent/adk/stream_parser.py +415 -0
  28. solace_agent_mesh/agent/adk/tool_wrapper.py +165 -0
  29. solace_agent_mesh/agent/agent_llm.txt +369 -0
  30. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  31. solace_agent_mesh/agent/protocol/__init__.py +0 -0
  32. solace_agent_mesh/agent/protocol/event_handlers.py +2041 -0
  33. solace_agent_mesh/agent/protocol/protocol_llm.txt +81 -0
  34. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  35. solace_agent_mesh/agent/proxies/__init__.py +0 -0
  36. solace_agent_mesh/agent/proxies/a2a/__init__.py +3 -0
  37. solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
  38. solace_agent_mesh/agent/proxies/a2a/app.py +56 -0
  39. solace_agent_mesh/agent/proxies/a2a/component.py +1585 -0
  40. solace_agent_mesh/agent/proxies/a2a/config.py +216 -0
  41. solace_agent_mesh/agent/proxies/a2a/oauth_token_cache.py +104 -0
  42. solace_agent_mesh/agent/proxies/base/__init__.py +3 -0
  43. solace_agent_mesh/agent/proxies/base/app.py +100 -0
  44. solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
  45. solace_agent_mesh/agent/proxies/base/component.py +816 -0
  46. solace_agent_mesh/agent/proxies/base/config.py +85 -0
  47. solace_agent_mesh/agent/proxies/base/proxy_task_context.py +19 -0
  48. solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
  49. solace_agent_mesh/agent/sac/__init__.py +0 -0
  50. solace_agent_mesh/agent/sac/app.py +595 -0
  51. solace_agent_mesh/agent/sac/component.py +3668 -0
  52. solace_agent_mesh/agent/sac/patch_adk.py +103 -0
  53. solace_agent_mesh/agent/sac/sac_llm.txt +189 -0
  54. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  55. solace_agent_mesh/agent/sac/task_execution_context.py +415 -0
  56. solace_agent_mesh/agent/testing/__init__.py +3 -0
  57. solace_agent_mesh/agent/testing/debug_utils.py +135 -0
  58. solace_agent_mesh/agent/testing/testing_llm.txt +58 -0
  59. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  60. solace_agent_mesh/agent/tools/__init__.py +16 -0
  61. solace_agent_mesh/agent/tools/audio_tools.py +1740 -0
  62. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +2500 -0
  63. solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +244 -0
  64. solace_agent_mesh/agent/tools/dynamic_tool.py +396 -0
  65. solace_agent_mesh/agent/tools/general_agent_tools.py +572 -0
  66. solace_agent_mesh/agent/tools/image_tools.py +1185 -0
  67. solace_agent_mesh/agent/tools/peer_agent_tool.py +363 -0
  68. solace_agent_mesh/agent/tools/registry.py +38 -0
  69. solace_agent_mesh/agent/tools/test_tools.py +136 -0
  70. solace_agent_mesh/agent/tools/time_tools.py +126 -0
  71. solace_agent_mesh/agent/tools/tool_config_types.py +93 -0
  72. solace_agent_mesh/agent/tools/tool_definition.py +53 -0
  73. solace_agent_mesh/agent/tools/tools_llm.txt +276 -0
  74. solace_agent_mesh/agent/tools/tools_llm_detail.txt +275 -0
  75. solace_agent_mesh/agent/tools/web_tools.py +392 -0
  76. solace_agent_mesh/agent/utils/__init__.py +0 -0
  77. solace_agent_mesh/agent/utils/artifact_helpers.py +1353 -0
  78. solace_agent_mesh/agent/utils/config_parser.py +49 -0
  79. solace_agent_mesh/agent/utils/context_helpers.py +77 -0
  80. solace_agent_mesh/agent/utils/utils_llm.txt +152 -0
  81. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  82. solace_agent_mesh/assets/docs/404.html +16 -0
  83. solace_agent_mesh/assets/docs/assets/css/styles.8162edfb.css +1 -0
  84. solace_agent_mesh/assets/docs/assets/images/Solace_AI_Framework_With_Broker-85f0a306a9bcdd20b390b7a949f6d862.png +0 -0
  85. solace_agent_mesh/assets/docs/assets/images/sam-enterprise-credentials-b269f095349473118b2b33bdfcc40122.png +0 -0
  86. solace_agent_mesh/assets/docs/assets/js/032c2d61.f3d37824.js +1 -0
  87. solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
  88. solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
  89. solace_agent_mesh/assets/docs/assets/js/1001.0182a8bd.js +1 -0
  90. solace_agent_mesh/assets/docs/assets/js/1039.0bd46aa1.js +1 -0
  91. solace_agent_mesh/assets/docs/assets/js/149.b797a808.js +1 -0
  92. solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
  93. solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
  94. solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js +2 -0
  95. solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js.LICENSE.txt +9 -0
  96. solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
  97. solace_agent_mesh/assets/docs/assets/js/2130.ab9fd314.js +1 -0
  98. solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
  99. solace_agent_mesh/assets/docs/assets/js/2237.5e477fc6.js +1 -0
  100. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
  101. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js.LICENSE.txt +13 -0
  102. solace_agent_mesh/assets/docs/assets/js/2334.1cf50a20.js +1 -0
  103. solace_agent_mesh/assets/docs/assets/js/240a0364.9ad94d1b.js +1 -0
  104. solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
  105. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
  106. solace_agent_mesh/assets/docs/assets/js/3219.adc1d663.js +1 -0
  107. solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
  108. solace_agent_mesh/assets/docs/assets/js/3624.0eaa1fd0.js +1 -0
  109. solace_agent_mesh/assets/docs/assets/js/375.708d48db.js +1 -0
  110. solace_agent_mesh/assets/docs/assets/js/3834.b6cd790e.js +1 -0
  111. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
  112. solace_agent_mesh/assets/docs/assets/js/3ac1795d.28b7c67b.js +1 -0
  113. solace_agent_mesh/assets/docs/assets/js/3ff0015d.2ddc75c0.js +1 -0
  114. solace_agent_mesh/assets/docs/assets/js/41adc471.48b12a4e.js +1 -0
  115. solace_agent_mesh/assets/docs/assets/js/4250.95455b28.js +1 -0
  116. solace_agent_mesh/assets/docs/assets/js/4356.d169ab5b.js +1 -0
  117. solace_agent_mesh/assets/docs/assets/js/4458.518e66fa.js +1 -0
  118. solace_agent_mesh/assets/docs/assets/js/4488.c7cc3442.js +1 -0
  119. solace_agent_mesh/assets/docs/assets/js/4494.6ee23046.js +1 -0
  120. solace_agent_mesh/assets/docs/assets/js/4855.fc4444b6.js +1 -0
  121. solace_agent_mesh/assets/docs/assets/js/4866.22daefc0.js +1 -0
  122. solace_agent_mesh/assets/docs/assets/js/4950.ca4caeda.js +1 -0
  123. solace_agent_mesh/assets/docs/assets/js/509e993c.a1fbf45a.js +1 -0
  124. solace_agent_mesh/assets/docs/assets/js/5388.7a136447.js +1 -0
  125. solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
  126. solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
  127. solace_agent_mesh/assets/docs/assets/js/5607.081356f8.js +1 -0
  128. solace_agent_mesh/assets/docs/assets/js/5864.b0d0e9de.js +1 -0
  129. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.90a87880.js +1 -0
  130. solace_agent_mesh/assets/docs/assets/js/5e95c892.558d5167.js +1 -0
  131. solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
  132. solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
  133. solace_agent_mesh/assets/docs/assets/js/6143.0a1464c9.js +1 -0
  134. solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
  135. solace_agent_mesh/assets/docs/assets/js/6395.e9c73649.js +1 -0
  136. solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
  137. solace_agent_mesh/assets/docs/assets/js/66d4869e.b77431fc.js +1 -0
  138. solace_agent_mesh/assets/docs/assets/js/6796.51d2c9b7.js +1 -0
  139. solace_agent_mesh/assets/docs/assets/js/6976.379be23b.js +1 -0
  140. solace_agent_mesh/assets/docs/assets/js/6978.ee0b945c.js +1 -0
  141. solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
  142. solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
  143. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
  144. solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
  145. solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.js +1 -0
  146. solace_agent_mesh/assets/docs/assets/js/7040.cb436723.js +1 -0
  147. solace_agent_mesh/assets/docs/assets/js/7195.412f418a.js +1 -0
  148. solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
  149. solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
  150. solace_agent_mesh/assets/docs/assets/js/7280.3fb73bdb.js +1 -0
  151. solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
  152. solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.js +1 -0
  153. solace_agent_mesh/assets/docs/assets/js/7845.e33e7c4c.js +1 -0
  154. solace_agent_mesh/assets/docs/assets/js/7900.69516146.js +1 -0
  155. solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
  156. solace_agent_mesh/assets/docs/assets/js/81a99df0.2484b8d9.js +1 -0
  157. solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
  158. solace_agent_mesh/assets/docs/assets/js/8356.8a379c04.js +1 -0
  159. solace_agent_mesh/assets/docs/assets/js/8567.4732c6b7.js +1 -0
  160. solace_agent_mesh/assets/docs/assets/js/8573.cb04eda5.js +1 -0
  161. solace_agent_mesh/assets/docs/assets/js/8577.1d54e766.js +1 -0
  162. solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js +2 -0
  163. solace_agent_mesh/assets/docs/assets/js/8591.5d015485.js.LICENSE.txt +61 -0
  164. solace_agent_mesh/assets/docs/assets/js/8709.7ecd4047.js +1 -0
  165. solace_agent_mesh/assets/docs/assets/js/8731.6c1dbf0c.js +1 -0
  166. solace_agent_mesh/assets/docs/assets/js/8908.f9d1b506.js +1 -0
  167. solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
  168. solace_agent_mesh/assets/docs/assets/js/9157.b4093d07.js +1 -0
  169. solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
  170. solace_agent_mesh/assets/docs/assets/js/9278.a4fd875d.js +1 -0
  171. solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
  172. solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
  173. solace_agent_mesh/assets/docs/assets/js/9616.b75c2f6d.js +1 -0
  174. solace_agent_mesh/assets/docs/assets/js/9793.c6d16376.js +1 -0
  175. solace_agent_mesh/assets/docs/assets/js/9bb13469.b2333011.js +1 -0
  176. solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
  177. solace_agent_mesh/assets/docs/assets/js/a7bd4aaa.2204d2f7.js +1 -0
  178. solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
  179. solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +1 -0
  180. solace_agent_mesh/assets/docs/assets/js/aba21aa0.c42a534c.js +1 -0
  181. solace_agent_mesh/assets/docs/assets/js/ad71b5ed.af3ecfd1.js +1 -0
  182. solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
  183. solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
  184. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
  185. solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
  186. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
  187. solace_agent_mesh/assets/docs/assets/js/ceb2a7a6.5d92d7d0.js +1 -0
  188. solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
  189. solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
  190. solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.js +1 -0
  191. solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
  192. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
  193. solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
  194. solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
  195. solace_agent_mesh/assets/docs/assets/js/e04b235d.52cb25ed.js +1 -0
  196. solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.b1068f9b.js +1 -0
  197. solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
  198. solace_agent_mesh/assets/docs/assets/js/e6f9706b.4488e34c.js +1 -0
  199. solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
  200. solace_agent_mesh/assets/docs/assets/js/f284c35a.250993bf.js +1 -0
  201. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
  202. solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js +2 -0
  203. solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js.LICENSE.txt +81 -0
  204. solace_agent_mesh/assets/docs/assets/js/runtime~main.9e0813a2.js +1 -0
  205. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +154 -0
  206. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +99 -0
  207. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +90 -0
  208. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +107 -0
  209. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +166 -0
  210. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +101 -0
  211. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +219 -0
  212. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +92 -0
  213. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
  214. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
  215. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
  216. solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
  217. solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
  218. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +345 -0
  219. solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
  220. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +83 -0
  221. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +84 -0
  222. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
  223. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
  224. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +85 -0
  225. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +60 -0
  226. solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
  227. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +144 -0
  228. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +191 -0
  229. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +128 -0
  230. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
  231. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
  232. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +34 -0
  233. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
  234. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +267 -0
  235. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +142 -0
  236. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +116 -0
  237. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +86 -0
  238. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +164 -0
  239. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +140 -0
  240. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +57 -0
  241. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
  242. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +102 -0
  243. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
  244. solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
  245. solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
  246. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +37 -0
  247. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +86 -0
  248. solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
  249. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +247 -0
  250. solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
  251. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +184 -0
  252. solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
  253. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
  254. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +54 -0
  255. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +85 -0
  256. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
  257. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
  258. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +78 -0
  259. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
  260. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +78 -0
  261. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +160 -0
  262. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
  263. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
  264. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
  265. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
  266. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +52 -0
  267. solace_agent_mesh/assets/docs/img/Solace_AI_Framework_With_Broker.png +0 -0
  268. solace_agent_mesh/assets/docs/img/logo.png +0 -0
  269. solace_agent_mesh/assets/docs/img/sac-flows.png +0 -0
  270. solace_agent_mesh/assets/docs/img/sac_parts_of_a_component.png +0 -0
  271. solace_agent_mesh/assets/docs/img/sam-enterprise-credentials.png +0 -0
  272. solace_agent_mesh/assets/docs/img/solace-logo-text.svg +18 -0
  273. solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
  274. solace_agent_mesh/assets/docs/lunr-index-1765810064709.json +1 -0
  275. solace_agent_mesh/assets/docs/lunr-index.json +1 -0
  276. solace_agent_mesh/assets/docs/search-doc-1765810064709.json +1 -0
  277. solace_agent_mesh/assets/docs/search-doc.json +1 -0
  278. solace_agent_mesh/assets/docs/sitemap.xml +1 -0
  279. solace_agent_mesh/cli/__init__.py +1 -0
  280. solace_agent_mesh/cli/commands/__init__.py +0 -0
  281. solace_agent_mesh/cli/commands/add_cmd/__init__.py +15 -0
  282. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +250 -0
  283. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +729 -0
  284. solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +322 -0
  285. solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +102 -0
  286. solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +114 -0
  287. solace_agent_mesh/cli/commands/docs_cmd.py +60 -0
  288. solace_agent_mesh/cli/commands/eval_cmd.py +46 -0
  289. solace_agent_mesh/cli/commands/init_cmd/__init__.py +439 -0
  290. solace_agent_mesh/cli/commands/init_cmd/broker_step.py +201 -0
  291. solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
  292. solace_agent_mesh/cli/commands/init_cmd/directory_step.py +28 -0
  293. solace_agent_mesh/cli/commands/init_cmd/env_step.py +238 -0
  294. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
  295. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +464 -0
  296. solace_agent_mesh/cli/commands/init_cmd/project_files_step.py +38 -0
  297. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +119 -0
  298. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +215 -0
  299. solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +20 -0
  300. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +137 -0
  301. solace_agent_mesh/cli/commands/plugin_cmd/build_cmd.py +86 -0
  302. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +144 -0
  303. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +306 -0
  304. solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +283 -0
  305. solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +175 -0
  306. solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +305 -0
  307. solace_agent_mesh/cli/commands/run_cmd.py +215 -0
  308. solace_agent_mesh/cli/main.py +52 -0
  309. solace_agent_mesh/cli/utils.py +262 -0
  310. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-Dj3JtK42.js +1 -0
  311. solace_agent_mesh/client/webui/frontend/static/assets/client-ZKk9kEJ5.js +25 -0
  312. solace_agent_mesh/client/webui/frontend/static/assets/favicon-BLgzUch9.ico +0 -0
  313. solace_agent_mesh/client/webui/frontend/static/assets/main-BcUaNZ-Q.css +1 -0
  314. solace_agent_mesh/client/webui/frontend/static/assets/main-vjch4RYc.js +435 -0
  315. solace_agent_mesh/client/webui/frontend/static/assets/vendor-BNV4kZN0.js +535 -0
  316. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +15 -0
  317. solace_agent_mesh/client/webui/frontend/static/index.html +16 -0
  318. solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
  319. solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
  320. solace_agent_mesh/common/__init__.py +1 -0
  321. solace_agent_mesh/common/a2a/__init__.py +241 -0
  322. solace_agent_mesh/common/a2a/a2a_llm.txt +175 -0
  323. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  324. solace_agent_mesh/common/a2a/artifact.py +368 -0
  325. solace_agent_mesh/common/a2a/events.py +213 -0
  326. solace_agent_mesh/common/a2a/message.py +375 -0
  327. solace_agent_mesh/common/a2a/protocol.py +689 -0
  328. solace_agent_mesh/common/a2a/task.py +127 -0
  329. solace_agent_mesh/common/a2a/translation.py +655 -0
  330. solace_agent_mesh/common/a2a/types.py +55 -0
  331. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  332. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +445 -0
  333. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  334. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  335. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +48 -0
  336. solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
  337. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +41 -0
  338. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +330 -0
  339. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  340. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +48 -0
  341. solace_agent_mesh/common/agent_registry.py +122 -0
  342. solace_agent_mesh/common/common_llm.txt +230 -0
  343. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  344. solace_agent_mesh/common/constants.py +6 -0
  345. solace_agent_mesh/common/data_parts.py +150 -0
  346. solace_agent_mesh/common/exceptions.py +49 -0
  347. solace_agent_mesh/common/middleware/__init__.py +12 -0
  348. solace_agent_mesh/common/middleware/config_resolver.py +132 -0
  349. solace_agent_mesh/common/middleware/middleware_llm.txt +174 -0
  350. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  351. solace_agent_mesh/common/middleware/registry.py +127 -0
  352. solace_agent_mesh/common/oauth/__init__.py +17 -0
  353. solace_agent_mesh/common/oauth/oauth_client.py +408 -0
  354. solace_agent_mesh/common/oauth/utils.py +50 -0
  355. solace_agent_mesh/common/sac/__init__.py +0 -0
  356. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  357. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  358. solace_agent_mesh/common/sac/sam_component_base.py +730 -0
  359. solace_agent_mesh/common/sam_events/__init__.py +9 -0
  360. solace_agent_mesh/common/sam_events/event_service.py +208 -0
  361. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  362. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  363. solace_agent_mesh/common/services/__init__.py +4 -0
  364. solace_agent_mesh/common/services/employee_service.py +164 -0
  365. solace_agent_mesh/common/services/identity_service.py +134 -0
  366. solace_agent_mesh/common/services/providers/__init__.py +4 -0
  367. solace_agent_mesh/common/services/providers/local_file_identity_service.py +151 -0
  368. solace_agent_mesh/common/services/providers/providers_llm.txt +81 -0
  369. solace_agent_mesh/common/services/services_llm.txt +368 -0
  370. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  371. solace_agent_mesh/common/utils/__init__.py +7 -0
  372. solace_agent_mesh/common/utils/artifact_utils.py +31 -0
  373. solace_agent_mesh/common/utils/asyncio_macos_fix.py +88 -0
  374. solace_agent_mesh/common/utils/embeds/__init__.py +33 -0
  375. solace_agent_mesh/common/utils/embeds/constants.py +56 -0
  376. solace_agent_mesh/common/utils/embeds/converter.py +447 -0
  377. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +220 -0
  378. solace_agent_mesh/common/utils/embeds/evaluators.py +395 -0
  379. solace_agent_mesh/common/utils/embeds/modifiers.py +793 -0
  380. solace_agent_mesh/common/utils/embeds/resolver.py +967 -0
  381. solace_agent_mesh/common/utils/embeds/types.py +23 -0
  382. solace_agent_mesh/common/utils/in_memory_cache.py +108 -0
  383. solace_agent_mesh/common/utils/initializer.py +52 -0
  384. solace_agent_mesh/common/utils/log_formatters.py +64 -0
  385. solace_agent_mesh/common/utils/message_utils.py +80 -0
  386. solace_agent_mesh/common/utils/mime_helpers.py +172 -0
  387. solace_agent_mesh/common/utils/push_notification_auth.py +135 -0
  388. solace_agent_mesh/common/utils/pydantic_utils.py +159 -0
  389. solace_agent_mesh/common/utils/rbac_utils.py +69 -0
  390. solace_agent_mesh/common/utils/templates/__init__.py +8 -0
  391. solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
  392. solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
  393. solace_agent_mesh/common/utils/type_utils.py +28 -0
  394. solace_agent_mesh/common/utils/utils_llm.txt +335 -0
  395. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  396. solace_agent_mesh/config_portal/__init__.py +0 -0
  397. solace_agent_mesh/config_portal/backend/__init__.py +0 -0
  398. solace_agent_mesh/config_portal/backend/common.py +77 -0
  399. solace_agent_mesh/config_portal/backend/plugin_catalog/__init__.py +0 -0
  400. solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +24 -0
  401. solace_agent_mesh/config_portal/backend/plugin_catalog/models.py +49 -0
  402. solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +166 -0
  403. solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +521 -0
  404. solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +217 -0
  405. solace_agent_mesh/config_portal/backend/server.py +644 -0
  406. solace_agent_mesh/config_portal/frontend/static/client/Solace_community_logo.png +0 -0
  407. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DiOiAjzL.js +103 -0
  408. solace_agent_mesh/config_portal/frontend/static/client/assets/components-Rk0n-9cK.js +140 -0
  409. solace_agent_mesh/config_portal/frontend/static/client/assets/entry.client-mvZjNKiz.js +19 -0
  410. solace_agent_mesh/config_portal/frontend/static/client/assets/index-DzNKzXrc.js +68 -0
  411. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-ba77705e.js +1 -0
  412. solace_agent_mesh/config_portal/frontend/static/client/assets/root-B17tZKK7.css +1 -0
  413. solace_agent_mesh/config_portal/frontend/static/client/assets/root-V2BeTIUc.js +10 -0
  414. solace_agent_mesh/config_portal/frontend/static/client/favicon.ico +0 -0
  415. solace_agent_mesh/config_portal/frontend/static/client/index.html +7 -0
  416. solace_agent_mesh/core_a2a/__init__.py +1 -0
  417. solace_agent_mesh/core_a2a/core_a2a_llm.txt +90 -0
  418. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  419. solace_agent_mesh/core_a2a/service.py +307 -0
  420. solace_agent_mesh/evaluation/__init__.py +0 -0
  421. solace_agent_mesh/evaluation/evaluator.py +691 -0
  422. solace_agent_mesh/evaluation/message_organizer.py +553 -0
  423. solace_agent_mesh/evaluation/report/benchmark_info.html +35 -0
  424. solace_agent_mesh/evaluation/report/chart_section.html +141 -0
  425. solace_agent_mesh/evaluation/report/detailed_breakdown.html +28 -0
  426. solace_agent_mesh/evaluation/report/modal.html +59 -0
  427. solace_agent_mesh/evaluation/report/modal_chart_functions.js +411 -0
  428. solace_agent_mesh/evaluation/report/modal_script.js +296 -0
  429. solace_agent_mesh/evaluation/report/modal_styles.css +340 -0
  430. solace_agent_mesh/evaluation/report/performance_metrics_styles.css +93 -0
  431. solace_agent_mesh/evaluation/report/templates/footer.html +2 -0
  432. solace_agent_mesh/evaluation/report/templates/header.html +340 -0
  433. solace_agent_mesh/evaluation/report_data_processor.py +970 -0
  434. solace_agent_mesh/evaluation/report_generator.py +607 -0
  435. solace_agent_mesh/evaluation/run.py +954 -0
  436. solace_agent_mesh/evaluation/shared/__init__.py +92 -0
  437. solace_agent_mesh/evaluation/shared/constants.py +47 -0
  438. solace_agent_mesh/evaluation/shared/exceptions.py +50 -0
  439. solace_agent_mesh/evaluation/shared/helpers.py +35 -0
  440. solace_agent_mesh/evaluation/shared/test_case_loader.py +167 -0
  441. solace_agent_mesh/evaluation/shared/test_suite_loader.py +280 -0
  442. solace_agent_mesh/evaluation/subscriber.py +776 -0
  443. solace_agent_mesh/evaluation/summary_builder.py +880 -0
  444. solace_agent_mesh/gateway/__init__.py +0 -0
  445. solace_agent_mesh/gateway/adapter/__init__.py +1 -0
  446. solace_agent_mesh/gateway/adapter/base.py +143 -0
  447. solace_agent_mesh/gateway/adapter/types.py +221 -0
  448. solace_agent_mesh/gateway/base/__init__.py +1 -0
  449. solace_agent_mesh/gateway/base/app.py +345 -0
  450. solace_agent_mesh/gateway/base/base_llm.txt +226 -0
  451. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  452. solace_agent_mesh/gateway/base/component.py +2030 -0
  453. solace_agent_mesh/gateway/base/task_context.py +75 -0
  454. solace_agent_mesh/gateway/gateway_llm.txt +369 -0
  455. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  456. solace_agent_mesh/gateway/generic/__init__.py +1 -0
  457. solace_agent_mesh/gateway/generic/app.py +50 -0
  458. solace_agent_mesh/gateway/generic/component.py +727 -0
  459. solace_agent_mesh/gateway/http_sse/__init__.py +0 -0
  460. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +345 -0
  461. solace_agent_mesh/gateway/http_sse/alembic/env.py +87 -0
  462. solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
  463. solace_agent_mesh/gateway/http_sse/alembic/versions/20250910_d5b3f8f2e9a0_create_initial_database.py +58 -0
  464. solace_agent_mesh/gateway/http_sse/alembic/versions/20250911_b1c2d3e4f5g6_add_database_indexes.py +83 -0
  465. solace_agent_mesh/gateway/http_sse/alembic/versions/20250916_f6e7d8c9b0a1_convert_timestamps_to_epoch_and_align_columns.py +412 -0
  466. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  467. solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
  468. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
  469. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
  470. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
  471. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
  472. solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
  473. solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
  474. solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
  475. solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
  476. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +161 -0
  477. solace_agent_mesh/gateway/http_sse/alembic.ini +109 -0
  478. solace_agent_mesh/gateway/http_sse/app.py +351 -0
  479. solace_agent_mesh/gateway/http_sse/component.py +2360 -0
  480. solace_agent_mesh/gateway/http_sse/components/__init__.py +7 -0
  481. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +105 -0
  482. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
  483. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +110 -0
  484. solace_agent_mesh/gateway/http_sse/dependencies.py +653 -0
  485. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +299 -0
  486. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  487. solace_agent_mesh/gateway/http_sse/main.py +789 -0
  488. solace_agent_mesh/gateway/http_sse/repository/__init__.py +46 -0
  489. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +102 -0
  490. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +11 -0
  491. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  492. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +221 -0
  493. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  494. solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
  495. solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
  496. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +66 -0
  497. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -0
  498. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +32 -0
  499. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  500. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +125 -0
  501. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +239 -0
  502. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +34 -0
  503. solace_agent_mesh/gateway/http_sse/repository/models/base.py +7 -0
  504. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  505. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  506. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +257 -0
  507. solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
  508. solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
  509. solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
  510. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +53 -0
  511. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  512. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +39 -0
  513. solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
  514. solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
  515. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +308 -0
  516. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +268 -0
  517. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +248 -0
  518. solace_agent_mesh/gateway/http_sse/routers/__init__.py +4 -0
  519. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +74 -0
  520. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1137 -0
  521. solace_agent_mesh/gateway/http_sse/routers/auth.py +311 -0
  522. solace_agent_mesh/gateway/http_sse/routers/config.py +371 -0
  523. solace_agent_mesh/gateway/http_sse/routers/dto/__init__.py +10 -0
  524. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +450 -0
  525. solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
  526. solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
  527. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +15 -0
  528. solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
  529. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +133 -0
  530. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +33 -0
  531. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  532. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +18 -0
  533. solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +42 -0
  534. solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
  535. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +123 -0
  536. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +33 -0
  537. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  538. solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
  539. solace_agent_mesh/gateway/http_sse/routers/feedback.py +168 -0
  540. solace_agent_mesh/gateway/http_sse/routers/people.py +38 -0
  541. solace_agent_mesh/gateway/http_sse/routers/projects.py +767 -0
  542. solace_agent_mesh/gateway/http_sse/routers/prompts.py +1415 -0
  543. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +312 -0
  544. solace_agent_mesh/gateway/http_sse/routers/sessions.py +634 -0
  545. solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
  546. solace_agent_mesh/gateway/http_sse/routers/sse.py +230 -0
  547. solace_agent_mesh/gateway/http_sse/routers/tasks.py +1089 -0
  548. solace_agent_mesh/gateway/http_sse/routers/users.py +83 -0
  549. solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
  550. solace_agent_mesh/gateway/http_sse/routers/visualization.py +1220 -0
  551. solace_agent_mesh/gateway/http_sse/services/__init__.py +4 -0
  552. solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +71 -0
  553. solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
  554. solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
  555. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +273 -0
  556. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +250 -0
  557. solace_agent_mesh/gateway/http_sse/services/people_service.py +78 -0
  558. solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
  559. solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
  560. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +303 -0
  561. solace_agent_mesh/gateway/http_sse/services/session_service.py +702 -0
  562. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +593 -0
  563. solace_agent_mesh/gateway/http_sse/services/task_service.py +119 -0
  564. solace_agent_mesh/gateway/http_sse/session_manager.py +219 -0
  565. solace_agent_mesh/gateway/http_sse/shared/__init__.py +146 -0
  566. solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
  567. solace_agent_mesh/gateway/http_sse/shared/base_repository.py +252 -0
  568. solace_agent_mesh/gateway/http_sse/shared/database_exceptions.py +274 -0
  569. solace_agent_mesh/gateway/http_sse/shared/database_helpers.py +43 -0
  570. solace_agent_mesh/gateway/http_sse/shared/enums.py +40 -0
  571. solace_agent_mesh/gateway/http_sse/shared/error_dto.py +107 -0
  572. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +217 -0
  573. solace_agent_mesh/gateway/http_sse/shared/exceptions.py +192 -0
  574. solace_agent_mesh/gateway/http_sse/shared/pagination.py +138 -0
  575. solace_agent_mesh/gateway/http_sse/shared/response_utils.py +134 -0
  576. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +319 -0
  577. solace_agent_mesh/gateway/http_sse/shared/timestamp_utils.py +97 -0
  578. solace_agent_mesh/gateway/http_sse/shared/types.py +50 -0
  579. solace_agent_mesh/gateway/http_sse/shared/utils.py +22 -0
  580. solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +88 -0
  581. solace_agent_mesh/gateway/http_sse/sse_manager.py +491 -0
  582. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  583. solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
  584. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +72 -0
  585. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  586. solace_agent_mesh/llm.txt +228 -0
  587. solace_agent_mesh/llm_detail.txt +2835 -0
  588. solace_agent_mesh/services/__init__.py +0 -0
  589. solace_agent_mesh/services/platform/__init__.py +18 -0
  590. solace_agent_mesh/services/platform/alembic/env.py +85 -0
  591. solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
  592. solace_agent_mesh/services/platform/alembic.ini +109 -0
  593. solace_agent_mesh/services/platform/api/__init__.py +3 -0
  594. solace_agent_mesh/services/platform/api/dependencies.py +147 -0
  595. solace_agent_mesh/services/platform/api/main.py +280 -0
  596. solace_agent_mesh/services/platform/api/middleware.py +51 -0
  597. solace_agent_mesh/services/platform/api/routers/__init__.py +24 -0
  598. solace_agent_mesh/services/platform/app.py +114 -0
  599. solace_agent_mesh/services/platform/component.py +235 -0
  600. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  601. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  602. solace_agent_mesh/templates/agent_template.yaml +53 -0
  603. solace_agent_mesh/templates/eval_backend_template.yaml +54 -0
  604. solace_agent_mesh/templates/gateway_app_template.py +75 -0
  605. solace_agent_mesh/templates/gateway_component_template.py +484 -0
  606. solace_agent_mesh/templates/gateway_config_template.yaml +38 -0
  607. solace_agent_mesh/templates/logging_config_template.yaml +48 -0
  608. solace_agent_mesh/templates/main_orchestrator.yaml +66 -0
  609. solace_agent_mesh/templates/plugin_agent_config_template.yaml +122 -0
  610. solace_agent_mesh/templates/plugin_custom_config_template.yaml +27 -0
  611. solace_agent_mesh/templates/plugin_custom_template.py +10 -0
  612. solace_agent_mesh/templates/plugin_gateway_config_template.yaml +60 -0
  613. solace_agent_mesh/templates/plugin_pyproject_template.toml +32 -0
  614. solace_agent_mesh/templates/plugin_readme_template.md +12 -0
  615. solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
  616. solace_agent_mesh/templates/plugin_tools_template.py +224 -0
  617. solace_agent_mesh/templates/shared_config.yaml +112 -0
  618. solace_agent_mesh/templates/templates_llm.txt +147 -0
  619. solace_agent_mesh/templates/webui.yaml +177 -0
  620. solace_agent_mesh-1.11.2.dist-info/METADATA +504 -0
  621. solace_agent_mesh-1.11.2.dist-info/RECORD +624 -0
  622. solace_agent_mesh-1.11.2.dist-info/WHEEL +4 -0
  623. solace_agent_mesh-1.11.2.dist-info/entry_points.txt +3 -0
  624. solace_agent_mesh-1.11.2.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,1089 @@
1
+ """
2
+ API Router for submitting and managing tasks to agents.
3
+ Includes background task status endpoints.
4
+ """
5
+
6
+ import logging
7
+ from typing import TYPE_CHECKING
8
+
9
+ import yaml
10
+ from a2a.types import (
11
+ CancelTaskRequest,
12
+ SendMessageRequest,
13
+ SendMessageSuccessResponse,
14
+ SendStreamingMessageRequest,
15
+ SendStreamingMessageSuccessResponse,
16
+ )
17
+ from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
18
+ from fastapi import Request as FastAPIRequest
19
+ from pydantic import BaseModel
20
+ from sqlalchemy.orm import Session as DBSession
21
+
22
+ from ....gateway.http_sse.services.project_service import ProjectService
23
+
24
+ from ....agent.utils.artifact_helpers import (
25
+ get_artifact_info_list,
26
+ )
27
+
28
+ from ....common import a2a
29
+ from ....gateway.http_sse.dependencies import (
30
+ get_db,
31
+ get_project_service_optional,
32
+ get_sac_component,
33
+ get_session_business_service,
34
+ get_session_manager,
35
+ get_task_repository,
36
+ get_task_service,
37
+ get_user_config,
38
+ get_user_id,
39
+ )
40
+ from ....gateway.http_sse.repository.entities import Task
41
+ from ....gateway.http_sse.repository.interfaces import ITaskRepository
42
+ from ....gateway.http_sse.repository.task_repository import TaskRepository
43
+ from ....gateway.http_sse.services.session_service import SessionService
44
+ from ....gateway.http_sse.services.task_service import TaskService
45
+ from ....gateway.http_sse.session_manager import SessionManager
46
+ from ....gateway.http_sse.shared.pagination import PaginationParams
47
+ from ....gateway.http_sse.shared.types import UserId
48
+ from ..utils.stim_utils import create_stim_from_task_data
49
+
50
+ if TYPE_CHECKING:
51
+ from ....gateway.http_sse.component import WebUIBackendComponent
52
+
53
+ router = APIRouter()
54
+
55
+ log = logging.getLogger(__name__)
56
+
57
+
58
+ # Background Task Status Models and Endpoints
59
+ class TaskStatusResponse(BaseModel):
60
+ """Response model for task status queries."""
61
+ task: Task
62
+ is_running: bool
63
+ is_background: bool
64
+ can_reconnect: bool
65
+
66
+
67
+ @router.get("/tasks/{task_id}/status", response_model=TaskStatusResponse, tags=["Tasks"])
68
+ async def get_task_status(
69
+ task_id: str,
70
+ db: DBSession = Depends(get_db),
71
+ ):
72
+ """
73
+ Get the current status of a task.
74
+ Used by frontend to check if a background task is still running.
75
+
76
+ Args:
77
+ task_id: The task ID to query
78
+
79
+ Returns:
80
+ Task status information including whether it's running and can be reconnected to
81
+ """
82
+ log_prefix = f"[GET /api/v1/tasks/{task_id}/status] "
83
+ log.debug("%sQuerying task status", log_prefix)
84
+
85
+ repo = TaskRepository()
86
+ task = repo.find_by_id(db, task_id)
87
+
88
+ if not task:
89
+ raise HTTPException(status_code=404, detail=f"Task {task_id} not found")
90
+
91
+ # Determine if task is still running
92
+ is_running = task.status in [None, "running", "pending"] and task.end_time is None
93
+
94
+ # Check if it's a background task
95
+ is_background = task.background_execution_enabled or False
96
+
97
+ # Can reconnect if it's a background task and still running
98
+ can_reconnect = is_background and is_running
99
+
100
+ log.info(
101
+ "%sTask status: running=%s, background=%s, can_reconnect=%s",
102
+ log_prefix,
103
+ is_running,
104
+ is_background,
105
+ can_reconnect,
106
+ )
107
+
108
+ return TaskStatusResponse(
109
+ task=task,
110
+ is_running=is_running,
111
+ is_background=is_background,
112
+ can_reconnect=can_reconnect
113
+ )
114
+
115
+
116
+ @router.get("/tasks/background/active", tags=["Tasks"])
117
+ async def get_active_background_tasks(
118
+ user_id: str = Query(..., description="User ID to filter tasks"),
119
+ db: DBSession = Depends(get_db),
120
+ ):
121
+ """
122
+ Get all active background tasks for a user.
123
+ Used by frontend on session load to detect running background tasks.
124
+
125
+ Args:
126
+ user_id: The user ID to filter by
127
+
128
+ Returns:
129
+ List of active background tasks
130
+ """
131
+ log_prefix = "[GET /api/v1/tasks/background/active] "
132
+ log.debug("%sQuerying active background tasks for user %s", log_prefix, user_id)
133
+
134
+ repo = TaskRepository()
135
+
136
+ # Get all background tasks
137
+ all_background_tasks = repo.find_background_tasks_by_status(db, status=None)
138
+
139
+ # Filter by user and running status
140
+ active_tasks = [
141
+ task for task in all_background_tasks
142
+ if task.user_id == user_id
143
+ and task.status in [None, "running", "pending"]
144
+ and task.end_time is None
145
+ ]
146
+
147
+ log.info("%sFound %d active background tasks for user %s", log_prefix, len(active_tasks), user_id)
148
+
149
+ return {
150
+ "tasks": active_tasks,
151
+ "count": len(active_tasks)
152
+ }
153
+
154
+
155
+ # =============================================================================
156
+ # Project Context Injection Helper
157
+ # =============================================================================
158
+
159
+
160
+ async def _inject_project_context(
161
+ project_id: str,
162
+ message_text: str,
163
+ user_id: str,
164
+ session_id: str,
165
+ project_service: ProjectService,
166
+ component: "WebUIBackendComponent",
167
+ log_prefix: str,
168
+ inject_full_context: bool = True,
169
+ ) -> str:
170
+ """
171
+ Helper function to inject project context and copy artifacts to session.
172
+
173
+ Args:
174
+ inject_full_context: If True, injects full project context (name, description, instructions).
175
+ If False, only copies new artifacts without modifying message text.
176
+ This allows existing sessions to get new project files without
177
+ re-injecting the full context on every message.
178
+
179
+ Returns the modified message text with project context injected (if inject_full_context=True).
180
+ """
181
+ if not project_id or not message_text:
182
+ return message_text
183
+
184
+ from ....gateway.http_sse.dependencies import SessionLocal
185
+ from ..utils.artifact_copy_utils import copy_project_artifacts_to_session
186
+
187
+ if SessionLocal is None:
188
+ log.warning(
189
+ "%sProject context injection skipped: database not configured", log_prefix
190
+ )
191
+ return message_text
192
+
193
+ db = SessionLocal()
194
+ artifact_service = None
195
+ should_clear_pending_flags = False
196
+
197
+ try:
198
+ project = project_service.get_project(db, project_id, user_id)
199
+ if not project:
200
+ return message_text
201
+
202
+ context_parts = []
203
+
204
+ # Only inject full context for new sessions
205
+ if inject_full_context:
206
+ # Start with clear workspace framing
207
+ context_parts.append(
208
+ f'You are working in the project workspace: "{project.name}"'
209
+ )
210
+
211
+ # Add system prompt if exists
212
+ if project.system_prompt and project.system_prompt.strip():
213
+ context_parts.append(f"\n{project.system_prompt.strip()}")
214
+
215
+ # Add project description if exists
216
+ if project.description and project.description.strip():
217
+ context_parts.append(f"\nProject Description: {project.description.strip()}")
218
+
219
+ # Always copy project artifacts to session (for both new and existing sessions)
220
+ # This ensures new project files are available to existing sessions
221
+ artifact_service = component.get_shared_artifact_service()
222
+ if artifact_service:
223
+ try:
224
+ artifacts_copied, new_artifact_names = await copy_project_artifacts_to_session(
225
+ project_id=project_id,
226
+ user_id=user_id,
227
+ session_id=session_id,
228
+ project_service=project_service,
229
+ component=component,
230
+ db=db,
231
+ log_prefix=log_prefix,
232
+ )
233
+
234
+ if inject_full_context and artifacts_copied > 0:
235
+ # need to clear the pending flags even if injection fails
236
+ should_clear_pending_flags = True
237
+
238
+ # Get artifact descriptions for context injection
239
+ if artifacts_copied > 0 or inject_full_context:
240
+ source_user_id = project.user_id
241
+ project_artifacts_session_id = f"project-{project.id}"
242
+
243
+ project_artifacts = await get_artifact_info_list(
244
+ artifact_service=artifact_service,
245
+ app_name=project_service.app_name,
246
+ user_id=source_user_id,
247
+ session_id=project_artifacts_session_id,
248
+ )
249
+
250
+ if project_artifacts:
251
+ # For new sessions - all files
252
+ all_artifact_descriptions = []
253
+ # For existing sessions - only new files
254
+ new_artifact_descriptions = []
255
+
256
+ for artifact_info in project_artifacts:
257
+ # Build description for all artifacts (for new sessions)
258
+ desc_str = f"- {artifact_info.filename}"
259
+ if artifact_info.description:
260
+ desc_str += f": {artifact_info.description}"
261
+ all_artifact_descriptions.append(desc_str)
262
+
263
+ # Track new artifacts for existing sessions
264
+ if artifact_info.filename in new_artifact_names:
265
+ new_artifact_descriptions.append(desc_str)
266
+
267
+ # Add artifact descriptions to context
268
+ files_added_header = (
269
+ "\nNew Files Added to Session:\n"
270
+ "The following files have been added to your session (in addition to any files already present):\n"
271
+ )
272
+
273
+ if inject_full_context and all_artifact_descriptions:
274
+ # New session: show all project files
275
+ artifacts_context = files_added_header + "\n".join(all_artifact_descriptions)
276
+ context_parts.append(artifacts_context)
277
+ elif not inject_full_context and new_artifact_descriptions:
278
+ # Existing session: notify about newly added files
279
+ new_files_context = files_added_header + "\n".join(new_artifact_descriptions)
280
+ context_parts.append(new_files_context)
281
+
282
+ except Exception as e:
283
+ log.warning(
284
+ "%sFailed to copy project artifacts to session: %s", log_prefix, e
285
+ )
286
+ # Do not fail the entire request, just log the warning
287
+
288
+ # Inject all gathered context into the message, ending with user query
289
+ # Only modify message text if we're injecting full context (new sessions)
290
+ modified_message_text = message_text
291
+ if context_parts:
292
+ project_context = "\n".join(context_parts)
293
+ modified_message_text = f"{project_context}\n\nUSER QUERY:\n{message_text}"
294
+ log.debug("%sInjected full project context for project: %s", log_prefix, project_id)
295
+ else:
296
+ log.debug("%sSkipped full context injection for existing session, but ensured new artifacts are copied", log_prefix)
297
+
298
+ return modified_message_text
299
+
300
+ except Exception as e:
301
+ log.warning("%sFailed to inject project context: %s", log_prefix, e)
302
+ # Continue without injection - don't fail the request
303
+ return message_text
304
+ finally:
305
+ # Clear the pending project context flags from all artifacts
306
+ if should_clear_pending_flags and artifact_service:
307
+ from ..utils.artifact_copy_utils import clear_pending_project_context
308
+ try:
309
+ await clear_pending_project_context(
310
+ user_id=user_id,
311
+ session_id=session_id,
312
+ artifact_service=artifact_service,
313
+ app_name=project_service.app_name,
314
+ db=db,
315
+ log_prefix=log_prefix,
316
+ )
317
+ log.debug("%sCleared pending project context flags", log_prefix)
318
+ except Exception as e:
319
+ log.warning("%sFailed to clear pending project context flags: %s", log_prefix, e)
320
+
321
+ db.close()
322
+
323
+
324
+ async def _submit_task(
325
+ request: FastAPIRequest,
326
+ payload: SendMessageRequest | SendStreamingMessageRequest,
327
+ session_manager: SessionManager,
328
+ component: "WebUIBackendComponent",
329
+ project_service: ProjectService | None,
330
+ is_streaming: bool,
331
+ session_service: SessionService | None = None,
332
+ ):
333
+ """
334
+ Helper to submit a task, handling both streaming and non-streaming cases.
335
+
336
+ Also handles project context injection.
337
+ """
338
+ log_prefix = f"[POST /api/v1/message:{'stream' if is_streaming else 'send'}] "
339
+
340
+ agent_name = None
341
+ project_id = None
342
+ if payload.params and payload.params.message and payload.params.message.metadata:
343
+ agent_name = payload.params.message.metadata.get("agent_name")
344
+ project_id = payload.params.message.metadata.get("project_id")
345
+
346
+ if not agent_name:
347
+ raise HTTPException(
348
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
349
+ detail="Missing 'agent_name' in request payload message metadata.",
350
+ )
351
+
352
+ log.info("%sReceived request for agent: %s", log_prefix, agent_name)
353
+
354
+ try:
355
+ user_identity = await component.authenticate_and_enrich_user(request)
356
+ if user_identity is None:
357
+ log.warning("%sUser authentication failed. Denying request.", log_prefix)
358
+ raise HTTPException(
359
+ status_code=status.HTTP_401_UNAUTHORIZED,
360
+ detail="User authentication failed or identity not found.",
361
+ )
362
+ log.debug(
363
+ "%sAuthenticated user identity: %s",
364
+ log_prefix,
365
+ user_identity.get("id", "unknown"),
366
+ )
367
+
368
+ client_id = session_manager.get_a2a_client_id(request)
369
+
370
+ # Use session ID from frontend request (contextId per A2A spec) instead of cookie-based session
371
+ # Handle various falsy values: None, empty string, whitespace-only string
372
+ frontend_session_id = None
373
+ if (
374
+ hasattr(payload.params.message, "context_id")
375
+ and payload.params.message.context_id
376
+ ):
377
+ context_id = payload.params.message.context_id
378
+ if isinstance(context_id, str) and context_id.strip():
379
+ frontend_session_id = context_id.strip()
380
+
381
+ user_id = user_identity.get("id")
382
+ from ....gateway.http_sse.dependencies import SessionLocal
383
+
384
+ # If project_id not in metadata, check if session has a project_id in database
385
+ # This handles cases where sessions are moved to projects after creation
386
+ if not project_id and session_service and frontend_session_id:
387
+ if SessionLocal is not None:
388
+ db = SessionLocal()
389
+ try:
390
+ session_details = session_service.get_session_details(
391
+ db, frontend_session_id, user_id
392
+ )
393
+ if session_details and session_details.project_id:
394
+ project_id = session_details.project_id
395
+ log.info(
396
+ "%sFound project_id %s from session database for session %s",
397
+ log_prefix,
398
+ project_id,
399
+ frontend_session_id,
400
+ )
401
+ except Exception as e:
402
+ log.warning(
403
+ "%sFailed to lookup session project_id: %s", log_prefix, e
404
+ )
405
+ finally:
406
+ db.close()
407
+
408
+ if frontend_session_id:
409
+ session_id = frontend_session_id
410
+ log.info(
411
+ "%sUsing session ID from frontend request: %s", log_prefix, session_id
412
+ )
413
+ else:
414
+ # Create new session when frontend doesn't provide one
415
+ session_id = session_manager.create_new_session_id(request)
416
+ log.debug(
417
+ "%sNo valid session ID from frontend, created new session: %s",
418
+ log_prefix,
419
+ session_id,
420
+ )
421
+
422
+ # Immediately create session in database if persistence is enabled
423
+ # This ensures the session exists before any other operations (like artifact listing)
424
+ if SessionLocal is not None and session_service is not None:
425
+ db = SessionLocal()
426
+ try:
427
+ session_service.create_session(
428
+ db=db,
429
+ user_id=user_id,
430
+ agent_id=agent_name,
431
+ session_id=session_id,
432
+ project_id=project_id,
433
+ )
434
+ db.commit()
435
+ log.debug(
436
+ "%sCreated session in database: %s", log_prefix, session_id
437
+ )
438
+ except Exception as e:
439
+ db.rollback()
440
+ log.warning(
441
+ "%sFailed to create session in database: %s", log_prefix, e
442
+ )
443
+ finally:
444
+ db.close()
445
+
446
+ log.info(
447
+ "%sUsing ClientID: %s, SessionID: %s", log_prefix, client_id, session_id
448
+ )
449
+
450
+ # Extract message text and apply project context injection
451
+ message_text = ""
452
+ if payload.params and payload.params.message:
453
+ parts = a2a.get_parts_from_message(payload.params.message)
454
+ for part in parts:
455
+ if hasattr(part, "text"):
456
+ message_text = part.text
457
+ break
458
+
459
+ # Project context injection - always inject for project sessions to ensure new files are available
460
+ # Skip if project_service is None (persistence disabled)
461
+ modified_message = payload.params.message
462
+ if project_service and project_id and message_text:
463
+ # Determine if we should inject full context:
464
+ should_inject_full_context = not frontend_session_id
465
+
466
+ # Check if there are artifacts with pending project context
467
+ if frontend_session_id and not should_inject_full_context:
468
+ from ..utils.artifact_copy_utils import has_pending_project_context
469
+ from ....gateway.http_sse.dependencies import SessionLocal
470
+
471
+ artifact_service = component.get_shared_artifact_service()
472
+ if artifact_service and SessionLocal:
473
+ db = SessionLocal()
474
+ try:
475
+ has_pending = await has_pending_project_context(
476
+ user_id=client_id,
477
+ session_id=session_id,
478
+ artifact_service=artifact_service,
479
+ app_name=component.gateway_id,
480
+ db=db,
481
+ )
482
+ if has_pending:
483
+ should_inject_full_context = True
484
+ log.info(
485
+ "%sDetected pending project context for session %s, will inject full context",
486
+ log_prefix,
487
+ session_id,
488
+ )
489
+ finally:
490
+ db.close()
491
+
492
+ modified_message_text = await _inject_project_context(
493
+ project_id=project_id,
494
+ message_text=message_text,
495
+ user_id=user_id,
496
+ session_id=session_id,
497
+ project_service=project_service,
498
+ component=component,
499
+ log_prefix=log_prefix,
500
+ inject_full_context=should_inject_full_context,
501
+ )
502
+
503
+ # Update the message with project context if it was modified
504
+ if modified_message_text != message_text:
505
+ # Create new text part with project context
506
+ new_text_part = a2a.create_text_part(modified_message_text)
507
+
508
+ # Get existing parts and replace the first text part with the modified one
509
+ existing_parts = a2a.get_parts_from_message(payload.params.message)
510
+ new_parts = []
511
+ text_part_replaced = False
512
+
513
+ for part in existing_parts:
514
+ if hasattr(part, "text") and not text_part_replaced:
515
+ new_parts.append(new_text_part)
516
+ text_part_replaced = True
517
+ else:
518
+ new_parts.append(part)
519
+
520
+ # If no text part was found, add the new text part at the beginning
521
+ if not text_part_replaced:
522
+ new_parts.insert(0, new_text_part)
523
+
524
+ # Update the message with the new parts
525
+ modified_message = a2a.update_message_parts(
526
+ payload.params.message, new_parts
527
+ )
528
+
529
+ # Use the helper to get the unwrapped parts from the modified message (with project context if applied).
530
+ a2a_parts = a2a.get_parts_from_message(modified_message)
531
+
532
+ external_req_ctx = {
533
+ "app_name_for_artifacts": component.gateway_id,
534
+ "user_id_for_artifacts": client_id,
535
+ "a2a_session_id": session_id, # This may have been updated by persistence layer
536
+ "user_id_for_a2a": client_id,
537
+ "target_agent_name": agent_name,
538
+ }
539
+
540
+ task_id = await component.submit_a2a_task(
541
+ target_agent_name=agent_name,
542
+ a2a_parts=a2a_parts,
543
+ external_request_context=external_req_ctx,
544
+ user_identity=user_identity,
545
+ is_streaming=is_streaming,
546
+ )
547
+
548
+ log.info("%sTask submitted successfully. TaskID: %s", log_prefix, task_id)
549
+
550
+ task_object = a2a.create_initial_task(
551
+ task_id=task_id,
552
+ context_id=session_id,
553
+ agent_name=agent_name,
554
+ )
555
+
556
+ if is_streaming:
557
+ # The task_object already contains the contextId from create_initial_task
558
+ return a2a.create_send_streaming_message_success_response(
559
+ result=task_object, request_id=payload.id
560
+ )
561
+ else:
562
+ return a2a.create_send_message_success_response(
563
+ result=task_object, request_id=payload.id
564
+ )
565
+
566
+ except PermissionError as pe:
567
+ log.warning("%sPermission denied: %s", log_prefix, str(pe))
568
+ raise HTTPException(
569
+ status_code=status.HTTP_403_FORBIDDEN,
570
+ detail=str(pe),
571
+ )
572
+ except Exception as e:
573
+ log.exception("%sUnexpected error submitting task: %s", log_prefix, e)
574
+ error_resp = a2a.create_internal_error(
575
+ message="Unexpected server error: %s" % e
576
+ )
577
+ raise HTTPException(
578
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
579
+ detail=error_resp.model_dump(exclude_none=True),
580
+ )
581
+
582
+
583
+ @router.get("/tasks", response_model=list[Task], tags=["Tasks"])
584
+ async def search_tasks(
585
+ request: FastAPIRequest,
586
+ start_date: str | None = None,
587
+ end_date: str | None = None,
588
+ page: int = 1,
589
+ page_size: int = 20,
590
+ query_user_id: str | None = None,
591
+ db: DBSession = Depends(get_db),
592
+ user_id: UserId = Depends(get_user_id),
593
+ user_config: dict = Depends(get_user_config),
594
+ repo: ITaskRepository = Depends(get_task_repository),
595
+ ):
596
+ """
597
+ Lists and filters historical tasks by date.
598
+ - Regular users can only view their own tasks.
599
+ - Users with the 'tasks:read:all' scope can view any user's tasks by providing `query_user_id`.
600
+ """
601
+ log_prefix = "[GET /api/v1/tasks] "
602
+ log.info("%sRequest from user %s", log_prefix, user_id)
603
+
604
+ target_user_id = user_id
605
+ can_query_all = user_config.get("scopes", {}).get("tasks:read:all", False)
606
+
607
+ if query_user_id:
608
+ if can_query_all:
609
+ target_user_id = query_user_id
610
+ log.info(
611
+ "%sAdmin user %s is querying for user %s",
612
+ log_prefix,
613
+ user_id,
614
+ target_user_id,
615
+ )
616
+ else:
617
+ raise HTTPException(
618
+ status_code=status.HTTP_403_FORBIDDEN,
619
+ detail="You do not have permission to query for other users' tasks.",
620
+ )
621
+ elif can_query_all:
622
+ target_user_id = "*"
623
+ log.info("%sAdmin user %s is querying for all users.", log_prefix, user_id)
624
+
625
+ start_time_ms = None
626
+ if start_date:
627
+ try:
628
+ start_time_ms = int(datetime.fromisoformat(start_date).timestamp() * 1000)
629
+ except ValueError:
630
+ raise HTTPException(
631
+ status_code=status.HTTP_400_BAD_REQUEST,
632
+ detail="Invalid start_date format. Use ISO 8601 format.",
633
+ )
634
+
635
+ end_time_ms = None
636
+ if end_date:
637
+ try:
638
+ end_time_ms = int(datetime.fromisoformat(end_date).timestamp() * 1000)
639
+ except ValueError:
640
+ raise HTTPException(
641
+ status_code=status.HTTP_400_BAD_REQUEST,
642
+ detail="Invalid end_date format. Use ISO 8601 format.",
643
+ )
644
+
645
+ pagination = PaginationParams(page_number=page, page_size=page_size)
646
+
647
+ try:
648
+ tasks = repo.search(
649
+ db,
650
+ user_id=target_user_id,
651
+ start_date=start_time_ms,
652
+ end_date=end_time_ms,
653
+ pagination=pagination,
654
+ )
655
+ return tasks
656
+ except Exception as e:
657
+ log.exception("%sError searching for tasks: %s", log_prefix, e)
658
+ raise HTTPException(
659
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
660
+ detail="An error occurred while searching for tasks.",
661
+ )
662
+
663
+
664
+ @router.get("/tasks/{task_id}/events", tags=["Tasks"])
665
+ async def get_task_events(
666
+ task_id: str,
667
+ request: FastAPIRequest,
668
+ db: DBSession = Depends(get_db),
669
+ user_id: UserId = Depends(get_user_id),
670
+ user_config: dict = Depends(get_user_config),
671
+ repo: ITaskRepository = Depends(get_task_repository),
672
+ ):
673
+ """
674
+ Retrieves the complete event history for a task and all its child tasks as JSON.
675
+ Returns events in the same format as the SSE stream for workflow visualization.
676
+ Recursively loads all descendant tasks to enable full workflow rendering.
677
+ """
678
+ log_prefix = f"[GET /api/v1/tasks/{task_id}/events] "
679
+ log.info("%sRequest from user %s", log_prefix, user_id)
680
+
681
+ try:
682
+ result = repo.find_by_id_with_events(db, task_id)
683
+ if not result:
684
+ raise HTTPException(
685
+ status_code=status.HTTP_404_NOT_FOUND,
686
+ detail=f"Task with ID '{task_id}' not found.",
687
+ )
688
+
689
+ task, events = result
690
+
691
+ can_read_all = user_config.get("scopes", {}).get("tasks:read:all", False)
692
+ if task.user_id != user_id and not can_read_all:
693
+ raise HTTPException(
694
+ status_code=status.HTTP_403_FORBIDDEN,
695
+ detail="You do not have permission to view this task.",
696
+ )
697
+
698
+ # Transform task events into A2AEventSSEPayload format for the frontend
699
+ # Need to reconstruct the SSE structure from stored data
700
+ formatted_events = []
701
+
702
+ for event in events:
703
+ # event.payload contains the raw A2A JSON-RPC message
704
+ # event.created_time is epoch milliseconds
705
+ # event.direction is simplified (request, response, status, error, etc)
706
+
707
+ # Convert timestamp from epoch milliseconds to ISO 8601
708
+ from datetime import datetime, timezone
709
+ timestamp_dt = datetime.fromtimestamp(event.created_time / 1000, tz=timezone.utc)
710
+ timestamp_iso = timestamp_dt.isoformat()
711
+
712
+ # Extract metadata from payload using similar logic to SSE component
713
+ payload = event.payload
714
+ message_id = payload.get("id")
715
+ source_entity = "unknown"
716
+ target_entity = "unknown"
717
+ method = "N/A"
718
+
719
+ # Parse based on direction
720
+ if event.direction == "request":
721
+ # It's a request - extract target from message metadata
722
+ method = payload.get("method", "N/A")
723
+ if "params" in payload and "message" in payload.get("params", {}):
724
+ message = payload["params"]["message"]
725
+ if isinstance(message, dict) and "metadata" in message:
726
+ target_entity = message["metadata"].get("agent_name", "unknown")
727
+ elif event.direction in ["status", "response", "error"]:
728
+ # It's a response - extract source from result metadata
729
+ if "result" in payload:
730
+ result = payload["result"]
731
+ if isinstance(result, dict):
732
+ # Check for agent_name in metadata
733
+ if "metadata" in result:
734
+ source_entity = result["metadata"].get("agent_name", "unknown")
735
+ # For status updates, check the message inside
736
+ if "message" in result:
737
+ message = result["message"]
738
+ if isinstance(message, dict) and "metadata" in message:
739
+ if source_entity == "unknown":
740
+ source_entity = message["metadata"].get("agent_name", "unknown")
741
+
742
+ # Map stored direction to SSE direction format
743
+ direction_map = {
744
+ "request": "request",
745
+ "response": "task",
746
+ "status": "status-update",
747
+ "error": "error_response",
748
+ }
749
+ sse_direction = direction_map.get(event.direction, event.direction)
750
+
751
+ # Build the A2AEventSSEPayload structure
752
+ formatted_event = {
753
+ "event_type": "a2a_message",
754
+ "timestamp": timestamp_iso,
755
+ "solace_topic": event.topic,
756
+ "direction": sse_direction,
757
+ "source_entity": source_entity,
758
+ "target_entity": target_entity,
759
+ "message_id": message_id,
760
+ "task_id": task_id,
761
+ "payload_summary": {
762
+ "method": method,
763
+ "params_preview": None,
764
+ },
765
+ "full_payload": payload,
766
+ }
767
+ formatted_events.append(formatted_event)
768
+
769
+ # Use database-level query to get all related tasks efficiently
770
+ related_task_ids = repo.find_all_by_parent_chain(db, task_id)
771
+ log.info(
772
+ "%sFound %d related tasks for task_id %s",
773
+ log_prefix,
774
+ len(related_task_ids),
775
+ task_id,
776
+ )
777
+
778
+ # Load and format all related tasks
779
+ all_tasks = {}
780
+ all_tasks[task_id] = {
781
+ "events": formatted_events,
782
+ "initial_request_text": task.initial_request_text or "",
783
+ }
784
+
785
+ # Load remaining related tasks
786
+ for tid in related_task_ids:
787
+ if tid == task_id:
788
+ continue # Already loaded
789
+
790
+ task_result = repo.find_by_id_with_events(db, tid)
791
+ if not task_result:
792
+ continue
793
+
794
+ related_task, related_events = task_result
795
+
796
+ # Check permissions for each related task
797
+ if related_task.user_id != user_id and not can_read_all:
798
+ log.warning(
799
+ "%sSkipping related task %s due to permission check",
800
+ log_prefix,
801
+ tid,
802
+ )
803
+ continue
804
+
805
+ # Format events for this related task
806
+ related_formatted_events = []
807
+
808
+ for event in related_events:
809
+ from datetime import datetime, timezone
810
+
811
+ timestamp_dt = datetime.fromtimestamp(
812
+ event.created_time / 1000, tz=timezone.utc
813
+ )
814
+ timestamp_iso = timestamp_dt.isoformat()
815
+ payload = event.payload
816
+ message_id = payload.get("id")
817
+ source_entity = "unknown"
818
+ target_entity = "unknown"
819
+ method = "N/A"
820
+
821
+ if event.direction == "request":
822
+ method = payload.get("method", "N/A")
823
+ if "params" in payload and "message" in payload.get("params", {}):
824
+ message = payload["params"]["message"]
825
+ if isinstance(message, dict) and "metadata" in message:
826
+ target_entity = message["metadata"].get(
827
+ "agent_name", "unknown"
828
+ )
829
+ elif event.direction in ["status", "response", "error"]:
830
+ if "result" in payload:
831
+ result = payload["result"]
832
+ if isinstance(result, dict):
833
+ if "metadata" in result:
834
+ source_entity = result["metadata"].get(
835
+ "agent_name", "unknown"
836
+ )
837
+ if "message" in result:
838
+ message = result["message"]
839
+ if isinstance(message, dict) and "metadata" in message:
840
+ if source_entity == "unknown":
841
+ source_entity = message["metadata"].get(
842
+ "agent_name", "unknown"
843
+ )
844
+
845
+ direction_map = {
846
+ "request": "request",
847
+ "response": "task",
848
+ "status": "status-update",
849
+ "error": "error_response",
850
+ }
851
+ sse_direction = direction_map.get(event.direction, event.direction)
852
+
853
+ formatted_event = {
854
+ "event_type": "a2a_message",
855
+ "timestamp": timestamp_iso,
856
+ "solace_topic": event.topic,
857
+ "direction": sse_direction,
858
+ "source_entity": source_entity,
859
+ "target_entity": target_entity,
860
+ "message_id": message_id,
861
+ "task_id": tid,
862
+ "payload_summary": {"method": method, "params_preview": None},
863
+ "full_payload": payload,
864
+ }
865
+ related_formatted_events.append(formatted_event)
866
+
867
+ all_tasks[tid] = {
868
+ "events": related_formatted_events,
869
+ "initial_request_text": related_task.initial_request_text or "",
870
+ }
871
+
872
+ # Return all tasks (parent + children) for the frontend to process
873
+ return {"tasks": all_tasks}
874
+
875
+ except HTTPException:
876
+ # Re-raise HTTPExceptions (404, 403, etc.) without modification
877
+ raise
878
+ except Exception as e:
879
+ log.exception("%sError retrieving task events: %s", log_prefix, e)
880
+ raise HTTPException(
881
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
882
+ detail="An error occurred while retrieving the task events.",
883
+ )
884
+
885
+
886
+ @router.get("/tasks/{task_id}", tags=["Tasks"])
887
+ async def get_task_as_stim_file(
888
+ task_id: str,
889
+ request: FastAPIRequest,
890
+ db: DBSession = Depends(get_db),
891
+ user_id: UserId = Depends(get_user_id),
892
+ user_config: dict = Depends(get_user_config),
893
+ repo: ITaskRepository = Depends(get_task_repository),
894
+ ):
895
+ """
896
+ Retrieves the complete event history for a task and all its child tasks, returning it as a `.stim` file.
897
+ """
898
+ log_prefix = f"[GET /api/v1/tasks/{task_id}] "
899
+ log.info("%sRequest from user %s", log_prefix, user_id)
900
+
901
+ try:
902
+ # Find all related task IDs (parent chain + all children)
903
+ related_task_ids = repo.find_all_by_parent_chain(db, task_id)
904
+
905
+ if not related_task_ids:
906
+ raise HTTPException(
907
+ status_code=status.HTTP_404_NOT_FOUND,
908
+ detail=f"Task with ID '{task_id}' not found.",
909
+ )
910
+
911
+ # Load all tasks and their events
912
+ tasks_dict = {}
913
+ events_dict = {}
914
+ can_read_all = user_config.get("scopes", {}).get("tasks:read:all", False)
915
+
916
+ for tid in related_task_ids:
917
+ result = repo.find_by_id_with_events(db, tid)
918
+ if result:
919
+ task, events = result
920
+
921
+ # Check permissions for each task
922
+ if task.user_id != user_id and not can_read_all:
923
+ raise HTTPException(
924
+ status_code=status.HTTP_403_FORBIDDEN,
925
+ detail="You do not have permission to view this task.",
926
+ )
927
+
928
+ tasks_dict[tid] = task
929
+ events_dict[tid] = events
930
+
931
+ if task_id not in tasks_dict:
932
+ raise HTTPException(
933
+ status_code=status.HTTP_404_NOT_FOUND,
934
+ detail=f"Task with ID '{task_id}' not found.",
935
+ )
936
+
937
+ # Determine the root task (the one without a parent)
938
+ root_task_id = task_id
939
+ for tid, task in tasks_dict.items():
940
+ if task.parent_task_id is None:
941
+ root_task_id = tid
942
+ break
943
+
944
+ # Format into .stim structure with all tasks
945
+ from ..utils.stim_utils import create_stim_from_task_hierarchy
946
+ stim_data = create_stim_from_task_hierarchy(tasks_dict, events_dict, root_task_id)
947
+
948
+ yaml_content = yaml.dump(
949
+ stim_data,
950
+ sort_keys=False,
951
+ allow_unicode=True,
952
+ indent=2,
953
+ default_flow_style=False,
954
+ )
955
+
956
+ return Response(
957
+ content=yaml_content,
958
+ media_type="application/yaml",
959
+ headers={"Content-Disposition": f'attachment; filename="{root_task_id}.stim"'},
960
+ )
961
+
962
+ except HTTPException:
963
+ # Re-raise HTTPExceptions (404, 403, etc.) without modification
964
+ raise
965
+ except Exception as e:
966
+ log.exception("%sError retrieving task: %s", log_prefix, e)
967
+ raise HTTPException(
968
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
969
+ detail="An error occurred while retrieving the task.",
970
+ )
971
+
972
+
973
+ @router.post("/message:send", response_model=SendMessageSuccessResponse)
974
+ async def send_task_to_agent(
975
+ request: FastAPIRequest,
976
+ payload: SendMessageRequest,
977
+ session_manager: SessionManager = Depends(get_session_manager),
978
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
979
+ project_service: ProjectService | None = Depends(get_project_service_optional),
980
+ ):
981
+ """
982
+ Submits a non-streaming task request to the specified agent.
983
+ Accepts application/json.
984
+ """
985
+ return await _submit_task(
986
+ request=request,
987
+ payload=payload,
988
+ session_manager=session_manager,
989
+ component=component,
990
+ project_service=project_service,
991
+ is_streaming=False,
992
+ session_service=None,
993
+ )
994
+
995
+
996
+ @router.post("/message:stream", response_model=SendStreamingMessageSuccessResponse)
997
+ async def subscribe_task_from_agent(
998
+ request: FastAPIRequest,
999
+ payload: SendStreamingMessageRequest,
1000
+ session_manager: SessionManager = Depends(get_session_manager),
1001
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
1002
+ project_service: ProjectService | None = Depends(get_project_service_optional),
1003
+ session_service: SessionService = Depends(get_session_business_service),
1004
+ ):
1005
+ """
1006
+ Submits a streaming task request to the specified agent.
1007
+ Accepts application/json.
1008
+ The client should subsequently connect to the SSE endpoint using the returned taskId.
1009
+ """
1010
+ return await _submit_task(
1011
+ request=request,
1012
+ payload=payload,
1013
+ session_manager=session_manager,
1014
+ component=component,
1015
+ project_service=project_service,
1016
+ is_streaming=True,
1017
+ session_service=session_service,
1018
+ )
1019
+
1020
+
1021
+ @router.post("/tasks/{taskId}:cancel", status_code=status.HTTP_202_ACCEPTED)
1022
+ async def cancel_agent_task(
1023
+ request: FastAPIRequest,
1024
+ taskId: str,
1025
+ payload: CancelTaskRequest,
1026
+ session_manager: SessionManager = Depends(get_session_manager),
1027
+ task_service: TaskService = Depends(get_task_service),
1028
+ component: "WebUIBackendComponent" = Depends(get_sac_component),
1029
+ ):
1030
+ """
1031
+ Sends a cancellation request for a specific task to the specified agent.
1032
+ Returns 202 Accepted, as cancellation is asynchronous.
1033
+ Returns 404 if the task context is not found.
1034
+ """
1035
+ log_prefix = f"[POST /api/v1/tasks/{taskId}:cancel] "
1036
+ log.info("%sReceived cancellation request.", log_prefix)
1037
+
1038
+ if taskId != payload.params.id:
1039
+ raise HTTPException(
1040
+ status_code=status.HTTP_400_BAD_REQUEST,
1041
+ detail="Task ID in URL path does not match task ID in payload.",
1042
+ )
1043
+
1044
+ context = component.task_context_manager.get_context(taskId)
1045
+ if not context:
1046
+ log.warning(
1047
+ "%sNo active task context found for task ID: %s",
1048
+ log_prefix,
1049
+ taskId,
1050
+ )
1051
+ raise HTTPException(
1052
+ status_code=status.HTTP_404_NOT_FOUND,
1053
+ detail=f"No active task context found for task ID: {taskId}",
1054
+ )
1055
+
1056
+ agent_name = context.get("target_agent_name")
1057
+ if not agent_name:
1058
+ log.error(
1059
+ "%sCould not determine target agent for task %s. Context is missing 'target_agent_name'.",
1060
+ log_prefix,
1061
+ taskId,
1062
+ )
1063
+ raise HTTPException(
1064
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
1065
+ detail="Could not determine target agent for the task.",
1066
+ )
1067
+
1068
+ log.info("%sTarget agent for cancellation is '%s'", log_prefix, agent_name)
1069
+
1070
+ try:
1071
+ client_id = session_manager.get_a2a_client_id(request)
1072
+
1073
+ log.info("%sUsing ClientID: %s", log_prefix, client_id)
1074
+
1075
+ await task_service.cancel_task(agent_name, taskId, client_id, client_id)
1076
+
1077
+ log.info("%sCancellation request published successfully.", log_prefix)
1078
+
1079
+ return {"message": "Cancellation request sent"}
1080
+
1081
+ except Exception as e:
1082
+ log.exception("%sUnexpected error sending cancellation: %s", log_prefix, e)
1083
+ error_resp = a2a.create_internal_error(
1084
+ message="Unexpected server error: %s" % e
1085
+ )
1086
+ raise HTTPException(
1087
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
1088
+ detail=error_resp.model_dump(exclude_none=True),
1089
+ )