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 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1537],{9377:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/developing/tutorials/rag-integration","title":"RAG Integration","description":"This tutorial guides you through setting up and configuring Agent Mesh Retrieval Augmented Generation (RAG) plugin. The RAG plugin enables your agents to answer questions by retrieving information from a knowledge base of your documents.","source":"@site/docs/documentation/developing/tutorials/rag-integration.md","sourceDirName":"documentation/developing/tutorials","slug":"/documentation/developing/tutorials/rag-integration","permalink":"/solace-agent-mesh/docs/documentation/developing/tutorials/rag-integration","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/developing/tutorials/rag-integration.md","tags":[],"version":"current","sidebarPosition":70,"frontMatter":{"title":"RAG Integration","sidebar_position":70,"toc_max_heading_level":4},"sidebar":"docSidebar","previous":{"title":"Slack Integration","permalink":"/solace-agent-mesh/docs/documentation/developing/tutorials/slack-integration"},"next":{"title":"Microsoft Teams Integration (Enterprise)","permalink":"/solace-agent-mesh/docs/documentation/developing/tutorials/teams-integration"}}');var r=t(4848),a=t(8453);const o={title:"RAG Integration",sidebar_position:70,toc_max_heading_level:4},s="RAG Integration",l={},c=[{value:"What is Agent Mesh RAG?",id:"what-is-agent-mesh-rag",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Adding the RAG Plugin",id:"adding-the-rag-plugin",level:2},{value:"Configuring the RAG Agent",id:"configuring-the-rag-agent",level:2},{value:"Shared Configuration",id:"shared-configuration",level:3},{value:"RAG Pipeline Configuration",id:"rag-pipeline-configuration",level:3},{value:"1. Scanner Configuration",id:"1-scanner-configuration",level:4},{value:"2. Preprocessor Configuration",id:"2-preprocessor-configuration",level:4},{value:"3. Splitter Configuration",id:"3-splitter-configuration",level:4},{value:"4. Embedding Configuration",id:"4-embedding-configuration",level:4},{value:"5. Vector Database Configuration",id:"5-vector-database-configuration",level:4},{value:"6. LLM Configuration",id:"6-llm-configuration",level:4},{value:"7. Retrieval Configuration",id:"7-retrieval-configuration",level:4},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Running the RAG Agent",id:"running-the-rag-agent",level:2},{value:"Testing the RAG Agent",id:"testing-the-rag-agent",level:2},{value:"Ingesting Documents",id:"ingesting-documents",level:3},{value:"Option 1: Automatic Scanning (Batch Ingestion)",id:"option-1-automatic-scanning-batch-ingestion",level:4},{value:"Option 2: Manual Upload via Gateway",id:"option-2-manual-upload-via-gateway",level:4},{value:"Querying the Knowledge Base",id:"querying-the-knowledge-base",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"rag-integration",children:"RAG Integration"})}),"\n",(0,r.jsx)(n.p,{children:"This tutorial guides you through setting up and configuring Agent Mesh Retrieval Augmented Generation (RAG) plugin. The RAG plugin enables your agents to answer questions by retrieving information from a knowledge base of your documents."}),"\n",(0,r.jsx)(n.h2,{id:"what-is-agent-mesh-rag",children:"What is Agent Mesh RAG?"}),"\n",(0,r.jsx)(n.p,{children:"The Agent Mesh RAG plugin enhances your agents with the ability to perform retrieval-augmented generation. This means the agent can:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Scan"})," documents from various sources (local filesystem, Google Drive, etc.)."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Preprocess"})," and ",(0,r.jsx)(n.strong,{children:"split"})," the text into manageable chunks."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Embed"})," these chunks into vectors and store them in a vector database."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Retrieve"})," relevant chunks of text based on a user's query."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Generate"})," an answer using a large language model (LLM) augmented with the retrieved information."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This allows you to build agents that can answer questions about your own private data."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.p,{children:"Before you begin, ensure you have:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/installation",children:"Installed Agent Mesh and the Agent Mesh CLI"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/run-project",children:"Created a new Agent Mesh project"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Access to a vector database (for example, Qdrant, Chroma, and Pinecone)."}),"\n",(0,r.jsx)(n.li,{children:"Access to an LLM for generation and an embedding model."}),"\n",(0,r.jsx)(n.li,{children:"A directory with some documents for the agent to ingest."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"adding-the-rag-plugin",children:"Adding the RAG Plugin"}),"\n",(0,r.jsx)(n.p,{children:"To add the RAG plugin to your Agent Mesh project, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"sam plugin add my-rag-agent --plugin sam-rag\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Replace ",(0,r.jsx)(n.code,{children:"my-rag-agent"})," with your preferred agent name. This command:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Installs the ",(0,r.jsx)(n.code,{children:"sam-rag"})," plugin."]}),"\n",(0,r.jsxs)(n.li,{children:["Creates a new agent configuration file at ",(0,r.jsx)(n.code,{children:"configs/agents/my-rag-agent.yaml"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"configuring-the-rag-agent",children:"Configuring the RAG Agent"}),"\n",(0,r.jsxs)(n.p,{children:["The RAG agent requires a detailed configuration. Open ",(0,r.jsx)(n.code,{children:"configs/agents/my-rag-agent.yaml"})," to configure the following sections:"]}),"\n",(0,r.jsx)(n.h3,{id:"shared-configuration",children:"Shared Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Like other agents, the RAG agent needs a connection to the Solace broker and a configured LLM. This is typically done in a ",(0,r.jsx)(n.code,{children:"shared_config.yaml"})," file."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"# configs/shared_config.yaml\nshared_config:\n - broker_connection: &broker_connection\n dev_mode: ${SOLACE_DEV_MODE, false}\n broker_url: ${SOLACE_BROKER_URL, ws://localhost:8008}\n broker_username: ${SOLACE_BROKER_USERNAME, default}\n broker_password: ${SOLACE_BROKER_PASSWORD, default}\n broker_vpn: ${SOLACE_BROKER_VPN, default}\n temporary_queue: ${USE_TEMPORARY_QUEUES, true}\n\n - models:\n general: &general_model\n model: ${LLM_SERVICE_GENERAL_MODEL_NAME}\n api_base: ${LLM_SERVICE_ENDPOINT}\n api_key: ${LLM_SERVICE_API_KEY}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"rag-pipeline-configuration",children:"RAG Pipeline Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["The RAG pipeline has several stages, each with its own configuration block within the ",(0,r.jsx)(n.code,{children:"app_config"})," section of your ",(0,r.jsx)(n.code,{children:"my-rag-agent.yaml"})," file."]}),"\n",(0,r.jsx)(n.h4,{id:"1-scanner-configuration",children:"1. Scanner Configuration"}),"\n",(0,r.jsx)(n.p,{children:"The scanner discovers documents to be ingested. You can configure it to scan a local filesystem or cloud sources."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Local Filesystem Example:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'scanner:\n batch: true\n use_memory_storage: true\n source:\n type: filesystem\n directories:\n - "/path/to/your/documents" # Important: Replace with your actual document directory path\n filters:\n file_formats:\n - ".txt"\n - ".pdf"\n - ".md"\n'})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Multi-Cloud Source Example:"}),"\nYou can also configure multiple sources, including Google Drive, OneDrive, and S3."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'scanner:\n batch: true\n use_memory_storage: true\n sources:\n - type: filesystem\n directories: ["${LOCAL_DOCUMENTS_PATH}"]\n - type: google_drive\n credentials_path: "${GOOGLE_DRIVE_CREDENTIALS_PATH}"\n folders:\n - folder_id: "${GOOGLE_DRIVE_FOLDER_ID_1}"\n name: "Documents"\n recursive: true\n'})}),"\n",(0,r.jsx)(n.h4,{id:"2-preprocessor-configuration",children:"2. Preprocessor Configuration"}),"\n",(0,r.jsx)(n.p,{children:"The preprocessor cleans the text extracted from documents."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"preprocessor:\n default_preprocessor:\n type: enhanced\n params:\n lowercase: true\n normalize_whitespace: true\n remove_urls: true\n preprocessors:\n pdf: \n type: document\n params:\n lowercase: true\n normalize_whitespace: true\n remove_non_ascii: true\n remove_urls: true\n"})}),"\n",(0,r.jsx)(n.h4,{id:"3-splitter-configuration",children:"3. Splitter Configuration"}),"\n",(0,r.jsx)(n.p,{children:"The splitter breaks down large documents into smaller chunks. Different splitters are available for different file types."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"splitter:\n default_splitter:\n type: recursive_character\n params:\n chunk_size: 2048\n chunk_overlap: 400\n splitters:\n markdown:\n type: markdown\n params:\n chunk_size: 2048\n chunk_overlap: 400\n pdf:\n type: token\n params:\n chunk_size: 500\n chunk_overlap: 100\n"})}),"\n",(0,r.jsx)(n.h4,{id:"4-embedding-configuration",children:"4. Embedding Configuration"}),"\n",(0,r.jsx)(n.p,{children:"This section defines the model used to create vector embeddings from the text chunks."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'embedding:\n embedder_type: "openai"\n embedder_params:\n model: "${OPENAI_EMBEDDING_MODEL}"\n api_key: "${OPENAI_API_KEY}"\n api_base: "${OPENAI_API_ENDPOINT}"\n normalize_embeddings: true\n'})}),"\n",(0,r.jsx)(n.h4,{id:"5-vector-database-configuration",children:"5. Vector Database Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Configure the connection to your vector database where the embeddings are stored."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Qdrant Example:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'vector_db:\n db_type: "qdrant"\n db_params:\n url: "${QDRANT_URL}"\n api_key: "${QDRANT_API_KEY}"\n collection_name: "${QDRANT_COLLECTION}"\n embedding_dimension: ${QDRANT_EMBEDDING_DIMENSION}\n'})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Chroma Example:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'vector_db:\n db_type: "chroma"\n db_params:\n host: "${CHROMA_HOST}"\n port: "${CHROMA_PORT}"\n collection_name: "${CHROMA_COLLECTION}"\n'})}),"\n",(0,r.jsx)(n.h4,{id:"6-llm-configuration",children:"6. LLM Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Configure the LLM that is used to generate answers based on the retrieved context."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'llm:\n load_balancer:\n - model_name: "gpt-4o"\n litellm_params:\n model: "openai/${OPENAI_MODEL_NAME}"\n api_key: "${OPENAI_API_KEY}"\n api_base: "${OPENAI_API_ENDPOINT}"\n'})}),"\n",(0,r.jsx)(n.h4,{id:"7-retrieval-configuration",children:"7. Retrieval Configuration"}),"\n",(0,r.jsx)(n.p,{children:"This defines how many document chunks are retrieved to answer a query."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"retrieval:\n top_k: 7\n"})}),"\n",(0,r.jsx)(n.h3,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,r.jsxs)(n.p,{children:["The RAG agent relies heavily on environment variables. Here are some of the most important ones you'll need to set in your ",(0,r.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'# Solace Connection\nSOLACE_BROKER_URL=ws://localhost:8008\nSOLACE_BROKER_VPN=default\nSOLACE_BROKER_USERNAME=default\nSOLACE_BROKER_PASSWORD=default\nNAMESPACE=my-org/dev\n\n# LLM and Embedding Models\nOPENAI_API_KEY="your-openai-api-key"\nOPENAI_API_ENDPOINT="your-openai-api-endpoint"\nOPENAI_MODEL_NAME="model name. E.g., gpt-4o"\nOPENAI_EMBEDDING_MODEL="embedding model name. E.g., text-embedding-3-small"\n\n# Vector Database (Qdrant example)\nQDRANT_URL="Qdrant url"\nQDRANT_API_KEY="API key"\nQDRANT_COLLECTION="my-rag-collection"\nQDRANT_EMBEDDING_DIMENSION=1536 # Depends on your embedding model\n\n# Scanner\nDOCUMENTS_PATH="./my_documents" # Relative path to your documents folder\n'})}),"\n",(0,r.jsxs)(n.p,{children:["Create a directory named ",(0,r.jsx)(n.code,{children:"my_documents"})," in your project root and place some text or markdown files inside it."]}),"\n",(0,r.jsx)(n.h2,{id:"running-the-rag-agent",children:"Running the RAG Agent"}),"\n",(0,r.jsx)(n.p,{children:"Once you have configured your agent and set the environment variables, you can run it:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"sam run configs/agents/my-rag-agent.yaml\n"})}),"\n",(0,r.jsx)(n.p,{children:"When the agent starts, it begins scanning the documents in the configured source, processing and ingesting them into your vector database. This process may take some time, depending on the number and size of your documents."}),"\n",(0,r.jsx)(n.h2,{id:"testing-the-rag-agent",children:"Testing the RAG Agent"}),"\n",(0,r.jsx)(n.p,{children:"Once your agent is running, you can test its retrieval capabilities and ingest new documents."}),"\n",(0,r.jsx)(n.h3,{id:"ingesting-documents",children:"Ingesting Documents"}),"\n",(0,r.jsx)(n.p,{children:"There are two primary ways to ingest documents into your RAG agent's knowledge base:"}),"\n",(0,r.jsx)(n.h4,{id:"option-1-automatic-scanning-batch-ingestion",children:"Option 1: Automatic Scanning (Batch Ingestion)"}),"\n",(0,r.jsxs)(n.p,{children:["This method uses the configured ",(0,r.jsx)(n.code,{children:"scanner"})," component. The agent automatically ingests documents from the directories specified in your configuration upon startup."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 1: Create a Document"})}),"\n",(0,r.jsxs)(n.p,{children:["First, create a simple text file named ",(0,r.jsx)(n.code,{children:"sam_features.txt"})," and add some content to it. For example:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-text",children:"Agent Mesh is a powerful framework for building AI agents.\nKey features of Agent Mesh include:\n- A flexible plugin architecture.\n- Integration with various LLMs and vector databases.\n- Scalable gateways for different communication protocols.\n- An event-driven design based on Solace event broker.\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 2: Place the Document in the Scanned Directory"})}),"\n",(0,r.jsxs)(n.p,{children:['In the "Environment Variables" section, we configured ',(0,r.jsx)(n.code,{children:"LOCAL_DOCUMENTS_PATH"})," to point to a directory (e.g., ",(0,r.jsx)(n.code,{children:"./my_documents"}),")."]}),"\n",(0,r.jsxs)(n.p,{children:["Create this directory in your project's root folder if you haven't already, and move your ",(0,r.jsx)(n.code,{children:"sam_features.txt"})," file into it."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir -p my_documents\nmv sam_features.txt my_documents/\n"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 3: Run the Agent to Trigger Ingestion"})}),"\n",(0,r.jsx)(n.p,{children:"If your agent is already running, you'll need to restart it to trigger the batch scan. If it's not running, start it now:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"sam run configs/agents/my-rag-agent.yaml\n"})}),"\n",(0,r.jsx)(n.p,{children:"You will see logs indicating that the file is being processed. Once the agent is running and the initial scan is complete, the document is successfully ingested and ready for retrieval."}),"\n",(0,r.jsx)(n.h4,{id:"option-2-manual-upload-via-gateway",children:"Option 2: Manual Upload via Gateway"}),"\n",(0,r.jsx)(n.p,{children:"You can also ingest documents dynamically by uploading them directly through a gateway, like the Web UI. This is useful for adding single documents without restarting the agent. The RAG agent exposes a tool for this purpose."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 1: Start the RAG Agent and Web UI"})}),"\n",(0,r.jsx)(n.p,{children:"Ensure both your RAG agent and the Web UI gateway are running."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 2: Upload a Document in the Web UI"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Open the Web UI (usually at ",(0,r.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"}),", or check your gateway configuration for the correct URL) and start a chat with your RAG agent."]}),"\n",(0,r.jsx)(n.li,{children:"Use the file attachment button to select a document from your local machine."}),"\n",(0,r.jsxs)(n.li,{children:["Send a prompt along with the file, instructing the agent to ingest it. For example:","\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:'"Please ingest the attached document into your knowledge base."'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The RAG agent uses its ",(0,r.jsx)(n.code,{children:"built-in"})," ingest_document tool to process the file you uploaded. The file goes through the same preprocessing, splitting, and embedding pipeline as the documents from the automatic scan."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Step 3: Confirm Ingestion"})}),"\n",(0,r.jsx)(n.p,{children:"After the agent confirms that the document has been ingested, you can immediately ask questions about its content."}),"\n",(0,r.jsx)(n.h3,{id:"querying-the-knowledge-base",children:"Querying the Knowledge Base"}),"\n",(0,r.jsx)(n.p,{children:"You can interact with your RAG agent through any gateway, such as the Web UI gateway."}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Make sure you have a Web UI gateway running (or add one to your project)."}),"\n",(0,r.jsxs)(n.li,{children:["Open the Web UI (usually at ",(0,r.jsx)(n.code,{children:"http://localhost:8000"}),")."]}),"\n",(0,r.jsxs)(n.li,{children:["Start a conversation with ",(0,r.jsx)(n.code,{children:"my-rag-agent"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"Ask a question related to the content of the documents you provided during the initial scan."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you have a document about product features, you could ask:"}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:'"What are the key features of Product X?"'}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The agent searches its knowledge base, finds the relevant information, and generates an answer based on the content of your documents."}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Connection Errors"}),": Double-check all your URLs, API keys, and credentials for your LLM and vector database."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Ingestion Issues"}),": Check the agent logs for errors during the scanning, preprocessing, or embedding stages. Ensure the file formats are supported and the paths are correct."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"No Answers"}),": If the agent can't answer, it might be because the information is not in the documents, or the ",(0,r.jsx)(n.code,{children:"top_k"})," retrieval setting is too low."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var i=t(6540);const r={},a=i.createContext(r);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[3731],{7376:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>a});const s=JSON.parse('{"id":"documentation/enterprise/openapi-tools","title":"OpenAPI Tools","description":"This guide walks you through configuring OpenAPI-based tools for Agent Mesh Enterprise. You will learn how to integrate REST APIs into your agents using OpenAPI specifications, enabling them to interact with any OpenAPI-compliant service.","source":"@site/docs/documentation/enterprise/openapi-tools.md","sourceDirName":"documentation/enterprise","slug":"/documentation/enterprise/openapi-tools","permalink":"/solace-agent-mesh/docs/documentation/enterprise/openapi-tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/enterprise/openapi-tools.md","tags":[],"version":"current","sidebarPosition":16,"frontMatter":{"title":"OpenAPI Tools","sidebar_position":16},"sidebar":"docSidebar","previous":{"title":"Secure User Delegated Access","permalink":"/solace-agent-mesh/docs/documentation/enterprise/secure-user-delegated-access"}}');var t=i(4848),r=i(8453);const l={title:"OpenAPI Tools",sidebar_position:16},o=void 0,c={},a=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Overview",id:"overview",level:2},{value:"Why Use OpenAPI Tools",id:"why-use-openapi-tools",level:3},{value:"Supported Features",id:"supported-features",level:3},{value:"Understanding OpenAPI Tools",id:"understanding-openapi-tools",level:2},{value:"How OpenAPI Tools Work",id:"how-openapi-tools-work",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"OpenAPI Specification",id:"openapi-specification",level:3},{value:"API Access",id:"api-access",level:3},{value:"Target Server URL",id:"target-server-url",level:3},{value:"Configuration Steps",id:"configuration-steps",level:2},{value:"Basic Configuration Structure",id:"basic-configuration-structure",level:3},{value:"Configuration Parameters",id:"configuration-parameters",level:3},{value:"tool_type",id:"tool_type",level:4},{value:"Specification Source (Mutually Exclusive)",id:"specification-source-mutually-exclusive",level:4},{value:"base_url",id:"base_url",level:4},{value:"Complete Example",id:"complete-example",level:3},{value:"Tool Filtering",id:"tool-filtering",level:2},{value:"Why Filter Tools",id:"why-filter-tools",level:3},{value:"Filter Types",id:"filter-types",level:3},{value:"allow_list",id:"allow_list",level:4},{value:"deny_list",id:"deny_list",level:4},{value:"Filter Configuration",id:"filter-configuration",level:3},{value:"Filtering Examples",id:"filtering-examples",level:3},{value:"Authentication",id:"authentication",level:2},{value:"API Key Authentication",id:"api-key-authentication",level:3},{value:"Service Account Authentication",id:"service-account-authentication",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"Use Environment Variables for Secrets",id:"use-environment-variables-for-secrets",level:3},{value:"Fetch Specs from URLs When Possible",id:"fetch-specs-from-urls-when-possible",level:3},{value:"Use allow_list for Security-Sensitive APIs",id:"use-allow_list-for-security-sensitive-apis",level:3},{value:"Provide Clear Agent Instructions",id:"provide-clear-agent-instructions",level:3},{value:"Test with Local APIs First",id:"test-with-local-apis-first",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Specification Loading Fails",id:"specification-loading-fails",level:3},{value:"Tools Not Available to Agent",id:"tools-not-available-to-agent",level:3},{value:"Authentication Errors",id:"authentication-errors",level:3},{value:"API Calls Fail or Return Errors",id:"api-calls-fail-or-return-errors",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"This guide walks you through configuring OpenAPI-based tools for Agent Mesh Enterprise. You will learn how to integrate REST APIs into your agents using OpenAPI specifications, enabling them to interact with any OpenAPI-compliant service."}),"\n",(0,t.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#overview",children:"Overview"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#understanding-openapi-tools",children:"Understanding OpenAPI Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#configuration-steps",children:"Configuration Steps"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#tool-filtering",children:"Tool Filtering"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#authentication",children:"Authentication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#best-practices",children:"Best Practices"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#troubleshooting",children:"Troubleshooting"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsx)(n.p,{children:"OpenAPI Tools allow agents to interact with REST APIs by automatically generating tool definitions from OpenAPI (Swagger) specifications. This enables agents to call API endpoints as if they were native tools, with proper parameter validation, type checking, and documentation."}),"\n",(0,t.jsx)(n.h3,{id:"why-use-openapi-tools",children:"Why Use OpenAPI Tools"}),"\n",(0,t.jsx)(n.p,{children:"OpenAPI tools provide several important benefits for agent development:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Automatic Tool Generation"}),": Define REST API integrations declaratively using existing OpenAPI specifications. No manual tool implementation required."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Type Safety"}),": Parameter types, validation, and required fields are automatically enforced based on the OpenAPI schema."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Documentation"}),": Tool descriptions and parameter documentation are extracted from the OpenAPI spec, helping the AI model understand how to use each tool effectively."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Flexibility"}),": Support for multiple OpenAPI spec sources (files, URLs, inline), server URL overrides, and authentication methods."]}),"\n",(0,t.jsx)(n.h3,{id:"supported-features",children:"Supported Features"}),"\n",(0,t.jsx)(n.p,{children:"Agent Mesh Enterprise's OpenAPI tool integration supports:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"OpenAPI 3.0+ specifications"})," in JSON or YAML format"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Multiple specification sources"}),": local files, remote URLs, or inline specs"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Server URL overrides"}),": Point specs to different environments (development, staging, production)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Tool filtering"}),": Include or exclude specific API operations using allow/deny lists"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Authentication"}),": API key, and service account authentication"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Automatic name conversion"}),": Handles camelCase operation IDs correctly"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"understanding-openapi-tools",children:"Understanding OpenAPI Tools"}),"\n",(0,t.jsx)(n.p,{children:"Before you configure OpenAPI tools, you need to understand how they work and how API operations become callable tools."}),"\n",(0,t.jsx)(n.h3,{id:"how-openapi-tools-work",children:"How OpenAPI Tools Work"}),"\n",(0,t.jsx)(n.p,{children:"When you configure an OpenAPI tool, Agent Mesh Enterprise performs the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Specification Loading"}),": The system loads the OpenAPI specification from the configured source (file, URL, or inline)."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Operation Discovery"}),": Each path and HTTP method combination in the spec becomes a potential tool. The operation's ",(0,t.jsx)(n.code,{children:"operationId"})," becomes the tool name."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Schema Conversion"}),": OpenAPI parameter schemas are converted to the format expected by the AI model, including type information, validation rules, and descriptions."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Tool Registration"}),": Each operation is registered as a callable tool with the agent. The AI model can then invoke these tools by name."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Request Execution"}),": When the agent calls a tool, Agent Mesh Enterprise constructs the appropriate HTTP request based on the OpenAPI spec and executes it against the target API."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Response Handling"}),": API responses are returned to the agent and can be used in subsequent tool calls or included in the agent's response to the user."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"Before you configure OpenAPI tools, ensure you have the following:"}),"\n",(0,t.jsx)(n.h3,{id:"openapi-specification",children:"OpenAPI Specification"}),"\n",(0,t.jsx)(n.p,{children:"You need access to an OpenAPI specification for the API you want to integrate. This can be:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"A local OpenAPI spec file (JSON or YAML)"}),"\n",(0,t.jsx)(n.li,{children:"A URL to a remote OpenAPI spec"}),"\n",(0,t.jsx)(n.li,{children:"An inline OpenAPI spec defined in your configuration"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Most modern REST APIs provide OpenAPI specifications. Check the API provider's documentation for:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Swagger/OpenAPI spec download links"}),"\n",(0,t.jsx)(n.li,{children:"API documentation pages (often generated from the spec)"}),"\n",(0,t.jsx)(n.li,{children:"Developer portals that provide spec access"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"api-access",children:"API Access"}),"\n",(0,t.jsx)(n.p,{children:"Depending on the API's authentication requirements, you may need:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"API Keys"}),": For APIs using API key authentication"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Service Account"}),": For Google Cloud and similar services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Network Access"}),": Ensure your Agent Mesh Enterprise deployment can reach the API endpoints"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"target-server-url",children:"Target Server URL"}),"\n",(0,t.jsx)(n.p,{children:"If the OpenAPI spec's server URLs don't match your target environment, you'll need the correct base URL for the API. For example:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Spec may contain: ",(0,t.jsx)(n.code,{children:"https://api.production.com"})]}),"\n",(0,t.jsxs)(n.li,{children:["You may want to use: ",(0,t.jsx)(n.code,{children:"http://localhost:8080"})," (local development)"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"configuration-steps",children:"Configuration Steps"}),"\n",(0,t.jsx)(n.p,{children:"Configuring OpenAPI tools involves specifying the spec source, optional server URL override, authentication, and tool filtering."}),"\n",(0,t.jsx)(n.h3,{id:"basic-configuration-structure",children:"Basic Configuration Structure"}),"\n",(0,t.jsx)(n.p,{children:"An OpenAPI tool configuration follows this structure:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n base_url: "http://localhost:8080"\n auth:\n type: apikey\n in: header\n name: api_key\n value: ${API_KEY}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"configuration-parameters",children:"Configuration Parameters"}),"\n",(0,t.jsx)(n.h4,{id:"tool_type",children:"tool_type"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Required"}),": Yes"]}),"\n",(0,t.jsx)(n.p,{children:"Identifies this as an OpenAPI tool configuration."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"tool_type: openapi\n"})}),"\n",(0,t.jsx)(n.h4,{id:"specification-source-mutually-exclusive",children:"Specification Source (Mutually Exclusive)"}),"\n",(0,t.jsx)(n.p,{children:"You must provide exactly one of the following specification sources:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"specification_file"})," - Path to a local OpenAPI spec file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'specification_file: "examples/petstore_openapi.json"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"specification_url"})," - URL to fetch the OpenAPI spec from:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"specification"})," - Inline OpenAPI spec as a string:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'specification: |\n {\n "openapi": "3.0.0",\n "info": {\n "title": "My API",\n "version": "1.0.0"\n },\n "paths": {}\n }\nspecification_format: "json" # Optional: "json" or "yaml"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When using inline ",(0,t.jsx)(n.code,{children:"specification"}),", you can optionally provide ",(0,t.jsx)(n.code,{children:"specification_format"})," to hint at the format. The system auto-detects the format if not specified. Provide this only if auto-detection fails."]}),"\n",(0,t.jsx)(n.h4,{id:"base_url",children:"base_url"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Required"}),": No"]}),"\n",(0,t.jsx)(n.p,{children:"Override the server URLs in the OpenAPI specification. This is useful when:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The spec contains only a path (e.g., ",(0,t.jsx)(n.code,{children:"/api/v3"}),") without a base URL"]}),"\n",(0,t.jsx)(n.li,{children:"You want to point to a different environment (development, staging, production)"}),"\n",(0,t.jsx)(n.li,{children:"You're using a spec from one source but targeting a different server"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'base_url: "http://localhost:8080"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"How it works"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["If the original spec URL is ",(0,t.jsx)(n.code,{children:"/api/v3"})," and ",(0,t.jsx)(n.code,{children:"base_url"})," is ",(0,t.jsx)(n.code,{children:"http://localhost:8080"}),", the result is ",(0,t.jsx)(n.code,{children:"http://localhost:8080/api/v3"})]}),"\n",(0,t.jsxs)(n.li,{children:["If the original spec URL is ",(0,t.jsx)(n.code,{children:"https://petstore.swagger.io/api/v3"})," and ",(0,t.jsx)(n.code,{children:"base_url"})," is ",(0,t.jsx)(n.code,{children:"http://localhost:8080"}),", the result is ",(0,t.jsx)(n.code,{children:"http://localhost:8080/api/v3"})," (path is preserved, base is replaced)"]}),"\n",(0,t.jsx)(n.li,{children:"Duplicate slashes are automatically handled"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"complete-example",children:"Complete Example"}),"\n",(0,t.jsx)(n.p,{children:"Here's a complete agent configuration using an OpenAPI tool:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'apps:\n - name: pet_store_agent\n app_config:\n agent_name: "PetStoreAgent"\n display_name: "Pet Store API Agent"\n\n model: gemini-2.5-pro\n\n instruction: |\n You are a Pet Store API agent that can manage pets, orders, and users.\n Always provide the required fields when creating or updating resources.\n\n tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n base_url: "http://localhost:8080"\n auth:\n type: apikey\n in: header\n name: api_key\n value: ${PET_STORE_API_KEY}\n\n session_service:\n type: "sql"\n database_url: "${DATABASE_URL}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"tool-filtering",children:"Tool Filtering"}),"\n",(0,t.jsx)(n.p,{children:"OpenAPI specifications often include many operations, but you may only want to expose a subset to your agent. Tool filtering allows you to control which operations are available."}),"\n",(0,t.jsx)(n.h3,{id:"why-filter-tools",children:"Why Filter Tools"}),"\n",(0,t.jsx)(n.p,{children:"Filtering tools provides several benefits:"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Security"}),": Exclude dangerous or administrative operations from agent access."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Focused Agents"}),": Create specialized agents that only access relevant operations."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Performance"}),": Reduce the number of tools the AI model must consider, improving response time and accuracy."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Cost Control"}),": Fewer tools mean less token usage when the AI model selects tools."]}),"\n",(0,t.jsx)(n.h3,{id:"filter-types",children:"Filter Types"}),"\n",(0,t.jsx)(n.p,{children:"You can use two mutually exclusive filter types:"}),"\n",(0,t.jsx)(n.h4,{id:"allow_list",children:"allow_list"}),"\n",(0,t.jsx)(n.p,{children:"Include only specific operations. All other operations are excluded."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n allow_list:\n - "getPetById"\n - "findPetsByStatus"\n - "updatePet"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Use when"}),": You want explicit control over allowed operations, typically for security-sensitive APIs."]}),"\n",(0,t.jsx)(n.h4,{id:"deny_list",children:"deny_list"}),"\n",(0,t.jsx)(n.p,{children:"Exclude specific operations. All other operations are included."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n deny_list:\n - "deletePet"\n - "deleteOrder"\n - "deleteUser"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Use when"}),": You want most operations available but need to exclude a few dangerous or unnecessary ones."]}),"\n",(0,t.jsx)(n.h3,{id:"filter-configuration",children:"Filter Configuration"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Specifying Operation IDs"}),": Use the ",(0,t.jsx)(n.code,{children:"operationId"})," as they appear in the OpenAPI spec."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Finding Operation IDs"}),": Look in the OpenAPI spec under ",(0,t.jsx)(n.code,{children:"paths[path][method].operationId"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "paths": {\n "/pet/{petId}": {\n "get": {\n "operationId": "getPetById",\n "summary": "Find pet by ID"\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Mutual Exclusivity"}),": You cannot specify both ",(0,t.jsx)(n.code,{children:"allow_list"})," and ",(0,t.jsx)(n.code,{children:"deny_list"}),". The system will reject the configuration with a validation error."]}),"\n",(0,t.jsx)(n.h3,{id:"filtering-examples",children:"Filtering Examples"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Read-Only Agent"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n allow_list:\n - "getPetById"\n - "findPetsByStatus"\n - "findPetsByTags"\n - "getInventory"\n - "getOrderById"\n - "getUserByName"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Full Access Except Deletes"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: openapi\n specification_url: "https://petstore3.swagger.io/api/v3/openapi.json"\n deny_list:\n - "deletePet"\n - "deleteOrder"\n - "deleteUser"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"authentication",children:"Authentication"}),"\n",(0,t.jsx)(n.p,{children:"OpenAPI tools support two authentication methods: API key, and service account authentication."}),"\n",(0,t.jsx)(n.h3,{id:"api-key-authentication",children:"API Key Authentication"}),"\n",(0,t.jsx)(n.p,{children:"API key authentication sends a key in either the request header or query parameter."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'auth:\n type: apikey\n in: header # or "query"\n name: api_key\n value: ${API_KEY}\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Parameters"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"type"}),": Must be ",(0,t.jsx)(n.code,{children:'"apikey"'})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"in"}),": Where to send the key - ",(0,t.jsx)(n.code,{children:'"header"'})," or ",(0,t.jsx)(n.code,{children:'"query"'})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"name"}),": The name of the header or query parameter"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"value"}),": The API key value (use environment variables for security)"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"})," (header-based):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"auth:\n type: apikey\n in: header\n name: X-API-Key\n value: ${MY_API_KEY}\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"})," (query-based):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"auth:\n type: apikey\n in: query\n name: apikey\n value: ${MY_API_KEY}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"service-account-authentication",children:"Service Account Authentication"}),"\n",(0,t.jsx)(n.p,{children:"Service account authentication uses Google Cloud service account credentials."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'auth:\n type: serviceaccount\n service_account_json: ${SERVICE_ACCOUNT_JSON}\n scopes:\n - "https://www.googleapis.com/auth/cloud-platform"\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Parameters"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"type"}),": Must be ",(0,t.jsx)(n.code,{children:'"serviceaccount"'})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"service_account_json"}),": JSON string containing the service account credentials"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"scopes"}),": List of API scopes to request"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,t.jsx)(n.p,{children:"Following these best practices helps you deploy OpenAPI tools effectively."}),"\n",(0,t.jsx)(n.h3,{id:"use-environment-variables-for-secrets",children:"Use Environment Variables for Secrets"}),"\n",(0,t.jsx)(n.p,{children:"Never hardcode API keys or other credentials in configuration files:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# Good - use environment variables\nauth:\n type: apikey\n in: header\n name: api_key\n value: ${API_KEY}\n\n# Bad - hardcoded credentials\nauth:\n type: apikey\n in: header\n name: api_key\n value: "sk-1234567890abcdef" # Don\'t do this!\n'})}),"\n",(0,t.jsx)(n.h3,{id:"fetch-specs-from-urls-when-possible",children:"Fetch Specs from URLs When Possible"}),"\n",(0,t.jsx)(n.p,{children:"Fetching specs from URLs ensures you always use the latest version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# Good - fetches latest spec\nspecification_url: "https://api.example.com/openapi.json"\n\n# Less ideal - may become outdated\nspecification_file: "examples/api_spec.json"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Use local files only when:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The API doesn't provide a public spec URL"}),"\n",(0,t.jsx)(n.li,{children:"You need to use a modified or customized spec"}),"\n",(0,t.jsx)(n.li,{children:"You want to lock to a specific API version"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"use-allow_list-for-security-sensitive-apis",children:"Use allow_list for Security-Sensitive APIs"}),"\n",(0,t.jsxs)(n.p,{children:["For APIs with dangerous operations (delete, administrative functions), use ",(0,t.jsx)(n.code,{children:"allow_list"})," to explicitly control access:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'allow_list:\n - "getResource"\n - "listResources"\n - "updateResource"\n# Deliberately exclude "deleteResource"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"deny_list"})," only when you're confident about the safety of unlisted operations."]}),"\n",(0,t.jsx)(n.h3,{id:"provide-clear-agent-instructions",children:"Provide Clear Agent Instructions"}),"\n",(0,t.jsx)(n.p,{children:"Include guidance in your agent's instructions about the API and required parameters:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'instruction: |\n You are a Pet Store API agent.\n\n When creating pets:\n - name (required): The pet\'s name\n - photoUrls (required): Array of photo URLs\n - id (required): Unique integer ID\n - category: Optional object with id and name\n - status: "available", "pending", or "sold"\n\n Always validate required fields before making requests.\n'})}),"\n",(0,t.jsx)(n.h3,{id:"test-with-local-apis-first",children:"Test with Local APIs First"}),"\n",(0,t.jsx)(n.p,{children:"Test your configuration against local or development API instances before connecting to production:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# Development\nbase_url: "http://localhost:8080"\n\n# Production (after testing)\nbase_url: "https://api.production.com"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsx)(n.p,{children:"This section addresses common issues when configuring OpenAPI tools."}),"\n",(0,t.jsx)(n.h3,{id:"specification-loading-fails",children:"Specification Loading Fails"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Symptoms"}),": Agent fails to start with errors about loading or parsing the OpenAPI specification."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Possible Causes and Solutions"}),":"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Invalid Specification Format"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify the spec is valid JSON or YAML"}),"\n",(0,t.jsx)(n.li,{children:"Validate using online tools (Swagger Editor, OpenAPI Validator)"}),"\n",(0,t.jsx)(n.li,{children:"Check for syntax errors (missing commas, quotes, etc.)"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"URL Not Accessible"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.code,{children:"specification_url"})," is accessible from your deployment"]}),"\n",(0,t.jsx)(n.li,{children:"Check network connectivity and firewall rules"}),"\n",(0,t.jsx)(n.li,{children:"Ensure HTTPS certificates are valid"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"File Not Found"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.code,{children:"specification_file"})," path is correct relative to the working directory"]}),"\n",(0,t.jsx)(n.li,{children:"Check file permissions"}),"\n",(0,t.jsx)(n.li,{children:"Use absolute paths if relative paths fail"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"tools-not-available-to-agent",children:"Tools Not Available to Agent"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Symptoms"}),": The AI model reports that tools are not available or cannot be found."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Possible Causes and Solutions"}),":"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Filtering Excluded All Tools"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Review your ",(0,t.jsx)(n.code,{children:"allow_list"})," or ",(0,t.jsx)(n.code,{children:"deny_list"})," configuration"]}),"\n",(0,t.jsx)(n.li,{children:"Verify operation IDs match those in the spec (case-sensitive)"}),"\n",(0,t.jsx)(n.li,{children:"Check agent logs for tool loading messages"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Empty Specification"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the OpenAPI spec contains ",(0,t.jsx)(n.code,{children:"paths"})," with operations"]}),"\n",(0,t.jsxs)(n.li,{children:["Check that operations have ",(0,t.jsx)(n.code,{children:"operationId"})," fields"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"authentication-errors",children:"Authentication Errors"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Symptoms"}),": API calls fail with 401 or 403 errors."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Possible Causes and Solutions"}),":"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Invalid or Missing Credentials"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify environment variables are set correctly"}),"\n",(0,t.jsx)(n.li,{children:"Check that credentials haven't expired"}),"\n",(0,t.jsx)(n.li,{children:"Test credentials directly with the API using curl or Postman"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Wrong Authentication Location"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify ",(0,t.jsx)(n.code,{children:"in: header"})," vs ",(0,t.jsx)(n.code,{children:"in: query"})," matches API requirements"]}),"\n",(0,t.jsxs)(n.li,{children:["Check the ",(0,t.jsx)(n.code,{children:"name"})," parameter matches what the API expects"]}),"\n",(0,t.jsx)(n.li,{children:"Review API documentation for exact auth requirements"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"api-calls-fail-or-return-errors",children:"API Calls Fail or Return Errors"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Symptoms"}),": Tools execute but API returns errors or unexpected responses."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Possible Causes and Solutions"}),":"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Wrong Server URL"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify ",(0,t.jsx)(n.code,{children:"base_url"})," points to the correct environment"]}),"\n",(0,t.jsx)(n.li,{children:"Check that paths are correctly combined with base URL"}),"\n",(0,t.jsx)(n.li,{children:"Review server URL in agent logs"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Missing Required Parameters"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Review API error messages for missing parameters"}),"\n",(0,t.jsx)(n.li,{children:"Update agent instructions to include required parameter guidance"}),"\n",(0,t.jsx)(n.li,{children:"Check OpenAPI spec for parameter requirements"}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Type Mismatches"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify parameter types match spec (string vs integer, etc.)"}),"\n",(0,t.jsx)(n.li,{children:"Check that enum values are valid"}),"\n",(0,t.jsx)(n.li,{children:"Review validation errors in API responses"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,t.jsx)(n.p,{children:"OpenAPI tools provide a powerful way to integrate REST APIs into your agents without manual tool implementation. By following the configuration steps, authentication methods, and best practices in this guide, you can quickly enable agents to interact with any OpenAPI-compliant service."}),"\n",(0,t.jsx)(n.p,{children:"Key takeaways:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Use ",(0,t.jsx)(n.code,{children:"specification_url"})," to fetch specs from URLs when possible"]}),"\n",(0,t.jsxs)(n.li,{children:["Override server URLs with ",(0,t.jsx)(n.code,{children:"base_url"})," for environment-specific deployments"]}),"\n",(0,t.jsxs)(n.li,{children:["Filter tools using ",(0,t.jsx)(n.code,{children:"allow_list"})," (security-sensitive) or ",(0,t.jsx)(n.code,{children:"deny_list"})," (convenience)"]}),"\n",(0,t.jsx)(n.li,{children:"Always use environment variables for credentials"}),"\n",(0,t.jsx)(n.li,{children:"Use camelCase operation IDs in filter configurations"}),"\n",(0,t.jsx)(n.li,{children:"Test with local/development APIs before production deployment"}),"\n",(0,t.jsx)(n.li,{children:"Monitor tool usage and API errors through logging"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>o});var s=i(6540);const t={},r=s.createContext(t);function l(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[9489],{8730:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"documentation/enterprise/connectors/connectors","title":"Connectors","description":"Connectors link agents to external data sources and services. Each connector type provides access to different systems using configured credentials and connection details. Agents use connectors to retrieve information, execute queries, and interact with external platforms through natural language conversations.","source":"@site/docs/documentation/enterprise/connectors/connectors.md","sourceDirName":"documentation/enterprise/connectors","slug":"/documentation/enterprise/connectors/","permalink":"/solace-agent-mesh/docs/documentation/enterprise/connectors/","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/enterprise/connectors/connectors.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Connectors","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Agent Builder","permalink":"/solace-agent-mesh/docs/documentation/enterprise/agent-builder"},"next":{"title":"Setting Up RBAC","permalink":"/solace-agent-mesh/docs/documentation/enterprise/rbac-setup-guide"}}');var a=t(4848),o=t(8453);const i={title:"Connectors",sidebar_position:10},r="Connectors",c={},d=[{value:"SQL Connectors",id:"sql-connectors",level:2},{value:"Supported Databases",id:"supported-databases",level:3},{value:"Creating SQL Connectors",id:"creating-sql-connectors",level:3},{value:"Security Considerations",id:"security-considerations",level:3},{value:"Shared Credential Architecture",id:"shared-credential-architecture",level:4},{value:"Implementing Database-Level Security",id:"implementing-database-level-security",level:4},{value:"Natural Language Query Risks",id:"natural-language-query-risks",level:4},{value:"Best Practices",id:"best-practices",level:4},{value:"Assigning Connectors to Agents",id:"assigning-connectors-to-agents",level:3},{value:"Managing Connectors",id:"managing-connectors",level:3},{value:"Editing Connectors",id:"editing-connectors",level:4},{value:"Testing Connections",id:"testing-connections",level:4},{value:"Deleting Connectors",id:"deleting-connectors",level:4},{value:"Troubleshooting",id:"troubleshooting",level:3},{value:"Access Control",id:"access-control",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"connectors",children:"Connectors"})}),"\n",(0,a.jsx)(n.p,{children:"Connectors link agents to external data sources and services. Each connector type provides access to different systems using configured credentials and connection details. Agents use connectors to retrieve information, execute queries, and interact with external platforms through natural language conversations."}),"\n",(0,a.jsx)(n.h2,{id:"sql-connectors",children:"SQL Connectors"}),"\n",(0,a.jsx)(n.p,{children:"SQL connectors enable agents to query and analyze database information using natural language. These connectors convert user questions into SQL queries, execute them against configured databases, and return results in a conversational format. This capability makes database information accessible through agent interactions without requiring users to write SQL code."}),"\n",(0,a.jsx)(n.h3,{id:"supported-databases",children:"Supported Databases"}),"\n",(0,a.jsx)(n.p,{children:"SQL connectors support three database types:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"MySQL"}),"\n",(0,a.jsx)(n.li,{children:"PostgreSQL"}),"\n",(0,a.jsx)(n.li,{children:"MariaDB"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Each database type follows the same configuration process but may have specific connection string requirements or authentication methods."}),"\n",(0,a.jsx)(n.h3,{id:"creating-sql-connectors",children:"Creating SQL Connectors"}),"\n",(0,a.jsx)(n.p,{children:"You create SQL connectors in the Connectors section of the Enterprise web interface. This process must be completed before you can assign connectors to agents."}),"\n",(0,a.jsx)(n.p,{children:"Each SQL connector configuration includes the database type selection, connection details (host address, port number, and database name), and authentication credentials (username and password). The connection configuration establishes a persistent connection pool that agents use to execute queries. You should verify that the database server allows connections from the Agent Mesh deployment and that any required firewall rules permit access."}),"\n",(0,a.jsx)(n.p,{children:"Once you create a connector, it becomes available for assignment to any agent in your deployment. This reusability means you can connect multiple agents to the same database without duplicating connection configuration. All agents assigned to a connector share the same database connection pool and credentials."}),"\n",(0,a.jsx)(n.h3,{id:"security-considerations",children:"Security Considerations"}),"\n",(0,a.jsx)(n.p,{children:"The framework implements a shared credential model that has significant implications for access control when planning your deployment architecture."}),"\n",(0,a.jsx)(n.h4,{id:"shared-credential-architecture",children:"Shared Credential Architecture"}),"\n",(0,a.jsx)(n.p,{children:"The framework does not sandbox database access at the agent level. All agents assigned to a connector share the same database credentials and permissions. This design means that any agent with the connector can access all data the connector's credentials permit. Security boundaries exist at the database level, not between agents."}),"\n",(0,a.jsx)(n.h4,{id:"implementing-database-level-security",children:"Implementing Database-Level Security"}),"\n",(0,a.jsx)(n.p,{children:"Database-level access control is your primary security mechanism. You should create database users with minimal necessary privileges, use database views or restricted schemas to limit what agents can access, and audit database queries to monitor what agents are accessing."}),"\n",(0,a.jsx)(n.p,{children:"For example, if you have agents that should only read customer data and other agents that need full database access, you must create separate connectors with different database users. Each database user has appropriate permissions configured at the database level. You cannot restrict access by assigning the same connector to different agents because all agents sharing a connector have identical database permissions."}),"\n",(0,a.jsx)(n.h4,{id:"natural-language-query-risks",children:"Natural Language Query Risks"}),"\n",(0,a.jsx)(n.p,{children:"The natural language to SQL conversion capability makes databases accessible through conversation, but this also means users can potentially request any data the connector can access. You should plan your database permissions accordingly and consider what information should be available through agent interactions."}),"\n",(0,a.jsx)(n.p,{children:"Users might phrase questions in ways that expose data you intended to restrict, or they might discover table and column names through exploratory questions. Database views that present only approved data columns, user accounts with read-only permissions on specific tables, and query result size limits all help mitigate these risks."}),"\n",(0,a.jsx)(n.h4,{id:"best-practices",children:"Best Practices"}),"\n",(0,a.jsx)(n.p,{children:"Create separate connectors for different security boundaries. If agents require different levels of database access, configure multiple connectors with appropriately scoped database users rather than sharing a single connector across all agents."}),"\n",(0,a.jsx)(n.p,{children:"Use read-only database accounts whenever possible. Many agent use cases only require reading data, and read-only permissions prevent accidental or malicious data modification."}),"\n",(0,a.jsx)(n.p,{children:"Implement database views to present filtered data. Views can hide sensitive columns, join tables to present aggregated information, or implement row-level security logic at the database level."}),"\n",(0,a.jsx)(n.p,{children:"Enable query logging and monitoring to track what agents access. Database audit logs help you detect suspicious query patterns or unauthorized data access attempts."}),"\n",(0,a.jsx)(n.h3,{id:"assigning-connectors-to-agents",children:"Assigning Connectors to Agents"}),"\n",(0,a.jsx)(n.p,{children:"You assign connectors to agents through Agent Builder. When creating or editing an agent, you select connectors from a list during agent configuration. You can assign connectors before or after deployment, and changes to connector assignments take effect when you deploy or update the agent."}),"\n",(0,a.jsx)(n.h3,{id:"managing-connectors",children:"Managing Connectors"}),"\n",(0,a.jsx)(n.p,{children:"Connector management operations require specific RBAC capabilities and follow particular patterns to prevent service disruptions."}),"\n",(0,a.jsx)(n.h4,{id:"editing-connectors",children:"Editing Connectors"}),"\n",(0,a.jsx)(n.p,{children:"You can modify connector configurations at any time. Changes to connection details or credentials take effect immediately for new database connections. Existing connections in the pool may continue using previous credentials until they expire and reconnect."}),"\n",(0,a.jsx)(n.p,{children:"If agents are actively using a connector when you modify it, query failures may occur during the transition period. You should plan connector updates during maintenance windows or coordinate with agent users to minimize disruptions."}),"\n",(0,a.jsx)(n.h4,{id:"testing-connections",children:"Testing Connections"}),"\n",(0,a.jsx)(n.p,{children:"The Connectors interface provides connection testing functionality that validates credentials and connectivity before you save the connector configuration. This testing helps identify configuration errors before agents attempt to use the connector."}),"\n",(0,a.jsx)(n.h4,{id:"deleting-connectors",children:"Deleting Connectors"}),"\n",(0,a.jsx)(n.p,{children:"You can delete connectors, but the system enforces restrictions to prevent breaking deployed agents. If any agents are assigned to a connector, you must first remove the connector from those agents or undeploy them before deletion succeeds."}),"\n",(0,a.jsx)(n.p,{children:"The deletion process removes the connector configuration but does not affect the database itself. Database users and permissions remain in place, requiring separate cleanup if you no longer need them."}),"\n",(0,a.jsx)(n.h3,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,a.jsx)(n.p,{children:"When connecting SAM to a PostgreSQL databases hosted on Supabase, you may encounter network errors like:"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.code,{children:'{ "detail": "Invalid token", "error_type": "invalid_token" }'})}),"\n",(0,a.jsx)(n.p,{children:"This is because Supabase's direct connection endpoint uses IPv6, however most Kubernetes clusters are IPv4 by default.\nThe solution is to use the Session Pooler endpoint as it is IPv4 compatible."}),"\n",(0,a.jsx)(n.h2,{id:"access-control",children:"Access Control"}),"\n",(0,a.jsx)(n.p,{children:"Connector operations require specific RBAC capabilities. The table below shows the capabilities and what they control:"}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Capability"}),(0,a.jsx)(n.th,{children:"Purpose"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"sam:connectors:create"})}),(0,a.jsx)(n.td,{children:"Create new connectors in the Connectors section"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"sam:connectors:read"})}),(0,a.jsx)(n.td,{children:"View connector configurations and list available connectors"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"sam:connectors:update"})}),(0,a.jsx)(n.td,{children:"Modify connector configurations and credentials"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"sam:connectors:delete"})}),(0,a.jsx)(n.td,{children:"Remove connectors from the system"})]})]})]}),"\n",(0,a.jsxs)(n.p,{children:["For detailed information about configuring role-based access control, see ",(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/rbac-setup-guide",children:"Setting Up RBAC"}),"."]})]})}function u(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var s=t(6540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[582],{4415:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"documentation/developing/create-gateways","title":"Creating Custom Gateways","description":"Gateway adapters connect external systems to the Agent Mesh through custom interfaces. They translate between platform-specific formats (Slack messages, HTTP requests, webhook payloads) and the standardized A2A protocol that agents understand. Gateway adapters handle platform events, extract user identity, and deliver agent responses back to users in the appropriate format.","source":"@site/docs/documentation/developing/create-gateways.md","sourceDirName":"documentation/developing","slug":"/documentation/developing/create-gateways","permalink":"/solace-agent-mesh/docs/documentation/developing/create-gateways","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/developing/create-gateways.md","tags":[],"version":"current","sidebarPosition":430,"frontMatter":{"title":"Creating Custom Gateways","sidebar_position":430},"sidebar":"docSidebar","previous":{"title":"Creating Agents","permalink":"/solace-agent-mesh/docs/documentation/developing/create-agents"},"next":{"title":"Creating Python Tools","permalink":"/solace-agent-mesh/docs/documentation/developing/creating-python-tools"}}');var s=t(4848),r=t(8453);const i={title:"Creating Custom Gateways",sidebar_position:430},o="Creating Custom Gateways",l={},c=[{value:"Key Functions",id:"key-functions",level:2},{value:"Architecture Overview",id:"architecture-overview",level:2},{value:"Core Concepts",id:"core-concepts",level:2},{value:"The Gateway Adapter Contract",id:"the-gateway-adapter-contract",level:3},{value:"The Gateway Context",id:"the-gateway-context",level:3},{value:"The Type System",id:"the-type-system",level:3},{value:"Adapter Lifecycle",id:"adapter-lifecycle",level:2},{value:"Initialization",id:"initialization",level:3},{value:"Active Processing",id:"active-processing",level:3},{value:"Cleanup",id:"cleanup",level:3},{value:"Implementing an Adapter",id:"implementing-an-adapter",level:2},{value:"Required Configuration",id:"required-configuration",level:3},{value:"Authentication: extract_auth_claims()",id:"authentication-extract_auth_claims",level:3},{value:"Inbound: prepare_task()",id:"inbound-prepare_task",level:3},{value:"Outbound: handle_update()",id:"outbound-handle_update",level:3},{value:"Completion: handle_task_complete()",id:"completion-handle_task_complete",level:3},{value:"Error Handling: handle_error()",id:"error-handling-handle_error",level:3},{value:"Gateway Context Services",id:"gateway-context-services",level:2},{value:"Task Management",id:"task-management",level:3},{value:"Artifact Management",id:"artifact-management",level:3},{value:"Feedback Collection",id:"feedback-collection",level:3},{value:"State Management",id:"state-management",level:3},{value:"Timer Management",id:"timer-management",level:3},{value:"Configuration",id:"configuration",level:2},{value:"Example: Slack Adapter",id:"example-slack-adapter",level:2},{value:"Configuration Model",id:"configuration-model",level:3},{value:"Authentication with Caching",id:"authentication-with-caching",level:3},{value:"Streaming Updates with Message Queue",id:"streaming-updates-with-message-queue",level:3},{value:"Creating Your Own Adapter",id:"creating-your-own-adapter",level:2},{value:"Option 1: Create as a Plugin (Recommended)",id:"option-1-create-as-a-plugin-recommended",level:3},{value:"Option 2: Add to Existing Project",id:"option-2-add-to-existing-project",level:3},{value:"Advanced: Full Custom Gateways",id:"advanced-full-custom-gateways",level:2},{value:"Related Documentation",id:"related-documentation",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"creating-custom-gateways",children:"Creating Custom Gateways"})}),"\n",(0,s.jsx)(n.p,{children:"Gateway adapters connect external systems to the Agent Mesh through custom interfaces. They translate between platform-specific formats (Slack messages, HTTP requests, webhook payloads) and the standardized A2A protocol that agents understand. Gateway adapters handle platform events, extract user identity, and deliver agent responses back to users in the appropriate format."}),"\n",(0,s.jsx)(n.p,{children:"This guide walks you through creating custom gateways using the gateway adapter pattern."}),"\n",(0,s.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,s.jsx)(n.p,{children:"Gateway adapters are custom interfaces that connect external platforms to the agent mesh by translating events and responses between platform formats and the A2A protocol."})}),"\n",(0,s.jsx)(n.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,s.jsx)(n.p,{children:"Gateway adapters provide the following capabilities:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Platform Integration"}),": Connect external systems such as Slack, webhooks, REST APIs, or custom protocols to the agent mesh. Handle incoming events, commands, and messages from these platforms."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Authentication"}),": Extract user identity from platform events (OAuth tokens, API keys, platform user IDs) and integrate with identity providers for user enrichment."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Message Translation"}),": Convert platform-specific message formats into standardized content that agents can process. Transform agent responses back into platform-native formats."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Streaming Responses"}),": Deliver real-time updates from agents to users as they are generated. Handle text streaming, status updates, and progress indicators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"File Management"}),": Process file uploads from users and deliver agent-generated artifacts (reports, images, data files) back to the platform in the appropriate format."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Built-in Services"}),": Access state management for maintaining conversation context, timer scheduling for delayed operations, and feedback collection for gathering user ratings."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"architecture-overview",children:"Architecture Overview"}),"\n",(0,s.jsx)(n.p,{children:"Gateway adapters work alongside a generic gateway component to connect platforms to the agent mesh:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Gateway Adapter"}),": Your platform-specific code that receives events from external systems and formats responses for delivery back to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Generic Gateway Component"}),": Handles A2A protocol communication, authentication flow, user enrichment, message routing, and artifact management"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The following diagram illustrates the complete flow from external platform to agent mesh and back:"}),"\n",(0,s.jsx)(n.mermaid,{value:"sequenceDiagram\n participant Platform as External Platform\n participant Adapter as Gateway Adapter\n participant Generic as Generic Gateway\n participant Mesh as Agent Mesh\n\n rect rgba(234, 234, 234, 1)\n Note over Platform,Adapter: 1. External Event Arrives\n Platform->>Adapter: Platform Event\n end\n\n rect rgba(234, 234, 234, 1)\n Note over Adapter,Generic: 2. Adapter Processes Event\n Adapter->>Adapter: extract_auth_claims()\n Adapter->>Adapter: prepare_task()\n Adapter->>Generic: handle_external_input(SamTask)\n end\n\n rect rgba(234, 234, 234, 1)\n Note over Generic,Mesh: 3. Generic Gateway Handles A2A\n Generic->>Generic: Authenticate & Enrich User\n Generic->>Generic: Convert to A2A Format\n Generic->>Mesh: Submit A2A Task\n end\n\n rect rgba(234, 234, 234, 1)\n Note over Mesh,Adapter: 4. Response Flow\n Mesh--\x3e>Generic: A2A Updates\n Generic->>Generic: Convert to SAM Types\n Generic->>Adapter: handle_update(SamUpdate)\n Adapter->>Platform: Platform Response\n end\n\n %%{init: {\n 'theme': 'base',\n 'themeVariables': {\n 'actorBkg': '#00C895',\n 'actorBorder': '#00C895',\n 'actorTextColor': '#000000',\n 'noteBkgColor': '#FFF7C2',\n 'noteTextColor': '#000000',\n 'noteBorderColor': '#FFF7C2'\n }\n }}%%"}),"\n",(0,s.jsx)(n.h2,{id:"core-concepts",children:"Core Concepts"}),"\n",(0,s.jsx)(n.h3,{id:"the-gateway-adapter-contract",children:"The Gateway Adapter Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Gateway adapters extend the ",(0,s.jsx)(n.code,{children:"GatewayAdapter"})," base class and implement methods for handling platform-specific events:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Extract authentication information from platform events"}),"\n",(0,s.jsx)(n.li,{children:"Convert platform events into standardized task format"}),"\n",(0,s.jsx)(n.li,{children:"Format and send responses back to the platform"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"the-gateway-context",children:"The Gateway Context"}),"\n",(0,s.jsxs)(n.p,{children:["When your adapter initializes, it receives a ",(0,s.jsx)(n.code,{children:"GatewayContext"})," object that provides access to framework services:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Task submission and cancellation"}),"\n",(0,s.jsx)(n.li,{children:"Artifact loading and management"}),"\n",(0,s.jsx)(n.li,{children:"User feedback collection"}),"\n",(0,s.jsx)(n.li,{children:"State management (task-level and session-level)"}),"\n",(0,s.jsx)(n.li,{children:"Timer scheduling"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"the-type-system",children:"The Type System"}),"\n",(0,s.jsx)(n.p,{children:"Gateway adapters use a standardized type system for messages:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SamTask"}),": An inbound request with content parts and metadata"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SamUpdate"}),": An outbound update containing one or more content parts"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SamTextPart"}),": Text content in tasks or updates"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SamFilePart"}),": File content with bytes or URI"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SamDataPart"}),": Structured data with metadata"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"AuthClaims"}),": User authentication information"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"ResponseContext"}),": Context provided with each outbound callback"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"adapter-lifecycle",children:"Adapter Lifecycle"}),"\n",(0,s.jsx)(n.p,{children:"Gateway adapters follow a simple lifecycle:"}),"\n",(0,s.jsx)(n.h3,{id:"initialization",children:"Initialization"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"init()"})," method is called when the gateway starts:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def init(self, context: GatewayContext) -> None:\n """\n Initialize the gateway adapter.\n\n This is where you should:\n - Store the context for later use\n - Start platform listeners (WebSocket, HTTP server, etc.)\n - Connect to external services\n """\n self.context = context\n # Initialize your platform connection\n await self.start_platform_listener()\n'})}),"\n",(0,s.jsx)(n.h3,{id:"active-processing",children:"Active Processing"}),"\n",(0,s.jsx)(n.p,{children:"During normal operation, the generic gateway calls your adapter methods:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"extract_auth_claims()"})," - Extract user identity from platform events"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"prepare_task()"})," - Convert platform events to SamTask format"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"handle_update()"})," - Process updates from agents"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"handle_task_complete()"})," - Handle task completion"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"handle_error()"})," - Handle errors"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cleanup",children:"Cleanup"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"cleanup()"})," method is called during shutdown:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def cleanup(self) -> None:\n """\n Clean up resources on shutdown.\n\n This is where you should:\n - Stop platform listeners\n - Close connections\n - Release resources\n """\n await self.stop_platform_listener()\n'})}),"\n",(0,s.jsx)(n.h2,{id:"implementing-an-adapter",children:"Implementing an Adapter"}),"\n",(0,s.jsx)(n.h3,{id:"required-configuration",children:"Required Configuration"}),"\n",(0,s.jsx)(n.p,{children:"Define a configuration model for your adapter using Pydantic:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'from pydantic import BaseModel, Field\n\nclass MyAdapterConfig(BaseModel):\n """Configuration model for MyAdapter."""\n\n api_token: str = Field(..., description="API token for the platform.")\n webhook_url: str = Field(..., description="Webhook URL to listen on.")\n timeout_seconds: int = Field(default=30, description="Request timeout.")\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Set the ",(0,s.jsx)(n.code,{children:"ConfigModel"})," class attribute:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"from solace_agent_mesh.gateway.adapter.base import GatewayAdapter\n\nclass MyAdapter(GatewayAdapter):\n ConfigModel = MyAdapterConfig\n"})}),"\n",(0,s.jsx)(n.h3,{id:"authentication-extract_auth_claims",children:"Authentication: extract_auth_claims()"}),"\n",(0,s.jsx)(n.p,{children:"Extract user identity from platform events:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def extract_auth_claims(\n self,\n external_input: Dict,\n endpoint_context: Optional[Dict[str, Any]] = None,\n) -> Optional[AuthClaims]:\n """\n Extract authentication claims from platform input.\n\n Return AuthClaims with user info, or None to use config-based auth.\n """\n user_id = external_input.get("user_id")\n user_email = external_input.get("user_email")\n\n if user_id and user_email:\n return AuthClaims(\n id=user_email,\n email=user_email,\n source="platform_api",\n raw_context={"platform_user_id": user_id}\n )\n\n return None\n'})}),"\n",(0,s.jsx)(n.h3,{id:"inbound-prepare_task",children:"Inbound: prepare_task()"}),"\n",(0,s.jsx)(n.p,{children:"Convert platform events into standardized task format:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def prepare_task(\n self,\n external_input: Dict,\n endpoint_context: Optional[Dict[str, Any]] = None,\n) -> SamTask:\n """\n Prepare a task from platform input.\n\n This method is called after authentication succeeds. Convert your\n platform\'s event format into a SamTask with parts.\n """\n message_text = external_input.get("message", "")\n conversation_id = external_input.get("conversation_id")\n\n # Create content parts\n parts = [self.context.create_text_part(message_text)]\n\n # Handle file attachments if present\n if "attachments" in external_input:\n for attachment in external_input["attachments"]:\n file_bytes = await self._download_attachment(attachment)\n parts.append(\n self.context.create_file_part_from_bytes(\n name=attachment["filename"],\n content_bytes=file_bytes,\n mime_type=attachment["mime_type"]\n )\n )\n\n return SamTask(\n parts=parts,\n session_id=conversation_id,\n target_agent=self.context.config.get("default_agent_name", "default"),\n platform_context={\n "conversation_id": conversation_id,\n # Store any platform-specific data needed for responses\n }\n )\n'})}),"\n",(0,s.jsx)(n.h3,{id:"outbound-handle_update",children:"Outbound: handle_update()"}),"\n",(0,s.jsx)(n.p,{children:"Process updates from agents and send them to your platform:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def handle_update(self, update: SamUpdate, context: ResponseContext) -> None:\n """\n Handle an update from the agent.\n\n By default, this dispatches to individual part handlers.\n Override for custom batch processing.\n """\n # Default implementation handles each part type\n for part in update.parts:\n if isinstance(part, SamTextPart):\n await self.handle_text_chunk(part.text, context)\n elif isinstance(part, SamFilePart):\n await self.handle_file(part, context)\n elif isinstance(part, SamDataPart):\n await self.handle_data_part(part, context)\n'})}),"\n",(0,s.jsx)(n.p,{children:"Implement individual part handlers:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def handle_text_chunk(self, text: str, context: ResponseContext) -> None:\n """Handle streaming text chunk from the agent."""\n conversation_id = context.platform_context["conversation_id"]\n await self.platform_api.send_message(conversation_id, text)\n\nasync def handle_file(self, file_part: SamFilePart, context: ResponseContext) -> None:\n """Handle file/artifact from the agent."""\n conversation_id = context.platform_context["conversation_id"]\n await self.platform_api.upload_file(\n conversation_id,\n filename=file_part.name,\n content=file_part.content_bytes\n )\n\nasync def handle_data_part(self, data_part: SamDataPart, context: ResponseContext) -> None:\n """Handle structured data part from the agent."""\n # Check for special data part types\n if data_part.data.get("type") == "agent_progress_update":\n status_text = data_part.data.get("status_text")\n if status_text:\n await self.handle_status_update(status_text, context)\n\nasync def handle_status_update(self, status_text: str, context: ResponseContext) -> None:\n """Handle agent status update (progress indicator)."""\n conversation_id = context.platform_context["conversation_id"]\n await self.platform_api.update_status(conversation_id, status_text)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"completion-handle_task_complete",children:"Completion: handle_task_complete()"}),"\n",(0,s.jsx)(n.p,{children:"Handle task completion notification:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def handle_task_complete(self, context: ResponseContext) -> None:\n """Handle task completion notification."""\n conversation_id = context.platform_context["conversation_id"]\n await self.platform_api.send_message(\n conversation_id,\n "\u2705 Task complete."\n )\n'})}),"\n",(0,s.jsx)(n.h3,{id:"error-handling-handle_error",children:"Error Handling: handle_error()"}),"\n",(0,s.jsx)(n.p,{children:"Handle errors from the agent or gateway:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def handle_error(self, error: SamError, context: ResponseContext) -> None:\n """Handle error from the agent or gateway."""\n conversation_id = context.platform_context.get("conversation_id")\n\n if error.category == "CANCELED":\n error_message = "\ud83d\uded1 Task canceled."\n else:\n error_message = f"\u274c Error: {error.message}"\n\n if conversation_id:\n await self.platform_api.send_message(conversation_id, error_message)\n'})}),"\n",(0,s.jsx)(n.h2,{id:"gateway-context-services",children:"Gateway Context Services"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"GatewayContext"})," provides access to framework services:"]}),"\n",(0,s.jsx)(n.h3,{id:"task-management",children:"Task Management"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'# Submit a new task to the agent mesh\ntask_id = await self.context.handle_external_input(\n external_input=platform_event,\n endpoint_context={"source": "webhook"}\n)\n\n# Cancel an in-flight task\nawait self.context.cancel_task(task_id)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"artifact-management",children:"Artifact Management"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'# Load artifact content\ncontent_bytes = await self.context.load_artifact_content(\n context=response_context,\n filename="report.pdf",\n version="latest"\n)\n\n# List available artifacts\nartifacts = await self.context.list_artifacts(response_context)\nfor artifact in artifacts:\n print(f"{artifact.filename}: {artifact.version}")\n'})}),"\n",(0,s.jsx)(n.h3,{id:"feedback-collection",children:"Feedback Collection"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'# Submit user feedback\nfeedback = SamFeedback(\n task_id=task_id,\n session_id=session_id,\n rating="up", # or "down"\n comment="Great response!",\n user_id=user_id\n)\nawait self.context.submit_feedback(feedback)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"state-management",children:"State Management"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'# Task-level state (expires after 1 hour)\nself.context.set_task_state(task_id, "status_message_id", message_id)\nmessage_id = self.context.get_task_state(task_id, "status_message_id")\n\n# Session-level state (expires after 24 hours)\nself.context.set_session_state(session_id, "user_preferences", preferences)\npreferences = self.context.get_session_state(session_id, "user_preferences")\n'})}),"\n",(0,s.jsx)(n.h3,{id:"timer-management",children:"Timer Management"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"# Schedule a one-time callback\ntimer_id = self.context.add_timer(\n delay_ms=5000,\n callback=self.my_async_callback\n)\n\n# Schedule a recurring callback\ntimer_id = self.context.add_timer(\n delay_ms=1000,\n callback=self.my_async_callback,\n interval_ms=1000\n)\n\n# Cancel a timer\nself.context.cancel_timer(timer_id)\n"})}),"\n",(0,s.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,s.jsx)(n.p,{children:"Configure a gateway adapter in your YAML file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apps:\n - name: my_gateway_app\n app_base_path: .\n app_module: solace_agent_mesh.gateway.generic.app\n\n broker:\n # Broker connection configuration\n <<: *broker_connection\n\n app_config:\n # Required: namespace for A2A topics\n namespace: ${NAMESPACE}\n\n # Required: path to your adapter class\n gateway_adapter: my_package.adapters.MyAdapter\n\n # Adapter-specific configuration\n adapter_config:\n api_token: ${MY_PLATFORM_API_TOKEN}\n webhook_url: ${WEBHOOK_URL}\n timeout_seconds: 30\n\n # Standard gateway configuration\n default_agent_name: OrchestratorAgent\n\n # Artifact service configuration\n artifact_service:\n type: "filesystem"\n base_path: "/tmp/artifacts"\n artifact_scope: "namespace"\n\n # System purpose and response format\n system_purpose: >\n The system is an AI assistant that helps users\n accomplish tasks through natural language interaction.\n\n response_format: >\n Responses should be clear, concise, and formatted\n appropriately for the platform.\n'})}),"\n",(0,s.jsx)(n.h2,{id:"example-slack-adapter",children:"Example: Slack Adapter"}),"\n",(0,s.jsx)(n.p,{children:"The Slack gateway adapter demonstrates a complete implementation of the adapter pattern. It handles:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Socket Mode Connection"}),": Maintains WebSocket connection to Slack"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Event Handling"}),": Processes messages, mentions, slash commands, and button actions"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Message Queuing"}),": Manages streaming updates with proper ordering"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"File Uploads"}),": Handles artifact uploads to Slack"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Markdown Conversion"}),": Converts standard Markdown to Slack format"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Feedback Collection"}),": Provides thumbs up/down buttons for user feedback"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Key highlights from the Slack adapter implementation:"}),"\n",(0,s.jsx)(n.h3,{id:"configuration-model",children:"Configuration Model"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'class SlackAdapterConfig(BaseModel):\n slack_bot_token: str = Field(..., description="Slack Bot Token (xoxb-...).")\n slack_app_token: str = Field(..., description="Slack App Token (xapp-...).")\n slack_initial_status_message: str = Field(\n "Got it, thinking...",\n description="Message posted to Slack upon receiving a user request."\n )\n correct_markdown_formatting: bool = Field(\n True,\n description="Attempt to convert common Markdown to Slack\'s format."\n )\n feedback_enabled: bool = Field(\n False,\n description="Enable thumbs up/down feedback buttons."\n )\n'})}),"\n",(0,s.jsx)(n.h3,{id:"authentication-with-caching",children:"Authentication with Caching"}),"\n",(0,s.jsx)(n.p,{children:"The Slack adapter extracts user email from Slack's API and caches the results:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'async def extract_auth_claims(\n self,\n external_input: Dict,\n endpoint_context: Optional[Dict[str, Any]] = None,\n) -> Optional[AuthClaims]:\n slack_user_id = external_input.get("user")\n\n # Check cache first\n if cached_email := self.get_cached_email(slack_user_id):\n return AuthClaims(id=cached_email, email=cached_email, source="slack_api")\n\n # Fetch from Slack API\n profile = await self.slack_app.client.users_profile_get(user=slack_user_id)\n user_email = profile.get("profile", {}).get("email")\n\n if user_email:\n self.cache_email(slack_user_id, user_email)\n return AuthClaims(id=user_email, email=user_email, source="slack_api")\n'})}),"\n",(0,s.jsx)(n.h3,{id:"streaming-updates-with-message-queue",children:"Streaming Updates with Message Queue"}),"\n",(0,s.jsx)(n.p,{children:"The Slack adapter uses a message queue to handle streaming updates efficiently:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"async def handle_update(self, update: SamUpdate, context: ResponseContext) -> None:\n task_id = context.task_id\n queue = await self._get_or_create_queue(task_id, channel_id, thread_ts)\n\n for part in update.parts:\n if isinstance(part, SamTextPart):\n await queue.queue_text_update(part.text)\n elif isinstance(part, SamFilePart):\n await queue.queue_file_upload(part.name, part.content_bytes)\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For the complete Slack adapter implementation, see ",(0,s.jsx)(n.code,{children:"src/solace_agent_mesh/gateway/slack/adapter.py"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"creating-your-own-adapter",children:"Creating Your Own Adapter"}),"\n",(0,s.jsx)(n.h3,{id:"option-1-create-as-a-plugin-recommended",children:"Option 1: Create as a Plugin (Recommended)"}),"\n",(0,s.jsx)(n.p,{children:"For reusable adapters that you plan to share or use across multiple projects:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sam plugin create my-gateway-plugin\n"})}),"\n",(0,s.jsx)(n.p,{children:'Select "Gateway Plugin" when prompted. This creates a complete plugin structure with:'}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Python package structure"}),"\n",(0,s.jsx)(n.li,{children:"Sample adapter implementation"}),"\n",(0,s.jsx)(n.li,{children:"Configuration template"}),"\n",(0,s.jsx)(n.li,{children:"Build tooling"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"After implementing your adapter, build and distribute:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd my-gateway-plugin\nsam plugin build\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For more information on plugins, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins",children:"Plugins"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"option-2-add-to-existing-project",children:"Option 2: Add to Existing Project"}),"\n",(0,s.jsx)(n.p,{children:"For project-specific adapters, create your adapter class in your project:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Create your adapter module:"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:"# my_project/gateways/my_adapter.py\nfrom solace_agent_mesh.gateway.adapter.base import GatewayAdapter\nfrom solace_agent_mesh.gateway.adapter.types import (\n AuthClaims,\n GatewayContext,\n ResponseContext,\n SamTask,\n SamUpdate\n)\n\nclass MyAdapter(GatewayAdapter):\n async def init(self, context: GatewayContext) -> None:\n self.context = context\n # Initialize your platform connection\n\n async def prepare_task(self, external_input, endpoint_context=None) -> SamTask:\n # Convert platform event to SamTask\n pass\n\n async def handle_update(self, update: SamUpdate, context: ResponseContext) -> None:\n # Send update to platform\n pass\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsx)(n.li,{children:"Reference it in your configuration:"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"app_config:\n gateway_adapter: my_project.gateways.my_adapter.MyAdapter\n adapter_config:\n # Your adapter configuration\n"})}),"\n",(0,s.jsx)(n.h2,{id:"advanced-full-custom-gateways",children:"Advanced: Full Custom Gateways"}),"\n",(0,s.jsx)(n.p,{children:"For most use cases, gateway adapters provide all the functionality you need to connect external platforms to the agent mesh. However, if you have highly specialized requirements, you can create a full custom gateway that implements the complete gateway lifecycle and A2A protocol handling from scratch."}),"\n",(0,s.jsx)(n.p,{children:"Consider a full custom gateway only if you need:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Highly specialized authentication flows not supported by the standard flow"}),"\n",(0,s.jsx)(n.li,{children:"Custom A2A protocol behavior or extensions"}),"\n",(0,s.jsx)(n.li,{children:"Complex multi-stage processing pipelines with custom state management"}),"\n",(0,s.jsx)(n.li,{children:"Fine-grained control over every aspect of the gateway lifecycle"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Full custom gateways extend ",(0,s.jsx)(n.code,{children:"BaseGatewayComponent"})," directly and implement all protocol handling manually. This approach requires significantly more code and expertise but provides complete control over the gateway behavior."]}),"\n",(0,s.jsx)(n.h2,{id:"related-documentation",children:"Related Documentation"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/gateways",children:"Gateways"})," - Overview of gateway concepts and types"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins",children:"Plugins"})," - Creating and distributing gateway plugins"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var a=t(6540);const s={},r=a.createContext(s);function i(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1188],{7026:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"documentation/enterprise/enterprise","title":"Agent Mesh Enterprise","description":"Agent Mesh Enterprise extends the open-source framework with production-ready features that enterprise environments require. This version provides enhanced security through single sign-on integration, granular access control through role-based permissions, intelligent data management for cost optimization, and comprehensive observability tools for monitoring agent workflows and system performance.","source":"@site/docs/documentation/enterprise/enterprise.md","sourceDirName":"documentation/enterprise","slug":"/documentation/enterprise/","permalink":"/solace-agent-mesh/docs/documentation/enterprise/","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/enterprise/enterprise.md","tags":[],"version":"current","sidebarPosition":700,"frontMatter":{"title":"Agent Mesh Enterprise","sidebar_position":700},"sidebar":"docSidebar","previous":{"title":"A2A Technical Migration Map","permalink":"/solace-agent-mesh/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map"},"next":{"title":"Installing Agent Mesh Enterprise","permalink":"/solace-agent-mesh/docs/documentation/enterprise/installation"}}');var r=t(4848),s=t(8453);const o={title:"Agent Mesh Enterprise",sidebar_position:700},a="Agent Mesh Enterprise",c={},l=[{value:"Enterprise Features",id:"enterprise-features",level:2},{value:"Getting Started with Enterprise",id:"getting-started-with-enterprise",level:2},{value:"Installation",id:"installation",level:3},{value:"Access Control",id:"access-control",level:3},{value:"Single Sign-On",id:"single-sign-on",level:3},{value:"Connectors",id:"connectors",level:3},{value:"Agent Builder",id:"agent-builder",level:3},{value:"What&#39;s Next",id:"whats-next",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"agent-mesh-enterprise",children:"Agent Mesh Enterprise"})}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh Enterprise extends the open-source framework with production-ready features that enterprise environments require. This version provides enhanced security through single sign-on integration, granular access control through role-based permissions, intelligent data management for cost optimization, and comprehensive observability tools for monitoring agent workflows and system performance."}),"\n",(0,r.jsxs)(n.p,{children:["Enterprise is available as a self-managed container image that you can deploy in your own infrastructure. You can obtain access by joining the pilot program at ",(0,r.jsx)(n.a,{href:"https://solace.com/solace-agent-mesh-pilot-registration/",children:"solace.com/solace-agent-mesh-pilot-registration"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"enterprise-features",children:"Enterprise Features"}),"\n",(0,r.jsx)(n.p,{children:"The Enterprise version delivers several capabilities that distinguish it from the Community edition."}),"\n",(0,r.jsx)(n.p,{children:"Authentication and authorization integrate with your existing identity systems through SSO, eliminating the need for separate credentials while maintaining security standards. You can configure role-based access control to implement granular authorization policies that determine which agents and resources each user can access through the Agent Mesh Gateways."}),"\n",(0,r.jsx)(n.p,{children:"Data management features help you optimize costs and improve accuracy. Smart filtering capabilities reduce unnecessary compute expenses while precise data governance helps prevent hallucinations by controlling what information reaches your language models."}),"\n",(0,r.jsx)(n.p,{children:"Observability tools provide complete visibility into your agent ecosystem. The built-in workflow viewer tracks LLM interactions and agent communications in real time, giving you the insights needed to monitor performance, diagnose issues, and understand system behavior."}),"\n",(0,r.jsx)(n.h2,{id:"getting-started-with-enterprise",children:"Getting Started with Enterprise"}),"\n",(0,r.jsx)(n.p,{children:"Setting up Agent Mesh Enterprise involves installation, security configuration, and authentication setup."}),"\n",(0,r.jsx)(n.h3,{id:"installation",children:"Installation"}),"\n",(0,r.jsxs)(n.p,{children:["The Docker-based installation process downloads the enterprise image from the Solace Product Portal, loads it into your container environment, and launches it with the appropriate configuration for your deployment scenario. You can run Enterprise in development mode with an embedded broker for testing, or connect it to an external Solace broker for production deployments. For complete installation instructions, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/installation",children:"Installing Agent Mesh Enterprise"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"access-control",children:"Access Control"}),"\n",(0,r.jsxs)(n.p,{children:["Role-based access control lets you define who can access which agents and features in your deployment. You create roles that represent job functions, assign permissions to those roles through scopes, and then assign roles to users. This three-tier model implements the principle of least privilege while simplifying administration. For guidance on planning and implementing RBAC, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/rbac-setup-guide",children:"Setting Up RBAC"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"single-sign-on",children:"Single Sign-On"}),"\n",(0,r.jsxs)(n.p,{children:["SSO integration connects Agent Mesh Enterprise with your organization's identity provider, whether you use Azure, Google, Auth0, Okta, Keycloak, or another OAuth2-compliant system. The configuration process involves creating YAML files that define the authentication service and provider settings, then launching the container with the appropriate environment variables. For step-by-step configuration instructions, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/single-sign-on",children:"Enabling SSO"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"connectors",children:"Connectors"}),"\n",(0,r.jsxs)(n.p,{children:["Connectors link agents to external data sources such as databases and APIs, enabling agents to retrieve and analyze information through natural language interactions. The Enterprise version supports SQL connectors for MySQL, PostgreSQL, and MariaDB databases. You create connectors in the Connectors section of the web interface, where they become available for assignment to any agent in your deployment. All agents assigned to a connector share the same credentials, requiring careful planning of data source permissions to maintain appropriate access control. For information about creating and managing connectors, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/connectors/",children:"Connectors"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"agent-builder",children:"Agent Builder"}),"\n",(0,r.jsxs)(n.p,{children:["The Enterprise version includes Agent Builder, a visual interface for creating and managing agents without writing configuration files directly. Agent Builder supports both AI-assisted generation from natural language descriptions and manual configuration for precise control over agent capabilities. You can create agents, assign toolsets and connectors, and deploy them dynamically through the Deployer component without restarting services. The Deployer handles deployment operations asynchronously, enabling scalable agent creation through the web interface. You can also download agent configurations as YAML files for version control or infrastructure-as-code deployments. For comprehensive information about creating and managing agents, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/agent-builder",children:"Agent Builder"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"whats-next",children:"What's Next"}),"\n",(0,r.jsx)(n.p,{children:"After you complete the initial setup and create agents using Agent Builder, you can begin deploying them to make them available for user interactions. The Enterprise features operate transparently\u2014your agents and tools work the same way, but with the added security, governance, and observability that production environments demand."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(6540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[7669],{2260:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"documentation/developing/create-agents","title":"Creating Agents","description":"For a more comprehensive tutorial example, see the Build Your Own Agent guide.","source":"@site/docs/documentation/developing/create-agents.md","sourceDirName":"documentation/developing","slug":"/documentation/developing/create-agents","permalink":"/solace-agent-mesh/docs/documentation/developing/create-agents","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/developing/create-agents.md","tags":[],"version":"current","sidebarPosition":420,"frontMatter":{"title":"Creating Agents","sidebar_position":420},"sidebar":"docSidebar","previous":{"title":"Project Structure","permalink":"/solace-agent-mesh/docs/documentation/developing/structure"},"next":{"title":"Creating Custom Gateways","permalink":"/solace-agent-mesh/docs/documentation/developing/create-gateways"}}');var i=t(4848),s=t(8453);const a={title:"Creating Agents",sidebar_position:420},r=void 0,l={},c=[{value:"Understanding the Architecture",id:"understanding-the-architecture",level:2},{value:"Core Concepts",id:"core-concepts",level:2},{value:"Tools: The Building Blocks",id:"tools-the-building-blocks",level:3},{value:"Configuration File: The Blueprint",id:"configuration-file-the-blueprint",level:3},{value:"Tool Configuration: Customizing Behavior",id:"tool-configuration-customizing-behavior",level:3},{value:"ToolContext: Accessing Framework Services",id:"toolcontext-accessing-framework-services",level:3},{value:"Lifecycle Functions: Managing Resources",id:"lifecycle-functions-managing-resources",level:3},{value:"Creating Your First Agent: Step-by-Step",id:"creating-your-first-agent-step-by-step",level:2},{value:"Step 1: Initialize Your Agent Plugin",id:"step-1-initialize-your-agent-plugin",level:3},{value:"Step 2: Create Your Tool Functions",id:"step-2-create-your-tool-functions",level:3},{value:"Step 3: Configure Your Agent",id:"step-3-configure-your-agent",level:3},{value:"Step 4: Create Lifecycle Functions",id:"step-4-create-lifecycle-functions",level:3},{value:"Running Your Agent",id:"running-your-agent",level:2},{value:"Building and Installing the Plugin",id:"building-and-installing-the-plugin",level:3},{value:"Quick Debug Mode",id:"quick-debug-mode",level:3},{value:"Advanced Concepts",id:"advanced-concepts",level:2},{value:"Working with Artifacts",id:"working-with-artifacts",level:3},{value:"Using Multiple Tool Configurations",id:"using-multiple-tool-configurations",level:3},{value:"Quick Start: Using the CLI",id:"quick-start-using-the-cli",level:2},{value:"CLI Options",id:"cli-options",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"Tool Design",id:"tool-design",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Testing",id:"testing",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",mermaid:"mermaid",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["For a more comprehensive tutorial example, see the ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/custom-agent",children:"Build Your Own Agent"})," guide.\nThis page walks through the fundamental concepts for creating agents in Agent Mesh."]})}),"\n",(0,i.jsx)(n.p,{children:"Agent Mesh is a powerful platform that enables you to create intelligent agents that can communicate with each other and perform complex tasks. At its core, Agent Mesh uses a tool-based architecture where LLM-powered agents are equipped with specific capabilities (tools) that they can use to accomplish user requests."}),"\n",(0,i.jsxs)(n.p,{children:["Before continuing with this tutorial, make sure you are familiar with the basic ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/agents",children:"agent concept"}),"."]}),"\n",(0,i.jsx)(n.p,{children:'This tutorial guides you through creating your first Agent Mesh agent from scratch. You will learn how to define tools as Python functions, configure an agent using YAML, and set up agent lifecycle functions. By the end of this tutorial, you should have a working "Hello World" agent that demonstrates the fundamental concepts of Agent Mesh agent development.'}),"\n",(0,i.jsx)(n.h2,{id:"understanding-the-architecture",children:"Understanding the Architecture"}),"\n",(0,i.jsx)(n.p,{children:"Before diving into implementation, you need to understand how the different components of an Agent Mesh agent work together. This architectural overview will help you see the big picture before you start building."}),"\n",(0,i.jsx)(n.mermaid,{value:"graph TD\n subgraph Agent Configuration\n direction LR\n A[config.yaml] --\x3e|Defines| B(Agent Properties);\n A --\x3e|Lists & Configures| C(Tools);\n end\n\n subgraph Agent Host\n direction TB\n D[Agent Mesh Host] --\x3e|Loads| A;\n D --\x3e|Instantiates| E[Agent];\n E --\x3e|Initializes with| F[Lifecycle Functions];\n end\n\n subgraph Tool Implementation\n direction LR\n G[Python Module tools.py] --\x3e|Contains| H[Tool Functions];\n end\n\n subgraph Execution Flow\n direction TB\n I[User Request] --\x3e J[LLM Orchestrator];\n J --\x3e|Selects Tool| K{ADKToolWrapper};\n K --\x3e|Calls| H;\n H --\x3e|Accesses| L[ToolContext];\n H --\x3e|Uses| M[tool_config];\n H --\x3e|Returns Result| J;\n end\n\n C --\x3e|Wrapped by| K;\n\n style A fill:#b60000,stroke:#faa,stroke-width:2px\n style H fill:#b60000,stroke:#faa,stroke-width:2px\n style F fill:#007000,stroke:#faa,stroke-width:2px"}),"\n",(0,i.jsx)(n.p,{children:"When a user sends a request to your agent, the LLM orchestrator analyzes the request and decides which tool to use. The framework wraps your tool functions and provides them with context and configuration. Your tool executes its logic and returns results to the LLM, which then formulates a response to the user."}),"\n",(0,i.jsx)(n.h2,{id:"core-concepts",children:"Core Concepts"}),"\n",(0,i.jsx)(n.p,{children:"Understanding these fundamental concepts will help you build effective agents."}),"\n",(0,i.jsx)(n.h3,{id:"tools-the-building-blocks",children:"Tools: The Building Blocks"}),"\n",(0,i.jsx)(n.p,{children:"Tools are the fundamental building blocks of Agent Mesh agents. Each tool is implemented as a Python function that performs a specific task. The LLM orchestrating your agent decides which tools to use based on the user's request and the tool descriptions you provide."}),"\n",(0,i.jsx)(n.p,{children:"Tools can process text and data, interact with external APIs, create and manipulate files, communicate with other agents, and access databases and services. You write tools as standard Python functions, and the framework handles the integration with the LLM."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Agent Mesh provides a set of ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/builtin-tools/",children:"built-in tools"})," plus support for ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/mcp-integration",children:"model context protocol (MCP)"})," servers, which can be configured in the tools list of your agent configuration."]})}),"\n",(0,i.jsx)(n.h3,{id:"configuration-file-the-blueprint",children:"Configuration File: The Blueprint"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.yaml"})," (for plugin template) or ",(0,i.jsx)(n.code,{children:"agent-name.yaml"})," (for agent instances) file is the blueprint of your agent. This YAML file defines your agent's identity (name, description, and capabilities), model configuration (which LLM to use), tools list (which tools the agent can access and how they're configured), lifecycle functions (setup and cleanup procedures), framework services (session management, artifact storage, and so on), and ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/agents#agent-card",children:"agent card"})," (metadata describing the agent capabilities, skills and its visibility in the system)."]}),"\n",(0,i.jsx)(n.p,{children:"The configuration file connects all the pieces together. It tells the framework where to find your tool functions, how to configure them, and what instructions to give the LLM about your agent's purpose."}),"\n",(0,i.jsx)(n.h3,{id:"tool-configuration-customizing-behavior",children:"Tool Configuration: Customizing Behavior"}),"\n",(0,i.jsxs)(n.p,{children:["Within the ",(0,i.jsx)(n.code,{children:"tools"})," list in your YAML config, each tool can have its own ",(0,i.jsx)(n.code,{children:"tool_config"})," section. This allows you to configure the same tool function for different purposes, pass specific parameters to tool instances, and customize tool behavior per agent."]}),"\n",(0,i.jsx)(n.p,{children:"This design pattern enables code reuse. You can write a single generic tool function and configure it multiple times with different parameters to serve different purposes within the same agent."}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsxs)(n.p,{children:['For tools of type "python", you can also use the ',(0,i.jsx)(n.code,{children:"tool_name"})," and ",(0,i.jsx)(n.code,{children:"tool_description"})," to overwrite the function name and description in the tool docstring."]}),(0,i.jsx)(n.p,{children:"This is useful when using a generic tool function for multiple purposes, allowing you to provide a more descriptive name and description for each instance."})]}),"\n",(0,i.jsx)(n.h3,{id:"toolcontext-accessing-framework-services",children:"ToolContext: Accessing Framework Services"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ToolContext"})," object (passed as one of the arguments to your tool function) provides your tools with access to Agent Mesh core services. Through this context object, your tools can access structured logging for debugging and monitoring, the artifact service for file storage and retrieval, session information about the current user and session context, and agent state for sharing data between tool calls."]}),"\n",(0,i.jsx)(n.p,{children:"The framework automatically provides this context to your tool functions. You don't need to create or manage it yourself."}),"\n",(0,i.jsx)(n.h3,{id:"lifecycle-functions-managing-resources",children:"Lifecycle Functions: Managing Resources"}),"\n",(0,i.jsxs)(n.p,{children:["Lifecycle functions allow you to manage resources that should persist for the agent's lifetime. The ",(0,i.jsx)(n.code,{children:"agent_init_function"})," runs when the agent starts (for example, to establish database connections), and the ",(0,i.jsx)(n.code,{children:"agent_cleanup_function"})," runs when the agent shuts down (for example, to close connections gracefully)."]}),"\n",(0,i.jsx)(n.p,{children:"These functions are optional but recommended for managing resources effectively. They ensure that your agent properly initializes any required resources and cleans them up when shutting down."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Lifecycle functions are optional but recommended for managing resources effectively."})}),"\n",(0,i.jsx)(n.h2,{id:"creating-your-first-agent-step-by-step",children:"Creating Your First Agent: Step-by-Step"}),"\n",(0,i.jsx)(n.p,{children:'Now that you understand the core concepts, you can create a simple agent that demonstrates how these pieces work together. You will build a "Hello World" agent that can greet users and say goodbye.'}),"\n",(0,i.jsx)(n.h3,{id:"step-1-initialize-your-agent-plugin",children:"Step 1: Initialize Your Agent Plugin"}),"\n",(0,i.jsxs)(n.p,{children:["You can create an agent either by using the ",(0,i.jsx)(n.code,{children:"sam add agent"})," command or by creating a new plugin of type agent with ",(0,i.jsx)(n.code,{children:"sam plugin create my-hello-agent --type agent"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["For information and recommendations about these options, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins#agent-or-plugin-which-to-use",children:(0,i.jsx)(n.code,{children:"Agent or Plugin: Which To use?"})}),"."]})}),"\n",(0,i.jsxs)(n.p,{children:["In this tutorial, you create a new agent by creating a new plugin of type agent. For an example of custom agents, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/custom-agent",children:"Build Your Own Agent"})," guide."]}),"\n",(0,i.jsx)(n.p,{children:"Although the directory structure for plugins is slightly different than the one for agents, both require a YAML configuration file, and a python module with the tools and lifecycle functions you want."}),"\n",(0,i.jsx)(n.p,{children:"To create a new agent plugin, run the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin create my-hello-agent --type agent\n"})}),"\n",(0,i.jsx)(n.p,{children:"Follow the prompts to set up your agent. The prompts create a new directory structure for your agent:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"my-hello-agent/\n\u251c\u2500\u2500 src/\n\u2502 \u2514\u2500\u2500 my_hello_agent/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 tools.py\n\u2502 \u2514\u2500\u2500 lifecycle.py # This file won't be automatically created\n\u251c\u2500\u2500 config.yaml\n\u251c\u2500\u2500 pyproject.toml\n\u2514\u2500\u2500 README.md\n"})}),"\n",(0,i.jsx)(n.mermaid,{value:"graph TD\n A[my-hello-agent/] --\x3e B[src/]\n A --\x3e C[config.yaml]\n A --\x3e D[pyproject.toml]\n A --\x3e E[README.md]\n \n B --\x3e F[my_hello_agent/]\n F --\x3e G[__init__.py]\n F --\x3e H[tools.py]\n F --\x3e I[lifecycle.py]\n \n style C fill:#b60000,stroke:#333,stroke-width:2px\n style H fill:#b60000,stroke:#333,stroke-width:2px\n style I fill:#007000,stroke:#333,stroke-width:2px"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.yaml"})," file will contain your agent configuration, ",(0,i.jsx)(n.code,{children:"tools.py"})," will contain your tool functions, and ",(0,i.jsx)(n.code,{children:"lifecycle.py"})," (which you'll create manually) will contain your lifecycle functions. The ",(0,i.jsx)(n.code,{children:"pyproject.toml"})," file manages your plugin's dependencies and metadata."]}),"\n",(0,i.jsx)(n.h3,{id:"step-2-create-your-tool-functions",children:"Step 2: Create Your Tool Functions"}),"\n",(0,i.jsx)(n.p,{children:"Tools are where your agent's actual capabilities live. You will create two simple tools: one to greet users and one to say goodbye."}),"\n",(0,i.jsxs)(n.p,{children:["Create your tool functions in the ",(0,i.jsx)(n.code,{children:"src/my_hello_agent/tools.py"})," file. For a complete guide on creating python tools, see our ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/creating-python-tools",children:"Creating Python Tools"})," documentation."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_hello_agent/tools.py\n"""\nTools for the Hello World agent.\n"""\n\nfrom typing import Any, Dict, Optional\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\n\n\nasync def hello_tool(\n name: str,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Greets a user with a personalized message.\n \n Args:\n name: The name of the person to greet\n \n Returns:\n A dictionary with the greeting message\n """\n log_identifier = "[HelloTool]"\n log.info(f"{log_identifier} Greeting user: {name}")\n \n # Get configuration from tool_config\n greeting_prefix = "Hello"\n if tool_config:\n greeting_prefix = tool_config.get("greeting_prefix", "Hello")\n \n # Create the greeting message\n greeting_message = f"{greeting_prefix}, {name}! Welcome to Agent Mesh!"\n \n log.info(f"{log_identifier} Generated greeting: {greeting_message}")\n \n return {\n "status": "success",\n "message": greeting_message,\n "greeted_name": name\n }\n\n\nasync def farewell_tool(\n name: str,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Says goodbye to a user.\n \n Args:\n name: The name of the person to say goodbye to\n \n Returns:\n A dictionary with the farewell message\n """\n log_identifier = "[FarewellTool]"\n log.info(f"{log_identifier} Saying goodbye to user: {name}")\n \n # Get configuration from tool_config\n farewell_prefix = "Goodbye"\n if tool_config:\n farewell_prefix = tool_config.get("farewell_prefix", "Goodbye")\n \n # Create the farewell message\n farewell_message = f"{farewell_prefix}, {name}! Thanks for using Agent Mesh!"\n \n log.info(f"{log_identifier} Generated farewell: {farewell_message}")\n \n return {\n "status": "success",\n "message": farewell_message,\n "farewell_name": name\n }\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Let's examine what makes these tool functions work. All tool functions must be asynchronous (defined with ",(0,i.jsx)(n.code,{children:"async def"}),") because the framework uses asynchronous execution. The framework automatically provides two special parameters: ",(0,i.jsx)(n.code,{children:"tool_context"})," gives you access to framework services like logging and artifact storage, and ",(0,i.jsx)(n.code,{children:"tool_config"})," contains any custom configuration you define in your YAML file."]}),"\n",(0,i.jsxs)(n.p,{children:["The function signature includes regular parameters (like ",(0,i.jsx)(n.code,{children:"name"}),") that the LLM will provide when calling the tool. The docstring is important because the LLM uses it to understand what the tool does and when to use it. You should always write clear, descriptive docstrings."]}),"\n",(0,i.jsxs)(n.p,{children:["The tool retrieves its configuration from the ",(0,i.jsx)(n.code,{children:"tool_config"})," dictionary. This allows you to customize the tool's behavior without changing the code. In this example, you can configure different greeting prefixes for different use cases."]}),"\n",(0,i.jsxs)(n.p,{children:["The tool returns a dictionary with at least a ",(0,i.jsx)(n.code,{children:"status"})," field. This structured format makes it easy for the LLM to understand the result. You can include any additional data that might be useful for the LLM or for debugging."]}),"\n",(0,i.jsx)(n.p,{children:"The logging statements help you track what your tool is doing. The framework provides a logger that you should use for consistent logging across your agent."}),"\n",(0,i.jsx)(n.h3,{id:"step-3-configure-your-agent",children:"Step 3: Configure Your Agent"}),"\n",(0,i.jsxs)(n.p,{children:["Now you need to tell the framework about your agent and its tools. Create the main configuration file for your agent in ",(0,i.jsx)(n.code,{children:"config.yaml"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# File: config.yaml (at root of project directory)\n# ... (additional services and configurations)\n\napps:\n - name: my-hello-agent\n app_module: solace_agent_mesh.agent.sac.app \n broker:\n # Can be found in configs/shared_config.yaml after running sam init\n <<: *broker_connection\n \n # Agent-specific configuration\n app_config:\n # Basic agent identity\n namespace: ${NAMESPACE} \n supports_streaming: true \n agent_name: "HelloAgent"\n display_name: "Hello World Agent"\n \n # LLM model configuration\n model: *general_model \n \n # Agent instructions (system prompt)\n instruction: |\n You are a friendly Hello World agent. Your purpose is to greet users and \n demonstrate the capabilities of Agent Mesh. You can:\n \n 1. Greet users with personalized messages using the hello_tool\n 2. Say goodbye to users using the farewell_tool\n \n Always be polite and helpful. When greeting someone, ask for their name \n if they haven\'t provided it.\n \n # Lifecycle functions\n agent_init_function:\n module: "my_hello_agent.lifecycle" # This should point to your lifecycle python module\n name: "initialize_hello_agent"\n base_path: .\n config:\n startup_message: "Hello Agent is starting up!"\n log_level: "INFO"\n \n agent_cleanup_function:\n module: "my_hello_agent.lifecycle"\n base_path: .\n name: "cleanup_hello_agent"\n \n # Tools configuration\n tools:\n # Hello tool with custom greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n component_base_path: .\n function_name: "hello_tool"\n tool_name: "greet_user" # Renaming the tool, must use this name in the agent card\n tool_config:\n greeting_prefix: "Hello there"\n \n # Farewell tool with custom farewell\n - tool_type: python\n component_module: "my_hello_agent.tools"\n component_base_path: .\n function_name: "farewell_tool"\n tool_name: "say_goodbye"\n tool_config:\n farewell_prefix: "See you later"\n \n # Built-in artifact tools for file operations\n - tool_type: builtin-group\n group_name: "artifact_management"\n \n # Agent card (describes the agent\'s capabilities)\n agent_card:\n description: "A friendly Hello World agent that demonstrates Agent Mesh capabilities"\n defaultInputModes: ["text"]\n defaultOutputModes: ["text"]\n skills:\n - id: "greet_user"\n name: "Greet User"\n description: "Greets users with personalized messages"\n - id: "say_goodbye"\n name: "Say Goodbye"\n description: "Says goodbye to users"\n - id: "file_operations"\n name: "File Operations"\n description: "Create, read, and manage files and artifacts"\n \n # Session and artifact services\n session_service: *default_session_service\n artifact_service: *default_artifact_service\n# ... (additional services and configurations)\n'})}),"\n",(0,i.jsx)(n.p,{children:"This configuration file connects all the pieces of your agent. Let's examine each section to understand its purpose."}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"namespace"})," uniquely identifies your agent in the mesh. This allows multiple agents to coexist and communicate. The ",(0,i.jsx)(n.code,{children:"agent_name"})," and ",(0,i.jsx)(n.code,{children:"display_name"})," provide human-readable identifiers for your agent."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"model"})," section specifies which LLM to use. The ",(0,i.jsx)(n.code,{children:"*general_model"})," reference points to a model configuration defined elsewhere in your configuration files (typically in ",(0,i.jsx)(n.code,{children:"shared_config.yaml"}),"). This allows you to centrally manage model configurations across multiple agents."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"instruction"})," field contains the system prompt that defines your agent's personality and behavior. This text tells the LLM what role it should play and what capabilities it has. You\nshould write clear, specific instructions that help the LLM understand its role."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"tools"})," section lists all the tools your agent can use. Each tool entry specifies the ",(0,i.jsx)(n.code,{children:"tool_type"})," (python for custom functions, builtin-group for built-in tools), the ",(0,i.jsx)(n.code,{children:"component_module"})," that contains the function, the ",(0,i.jsx)(n.code,{children:"function_name"})," to call, and optionally a ",(0,i.jsx)(n.code,{children:"tool_name"})," to rename the tool for the LLM. The ",(0,i.jsx)(n.code,{children:"tool_config"})," section passes custom configuration to each tool instance. This is where you provide the ",(0,i.jsx)(n.code,{children:"greeting_prefix"})," and ",(0,i.jsx)(n.code,{children:"farewell_prefix"})," values that your tool functions read."]}),"\n",(0,i.jsxs)(n.p,{children:["Notice that you can configure the same function multiple times with different names and configurations. The ",(0,i.jsx)(n.code,{children:"hello_tool"})," function is configured as ",(0,i.jsx)(n.code,{children:"greet_user"})," with one greeting prefix, but you could add another configuration with a different prefix for formal greetings."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"agent_card"})," section describes your agent's capabilities to other parts of the system. The ",(0,i.jsx)(n.code,{children:"skills"})," list should match the tools you've configured. Each skill has an ",(0,i.jsx)(n.code,{children:"id"})," that corresponds to a tool name, making it discoverable by other agents and the user interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"session_service"})," and ",(0,i.jsx)(n.code,{children:"artifact_service"})," references connect your agent to framework services for managing user sessions and storing files. These services are typically defined in your shared configuration."]}),"\n",(0,i.jsx)(n.h3,{id:"step-4-create-lifecycle-functions",children:"Step 4: Create Lifecycle Functions"}),"\n",(0,i.jsx)(n.p,{children:"Lifecycle functions manage resources that should persist for your agent's lifetime. Although these functions are optional, they demonstrate how to properly initialize and clean up resources."}),"\n",(0,i.jsx)(n.p,{children:"The lifecycle file is not automatically created, so you need to create it manually:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"touch src/my_hello_agent/lifecycle.py\n"})}),"\n",(0,i.jsx)(n.p,{children:"Now add your lifecycle functions:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_hello_agent/lifecycle.py\n"""\nLifecycle functions for the Hello World agent.\n"""\n\nfrom typing import Any, Dict\nfrom pydantic import BaseModel, Field\nfrom solace_ai_connector.common.log import log\n\n\nclass HelloAgentInitConfig(BaseModel):\n """\n Configuration model for the Hello Agent initialization.\n """\n startup_message: str = Field(description="Message to log on startup")\n log_level: str = Field(default="INFO", description="Logging level for the agent")\n\n\ndef initialize_hello_agent(host_component: Any, init_config: HelloAgentInitConfig):\n """\n Initializes the Hello World agent.\n \n Args:\n host_component: The agent host component\n init_config: Validated initialization configuration\n """\n log_identifier = f"[{host_component.agent_name}:init]"\n log.info(f"{log_identifier} Starting Hello Agent initialization...")\n \n # Log the startup message from config\n log.info(f"{log_identifier} {init_config.startup_message}")\n \n # You could initialize shared resources here, such as:\n # - Database connections\n # - API clients\n # - Caches or shared data structures\n \n # Store any shared state in the agent\n host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z")\n host_component.set_agent_specific_state("greeting_count", 0)\n \n log.info(f"{log_identifier} Hello Agent initialization completed successfully")\n\n\ndef cleanup_hello_agent(host_component: Any):\n """\n Cleans up resources when the Hello World agent shuts down.\n \n Args:\n host_component: The agent host component\n """\n log_identifier = f"[{host_component.agent_name}:cleanup]"\n log.info(f"{log_identifier} Starting Hello Agent cleanup...")\n \n # Retrieve any shared state\n greeting_count = host_component.get_agent_specific_state("greeting_count", 0)\n log.info(f"{log_identifier} Agent processed {greeting_count} greetings during its lifetime")\n \n # Clean up resources here, such as:\n # - Closing database connections\n # - Shutting down background tasks\n # - Saving final state\n \n log.info(f"{log_identifier} Hello Agent cleanup completed")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The lifecycle functions follow a specific pattern. The ",(0,i.jsx)(n.code,{children:"initialize_hello_agent"})," function receives two parameters: ",(0,i.jsx)(n.code,{children:"host_component"})," provides access to the agent instance and its methods, and ",(0,i.jsx)(n.code,{children:"init_config"})," contains the validated configuration from your YAML file's ",(0,i.jsx)(n.code,{children:"agent_init_function.config"})," section."]}),"\n",(0,i.jsxs)(n.p,{children:["Using a Pydantic model for ",(0,i.jsx)(n.code,{children:"init_config"})," provides automatic validation. The framework validates your configuration against this model when the agent starts, catching configuration errors early. This is better than manually checking configuration values in your code."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"host_component"})," object provides methods for managing agent state. The ",(0,i.jsx)(n.code,{children:"set_agent_specific_state"})," method stores data that persists across tool calls within the same agent instance. This is useful for tracking statistics, caching data, or maintaining connections. The state is specific to this agent instance and is not shared with other agents."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"cleanup_hello_agent"})," function runs when the agent shuts down. This is your opportunity to gracefully close connections, save final state, or perform any other cleanup tasks. The function receives only the ",(0,i.jsx)(n.code,{children:"host_component"})," parameter because cleanup typically doesn't need additional configuration."]}),"\n",(0,i.jsx)(n.p,{children:"In this example, you retrieve the greeting count from the agent state and log it. In a real application, you might close database connections, flush caches to disk, or notify other services that the agent is shutting down."}),"\n",(0,i.jsx)(n.h2,{id:"running-your-agent",children:"Running Your Agent"}),"\n",(0,i.jsx)(n.p,{children:"Now that you have created all the necessary components, you can run your agent. The process involves building your plugin and adding it to your Agent Mesh project."}),"\n",(0,i.jsx)(n.h3,{id:"building-and-installing-the-plugin",children:"Building and Installing the Plugin"}),"\n",(0,i.jsxs)(n.p,{children:["To properly instantiate your plugin agent, first build the plugin. The following command will produce a python wheel file under ",(0,i.jsx)(n.code,{children:"dist"})," directory:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin build\n"})}),"\n",(0,i.jsx)(n.p,{children:"This command packages your agent code, configuration, and dependencies into a distributable wheel file. The wheel file is a standard Python package format that can be installed into any Python environment."}),"\n",(0,i.jsxs)(n.p,{children:["Check into ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/try-agent-mesh",children:"your Agent Mesh project directory"}),", and add the plugin wheel with a given name:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin add my-first-weather-agent --plugin PATH/TO/weather-agent/dist/weather-agent.whl\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["Using the ",(0,i.jsx)(n.code,{children:"sam plugin add"})," command installs your plugin as a python dependency into your python environment.\nThis also means changing the source code without reinstalling the plugin will not reflect the changes."]})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"sam plugin add"})," command does several things. It installs your plugin package into your Python environment, making your tool functions and lifecycle functions importable. It also creates a configuration file in your project's ",(0,i.jsx)(n.code,{children:"configs/agents/"})," directory that references your plugin. This configuration file is what the framework loads when you run your agent."]}),"\n",(0,i.jsx)(n.p,{children:"Now, you can run the complete Agent Mesh application along with your newly added agent:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam run\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Alternatively, only run the newly added agent using ",(0,i.jsx)(n.code,{children:"sam run configs/agents/my-first-weather-agent.yaml"})]}),"\n",(0,i.jsx)(n.h3,{id:"quick-debug-mode",children:"Quick Debug Mode"}),"\n",(0,i.jsxs)(n.admonition,{title:"Quick Debug",type:"tip",children:[(0,i.jsxs)(n.p,{children:["For debugging or isolated development testing, you can run your agent from the ",(0,i.jsx)(n.code,{children:"src"})," directory directly using the Agent Mesh CLI."]}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd src\nsam run ../config.yaml\n"})}),(0,i.jsx)(n.p,{children:"Changing to the src directory allows the module path to be set correctly so that Agent Mesh can find your functions without your having to install them in your python environment as a plugin package."})]}),"\n",(0,i.jsx)(n.p,{children:"This quick debug mode is useful during development because you can make changes to your code and immediately test them without rebuilding and reinstalling the plugin. However, you should always test with the full plugin installation process before deploying to production."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-concepts",children:"Advanced Concepts"}),"\n",(0,i.jsx)(n.p,{children:"Once you understand the basics, you can explore more advanced patterns for building sophisticated agents."}),"\n",(0,i.jsx)(n.h3,{id:"working-with-artifacts",children:"Working with Artifacts"}),"\n",(0,i.jsx)(n.p,{children:"The artifact service allows your tools to create, store, and retrieve files. You can enhance your hello tool to save greetings to a file using the artifact service:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'\nfrom datetime import datetime\nfrom solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata\n\nasync def hello_tool_with_artifact(\n name: str,\n save_to_file: bool = False,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Greets a user and optionally saves the greeting to a file.\n """\n log_identifier = "[HelloToolWithArtifact]"\n \n # Generate greeting (same as before)\n greeting_prefix = tool_config.get("greeting_prefix", "Hello") if tool_config else "Hello"\n greeting_message = f"{greeting_prefix}, {name}! Welcome to Agent Mesh!"\n \n result = {\n "status": "success",\n "message": greeting_message,\n "greeted_name": name\n }\n \n # Save to artifact if requested\n if save_to_file and tool_context:\n try:\n # Prepare content\n timestamp = datetime.now(timezone.utc)\n filename = f"greeting_{name}_{timestamp}.txt"\n content = f"Greeting: {greeting_message}\\nTimestamp: {timestamp}\\n"\n \n # Save artifact\n artifact_service = tool_context._invocation_context.artifact_service\n await save_artifact_with_metadata(\n artifact_service=artifact_service,\n app_name=tool_context._invocation_context.app_name,\n user_id=tool_context._invocation_context.user_id,\n session_id=tool_context._invocation_context.session.id,\n filename=filename,\n content_bytes=content.encode(\'utf-8\'),\n mime_type="application/json",\n metadata_dict={\n "description": "Greeting message",\n "source": "Greeting Agent",\n },\n timestamp=timestamp\n )\n \n result["artifact_saved"] = filename\n log.info(f"{log_identifier} Saved greeting to artifact: {filename}")\n \n except Exception as e:\n log.error(f"{log_identifier} Failed to save artifact: {e}")\n result["artifact_error"] = str(e)\n \n return result\n'})}),"\n",(0,i.jsxs)(n.p,{children:["This enhanced tool demonstrates several important concepts. The ",(0,i.jsx)(n.code,{children:"save_to_file"})," parameter allows the LLM to decide whether to save the greeting based on the user's request. This gives your agent flexibility in how it uses the tool."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"tool_context"})," object provides access to the artifact service through its ",(0,i.jsx)(n.code,{children:"_invocation_context"})," property. The invocation context contains information about the current execution environment, including the user ID, session ID, and app name. These identifiers are necessary for properly organizing and retrieving artifacts."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"save_artifact_with_metadata"})," helper function handles the details of saving files to the artifact service. You provide the content as bytes, specify a MIME type, and include metadata that describes the artifact. The metadata makes it easier to search for and manage artifacts later."]}),"\n",(0,i.jsx)(n.p,{children:"Error handling is important when working with external services. The try-except block ensures that if artifact saving fails, your tool can still return a successful greeting. The error is logged and included in the result, allowing the LLM to inform the user about the issue."}),"\n",(0,i.jsx)(n.h3,{id:"using-multiple-tool-configurations",children:"Using Multiple Tool Configurations"}),"\n",(0,i.jsx)(n.p,{children:"You can configure the same tool function multiple times with different settings. This pattern is useful when you want to provide the LLM with multiple variations of the same capability:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'tools:\n # Formal greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "formal_greeting"\n tool_config:\n greeting_prefix: "Good day"\n \n # Casual greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "casual_greeting"\n tool_config:\n greeting_prefix: "Hey there"\n \n # Enthusiastic greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "enthusiastic_greeting"\n tool_config:\n greeting_prefix: "Hello and welcome"\n'})}),"\n",(0,i.jsx)(n.p,{children:"This configuration creates three different tools from the same function. The LLM sees these as distinct capabilities and can choose the appropriate greeting style based on the context of the conversation. For example, it might use the formal greeting for business contexts and the casual greeting for friendly conversations."}),"\n",(0,i.jsxs)(n.p,{children:["Each tool configuration should have a unique ",(0,i.jsx)(n.code,{children:"tool_name"})," and should be listed in your agent card's skills section. This makes each variation discoverable and allows you to provide specific descriptions for each greeting style."]}),"\n",(0,i.jsx)(n.h2,{id:"quick-start-using-the-cli",children:"Quick Start: Using the CLI"}),"\n",(0,i.jsx)(n.p,{children:"If you want to get started quickly without manually creating all the files, you can use the Agent Mesh CLI to generate the basic structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam add agent my-first-agent\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This command launches an interactive setup (or use ",(0,i.jsx)(n.code,{children:"--gui"})," for browser-based configuration) that generates the necessary files and configuration, and sets up the basic agent structure."]}),"\n",(0,i.jsx)(n.p,{children:"Note that creating an agent as a plugin is preferred over creating an agent directly because plugins are more portable and easier to share."}),"\n",(0,i.jsx)(n.h3,{id:"cli-options",children:"CLI Options"}),"\n",(0,i.jsx)(n.p,{children:"You can customize the agent creation with provided CLI options. For a complete list of options, run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam add agent --help\n"})}),"\n",(0,i.jsx)(n.p,{children:"The CLI tool is useful for quickly scaffolding new agents, but understanding the manual process helps you customize and troubleshoot your agents more effectively."}),"\n",(0,i.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,i.jsx)(n.p,{children:"Following these best practices will help you create robust, maintainable agents."}),"\n",(0,i.jsx)(n.h3,{id:"tool-design",children:"Tool Design"}),"\n",(0,i.jsx)(n.p,{children:"Each tool should do one thing well. This single responsibility principle makes your tools easier to test, debug, and reuse. Instead of creating one large tool that handles multiple tasks, create several focused tools that each handle a specific task."}),"\n",(0,i.jsx)(n.p,{children:"Write detailed docstrings for your tools. The LLM uses these docstrings to understand what each tool does and when to use it. Include descriptions of all parameters, return values, and any important behavior or limitations."}),"\n",(0,i.jsx)(n.p,{children:"Always return structured error responses. When something goes wrong, your tool should return a dictionary with a status field indicating failure and a message explaining what went wrong. This allows the LLM to understand the error and potentially retry with different parameters or inform the user about the issue."}),"\n",(0,i.jsx)(n.p,{children:"Use consistent logging for debugging and monitoring. Log important events, parameter values, and results. This makes it much easier to troubleshoot issues when your agent is running in production."}),"\n",(0,i.jsx)(n.h3,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsx)(n.p,{children:"Use environment variables for sensitive data like API keys, database passwords, and other credentials. Never hardcode sensitive information in your configuration files or source code."}),"\n",(0,i.jsx)(n.p,{children:"Use Pydantic models for configuration validation. This catches configuration errors early and provides clear error messages when something is wrong. It also serves as documentation for what configuration options are available."}),"\n",(0,i.jsx)(n.p,{children:"Comment your configuration files thoroughly. YAML files can become complex, and clear comments help other developers (and your future self) understand what each section does and why it's configured that way."}),"\n",(0,i.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.p,{children:["Write unit tests for your tool functions independently. Test them with various inputs, including edge cases and error conditions. Mock the ",(0,i.jsx)(n.code,{children:"tool_context"})," and ",(0,i.jsx)(n.code,{children:"tool_config"})," parameters to isolate your tool logic from the framework."]}),"\n",(0,i.jsx)(n.p,{children:"Write integration tests that test your agent with real Agent Mesh infrastructure. These tests verify that your configuration is correct and that your tools work properly when called by the LLM."}),"\n",(0,i.jsx)(n.p,{children:"Mock external dependencies for reliable testing. If your tools call external APIs or databases, create mock versions for testing. This makes your tests faster and more reliable because they don't depend on external services being available."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(6540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[6426],{1007:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"documentation/installing-and-configuring/large_language_models","title":"Configuring LLMs","description":"Large Language Models (LLMs) serve as the intelligence foundation for Agent Mesh, powering everything from natural language understanding to complex reasoning and decision-making. The system provides flexible configuration options that allow you to connect with various LLM providers through a unified interface, making it easy to switch between providers or use multiple models for different purposes.","source":"@site/docs/documentation/installing-and-configuring/large_language_models.md","sourceDirName":"documentation/installing-and-configuring","slug":"/documentation/installing-and-configuring/large_language_models","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/large_language_models","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/installing-and-configuring/large_language_models.md","tags":[],"version":"current","sidebarPosition":340,"frontMatter":{"title":"Configuring LLMs","sidebar_position":340},"sidebar":"docSidebar","previous":{"title":"Configuring Agent Mesh","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations"},"next":{"title":"User Feedback","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/user-feedback"}}');var r=i(4848),s=i(8453);const o={title:"Configuring LLMs",sidebar_position:340},a=void 0,c={},l=[{value:"Understanding LiteLLM Integration",id:"understanding-litellm-integration",level:2},{value:"Provider-Specific Configurations",id:"provider-specific-configurations",level:2},{value:"OpenAI",id:"openai",level:3},{value:"Azure OpenAI",id:"azure-openai",level:3},{value:"Google Vertex AI",id:"google-vertex-ai",level:3},{value:"Amazon Bedrock",id:"amazon-bedrock",level:3},{value:"Anthropic",id:"anthropic",level:3},{value:"Additional Providers",id:"additional-providers",level:3},{value:"Prompt Caching",id:"prompt-caching",level:2},{value:"How Prompt Caching Works",id:"how-prompt-caching-works",level:3},{value:"Supported Providers",id:"supported-providers",level:3},{value:"Cache Strategy Configuration",id:"cache-strategy-configuration",level:3},{value:"Configuration Examples",id:"configuration-examples",level:3},{value:"Cache Strategy Selection Guidelines",id:"cache-strategy-selection-guidelines",level:3},{value:"What Gets Cached",id:"what-gets-cached",level:3},{value:"Cache Invalidation",id:"cache-invalidation",level:3},{value:"OAuth 2.0 Authentication",id:"oauth-20-authentication",level:2},{value:"Overview",id:"overview",level:3},{value:"Configuration Parameters",id:"configuration-parameters",level:3},{value:"Environment Variables",id:"environment-variables",level:3},{value:"YAML Configuration",id:"yaml-configuration",level:3},{value:"Error Handling and Fallback",id:"error-handling-and-fallback",level:3},{value:"Security Considerations",id:"security-considerations",level:3},{value:"Troubleshooting OAuth Issues",id:"troubleshooting-oauth-issues",level:3},{value:"Supported Providers",id:"supported-providers-1",level:3},{value:"Security and SSL/TLS Configuration",id:"security-and-ssltls-configuration",level:2},{value:"Example Environment Configuration",id:"example-environment-configuration",level:3}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Large Language Models (LLMs) serve as the intelligence foundation for Agent Mesh, powering everything from natural language understanding to complex reasoning and decision-making. The system provides flexible configuration options that allow you to connect with various LLM providers through a unified interface, making it easy to switch between providers or use multiple models for different purposes."}),"\n",(0,r.jsxs)(n.p,{children:["You can configure LLM settings in two locations within your Agent Mesh deployment. The ",(0,r.jsx)(n.code,{children:"apps.app_config.model"})," field allows you to specify model settings for individual agents or gateways, providing fine-grained control over which models specific components use. Alternatively, you can define models globally in the ",(0,r.jsx)(n.code,{children:"shared_config.yaml"})," file under the ",(0,r.jsx)(n.code,{children:"models"})," section, creating reusable configurations that multiple components can reference. For detailed information about the overall configuration structure and shared configuration management, see the ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations",children:"Configuring Agent Mesh"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"understanding-litellm-integration",children:"Understanding LiteLLM Integration"}),"\n",(0,r.jsxs)(n.p,{children:["Agent Mesh leverages ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers",children:"LiteLLM"})," to provide seamless integration with numerous LLM providers. This integration layer abstracts the differences between various provider APIs, allowing you to use a consistent configuration format regardless of whether you're connecting to OpenAI, Anthropic, Google, Amazon, or other supported providers."]}),"\n",(0,r.jsxs)(n.p,{children:["The configuration system passes all fields from the ",(0,r.jsx)(n.code,{children:"models"})," section directly to LiteLLM, giving you access to the full range of provider-specific options and features. This approach ensures that you can take advantage of advanced capabilities offered by different providers while maintaining a consistent configuration experience across your deployment."]}),"\n",(0,r.jsxs)(n.p,{children:["Environment variables provide a secure and flexible way to manage sensitive information such as API keys and endpoint URLs. The configuration system supports environment variable substitution using the format ",(0,r.jsx)(n.code,{children:"${ENV_VAR_NAME, default_value}"}),", allowing you to keep secrets out of your configuration files while providing sensible defaults for development environments."]}),"\n",(0,r.jsx)(n.h2,{id:"provider-specific-configurations",children:"Provider-Specific Configurations"}),"\n",(0,r.jsx)(n.h3,{id:"openai",children:"OpenAI"}),"\n",(0,r.jsx)(n.p,{children:"OpenAI provides some of the most widely-used language models, including the GPT series. The configuration requires minimal setup, needing only the model name and your API key. The system uses OpenAI's default endpoints automatically, simplifying the configuration process."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"model: gpt-5\napi_key: ${OPENAI_API_KEY}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If your organization belongs to multiple OpenAI organizations, you can specify which organization to use by adding the ",(0,r.jsx)(n.code,{children:"organization"})," parameter. This parameter helps ensure billing and usage tracking align with your organizational structure."]}),"\n",(0,r.jsxs)(n.p,{children:["For comprehensive details about OpenAI-specific configuration options and advanced features, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers/openai",children:"OpenAI documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"azure-openai",children:"Azure OpenAI"}),"\n",(0,r.jsx)(n.p,{children:"Azure OpenAI Service provides OpenAI models through Microsoft's cloud infrastructure, offering additional enterprise features such as private networking and enhanced security controls. The configuration requires specifying your custom Azure endpoint, API key, and API version."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'model: azure/gpt-5\napi_base: ${AZURE_API_BASE,"https://your-custom-endpoint.openai.azure.com/"}\napi_key: ${AZURE_API_KEY}\napi_version: ${AZURE_API_VERSION,"2024-12-01-preview"}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The model name must include the ",(0,r.jsx)(n.code,{children:"azure/"})," prefix to indicate you're using Azure OpenAI rather than the standard OpenAI service. The API base URL points to your specific Azure OpenAI resource, which you configure during the Azure setup process."]}),"\n",(0,r.jsxs)(n.p,{children:["For detailed information about Azure-specific configuration options, deployment models, and enterprise features, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers/azure/",children:"Azure OpenAI documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"google-vertex-ai",children:"Google Vertex AI"}),"\n",(0,r.jsx)(n.p,{children:"Google Vertex AI provides access to both Google's own models and third-party models through a unified platform. This service offers enterprise-grade features including fine-tuning capabilities, model versioning, and integration with other Google Cloud services."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'model: vertex_ai/claude-sonnet-4@20250514\nvertex_project: ${VERTEX_PROJECT}\nvertex_location: ${VERTEX_LOCATION,"us-east5"}\nvertex_credentials: ${VERTEX_CREDENTIALS}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"vertex_credentials"})," parameter requires a JSON string containing your Google Cloud service account key. This credential provides the necessary authentication for accessing Vertex AI services. You can obtain this key from the Google Cloud Console by creating a service account with appropriate Vertex AI permissions."]}),"\n",(0,r.jsx)(n.p,{children:"An example of the credential structure follows this format:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'export VERTEX_CREDENTIALS=\'{"type": "", "project_id": "", "private_key_id": "", "private_key": "", "client_email": "", "client_id": "", "auth_uri": "", "token_uri": "", "auth_provider_x509_cert_url": "", "client_x509_cert_url": "", "universe_domain": ""}\'\n'})}),"\n",(0,r.jsxs)(n.p,{children:["For comprehensive information about Vertex AI configuration, available models, and advanced features, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers/vertex",children:"Vertex AI documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"amazon-bedrock",children:"Amazon Bedrock"}),"\n",(0,r.jsx)(n.p,{children:"Amazon Bedrock provides access to foundation models from various providers through AWS infrastructure. This service offers enterprise features such as private VPC connectivity, AWS IAM integration, and comprehensive logging through AWS CloudTrail."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'model: bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0\naws_region_name: ${AWS_REGION_NAME,"us-east-1"}\naws_access_key_id: ${AWS_ACCESS_KEY_ID}\naws_secret_access_key: ${AWS_SECRET_ACCESS_KEY}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The model name includes the ",(0,r.jsx)(n.code,{children:"bedrock/"})," prefix followed by the specific model identifier as defined in the Bedrock service. AWS credentials follow standard AWS authentication patterns, allowing you to use IAM roles, environment variables, or credential files depending on your deployment environment."]}),"\n",(0,r.jsxs)(n.p,{children:["For detailed information about Bedrock-specific configuration options, available models, and AWS integration features, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers/bedrock",children:"AWS Bedrock documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"anthropic",children:"Anthropic"}),"\n",(0,r.jsx)(n.p,{children:"Anthropic provides the Claude family of models, known for their strong reasoning capabilities and helpful, harmless, and honest behavior. The direct Anthropic API offers the most up-to-date model versions and features."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"model: claude-4\napi_key: ${ANTHROPIC_API_KEY}\n"})}),"\n",(0,r.jsx)(n.p,{children:"The configuration requires only the model name and your Anthropic API key, making it straightforward to integrate Claude models into your agent workflows. Anthropic regularly updates their models with improved capabilities, and the direct API typically provides access to the latest versions first."}),"\n",(0,r.jsxs)(n.p,{children:["For comprehensive details about Anthropic-specific configuration options and model capabilities, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers/anthropic",children:"Anthropic documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"additional-providers",children:"Additional Providers"}),"\n",(0,r.jsx)(n.p,{children:"LiteLLM supports numerous other providers including Cohere, Hugging Face, Together AI, and many more. Each provider may have specific configuration requirements and capabilities, but the general pattern of specifying model names, endpoints, and authentication credentials remains consistent."}),"\n",(0,r.jsxs)(n.p,{children:["For a complete list of supported providers and their specific configuration requirements, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/providers",children:"LiteLLM providers documentation"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"prompt-caching",children:"Prompt Caching"}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh supports prompt caching to significantly reduce costs and latency when using LLM providers that support this feature. Prompt caching allows frequently-used content such as system instructions and tool definitions to be cached by the LLM provider, reducing both processing time and token costs on subsequent requests."}),"\n",(0,r.jsx)(n.h3,{id:"how-prompt-caching-works",children:"How Prompt Caching Works"}),"\n",(0,r.jsx)(n.p,{children:"When you configure prompt caching, the system marks specific portions of each request for caching by the LLM provider. These cached portions persist for a provider-defined duration (typically 5 minutes to 1 hour) and can be reused across multiple requests without re-processing. This approach provides substantial cost savings for agents with large system instructions or extensive tool definitions."}),"\n",(0,r.jsx)(n.h3,{id:"supported-providers",children:"Supported Providers"}),"\n",(0,r.jsx)(n.p,{children:"The caching mechanism operates transparently through LiteLLM's provider-agnostic interface. Prompt caching support varies by provider:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Anthropic Claude"}),": Full support with explicit cache control, 90% cost reduction on cache hits"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"OpenAI"}),": Automatic caching for content exceeding 1,024 tokens"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Azure OpenAI"}),": Automatic caching following OpenAI behavior"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"AWS Bedrock"}),": Native caching support via LiteLLM translation"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Deepseek"}),": Native caching support via LiteLLM translation"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Providers without caching support safely ignore cache control markers, ensuring backward compatibility across all providers."}),"\n",(0,r.jsx)(n.h3,{id:"cache-strategy-configuration",children:"Cache Strategy Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh provides three cache strategies that you can configure per model to optimize costs based on usage patterns:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Strategy"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Cache Duration"}),(0,r.jsx)(n.th,{children:"Best For"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:'"5m"'})}),(0,r.jsx)(n.td,{children:"5-minute ephemeral cache"}),(0,r.jsx)(n.td,{children:"5 minutes"}),(0,r.jsx)(n.td,{children:"High-frequency agents (10+ calls/hour)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:'"1h"'})}),(0,r.jsx)(n.td,{children:"1-hour extended cache"}),(0,r.jsx)(n.td,{children:"1 hour"}),(0,r.jsx)(n.td,{children:"Burst patterns with gaps (3-10 calls/hour)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:'"none"'})}),(0,r.jsx)(n.td,{children:"Disable caching"}),(0,r.jsx)(n.td,{children:"N/A"}),(0,r.jsx)(n.td,{children:"Rarely-used agents (less than 2 calls/hour)"})]})]})]}),"\n",(0,r.jsxs)(n.p,{children:["The default strategy is ",(0,r.jsx)(n.code,{children:'"5m"'})," when not explicitly specified, providing optimal performance for most use cases without requiring configuration changes."]}),"\n",(0,r.jsx)(n.h3,{id:"configuration-examples",children:"Configuration Examples"}),"\n",(0,r.jsxs)(n.p,{children:["Configure prompt caching in your model settings using the ",(0,r.jsx)(n.code,{children:"cache_strategy"})," parameter:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'models:\n # High-frequency orchestrator with 5-minute cache\n planning:\n model: anthropic/claude-sonnet-4-5-20250929\n api_key: ${ANTHROPIC_API_KEY}\n cache_strategy: "5m"\n temperature: 0.1\n\n # Burst-pattern agent with 1-hour cache\n analysis:\n model: anthropic/claude-sonnet-4-5-20250929\n api_key: ${ANTHROPIC_API_KEY}\n cache_strategy: "1h"\n temperature: 0.7\n\n # Low-frequency agent with caching disabled\n maintenance:\n model: anthropic/claude-sonnet-4-5-20250929\n api_key: ${ANTHROPIC_API_KEY}\n cache_strategy: "none"\n'})}),"\n",(0,r.jsx)(n.h3,{id:"cache-strategy-selection-guidelines",children:"Cache Strategy Selection Guidelines"}),"\n",(0,r.jsx)(n.p,{children:"Choose your cache strategy based on agent usage patterns:"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:'Use "5m" strategy'})," when:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Agent receives 10 or more requests per hour"}),"\n",(0,r.jsx)(n.li,{children:"Requests arrive in steady streams rather than isolated bursts"}),"\n",(0,r.jsx)(n.li,{children:"Cache remains warm through continuous use"}),"\n",(0,r.jsx)(n.li,{children:"Example: Primary orchestrator agents handling user interactions"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:'Use "1h" strategy'})," when:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Agent receives 3-10 requests per hour in burst patterns"}),"\n",(0,r.jsx)(n.li,{children:"Gaps between request bursts exceed 5 minutes"}),"\n",(0,r.jsx)(n.li,{children:"Extended cache duration bridges usage gaps"}),"\n",(0,r.jsx)(n.li,{children:"Example: Development and testing scenarios, periodic analysis agents"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:'Use "none" strategy'})," when:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Agent receives fewer than 2 requests per hour"}),"\n",(0,r.jsx)(n.li,{children:"Cache write premium exceeds potential savings"}),"\n",(0,r.jsx)(n.li,{children:"System instructions change frequently"}),"\n",(0,r.jsx)(n.li,{children:"Example: Maintenance agents, backup handlers, rarely-used specialized agents"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"what-gets-cached",children:"What Gets Cached"}),"\n",(0,r.jsx)(n.p,{children:"The caching system optimizes two primary components of LLM requests:"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"System Instructions"}),": The complete agent system prompt, including capabilities, guidelines, and any static context. System instructions typically represent the largest cacheable content and provide the most significant cost savings."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Tool Definitions"}),": All tool declarations available to the agent, including peer agent communication tools. Agent Mesh ensures tool order stability through alphabetical sorting, maintaining cache validity across requests."]}),"\n",(0,r.jsx)(n.p,{children:"Conversation history and user messages are never cached, as these components change with each request and represent the unique context for each interaction."}),"\n",(0,r.jsx)(n.h3,{id:"cache-invalidation",children:"Cache Invalidation"}),"\n",(0,r.jsx)(n.p,{children:"The system automatically handles cache invalidation, requiring no manual intervention. When the cache expires or invalidates, the next request writes new cache content, and subsequent requests benefit from the refreshed cache."}),"\n",(0,r.jsx)(n.h2,{id:"oauth-20-authentication",children:"OAuth 2.0 Authentication"}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh supports OAuth 2.0 Client Credentials authentication for LLM providers that require OAuth-based authentication instead of traditional API keys. This authentication method provides enhanced security through automatic token management, secure credential handling, and seamless integration with OAuth-enabled LLM endpoints."}),"\n",(0,r.jsx)(n.h3,{id:"overview",children:"Overview"}),"\n",(0,r.jsxs)(n.p,{children:["The OAuth 2.0 Client Credentials flow is a machine-to-machine authentication method defined in ",(0,r.jsx)(n.a,{href:"https://tools.ietf.org/html/rfc6749#section-4.4",children:"RFC 6749"}),". Agent Mesh handles the complete OAuth lifecycle automatically, including token acquisition, caching, refresh, and injection into LLM requests. This implementation ensures secure and efficient authentication without requiring manual token management."]}),"\n",(0,r.jsx)(n.h3,{id:"configuration-parameters",children:"Configuration Parameters"}),"\n",(0,r.jsx)(n.p,{children:"OAuth authentication requires several configuration parameters that you can specify through environment variables and YAML configuration:"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Parameter"}),(0,r.jsx)(n.th,{children:"Required"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Default"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_token_url"})}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"OAuth token endpoint URL"}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_client_id"})}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"OAuth client identifier"}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_client_secret"})}),(0,r.jsx)(n.td,{children:"Yes"}),(0,r.jsx)(n.td,{children:"OAuth client secret"}),(0,r.jsx)(n.td,{children:"-"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_scope"})}),(0,r.jsx)(n.td,{children:"No"}),(0,r.jsx)(n.td,{children:"OAuth scope (space-separated)"}),(0,r.jsx)(n.td,{children:"None"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_ca_cert"})}),(0,r.jsx)(n.td,{children:"No"}),(0,r.jsx)(n.td,{children:"Custom CA certificate path for OAuth endpoint"}),(0,r.jsx)(n.td,{children:"None"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"oauth_token_refresh_buffer_seconds"})}),(0,r.jsx)(n.td,{children:"No"}),(0,r.jsx)(n.td,{children:"Seconds before expiration to refresh token"}),(0,r.jsx)(n.td,{children:"300"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,r.jsxs)(n.p,{children:["Configure OAuth credentials securely using environment variables in your ",(0,r.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'# Required OAuth Configuration\nOAUTH_TOKEN_URL="https://auth.example.com/oauth/token"\nOAUTH_CLIENT_ID="your_client_id"\nOAUTH_CLIENT_SECRET="your_client_secret"\n\n# Optional OAuth Configuration\nOAUTH_SCOPE="llm.read llm.write"\nOAUTH_CA_CERT_PATH="/path/to/ca.crt"\nOAUTH_TOKEN_REFRESH_BUFFER_SECONDS="300"\n\n# LLM Endpoint Configuration\nOAUTH_LLM_API_BASE="https://api.example.com/v1"\n'})}),"\n",(0,r.jsx)(n.h3,{id:"yaml-configuration",children:"YAML Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Configure OAuth-authenticated models in your ",(0,r.jsx)(n.code,{children:"shared_config.yaml"})," file:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"models:\n # OAuth-authenticated planning model\n planning:\n model: ${OAUTH_LLM_PLANNING_MODEL_NAME}\n api_base: ${OAUTH_LLM_API_BASE}\n \n # OAuth 2.0 Client Credentials configuration\n oauth_token_url: ${OAUTH_TOKEN_URL}\n oauth_client_id: ${OAUTH_CLIENT_ID}\n oauth_client_secret: ${OAUTH_CLIENT_SECRET}\n oauth_scope: ${OAUTH_SCOPE}\n oauth_ca_cert: ${OAUTH_CA_CERT_PATH}\n oauth_token_refresh_buffer_seconds: ${OAUTH_TOKEN_REFRESH_BUFFER_SECONDS, 300}\n \n parallel_tool_calls: true\n temperature: 0.1\n\n # OAuth-authenticated general model\n general:\n model: ${OAUTH_LLM_GENERAL_MODEL_NAME}\n api_base: ${OAUTH_LLM_API_BASE}\n \n # OAuth 2.0 Client Credentials configuration\n oauth_token_url: ${OAUTH_TOKEN_URL}\n oauth_client_id: ${OAUTH_CLIENT_ID}\n oauth_client_secret: ${OAUTH_CLIENT_SECRET}\n oauth_scope: ${OAUTH_SCOPE}\n oauth_ca_cert: ${OAUTH_CA_CERT_PATH}\n oauth_token_refresh_buffer_seconds: ${OAUTH_TOKEN_REFRESH_BUFFER_SECONDS, 300}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"error-handling-and-fallback",children:"Error Handling and Fallback"}),"\n",(0,r.jsx)(n.p,{children:"The OAuth system implements robust error handling:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"4xx Errors"}),": Client configuration errors result in no retries, as these indicate credential or configuration issues"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"5xx Errors"}),": Server errors trigger exponential backoff with jitter for up to 3 retry attempts"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Network Errors"}),": Connection issues trigger exponential backoff with jitter for up to 3 retry attempts"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["If OAuth authentication fails and an ",(0,r.jsx)(n.code,{children:"api_key"})," is configured in the model settings, the system automatically falls back to API key authentication and logs the OAuth failure. If no fallback is available, the request fails with the OAuth error."]}),"\n",(0,r.jsx)(n.h3,{id:"security-considerations",children:"Security Considerations"}),"\n",(0,r.jsx)(n.p,{children:"When implementing OAuth authentication, follow these security best practices:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Credential Storage"}),": Always store OAuth credentials securely using environment variables, never hardcode them in configuration files"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Token Caching"}),": Tokens are cached in memory only and never persisted to disk"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"SSL/TLS"}),": Always use HTTPS for OAuth endpoints to protect credentials in transit"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Custom CA Certificates"}),": Use the ",(0,r.jsx)(n.code,{children:"oauth_ca_cert"})," parameter for private or internal OAuth servers with custom certificate authorities"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Scope Limitation"}),": Request only the minimal OAuth scopes required for your LLM operations"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"troubleshooting-oauth-issues",children:"Troubleshooting OAuth Issues"}),"\n",(0,r.jsx)(n.p,{children:"Common OAuth authentication issues and their solutions:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Invalid Client Credentials"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ERROR: OAuth token request failed with status 401: Invalid client credentials\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Verify that ",(0,r.jsx)(n.code,{children:"OAUTH_CLIENT_ID"})," and ",(0,r.jsx)(n.code,{children:"OAUTH_CLIENT_SECRET"})," are correct and properly URL-encoded if they contain special characters."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Invalid Scope"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ERROR: OAuth token request failed with status 400: Invalid scope\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Verify that ",(0,r.jsx)(n.code,{children:"OAUTH_SCOPE"})," matches your provider's requirements and that scope values are space-separated."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"SSL Certificate Issues"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ERROR: OAuth token request failed: SSL certificate verification failed\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Set ",(0,r.jsx)(n.code,{children:"OAUTH_CA_CERT_PATH"})," to point to your custom CA certificate file and verify the certificate chain is complete."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Token Refresh Issues"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"WARNING: OAuth token request failed (attempt 1/4): Connection timeout\n"})}),"\n",(0,r.jsx)(n.p,{children:"Check network connectivity to the OAuth endpoint, verify the OAuth endpoint URL is correct, and consider increasing timeout values if needed."}),"\n",(0,r.jsx)(n.h3,{id:"supported-providers-1",children:"Supported Providers"}),"\n",(0,r.jsxs)(n.p,{children:["This OAuth implementation works with any LLM provider that supports OAuth 2.0 Client Credentials flow, accepts Bearer tokens in the ",(0,r.jsx)(n.code,{children:"Authorization"})," header, and is compatible with LiteLLM's request format. Examples include Azure OpenAI with OAuth-enabled endpoints, custom enterprise LLM deployments, and third-party LLM services with OAuth support."]}),"\n",(0,r.jsx)(n.h2,{id:"security-and-ssltls-configuration",children:"Security and SSL/TLS Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh provides comprehensive security controls for connections to LLM endpoints, allowing you to fine-tune SSL/TLS behavior to meet your organization's security requirements. These settings help ensure secure communication with LLM providers while providing flexibility for various network environments and security policies."}),"\n",(0,r.jsx)(n.p,{children:"The SSL verification setting controls whether the system validates SSL certificates when connecting to LLM endpoints. Although disabling verification can resolve connectivity issues in development environments, production deployments should always use proper SSL verification to maintain security."}),"\n",(0,r.jsx)(n.p,{children:"SSL security levels determine the cryptographic standards required for connections. Higher security levels enforce stricter requirements but may cause compatibility issues with older endpoints. The default level provides a good balance between security and compatibility for most deployments."}),"\n",(0,r.jsx)(n.p,{children:"Custom SSL certificates allow you to specify additional trusted certificate authorities or use self-signed certificates in controlled environments. You can provide certificates either as file paths or as direct certificate content in PEM format."}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Parameter"}),(0,r.jsx)(n.th,{children:"Type"}),(0,r.jsx)(n.th,{children:"Description"}),(0,r.jsx)(n.th,{children:"Default"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SSL_VERIFY"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"boolean"})}),(0,r.jsx)(n.td,{children:"Controls SSL certificate verification for outbound connections."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"true"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SSL_SECURITY_LEVEL"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"integer"})}),(0,r.jsx)(n.td,{children:"Sets the SSL security level (higher values enforce stricter checks)."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"2"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SSL_CERT_FILE"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"string"})}),(0,r.jsx)(n.td,{children:"Path to a custom SSL certificate file to use for verification."}),(0,r.jsx)(n.td,{children:"(none)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"SSL_CERTIFICATE"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"string"})}),(0,r.jsx)(n.td,{children:"Direct content of the SSL certificate (PEM format)."}),(0,r.jsx)(n.td,{children:"(none)"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"DISABLE_AIOHTTP_TRANSPORT"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"boolean"})}),(0,r.jsx)(n.td,{children:"Flag to disable the use of aiohttp transport for HTTP requests."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"false"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"AIOHTTP_TRUST_ENV"})}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"boolean"})}),(0,r.jsx)(n.td,{children:"Flag to enable aiohttp to trust environment proxy settings."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"false"})})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"The HTTP transport settings control how the system makes network requests to LLM endpoints. The aiohttp transport provides efficient asynchronous HTTP handling, although some environments may require disabling it for compatibility reasons. The trust environment setting allows the HTTP client to use proxy settings from environment variables, which can be useful in corporate networks."}),"\n",(0,r.jsxs)(n.p,{children:["For detailed information about each security setting and specific use cases, see the ",(0,r.jsx)(n.a,{href:"https://docs.litellm.ai/docs/guides/security_settings",children:"LiteLLM security documentation"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"example-environment-configuration",children:"Example Environment Configuration"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'# SSL Configuration\nSSL_VERIFY=true\nSSL_SECURITY_LEVEL=2\nSSL_CERT_FILE=/path/to/your/certificate.pem\nSSL_CERTIFICATE="-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAg...T2u3V4w5X6y7Z8\n-----END CERTIFICATE-----"\n\n# HTTP Transport Configuration\nDISABLE_AIOHTTP_TRANSPORT=false\nAIOHTTP_TRUST_ENV=false\n'})}),"\n",(0,r.jsx)(n.p,{children:"This example demonstrates how to configure SSL settings through environment variables, providing a secure foundation for LLM communications while maintaining flexibility for different deployment scenarios. The certificate content should be replaced with your actual certificate data, and file paths should point to your specific certificate locations."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>a});var t=i(6540);const r={},s=t.createContext(r);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]);