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
@@ -1,15 +1,19 @@
1
1
  import logging
2
+ from typing import Optional
2
3
  from fastapi import APIRouter, Body, Depends, HTTPException, Query, status
4
+ from pydantic import ValidationError
3
5
  from sqlalchemy.orm import Session
4
6
 
5
7
  from ..dependencies import get_session_business_service, get_db
6
8
  from ..services.session_service import SessionService
7
- from ..shared.auth_utils import get_current_user
8
- from ..shared.pagination import DataResponse, PaginatedResponse, PaginationParams
9
- from ..shared.response_utils import create_data_response
9
+ from solace_agent_mesh.shared.api.auth_utils import get_current_user
10
+ from solace_agent_mesh.shared.api.pagination import DataResponse, PaginatedResponse, PaginationParams
11
+ from solace_agent_mesh.shared.api.response_utils import create_data_response
10
12
  from .dto.requests.session_requests import (
11
13
  GetSessionRequest,
12
14
  UpdateSessionRequest,
15
+ MoveSessionRequest,
16
+ SearchSessionsRequest,
13
17
  )
14
18
  from .dto.requests.task_requests import SaveTaskRequest
15
19
  from .dto.responses.session_responses import SessionResponse
@@ -24,6 +28,7 @@ SESSION_NOT_FOUND_MSG = "Session not found."
24
28
 
25
29
  @router.get("/sessions", response_model=PaginatedResponse[SessionResponse])
26
30
  async def get_all_sessions(
31
+ project_id: Optional[str] = Query(default=None, alias="project_id"),
27
32
  page_number: int = Query(default=1, ge=1, alias="pageNumber"),
28
33
  page_size: int = Query(default=20, ge=1, le=100, alias="pageSize"),
29
34
  db: Session = Depends(get_db),
@@ -31,10 +36,14 @@ async def get_all_sessions(
31
36
  session_service: SessionService = Depends(get_session_business_service),
32
37
  ):
33
38
  user_id = user.get("id")
39
+ log_msg = f"User '{user_id}' is listing sessions with pagination (page={page_number}, size={page_size})"
40
+ if project_id:
41
+ log_msg += f" filtered by project_id={project_id}"
42
+ log.info(log_msg)
34
43
 
35
44
  try:
36
45
  pagination = PaginationParams(page_number=page_number, page_size=page_size)
37
- paginated_response = session_service.get_user_sessions(db, user_id, pagination)
46
+ paginated_response = session_service.get_user_sessions(db, user_id, pagination, project_id=project_id)
38
47
 
39
48
  session_responses = []
40
49
  for session_domain in paginated_response.data:
@@ -43,6 +52,9 @@ async def get_all_sessions(
43
52
  user_id=session_domain.user_id,
44
53
  name=session_domain.name,
45
54
  agent_id=session_domain.agent_id,
55
+ project_id=session_domain.project_id,
56
+ project_name=session_domain.project_name,
57
+ has_running_background_task=session_domain.has_running_background_task,
46
58
  created_time=session_domain.created_time,
47
59
  updated_time=session_domain.updated_time,
48
60
  )
@@ -58,6 +70,64 @@ async def get_all_sessions(
58
70
  ) from e
59
71
 
60
72
 
73
+ @router.get("/sessions/search", response_model=PaginatedResponse[SessionResponse])
74
+ async def search_sessions(
75
+ query: str = Query(..., min_length=1, description="Search query"),
76
+ project_id: Optional[str] = Query(default=None, alias="projectId"),
77
+ page_number: int = Query(default=1, ge=1, alias="pageNumber"),
78
+ page_size: int = Query(default=20, ge=1, le=100, alias="pageSize"),
79
+ db: Session = Depends(get_db),
80
+ user: dict = Depends(get_current_user),
81
+ session_service: SessionService = Depends(get_session_business_service),
82
+ ):
83
+ """
84
+ Search sessions by name/title only.
85
+ """
86
+ user_id = user.get("id")
87
+ log.info(
88
+ "User %s searching sessions with query '%s' (page=%d, size=%d)",
89
+ user_id,
90
+ query,
91
+ page_number,
92
+ page_size,
93
+ )
94
+
95
+ try:
96
+ pagination = PaginationParams(page_number=page_number, page_size=page_size)
97
+ paginated_response = session_service.search_sessions(
98
+ db, user_id, query, pagination, project_id=project_id
99
+ )
100
+
101
+ session_responses = []
102
+ for session_domain in paginated_response.data:
103
+ session_response = SessionResponse(
104
+ id=session_domain.id,
105
+ user_id=session_domain.user_id,
106
+ name=session_domain.name,
107
+ agent_id=session_domain.agent_id,
108
+ project_id=session_domain.project_id,
109
+ project_name=session_domain.project_name,
110
+ has_running_background_task=session_domain.has_running_background_task,
111
+ created_time=session_domain.created_time,
112
+ updated_time=session_domain.updated_time,
113
+ )
114
+ session_responses.append(session_response)
115
+
116
+ return PaginatedResponse(data=session_responses, meta=paginated_response.meta)
117
+
118
+ except ValueError as e:
119
+ log.warning("Validation error searching sessions: %s", e)
120
+ raise HTTPException(
121
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e)
122
+ ) from e
123
+ except Exception as e:
124
+ log.error("Error searching sessions for user %s: %s", user_id, e)
125
+ raise HTTPException(
126
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
127
+ detail="Failed to search sessions",
128
+ ) from e
129
+
130
+
61
131
  @router.get("/sessions/{session_id}", response_model=DataResponse[SessionResponse])
62
132
  async def get_session(
63
133
  session_id: str,
@@ -95,6 +165,7 @@ async def get_session(
95
165
  user_id=session_domain.user_id,
96
166
  name=session_domain.name,
97
167
  agent_id=session_domain.agent_id,
168
+ project_id=session_domain.project_id,
98
169
  created_time=session_domain.created_time,
99
170
  updated_time=session_domain.updated_time,
100
171
  )
@@ -129,7 +200,7 @@ async def save_task(
129
200
  Creates a new task or updates an existing one.
130
201
  """
131
202
  user_id = user.get("id")
132
- log.info(
203
+ log.debug(
133
204
  "User %s attempting to save task %s for session %s",
134
205
  user_id,
135
206
  request.task_id,
@@ -399,12 +470,18 @@ async def update_session_name(
399
470
  user_id=updated_domain.user_id,
400
471
  name=updated_domain.name,
401
472
  agent_id=updated_domain.agent_id,
473
+ project_id=updated_domain.project_id,
402
474
  created_time=updated_domain.created_time,
403
475
  updated_time=updated_domain.updated_time,
404
476
  )
405
477
 
406
478
  except HTTPException:
407
479
  raise
480
+ except ValidationError as e:
481
+ log.warning("Pydantic validation error updating session %s: %s", session_id, e)
482
+ raise HTTPException(
483
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e)
484
+ ) from e
408
485
  except ValueError as e:
409
486
  log.warning("Validation error updating session %s: %s", session_id, e)
410
487
  raise HTTPException(
@@ -430,8 +507,11 @@ async def delete_session(
430
507
  user: dict = Depends(get_current_user),
431
508
  session_service: SessionService = Depends(get_session_business_service),
432
509
  ):
510
+ """
511
+ Soft delete a session (marks as deleted without removing from database).
512
+ """
433
513
  user_id = user.get("id")
434
- log.info("User %s attempting to delete session %s", user_id, session_id)
514
+ log.info("User %s attempting to soft delete session %s", user_id, session_id)
435
515
 
436
516
  try:
437
517
  if (
@@ -452,7 +532,7 @@ async def delete_session(
452
532
  status_code=status.HTTP_404_NOT_FOUND, detail=SESSION_NOT_FOUND_MSG
453
533
  )
454
534
 
455
- log.info("Session %s deleted successfully", session_id)
535
+ log.info("Session %s soft deleted successfully", session_id)
456
536
 
457
537
  except HTTPException:
458
538
  raise
@@ -472,3 +552,83 @@ async def delete_session(
472
552
  status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
473
553
  detail="Failed to delete session",
474
554
  ) from e
555
+
556
+
557
+ @router.patch("/sessions/{session_id}/project", response_model=SessionResponse)
558
+ async def move_session_to_project(
559
+ session_id: str,
560
+ request: MoveSessionRequest,
561
+ db: Session = Depends(get_db),
562
+ user: dict = Depends(get_current_user),
563
+ session_service: SessionService = Depends(get_session_business_service),
564
+ ):
565
+ """
566
+ Move a session to a different project or remove from project.
567
+ When moving to a project, artifacts from that project are immediately copied to the session.
568
+ """
569
+ user_id = user.get("id")
570
+ log.info(
571
+ "User %s attempting to move session %s to project %s",
572
+ user_id,
573
+ session_id,
574
+ request.project_id,
575
+ )
576
+
577
+ try:
578
+ if (
579
+ not session_id
580
+ or session_id.strip() == ""
581
+ or session_id in ["null", "undefined"]
582
+ ):
583
+ raise HTTPException(
584
+ status_code=status.HTTP_404_NOT_FOUND, detail=SESSION_NOT_FOUND_MSG
585
+ )
586
+
587
+ updated_session = await session_service.move_session_to_project(
588
+ db=db,
589
+ session_id=session_id,
590
+ user_id=user_id,
591
+ new_project_id=request.project_id,
592
+ )
593
+
594
+ if not updated_session:
595
+ raise HTTPException(
596
+ status_code=status.HTTP_404_NOT_FOUND, detail=SESSION_NOT_FOUND_MSG
597
+ )
598
+
599
+ log.info(
600
+ "Session %s moved to project %s successfully",
601
+ session_id,
602
+ request.project_id or "None",
603
+ )
604
+
605
+ return SessionResponse(
606
+ id=updated_session.id,
607
+ user_id=updated_session.user_id,
608
+ name=updated_session.name,
609
+ agent_id=updated_session.agent_id,
610
+ project_id=updated_session.project_id,
611
+ created_time=updated_session.created_time,
612
+ updated_time=updated_session.updated_time,
613
+ )
614
+
615
+ except HTTPException:
616
+ raise
617
+ except ValueError as e:
618
+ log.warning("Validation error moving session %s: %s", session_id, e)
619
+ raise HTTPException(
620
+ status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=str(e)
621
+ ) from e
622
+ except Exception as e:
623
+ log.error(
624
+ "Error moving session %s for user %s: %s",
625
+ session_id,
626
+ user_id,
627
+ e,
628
+ )
629
+ raise HTTPException(
630
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
631
+ detail="Failed to move session",
632
+ ) from e
633
+
634
+
@@ -0,0 +1,355 @@
1
+ """
2
+ Speech API routes for STT and TTS functionality.
3
+ """
4
+
5
+ from typing import Optional
6
+ from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile
7
+ from fastapi.responses import StreamingResponse, Response
8
+ from pydantic import BaseModel
9
+
10
+ from solace_ai_connector.common.log import log
11
+
12
+ from ..services.audio_service import AudioService
13
+ from ..dependencies import get_audio_service
14
+ from solace_agent_mesh.shared.api.auth_utils import get_current_user
15
+
16
+
17
+ router = APIRouter()
18
+
19
+
20
+ class TTSRequest(BaseModel):
21
+ """Request model for text-to-speech"""
22
+ input: str
23
+ voice: Optional[str] = None
24
+ messageId: Optional[str] = None
25
+ provider: Optional[str] = None
26
+
27
+
28
+ class StreamTTSRequest(BaseModel):
29
+ """Request model for streaming text-to-speech"""
30
+ input: str
31
+ voice: Optional[str] = None
32
+ runId: Optional[str] = None
33
+ provider: Optional[str] = None
34
+
35
+
36
+ @router.post("/stt")
37
+ async def speech_to_text(
38
+ audio: UploadFile = File(...),
39
+ provider: Optional[str] = Form(None),
40
+ language: Optional[str] = Form(None),
41
+ user: dict = Depends(get_current_user),
42
+ audio_service: AudioService = Depends(get_audio_service)
43
+ ):
44
+ """
45
+ Transcribe audio to text using configured STT service.
46
+
47
+ Args:
48
+ audio: Audio file (wav, mp3, webm, ogg)
49
+ provider: Optional provider override (openai, azure)
50
+ language: Optional language code (e.g., "en-US", "es-ES")
51
+ user: Current authenticated user
52
+ audio_service: Audio service instance
53
+
54
+ Returns:
55
+ JSON with transcribed text:
56
+ {
57
+ "text": "transcribed text",
58
+ "language": "en",
59
+ "duration": 5.2
60
+ }
61
+
62
+ Raises:
63
+ HTTPException: If transcription fails
64
+ """
65
+ log.info(
66
+ "[SpeechAPI] STT request from user=%s, filename=%s, provider=%s, language=%s",
67
+ user.get("user_id"),
68
+ audio.filename,
69
+ provider,
70
+ language
71
+ )
72
+
73
+ try:
74
+ # Validate content type
75
+ if not audio.content_type or not audio.content_type.startswith("audio/"):
76
+ raise HTTPException(
77
+ 415,
78
+ f"Unsupported media type: {audio.content_type}. Expected audio/*"
79
+ )
80
+
81
+ result = await audio_service.transcribe_audio(
82
+ audio_file=audio,
83
+ user_id=user.get("user_id", "anonymous"),
84
+ session_id=user.get("session_id", "default"),
85
+ app_name=user.get("app_name", "webui"),
86
+ provider=provider,
87
+ language=language
88
+ )
89
+
90
+ return result.to_dict()
91
+
92
+ except HTTPException:
93
+ raise
94
+ except Exception as e:
95
+ log.exception("[SpeechAPI] STT error: %s", e)
96
+ raise HTTPException(500, f"Transcription failed: {str(e)}")
97
+
98
+
99
+ @router.post("/tts")
100
+ async def text_to_speech(
101
+ request: TTSRequest,
102
+ user: dict = Depends(get_current_user),
103
+ audio_service: AudioService = Depends(get_audio_service)
104
+ ):
105
+ """
106
+ Convert text to speech using configured TTS service.
107
+
108
+ Args:
109
+ request: TTS request with text and voice
110
+ user: Current authenticated user
111
+ audio_service: Audio service instance
112
+
113
+ Returns:
114
+ Audio data as MP3
115
+
116
+ Raises:
117
+ HTTPException: If generation fails
118
+ """
119
+ log.info(
120
+ "[SpeechAPI] TTS request from user=%s, text_len=%d, voice=%s",
121
+ user.get("user_id"),
122
+ len(request.input),
123
+ request.voice
124
+ )
125
+
126
+ try:
127
+ # Validate input
128
+ if not request.input or not request.input.strip():
129
+ raise HTTPException(400, "Input text is required")
130
+
131
+ if len(request.input) > 10000:
132
+ raise HTTPException(
133
+ 413,
134
+ "Text too long (max 10000 characters). Use /tts/stream for longer text."
135
+ )
136
+
137
+ audio_data = await audio_service.generate_speech(
138
+ text=request.input,
139
+ voice=request.voice,
140
+ user_id=user.get("user_id", "anonymous"),
141
+ session_id=user.get("session_id", "default"),
142
+ app_name=user.get("app_name", "webui"),
143
+ message_id=request.messageId,
144
+ provider=request.provider # NEW: Pass provider from request
145
+ )
146
+
147
+ return Response(
148
+ content=audio_data,
149
+ media_type="audio/mpeg"
150
+ )
151
+
152
+ except HTTPException:
153
+ raise
154
+ except Exception as e:
155
+ log.exception("[SpeechAPI] TTS error: %s", e)
156
+ raise HTTPException(500, f"TTS generation failed: {str(e)}")
157
+
158
+
159
+ @router.post("/tts/stream")
160
+ async def stream_audio(
161
+ request: StreamTTSRequest,
162
+ user: dict = Depends(get_current_user),
163
+ audio_service: AudioService = Depends(get_audio_service)
164
+ ):
165
+ """
166
+ Stream TTS audio for long text (>4096 chars).
167
+ Uses chunking and streaming for better UX.
168
+
169
+ Args:
170
+ request: Stream TTS request with text and voice
171
+ user: Current authenticated user
172
+ audio_service: Audio service instance
173
+
174
+ Returns:
175
+ Streaming audio response
176
+
177
+ Raises:
178
+ HTTPException: If generation fails
179
+ """
180
+ log.info(
181
+ "[SpeechAPI] TTS stream request from user=%s, text_len=%d",
182
+ user.get("user_id"),
183
+ len(request.input)
184
+ )
185
+
186
+ try:
187
+ # Validate input
188
+ if not request.input or not request.input.strip():
189
+ raise HTTPException(400, "Input text is required")
190
+
191
+ # Add max length validation to prevent abuse (100KB max for streaming)
192
+ if len(request.input) > 100000:
193
+ raise HTTPException(
194
+ 413,
195
+ "Text too long (max 100000 characters for streaming)"
196
+ )
197
+
198
+ async def audio_generator():
199
+ async for chunk in audio_service.stream_speech(
200
+ text=request.input,
201
+ voice=request.voice,
202
+ user_id=user.get("user_id", "anonymous"),
203
+ session_id=user.get("session_id", "default"),
204
+ app_name=user.get("app_name", "webui"),
205
+ provider=request.provider # Pass provider from request
206
+ ):
207
+ yield chunk
208
+
209
+ return StreamingResponse(
210
+ audio_generator(),
211
+ media_type="audio/mpeg",
212
+ headers={
213
+ "Content-Disposition": f"inline; filename=tts_stream_{request.runId or 'audio'}.mp3",
214
+ "Cache-Control": "no-cache"
215
+ }
216
+ )
217
+
218
+ except HTTPException:
219
+ raise
220
+ except Exception as e:
221
+ log.exception("[SpeechAPI] TTS stream error: %s", e)
222
+ raise HTTPException(500, f"TTS streaming failed: {str(e)}")
223
+
224
+
225
+ @router.get("/voices")
226
+ async def get_voices(
227
+ provider: Optional[str] = None, # NEW: Accept provider as query parameter
228
+ user: dict = Depends(get_current_user),
229
+ audio_service: AudioService = Depends(get_audio_service)
230
+ ):
231
+ """
232
+ Get available TTS voices based on configuration and provider.
233
+
234
+ Args:
235
+ provider: Optional provider filter (azure, gemini)
236
+ user: Current authenticated user
237
+ audio_service: Audio service instance
238
+
239
+ Returns:
240
+ JSON with available voices:
241
+ {
242
+ "voices": ["Kore", "Puck", "Zephyr", ...],
243
+ "default": "Kore"
244
+ }
245
+ """
246
+ log.debug("[SpeechAPI] Voices request from user=%s, provider=%s", user.get("user_id"), provider)
247
+
248
+ try:
249
+ voices = await audio_service.get_available_voices(provider=provider) # Pass provider
250
+
251
+ # Get default voice from config
252
+ config = audio_service.get_speech_config()
253
+ default_voice = config.get("voice", "Kore")
254
+
255
+ return {
256
+ "voices": voices,
257
+ "default": default_voice
258
+ }
259
+
260
+ except Exception as e:
261
+ log.exception("[SpeechAPI] Error getting voices: %s", e)
262
+ raise HTTPException(500, f"Failed to get voices: {str(e)}")
263
+
264
+
265
+ @router.get("/config")
266
+ async def get_speech_config(
267
+ user: dict = Depends(get_current_user),
268
+ audio_service: AudioService = Depends(get_audio_service)
269
+ ):
270
+ """
271
+ Get speech configuration for frontend initialization.
272
+
273
+ Args:
274
+ user: Current authenticated user
275
+ audio_service: Audio service instance
276
+
277
+ Returns:
278
+ JSON with speech configuration:
279
+ {
280
+ "sttExternal": true,
281
+ "ttsExternal": true,
282
+ "speechToText": true,
283
+ "textToSpeech": true,
284
+ "engineSTT": "external",
285
+ "engineTTS": "external",
286
+ "voice": "Kore",
287
+ "playbackRate": 1.0,
288
+ "cacheTTS": true,
289
+ ...
290
+ }
291
+ """
292
+ log.debug("[SpeechAPI] Config request from user=%s", user.get("user_id"))
293
+
294
+ try:
295
+ config = audio_service.get_speech_config()
296
+ return config
297
+
298
+ except Exception as e:
299
+ log.exception("[SpeechAPI] Error getting config: %s", e)
300
+ raise HTTPException(500, f"Failed to get config: {str(e)}")
301
+
302
+
303
+ @router.post("/voice-sample")
304
+ async def get_voice_sample(
305
+ voice: str = Form(...),
306
+ provider: Optional[str] = Form(None),
307
+ user: dict = Depends(get_current_user),
308
+ audio_service: AudioService = Depends(get_audio_service)
309
+ ):
310
+ """
311
+ Generate a sample audio for a specific voice to preview before selection.
312
+
313
+ Args:
314
+ voice: Voice name to sample
315
+ provider: Optional provider (azure, gemini)
316
+ user: Current authenticated user
317
+ audio_service: Audio service instance
318
+
319
+ Returns:
320
+ Audio data as MP3
321
+
322
+ Raises:
323
+ HTTPException: If generation fails
324
+ """
325
+ log.debug("[SpeechAPI] Voice sample request from user=%s, voice=%s, provider=%s",
326
+ user.get("user_id"), voice, provider)
327
+
328
+ try:
329
+ # Validate voice parameter
330
+ if not voice or not voice.strip():
331
+ raise HTTPException(400, "Voice parameter is required")
332
+
333
+ # Generate a sample text based on provider
334
+ sample_text = "Hello! This is a sample of my voice. I hope you find it pleasant to listen to."
335
+
336
+ audio_data = await audio_service.generate_speech(
337
+ text=sample_text,
338
+ voice=voice,
339
+ user_id=user.get("user_id", "anonymous"),
340
+ session_id=user.get("session_id", "default"),
341
+ app_name=user.get("app_name", "webui"),
342
+ message_id=f"voice_sample_{voice}",
343
+ provider=provider
344
+ )
345
+
346
+ return Response(
347
+ content=audio_data,
348
+ media_type="audio/mpeg"
349
+ )
350
+
351
+ except HTTPException:
352
+ raise
353
+ except Exception as e:
354
+ log.exception("[SpeechAPI] Voice sample error: %s", e)
355
+ raise HTTPException(500, f"Voice sample generation failed: {str(e)}")