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
@@ -0,0 +1,408 @@
1
+ """Pure OAuth 2.0 protocol implementation.
2
+
3
+ This module provides stateless OAuth 2.0 flow implementations without any
4
+ caching, retry logic, or domain-specific behavior. It implements the core
5
+ OAuth 2.0 flows as defined in RFC 6749.
6
+ """
7
+
8
+ import asyncio
9
+ import logging
10
+ import random
11
+ from typing import Any, Dict, Optional, Union
12
+
13
+ import httpx
14
+
15
+ from .utils import calculate_expires_at
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class OAuth2Client:
21
+ """Pure OAuth 2.0 protocol implementation.
22
+
23
+ This class provides stateless OAuth 2.0 flow implementations without any
24
+ caching, retry logic, or domain-specific behavior. Each method makes a
25
+ single HTTP request to the token endpoint and returns the parsed response.
26
+
27
+ All OAuth 2.0 flows follow RFC 6749 specification.
28
+ """
29
+
30
+ async def fetch_client_credentials_token(
31
+ self,
32
+ token_url: str,
33
+ client_id: str,
34
+ client_secret: str,
35
+ scope: Optional[str] = None,
36
+ verify: Union[bool, str] = True,
37
+ timeout: float = 30.0,
38
+ ) -> Dict[str, Any]:
39
+ """Execute OAuth 2.0 Client Credentials flow (RFC 6749 Section 4.4).
40
+
41
+ This flow is used for server-to-server authentication where the client
42
+ acts on its own behalf rather than on behalf of a user.
43
+
44
+ Args:
45
+ token_url: OAuth 2.0 token endpoint URL
46
+ client_id: OAuth 2.0 client identifier
47
+ client_secret: OAuth 2.0 client secret
48
+ scope: Optional space-separated list of scopes
49
+ verify: SSL certificate verification (True, False, or path to CA bundle)
50
+ timeout: Request timeout in seconds
51
+
52
+ Returns:
53
+ Token response dictionary containing:
54
+ - access_token: The access token string
55
+ - expires_in: Token lifetime in seconds
56
+ - token_type: Token type (usually "Bearer")
57
+ - scope: Granted scopes (optional)
58
+ - expires_at: Unix timestamp when token expires (added by this method)
59
+
60
+ Raises:
61
+ httpx.HTTPStatusError: If the token request fails
62
+ ValueError: If the response is missing required fields
63
+ """
64
+ payload = {
65
+ "grant_type": "client_credentials",
66
+ "client_id": client_id,
67
+ "client_secret": client_secret,
68
+ }
69
+
70
+ if scope:
71
+ payload["scope"] = scope
72
+
73
+ return await self._execute_token_request(
74
+ token_url=token_url,
75
+ payload=payload,
76
+ verify=verify,
77
+ timeout=timeout,
78
+ )
79
+
80
+ async def fetch_authorization_code_token(
81
+ self,
82
+ token_url: str,
83
+ client_id: str,
84
+ client_secret: str,
85
+ code: str,
86
+ redirect_uri: str,
87
+ verify: Union[bool, str] = True,
88
+ timeout: float = 30.0,
89
+ ) -> Dict[str, Any]:
90
+ """Execute OAuth 2.0 Authorization Code flow (RFC 6749 Section 4.1).
91
+
92
+ This flow is used for user-delegated authentication where the application
93
+ acts on behalf of a user who has granted permission.
94
+
95
+ Args:
96
+ token_url: OAuth 2.0 token endpoint URL
97
+ client_id: OAuth 2.0 client identifier
98
+ client_secret: OAuth 2.0 client secret
99
+ code: Authorization code received from authorization server
100
+ redirect_uri: Redirect URI used in authorization request (must match)
101
+ verify: SSL certificate verification (True, False, or path to CA bundle)
102
+ timeout: Request timeout in seconds
103
+
104
+ Returns:
105
+ Token response dictionary containing:
106
+ - access_token: The access token string
107
+ - expires_in: Token lifetime in seconds
108
+ - refresh_token: Refresh token for obtaining new access tokens (optional)
109
+ - token_type: Token type (usually "Bearer")
110
+ - scope: Granted scopes (optional)
111
+ - expires_at: Unix timestamp when token expires (added by this method)
112
+
113
+ Raises:
114
+ httpx.HTTPStatusError: If the token request fails
115
+ ValueError: If the response is missing required fields
116
+ """
117
+ payload = {
118
+ "grant_type": "authorization_code",
119
+ "code": code,
120
+ "redirect_uri": redirect_uri,
121
+ "client_id": client_id,
122
+ "client_secret": client_secret,
123
+ }
124
+
125
+ return await self._execute_token_request(
126
+ token_url=token_url,
127
+ payload=payload,
128
+ verify=verify,
129
+ timeout=timeout,
130
+ )
131
+
132
+ async def fetch_refresh_token(
133
+ self,
134
+ token_url: str,
135
+ client_id: str,
136
+ client_secret: str,
137
+ refresh_token: str,
138
+ scope: Optional[str] = None,
139
+ verify: Union[bool, str] = True,
140
+ timeout: float = 30.0,
141
+ ) -> Dict[str, Any]:
142
+ """Execute OAuth 2.0 Refresh Token flow (RFC 6749 Section 6).
143
+
144
+ This flow is used to obtain a new access token using a refresh token,
145
+ without requiring user interaction.
146
+
147
+ Args:
148
+ token_url: OAuth 2.0 token endpoint URL
149
+ client_id: OAuth 2.0 client identifier
150
+ client_secret: OAuth 2.0 client secret
151
+ refresh_token: The refresh token
152
+ scope: Optional space-separated list of scopes (must not exceed original grant)
153
+ verify: SSL certificate verification (True, False, or path to CA bundle)
154
+ timeout: Request timeout in seconds
155
+
156
+ Returns:
157
+ Token response dictionary containing:
158
+ - access_token: The new access token string
159
+ - expires_in: Token lifetime in seconds
160
+ - refresh_token: New refresh token (optional, may be same as input)
161
+ - token_type: Token type (usually "Bearer")
162
+ - scope: Granted scopes (optional)
163
+ - expires_at: Unix timestamp when token expires (added by this method)
164
+
165
+ Raises:
166
+ httpx.HTTPStatusError: If the token request fails
167
+ ValueError: If the response is missing required fields
168
+ """
169
+ payload = {
170
+ "grant_type": "refresh_token",
171
+ "refresh_token": refresh_token,
172
+ "client_id": client_id,
173
+ "client_secret": client_secret,
174
+ }
175
+
176
+ if scope:
177
+ payload["scope"] = scope
178
+
179
+ return await self._execute_token_request(
180
+ token_url=token_url,
181
+ payload=payload,
182
+ verify=verify,
183
+ timeout=timeout,
184
+ )
185
+
186
+ async def _execute_token_request(
187
+ self,
188
+ token_url: str,
189
+ payload: Dict[str, str],
190
+ verify: Union[bool, str],
191
+ timeout: float,
192
+ ) -> Dict[str, Any]:
193
+ """Execute a token request to the OAuth 2.0 token endpoint.
194
+
195
+ This is the core HTTP operation shared by all OAuth flows.
196
+
197
+ Args:
198
+ token_url: OAuth 2.0 token endpoint URL
199
+ payload: Request payload (grant-specific parameters)
200
+ verify: SSL certificate verification
201
+ timeout: Request timeout in seconds
202
+
203
+ Returns:
204
+ Token response dictionary with added expires_at field
205
+
206
+ Raises:
207
+ httpx.HTTPStatusError: If the token request fails
208
+ ValueError: If the response is missing required fields
209
+ """
210
+ headers = {
211
+ "Content-Type": "application/x-www-form-urlencoded",
212
+ "Accept": "application/json",
213
+ }
214
+
215
+ async with httpx.AsyncClient(verify=verify) as client:
216
+ response = await client.post(
217
+ token_url,
218
+ data=payload,
219
+ headers=headers,
220
+ timeout=timeout,
221
+ )
222
+ response.raise_for_status()
223
+
224
+ token_data = response.json()
225
+
226
+ # Validate response contains required fields
227
+ if "access_token" not in token_data:
228
+ raise ValueError(
229
+ f"Token response missing 'access_token' field. "
230
+ f"Response keys: {list(token_data.keys())}"
231
+ )
232
+
233
+ # Add expiration timestamp for convenience
234
+ expires_in = token_data.get("expires_in", 3600) # Default 1 hour
235
+ token_data["expires_at"] = calculate_expires_at(expires_in)
236
+
237
+ return token_data
238
+
239
+
240
+ class OAuth2RetryClient:
241
+ """OAuth 2.0 client with configurable retry logic.
242
+
243
+ This class wraps OAuth2Client and adds retry logic with exponential backoff
244
+ for handling transient failures. Retry behavior:
245
+ - 4xx errors (client errors): No retry - fail immediately
246
+ - 5xx errors (server errors): Retry with exponential backoff
247
+ - Network errors: Retry with exponential backoff
248
+ """
249
+
250
+ def __init__(
251
+ self,
252
+ max_retries: int = 0,
253
+ backoff_base: float = 2.0,
254
+ backoff_jitter: bool = True,
255
+ ):
256
+ """Initialize the retry client.
257
+
258
+ Args:
259
+ max_retries: Maximum number of retry attempts (0 = no retries)
260
+ backoff_base: Base for exponential backoff (delay = base^attempt)
261
+ backoff_jitter: Whether to add random jitter to backoff delay
262
+ """
263
+ self._base_client = OAuth2Client()
264
+ self._max_retries = max_retries
265
+ self._backoff_base = backoff_base
266
+ self._backoff_jitter = backoff_jitter
267
+
268
+ async def fetch_client_credentials_token(
269
+ self,
270
+ token_url: str,
271
+ client_id: str,
272
+ client_secret: str,
273
+ scope: Optional[str] = None,
274
+ verify: Union[bool, str] = True,
275
+ timeout: float = 30.0,
276
+ ) -> Dict[str, Any]:
277
+ """Execute Client Credentials flow with retry logic.
278
+
279
+ See OAuth2Client.fetch_client_credentials_token for parameter details.
280
+ """
281
+ return await self._execute_with_retry(
282
+ self._base_client.fetch_client_credentials_token,
283
+ token_url=token_url,
284
+ client_id=client_id,
285
+ client_secret=client_secret,
286
+ scope=scope,
287
+ verify=verify,
288
+ timeout=timeout,
289
+ )
290
+
291
+ async def fetch_authorization_code_token(
292
+ self,
293
+ token_url: str,
294
+ client_id: str,
295
+ client_secret: str,
296
+ code: str,
297
+ redirect_uri: str,
298
+ verify: Union[bool, str] = True,
299
+ timeout: float = 30.0,
300
+ ) -> Dict[str, Any]:
301
+ """Execute Authorization Code flow with retry logic.
302
+
303
+ See OAuth2Client.fetch_authorization_code_token for parameter details.
304
+ """
305
+ return await self._execute_with_retry(
306
+ self._base_client.fetch_authorization_code_token,
307
+ token_url=token_url,
308
+ client_id=client_id,
309
+ client_secret=client_secret,
310
+ code=code,
311
+ redirect_uri=redirect_uri,
312
+ verify=verify,
313
+ timeout=timeout,
314
+ )
315
+
316
+ async def fetch_refresh_token(
317
+ self,
318
+ token_url: str,
319
+ client_id: str,
320
+ client_secret: str,
321
+ refresh_token: str,
322
+ scope: Optional[str] = None,
323
+ verify: Union[bool, str] = True,
324
+ timeout: float = 30.0,
325
+ ) -> Dict[str, Any]:
326
+ """Execute Refresh Token flow with retry logic.
327
+
328
+ See OAuth2Client.fetch_refresh_token for parameter details.
329
+ """
330
+ return await self._execute_with_retry(
331
+ self._base_client.fetch_refresh_token,
332
+ token_url=token_url,
333
+ client_id=client_id,
334
+ client_secret=client_secret,
335
+ refresh_token=refresh_token,
336
+ scope=scope,
337
+ verify=verify,
338
+ timeout=timeout,
339
+ )
340
+
341
+ async def _execute_with_retry(self, func, **kwargs) -> Dict[str, Any]:
342
+ """Execute a function with retry logic.
343
+
344
+ Args:
345
+ func: Async function to execute
346
+ **kwargs: Arguments to pass to the function
347
+
348
+ Returns:
349
+ Result from the function
350
+
351
+ Raises:
352
+ Exception: Last exception if all retries are exhausted
353
+ """
354
+ last_exception = None
355
+
356
+ for attempt in range(self._max_retries + 1):
357
+ try:
358
+ return await func(**kwargs)
359
+
360
+ except httpx.HTTPStatusError as e:
361
+ last_exception = e
362
+ # Don't retry on 4xx errors (client errors)
363
+ if 400 <= e.response.status_code < 500:
364
+ logger.error(
365
+ "OAuth token request failed with client error %d: %s",
366
+ e.response.status_code,
367
+ e.response.text,
368
+ )
369
+ raise
370
+
371
+ logger.warning(
372
+ "OAuth token request failed with status %d (attempt %d/%d): %s",
373
+ e.response.status_code,
374
+ attempt + 1,
375
+ self._max_retries + 1,
376
+ e.response.text,
377
+ )
378
+
379
+ except httpx.RequestError as e:
380
+ last_exception = e
381
+ logger.warning(
382
+ "OAuth token request failed (attempt %d/%d): %s",
383
+ attempt + 1,
384
+ self._max_retries + 1,
385
+ str(e),
386
+ )
387
+
388
+ except Exception as e:
389
+ last_exception = e
390
+ logger.error("Unexpected error during OAuth token fetch: %s", str(e))
391
+ raise
392
+
393
+ # Exponential backoff with optional jitter
394
+ if attempt < self._max_retries:
395
+ delay = self._backoff_base**attempt
396
+ if self._backoff_jitter:
397
+ delay += random.uniform(0, 1)
398
+ logger.info("Retrying OAuth token request in %.2f seconds", delay)
399
+ await asyncio.sleep(delay)
400
+
401
+ # All retries exhausted
402
+ logger.error(
403
+ "OAuth token request failed after %d attempts", self._max_retries + 1
404
+ )
405
+ if last_exception:
406
+ raise last_exception
407
+ else:
408
+ raise RuntimeError("OAuth token request failed after all retries")
@@ -0,0 +1,50 @@
1
+ """Utility functions for OAuth 2.0 operations."""
2
+
3
+ import time
4
+ from urllib.parse import urlparse
5
+
6
+
7
+ def validate_https_url(url: str) -> None:
8
+ """Validate that a URL uses HTTPS scheme.
9
+
10
+ OAuth 2.0 requires HTTPS for security when transmitting credentials.
11
+
12
+ Args:
13
+ url: The URL to validate
14
+
15
+ Raises:
16
+ ValueError: If the URL does not use HTTPS scheme
17
+ """
18
+ parsed_url = urlparse(url)
19
+ if parsed_url.scheme != "https":
20
+ raise ValueError(
21
+ f"OAuth 2.0 URLs must use HTTPS for security. "
22
+ f"Got scheme: {parsed_url.scheme}"
23
+ )
24
+
25
+
26
+ def calculate_expires_at(expires_in: int) -> float:
27
+ """Calculate expiration timestamp from expires_in seconds.
28
+
29
+ Args:
30
+ expires_in: Number of seconds until token expires
31
+
32
+ Returns:
33
+ Unix timestamp (float) when the token will expire
34
+ """
35
+ return time.time() + expires_in
36
+
37
+
38
+ def is_token_expired(expires_at: float, buffer_seconds: int = 0) -> bool:
39
+ """Check if a token is expired or will expire within buffer time.
40
+
41
+ Args:
42
+ expires_at: Unix timestamp when token expires
43
+ buffer_seconds: Optional buffer to consider token expired early
44
+ (useful for proactive refresh)
45
+
46
+ Returns:
47
+ True if token is expired or within buffer time of expiring
48
+ """
49
+ current_time = time.time()
50
+ return current_time >= (expires_at - buffer_seconds)
@@ -0,0 +1,156 @@
1
+ """
2
+ Pydantic models for RAG (Retrieval-Augmented Generation) metadata.
3
+ Handles automatic conversion between snake_case (backend) and camelCase (frontend).
4
+
5
+ This module is placed in common/ to be shared across different components
6
+ (agent tools, gateway, etc.) without creating cross-layer dependencies.
7
+ """
8
+
9
+ from typing import Any, Dict, List, Optional
10
+ from pydantic import BaseModel, Field
11
+
12
+
13
+ class RAGSourceResponse(BaseModel):
14
+ """Schema for RAG source with automatic snake_case to camelCase conversion"""
15
+ citation_id: str = Field(..., alias="citationId", description="Unique citation ID")
16
+ file_id: Optional[str] = Field(None, alias="fileId", description="File identifier")
17
+ filename: Optional[str] = Field(None, description="Filename or title")
18
+ title: Optional[str] = Field(None, description="Source title")
19
+ source_type: Optional[str] = Field(None, alias="sourceType", description="Type of source (web, kb, etc.)")
20
+ source_url: Optional[str] = Field(None, alias="sourceUrl", description="Source URL")
21
+ url: Optional[str] = Field(None, description="Alternative URL field")
22
+ content_preview: str = Field(..., alias="contentPreview", description="Preview of content")
23
+ relevance_score: float = Field(..., alias="relevanceScore", description="Relevance score (0-1)")
24
+ retrieved_at: Optional[str] = Field(None, alias="retrievedAt", description="Timestamp when retrieved")
25
+ metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
26
+
27
+ class Config:
28
+ from_attributes = True
29
+ populate_by_name = True # Accept both snake_case and camelCase
30
+ by_alias = True # Serialize using aliases (camelCase)
31
+
32
+
33
+ class RAGQueryInfo(BaseModel):
34
+ """Schema for query information in RAG metadata"""
35
+ query: str = Field(..., description="Search query")
36
+ timestamp: str = Field(..., description="Query timestamp")
37
+ source_citation_ids: List[str] = Field(..., alias="sourceCitationIds", description="Citation IDs for this query")
38
+
39
+ class Config:
40
+ populate_by_name = True
41
+ by_alias = True
42
+
43
+
44
+ class RAGMetadata(BaseModel):
45
+ """Schema for RAG metadata"""
46
+ queries: Optional[List[RAGQueryInfo]] = Field(None, description="Query breakdown for timeline")
47
+
48
+ class Config:
49
+ populate_by_name = True
50
+ by_alias = True
51
+ extra = "allow" # Allow additional fields
52
+
53
+
54
+ class RAGSearchResultResponse(BaseModel):
55
+ """Schema for RAG search result with automatic snake_case to camelCase conversion"""
56
+ query: str = Field(..., description="Search query")
57
+ title: Optional[str] = Field(None, description="Human-readable title for the research (generated by LLM)")
58
+ search_type: str = Field(..., alias="searchType", description="Type of search (file_search, kb_search, deep_research, web_search)")
59
+ turn_number: Optional[int] = Field(None, alias="turnNumber", description="Turn number for citation tracking")
60
+ timestamp: str = Field(..., description="Search timestamp")
61
+ sources: List[RAGSourceResponse] = Field(default_factory=list, description="List of sources")
62
+ task_id: Optional[str] = Field(None, alias="taskId", description="Associated task ID")
63
+ metadata: Optional[RAGMetadata] = Field(None, description="Additional metadata")
64
+
65
+ class Config:
66
+ from_attributes = True
67
+ populate_by_name = True
68
+ by_alias = True
69
+
70
+
71
+ def create_rag_source(
72
+ citation_id: str,
73
+ content_preview: str,
74
+ relevance_score: float,
75
+ file_id: Optional[str] = None,
76
+ filename: Optional[str] = None,
77
+ title: Optional[str] = None,
78
+ source_type: Optional[str] = None,
79
+ source_url: Optional[str] = None,
80
+ url: Optional[str] = None,
81
+ retrieved_at: Optional[str] = None,
82
+ metadata: Optional[Dict[str, Any]] = None
83
+ ) -> Dict[str, Any]:
84
+ """
85
+ Helper function to create a RAG source dict that will be automatically
86
+ converted to camelCase when serialized through RAGSourceResponse.
87
+
88
+ Returns a dict that can be passed to RAGSourceResponse for serialization.
89
+ """
90
+ source = RAGSourceResponse(
91
+ citation_id=citation_id,
92
+ file_id=file_id,
93
+ filename=filename,
94
+ title=title,
95
+ source_type=source_type,
96
+ source_url=source_url,
97
+ url=url,
98
+ content_preview=content_preview,
99
+ relevance_score=relevance_score,
100
+ retrieved_at=retrieved_at,
101
+ metadata=metadata or {}
102
+ )
103
+ return source.model_dump(by_alias=True)
104
+
105
+
106
+ def create_rag_search_result(
107
+ query: str,
108
+ search_type: str,
109
+ timestamp: str,
110
+ sources: List[Dict[str, Any]],
111
+ task_id: Optional[str] = None,
112
+ turn_number: Optional[int] = None,
113
+ metadata: Optional[Dict[str, Any]] = None,
114
+ title: Optional[str] = None
115
+ ) -> Dict[str, Any]:
116
+ """
117
+ Helper function to create a RAG search result dict that will be automatically
118
+ converted to camelCase when serialized through RAGSearchResultResponse.
119
+
120
+ Args:
121
+ query: Search query
122
+ search_type: Type of search (file_search, kb_search, deep_research, web_search)
123
+ timestamp: Search timestamp
124
+ sources: List of source dicts (will be converted to RAGSourceResponse)
125
+ task_id: Optional task ID
126
+ turn_number: Optional turn number
127
+ metadata: Optional metadata dict
128
+ title: Optional human-readable title (generated by LLM for deep research)
129
+
130
+ Returns a dict with camelCase keys ready for frontend consumption.
131
+ """
132
+ # Convert source dicts to RAGSourceResponse for proper serialization
133
+ source_responses = [RAGSourceResponse(**src) for src in sources]
134
+
135
+ # Create metadata if provided
136
+ rag_metadata = None
137
+ if metadata:
138
+ # Convert queries if present
139
+ if "queries" in metadata:
140
+ query_infos = [RAGQueryInfo(**q) for q in metadata["queries"]]
141
+ rag_metadata = RAGMetadata(queries=query_infos, **{k: v for k, v in metadata.items() if k != "queries"})
142
+ else:
143
+ rag_metadata = RAGMetadata(**metadata)
144
+
145
+ result = RAGSearchResultResponse(
146
+ query=query,
147
+ title=title,
148
+ search_type=search_type,
149
+ timestamp=timestamp,
150
+ sources=source_responses,
151
+ task_id=task_id,
152
+ turn_number=turn_number,
153
+ metadata=rag_metadata
154
+ )
155
+
156
+ return result.model_dump(by_alias=True)