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
@@ -201,13 +201,13 @@ async def run_adk_async_task_thread_wrapper(
201
201
  llm_limit_e,
202
202
  )
203
203
  except BadRequestError as e:
204
+ exception_to_finalize_with = e
204
205
  log.error(
205
- "%s Bad Request for task %s: %s.",
206
+ "%s Bad Request for task %s: %s. Scheduling finalization.",
206
207
  component.log_identifier,
207
208
  logical_task_id,
208
209
  e.message,
209
210
  )
210
- raise
211
211
  except Exception as e:
212
212
  exception_to_finalize_with = e
213
213
  log.exception(
@@ -261,7 +261,11 @@ async def run_adk_async_task(
261
261
  logical_task_id = a2a_context.get("logical_task_id", "unknown_task")
262
262
  event_loop_stored = False
263
263
  current_loop = asyncio.get_running_loop()
264
- is_paused = False
264
+ # Track pending long-running tools by their function_call IDs
265
+ # This replaces the simple boolean is_paused to properly handle sync returns
266
+ pending_long_running_tools: set[str] = set()
267
+ # Collect synchronous responses from long-running tools for potential re-run
268
+ sync_tool_responses: list[adk_types.Part] = []
265
269
 
266
270
  adk_event_generator = component.runner.run_async(
267
271
  user_id=adk_session.user_id,
@@ -316,7 +320,10 @@ async def run_adk_async_task(
316
320
  break
317
321
 
318
322
  if event.long_running_tool_ids:
319
- is_paused = True
323
+ # Track which long-running tool calls are pending (waiting for async response)
324
+ pending_long_running_tools = pending_long_running_tools.union(
325
+ event.long_running_tool_ids
326
+ )
320
327
 
321
328
  if not event_loop_stored and event.invocation_id:
322
329
  task_context.set_event_loop(current_loop)
@@ -342,8 +349,18 @@ async def run_adk_async_task(
342
349
  if event.content and event.content.parts:
343
350
  for part in event.content.parts:
344
351
  if part.function_response:
345
- if part.function_response.name.startswith("peer_"):
346
- pass
352
+ # Check if this is a sync response from a long-running tool
353
+ # (i.e., the tool returned immediately instead of async)
354
+ response_id = part.function_response.id
355
+ if response_id and response_id in pending_long_running_tools:
356
+ pending_long_running_tools.discard(response_id)
357
+ sync_tool_responses.append(part)
358
+ log.info(
359
+ "%s Long-running tool %s (id=%s) returned synchronously.",
360
+ component.log_identifier,
361
+ part.function_response.name,
362
+ response_id,
363
+ )
347
364
 
348
365
  except TaskCancelledError:
349
366
  raise
@@ -374,14 +391,55 @@ async def run_adk_async_task(
374
391
  f"Task {logical_task_id} was cancelled before finalization."
375
392
  )
376
393
 
377
- if is_paused:
394
+ invocation_id = a2a_context.get("invocation_id")
395
+
396
+ # Check if we still have pending long-running tools (waiting for async responses)
397
+ if pending_long_running_tools:
398
+ # Store any sync responses using the SAME format as event_handlers.py
399
+ # This ensures they're combined with async responses when _retrigger is called
400
+ if sync_tool_responses:
401
+ for part in sync_tool_responses:
402
+ result = {
403
+ "adk_function_call_id": part.function_response.id,
404
+ "peer_tool_name": part.function_response.name,
405
+ "payload": part.function_response.response, # Already a dict from ADK
406
+ }
407
+ task_context.record_parallel_result(result, invocation_id)
408
+ log.info(
409
+ "%s Stored %d sync tool response(s) for later combination. Waiting for: %s",
410
+ component.log_identifier,
411
+ len(sync_tool_responses),
412
+ pending_long_running_tools,
413
+ )
414
+
378
415
  log.info(
379
- "%s ADK run completed by invoking a long-running tool. Task %s will remain open, awaiting peer response.",
416
+ "%s Task %s paused, waiting for %d async tool response(s).",
380
417
  component.log_identifier,
381
418
  logical_task_id,
419
+ len(pending_long_running_tools),
382
420
  )
383
421
  return True
384
422
 
423
+ # All tools returned synchronously - re-run ADK with their responses
424
+ # The ADK already created the Part objects, so we use them directly (no duplication)
425
+ if sync_tool_responses:
426
+ log.info(
427
+ "%s All %d long-running tool(s) returned synchronously for task %s. Re-running ADK.",
428
+ component.log_identifier,
429
+ len(sync_tool_responses),
430
+ logical_task_id,
431
+ )
432
+ # Use the Part objects directly from the ADK (already properly formatted)
433
+ tool_response_content = adk_types.Content(role="tool", parts=sync_tool_responses)
434
+ return await run_adk_async_task(
435
+ component=component,
436
+ task_context=task_context,
437
+ adk_session=adk_session,
438
+ adk_content=tool_response_content,
439
+ run_config=run_config,
440
+ a2a_context=a2a_context,
441
+ )
442
+
385
443
  log.debug(
386
444
  "%s ADK run_async completed for task %s. Returning to wrapper for finalization.",
387
445
  component.log_identifier,
@@ -0,0 +1,88 @@
1
+ """
2
+ ADK Database Schema Migrations
3
+
4
+ Automatically runs Alembic migrations on agent startup to ensure
5
+ database schema compatibility with the installed ADK version.
6
+
7
+ This uses Google ADK's official migration approach via Alembic's
8
+ autogenerate feature to detect and apply schema changes.
9
+ """
10
+
11
+ import logging
12
+ import re
13
+ from pathlib import Path
14
+ from alembic.config import Config
15
+ from alembic import command
16
+
17
+ log = logging.getLogger(__name__)
18
+
19
+
20
+ def run_migrations(db_service, component):
21
+ """
22
+ Run Alembic database migrations programmatically.
23
+
24
+ Executes any pending migrations to ensure the database schema
25
+ matches ADK's model definitions. This is equivalent to running:
26
+ alembic upgrade head
27
+
28
+ Args:
29
+ db_service: DatabaseSessionService instance
30
+ component: Component that owns this service (for logging)
31
+
32
+ Raises:
33
+ RuntimeError: If migration fails
34
+ """
35
+
36
+ try:
37
+ # Get paths to alembic directory and config
38
+ module_dir = Path(__file__).parent
39
+ alembic_ini = module_dir / "alembic.ini"
40
+ alembic_dir = module_dir / "alembic"
41
+
42
+ # Verify files exist
43
+ if not alembic_ini.exists():
44
+ log.warning(
45
+ "%s alembic.ini not found at %s, skipping migration",
46
+ component.log_identifier,
47
+ alembic_ini
48
+ )
49
+ return
50
+
51
+ if not alembic_dir.exists():
52
+ log.warning(
53
+ "%s alembic/ directory not found at %s, skipping migration",
54
+ component.log_identifier,
55
+ alembic_dir
56
+ )
57
+ return
58
+
59
+ # Create Alembic config
60
+ alembic_cfg = Config(str(alembic_ini))
61
+ alembic_cfg.set_main_option("script_location", str(alembic_dir))
62
+
63
+ # IMPORTANT: Store the engine in config attributes so env.py can access it
64
+ # This avoids URL encoding issues entirely
65
+ alembic_cfg.attributes['connection'] = db_service.db_engine
66
+
67
+ log.info(
68
+ "%s Running Alembic migrations for ADK schema compatibility...",
69
+ component.log_identifier
70
+ )
71
+
72
+ # Run migrations (equivalent to: alembic upgrade head)
73
+ # Run migrations (env.py will use the engine from attributes)
74
+ command.upgrade(alembic_cfg, "head")
75
+
76
+ log.info(
77
+ "%s Database schema migration complete",
78
+ component.log_identifier
79
+ )
80
+
81
+ except Exception as e:
82
+ log.error(
83
+ "%s Database migration failed: %s",
84
+ component.log_identifier,
85
+ e
86
+ )
87
+ raise RuntimeError(f"ADK database migration failed: {e}") from e
88
+
@@ -12,6 +12,7 @@ from google.adk.artifacts import (
12
12
  GcsArtifactService,
13
13
  InMemoryArtifactService,
14
14
  )
15
+ from google.adk.artifacts.base_artifact_service import ArtifactVersion
15
16
  from google.adk.auth.credential_service.base_credential_service import (
16
17
  BaseCredentialService,
17
18
  )
@@ -33,6 +34,7 @@ from google.genai import types as adk_types
33
34
  from typing_extensions import override
34
35
 
35
36
  from .artifacts.filesystem_artifact_service import FilesystemArtifactService
37
+ from .schema_migration import run_migrations
36
38
 
37
39
  log = logging.getLogger(__name__)
38
40
 
@@ -156,6 +158,42 @@ class ScopedArtifactServiceWrapper(BaseArtifactService):
156
158
  filename=filename,
157
159
  )
158
160
 
161
+ @override
162
+ async def list_artifact_versions(
163
+ self,
164
+ *,
165
+ app_name: str,
166
+ user_id: str,
167
+ filename: str,
168
+ session_id: str,
169
+ ) -> List[ArtifactVersion]:
170
+ scoped_app_name = self._get_scoped_app_name(app_name)
171
+ return await self.wrapped_service.list_artifact_versions(
172
+ app_name=scoped_app_name,
173
+ user_id=user_id,
174
+ filename=filename,
175
+ session_id=session_id,
176
+ )
177
+
178
+ @override
179
+ async def get_artifact_version(
180
+ self,
181
+ *,
182
+ app_name: str,
183
+ user_id: str,
184
+ filename: str,
185
+ session_id: str,
186
+ version: Optional[int] = None,
187
+ ) -> Optional[ArtifactVersion]:
188
+ scoped_app_name = self._get_scoped_app_name(app_name)
189
+ return await self.wrapped_service.get_artifact_version(
190
+ app_name=scoped_app_name,
191
+ user_id=user_id,
192
+ filename=filename,
193
+ session_id=session_id,
194
+ version=version,
195
+ )
196
+
159
197
 
160
198
  def _sanitize_for_path(identifier: str) -> str:
161
199
  """Sanitizes a string to be safe for use as a directory name."""
@@ -195,7 +233,9 @@ def initialize_session_service(component) -> BaseSessionService:
195
233
  f"{component.log_identifier} 'database_url' is required for sql session service."
196
234
  )
197
235
  try:
198
- return DatabaseSessionService(db_url=db_url)
236
+ db_service = DatabaseSessionService(db_url=db_url)
237
+ run_migrations(db_service, component)
238
+ return db_service
199
239
  except ImportError:
200
240
  log.error(
201
241
  "%s SQLAlchemy not installed. Please install 'google-adk[database]' or 'sqlalchemy'.",
@@ -5,7 +5,19 @@ Handles ADK Agent and Runner initialization, including tool loading and callback
5
5
  import functools
6
6
  import inspect
7
7
  import logging
8
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Set, Tuple, Type, Union
8
+ import os
9
+ from typing import (
10
+ TYPE_CHECKING,
11
+ Any,
12
+ Callable,
13
+ Dict,
14
+ List,
15
+ Optional,
16
+ Set,
17
+ Tuple,
18
+ Type,
19
+ Union,
20
+ )
9
21
 
10
22
  from google.adk import tools as adk_tools_module
11
23
  from google.adk.agents.callback_context import CallbackContext
@@ -14,6 +26,7 @@ from google.adk.models.llm_request import LlmRequest
14
26
  from google.adk.models.llm_response import LlmResponse
15
27
  from google.adk.runners import Runner
16
28
  from google.adk.tools import BaseTool, ToolContext
29
+ from google.adk.tools.mcp_tool import MCPTool
17
30
  from google.adk.tools.mcp_tool.mcp_session_manager import (
18
31
  SseServerParams,
19
32
  StdioConnectionParams,
@@ -29,8 +42,8 @@ from ..tools.dynamic_tool import DynamicTool, DynamicToolProvider
29
42
  from ..tools.registry import tool_registry
30
43
  from ..tools.tool_config_types import (
31
44
  AnyToolConfig,
32
- BuiltinToolConfig,
33
45
  BuiltinGroupToolConfig,
46
+ BuiltinToolConfig,
34
47
  McpToolConfig,
35
48
  PythonToolConfig,
36
49
  )
@@ -483,7 +496,16 @@ async def _load_builtin_group_tool(component: "SamAgentComponent", tool_config:
483
496
  loaded_tools: List[Union[BaseTool, Callable]] = []
484
497
  enabled_builtin_tools: List[BuiltinTool] = []
485
498
  for tool_def in tools_in_group:
499
+ # Try to get tool-specific config, but fall back to the entire tool_config
500
+ # This allows both patterns:
501
+ # 1. tool_config with keys at top level (e.g., api_key: "xxx")
502
+ # 2. tool_config with nested configs per tool (e.g., tool_name: {api_key: "xxx"})
486
503
  specific_tool_config = tool_config_model.tool_config.get(tool_def.name)
504
+ if specific_tool_config is None:
505
+ # No tool-specific config found, use the entire tool_config
506
+ # This is the common case for groups where all tools share the same config
507
+ specific_tool_config = tool_config_model.tool_config
508
+
487
509
  tool_callable = ADKToolWrapper(
488
510
  tool_def.implementation,
489
511
  specific_tool_config,
@@ -501,6 +523,35 @@ async def _load_builtin_group_tool(component: "SamAgentComponent", tool_config:
501
523
  )
502
524
  return loaded_tools, enabled_builtin_tools, []
503
525
 
526
+ def validate_filesystem_path(path, log_identifier=""):
527
+ """
528
+ Validates that a filesystem path exists and is accessible.
529
+
530
+ Args:
531
+ path: The filesystem path to validate
532
+ log_identifier: Optional identifier for logging
533
+
534
+ Returns:
535
+ bool: True if the path exists and is accessible, False otherwise
536
+
537
+ Raises:
538
+ ValueError: If the path doesn't exist or isn't accessible
539
+ """
540
+ if not path:
541
+ raise ValueError(f"{log_identifier} Filesystem path is empty or None")
542
+
543
+ if not os.path.exists(path):
544
+ raise ValueError(f"{log_identifier} Filesystem path does not exist: {path}")
545
+
546
+ if not os.path.isdir(path):
547
+ raise ValueError(f"{log_identifier} Filesystem path is not a directory: {path}")
548
+
549
+ # Check if the directory is readable and writable
550
+ if not os.access(path, os.R_OK | os.W_OK):
551
+ raise ValueError(f"{log_identifier} Filesystem path is not readable and writable: {path}")
552
+
553
+ return True
554
+
504
555
  async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> ToolLoadingResult:
505
556
  """Loads an MCP toolset based on connection parameters."""
506
557
  from pydantic import TypeAdapter
@@ -548,6 +599,31 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
548
599
  raise ValueError(
549
600
  f"MCP tool 'args' parameter must be a list, got {type(args_list)}"
550
601
  )
602
+
603
+ # Check if this is the filesystem MCP server
604
+ if args_list and any("@modelcontextprotocol/server-filesystem" in arg for arg in args_list):
605
+ # Find the index of the server-filesystem argument
606
+ server_fs_index = -1
607
+ for i, arg in enumerate(args_list):
608
+ if "@modelcontextprotocol/server-filesystem" in arg:
609
+ server_fs_index = i
610
+ break
611
+
612
+ # All arguments after server-filesystem are directory paths
613
+ if server_fs_index >= 0 and server_fs_index + 1 < len(args_list):
614
+ directory_paths = args_list[server_fs_index + 1:]
615
+
616
+ for path in directory_paths:
617
+ try:
618
+ validate_filesystem_path(path, log_identifier=component.log_identifier)
619
+ log.info(
620
+ "%s Validated filesystem path for MCP server: %s",
621
+ component.log_identifier,
622
+ path
623
+ )
624
+ except ValueError as e:
625
+ log.error("%s", str(e))
626
+ raise ValueError(f"MCP filesystem server path validation failed: {e}")
551
627
  final_connection_args = {
552
628
  k: v
553
629
  for k, v in connection_args.items()
@@ -570,14 +646,30 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
570
646
  else:
571
647
  raise ValueError(f"Unsupported MCP connection type: {connection_type}")
572
648
 
573
- tool_filter_list = (
574
- [tool_config_model.tool_name] if tool_config_model.tool_name else None
575
- )
576
- if tool_filter_list:
649
+ # Determine tool filter based on configuration
650
+ # tool_name, allow_list, and deny_list are mutually exclusive (validated by pydantic)
651
+ tool_filter = None
652
+ filter_description = "none (all tools)"
653
+
654
+ if tool_config_model.tool_name:
655
+ # Backward compatible: single tool name becomes a list
656
+ tool_filter = [tool_config_model.tool_name]
657
+ filter_description = f"tool_name='{tool_config_model.tool_name}'"
658
+ elif tool_config_model.allow_list:
659
+ # Allow list: pass directly as list of tool names
660
+ tool_filter = tool_config_model.allow_list
661
+ filter_description = f"allow_list={tool_config_model.allow_list}"
662
+ elif tool_config_model.deny_list:
663
+ # Deny list: create a ToolPredicate that excludes these tools
664
+ deny_set = set(tool_config_model.deny_list)
665
+ tool_filter = lambda tool, ctx=None, _deny=deny_set: tool.name not in _deny
666
+ filter_description = f"deny_list={tool_config_model.deny_list}"
667
+
668
+ if tool_filter:
577
669
  log.info(
578
- "%s MCP tool config specifies tool_name: '%s'. Applying as tool_filter.",
670
+ "%s MCP tool config specifies filter: %s",
579
671
  component.log_identifier,
580
- tool_config_model.tool_name,
672
+ filter_description,
581
673
  )
582
674
 
583
675
  additional_params = {}
@@ -592,7 +684,7 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
592
684
  tool_type="mcp",
593
685
  tool_config=tool_config,
594
686
  connection_params=connection_params,
595
- tool_filter=tool_filter_list,
687
+ tool_filter=tool_filter,
596
688
  )
597
689
  except Exception as e:
598
690
  log.error(
@@ -609,7 +701,8 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
609
701
  # Create the EmbedResolvingMCPToolset with base parameters
610
702
  toolset_params = {
611
703
  "connection_params": connection_params,
612
- "tool_filter": tool_filter_list,
704
+ "tool_filter": tool_filter,
705
+ "tool_name_prefix": tool_config_model.tool_name_prefix,
613
706
  "tool_config": tool_config,
614
707
  }
615
708
 
@@ -620,14 +713,86 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
620
713
  mcp_toolset_instance.origin = "mcp"
621
714
 
622
715
  log.info(
623
- "%s Initialized MCPToolset (filter: %s) for server: %s",
624
- component.log_identifier,
625
- (tool_filter_list if tool_filter_list else "none (all tools)"),
626
- connection_params,
716
+ "%s Initialized MCPToolset (filter: %s) for server: %s",
717
+ component.log_identifier,
718
+ filter_description,
719
+ connection_params,
627
720
  )
628
721
 
629
722
  return [mcp_toolset_instance], [], []
630
723
 
724
+
725
+ async def _load_openapi_tool(component: "SamAgentComponent", tool_config: Dict) -> ToolLoadingResult:
726
+ """
727
+ Loads an OpenAPI toolset by delegating to the enterprise configurator.
728
+
729
+ This function validates the tool configuration and attempts to load the OpenAPI tool
730
+ using the enterprise package. If the enterprise package is not available, it logs a
731
+ warning and returns empty results.
732
+
733
+ Args:
734
+ component: The SamAgentComponent instance
735
+ tool_config: Dictionary containing the tool's configuration
736
+
737
+ Returns:
738
+ ToolLoadingResult: Tuple of (tools, builtins, cleanup_hooks)
739
+ Returns ([], [], []) if enterprise package not available
740
+ """
741
+ from pydantic import TypeAdapter
742
+
743
+ from ..tools.tool_config_types import OpenApiToolConfig
744
+
745
+ # Validate basic tool configuration structure
746
+ openapi_tool_adapter = TypeAdapter(OpenApiToolConfig)
747
+ try:
748
+ tool_config_model = openapi_tool_adapter.validate_python(tool_config)
749
+ except Exception as e:
750
+ log.error(
751
+ "%s Invalid OpenAPI tool configuration: %s",
752
+ component.log_identifier,
753
+ e,
754
+ )
755
+ raise
756
+
757
+ # Try to load the tool using the enterprise configurator
758
+ try:
759
+ from solace_agent_mesh_enterprise.auth.tool_configurator import (
760
+ configure_openapi_tool,
761
+ )
762
+
763
+ try:
764
+ openapi_toolset = configure_openapi_tool(
765
+ tool_type="openapi",
766
+ tool_config=tool_config,
767
+ )
768
+ openapi_toolset.origin = "openapi"
769
+
770
+ log.info(
771
+ "%s Loaded OpenAPI toolset via enterprise configurator",
772
+ component.log_identifier,
773
+ )
774
+
775
+ return [openapi_toolset], [], []
776
+
777
+ except Exception as e:
778
+ log.error(
779
+ "%s Failed to create OpenAPI tool %s: %s",
780
+ component.log_identifier,
781
+ tool_config.get("name", "unknown"),
782
+ e,
783
+ )
784
+ raise
785
+
786
+ except ImportError:
787
+ log.warning(
788
+ "%s OpenAPI tools require the solace-agent-mesh-enterprise package. "
789
+ "Skipping tool configuration: %s",
790
+ component.log_identifier,
791
+ tool_config.get("name", "unknown"),
792
+ )
793
+ return [], [], []
794
+
795
+
631
796
  def _load_internal_tools(component: "SamAgentComponent", loaded_tool_names: Set[str]) -> ToolLoadingResult:
632
797
  """Loads internal framework tools that are not explicitly configured by the user."""
633
798
  loaded_tools: List[Union[BaseTool, Callable]] = []
@@ -749,6 +914,12 @@ async def load_adk_tools(
749
914
  new_builtins,
750
915
  new_cleanups,
751
916
  ) = await _load_mcp_tool(component, tool_config)
917
+ elif tool_type == "openapi":
918
+ (
919
+ new_tools,
920
+ new_builtins,
921
+ new_cleanups,
922
+ ) = await _load_openapi_tool(component, tool_config)
752
923
  else:
753
924
  log.warning(
754
925
  "%s Unknown tool type '%s' in config: %s",
@@ -761,19 +932,7 @@ async def load_adk_tools(
761
932
  for tool in new_tools:
762
933
  if isinstance(tool, EmbedResolvingMCPToolset):
763
934
  # Special handling for MCPToolset which can load multiple tools
764
- try:
765
- mcp_tools = await tool.get_tools()
766
- for mcp_tool in mcp_tools:
767
- _check_and_register_tool_name(
768
- mcp_tool.name, "mcp", loaded_tool_names
769
- )
770
- except Exception as e:
771
- log.error(
772
- "%s Failed to discover tools from MCP server for name registration: %s",
773
- component.log_identifier,
774
- str(e),
775
- )
776
- raise
935
+ await _check_and_register_tool_name_mcp(component, loaded_tool_names, tool)
777
936
  else:
778
937
  tool_name = getattr(
779
938
  tool, "name", getattr(tool, "__name__", None)
@@ -817,6 +976,25 @@ async def load_adk_tools(
817
976
  return loaded_tools, enabled_builtin_tools, cleanup_hooks
818
977
 
819
978
 
979
+ async def _check_and_register_tool_name_mcp(component, loaded_tool_names: set[str], tool: EmbedResolvingMCPToolset):
980
+ try:
981
+ mcp_tools: list[MCPTool] = await tool.get_tools()
982
+ for mcp_tool in mcp_tools:
983
+ toolname = mcp_tool.name
984
+ if tool.tool_name_prefix != None:
985
+ toolname = f"{tool.tool_name_prefix}_{toolname}"
986
+ _check_and_register_tool_name(
987
+ toolname, "mcp", loaded_tool_names
988
+ )
989
+ except Exception as e:
990
+ log.error(
991
+ "%s Failed to discover tools from MCP server for name registration: %s",
992
+ component.log_identifier,
993
+ str(e),
994
+ )
995
+ raise
996
+
997
+
820
998
  def initialize_adk_agent(
821
999
  component,
822
1000
  loaded_explicit_tools: List[Union[BaseTool, Callable]],
@@ -1089,7 +1267,17 @@ def initialize_adk_agent(
1089
1267
  # The callbacks are executed in the order they are added to this list.
1090
1268
  callbacks_in_order_for_after_model = []
1091
1269
 
1092
- # 1. Fenced Artifact Block Processing (must run before auto-continue)
1270
+ # 1. Pre-register long-running tools (must run BEFORE tool execution)
1271
+ preregister_cb = functools.partial(
1272
+ adk_callbacks.preregister_long_running_tools_callback, host_component=component
1273
+ )
1274
+ callbacks_in_order_for_after_model.append(preregister_cb)
1275
+ log.debug(
1276
+ "%s Added preregister_long_running_tools_callback to after_model chain.",
1277
+ component.log_identifier,
1278
+ )
1279
+
1280
+ # 2. Fenced Artifact Block Processing (must run before auto-continue)
1093
1281
  artifact_block_cb = functools.partial(
1094
1282
  adk_callbacks.process_artifact_blocks_callback, host_component=component
1095
1283
  )
@@ -1099,7 +1287,7 @@ def initialize_adk_agent(
1099
1287
  component.log_identifier,
1100
1288
  )
1101
1289
 
1102
- # 2. Auto-Continuation (may short-circuit the chain)
1290
+ # 3. Auto-Continuation (may short-circuit the chain)
1103
1291
  auto_continue_cb = functools.partial(
1104
1292
  adk_callbacks.auto_continue_on_max_tokens_callback, host_component=component
1105
1293
  )
@@ -1109,13 +1297,13 @@ def initialize_adk_agent(
1109
1297
  component.log_identifier,
1110
1298
  )
1111
1299
 
1112
- # 3. Solace LLM Response Logging
1300
+ # 4. Solace LLM Response Logging
1113
1301
  solace_llm_response_cb = functools.partial(
1114
1302
  adk_callbacks.solace_llm_response_callback, host_component=component
1115
1303
  )
1116
1304
  callbacks_in_order_for_after_model.append(solace_llm_response_cb)
1117
1305
 
1118
- # 4. Chunk Logging
1306
+ # 5. Chunk Logging
1119
1307
  log_chunk_cb = functools.partial(
1120
1308
  adk_callbacks.log_streaming_chunk_callback, host_component=component
1121
1309
  )
@@ -1190,4 +1378,4 @@ def initialize_adk_runner(component) -> Runner:
1190
1378
  return runner
1191
1379
  except Exception as e:
1192
1380
  log.error("%s Failed to create ADK Runner: %s", component.log_identifier, e)
1193
- raise
1381
+ raise