solace-agent-mesh 1.7.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 (447) 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/artifacts/filesystem_artifact_service.py +164 -0
  7. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
  8. solace_agent_mesh/agent/adk/callbacks.py +752 -127
  9. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +99 -7
  10. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
  11. solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
  12. solace_agent_mesh/agent/adk/models/lite_llm.py +34 -16
  13. solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
  14. solace_agent_mesh/agent/adk/runner.py +66 -8
  15. solace_agent_mesh/agent/adk/schema_migration.py +88 -0
  16. solace_agent_mesh/agent/adk/services.py +41 -1
  17. solace_agent_mesh/agent/adk/setup.py +220 -32
  18. solace_agent_mesh/agent/adk/stream_parser.py +229 -40
  19. solace_agent_mesh/agent/protocol/event_handlers.py +219 -33
  20. solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
  21. solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
  22. solace_agent_mesh/agent/proxies/base/component.py +188 -22
  23. solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
  24. solace_agent_mesh/agent/sac/app.py +37 -12
  25. solace_agent_mesh/agent/sac/component.py +322 -52
  26. solace_agent_mesh/agent/sac/patch_adk.py +8 -16
  27. solace_agent_mesh/agent/sac/task_execution_context.py +90 -0
  28. solace_agent_mesh/agent/tools/__init__.py +3 -0
  29. solace_agent_mesh/agent/tools/audio_tools.py +3 -3
  30. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +698 -24
  31. solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
  32. solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
  33. solace_agent_mesh/agent/tools/time_tools.py +126 -0
  34. solace_agent_mesh/agent/tools/tool_config_types.py +54 -2
  35. solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
  36. solace_agent_mesh/agent/tools/web_tools.py +125 -17
  37. solace_agent_mesh/agent/utils/artifact_helpers.py +243 -5
  38. solace_agent_mesh/agent/utils/context_helpers.py +17 -0
  39. solace_agent_mesh/assets/docs/404.html +6 -6
  40. solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
  41. solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
  42. solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
  43. solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
  44. solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
  45. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
  46. solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
  47. solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
  48. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
  49. solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
  50. solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
  51. solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
  52. solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
  53. solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
  54. solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
  55. solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
  56. solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
  57. solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
  58. solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
  59. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
  60. solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
  61. solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
  62. solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
  63. solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
  64. solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
  65. solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
  66. solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
  67. solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
  68. solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
  69. solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
  70. solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
  71. solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
  72. solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
  73. solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
  74. solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
  75. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
  76. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
  77. solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
  78. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
  79. solace_agent_mesh/assets/docs/assets/js/e04b235d.06d23db6.js +1 -0
  80. solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
  81. solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
  82. solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
  83. solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
  84. solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
  85. solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
  86. solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
  87. solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
  88. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
  89. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
  90. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
  91. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
  92. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +75 -75
  93. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
  94. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
  95. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
  96. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
  97. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
  98. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
  99. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
  100. solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
  101. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
  102. solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +98 -112
  103. solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
  104. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
  105. solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
  106. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -28
  107. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -29
  108. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
  109. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
  110. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
  111. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +67 -53
  112. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -17
  113. solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
  114. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
  115. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +87 -87
  116. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
  117. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
  118. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
  119. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
  120. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
  121. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
  122. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
  123. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
  124. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
  125. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
  126. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
  127. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
  128. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
  129. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
  130. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
  131. solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +50 -23
  132. solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +29 -24
  133. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +21 -21
  134. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
  135. solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
  136. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +96 -66
  137. solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +181 -181
  138. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +75 -75
  139. solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +27 -27
  140. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +44 -44
  141. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -38
  142. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
  143. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
  144. solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
  145. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +135 -114
  146. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +37 -37
  147. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
  148. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
  149. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
  150. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
  151. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +112 -112
  152. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +28 -28
  153. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +42 -42
  154. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
  155. solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
  156. solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
  157. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  158. solace_agent_mesh/assets/docs/search-doc-1768329217460.json +1 -0
  159. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  160. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  161. solace_agent_mesh/cli/__init__.py +1 -1
  162. solace_agent_mesh/cli/commands/add_cmd/__init__.py +3 -1
  163. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
  164. solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
  165. solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
  166. solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
  167. solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
  168. solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
  169. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
  170. solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
  171. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
  172. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
  173. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
  174. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
  175. solace_agent_mesh/cli/commands/run_cmd.py +64 -49
  176. solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
  177. solace_agent_mesh/cli/main.py +15 -0
  178. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-tcIFZLis.js → authCallback-KnKMP_vb.js} +1 -1
  179. solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
  180. solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
  181. solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
  182. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CINwxvwV.js → vendor-CGk8Suyh.js} +189 -94
  183. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  184. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  185. solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
  186. solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
  187. solace_agent_mesh/common/a2a/types.py +1 -1
  188. solace_agent_mesh/common/agent_registry.py +38 -11
  189. solace_agent_mesh/common/data_parts.py +124 -0
  190. solace_agent_mesh/common/error_handlers.py +83 -0
  191. solace_agent_mesh/common/exceptions.py +24 -0
  192. solace_agent_mesh/common/oauth/__init__.py +17 -0
  193. solace_agent_mesh/common/oauth/oauth_client.py +408 -0
  194. solace_agent_mesh/common/oauth/utils.py +50 -0
  195. solace_agent_mesh/common/rag_dto.py +156 -0
  196. solace_agent_mesh/common/sac/sam_component_base.py +73 -1
  197. solace_agent_mesh/common/sam_events/event_service.py +2 -2
  198. solace_agent_mesh/common/utils/embeds/converter.py +1 -8
  199. solace_agent_mesh/common/utils/embeds/modifiers.py +2 -27
  200. solace_agent_mesh/common/utils/embeds/resolver.py +94 -25
  201. solace_agent_mesh/common/utils/embeds/types.py +1 -0
  202. solace_agent_mesh/common/utils/log_formatters.py +20 -0
  203. solace_agent_mesh/common/utils/mime_helpers.py +12 -5
  204. solace_agent_mesh/common/utils/rbac_utils.py +69 -0
  205. solace_agent_mesh/common/utils/templates/__init__.py +8 -0
  206. solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
  207. solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
  208. solace_agent_mesh/config_portal/backend/common.py +12 -0
  209. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
  210. solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
  211. solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
  212. solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
  213. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
  214. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
  215. solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
  216. solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
  217. solace_agent_mesh/core_a2a/service.py +3 -2
  218. solace_agent_mesh/gateway/adapter/base.py +28 -1
  219. solace_agent_mesh/gateway/adapter/types.py +9 -0
  220. solace_agent_mesh/gateway/base/app.py +10 -0
  221. solace_agent_mesh/gateway/base/auth_interface.py +103 -0
  222. solace_agent_mesh/gateway/base/component.py +451 -10
  223. solace_agent_mesh/gateway/generic/component.py +274 -30
  224. solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
  225. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +2 -43
  226. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +2 -2
  227. solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
  228. solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
  229. solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
  230. solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
  231. solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
  232. solace_agent_mesh/gateway/http_sse/app.py +23 -6
  233. solace_agent_mesh/gateway/http_sse/component.py +158 -73
  234. solace_agent_mesh/gateway/http_sse/dependencies.py +50 -57
  235. solace_agent_mesh/gateway/http_sse/main.py +58 -482
  236. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
  237. solace_agent_mesh/gateway/http_sse/repository/entities/project.py +1 -1
  238. solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +1 -1
  239. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +3 -2
  240. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
  241. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +2 -2
  242. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +2 -2
  243. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +5 -0
  244. solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
  245. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +1 -1
  246. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
  247. solace_agent_mesh/gateway/http_sse/repository/project_repository.py +1 -1
  248. solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +1 -1
  249. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +12 -107
  250. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
  251. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
  252. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +113 -7
  253. solace_agent_mesh/gateway/http_sse/routers/auth.py +69 -132
  254. solace_agent_mesh/gateway/http_sse/routers/config.py +235 -10
  255. solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
  256. solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
  257. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +1 -1
  258. solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
  259. solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +1 -0
  260. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +3 -2
  261. solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
  262. solace_agent_mesh/gateway/http_sse/routers/feedback.py +2 -2
  263. solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
  264. solace_agent_mesh/gateway/http_sse/routers/projects.py +250 -24
  265. solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
  266. solace_agent_mesh/gateway/http_sse/routers/sessions.py +14 -5
  267. solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
  268. solace_agent_mesh/gateway/http_sse/routers/sse.py +117 -4
  269. solace_agent_mesh/gateway/http_sse/routers/tasks.py +509 -149
  270. solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
  271. solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
  272. solace_agent_mesh/gateway/http_sse/routers/visualization.py +2 -1
  273. solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
  274. solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
  275. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
  276. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
  277. solace_agent_mesh/gateway/http_sse/services/project_service.py +539 -12
  278. solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
  279. solace_agent_mesh/gateway/http_sse/services/session_service.py +198 -21
  280. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
  281. solace_agent_mesh/gateway/http_sse/sse_manager.py +280 -169
  282. solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
  283. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
  284. solace_agent_mesh/services/__init__.py +0 -0
  285. solace_agent_mesh/services/platform/__init__.py +29 -0
  286. solace_agent_mesh/services/platform/alembic/env.py +85 -0
  287. solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
  288. solace_agent_mesh/services/platform/alembic.ini +109 -0
  289. solace_agent_mesh/services/platform/api/__init__.py +3 -0
  290. solace_agent_mesh/services/platform/api/dependencies.py +154 -0
  291. solace_agent_mesh/services/platform/api/main.py +314 -0
  292. solace_agent_mesh/services/platform/api/middleware.py +51 -0
  293. solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
  294. solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
  295. solace_agent_mesh/services/platform/app.py +215 -0
  296. solace_agent_mesh/services/platform/component.py +777 -0
  297. solace_agent_mesh/shared/__init__.py +14 -0
  298. solace_agent_mesh/shared/api/__init__.py +42 -0
  299. solace_agent_mesh/shared/auth/__init__.py +26 -0
  300. solace_agent_mesh/shared/auth/dependencies.py +204 -0
  301. solace_agent_mesh/shared/auth/middleware.py +347 -0
  302. solace_agent_mesh/shared/database/__init__.py +20 -0
  303. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
  304. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
  305. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
  306. solace_agent_mesh/shared/exceptions/__init__.py +36 -0
  307. solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +1 -1
  308. solace_agent_mesh/shared/utils/__init__.py +21 -0
  309. solace_agent_mesh/templates/logging_config_template.yaml +48 -0
  310. solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
  311. solace_agent_mesh/templates/platform.yaml +49 -0
  312. solace_agent_mesh/templates/plugin_readme_template.md +3 -25
  313. solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
  314. solace_agent_mesh/templates/proxy_template.yaml +62 -0
  315. solace_agent_mesh/templates/webui.yaml +148 -6
  316. solace_agent_mesh/tools/web_search/__init__.py +18 -0
  317. solace_agent_mesh/tools/web_search/base.py +84 -0
  318. solace_agent_mesh/tools/web_search/google_search.py +247 -0
  319. solace_agent_mesh/tools/web_search/models.py +99 -0
  320. {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +29 -8
  321. {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/RECORD +334 -313
  322. {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
  323. solace_agent_mesh/agent/adk/adk_llm.txt +0 -226
  324. solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
  325. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
  326. solace_agent_mesh/agent/adk/models/models_llm.txt +0 -189
  327. solace_agent_mesh/agent/agent_llm.txt +0 -369
  328. solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
  329. solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
  330. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
  331. solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +0 -190
  332. solace_agent_mesh/agent/proxies/base/base_llm.txt +0 -148
  333. solace_agent_mesh/agent/proxies/proxies_llm.txt +0 -283
  334. solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
  335. solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
  336. solace_agent_mesh/agent/testing/testing_llm.txt +0 -58
  337. solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
  338. solace_agent_mesh/agent/tools/tools_llm.txt +0 -276
  339. solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -275
  340. solace_agent_mesh/agent/utils/utils_llm.txt +0 -152
  341. solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
  342. solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +0 -1
  343. solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +0 -1
  344. solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +0 -1
  345. solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
  346. solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.js +0 -1
  347. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
  348. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +0 -1
  349. solace_agent_mesh/assets/docs/assets/js/3ac1795d.e4870a49.js +0 -1
  350. solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +0 -1
  351. solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +0 -1
  352. solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
  353. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +0 -1
  354. solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +0 -1
  355. solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +0 -1
  356. solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
  357. solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +0 -1
  358. solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
  359. solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
  360. solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
  361. solace_agent_mesh/assets/docs/assets/js/94e8668d.09ed9234.js +0 -1
  362. solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
  363. solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
  364. solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +0 -1
  365. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
  366. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +0 -1
  367. solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +0 -1
  368. solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +0 -1
  369. solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +0 -1
  370. solace_agent_mesh/assets/docs/assets/js/e6f9706b.045d0fa1.js +0 -1
  371. solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +0 -1
  372. solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +0 -1
  373. solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +0 -2
  374. solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +0 -1
  375. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +0 -47
  376. solace_agent_mesh/assets/docs/lunr-index-1762283454666.json +0 -1
  377. solace_agent_mesh/assets/docs/search-doc-1762283454666.json +0 -1
  378. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
  379. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
  380. solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
  381. solace_agent_mesh/client/webui/frontend/static/assets/client-CRYdKo2Q.js +0 -25
  382. solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +0 -1
  383. solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +0 -353
  384. solace_agent_mesh/common/a2a/a2a_llm.txt +0 -175
  385. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
  386. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -445
  387. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
  388. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -330
  389. solace_agent_mesh/common/common_llm.txt +0 -230
  390. solace_agent_mesh/common/common_llm_detail.txt +0 -2562
  391. solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
  392. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
  393. solace_agent_mesh/common/sac/sac_llm.txt +0 -71
  394. solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
  395. solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
  396. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
  397. solace_agent_mesh/common/services/providers/providers_llm.txt +0 -81
  398. solace_agent_mesh/common/services/services_llm.txt +0 -368
  399. solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
  400. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
  401. solace_agent_mesh/common/utils/utils_llm.txt +0 -335
  402. solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
  403. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
  404. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
  405. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
  406. solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
  407. solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
  408. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
  409. solace_agent_mesh/gateway/base/base_llm.txt +0 -226
  410. solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
  411. solace_agent_mesh/gateway/gateway_llm.txt +0 -369
  412. solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
  413. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -345
  414. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +0 -92
  415. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -161
  416. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
  417. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
  418. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
  419. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -221
  420. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -257
  421. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -308
  422. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -450
  423. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -133
  424. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -123
  425. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -312
  426. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -303
  427. solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
  428. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -319
  429. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
  430. solace_agent_mesh/llm.txt +0 -228
  431. solace_agent_mesh/llm_detail.txt +0 -2835
  432. solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
  433. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
  434. solace_agent_mesh/templates/logging_config_template.ini +0 -45
  435. solace_agent_mesh/templates/templates_llm.txt +0 -147
  436. /solace_agent_mesh/assets/docs/assets/js/{main.f213fe0c.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
  437. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
  438. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
  439. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
  440. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
  441. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
  442. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
  443. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
  444. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
  445. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
  446. {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
  447. {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,303 @@
1
+ """
2
+ AI Assistant for Prompt Template Builder.
3
+ Manages conversational prompt template creation through natural language.
4
+ """
5
+
6
+ import json
7
+ import logging
8
+ import os
9
+ import re
10
+ from typing import Dict, Any, List, Optional
11
+ from pydantic import BaseModel, Field
12
+ from litellm import acompletion
13
+ from sqlalchemy.orm import Session
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class PromptBuilderResponse(BaseModel):
19
+ """Response from the prompt builder assistant."""
20
+ message: str
21
+ template_updates: Dict[str, Any] = Field(default_factory=dict)
22
+ confidence: float = Field(ge=0.0, le=1.0)
23
+ ready_to_save: bool = False
24
+
25
+
26
+ class PromptBuilderAssistant:
27
+ """
28
+ AI assistant for prompt template creation.
29
+ Manages conversation flow and template generation.
30
+ """
31
+
32
+ SYSTEM_PROMPT = """You are an AI assistant helping users create reusable prompt templates.
33
+
34
+ CRITICAL RULES:
35
+ 1. You MUST respond with valid JSON in this exact format - NO EXCEPTIONS
36
+ 2. You MUST always include a "message" field with a helpful, conversational response
37
+ 3. NEVER respond with just "I understand" - always provide actionable guidance
38
+ 4. ONLY create placeholders for DATA that changes (names, paths, dates, numbers, specific values)
39
+ 5. Keep instructions, steps, requirements, and process descriptions as FIXED TEXT
40
+ 6. Use descriptive variable names in Title Case (e.g., {{File Path}}, {{Module Name}})
41
+ 7. Suggest appropriate categories (Development, Analysis, Documentation, Communication, Testing, etc.)
42
+ 8. Generate short command names (lowercase, hyphens only)
43
+
44
+ RESPONSE FORMAT (REQUIRED):
45
+ {{
46
+ "message": "your conversational response here - MUST be helpful and specific",
47
+ "template_updates": {{
48
+ "name": "Name",
49
+ "category": "Category",
50
+ "command": "command-name",
51
+ "promptText": "Template with {{placeholders}} for variable data only",
52
+ "description": "Brief description"
53
+ }},
54
+ "confidence": 0.0-1.0,
55
+ "ready_to_save": false
56
+ }}
57
+
58
+ VARIABLE PLACEHOLDER RULES:
59
+ - Use {{Variable Name}} format for placeholders (Title Case with spaces)
60
+ - ONLY for data that changes: file paths, names, dates, numbers, specific values
61
+ - NOT for instructions, steps, or requirements
62
+ - Use descriptive names: {{File Path}}, {{Module Name}}, {{Task Description}}
63
+
64
+ EXAMPLES:
65
+
66
+ Example 1: Code Review Template
67
+ User: "I need a template for code reviews"
68
+ {{
69
+ "message": "Great! I'll create a code review template. What information changes each time you do a code review? For example: file path, module name, specific concerns?",
70
+ "template_updates": {{
71
+ "name": "Code Review Template",
72
+ "category": "Development"
73
+ }},
74
+ "confidence": 0.6,
75
+ "ready_to_save": false
76
+ }}
77
+
78
+ User: "The file path, module name, and specific security concerns"
79
+ {{
80
+ "message": "Perfect! I've created a code review template with placeholders for file path, module name, and security concerns. Check the preview on the left!",
81
+ "template_updates": {{
82
+ "name": "Code Review Template",
83
+ "category": "Development",
84
+ "command": "code-review",
85
+ "promptText": "Review the {{Module Name}} module located at {{File Path}}.\\n\\nPlease perform a comprehensive code review focusing on:\\n1. Security vulnerabilities\\n2. Error handling\\n3. Code quality and best practices\\n4. Specific attention to: {{Security Concerns}}\\n\\nProvide a detailed report with:\\n- List of issues with severity levels\\n- Specific code snippets that need attention\\n- Recommendations for improvements",
86
+ "description": "Template for code review with security focus"
87
+ }},
88
+ "confidence": 0.9,
89
+ "ready_to_save": true
90
+ }}
91
+
92
+ Example 2: Bug Report Template
93
+ User: "Create a bug report template"
94
+ {{
95
+ "message": "I'll create a bug report template! What details vary for each bug report? For example: bug description, steps to reproduce, expected vs actual behavior?",
96
+ "template_updates": {{
97
+ "name": "Bug Report Template",
98
+ "category": "Testing"
99
+ }},
100
+ "confidence": 0.6,
101
+ "ready_to_save": false
102
+ }}
103
+
104
+ User: "Bug description, steps to reproduce, and environment details"
105
+ {{
106
+ "message": "Excellent! I've created a bug report template with those placeholders. You can see it in the preview!",
107
+ "template_updates": {{
108
+ "name": "Bug Report Template",
109
+ "category": "Testing",
110
+ "command": "bug-report",
111
+ "promptText": "# Bug Report\\n\\n## Description\\n{{Bug Description}}\\n\\n## Steps to Reproduce\\n{{Steps To Reproduce}}\\n\\n## Environment\\n{{Environment Details}}\\n\\n## Expected Behavior\\nDescribe what should happen\\n\\n## Actual Behavior\\nDescribe what actually happens\\n\\n## Additional Context\\nAny other relevant information",
112
+ "description": "Template for reporting bugs with structured format"
113
+ }},
114
+ "confidence": 0.9,
115
+ "ready_to_save": true
116
+ }}
117
+
118
+ REMEMBER:
119
+ - Ask clarifying questions to understand what data changes
120
+ - Create detailed, useful templates
121
+ - Only use placeholders for variable data
122
+ - Keep instructions and structure as fixed text
123
+ - Set ready_to_save to true when template is complete
124
+ """
125
+
126
+ def __init__(self, db: Optional[Session] = None, model_config: Optional[Dict[str, Any]] = None):
127
+ """Initialize the assistant with model configuration from component config."""
128
+ self.system_prompt = self.SYSTEM_PROMPT
129
+ self.db = db
130
+
131
+ # Get LLM configuration from provided config
132
+ if not model_config or not isinstance(model_config, dict):
133
+ raise ValueError("model_config is required and must be a dictionary")
134
+
135
+ if not model_config.get("model"):
136
+ raise ValueError("model_config must contain 'model' key")
137
+
138
+ self.model = model_config.get("model")
139
+ self.api_base = model_config.get("api_base")
140
+ self.api_key = model_config.get("api_key", "dummy")
141
+
142
+ def _get_existing_commands(self, user_id: str) -> List[str]:
143
+ """Get list of existing command shortcuts to avoid conflicts."""
144
+ if not self.db:
145
+ return []
146
+
147
+ try:
148
+ from ..repository.models import PromptGroupModel
149
+
150
+ groups = self.db.query(PromptGroupModel).filter(
151
+ PromptGroupModel.user_id == user_id,
152
+ PromptGroupModel.command.isnot(None)
153
+ ).all()
154
+
155
+ return [group.command for group in groups if group.command]
156
+ except Exception as e:
157
+ logger.error(f"Error fetching existing commands: {e}")
158
+ return []
159
+
160
+ async def process_message(
161
+ self,
162
+ user_message: str,
163
+ conversation_history: List[Dict[str, str]],
164
+ current_template: Dict[str, Any],
165
+ user_id: Optional[str] = None
166
+ ) -> PromptBuilderResponse:
167
+ """
168
+ Process user message and update template using LLM.
169
+
170
+ Args:
171
+ user_message: The user's message
172
+ conversation_history: Previous conversation messages
173
+ current_template: Current template configuration
174
+
175
+ Returns:
176
+ PromptBuilderResponse with updates
177
+ """
178
+ try:
179
+ return await self._llm_response(
180
+ user_message,
181
+ conversation_history,
182
+ current_template,
183
+ user_id
184
+ )
185
+ except Exception as e:
186
+ logger.error(f"Error processing message: {e}", exc_info=True)
187
+ return PromptBuilderResponse(
188
+ message="I encountered an error. Could you please rephrase that?",
189
+ confidence=0.0,
190
+ ready_to_save=False
191
+ )
192
+
193
+ async def _llm_response(
194
+ self,
195
+ user_message: str,
196
+ conversation_history: List[Dict[str, str]],
197
+ current_template: Dict[str, Any],
198
+ user_id: Optional[str] = None
199
+ ) -> PromptBuilderResponse:
200
+ """Use LLM to generate response and template updates."""
201
+
202
+ # Get existing commands to avoid conflicts
203
+ existing_commands = []
204
+ if user_id and self.db:
205
+ existing_commands = self._get_existing_commands(user_id)
206
+
207
+ # Build messages for LLM
208
+ messages = [
209
+ {"role": "system", "content": self.system_prompt}
210
+ ]
211
+
212
+ # Add conversation history
213
+ messages.extend(conversation_history)
214
+
215
+ # Add current message with template context and existing commands
216
+ template_context = f"\n\nCurrent Template:\n{json.dumps(current_template, indent=2)}"
217
+
218
+ commands_context = ""
219
+ if existing_commands:
220
+ commands_context = f"\n\nEXISTING COMMANDS (avoid these):\n{', '.join(['/' + cmd for cmd in existing_commands])}"
221
+
222
+ messages.append({
223
+ "role": "user",
224
+ "content": user_message + template_context + commands_context
225
+ })
226
+
227
+ # Call LLM with JSON mode
228
+ try:
229
+ completion_args = {
230
+ "model": self.model,
231
+ "messages": messages,
232
+ "response_format": {"type": "json_object"},
233
+ "temperature": 0.1, # Low temperature for consistency
234
+ }
235
+
236
+ if self.api_base:
237
+ completion_args["api_base"] = self.api_base
238
+ if self.api_key:
239
+ completion_args["api_key"] = self.api_key
240
+
241
+ response = await acompletion(**completion_args)
242
+
243
+ # Parse response
244
+ content = response.choices[0].message.content
245
+ logger.info(f"LLM Response: {content}")
246
+
247
+ try:
248
+ parsed = json.loads(content)
249
+ except json.JSONDecodeError as e:
250
+ logger.error(f"Failed to parse LLM response as JSON: {e}")
251
+ logger.error(f"Response content: {content}")
252
+ # Try to extract JSON from response
253
+ json_match = re.search(r'\{.*\}', content, re.DOTALL)
254
+ if json_match:
255
+ parsed = json.loads(json_match.group())
256
+ else:
257
+ raise
258
+
259
+ # Handle nested response structure (some LLMs wrap in various keys)
260
+ if "response" in parsed and isinstance(parsed["response"], dict):
261
+ logger.info("Unwrapping nested 'response' structure from LLM")
262
+ parsed = parsed["response"]
263
+
264
+ # Handle case where LLM wraps response in an arbitrary key (e.g., "{}", "result", etc.)
265
+ # If we don't have a "message" key but have exactly one key with a dict value containing "message"
266
+ if "message" not in parsed and len(parsed) == 1:
267
+ single_key = list(parsed.keys())[0]
268
+ if isinstance(parsed[single_key], dict) and "message" in parsed[single_key]:
269
+ logger.info(f"Unwrapping nested structure from key '{single_key}'")
270
+ parsed = parsed[single_key]
271
+
272
+ # Validate that we have a proper message
273
+ message = parsed.get("message", "")
274
+ if not message or message.strip().lower() in ["i understand", "i understand.", "ok", "okay"]:
275
+ logger.warning(f"LLM returned generic/empty message: '{message}'")
276
+ message = "I'll help you create that template. Could you provide more details about what information changes each time you use this prompt?"
277
+
278
+ return PromptBuilderResponse(
279
+ message=message,
280
+ template_updates=parsed.get("template_updates", {}),
281
+ confidence=parsed.get("confidence", 0.5),
282
+ ready_to_save=parsed.get("ready_to_save", False)
283
+ )
284
+
285
+ except Exception as e:
286
+ logger.error(f"LLM call failed: {e}", exc_info=True)
287
+ # Fallback response with helpful guidance
288
+ return PromptBuilderResponse(
289
+ message="I'm having trouble processing that. Could you describe what you'd like this template to do? For example, what task are you trying to automate or what information changes each time?",
290
+ confidence=0.3,
291
+ ready_to_save=False
292
+ )
293
+
294
+ def get_initial_greeting(self) -> PromptBuilderResponse:
295
+ """Get the initial greeting message."""
296
+ return PromptBuilderResponse(
297
+ message="Hi! I'll help you create a prompt template. You can either:\n\n"
298
+ "1. Describe a recurring task you'd like to template\n"
299
+ "2. Paste an example transcript of the task\n\n"
300
+ "What would you like to create a template for?",
301
+ confidence=1.0,
302
+ ready_to_save=False
303
+ )
@@ -9,11 +9,12 @@ from ..repository import (
9
9
  Session,
10
10
  )
11
11
  from ..repository.chat_task_repository import ChatTaskRepository
12
+ from ..repository.task_repository import TaskRepository
12
13
  from ..repository.entities import ChatTask
13
- from ..shared.enums import SenderType
14
- from ..shared.types import SessionId, UserId
15
- from ..shared import now_epoch_ms
16
- from ..shared.pagination import PaginationParams, PaginatedResponse, get_pagination_or_default
14
+ from solace_agent_mesh.shared.utils.enums import SenderType
15
+ from solace_agent_mesh.shared.utils.types import SessionId, UserId
16
+ from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
17
+ from solace_agent_mesh.shared.api.pagination import PaginationParams, PaginatedResponse, get_pagination_or_default
17
18
 
18
19
  log = logging.getLogger(__name__)
19
20
 
@@ -46,7 +47,7 @@ class SessionService:
46
47
  project_id: str | None = None
47
48
  ) -> PaginatedResponse[Session]:
48
49
  """
49
- Get paginated sessions for a user with full metadata including project names.
50
+ Get paginated sessions for a user with full metadata including project names and background task status.
50
51
  Uses default pagination if none provided (page 1, size 20).
51
52
  Returns paginated response with pageNumber, pageSize, nextPage, totalPages, totalCount.
52
53
 
@@ -81,6 +82,63 @@ class SessionService:
81
82
  if session.project_id:
82
83
  session.project_name = project_map.get(session.project_id)
83
84
 
85
+ # Check for running background tasks in these sessions
86
+ task_repo = TaskRepository()
87
+ session_ids = [s.id for s in sessions]
88
+
89
+ # Get all running background tasks for this user
90
+ running_bg_tasks = task_repo.find_background_tasks_by_status(db, status=None)
91
+ running_bg_tasks = [
92
+ task for task in running_bg_tasks
93
+ if task.status in [None, "running", "pending"] and task.end_time is None and task.user_id == user_id
94
+ ]
95
+
96
+ log.info(f"[get_user_sessions] Found {len(running_bg_tasks)} running background tasks for user {user_id}")
97
+
98
+ # Create a map of session_id -> has_running_background_task
99
+ # Query ChatTaskModel to find which sessions these tasks belong to
100
+ # Also filter out tasks that have been marked as completed in their metadata
101
+ from ..repository.models import ChatTaskModel
102
+ import json
103
+ session_task_map = {}
104
+ if running_bg_tasks:
105
+ task_ids = [task.id for task in running_bg_tasks]
106
+ log.info(f"[get_user_sessions] Looking up chat tasks for task IDs: {task_ids}")
107
+
108
+ # Query chat tasks for these task IDs
109
+ chat_tasks = db.query(ChatTaskModel).filter(
110
+ ChatTaskModel.id.in_(task_ids),
111
+ ChatTaskModel.user_id == user_id
112
+ ).all()
113
+
114
+ log.info(f"[get_user_sessions] Found {len(chat_tasks)} chat tasks")
115
+
116
+ for chat_task in chat_tasks:
117
+ if chat_task.session_id:
118
+ # Check if task metadata indicates completion
119
+ is_completed = False
120
+ if chat_task.task_metadata:
121
+ try:
122
+ metadata = json.loads(chat_task.task_metadata) if isinstance(chat_task.task_metadata, str) else chat_task.task_metadata
123
+ task_status = metadata.get("status")
124
+ is_completed = task_status in ["completed", "error", "failed"]
125
+ log.info(f"[get_user_sessions] Task {chat_task.id} metadata status: {task_status}, is_completed: {is_completed}")
126
+ except Exception as e:
127
+ log.warning(f"[get_user_sessions] Failed to parse task metadata for {chat_task.id}: {e}")
128
+
129
+ # Only mark session as having running task if task is not completed
130
+ if not is_completed:
131
+ session_task_map[chat_task.session_id] = True
132
+ log.debug(f"[get_user_sessions] Session {chat_task.session_id} has running background task {chat_task.id}")
133
+ else:
134
+ log.debug(f"[get_user_sessions] Task {chat_task.id} is completed, not marking session as having running task")
135
+
136
+ # Add background task status to sessions
137
+ for session in sessions:
138
+ session.has_running_background_task = session_task_map.get(session.id, False)
139
+ if session.has_running_background_task:
140
+ log.info(f"[get_user_sessions] Marking session {session.id} as having running background task")
141
+
84
142
  return PaginatedResponse.create(sessions, total_count, pagination)
85
143
 
86
144
  def get_session_details(
@@ -229,21 +287,24 @@ class SessionService:
229
287
  log.info("Session %s soft deleted successfully by user %s", session_id, user_id)
230
288
  return True
231
289
 
232
- def move_session_to_project(
290
+ async def move_session_to_project(
233
291
  self, db: DbSession, session_id: SessionId, user_id: UserId, new_project_id: str | None
234
292
  ) -> Session | None:
235
293
  """
236
294
  Move a session to a different project.
237
-
295
+
296
+ When moving to a project, this also copies all project artifacts to the session
297
+ so they are immediately available without waiting for the next user message.
298
+
238
299
  Args:
239
300
  db: Database session
240
301
  session_id: Session ID to move
241
302
  user_id: User ID performing the move
242
303
  new_project_id: New project ID (or None to remove from project)
243
-
304
+
244
305
  Returns:
245
306
  Session: Updated session if successful, None otherwise
246
-
307
+
247
308
  Raises:
248
309
  ValueError: If session or project validation fails
249
310
  """
@@ -258,13 +319,13 @@ class SessionService:
258
319
  ProjectModel.user_id == user_id,
259
320
  ProjectModel.deleted_at.is_(None)
260
321
  ).first()
261
-
322
+
262
323
  if not project:
263
324
  raise ValueError(f"Project {new_project_id} not found or access denied")
264
325
 
265
326
  session_repository = self._get_repositories(db)
266
327
  updated_session = session_repository.move_to_project(db, session_id, user_id, new_project_id)
267
-
328
+
268
329
  if not updated_session:
269
330
  log.warning(
270
331
  "Failed to move session %s to project %s for user %s",
@@ -274,12 +335,63 @@ class SessionService:
274
335
  )
275
336
  return None
276
337
 
277
- log.info(
278
- "Session %s moved to project %s by user %s",
279
- session_id,
280
- new_project_id or "None",
281
- user_id,
282
- )
338
+ try:
339
+ db.commit()
340
+ log.info(
341
+ "Session %s moved to project %s by user %s",
342
+ session_id,
343
+ new_project_id or "None",
344
+ user_id,
345
+ )
346
+ except Exception as e:
347
+ db.rollback()
348
+ log.error(
349
+ "Failed to commit session move for session %s: %s",
350
+ session_id,
351
+ e,
352
+ )
353
+ raise
354
+
355
+ # Copy project artifacts to session immediately when moving to a project
356
+ if new_project_id and self.component:
357
+ from ..utils.artifact_copy_utils import copy_project_artifacts_to_session
358
+ from ..services.project_service import ProjectService
359
+ from ..dependencies import SessionLocal
360
+
361
+ if SessionLocal:
362
+ artifact_db = SessionLocal()
363
+ try:
364
+ project_service = ProjectService(component=self.component)
365
+ log_prefix = f"[move_session_to_project session_id={session_id}] "
366
+
367
+ artifacts_copied, _ = await copy_project_artifacts_to_session(
368
+ project_id=new_project_id,
369
+ user_id=user_id,
370
+ session_id=session_id,
371
+ project_service=project_service,
372
+ component=self.component,
373
+ db=artifact_db,
374
+ log_prefix=log_prefix,
375
+ )
376
+
377
+ if artifacts_copied > 0:
378
+ log.info(
379
+ "%sCopied %d project artifacts to session during move",
380
+ log_prefix,
381
+ artifacts_copied,
382
+ )
383
+ except Exception as e:
384
+ # Don't fail the move operation if artifact copying fails
385
+ # The session move has already been committed at this point
386
+ log.warning(
387
+ "Failed to copy project artifacts when moving session %s to project %s: %s",
388
+ session_id,
389
+ new_project_id,
390
+ e,
391
+ )
392
+ finally:
393
+ artifact_db.close()
394
+
283
395
  return updated_session
284
396
 
285
397
  def search_sessions(
@@ -291,15 +403,15 @@ class SessionService:
291
403
  project_id: str | None = None
292
404
  ) -> PaginatedResponse[Session]:
293
405
  """
294
- Search sessions by name or content.
295
-
406
+ Search sessions by name/title only.
407
+
296
408
  Args:
297
409
  db: Database session
298
410
  user_id: User ID to filter sessions by
299
411
  query: Search query string
300
412
  pagination: Pagination parameters
301
413
  project_id: Optional project ID to filter sessions by
302
-
414
+
303
415
  Returns:
304
416
  PaginatedResponse[Session]: Paginated search results
305
417
  """
@@ -328,6 +440,63 @@ class SessionService:
328
440
  if session.project_id:
329
441
  session.project_name = project_map.get(session.project_id)
330
442
 
443
+ # Check for running background tasks in these sessions
444
+ task_repo = TaskRepository()
445
+ session_ids = [s.id for s in sessions]
446
+
447
+ # Get all running background tasks for this user
448
+ running_bg_tasks = task_repo.find_background_tasks_by_status(db, status=None)
449
+ running_bg_tasks = [
450
+ task for task in running_bg_tasks
451
+ if task.status in [None, "running", "pending"] and task.end_time is None and task.user_id == user_id
452
+ ]
453
+
454
+ log.info(f"[search_sessions] Found {len(running_bg_tasks)} running background tasks for user {user_id}")
455
+
456
+ # Create a map of session_id -> has_running_background_task
457
+ # Query ChatTaskModel to find which sessions these tasks belong to
458
+ # Also filter out tasks that have been marked as completed in their metadata
459
+ from ..repository.models import ChatTaskModel
460
+ import json
461
+ session_task_map = {}
462
+ if running_bg_tasks:
463
+ task_ids = [task.id for task in running_bg_tasks]
464
+ log.info(f"[search_sessions] Looking up chat tasks for task IDs: {task_ids}")
465
+
466
+ # Query chat tasks for these task IDs
467
+ chat_tasks = db.query(ChatTaskModel).filter(
468
+ ChatTaskModel.id.in_(task_ids),
469
+ ChatTaskModel.user_id == user_id
470
+ ).all()
471
+
472
+ log.info(f"[search_sessions] Found {len(chat_tasks)} chat tasks")
473
+
474
+ for chat_task in chat_tasks:
475
+ if chat_task.session_id:
476
+ # Check if task metadata indicates completion
477
+ is_completed = False
478
+ if chat_task.task_metadata:
479
+ try:
480
+ metadata = json.loads(chat_task.task_metadata) if isinstance(chat_task.task_metadata, str) else chat_task.task_metadata
481
+ task_status = metadata.get("status")
482
+ is_completed = task_status in ["completed", "error", "failed"]
483
+ log.info(f"[search_sessions] Task {chat_task.id} metadata status: {task_status}, is_completed: {is_completed}")
484
+ except Exception as e:
485
+ log.warning(f"[search_sessions] Failed to parse task metadata for {chat_task.id}: {e}")
486
+
487
+ # Only mark session as having running task if task is not completed
488
+ if not is_completed:
489
+ session_task_map[chat_task.session_id] = True
490
+ log.info(f"[search_sessions] Session {chat_task.session_id} has running background task {chat_task.id}")
491
+ else:
492
+ log.info(f"[search_sessions] Task {chat_task.id} is completed, not marking session as having running task")
493
+
494
+ # Add background task status to sessions
495
+ for session in sessions:
496
+ session.has_running_background_task = session_task_map.get(session.id, False)
497
+ if session.has_running_background_task:
498
+ log.info(f"[search_sessions] Marking session {session.id} as having running background task")
499
+
331
500
  log.info(
332
501
  "Search for '%s' by user %s returned %d results (total: %d)",
333
502
  query,
@@ -423,7 +592,15 @@ class SessionService:
423
592
 
424
593
  # Load tasks
425
594
  task_repo = ChatTaskRepository()
426
- return task_repo.find_by_session(db, session_id, user_id)
595
+ tasks = task_repo.find_by_session(db, session_id, user_id)
596
+
597
+ # Note: Deduplication logic was removed because the root cause of duplicate
598
+ # artifact markers has been fixed in task_logger_service.py. The fix ensures
599
+ # that when reconstructing chat messages for background tasks, existing
600
+ # versioned markers (e.g., «artifact_return:report.md:0») are properly
601
+ # detected and prevent adding duplicate non-versioned markers.
602
+
603
+ return tasks
427
604
 
428
605
  def get_session_messages_from_tasks(
429
606
  self,