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
@@ -4,6 +4,7 @@ Base Component class for Gateway implementations in the Solace AI Connector.
4
4
 
5
5
  import logging
6
6
  import asyncio
7
+ import base64
7
8
  import queue
8
9
  import re
9
10
  import uuid
@@ -21,7 +22,9 @@ from ...common.services.identity_service import (
21
22
  create_identity_service,
22
23
  )
23
24
  from .task_context import TaskContextManager
25
+ from .auth_interface import AuthHandler
24
26
  from ...common.a2a.types import ContentPart
27
+ from ...common.utils.rbac_utils import validate_agent_access
25
28
  from a2a.types import (
26
29
  Message as A2AMessage,
27
30
  AgentCard,
@@ -33,6 +36,7 @@ from a2a.types import (
33
36
  TextPart,
34
37
  DataPart,
35
38
  FilePart,
39
+ FileWithBytes,
36
40
  Artifact as A2AArtifact,
37
41
  )
38
42
  from ...common import a2a
@@ -41,12 +45,14 @@ from ...common.utils.embeds import (
41
45
  evaluate_embed,
42
46
  LATE_EMBED_TYPES,
43
47
  EARLY_EMBED_TYPES,
48
+ resolve_embeds_recursively_in_string,
44
49
  )
45
50
  from ...common.utils.embeds.types import ResolutionMode
46
51
  from ...agent.utils.artifact_helpers import (
47
52
  load_artifact_content_or_metadata,
48
53
  format_artifact_uri,
49
54
  )
55
+ from ...common.utils.mime_helpers import is_text_based_mime_type
50
56
  from solace_ai_connector.common.message import (
51
57
  Message as SolaceMessage,
52
58
  )
@@ -164,7 +170,9 @@ class BaseGatewayComponent(SamComponentBase):
164
170
 
165
171
  self.agent_registry: AgentRegistry = AgentRegistry()
166
172
  self.core_a2a_service: CoreA2AService = CoreA2AService(
167
- agent_registry=self.agent_registry, namespace=self.namespace
173
+ agent_registry=self.agent_registry,
174
+ namespace=self.namespace,
175
+ component_id="WebUI"
168
176
  )
169
177
  self.shared_artifact_service: Optional[BaseArtifactService] = (
170
178
  initialize_artifact_service(self)
@@ -184,10 +192,65 @@ class BaseGatewayComponent(SamComponentBase):
184
192
  self.log_identifier,
185
193
  )
186
194
 
195
+ # Authentication handler (optional, enterprise feature)
196
+ self.auth_handler: Optional[AuthHandler] = None
197
+
198
+ # Setup authentication if enabled (subclasses override _setup_auth)
199
+ self._setup_auth()
200
+
187
201
  log.info(
188
202
  "%s Initialized Base Gateway Component.", self.log_identifier
189
203
  )
190
204
 
205
+ def _setup_auth(self) -> None:
206
+ """
207
+ Setup authentication handler if enabled.
208
+
209
+ This method is called during initialization and can be overridden
210
+ by subclasses to customize auth setup. The default implementation
211
+ does nothing - subclasses should override to enable auth.
212
+
213
+ Example override in subclass:
214
+ def _setup_auth(self):
215
+ if self.get_config('enable_auth', False):
216
+ from enterprise.auth import SAMOAuth2Handler
217
+ self.auth_handler = SAMOAuth2Handler(self.config)
218
+ """
219
+ # Base implementation: no auth
220
+ # Subclasses (like GenericGateway) override to enable auth
221
+ pass
222
+
223
+ async def _inject_auth_headers(self, headers: Dict[str, str]) -> Dict[str, str]:
224
+ """
225
+ Inject authentication headers if authenticated.
226
+
227
+ This helper method should be called before making outgoing HTTP requests
228
+ to add authentication headers (e.g., Bearer tokens) to the request.
229
+
230
+ Args:
231
+ headers: Existing headers dictionary
232
+
233
+ Returns:
234
+ Headers dictionary with auth headers added (if authenticated)
235
+
236
+ Example:
237
+ headers = {"Content-Type": "application/json"}
238
+ headers = await self._inject_auth_headers(headers)
239
+ # headers now includes Authorization if authenticated
240
+ """
241
+ if self.auth_handler:
242
+ try:
243
+ auth_headers = await self.auth_handler.get_auth_headers()
244
+ headers.update(auth_headers)
245
+ except Exception as e:
246
+ log.warning(
247
+ "%s Failed to get auth headers: %s",
248
+ self.log_identifier,
249
+ e
250
+ )
251
+
252
+ return headers
253
+
191
254
  async def authenticate_and_enrich_user(
192
255
  self, external_event_data: Any
193
256
  ) -> Optional[Dict[str, Any]]:
@@ -285,6 +348,17 @@ class BaseGatewayComponent(SamComponentBase):
285
348
 
286
349
  user_config["user_profile"] = user_identity
287
350
 
351
+ # Validate user has permission to access this target agent
352
+ validate_agent_access(
353
+ user_config=user_config,
354
+ target_agent_name=target_agent_name,
355
+ validation_context={
356
+ "gateway_id": self.gateway_id,
357
+ "source": "gateway_request",
358
+ },
359
+ log_identifier=log_id_prefix,
360
+ )
361
+
288
362
  external_request_context["user_identity"] = user_identity
289
363
  external_request_context["a2a_user_config"] = user_config
290
364
  external_request_context["api_version"] = api_version
@@ -328,6 +402,15 @@ class BaseGatewayComponent(SamComponentBase):
328
402
  "system_purpose": system_purpose,
329
403
  "response_format": response_format,
330
404
  }
405
+
406
+ # Add session behavior if provided by adapter
407
+ session_behavior = external_request_context.get("session_behavior")
408
+ if session_behavior:
409
+ a2a_metadata["sessionBehavior"] = session_behavior
410
+ log.debug(
411
+ "%s Setting sessionBehavior to: %s", log_id_prefix, session_behavior
412
+ )
413
+
331
414
  invoked_artifacts = external_request_context.get("invoked_with_artifacts")
332
415
  if invoked_artifacts:
333
416
  a2a_metadata["invoked_with_artifacts"] = invoked_artifacts
@@ -628,11 +711,24 @@ class BaseGatewayComponent(SamComponentBase):
628
711
  )
629
712
  continue
630
713
 
714
+ # Resolve any late embeds inside the artifact content before returning.
715
+ content_bytes = await self._resolve_embeds_in_artifact_content(
716
+ content_bytes=content_bytes,
717
+ mime_type=artifact_data.get("metadata", {}).get(
718
+ "mime_type"
719
+ ),
720
+ filename=filename,
721
+ external_request_context=external_request_context,
722
+ log_id_prefix=log_id_prefix,
723
+ )
724
+
631
725
  # Create FilePart with bytes for legacy gateway to upload
632
726
  file_part = a2a.create_file_part_from_bytes(
633
727
  content_bytes=content_bytes,
634
728
  name=filename,
635
- mime_type=artifact_data.get("metadata", {}).get("mime_type"),
729
+ mime_type=artifact_data.get("metadata", {}).get(
730
+ "mime_type"
731
+ ),
636
732
  )
637
733
 
638
734
  # Create artifact with the file part
@@ -792,6 +888,123 @@ class BaseGatewayComponent(SamComponentBase):
792
888
  log.exception(
793
889
  "%s Error sending artifact creation completion signal: %s", log_id_prefix, e
794
890
  )
891
+ elif signal_type == "SIGNAL_DEEP_RESEARCH_REPORT":
892
+ # Handle deep research report signal for legacy gateways
893
+ # For legacy gateways, we send the report as a file attachment
894
+ if is_finalizing_context:
895
+ log.debug(
896
+ "%s Suppressing SIGNAL_DEEP_RESEARCH_REPORT during finalizing context to avoid duplicate: %s",
897
+ log_id_prefix,
898
+ signal_data,
899
+ )
900
+ continue
901
+
902
+ try:
903
+ filename = signal_data.get("filename")
904
+ version = signal_data.get("version")
905
+
906
+ if not filename:
907
+ log.error(
908
+ "%s SIGNAL_DEEP_RESEARCH_REPORT missing filename. Skipping.",
909
+ log_id_prefix,
910
+ )
911
+ continue
912
+
913
+ # Load artifact content for legacy gateways
914
+ artifact_data = await load_artifact_content_or_metadata(
915
+ self.shared_artifact_service,
916
+ app_name=external_request_context.get(
917
+ "app_name_for_artifacts", self.gateway_id
918
+ ),
919
+ user_id=external_request_context.get("user_id_for_artifacts"),
920
+ session_id=external_request_context.get("a2a_session_id"),
921
+ filename=filename,
922
+ version=version,
923
+ load_metadata_only=False,
924
+ )
925
+
926
+ if artifact_data.get("status") != "success":
927
+ log.error(
928
+ "%s Failed to load deep research report content for %s v%s",
929
+ log_id_prefix,
930
+ filename,
931
+ version,
932
+ )
933
+ continue
934
+
935
+ content = artifact_data.get("content")
936
+ if not content:
937
+ log.error(
938
+ "%s No content found in deep research report %s v%s",
939
+ log_id_prefix,
940
+ filename,
941
+ version,
942
+ )
943
+ continue
944
+
945
+ # Convert to bytes if it's a string
946
+ if isinstance(content, str):
947
+ content_bytes = content.encode("utf-8")
948
+ elif isinstance(content, bytes):
949
+ content_bytes = content
950
+ else:
951
+ log.error(
952
+ "%s Deep research report content is neither string nor bytes: %s",
953
+ log_id_prefix,
954
+ type(content),
955
+ )
956
+ continue
957
+
958
+ # Create FilePart with bytes for legacy gateway to upload
959
+ file_part = a2a.create_file_part_from_bytes(
960
+ content_bytes=content_bytes,
961
+ name=filename,
962
+ mime_type=artifact_data.get("metadata", {}).get(
963
+ "mime_type", "text/markdown"
964
+ ),
965
+ )
966
+
967
+ # Create artifact with the file part
968
+ from a2a.types import Artifact, Part
969
+ artifact = Artifact(
970
+ artifact_id=str(uuid.uuid4().hex),
971
+ parts=[Part(root=file_part)],
972
+ name=filename,
973
+ description=f"Deep Research Report: {filename}",
974
+ )
975
+
976
+ # Send as TaskArtifactUpdateEvent
977
+ a2a_task_id_for_signal = external_request_context.get(
978
+ "a2a_task_id_for_event", original_rpc_id
979
+ )
980
+
981
+ if not a2a_task_id_for_signal:
982
+ log.error(
983
+ "%s Cannot determine A2A task ID for deep research report signal. Skipping.",
984
+ log_id_prefix,
985
+ )
986
+ continue
987
+
988
+ artifact_event = a2a.create_artifact_update(
989
+ task_id=a2a_task_id_for_signal,
990
+ context_id=external_request_context.get("a2a_session_id"),
991
+ artifact=artifact,
992
+ )
993
+
994
+ await self._send_update_to_external(
995
+ external_request_context=external_request_context,
996
+ event_data=artifact_event,
997
+ is_final_chunk_of_update=False,
998
+ )
999
+ log.info(
1000
+ "%s Sent deep research report as TaskArtifactUpdateEvent for %s",
1001
+ log_id_prefix,
1002
+ filename,
1003
+ )
1004
+ except Exception as e:
1005
+ log.exception(
1006
+ "%s Error sending deep research report signal: %s", log_id_prefix, e
1007
+ )
795
1008
  else:
796
1009
  log.warning(
797
1010
  "%s Received unhandled signal type during embed resolution: %s",
@@ -799,10 +1012,80 @@ class BaseGatewayComponent(SamComponentBase):
799
1012
  signal_type,
800
1013
  )
801
1014
 
802
- async def _resolve_uri_in_file_part(self, file_part: FilePart):
1015
+ async def _resolve_embeds_in_artifact_content(
1016
+ self,
1017
+ content_bytes: bytes,
1018
+ mime_type: Optional[str],
1019
+ filename: str,
1020
+ external_request_context: Dict[str, Any],
1021
+ log_id_prefix: str,
1022
+ ) -> bytes:
1023
+ """
1024
+ Checks if content is text-based and, if so, resolves late embeds within it.
1025
+ Returns the (potentially modified) content as bytes.
1026
+ """
1027
+ if is_text_based_mime_type(mime_type):
1028
+ log.info(
1029
+ "%s Artifact '%s' is text-based (%s). Resolving late embeds.",
1030
+ log_id_prefix,
1031
+ filename,
1032
+ mime_type,
1033
+ )
1034
+ try:
1035
+ decoded_content = content_bytes.decode("utf-8")
1036
+
1037
+ # Construct context and config for the resolver
1038
+ embed_eval_context = {
1039
+ "artifact_service": self.shared_artifact_service,
1040
+ "session_context": {
1041
+ "app_name": external_request_context.get(
1042
+ "app_name_for_artifacts", self.gateway_id
1043
+ ),
1044
+ "user_id": external_request_context.get(
1045
+ "user_id_for_artifacts"
1046
+ ),
1047
+ "session_id": external_request_context.get("a2a_session_id"),
1048
+ },
1049
+ }
1050
+ embed_eval_config = {
1051
+ "gateway_max_artifact_resolve_size_bytes": self.gateway_max_artifact_resolve_size_bytes,
1052
+ "gateway_recursive_embed_depth": self.gateway_recursive_embed_depth,
1053
+ }
1054
+
1055
+ resolved_string = await resolve_embeds_recursively_in_string(
1056
+ text=decoded_content,
1057
+ context=embed_eval_context,
1058
+ resolver_func=evaluate_embed,
1059
+ types_to_resolve=LATE_EMBED_TYPES,
1060
+ resolution_mode=ResolutionMode.RECURSIVE_ARTIFACT_CONTENT,
1061
+ log_identifier=f"{log_id_prefix}[RecursiveResolve]",
1062
+ config=embed_eval_config,
1063
+ max_depth=self.gateway_recursive_embed_depth,
1064
+ )
1065
+ resolved_bytes = resolved_string.encode("utf-8")
1066
+ log.info(
1067
+ "%s Successfully resolved embeds in '%s'. New size: %d bytes.",
1068
+ log_id_prefix,
1069
+ filename,
1070
+ len(resolved_bytes),
1071
+ )
1072
+ return resolved_bytes
1073
+ except Exception as resolve_err:
1074
+ log.error(
1075
+ "%s Failed to resolve embeds within artifact '%s': %s. Returning raw content.",
1076
+ log_id_prefix,
1077
+ filename,
1078
+ resolve_err,
1079
+ )
1080
+ return content_bytes
1081
+
1082
+ async def _resolve_uri_in_file_part(
1083
+ self, file_part: FilePart, external_request_context: Dict[str, Any]
1084
+ ):
803
1085
  """
804
1086
  Checks if a FilePart has a resolvable URI and, if so,
805
1087
  resolves it and mutates the part in-place by calling the common utility.
1088
+ After resolving the URI, it also resolves any late embeds within the content.
806
1089
  """
807
1090
  await a2a.resolve_file_part_uri(
808
1091
  part=file_part,
@@ -810,15 +1093,43 @@ class BaseGatewayComponent(SamComponentBase):
810
1093
  log_identifier=self.log_identifier,
811
1094
  )
812
1095
 
813
- async def _resolve_uris_in_parts_list(self, parts: List[ContentPart]):
1096
+ # After resolving the URI to get the content, resolve any late embeds inside it.
1097
+ if file_part.file and isinstance(file_part.file, FileWithBytes):
1098
+ # The content is a base64 encoded string in the `bytes` attribute.
1099
+ # We need to decode it to raw bytes for processing.
1100
+ try:
1101
+ content_bytes = base64.b64decode(file_part.file.bytes)
1102
+ except Exception as e:
1103
+ log.error(
1104
+ "%s Failed to base64 decode file content for embed resolution: %s",
1105
+ f"{self.log_identifier}[UriResolve]",
1106
+ e,
1107
+ )
1108
+ return
1109
+
1110
+ resolved_bytes = await self._resolve_embeds_in_artifact_content(
1111
+ content_bytes=content_bytes,
1112
+ mime_type=file_part.file.mime_type,
1113
+ filename=file_part.file.name,
1114
+ external_request_context=external_request_context,
1115
+ log_id_prefix=f"{self.log_identifier}[UriResolve]",
1116
+ )
1117
+ # Re-encode the resolved content back to a base64 string for the FileWithBytes model.
1118
+ file_part.file.bytes = base64.b64encode(resolved_bytes).decode("utf-8")
1119
+
1120
+ async def _resolve_uris_in_parts_list(
1121
+ self, parts: List[ContentPart], external_request_context: Dict[str, Any]
1122
+ ):
814
1123
  """Iterates over a list of part objects and resolves any FilePart URIs."""
815
1124
  if not parts:
816
1125
  return
817
1126
  for part in parts:
818
1127
  if isinstance(part, FilePart):
819
- await self._resolve_uri_in_file_part(part)
1128
+ await self._resolve_uri_in_file_part(part, external_request_context)
820
1129
 
821
- async def _resolve_uris_in_payload(self, parsed_event: Any):
1130
+ async def _resolve_uris_in_payload(
1131
+ self, parsed_event: Any, external_request_context: Dict[str, Any]
1132
+ ):
822
1133
  """
823
1134
  Dispatcher that calls the appropriate targeted URI resolver based on the
824
1135
  Pydantic model type of the event.
@@ -842,7 +1153,9 @@ class BaseGatewayComponent(SamComponentBase):
842
1153
  parts_to_resolve.extend(a2a.get_parts_from_artifact(artifact))
843
1154
 
844
1155
  if parts_to_resolve:
845
- await self._resolve_uris_in_parts_list(parts_to_resolve)
1156
+ await self._resolve_uris_in_parts_list(
1157
+ parts_to_resolve, external_request_context
1158
+ )
846
1159
  else:
847
1160
  log.debug(
848
1161
  "%s Payload type '%s' did not yield any parts for URI resolution. Skipping.",
@@ -1095,6 +1408,69 @@ class BaseGatewayComponent(SamComponentBase):
1095
1408
  else:
1096
1409
  # Legacy gateway mode: pass signal through for gateway to handle
1097
1410
  other_signals.append(signal_tuple)
1411
+ elif signal_type == "SIGNAL_DEEP_RESEARCH_REPORT":
1412
+ # Deep research reports should be rendered by the frontend component
1413
+ # For modern gateways (HTTP SSE), create a DataPart with artifact reference
1414
+ # For legacy gateways, pass through as signal
1415
+ if self.supports_inline_artifact_resolution:
1416
+ try:
1417
+ filename = signal_data["filename"]
1418
+ version = signal_data["version"]
1419
+ log.info(
1420
+ "%s Converting SIGNAL_DEEP_RESEARCH_REPORT to DataPart for frontend rendering: %s v%s",
1421
+ log_id_prefix,
1422
+ filename,
1423
+ version,
1424
+ )
1425
+ # Create a DataPart that the frontend can use to render DeepResearchReportBubble
1426
+ # The frontend will fetch the artifact content separately
1427
+ artifact_data = (
1428
+ await load_artifact_content_or_metadata(
1429
+ self.shared_artifact_service,
1430
+ **embed_eval_context["session_context"],
1431
+ filename=filename,
1432
+ version=version,
1433
+ load_metadata_only=True,
1434
+ )
1435
+ )
1436
+ if artifact_data.get("status") == "success":
1437
+ uri = format_artifact_uri(
1438
+ **embed_eval_context["session_context"],
1439
+ filename=filename,
1440
+ version=artifact_data.get("version"),
1441
+ )
1442
+ # Create a DataPart with deep_research_report type
1443
+ # This will be rendered by DeepResearchReportBubble in the frontend
1444
+ data_part = a2a.create_data_part(
1445
+ data={
1446
+ "type": "deep_research_report",
1447
+ "filename": filename,
1448
+ "version": artifact_data.get("version"),
1449
+ "uri": uri,
1450
+ },
1451
+ metadata={"source": "deep_research_tool"},
1452
+ )
1453
+ new_parts.append(data_part)
1454
+ else:
1455
+ new_parts.append(
1456
+ a2a.create_text_part(
1457
+ f"[Error: Deep research report '{filename}' v{version} not found.]"
1458
+ )
1459
+ )
1460
+ except Exception as e:
1461
+ log.exception(
1462
+ "%s Error handling SIGNAL_DEEP_RESEARCH_REPORT: %s",
1463
+ log_id_prefix,
1464
+ e,
1465
+ )
1466
+ new_parts.append(
1467
+ a2a.create_text_part(
1468
+ f"[Error: Could not retrieve deep research report '{signal_data.get('filename')}'.]"
1469
+ )
1470
+ )
1471
+ else:
1472
+ # Legacy gateway mode: pass signal through for gateway to handle
1473
+ other_signals.append(signal_tuple)
1098
1474
  elif signal_type == "SIGNAL_INLINE_BINARY_CONTENT":
1099
1475
  signal_data["content_bytes"] = signal_data.get("bytes")
1100
1476
  del signal_data["bytes"]
@@ -1135,9 +1511,72 @@ class BaseGatewayComponent(SamComponentBase):
1135
1511
  # Handle recursive embeds in text-based FileParts
1136
1512
  new_parts.append(part) # Placeholder for now
1137
1513
  elif isinstance(part, DataPart):
1138
- # Handle artifact creation progress DataParts for legacy gateways
1514
+ # Handle special DataPart types
1139
1515
  data_type = part.data.get("type") if part.data else None
1140
- if (
1516
+
1517
+ if data_type == "template_block":
1518
+ # Resolve template block and replace with resolved text
1519
+ try:
1520
+ from ...common.utils.templates import resolve_template_blocks_in_string
1521
+
1522
+ # Reconstruct the template block syntax
1523
+ data_artifact = part.data.get("data_artifact", "")
1524
+ jsonpath = part.data.get("jsonpath")
1525
+ limit = part.data.get("limit")
1526
+ template_content = part.data.get("template_content", "")
1527
+
1528
+ # Build params string
1529
+ params_parts = [f'data="{data_artifact}"']
1530
+ if jsonpath:
1531
+ params_parts.append(f'jsonpath="{jsonpath}"')
1532
+ if limit is not None:
1533
+ params_parts.append(f'limit="{limit}"')
1534
+ params_str = " ".join(params_parts)
1535
+
1536
+ # Reconstruct full template block
1537
+ template_block = f"«««template: {params_str}\n{template_content}\n»»»"
1538
+
1539
+ log.debug(
1540
+ "%s Resolving template block inline: data=%s",
1541
+ log_id_prefix,
1542
+ data_artifact,
1543
+ )
1544
+
1545
+ # Resolve the template
1546
+ resolved_text = await resolve_template_blocks_in_string(
1547
+ text=template_block,
1548
+ artifact_service=self.shared_artifact_service,
1549
+ session_context={
1550
+ "app_name": external_request_context.get(
1551
+ "app_name_for_artifacts", self.gateway_id
1552
+ ),
1553
+ "user_id": external_request_context.get("user_id_for_artifacts"),
1554
+ "session_id": external_request_context.get("a2a_session_id"),
1555
+ },
1556
+ log_identifier=f"{log_id_prefix}[TemplateResolve]",
1557
+ )
1558
+
1559
+ log.info(
1560
+ "%s Template resolved successfully. Output length: %d",
1561
+ log_id_prefix,
1562
+ len(resolved_text),
1563
+ )
1564
+
1565
+ # Replace the DataPart with a TextPart containing the resolved content
1566
+ new_parts.append(a2a.create_text_part(text=resolved_text))
1567
+
1568
+ except Exception as e:
1569
+ log.error(
1570
+ "%s Failed to resolve template block: %s",
1571
+ log_id_prefix,
1572
+ e,
1573
+ exc_info=True,
1574
+ )
1575
+ # Send error message as TextPart
1576
+ error_text = f"[Template rendering error: {str(e)}]"
1577
+ new_parts.append(a2a.create_text_part(text=error_text))
1578
+
1579
+ elif (
1141
1580
  data_type == "artifact_creation_progress"
1142
1581
  and not self.supports_inline_artifact_resolution
1143
1582
  ):
@@ -1264,7 +1703,9 @@ class BaseGatewayComponent(SamComponentBase):
1264
1703
  "%s Resolving artifact URIs before sending to external...",
1265
1704
  log_id_prefix,
1266
1705
  )
1267
- await self._resolve_uris_in_payload(parsed_event)
1706
+ await self._resolve_uris_in_payload(
1707
+ parsed_event, external_request_context
1708
+ )
1268
1709
 
1269
1710
  send_this_event_to_external = True
1270
1711
  is_final_chunk_of_status_update = False