solace-agent-mesh 1.6.1__py3-none-any.whl → 1.13.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (481) hide show
  1. solace_agent_mesh/agent/adk/alembic/README +74 -0
  2. solace_agent_mesh/agent/adk/alembic/env.py +77 -0
  3. solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
  4. solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
  5. solace_agent_mesh/agent/adk/alembic.ini +112 -0
  6. solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
  7. solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +165 -1
  8. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
  9. solace_agent_mesh/agent/adk/callbacks.py +852 -109
  10. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +234 -36
  11. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
  12. solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
  13. solace_agent_mesh/agent/adk/models/lite_llm.py +77 -21
  14. solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
  15. solace_agent_mesh/agent/adk/runner.py +85 -20
  16. solace_agent_mesh/agent/adk/schema_migration.py +88 -0
  17. solace_agent_mesh/agent/adk/services.py +94 -18
  18. solace_agent_mesh/agent/adk/setup.py +281 -65
  19. solace_agent_mesh/agent/adk/stream_parser.py +231 -37
  20. solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
  21. solace_agent_mesh/agent/protocol/event_handlers.py +472 -137
  22. solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
  23. solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
  24. solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
  25. solace_agent_mesh/agent/proxies/base/app.py +3 -2
  26. solace_agent_mesh/agent/proxies/base/component.py +188 -22
  27. solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
  28. solace_agent_mesh/agent/sac/app.py +91 -3
  29. solace_agent_mesh/agent/sac/component.py +591 -157
  30. solace_agent_mesh/agent/sac/patch_adk.py +8 -16
  31. solace_agent_mesh/agent/sac/task_execution_context.py +146 -4
  32. solace_agent_mesh/agent/tools/__init__.py +3 -0
  33. solace_agent_mesh/agent/tools/audio_tools.py +3 -3
  34. solace_agent_mesh/agent/tools/builtin_artifact_tools.py +710 -171
  35. solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
  36. solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
  37. solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
  38. solace_agent_mesh/agent/tools/time_tools.py +126 -0
  39. solace_agent_mesh/agent/tools/tool_config_types.py +57 -2
  40. solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
  41. solace_agent_mesh/agent/tools/web_tools.py +125 -17
  42. solace_agent_mesh/agent/utils/artifact_helpers.py +248 -6
  43. solace_agent_mesh/agent/utils/context_helpers.py +17 -0
  44. solace_agent_mesh/assets/docs/404.html +6 -6
  45. solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
  46. solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
  47. solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
  48. solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
  49. solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
  50. solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
  51. solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
  52. solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
  53. solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
  54. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
  55. solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
  56. solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
  57. solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
  58. solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
  59. solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
  60. solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
  61. solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
  62. solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
  63. solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
  64. solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
  65. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
  66. solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
  67. solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
  68. solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
  69. solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
  70. solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
  71. solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
  72. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
  73. solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
  74. solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
  75. solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
  76. solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
  77. solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
  78. solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
  79. solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
  80. solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
  81. solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
  82. solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
  83. solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
  84. solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
  85. solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
  86. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
  87. solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
  88. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
  89. solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
  90. solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
  91. solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
  92. solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
  93. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
  94. solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
  95. solace_agent_mesh/assets/docs/assets/js/e04b235d.06d23db6.js +1 -0
  96. solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
  97. solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
  98. solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
  99. solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
  100. solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
  101. solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
  102. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
  103. solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
  104. solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
  105. solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
  106. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
  107. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
  108. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
  109. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +82 -68
  110. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
  111. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
  112. solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
  113. solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
  114. solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
  115. solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
  116. solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
  117. solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
  118. solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
  119. solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
  120. solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
  121. solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
  122. solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
  123. solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -49
  124. solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -30
  125. solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
  126. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
  127. solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
  128. solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +90 -0
  129. solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -16
  130. solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
  131. solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
  132. solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +162 -171
  133. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
  134. solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
  135. solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
  136. solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
  137. solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
  138. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
  139. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
  140. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
  141. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
  142. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
  143. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
  144. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
  145. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
  146. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
  147. solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
  148. solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
  149. solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
  150. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +23 -19
  151. solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
  152. solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
  153. solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +112 -87
  154. solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
  155. solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +87 -64
  156. solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
  157. solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +44 -44
  158. solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -37
  159. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
  160. solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
  161. solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
  162. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +311 -0
  163. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +39 -42
  164. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
  165. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
  166. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
  167. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
  168. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
  169. solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
  170. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +42 -42
  171. solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
  172. solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
  173. solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
  174. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  175. solace_agent_mesh/assets/docs/search-doc-1768329217460.json +1 -0
  176. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  177. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  178. solace_agent_mesh/cli/__init__.py +1 -1
  179. solace_agent_mesh/cli/commands/add_cmd/__init__.py +3 -1
  180. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
  181. solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
  182. solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
  183. solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
  184. solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
  185. solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
  186. solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
  187. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
  188. solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
  189. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
  190. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
  191. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
  192. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
  193. solace_agent_mesh/cli/commands/run_cmd.py +64 -49
  194. solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
  195. solace_agent_mesh/cli/main.py +15 -0
  196. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-KnKMP_vb.js} +1 -1
  197. solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
  198. solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
  199. solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
  200. solace_agent_mesh/client/webui/frontend/static/assets/vendor-CGk8Suyh.js +565 -0
  201. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  202. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  203. solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
  204. solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
  205. solace_agent_mesh/common/a2a/events.py +2 -1
  206. solace_agent_mesh/common/a2a/protocol.py +5 -0
  207. solace_agent_mesh/common/a2a/types.py +2 -1
  208. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
  209. solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
  210. solace_agent_mesh/common/agent_registry.py +38 -11
  211. solace_agent_mesh/common/data_parts.py +144 -4
  212. solace_agent_mesh/common/error_handlers.py +83 -0
  213. solace_agent_mesh/common/exceptions.py +24 -0
  214. solace_agent_mesh/common/oauth/__init__.py +17 -0
  215. solace_agent_mesh/common/oauth/oauth_client.py +408 -0
  216. solace_agent_mesh/common/oauth/utils.py +50 -0
  217. solace_agent_mesh/common/rag_dto.py +156 -0
  218. solace_agent_mesh/common/sac/sam_component_base.py +97 -19
  219. solace_agent_mesh/common/sam_events/event_service.py +2 -2
  220. solace_agent_mesh/common/services/employee_service.py +1 -1
  221. solace_agent_mesh/common/utils/embeds/constants.py +1 -0
  222. solace_agent_mesh/common/utils/embeds/converter.py +1 -8
  223. solace_agent_mesh/common/utils/embeds/modifiers.py +4 -28
  224. solace_agent_mesh/common/utils/embeds/resolver.py +152 -31
  225. solace_agent_mesh/common/utils/embeds/types.py +9 -0
  226. solace_agent_mesh/common/utils/log_formatters.py +20 -0
  227. solace_agent_mesh/common/utils/mime_helpers.py +12 -5
  228. solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
  229. solace_agent_mesh/common/utils/rbac_utils.py +69 -0
  230. solace_agent_mesh/common/utils/templates/__init__.py +8 -0
  231. solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
  232. solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
  233. solace_agent_mesh/config_portal/backend/common.py +12 -0
  234. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
  235. solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
  236. solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
  237. solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
  238. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
  239. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
  240. solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
  241. solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
  242. solace_agent_mesh/core_a2a/service.py +3 -2
  243. solace_agent_mesh/gateway/adapter/__init__.py +1 -0
  244. solace_agent_mesh/gateway/adapter/base.py +170 -0
  245. solace_agent_mesh/gateway/adapter/types.py +230 -0
  246. solace_agent_mesh/gateway/base/app.py +39 -2
  247. solace_agent_mesh/gateway/base/auth_interface.py +103 -0
  248. solace_agent_mesh/gateway/base/component.py +1027 -151
  249. solace_agent_mesh/gateway/generic/__init__.py +1 -0
  250. solace_agent_mesh/gateway/generic/app.py +50 -0
  251. solace_agent_mesh/gateway/generic/component.py +894 -0
  252. solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
  253. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
  254. solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
  255. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
  256. solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
  257. solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
  258. solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
  259. solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
  260. solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
  261. solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
  262. solace_agent_mesh/gateway/http_sse/app.py +40 -11
  263. solace_agent_mesh/gateway/http_sse/component.py +285 -160
  264. solace_agent_mesh/gateway/http_sse/dependencies.py +149 -114
  265. solace_agent_mesh/gateway/http_sse/main.py +68 -450
  266. solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
  267. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
  268. solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
  269. solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
  270. solace_agent_mesh/gateway/http_sse/repository/entities/session.py +26 -3
  271. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
  272. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
  273. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +114 -6
  274. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +13 -0
  275. solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
  276. solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
  277. solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
  278. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +8 -2
  279. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
  280. solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
  281. solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
  282. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +177 -11
  283. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
  284. solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
  285. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +256 -58
  286. solace_agent_mesh/gateway/http_sse/routers/auth.py +168 -134
  287. solace_agent_mesh/gateway/http_sse/routers/config.py +302 -8
  288. solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
  289. solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
  290. solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
  291. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +14 -1
  292. solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
  293. solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
  294. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +5 -2
  295. solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
  296. solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
  297. solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
  298. solace_agent_mesh/gateway/http_sse/routers/projects.py +768 -0
  299. solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
  300. solace_agent_mesh/gateway/http_sse/routers/sessions.py +167 -7
  301. solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
  302. solace_agent_mesh/gateway/http_sse/routers/sse.py +131 -8
  303. solace_agent_mesh/gateway/http_sse/routers/tasks.py +670 -18
  304. solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
  305. solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
  306. solace_agent_mesh/gateway/http_sse/routers/visualization.py +92 -9
  307. solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
  308. solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
  309. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
  310. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
  311. solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
  312. solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
  313. solace_agent_mesh/gateway/http_sse/services/session_service.py +361 -12
  314. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
  315. solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
  316. solace_agent_mesh/gateway/http_sse/sse_manager.py +286 -166
  317. solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
  318. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
  319. solace_agent_mesh/services/__init__.py +0 -0
  320. solace_agent_mesh/services/platform/__init__.py +29 -0
  321. solace_agent_mesh/services/platform/alembic/env.py +85 -0
  322. solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
  323. solace_agent_mesh/services/platform/alembic.ini +109 -0
  324. solace_agent_mesh/services/platform/api/__init__.py +3 -0
  325. solace_agent_mesh/services/platform/api/dependencies.py +154 -0
  326. solace_agent_mesh/services/platform/api/main.py +314 -0
  327. solace_agent_mesh/services/platform/api/middleware.py +51 -0
  328. solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
  329. solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
  330. solace_agent_mesh/services/platform/app.py +215 -0
  331. solace_agent_mesh/services/platform/component.py +777 -0
  332. solace_agent_mesh/shared/__init__.py +14 -0
  333. solace_agent_mesh/shared/api/__init__.py +42 -0
  334. solace_agent_mesh/shared/auth/__init__.py +26 -0
  335. solace_agent_mesh/shared/auth/dependencies.py +204 -0
  336. solace_agent_mesh/shared/auth/middleware.py +347 -0
  337. solace_agent_mesh/shared/database/__init__.py +20 -0
  338. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
  339. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
  340. solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
  341. solace_agent_mesh/shared/exceptions/__init__.py +36 -0
  342. solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +19 -5
  343. solace_agent_mesh/shared/utils/__init__.py +21 -0
  344. solace_agent_mesh/templates/logging_config_template.yaml +48 -0
  345. solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
  346. solace_agent_mesh/templates/platform.yaml +49 -0
  347. solace_agent_mesh/templates/plugin_readme_template.md +3 -25
  348. solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
  349. solace_agent_mesh/templates/proxy_template.yaml +62 -0
  350. solace_agent_mesh/templates/webui.yaml +148 -6
  351. solace_agent_mesh/tools/web_search/__init__.py +18 -0
  352. solace_agent_mesh/tools/web_search/base.py +84 -0
  353. solace_agent_mesh/tools/web_search/google_search.py +247 -0
  354. solace_agent_mesh/tools/web_search/models.py +99 -0
  355. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +31 -12
  356. solace_agent_mesh-1.13.2.dist-info/RECORD +591 -0
  357. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
  358. solace_agent_mesh/agent/adk/adk_llm.txt +0 -232
  359. solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
  360. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
  361. solace_agent_mesh/agent/adk/models/models_llm.txt +0 -142
  362. solace_agent_mesh/agent/agent_llm.txt +0 -378
  363. solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
  364. solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
  365. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
  366. solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
  367. solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
  368. solace_agent_mesh/agent/testing/testing_llm.txt +0 -57
  369. solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
  370. solace_agent_mesh/agent/tools/tools_llm.txt +0 -263
  371. solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -274
  372. solace_agent_mesh/agent/utils/utils_llm.txt +0 -138
  373. solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
  374. solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
  375. solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
  376. solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
  377. solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
  378. solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +0 -1
  379. solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
  380. solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
  381. solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
  382. solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
  383. solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
  384. solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
  385. solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
  386. solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
  387. solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
  388. solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
  389. solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
  390. solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
  391. solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
  392. solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
  393. solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
  394. solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
  395. solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
  396. solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +0 -1
  397. solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
  398. solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
  399. solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
  400. solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
  401. solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
  402. solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
  403. solace_agent_mesh/assets/docs/assets/js/e6f9706b.e74a984d.js +0 -1
  404. solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
  405. solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
  406. solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
  407. solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
  408. solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
  409. solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
  410. solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
  411. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
  412. solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
  413. solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
  414. solace_agent_mesh/client/webui/frontend/static/assets/client-CaY59VuC.js +0 -25
  415. solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
  416. solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
  417. solace_agent_mesh/client/webui/frontend/static/assets/vendor-BEmvJSYz.js +0 -405
  418. solace_agent_mesh/common/a2a/a2a_llm.txt +0 -182
  419. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
  420. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -407
  421. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
  422. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -313
  423. solace_agent_mesh/common/common_llm.txt +0 -251
  424. solace_agent_mesh/common/common_llm_detail.txt +0 -2562
  425. solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
  426. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
  427. solace_agent_mesh/common/sac/sac_llm.txt +0 -71
  428. solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
  429. solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
  430. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
  431. solace_agent_mesh/common/services/providers/providers_llm.txt +0 -80
  432. solace_agent_mesh/common/services/services_llm.txt +0 -363
  433. solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
  434. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
  435. solace_agent_mesh/common/utils/utils_llm.txt +0 -336
  436. solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
  437. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
  438. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
  439. solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
  440. solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
  441. solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
  442. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
  443. solace_agent_mesh/gateway/base/base_llm.txt +0 -224
  444. solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
  445. solace_agent_mesh/gateway/gateway_llm.txt +0 -373
  446. solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
  447. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -295
  448. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -155
  449. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
  450. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
  451. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
  452. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -263
  453. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -266
  454. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -340
  455. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -346
  456. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -83
  457. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -107
  458. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -314
  459. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -297
  460. solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
  461. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -285
  462. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
  463. solace_agent_mesh/llm.txt +0 -228
  464. solace_agent_mesh/llm_detail.txt +0 -2835
  465. solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
  466. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
  467. solace_agent_mesh/templates/logging_config_template.ini +0 -45
  468. solace_agent_mesh/templates/templates_llm.txt +0 -147
  469. solace_agent_mesh-1.6.1.dist-info/RECORD +0 -525
  470. /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
  471. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
  472. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
  473. /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
  474. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
  475. /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
  476. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
  477. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
  478. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
  479. /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
  480. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
  481. {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
@@ -11,11 +11,24 @@ from ..base.config import BaseProxyAppConfig, ProxiedAgentConfig
11
11
  from ....common.utils.pydantic_utils import SamConfigBase
12
12
 
13
13
 
14
+ class HttpHeaderConfig(SamConfigBase):
15
+ """Configuration for a single HTTP header."""
16
+
17
+ name: str = Field(
18
+ ...,
19
+ description="The HTTP header name (e.g., 'X-API-Key', 'Authorization').",
20
+ )
21
+ value: str = Field(
22
+ ...,
23
+ description="The HTTP header value.",
24
+ )
25
+
26
+
14
27
  class AuthenticationConfig(SamConfigBase):
15
28
  """Authentication configuration for downstream A2A agents."""
16
29
 
17
30
  type: Optional[
18
- Literal["static_bearer", "static_apikey", "oauth2_client_credentials"]
31
+ Literal["static_bearer", "static_apikey", "oauth2_client_credentials", "oauth2_authorization_code"]
19
32
  ] = Field(
20
33
  default=None,
21
34
  description="Authentication type. If not specified, inferred from 'scheme' for backward compatibility.",
@@ -34,11 +47,11 @@ class AuthenticationConfig(SamConfigBase):
34
47
  )
35
48
  client_id: Optional[str] = Field(
36
49
  default=None,
37
- description="OAuth 2.0 client identifier (required for oauth2_client_credentials type).",
50
+ description="OAuth 2.0 client identifier (required for oauth2_client_credentials and oauth2_authorization_code types).",
38
51
  )
39
52
  client_secret: Optional[str] = Field(
40
53
  default=None,
41
- description="OAuth 2.0 client secret (required for oauth2_client_credentials type).",
54
+ description="OAuth 2.0 client secret (required for oauth2_client_credentials type, optional for oauth2_authorization_code).",
42
55
  )
43
56
  scope: Optional[str] = Field(
44
57
  default=None,
@@ -50,6 +63,20 @@ class AuthenticationConfig(SamConfigBase):
50
63
  description="How long to cache OAuth 2.0 tokens before refresh, in seconds (default: 3300 = 55 minutes).",
51
64
  )
52
65
 
66
+ # NEW fields for oauth2_authorization_code
67
+ authorization_url: Optional[str] = Field(
68
+ default=None,
69
+ description="OAuth 2.0 authorization endpoint URL (for oauth2_authorization_code type). Can override agent card URL.",
70
+ )
71
+ redirect_uri: Optional[str] = Field(
72
+ default=None,
73
+ description="OAuth 2.0 redirect URI (required for oauth2_authorization_code type).",
74
+ )
75
+ scopes: Optional[List[str]] = Field(
76
+ default=None,
77
+ description="OAuth 2.0 scopes as a list of strings (optional for oauth2_authorization_code type).",
78
+ )
79
+
53
80
  @model_validator(mode="after")
54
81
  def validate_auth_config(self) -> "AuthenticationConfig":
55
82
  """Validates authentication configuration based on type."""
@@ -108,10 +135,35 @@ class AuthenticationConfig(SamConfigBase):
108
135
  "OAuth 2.0 client credentials flow requires 'client_secret'."
109
136
  )
110
137
 
138
+ elif auth_type == "oauth2_authorization_code":
139
+ # Validate client_id
140
+ if not self.client_id:
141
+ raise ValueError(
142
+ "OAuth 2.0 authorization code flow requires 'client_id'."
143
+ )
144
+
145
+ # Validate redirect_uri
146
+ if not self.redirect_uri:
147
+ raise ValueError(
148
+ "OAuth 2.0 authorization code flow requires 'redirect_uri'."
149
+ )
150
+
151
+ # Optional: Validate authorization_url if provided (can also come from agent card)
152
+ if self.authorization_url:
153
+ try:
154
+ parsed_url = urlparse(self.authorization_url)
155
+ if parsed_url.scheme not in ["https", "http"]:
156
+ raise ValueError(
157
+ f"OAuth 2.0 'authorization_url' must use HTTP(S). "
158
+ f"Got scheme: '{parsed_url.scheme}'"
159
+ )
160
+ except Exception as e:
161
+ raise ValueError(f"Failed to parse 'authorization_url': {e}")
162
+
111
163
  else:
112
164
  raise ValueError(
113
165
  f"Unsupported authentication type '{auth_type}'. "
114
- f"Supported types: static_bearer, static_apikey, oauth2_client_credentials."
166
+ f"Supported types: static_bearer, static_apikey, oauth2_client_credentials, oauth2_authorization_code."
115
167
  )
116
168
 
117
169
  return self
@@ -128,6 +180,30 @@ class A2AProxiedAgentConfig(ProxiedAgentConfig):
128
180
  default=None,
129
181
  description="Authentication details for the downstream agent.",
130
182
  )
183
+ use_auth_for_agent_card: bool = Field(
184
+ default=False,
185
+ description="If true, applies the configured authentication to agent card fetching. "
186
+ "If false, agent card requests are made without authentication.",
187
+ )
188
+ use_agent_card_url: bool = Field(
189
+ default=True,
190
+ description="If true, uses the URL from the agent card for task invocations. "
191
+ "If false, uses the configured URL directly for task invocations. "
192
+ "Note: The configured URL is always used to fetch the agent card itself.",
193
+ )
194
+ agent_card_headers: Optional[List[HttpHeaderConfig]] = Field(
195
+ default=None,
196
+ description="Custom HTTP headers to include when fetching the agent card. "
197
+ "These headers are added alongside authentication headers.",
198
+ )
199
+ task_headers: Optional[List[HttpHeaderConfig]] = Field(
200
+ default=None,
201
+ description="Custom HTTP headers to include when invoking A2A tasks. "
202
+ "These headers are added alongside authentication headers. Note: The A2A SDK's "
203
+ "AuthInterceptor applies authentication headers after these are set, so custom "
204
+ "headers cannot override authentication. For custom auth, omit the 'authentication' "
205
+ "config and use task_headers to set auth headers directly.",
206
+ )
131
207
 
132
208
 
133
209
  class A2AProxyAppConfig(BaseProxyAppConfig):
@@ -43,8 +43,9 @@ class BaseProxyApp(App, ABC):
43
43
  # Overwrite the raw dict with the validated object for downstream use
44
44
  app_info["app_config"] = app_config
45
45
  except ValidationError as e:
46
- log.error("Proxy configuration validation failed:\n%s", e)
47
- raise ValueError(f"Invalid proxy configuration: {e}") from e
46
+ message = BaseProxyAppConfig.format_validation_error_message(e, app_info['name'])
47
+ log.error("Invalid Proxy configuration:\n%s", message)
48
+ raise
48
49
 
49
50
  namespace = app_config.get("namespace")
50
51
  proxied_agents = app_config.get("proxied_agents", [])
@@ -7,8 +7,9 @@ from __future__ import annotations
7
7
  import asyncio
8
8
  import concurrent.futures
9
9
  import threading
10
+ import time
10
11
  from abc import ABC, abstractmethod
11
- from typing import Any, Dict, Optional, TYPE_CHECKING
12
+ from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING
12
13
 
13
14
  import httpx
14
15
 
@@ -32,6 +33,8 @@ from ....common.a2a.protocol import (
32
33
  from a2a.types import (
33
34
  A2ARequest,
34
35
  AgentCard,
36
+ AgentCapabilities,
37
+ AgentExtension,
35
38
  CancelTaskRequest,
36
39
  FilePart,
37
40
  InternalError,
@@ -77,16 +80,22 @@ class BaseProxyComponent(ComponentBase, ABC):
77
80
  "artifact_service", {"type": "memory"}
78
81
  )
79
82
  self.discovery_interval_sec = self.get_config("discovery_interval_seconds", 60)
83
+ self.task_state_ttl_minutes = self.get_config("task_state_ttl_minutes", 60)
84
+ self.task_cleanup_interval_minutes = self.get_config(
85
+ "task_cleanup_interval_minutes", 10
86
+ )
80
87
 
81
88
  self.agent_registry = AgentRegistry()
82
89
  self.artifact_service: Optional[BaseArtifactService] = None
83
- self.active_tasks: Dict[str, ProxyTaskContext] = {}
90
+ # Store (timestamp, ProxyTaskContext) tuples for TTL-based cleanup
91
+ self.active_tasks: Dict[str, Tuple[float, ProxyTaskContext]] = {}
84
92
  self.active_tasks_lock = threading.Lock()
85
93
 
86
94
  self._async_loop: Optional[asyncio.AbstractEventLoop] = None
87
95
  self._async_thread: Optional[threading.Thread] = None
88
96
  self._async_init_future: Optional[concurrent.futures.Future] = None
89
97
  self._discovery_timer_id = f"proxy_discovery_{self.name}"
98
+ self._task_cleanup_timer_id = f"proxy_task_cleanup_{self.name}"
90
99
 
91
100
  try:
92
101
  # Initialize synchronous services first
@@ -158,8 +167,11 @@ class BaseProxyComponent(ComponentBase, ABC):
158
167
  if not hasattr(event, "_proxy_message_handled"):
159
168
  event._proxy_message_handled = message_handled
160
169
  elif event.event_type == EventType.TIMER:
161
- if event.data.get("timer_id") == self._discovery_timer_id:
170
+ timer_id = event.data.get("timer_id")
171
+ if timer_id == self._discovery_timer_id:
162
172
  await self._discover_and_publish_agents()
173
+ elif timer_id == self._task_cleanup_timer_id:
174
+ await self._cleanup_stale_tasks()
163
175
  else:
164
176
  log.debug(
165
177
  "%s Ignoring unhandled event type: %s",
@@ -209,12 +221,13 @@ class BaseProxyComponent(ComponentBase, ABC):
209
221
  "status_topic": message.get_user_properties().get("a2aStatusTopic"),
210
222
  "reply_to_topic": message.get_user_properties().get("replyTo"),
211
223
  "is_streaming": isinstance(a2a_request.root, SendStreamingMessageRequest),
224
+ "user_properties": message.get_user_properties(),
212
225
  }
213
226
  task_context = ProxyTaskContext(
214
227
  task_id=logical_task_id, a2a_context=a2a_context
215
228
  )
216
229
  with self.active_tasks_lock:
217
- self.active_tasks[logical_task_id] = task_context
230
+ self.active_tasks[logical_task_id] = (time.time(), task_context)
218
231
 
219
232
  log.info(
220
233
  "%s Forwarding request for task %s to agent %s.",
@@ -228,12 +241,13 @@ class BaseProxyComponent(ComponentBase, ABC):
228
241
 
229
242
  elif isinstance(a2a_request.root, CancelTaskRequest):
230
243
  logical_task_id = get_task_id_from_cancel_request(a2a_request)
231
-
244
+
232
245
  # Get the agent name from the topic (same as for send_message)
233
246
  target_agent_name = topic.split("/")[-1]
234
-
247
+
235
248
  with self.active_tasks_lock:
236
- task_context = self.active_tasks.get(logical_task_id)
249
+ task_entry = self.active_tasks.get(logical_task_id)
250
+ task_context = task_entry[1] if task_entry else None
237
251
 
238
252
  if task_context:
239
253
  log.info(
@@ -319,6 +333,73 @@ class BaseProxyComponent(ComponentBase, ABC):
319
333
 
320
334
  return update_message_parts(original_message, resolved_parts)
321
335
 
336
+ def _update_agent_card_for_proxy(self, agent_card: AgentCard, agent_alias: str) -> AgentCard:
337
+ """
338
+ Updates an agent card for proxying by:
339
+ 1. Setting the name to the proxy alias
340
+ 2. Adding/updating the display-name extension to preserve the original name
341
+
342
+ Args:
343
+ agent_card: The original agent card fetched from the remote agent
344
+ agent_alias: The alias/name to use for this agent in SAM
345
+
346
+ Returns:
347
+ A modified copy of the agent card with updated name and display-name extension
348
+ """
349
+ # Create a deep copy to avoid modifying the original
350
+ card_copy = agent_card.model_copy(deep=True)
351
+
352
+ # Store the original name as the display name (if not already set)
353
+ # This preserves the agent's identity while allowing it to be proxied under an alias
354
+ original_display_name = agent_card.name
355
+
356
+ # Check if there's already a display-name extension to preserve
357
+ display_name_uri = "https://solace.com/a2a/extensions/display-name"
358
+ if card_copy.capabilities and card_copy.capabilities.extensions:
359
+ for ext in card_copy.capabilities.extensions:
360
+ if ext.uri == display_name_uri and ext.params and ext.params.get("display_name"):
361
+ # Use the existing display name from the extension
362
+ original_display_name = ext.params["display_name"]
363
+ break
364
+
365
+ # Update the card's name to the proxy alias
366
+ card_copy.name = agent_alias
367
+
368
+ # Ensure capabilities and extensions exist
369
+ if not card_copy.capabilities:
370
+ card_copy.capabilities = AgentCapabilities(extensions=[])
371
+ if not card_copy.capabilities.extensions:
372
+ card_copy.capabilities.extensions = []
373
+
374
+ # Find or create the display-name extension
375
+ display_name_ext = None
376
+ for ext in card_copy.capabilities.extensions:
377
+ if ext.uri == display_name_uri:
378
+ display_name_ext = ext
379
+ break
380
+
381
+ if display_name_ext:
382
+ # Update existing extension
383
+ if not display_name_ext.params:
384
+ display_name_ext.params = {}
385
+ display_name_ext.params["display_name"] = original_display_name
386
+ else:
387
+ # Create new extension
388
+ new_ext = AgentExtension(
389
+ uri=display_name_uri,
390
+ params={"display_name": original_display_name}
391
+ )
392
+ card_copy.capabilities.extensions.append(new_ext)
393
+
394
+ log.debug(
395
+ "%s Updated agent card: name='%s', display_name='%s'",
396
+ self.log_identifier,
397
+ agent_alias,
398
+ original_display_name
399
+ )
400
+
401
+ return card_copy
402
+
322
403
  def _initial_discovery_sync(self):
323
404
  """
324
405
  Synchronously fetches agent cards to populate the registry at startup.
@@ -340,12 +421,12 @@ class BaseProxyComponent(ComponentBase, ABC):
340
421
  continue
341
422
  try:
342
423
  # Use a synchronous client for this initial blocking call
343
- response = client.get(f"{agent_url}/.well-known/agent.json")
424
+ response = client.get(f"{agent_url}/.well-known/agent-card.json")
344
425
  response.raise_for_status()
345
426
  agent_card = AgentCard.model_validate(response.json())
346
427
 
347
- card_for_proxy = agent_card.model_copy(deep=True)
348
- card_for_proxy.name = agent_alias
428
+ # Update the card for proxying (preserves display name)
429
+ card_for_proxy = self._update_agent_card_for_proxy(agent_card, agent_alias)
349
430
  self.agent_registry.add_or_update_agent(card_for_proxy)
350
431
  log.info(
351
432
  "%s Initial discovery successful for alias '%s' (actual name: '%s').",
@@ -376,12 +457,12 @@ class BaseProxyComponent(ComponentBase, ABC):
376
457
  continue
377
458
 
378
459
  agent_alias = agent_config["name"]
379
- card_for_proxy = modern_card.model_copy(deep=True)
380
- card_for_proxy.name = agent_alias
381
- self.agent_registry.add_or_update_agent(card_for_proxy)
460
+ # Update the card for proxying (preserves display name)
461
+ card_for_registry = self._update_agent_card_for_proxy(modern_card, agent_alias)
462
+ self.agent_registry.add_or_update_agent(card_for_registry)
382
463
 
383
- # Publish the modern card directly after updating its URL
384
- card_to_publish = card_for_proxy.model_copy(deep=True)
464
+ # Create a separate copy for publishing
465
+ card_to_publish = card_for_registry.model_copy(deep=True)
385
466
  card_to_publish.url = (
386
467
  f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
387
468
  )
@@ -418,10 +499,14 @@ class BaseProxyComponent(ComponentBase, ABC):
418
499
  response = create_success_response(
419
500
  result=event, request_id=a2a_context.get("jsonrpc_request_id")
420
501
  )
421
- self._publish_a2a_message(response.model_dump(exclude_none=True), target_topic)
502
+ self._publish_a2a_message(
503
+ response.model_dump(exclude_none=True),
504
+ target_topic,
505
+ user_properties=a2a_context.get("user_properties")
506
+ )
422
507
 
423
- async def _publish_final_response(self, task: Task, a2a_context: Dict):
424
- """Publishes the final Task object to the appropriate Solace topic."""
508
+ async def _publish_task_response(self, task: Task, a2a_context: Dict):
509
+ """Publishes a Task object to the reply topic."""
425
510
  target_topic = a2a_context.get("reply_to_topic")
426
511
  if not target_topic:
427
512
  log.warning(
@@ -434,7 +519,11 @@ class BaseProxyComponent(ComponentBase, ABC):
434
519
  response = create_success_response(
435
520
  result=task, request_id=a2a_context.get("jsonrpc_request_id")
436
521
  )
437
- self._publish_a2a_message(response.model_dump(exclude_none=True), target_topic)
522
+ self._publish_a2a_message(
523
+ response.model_dump(exclude_none=True),
524
+ target_topic,
525
+ user_properties=a2a_context.get("user_properties")
526
+ )
438
527
 
439
528
  async def _publish_artifact_update(
440
529
  self, event: TaskArtifactUpdateEvent, a2a_context: Dict
@@ -452,7 +541,11 @@ class BaseProxyComponent(ComponentBase, ABC):
452
541
  response = create_success_response(
453
542
  result=event, request_id=a2a_context.get("jsonrpc_request_id")
454
543
  )
455
- self._publish_a2a_message(response.model_dump(exclude_none=True), target_topic)
544
+ self._publish_a2a_message(
545
+ response.model_dump(exclude_none=True),
546
+ target_topic,
547
+ user_properties=a2a_context.get("user_properties")
548
+ )
456
549
 
457
550
  async def _publish_error_response(
458
551
  self,
@@ -551,16 +644,73 @@ class BaseProxyComponent(ComponentBase, ABC):
551
644
  nack_e,
552
645
  )
553
646
 
647
+ async def _cleanup_stale_tasks(self):
648
+ """
649
+ Removes task state older than configured TTL.
650
+ This prevents memory leaks from tasks that complete without sending terminal events
651
+ (e.g., due to agent crashes or network failures).
652
+ """
653
+ ttl_seconds = self.task_state_ttl_minutes * 60
654
+ cutoff_time = time.time() - ttl_seconds
655
+
656
+ with self.active_tasks_lock:
657
+ stale_task_ids = [
658
+ task_id
659
+ for task_id, (timestamp, _) in self.active_tasks.items()
660
+ if timestamp < cutoff_time
661
+ ]
662
+ for task_id in stale_task_ids:
663
+ del self.active_tasks[task_id]
664
+ log.warning(
665
+ "%s Cleaned up stale task %s (exceeded TTL of %d minutes)",
666
+ self.log_identifier,
667
+ task_id,
668
+ self.task_state_ttl_minutes,
669
+ )
670
+
671
+ if stale_task_ids:
672
+ log.info(
673
+ "%s Stale task cleanup removed %d tasks",
674
+ self.log_identifier,
675
+ len(stale_task_ids),
676
+ )
677
+
678
+ def _cleanup_task_state(self, task_id: str) -> None:
679
+ """
680
+ Cleans up state for a completed task.
681
+ Called when a terminal event is detected (Task with terminal state,
682
+ or TaskStatusUpdateEvent with final=true).
683
+
684
+ Args:
685
+ task_id: The ID of the task to clean up
686
+ """
687
+ with self.active_tasks_lock:
688
+ entry = self.active_tasks.pop(task_id, None)
689
+ if entry:
690
+ log.info(
691
+ "%s Removed task %s from active_tasks (terminal event detected)",
692
+ self.log_identifier,
693
+ task_id,
694
+ )
695
+ else:
696
+ log.debug(
697
+ "%s Task %s not found in active_tasks during cleanup (already removed)",
698
+ self.log_identifier,
699
+ task_id,
700
+ )
701
+
554
702
  def _publish_discovered_cards(self):
555
703
  """Publishes all agent cards currently in the registry."""
556
704
  log.info(
557
705
  "%s Publishing initially discovered agent cards...", self.log_identifier
558
706
  )
559
707
  for agent_alias in self.agent_registry.get_agent_names():
560
- card_to_publish = self.agent_registry.get_agent(agent_alias)
561
- if not card_to_publish:
708
+ original_card = self.agent_registry.get_agent(agent_alias)
709
+ if not original_card:
562
710
  continue
563
711
 
712
+ # Create a copy for publishing to avoid modifying the card in the registry
713
+ card_to_publish = original_card.model_copy(deep=True)
564
714
  card_to_publish.url = (
565
715
  f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
566
716
  )
@@ -599,6 +749,21 @@ class BaseProxyComponent(ComponentBase, ABC):
599
749
  self.discovery_interval_sec,
600
750
  )
601
751
 
752
+ # Schedule the recurring task cleanup timer
753
+ if self.task_cleanup_interval_minutes > 0:
754
+ cleanup_interval_ms = self.task_cleanup_interval_minutes * 60 * 1000
755
+ self.add_timer(
756
+ delay_ms=cleanup_interval_ms,
757
+ timer_id=self._task_cleanup_timer_id,
758
+ interval_ms=cleanup_interval_ms,
759
+ )
760
+ log.info(
761
+ "%s Scheduled recurring stale task cleanup every %d minutes (TTL: %d minutes).",
762
+ self.log_identifier,
763
+ self.task_cleanup_interval_minutes,
764
+ self.task_state_ttl_minutes,
765
+ )
766
+
602
767
  super().run()
603
768
 
604
769
  def clear_client_cache(self):
@@ -614,6 +779,7 @@ class BaseProxyComponent(ComponentBase, ABC):
614
779
  """Cleans up resources on component shutdown."""
615
780
  log.info("%s Cleaning up proxy component.", self.log_identifier)
616
781
  self.cancel_timer(self._discovery_timer_id)
782
+ self.cancel_timer(self._task_cleanup_timer_id)
617
783
 
618
784
  # Clear active tasks (no need to signal cancellation - downstream agents own their tasks)
619
785
  with self.active_tasks_lock:
@@ -13,5 +13,7 @@ class ProxyTaskContext:
13
13
  This object is created when a task is initiated and destroyed when it completes.
14
14
  """
15
15
 
16
- task_id: str
16
+ task_id: str # SAM's task ID (used for upstream communication)
17
17
  a2a_context: Dict[str, Any]
18
+ downstream_task_id: str | None = None # Downstream agent's task ID (used for cancellation)
19
+ original_request: Any = None # Original A2A request (for task pause/resume in OAuth2 flows)
@@ -231,6 +231,32 @@ class ArtifactServiceConfig(SamConfigBase):
231
231
  return self
232
232
 
233
233
 
234
+ class AgentIdentityConfig(SamConfigBase):
235
+ """Configuration for agent identity and key management."""
236
+
237
+ key_mode: Literal["auto", "manual"] = Field(
238
+ default="auto",
239
+ description="Key mode for agent identity: 'auto' for automatic generation, 'manual' for user-provided.",
240
+ )
241
+ key_identity: Optional[str] = Field(
242
+ default=None, description="Actual key value when key_mode is 'manual'."
243
+ )
244
+ key_persistence: Optional[str] = Field(
245
+ default=None,
246
+ description="Path to the key file, e.g. '/path/to/keys/agent_{name}.key'.",
247
+ )
248
+
249
+ @model_validator(mode="after")
250
+ def check_key_mode_and_identity(self) -> "AgentIdentityConfig":
251
+ if self.key_mode == "manual" and not self.key_identity:
252
+ raise ValueError("'key_identity' is required when 'key_mode' is 'manual'.")
253
+ if self.key_mode == "auto" and self.key_identity:
254
+ log.warning(
255
+ "Configuration Warning: 'key_identity' is ignored when 'key_mode' is 'auto'."
256
+ )
257
+ return self
258
+
259
+
234
260
  class SessionServiceConfig(SamConfigBase):
235
261
  """Configuration for the ADK Session Service."""
236
262
 
@@ -245,6 +271,12 @@ class SessionServiceConfig(SamConfigBase):
245
271
  )
246
272
 
247
273
 
274
+ class CredentialServiceConfig(SamConfigBase):
275
+ """Configuration for the ADK Credential Service."""
276
+
277
+ type: str = Field(..., description="Service type (e.g., 'memory').")
278
+
279
+
248
280
  class SamAgentAppConfig(SamConfigBase):
249
281
  """Pydantic model for the complete agent application configuration."""
250
282
 
@@ -264,6 +296,10 @@ class SamAgentAppConfig(SamConfigBase):
264
296
  model: Union[str, Dict[str, Any]] = Field(
265
297
  ..., description="ADK model name (string) or BaseLlm config dict."
266
298
  )
299
+ agent_identity: Optional[AgentIdentityConfig] = Field(
300
+ default_factory=lambda: AgentIdentityConfig(key_mode="auto"),
301
+ description="Configuration for agent identity and key management.",
302
+ )
267
303
  trust_manager: Optional[Union[TrustManagerConfig, Dict[str, Any]]] = Field(
268
304
  default=None,
269
305
  description="Configuration for the Trust Manager (enterprise feature)",
@@ -306,6 +342,10 @@ class SamAgentAppConfig(SamConfigBase):
306
342
  default={"type": "memory"},
307
343
  description="Configuration for ADK Memory Service (defaults to memory).",
308
344
  )
345
+ credential_service: Optional[CredentialServiceConfig] = Field(
346
+ default=None,
347
+ description="Configuration for ADK Credential Service (optional).",
348
+ )
309
349
  multi_session_request_response: Dict[str, Any] = Field(
310
350
  default_factory=lambda: {"enabled": True},
311
351
  description="Enables multi-session request/response capabilities for the agent, required for peer delegation.",
@@ -335,6 +375,12 @@ class SamAgentAppConfig(SamConfigBase):
335
375
  ge=0,
336
376
  description="Maximum number of dictionary keys to inspect during schema inference.",
337
377
  )
378
+ schema_inference_depth: int = Field(
379
+ default=4,
380
+ ge=1,
381
+ le=10,
382
+ description="Maximum depth for schema inference on nested structures. Higher values reveal more nested field names but increase metadata size.",
383
+ )
338
384
  enable_embed_resolution: bool = Field(
339
385
  default=True,
340
386
  description="Enable early-stage processing of dynamic embeds and inject related instructions.",
@@ -344,7 +390,7 @@ class SamAgentAppConfig(SamConfigBase):
344
390
  description="If true, automatically attempts to continue LLM generation if it is interrupted by a token limit.",
345
391
  )
346
392
  stream_batching_threshold_bytes: int = Field(
347
- default=0,
393
+ default=100,
348
394
  description="Minimum size in bytes for accumulated text from LLM stream before sending a status update.",
349
395
  )
350
396
  max_message_size_bytes: int = Field(
@@ -436,8 +482,11 @@ class SamAgentApp(App):
436
482
  # Overwrite the raw dict with the validated object for downstream use
437
483
  app_info["app_config"] = app_config
438
484
  except ValidationError as e:
439
- log.error("Agent configuration validation failed:\n%s", e)
440
- raise ValueError(f"Invalid agent configuration: {e}") from e
485
+ message = SamAgentAppConfig.format_validation_error_message(
486
+ e, app_info["name"], app_config_dict.get("agent_name")
487
+ )
488
+ log.error("Invalid Agent configuration:\n%s", message)
489
+ raise
441
490
 
442
491
  # The rest of the method can now safely use .get() on the app_config object,
443
492
  # ensuring full backward compatibility.
@@ -510,3 +559,42 @@ class SamAgentApp(App):
510
559
 
511
560
  super().__init__(app_info, **kwargs)
512
561
  log.debug("%s Agent initialization complete.", agent_name)
562
+
563
+ def run(self):
564
+ """
565
+ Override run to ensure component initialization failures cause application failure.
566
+
567
+ This is critical for containerized deployments where the process must exit with
568
+ a non-zero code if initialization fails. By re-raising the exception, we allow
569
+ the SAC framework's main() to handle cleanup (component.cleanup(), broker
570
+ disconnection, etc.) before exiting with code 1.
571
+ """
572
+ try:
573
+ super().run()
574
+ except Exception as e:
575
+ log.critical(
576
+ "Failed to start agent application '%s': %s", self.name, e, exc_info=e
577
+ )
578
+ raise
579
+
580
+ def get_component(self, component_name: str = None) -> "SamAgentComponent":
581
+ """
582
+ Retrieves the running SamAgentComponent instance from the app's flow.
583
+
584
+ Args:
585
+ component_name: Optional component name (for compatibility, but ignored since there's only one component)
586
+
587
+ Returns:
588
+ The SamAgentComponent instance or None if not found
589
+ """
590
+ if self.flows and self.flows[0].component_groups:
591
+ for group in self.flows[0].component_groups:
592
+ for component_wrapper in group:
593
+ component = (
594
+ component_wrapper.component
595
+ if hasattr(component_wrapper, "component")
596
+ else component_wrapper
597
+ )
598
+ if isinstance(component, SamAgentComponent):
599
+ return component
600
+ return None