solace-agent-mesh 1.6.2__py3-none-any.whl → 1.7.0__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.
- solace_agent_mesh/agent/adk/adk_llm.txt +12 -18
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +138 -20
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +2 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +38 -5
- solace_agent_mesh/agent/adk/models/models_llm.txt +82 -35
- solace_agent_mesh/agent/adk/runner.py +9 -0
- solace_agent_mesh/agent/adk/services.py +3 -3
- solace_agent_mesh/agent/adk/stream_parser.py +6 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/agent_llm.txt +61 -70
- solace_agent_mesh/agent/protocol/event_handlers.py +29 -1
- solace_agent_mesh/agent/protocol/protocol_llm.txt +1 -1
- solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
- solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
- solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
- solace_agent_mesh/agent/sac/app.py +22 -0
- solace_agent_mesh/agent/sac/component.py +76 -40
- solace_agent_mesh/agent/sac/sac_llm.txt +1 -1
- solace_agent_mesh/agent/sac/task_execution_context.py +21 -0
- solace_agent_mesh/agent/testing/testing_llm.txt +2 -1
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +13 -148
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +93 -80
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +3 -2
- solace_agent_mesh/agent/utils/artifact_helpers.py +4 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +16 -2
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.e4870a49.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.09ed9234.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{ab9708a8.3e6dd091.js → ab9708a8.245ae0ef.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{e6f9706b.e74a984d.js → e6f9706b.045d0fa1.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.e6488e8b.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +18 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +196 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +6 -7
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +160 -169
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +59 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +10 -6
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +24 -29
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +27 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +5 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +9 -9
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1762189824009.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1762189824009.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-D4_RMYRh.js → authCallback-tcIFZLis.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-UZ3qU6Bq.js → client-CRYdKo2Q.js} +3 -3
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +353 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CINwxvwV.js +470 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/a2a_llm.txt +13 -20
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +1 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +49 -11
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +26 -9
- solace_agent_mesh/common/common_llm.txt +13 -34
- solace_agent_mesh/common/data_parts.py +20 -4
- solace_agent_mesh/common/middleware/middleware_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +1 -1
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/services/providers/providers_llm.txt +3 -2
- solace_agent_mesh/common/services/services_llm.txt +9 -4
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/embeds/modifiers.py +2 -1
- solace_agent_mesh/common/utils/embeds/resolver.py +58 -6
- solace_agent_mesh/common/utils/embeds/types.py +8 -0
- solace_agent_mesh/common/utils/utils_llm.txt +5 -6
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +1 -1
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +143 -0
- solace_agent_mesh/gateway/adapter/types.py +221 -0
- solace_agent_mesh/gateway/base/app.py +29 -2
- solace_agent_mesh/gateway/base/base_llm.txt +10 -8
- solace_agent_mesh/gateway/base/component.py +573 -142
- solace_agent_mesh/gateway/gateway_llm.txt +55 -59
- solace_agent_mesh/gateway/generic/__init__.py +1 -0
- solace_agent_mesh/gateway/generic/app.py +50 -0
- solace_agent_mesh/gateway/generic/component.py +650 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +99 -49
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +92 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +150 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +26 -20
- solace_agent_mesh/gateway/http_sse/app.py +19 -14
- solace_agent_mesh/gateway/http_sse/component.py +150 -118
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +1 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +21 -3
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +8 -8
- solace_agent_mesh/gateway/http_sse/main.py +55 -14
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +56 -98
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +23 -1
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +112 -4
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -1
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +51 -60
- solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +7 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +125 -157
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +269 -8
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +143 -51
- solace_agent_mesh/gateway/http_sse/routers/config.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +198 -94
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +68 -18
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +13 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +51 -35
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +2 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +542 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +9 -11
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +154 -3
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +296 -4
- solace_agent_mesh/gateway/http_sse/services/project_service.py +403 -0
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +16 -10
- solace_agent_mesh/gateway/http_sse/services/session_service.py +178 -6
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +2 -3
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +48 -14
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- {solace_agent_mesh-1.6.2.dist-info → solace_agent_mesh-1.7.0.dist-info}/METADATA +3 -5
- {solace_agent_mesh-1.6.2.dist-info → solace_agent_mesh-1.7.0.dist-info}/RECORD +219 -176
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.d1643f0b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.97f920d4.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761663789856.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761663789856.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-DSqhjwq_.js +0 -405
- /solace_agent_mesh/assets/docs/assets/js/{main.d1643f0b.js.LICENSE.txt → main.e6488e8b.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.6.2.dist-info → solace_agent_mesh-1.7.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.6.2.dist-info → solace_agent_mesh-1.7.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.2.dist-info → solace_agent_mesh-1.7.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[3349],{3085:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"documentation/developing/creating-python-tools","title":"Creating Python Tools","description":"Agent Mesh provides a powerful and unified system for creating custom agent tools using Python. This is the primary way to extend an agent\'s capabilities with your own business logic, integrate with proprietary APIs, or perform specialized data processing.","source":"@site/docs/documentation/developing/creating-python-tools.md","sourceDirName":"documentation/developing","slug":"/documentation/developing/creating-python-tools","permalink":"/solace-agent-mesh/docs/documentation/developing/creating-python-tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/developing/creating-python-tools.md","tags":[],"version":"current","sidebarPosition":440,"frontMatter":{"title":"Creating Python Tools","sidebar_position":440},"sidebar":"docSidebar","previous":{"title":"Creating Custom Gateways","permalink":"/solace-agent-mesh/docs/documentation/developing/create-gateways"},"next":{"title":"Creating Service Providers","permalink":"/solace-agent-mesh/docs/documentation/developing/creating-service-providers"}}');var i=o(4848),s=o(8453);const a={title:"Creating Python Tools",sidebar_position:440},l="Creating Python Tools",r={},c=[{value:"Tool Creation Patterns",id:"tool-creation-patterns",level:2},{value:"Pattern 1: Simple Function-Based Tools",id:"pattern-1-simple-function-based-tools",level:2},{value:"Step 1: Write the Tool Function",id:"step-1-write-the-tool-function",level:3},{value:"Step 2: Configure the Tool",id:"step-2-configure-the-tool",level:3},{value:"Pattern 2: Advanced Single-Class Tools",id:"pattern-2-advanced-single-class-tools",level:2},{value:"Step 1: Create the <code>DynamicTool</code> Class",id:"step-1-create-the-dynamictool-class",level:3},{value:"Step 2: Configure the Tool",id:"step-2-configure-the-tool-1",level:3},{value:"Pattern 3: The Tool Provider Factory",id:"pattern-3-the-tool-provider-factory",level:2},{value:"Step 1: Create the Provider and Tools",id:"step-1-create-the-provider-and-tools",level:3},{value:"Step 2: Configure the Provider",id:"step-2-configure-the-provider",level:3},{value:"Managing Tool Lifecycles with <code>init</code> and <code>cleanup</code>",id:"managing-tool-lifecycles-with-init-and-cleanup",level:2},{value:"YAML-Based Lifecycle Hooks",id:"yaml-based-lifecycle-hooks",level:3},{value:"Step 1: Define the Tool and Hook Functions",id:"step-1-define-the-tool-and-hook-functions",level:4},{value:"Step 2: Configure the Hooks in YAML",id:"step-2-configure-the-hooks-in-yaml",level:4},{value:"Class-Based Lifecycle Methods (for <code>DynamicTool</code>)",id:"class-based-lifecycle-methods-for-dynamictool",level:3},{value:"Execution Order and Guarantees",id:"execution-order-and-guarantees",level:3},{value:"Adding Validated Configuration to Dynamic Tools",id:"adding-validated-configuration-to-dynamic-tools",level:2},{value:"Example 1: Using a Pydantic Model with a Single <code>DynamicTool</code>",id:"example-1-using-a-pydantic-model-with-a-single-dynamictool",level:3},{value:"Step 1: Define the Model and Tool Class",id:"step-1-define-the-model-and-tool-class",level:4},{value:"Step 2: Configure the Tool in YAML",id:"step-2-configure-the-tool-in-yaml",level:4},{value:"Example 2: Using a Pydantic Model with a <code>DynamicToolProvider</code>",id:"example-2-using-a-pydantic-model-with-a-dynamictoolprovider",level:3},{value:"Step 1: Define the Model and Provider Class",id:"step-1-define-the-model-and-provider-class",level:4},{value:"Step 2: Configure the Provider in YAML",id:"step-2-configure-the-provider-in-yaml",level:4}];function d(e){const n={code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",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,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"creating-python-tools",children:"Creating Python Tools"})}),"\n",(0,i.jsx)(n.p,{children:"Agent Mesh provides a powerful and unified system for creating custom agent tools using Python. This is the primary way to extend an agent's capabilities with your own business logic, integrate with proprietary APIs, or perform specialized data processing."}),"\n",(0,i.jsxs)(n.p,{children:["This guide covers the different patterns for creating custom tools, all of which are configured using the versatile ",(0,i.jsx)(n.code,{children:"tool_type: python"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"tool-creation-patterns",children:"Tool Creation Patterns"}),"\n",(0,i.jsx)(n.p,{children:"There are three primary patterns for creating Python tools, ranging from simple to advanced. You can choose the best pattern for your needs, and even mix and match them within the same project."}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Pattern"}),(0,i.jsx)(n.th,{children:"Best For"}),(0,i.jsx)(n.th,{children:"Key Feature"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsx)(n.strong,{children:"Function-Based"})}),(0,i.jsx)(n.td,{children:"Simple, self-contained tools with static inputs."}),(0,i.jsx)(n.td,{children:"Quick and easy; uses function signature."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsxs)(n.strong,{children:["Single ",(0,i.jsx)(n.code,{children:"DynamicTool"})," Class"]})}),(0,i.jsx)(n.td,{children:"Tools that require complex logic or a programmatically defined interface."}),(0,i.jsx)(n.td,{children:"Full control over the tool's definition."})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:(0,i.jsxs)(n.strong,{children:[(0,i.jsx)(n.code,{children:"DynamicToolProvider"})," Class"]})}),(0,i.jsx)(n.td,{children:"Generating multiple related tools from a single, configurable source."}),(0,i.jsx)(n.td,{children:"Maximum scalability and code reuse."})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["All three patterns are configured in your agent's YAML file under the ",(0,i.jsx)(n.code,{children:"tools"})," list with ",(0,i.jsx)(n.code,{children:"tool_type: python"}),"."]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"pattern-1-simple-function-based-tools",children:"Pattern 1: Simple Function-Based Tools"}),"\n",(0,i.jsxs)(n.p,{children:["This is the most straightforward way to create a custom tool. You define a standard Python ",(0,i.jsx)(n.code,{children:"async"})," function, and Agent Mesh automatically introspects its signature and docstring to create the tool definition for the LLM."]}),"\n",(0,i.jsx)(n.h3,{id:"step-1-write-the-tool-function",children:"Step 1: Write the Tool Function"}),"\n",(0,i.jsxs)(n.p,{children:["Create a Python file (e.g., ",(0,i.jsx)(n.code,{children:"src/my_agent/tools.py"}),") and define your tool."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/tools.py\nfrom typing import Any, Dict, Optional\nfrom google.adk.tools import ToolContext\n\nasync def greet_user(\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 greeting_prefix = "Hello"\n if tool_config:\n greeting_prefix = tool_config.get("greeting_prefix", "Hello")\n\n greeting_message = f"{greeting_prefix}, {name}! Welcome to Agent Mesh!"\n\n return {\n "status": "success",\n "message": greeting_message\n }\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Key Requirements:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["The function must be ",(0,i.jsx)(n.code,{children:"async def"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["The function's docstring is used as the tool's ",(0,i.jsx)(n.code,{children:"description"})," for the LLM."]}),"\n",(0,i.jsxs)(n.li,{children:["Type hints (",(0,i.jsx)(n.code,{children:"str"}),", ",(0,i.jsx)(n.code,{children:"int"}),", ",(0,i.jsx)(n.code,{children:"bool"}),") are used to generate the parameter schema."]}),"\n",(0,i.jsxs)(n.li,{children:["The function should accept ",(0,i.jsx)(n.code,{children:"tool_context"})," and ",(0,i.jsx)(n.code,{children:"tool_config"})," as optional keyword arguments to receive framework context and YAML configuration."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-2-configure-the-tool",children:"Step 2: Configure the Tool"}),"\n",(0,i.jsxs)(n.p,{children:["In your agent's YAML configuration, add a ",(0,i.jsx)(n.code,{children:"tool_type: python"})," block and point it to your function."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: python\n component_module: "my_agent.tools"\n function_name: "greet_user"\n tool_config:\n greeting_prefix: "Greetings"\n'})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"component_module"}),": The Python module path to your tools file."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"function_name"}),": The exact name of the function to load."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"tool_config"}),": An optional dictionary passed to your tool at runtime."]}),"\n"]}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"pattern-2-advanced-single-class-tools",children:"Pattern 2: Advanced Single-Class Tools"}),"\n",(0,i.jsxs)(n.p,{children:["For tools that require more complex logic\u2014such as defining their interface programmatically based on configuration\u2014you can use a class that inherits from ",(0,i.jsx)(n.code,{children:"DynamicTool"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"step-1-create-the-dynamictool-class",children:["Step 1: Create the ",(0,i.jsx)(n.code,{children:"DynamicTool"})," Class"]}),"\n",(0,i.jsxs)(n.p,{children:["Instead of a function, define a class that implements the ",(0,i.jsx)(n.code,{children:"DynamicTool"})," abstract base class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/tools.py\nfrom typing import Optional, Dict, Any\nfrom google.genai import types as adk_types\nfrom solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool\n\nclass WeatherTool(DynamicTool):\n """A dynamic tool that fetches current weather information."""\n\n @property\n def tool_name(self) -> str:\n return "get_current_weather"\n\n @property\n def tool_description(self) -> str:\n return "Get the current weather for a specified location."\n\n @property\n def parameters_schema(self) -> adk_types.Schema:\n # Programmatically define the tool\'s parameters\n return adk_types.Schema(\n type=adk_types.Type.OBJECT,\n properties={\n "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."),\n "units": adk_types.Schema(type=adk_types.Type.STRING, enum=["celsius", "fahrenheit"], nullable=True),\n },\n required=["location"],\n )\n\n async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]:\n location = args["location"]\n # Access config via self.tool_config\n api_key = self.tool_config.get("api_key")\n if not api_key:\n return {"status": "error", "message": "API key not configured"}\n # ... implementation to call weather API ...\n return {"status": "success", "weather": "Sunny"}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"step-2-configure-the-tool-1",children:"Step 2: Configure the Tool"}),"\n",(0,i.jsxs)(n.p,{children:["The YAML configuration is very similar. You can either specify the ",(0,i.jsx)(n.code,{children:"class_name"})," or let Agent Mesh auto-discover it if it's the only ",(0,i.jsx)(n.code,{children:"DynamicTool"})," in the module."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"# In your agent's app_config:\ntools:\n - tool_type: python\n component_module: \"my_agent.tools\"\n # class_name: WeatherTool # Optional if it's the only one\n tool_config:\n api_key: ${WEATHER_API_KEY}\n"})}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"pattern-3-the-tool-provider-factory",children:"Pattern 3: The Tool Provider Factory"}),"\n",(0,i.jsx)(n.p,{children:"This is the most powerful pattern, designed for generating multiple, related tools from a single module and configuration block. It's perfect for creating toolsets based on external schemas, database tables, or other dynamic sources."}),"\n",(0,i.jsx)(n.h3,{id:"step-1-create-the-provider-and-tools",children:"Step 1: Create the Provider and Tools"}),"\n",(0,i.jsxs)(n.p,{children:["In your tools module, you define your ",(0,i.jsx)(n.code,{children:"DynamicTool"})," classes as before, but you also create a ",(0,i.jsx)(n.strong,{children:"provider"})," class that inherits from ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"}),". This provider acts as a factory."]}),"\n",(0,i.jsxs)(n.p,{children:["You can also use the ",(0,i.jsx)(n.code,{children:"@register_tool"})," decorator on simple functions to have them automatically included by the provider."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/database_tools.py\nfrom typing import Optional, Dict, Any, List\nfrom google.genai import types as adk_types\nfrom solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider\n\n# --- Tool Implementations ---\nclass DatabaseQueryTool(DynamicTool):\n # ... (implementation as in previous examples) ...\n pass\n\nclass DatabaseSchemaTool(DynamicTool):\n # ... (implementation as in previous examples) ...\n pass\n\n# --- Tool Provider Implementation ---\nclass DatabaseToolProvider(DynamicToolProvider):\n """A factory that creates all database-related tools."""\n\n # Use a decorator for a simple, function-based tool\n\n def create_tools(self, tool_config: Optional[dict] = None) -> List[DynamicTool]:\n """\n Generates a list of all database tools, passing the shared\n configuration to each one.\n """\n # 1. Create tools from any decorated functions in this module\n tools = self._create_tools_from_decorators(tool_config)\n\n # 2. Programmatically create and add more complex tools\n if tool_config and tool_config.get("connection_string"):\n tools.append(DatabaseQueryTool(tool_config=tool_config))\n tools.append(DatabaseSchemaTool(tool_config=tool_config))\n\n return tools\n\n# NOTE that you must use the decorator outside of any class with the provider\'s class name.\n@DatabaseToolProvider.register_tool\nasync def get_database_server_version(tool_config: dict, **kwargs) -> dict:\n """Returns the version of the connected PostgreSQL server."""\n # ... implementation ...\n return {"version": "PostgreSQL 15.3"}\n\n'})}),"\n",(0,i.jsx)(n.h3,{id:"step-2-configure-the-provider",children:"Step 2: Configure the Provider"}),"\n",(0,i.jsxs)(n.p,{children:["You only need a single YAML block. Agent Mesh will automatically detect the ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"})," and use it to load all the tools it generates."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n # This single block loads get_database_server_version,\n # execute_database_query, and get_database_schema.\n - tool_type: python\n component_module: "my_agent.database_tools"\n tool_config:\n connection_string: ${DB_CONNECTION_STRING}\n max_rows: 1000\n'})}),"\n",(0,i.jsx)(n.p,{children:"This approach is incredibly scalable, as one configuration entry can bootstrap an entire suite of dynamically generated tools."}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsxs)(n.h2,{id:"managing-tool-lifecycles-with-init-and-cleanup",children:["Managing Tool Lifecycles with ",(0,i.jsx)(n.code,{children:"init"})," and ",(0,i.jsx)(n.code,{children:"cleanup"})]}),"\n",(0,i.jsxs)(n.p,{children:["For tools that need to manage resources\u2014such as database connections, API clients, or temporary files\u2014Agent Mesh provides optional ",(0,i.jsx)(n.code,{children:"init"})," and ",(0,i.jsx)(n.code,{children:"cleanup"})," lifecycle hooks. These allow you to run code when the agent starts up and shuts down, ensuring that resources are acquired and released gracefully."]}),"\n",(0,i.jsx)(n.p,{children:"There are two ways to define these hooks:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.strong,{children:["YAML-based (",(0,i.jsx)(n.code,{children:"init_function"}),", ",(0,i.jsx)(n.code,{children:"cleanup_function"}),"):"]})," A flexible method that works for ",(0,i.jsx)(n.em,{children:"any"})," Python tool, including simple function-based ones."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsxs)(n.strong,{children:["Class-based (",(0,i.jsx)(n.code,{children:"init"}),", ",(0,i.jsx)(n.code,{children:"cleanup"})," methods):"]})," The idiomatic and recommended way for ",(0,i.jsx)(n.code,{children:"DynamicTool"})," and ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"})," classes."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"yaml-based-lifecycle-hooks",children:"YAML-Based Lifecycle Hooks"}),"\n",(0,i.jsxs)(n.p,{children:["You can add ",(0,i.jsx)(n.code,{children:"init_function"})," and ",(0,i.jsx)(n.code,{children:"cleanup_function"})," to any Python tool's configuration in your agent's YAML. The lifecycle functions must be defined in the same module as the tool itself."]}),"\n",(0,i.jsx)(n.h4,{id:"step-1-define-the-tool-and-hook-functions",children:"Step 1: Define the Tool and Hook Functions"}),"\n",(0,i.jsxs)(n.p,{children:["In your tool's Python file (e.g., ",(0,i.jsx)(n.code,{children:"src/my_agent/db_tools.py"}),"), define the tool function and its corresponding ",(0,i.jsx)(n.code,{children:"init"})," and ",(0,i.jsx)(n.code,{children:"cleanup"})," functions. These functions must be ",(0,i.jsx)(n.code,{children:"async"})," and will receive the agent component instance and the tool's configuration model object as arguments."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/db_tools.py\nfrom solace_agent_mesh.agent.sac.component import SamAgentComponent\nfrom solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig\nfrom google.adk.tools import ToolContext\nfrom typing import Dict, Any\n\n# --- Lifecycle Hooks ---\n\nasync def initialize_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig):\n """Initializes a database connection and stores it for the agent to use."""\n print("INFO: Initializing database connection...")\n # In a real scenario, you would create a client instance\n db_client = {"connection_string": tool_config_model.tool_config.get("connection_string")}\n # Store the client in a shared state accessible by the component\n component.set_agent_specific_state("db_client", db_client)\n print("INFO: Database client initialized.")\n\nasync def close_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig):\n """Retrieves and closes the database connection."""\n print("INFO: Closing database connection...")\n db_client = component.get_agent_specific_state("db_client")\n if db_client:\n # In a real scenario, you would call db_client.close()\n print("INFO: Database connection closed.")\n\n# --- Tool Function ---\n\nasync def query_database(query: str, tool_context: ToolContext, **kwargs) -> Dict[str, Any]:\n """Queries the database using the initialized connection."""\n host_component = tool_context._invocation_context.agent.host_component\n db_client = host_component.get_agent_specific_state("db_client")\n if not db_client:\n return {"error": "Database connection not initialized."}\n # ... use db_client to run query ...\n return {"result": "some data"}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"step-2-configure-the-hooks-in-yaml",children:"Step 2: Configure the Hooks in YAML"}),"\n",(0,i.jsxs)(n.p,{children:["In your YAML configuration, reference the lifecycle functions by name. The framework will automatically look for them in the ",(0,i.jsx)(n.code,{children:"component_module"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: python\n component_module: "my_agent.db_tools"\n function_name: "query_database"\n tool_config:\n connection_string: "postgresql://user:pass@host/db"\n\n # Initialize the tool on startup\n init_function: "initialize_db_connection"\n\n # Clean up the tool on shutdown\n cleanup_function: "close_db_connection"\n'})}),"\n",(0,i.jsxs)(n.h3,{id:"class-based-lifecycle-methods-for-dynamictool",children:["Class-Based Lifecycle Methods (for ",(0,i.jsx)(n.code,{children:"DynamicTool"}),")"]}),"\n",(0,i.jsxs)(n.p,{children:["For tools built with ",(0,i.jsx)(n.code,{children:"DynamicTool"})," or ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"}),", the recommended approach is to override the ",(0,i.jsx)(n.code,{children:"init"})," and ",(0,i.jsx)(n.code,{children:"cleanup"})," methods directly within the class. This co-locates the entire tool's logic and improves encapsulation."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["Example: Adding Lifecycle Methods to a ",(0,i.jsx)(n.code,{children:"DynamicTool"})]})}),"\n",(0,i.jsxs)(n.p,{children:["Here, we extend a ",(0,i.jsx)(n.code,{children:"DynamicTool"})," to manage its own API client."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/api_tool.py\nfrom solace_agent_mesh.agent.sac.component import SamAgentComponent\nfrom solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool\nfrom solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig\n# Assume WeatherApiClient is a custom class for an external service\nfrom my_agent.api_client import WeatherApiClient\n\nclass WeatherTool(DynamicTool):\n """A dynamic tool that fetches weather and manages its own API client."""\n\n async def init(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None:\n """Initializes the API client when the agent starts."""\n print("INFO: Initializing Weather API client...")\n # self.tool_config is the validated Pydantic model or dict from YAML\n api_key = self.tool_config.get("api_key")\n self.api_client = WeatherApiClient(api_key=api_key)\n print("INFO: Weather API client initialized.")\n\n async def cleanup(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None:\n """Closes the API client connection when the agent shuts down."""\n print("INFO: Closing Weather API client...")\n if hasattr(self, "api_client"):\n await self.api_client.close()\n print("INFO: Weather API client closed.")\n\n # ... other required properties like tool_name, tool_description, etc. ...\n\n async def _run_async_impl(self, args: dict, **kwargs) -> dict:\n """Uses the initialized client to perform its task."""\n location = args.get("location")\n if not hasattr(self, "api_client"):\n return {"error": "API client not initialized. Check lifecycle hooks."}\n weather_data = await self.api_client.get_weather(location)\n return {"weather": weather_data}\n'})}),"\n",(0,i.jsx)(n.p,{children:"The YAML configuration remains simple, as the lifecycle logic is now part of the tool's code."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: python\n component_module: "my_agent.api_tool"\n class_name: "WeatherTool"\n tool_config:\n api_key: ${WEATHER_API_KEY}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"execution-order-and-guarantees",children:"Execution Order and Guarantees"}),"\n",(0,i.jsx)(n.p,{children:"It's important to understand the order in which lifecycle hooks are executed, especially if you mix both YAML-based and class-based methods for a single tool."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsxs)(n.strong,{children:["Initialization (",(0,i.jsx)(n.code,{children:"init"}),"):"]})," All ",(0,i.jsx)(n.code,{children:"init"})," hooks are awaited during agent startup. A failure in any ",(0,i.jsx)(n.code,{children:"init"})," hook will prevent the agent from starting."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["The YAML-based ",(0,i.jsx)(n.code,{children:"init_function"})," is executed first."]}),"\n",(0,i.jsxs)(n.li,{children:["The class-based ",(0,i.jsx)(n.code,{children:"init()"})," method is executed second."]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsxs)(n.strong,{children:["Cleanup (",(0,i.jsx)(n.code,{children:"cleanup"}),"):"]})," All registered ",(0,i.jsx)(n.code,{children:"cleanup"})," hooks are executed during agent shutdown. They run in ",(0,i.jsx)(n.strong,{children:"LIFO (Last-In, First-Out)"})," order relative to initialization."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["The class-based ",(0,i.jsx)(n.code,{children:"cleanup()"})," method is executed first."]}),"\n",(0,i.jsxs)(n.li,{children:["The YAML-based ",(0,i.jsx)(n.code,{children:"cleanup_function"})," is executed second."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"This LIFO order for cleanup is intuitive: the resource that was initialized last is the first one to be torn down."}),"\n",(0,i.jsx)(n.hr,{}),"\n",(0,i.jsx)(n.h2,{id:"adding-validated-configuration-to-dynamic-tools",children:"Adding Validated Configuration to Dynamic Tools"}),"\n",(0,i.jsxs)(n.p,{children:["For any class-based tool (",(0,i.jsx)(n.code,{children:"DynamicTool"})," or ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"}),") that requires configuration, this is the recommended pattern. By linking a Pydantic model to your tool class, you can add automatic validation and type safety to your ",(0,i.jsx)(n.code,{children:"tool_config"}),". This provides several key benefits:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Automatic Validation:"})," The agent will fail to start if the YAML configuration doesn't match your model, providing clear error messages."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Type Safety:"})," Inside your tool, ",(0,i.jsx)(n.code,{children:"self.tool_config"})," is a fully typed Pydantic object, not a dictionary, enabling autocompletion and preventing common errors."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Self-Documentation:"})," The Pydantic model itself serves as clear, machine-readable documentation for your tool's required configuration."]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"example-1-using-a-pydantic-model-with-a-single-dynamictool",children:["Example 1: Using a Pydantic Model with a Single ",(0,i.jsx)(n.code,{children:"DynamicTool"})]}),"\n",(0,i.jsxs)(n.p,{children:["This example shows how to add a validated configuration to a standalone ",(0,i.jsx)(n.code,{children:"DynamicTool"})," class."]}),"\n",(0,i.jsx)(n.h4,{id:"step-1-define-the-model-and-tool-class",children:"Step 1: Define the Model and Tool Class"}),"\n",(0,i.jsxs)(n.p,{children:["In your tools file, define a ",(0,i.jsx)(n.code,{children:"pydantic.BaseModel"})," for your configuration. Then, in your ",(0,i.jsx)(n.code,{children:"DynamicTool"})," class, link to it using the ",(0,i.jsx)(n.code,{children:"config_model"})," class attribute."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/weather_tools.py\nfrom typing import Dict, Any\nfrom pydantic import BaseModel, Field\nfrom google.genai import types as adk_types\nfrom solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool\n\n# 1. Define the configuration model\nclass WeatherConfig(BaseModel):\n api_key: str = Field(..., description="The API key for the weather service.")\n default_unit: str = Field(default="celsius", description="The default temperature unit.")\n\n# 2. Create a tool and link the config model\nclass GetCurrentWeatherTool(DynamicTool):\n config_model = WeatherConfig\n\n def __init__(self, tool_config: WeatherConfig):\n super().__init__(tool_config)\n # self.tool_config is now a validated WeatherConfig instance\n # You can safely access attributes with type safety\n self.api_key = self.tool_config.api_key\n self.unit = self.tool_config.default_unit\n\n @property\n def tool_name(self) -> str:\n return "get_current_weather"\n\n @property\n def tool_description(self) -> str:\n return f"Get the current weather. The default unit is {self.unit}."\n\n @property\n def parameters_schema(self) -> adk_types.Schema:\n return adk_types.Schema(\n type=adk_types.Type.OBJECT,\n properties={\n "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."),\n },\n required=["location"],\n )\n\n async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]:\n # ... implementation using self.api_key ...\n return {"weather": f"Sunny in {args[\'location\']}"}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"step-2-configure-the-tool-in-yaml",children:"Step 2: Configure the Tool in YAML"}),"\n",(0,i.jsx)(n.p,{children:"The YAML configuration remains simple. The framework handles the validation against your Pydantic model automatically."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: python\n component_module: "my_agent.weather_tools"\n # The framework will auto-discover the GetCurrentWeatherTool class\n tool_config:\n api_key: ${WEATHER_API_KEY}\n default_unit: "fahrenheit" # Optional, overrides the model\'s default\n'})}),"\n",(0,i.jsxs)(n.p,{children:["If you were to forget ",(0,i.jsx)(n.code,{children:"api_key"})," in the YAML, the agent would fail to start and print a clear error message indicating that the ",(0,i.jsx)(n.code,{children:"api_key"})," field is required, making debugging configuration issues much easier."]}),"\n",(0,i.jsxs)(n.h3,{id:"example-2-using-a-pydantic-model-with-a-dynamictoolprovider",children:["Example 2: Using a Pydantic Model with a ",(0,i.jsx)(n.code,{children:"DynamicToolProvider"})]}),"\n",(0,i.jsx)(n.p,{children:"The same pattern applies to tool providers, allowing you to pass a validated, type-safe configuration object to your tool factory."}),"\n",(0,i.jsx)(n.h4,{id:"step-1-define-the-model-and-provider-class",children:"Step 1: Define the Model and Provider Class"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_agent/weather_tools_provider.py\nfrom typing import List\nfrom pydantic import BaseModel, Field\nfrom solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider\n# ... assume GetCurrentWeatherTool is defined in this file or imported ...\n\n# 1. Define the configuration model\nclass WeatherProviderConfig(BaseModel):\n api_key: str = Field(..., description="The API key for the weather service.")\n default_unit: str = Field(default="celsius", description="The default temperature unit.")\n\n# 2. Create a provider and link the config model\nclass WeatherToolProvider(DynamicToolProvider):\n config_model = WeatherProviderConfig\n\n def create_tools(self, tool_config: WeatherProviderConfig) -> List[DynamicTool]:\n # The framework passes a validated WeatherProviderConfig instance here\n return [\n GetCurrentWeatherTool(tool_config=tool_config)\n # You could create other tools here that also use the config\n ]\n'})}),"\n",(0,i.jsx)(n.h4,{id:"step-2-configure-the-provider-in-yaml",children:"Step 2: Configure the Provider in YAML"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: python\n component_module: "my_agent.weather_tools_provider"\n # The framework will auto-discover the WeatherToolProvider\n tool_config:\n api_key: ${WEATHER_API_KEY}\n default_unit: "fahrenheit" # Optional, overrides the model\'s default\n'})})]})}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,o)=>{o.d(n,{R:()=>a,x:()=>l});var t=o(6540);const i={},s=t.createContext(i);function a(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8498],{47:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"documentation/installing-and-configuring/user-feedback","title":"User Feedback","description":"User Feedback allows users to provide ratings and comments on AI agent responses through the Web UI. This feature enables quality monitoring, model improvement through evaluation datasets, and user satisfaction tracking. Feedback can be stored in a database for analytics and optionally published to Solace message broker topics for integration with external systems.","source":"@site/docs/documentation/installing-and-configuring/user-feedback.md","sourceDirName":"documentation/installing-and-configuring","slug":"/documentation/installing-and-configuring/user-feedback","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/user-feedback","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/installing-and-configuring/user-feedback.md","tags":[],"version":"current","sidebarPosition":345,"frontMatter":{"title":"User Feedback","sidebar_position":345},"sidebar":"docSidebar","previous":{"title":"Configuring LLMs","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/large_language_models"},"next":{"title":"Session Storage","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage"}}');var i=t(4848),a=t(8453);const l={title:"User Feedback",sidebar_position:345},d=void 0,r={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Enabling User Feedback",id:"enabling-user-feedback",level:2},{value:"Configuring Feedback Publishing",id:"configuring-feedback-publishing",level:2},{value:"Configuration Example",id:"configuration-example",level:3},{value:"Task Information Modes",id:"task-information-modes",level:3},{value:"Using User Feedback",id:"using-user-feedback",level:2},{value:"Retrieving Feedback",id:"retrieving-feedback",level:2},{value:"Query Parameters",id:"query-parameters",level:3},{value:"Security and Access Control",id:"security-and-access-control",level:3},{value:"Example API Calls",id:"example-api-calls",level:3},{value:"Publishing Feedback Events",id:"publishing-feedback-events",level:2},{value:"Event Payload Examples",id:"event-payload-examples",level:3},{value:"Integrating with External Systems",id:"integrating-with-external-systems",level:3},{value:"Data Retention",id:"data-retention",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"User Feedback allows users to provide ratings and comments on AI agent responses through the Web UI. This feature enables quality monitoring, model improvement through evaluation datasets, and user satisfaction tracking. Feedback can be stored in a database for analytics and optionally published to Solace message broker topics for integration with external systems."}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsx)(n.p,{children:"User Feedback requires session persistence to be enabled. Session persistence ensures that feedback submissions can be reliably stored and associated with specific user interactions and tasks."}),"\n",(0,i.jsxs)(n.p,{children:["To enable session persistence, configure the session service with a database backend in your ",(0,i.jsx)(n.code,{children:"shared_config.yaml"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'services:\n session_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL, sqlite:///webui-gateway.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["For more information about session service configuration and database setup options, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations#session-service",children:"Session Service"}),"."]}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsx)(n.p,{children:"If session persistence is not enabled, the system automatically disables the feedback collection feature to prevent data loss. Feedback buttons will not appear in the Web UI when persistence is disabled."})}),"\n",(0,i.jsx)(n.h2,{id:"enabling-user-feedback",children:"Enabling User Feedback"}),"\n",(0,i.jsxs)(n.p,{children:["To enable feedback collection in the Web UI, set the ",(0,i.jsx)(n.code,{children:"frontend_collect_feedback"})," parameter to ",(0,i.jsx)(n.code,{children:"true"})," in your gateway configuration file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apps:\n - name: webui_example_app\n app_config:\n # Enable feedback collection in the UI\n frontend_collect_feedback: true\n\n # Session persistence required (see Prerequisites)\n session_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL, sqlite:///webui-gateway.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,i.jsx)(n.p,{children:"When enabled, thumbs up and thumbs down buttons appear after completed agent responses in the Web UI. Users can click these buttons to submit feedback, with an optional text comment providing additional context."}),"\n",(0,i.jsx)(n.h2,{id:"configuring-feedback-publishing",children:"Configuring Feedback Publishing"}),"\n",(0,i.jsx)(n.p,{children:"Feedback can be published to Solace message broker topics for integration with external analytics systems, evaluation pipelines, or monitoring dashboards. This publishing capability is optional and can be configured independently of basic feedback collection."}),"\n",(0,i.jsx)(n.p,{children:"The following table describes the feedback publishing configuration parameters:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"enabled"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"boolean"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Enable or disable feedback event publishing."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"false"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"topic"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"The topic name for publishing feedback events. Supports environment variable substitution."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"sam/feedback/v1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"include_task_info"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["Controls what task information is included in published events. Options are ",(0,i.jsx)(n.code,{children:"none"}),", ",(0,i.jsx)(n.code,{children:"summary"}),", or ",(0,i.jsx)(n.code,{children:"stim"}),"."]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"none"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"max_payload_size_bytes"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"integer"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["Maximum payload size in bytes. If the payload exceeds this limit when using ",(0,i.jsx)(n.code,{children:"stim"})," mode, the system falls back to ",(0,i.jsx)(n.code,{children:"summary"})," mode."]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"9000000"})})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"configuration-example",children:"Configuration Example"}),"\n",(0,i.jsx)(n.p,{children:"The following example shows how to configure feedback publishing in your gateway configuration file:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apps:\n - name: webui_example_app\n app_config:\n frontend_collect_feedback: true\n\n feedback_publishing:\n enabled: true\n topic: "${NAMESPACE}/sam/feedback/v1"\n include_task_info: "summary"\n max_payload_size_bytes: 9000000\n'})}),"\n",(0,i.jsx)(n.h3,{id:"task-information-modes",children:"Task Information Modes"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"include_task_info"})," parameter determines what task details are included with each feedback event:"]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"none"})})," - Only feedback data (task_id, session_id, rating, comment, user_id) is published. Use this mode when you want minimal payload size and don't need task context in the consuming system."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"summary"})})," - Includes basic task information such as task_id, user_id, start_time, end_time, status, and initial_request_text. Use this mode for lightweight analytics and monitoring where you need basic task context without full execution details."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"stim"})})," - Includes complete task execution history with all events, tool calls, and agent interactions. This mode provides full traceability for debugging and detailed analysis. If the payload exceeds ",(0,i.jsx)(n.code,{children:"max_payload_size_bytes"}),", the system automatically falls back to ",(0,i.jsx)(n.code,{children:"summary"})," mode and logs the fallback decision."]}),"\n",(0,i.jsx)(n.h2,{id:"using-user-feedback",children:"Using User Feedback"}),"\n",(0,i.jsx)(n.p,{children:"Users submit feedback through the Web UI by clicking thumbs up or thumbs down buttons that appear after completed agent responses. A modal dialog allows users to optionally add text comments explaining their rating. Each task can receive one feedback submission, and buttons are disabled after submission to prevent duplicate feedback."}),"\n",(0,i.jsxs)(n.p,{children:["Feedback is stored in the ",(0,i.jsx)(n.code,{children:"feedback"})," database table with the following information:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Unique feedback ID"}),"\n",(0,i.jsx)(n.li,{children:"Associated task ID and session ID"}),"\n",(0,i.jsx)(n.li,{children:"User ID of the person who submitted the feedback"}),"\n",(0,i.jsx)(n.li,{children:"Rating type (up or down)"}),"\n",(0,i.jsx)(n.li,{children:"Optional text comment"}),"\n",(0,i.jsx)(n.li,{children:"Creation timestamp"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The feedback is also stored in the task metadata, allowing quick access to feedback status when retrieving task information through other APIs."}),"\n",(0,i.jsx)(n.h2,{id:"retrieving-feedback",children:"Retrieving Feedback"}),"\n",(0,i.jsxs)(n.p,{children:["You can retrieve feedback programmatically using the ",(0,i.jsx)(n.code,{children:"GET /api/v1/feedback"})," endpoint. This endpoint supports flexible filtering and pagination to help you analyze feedback data."]}),"\n",(0,i.jsx)(n.h3,{id:"query-parameters",children:"Query Parameters"}),"\n",(0,i.jsx)(n.p,{children:"The following table describes the available query parameters:"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Parameter"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Type"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Description"}),(0,i.jsx)(n.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"start_date"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Filter feedback created after this date (ISO 8601 format)."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"end_date"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Filter feedback created before this date (ISO 8601 format)."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"task_id"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Filter by specific task ID."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"session_id"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Filter by specific session ID."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"rating"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["Filter by rating type (",(0,i.jsx)(n.code,{children:"up"})," or ",(0,i.jsx)(n.code,{children:"down"}),")."]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"page"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"integer"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Page number for pagination."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"1"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"page_size"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"integer"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"Number of results per page."}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"20"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"query_user_id"})}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:(0,i.jsx)(n.code,{children:"string"})}),(0,i.jsxs)(n.td,{style:{textAlign:"left"},children:["(Admin only) Query feedback for a specific user. Requires ",(0,i.jsx)(n.code,{children:"feedback:read:all"})," scope."]}),(0,i.jsx)(n.td,{style:{textAlign:"left"},children:"(none)"})]})]})]}),"\n",(0,i.jsx)(n.p,{children:"All query parameters are optional and can be combined to create specific filters. Results are returned in descending order by creation time (most recent first)."}),"\n",(0,i.jsx)(n.h3,{id:"security-and-access-control",children:"Security and Access Control"}),"\n",(0,i.jsxs)(n.p,{children:["Regular users can only retrieve their own feedback. Users with the ",(0,i.jsx)(n.code,{children:"feedback:read:all"})," scope can retrieve feedback from any user or all users. When filtering by ",(0,i.jsx)(n.code,{children:"task_id"}),", the system verifies that the user owns the task or has admin permissions before returning results."]}),"\n",(0,i.jsx)(n.h3,{id:"example-api-calls",children:"Example API Calls"}),"\n",(0,i.jsx)(n.p,{children:"The following examples demonstrate common feedback retrieval scenarios:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Get your own feedback from the last week:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "http://localhost:8000/api/v1/feedback?start_date=2025-10-22T00:00:00&end_date=2025-10-29T23:59:59"\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Get all negative feedback for a specific task:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "http://localhost:8000/api/v1/feedback?task_id=task-abc123&rating=down"\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Get feedback from a specific session:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "http://localhost:8000/api/v1/feedback?session_id=web-session-xyz"\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Admin: Get all users' feedback from October:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "http://localhost:8000/api/v1/feedback?start_date=2025-10-01&end_date=2025-10-31"\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Get the first 50 results with pagination:"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'curl "http://localhost:8000/api/v1/feedback?page=1&page_size=50"\n'})}),"\n",(0,i.jsx)(n.h2,{id:"publishing-feedback-events",children:"Publishing Feedback Events"}),"\n",(0,i.jsxs)(n.p,{children:["When feedback publishing is enabled, the system publishes feedback events to the configured Solace topic. The payload structure varies based on the ",(0,i.jsx)(n.code,{children:"include_task_info"})," setting."]}),"\n",(0,i.jsx)(n.h3,{id:"event-payload-examples",children:"Event Payload Examples"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["Mode: ",(0,i.jsx)(n.code,{children:"none"})]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "feedback": {\n "task_id": "task-abc123",\n "session_id": "web-session-xyz",\n "feedback_type": "up",\n "feedback_text": "Great response!",\n "user_id": "user123"\n }\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["Mode: ",(0,i.jsx)(n.code,{children:"summary"})]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "feedback": {\n "task_id": "task-abc123",\n "session_id": "web-session-xyz",\n "feedback_type": "up",\n "feedback_text": "Great response!",\n "user_id": "user123"\n },\n "task_summary": {\n "id": "task-abc123",\n "user_id": "user123",\n "start_time": 1730217600000,\n "end_time": 1730217650000,\n "status": "completed",\n "initial_request_text": "Help me analyze this data"\n }\n}\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["Mode: ",(0,i.jsx)(n.code,{children:"stim"})]})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "feedback": {\n "task_id": "task-abc123",\n "session_id": "web-session-xyz",\n "feedback_type": "up",\n "feedback_text": "Great response!",\n "user_id": "user123"\n },\n "task_stim_data": {\n "invocation_details": {\n "log_file_version": "2.0",\n "task_id": "task-abc123",\n "user_id": "user123",\n "start_time": 1730217600000,\n "end_time": 1730217650000,\n "status": "completed",\n "initial_request_text": "Help me analyze this data"\n },\n "invocation_flow": [\n {\n "id": "event-1",\n "created_time": 1730217600000,\n "topic": "namespace/agent/request",\n "direction": "request",\n "payload": { "message": "..." }\n },\n {\n "id": "event-2",\n "created_time": 1730217625000,\n "topic": "namespace/agent/response",\n "direction": "response",\n "payload": { "result": "..." }\n }\n ]\n }\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"integrating-with-external-systems",children:"Integrating with External Systems"}),"\n",(0,i.jsx)(n.p,{children:"External systems can subscribe to the feedback topic to consume feedback events in real-time. This approach enables integration with various downstream systems such as analytics platforms, evaluation pipelines, and monitoring dashboards."}),"\n",(0,i.jsxs)(n.p,{children:["The topic naming pattern follows the format ",(0,i.jsx)(n.code,{children:"{namespace}/sam/feedback/v1"}),", where ",(0,i.jsx)(n.code,{children:"{namespace}"})," is your configured namespace. You can customize this pattern using the ",(0,i.jsx)(n.code,{children:"topic"})," configuration parameter and environment variable substitution."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Use ",(0,i.jsx)(n.code,{children:"summary"})," mode for most analytics and monitoring use cases, as it provides essential task context without the overhead of full execution traces. Reserve ",(0,i.jsx)(n.code,{children:"stim"})," mode for detailed debugging and analysis scenarios where complete execution history is required."]})}),"\n",(0,i.jsx)(n.h2,{id:"data-retention",children:"Data Retention"}),"\n",(0,i.jsx)(n.p,{children:"Feedback records are subject to the data retention policies configured in your gateway. The data retention service automatically cleans up old feedback records based on the configured retention period, preventing unbounded database growth."}),"\n",(0,i.jsxs)(n.p,{children:["To configure data retention for feedback, set the ",(0,i.jsx)(n.code,{children:"feedback_retention_days"})," parameter in your gateway configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apps:\n - name: webui_example_app\n app_config:\n data_retention:\n enabled: true\n feedback_retention_days: 90\n cleanup_interval_hours: 24\n batch_size: 1000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For detailed information about data retention configuration and cleanup policies, see the ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations",children:"Data Retention documentation"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>d});var s=t(6540);const i={},a=s.createContext(i);function l(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8627],{5483:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"documentation/enterprise/rbac-setup-guide","title":"Setting Up RBAC","description":"This guide walks you through configuring Role-Based Access Control (RBAC) in a Docker installation for Agent Mesh. You will learn how to control access to Agent Mesh Enterprise features and resources based on user roles and permissions.","source":"@site/docs/documentation/enterprise/rbac-setup-guide.md","sourceDirName":"documentation/enterprise","slug":"/documentation/enterprise/rbac-setup-guide","permalink":"/solace-agent-mesh/docs/documentation/enterprise/rbac-setup-guide","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/enterprise/rbac-setup-guide.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Setting Up RBAC","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Connectors","permalink":"/solace-agent-mesh/docs/documentation/enterprise/connectors/"},"next":{"title":"Enabling SSO","permalink":"/solace-agent-mesh/docs/documentation/enterprise/single-sign-on"}}');var r=s(4848),t=s(8453);const o={title:"Setting Up RBAC",sidebar_position:10},a=void 0,c={},l=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Understanding RBAC in Agent Mesh Enterprise",id:"understanding-rbac-in-agent-mesh-enterprise",level:2},{value:"The Three Components",id:"the-three-components",level:3},{value:"How Authorization Works",id:"how-authorization-works",level:3},{value:"Planning Your RBAC Configuration",id:"planning-your-rbac-configuration",level:2},{value:"Identifying User Types",id:"identifying-user-types",level:3},{value:"Designing Roles",id:"designing-roles",level:3},{value:"Mapping Scopes to Features",id:"mapping-scopes-to-features",level:3},{value:"Setting Up RBAC in Docker",id:"setting-up-rbac-in-docker",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Creating the Configuration Directory Structure",id:"creating-the-configuration-directory-structure",level:3},{value:"Defining Roles and Permissions",id:"defining-roles-and-permissions",level:3},{value:"Assigning Users to Roles",id:"assigning-users-to-roles",level:3},{value:"Creating the Enterprise Configuration",id:"creating-the-enterprise-configuration",level:3},{value:"Running the Docker Container",id:"running-the-docker-container",level:3},{value:"Verifying Your Configuration",id:"verifying-your-configuration",level:3},{value:"Understanding Configuration Files",id:"understanding-configuration-files",level:2},{value:"Role-to-Scope Definitions Structure",id:"role-to-scope-definitions-structure",level:3},{value:"User-to-Role Assignments Structure",id:"user-to-role-assignments-structure",level:3},{value:"Enterprise Configuration Structure",id:"enterprise-configuration-structure",level:3},{value:"Advanced Configuration Options",id:"advanced-configuration-options",level:2},{value:"Production-Ready Role Configuration",id:"production-ready-role-configuration",level:3},{value:"Integrating with Microsoft Graph",id:"integrating-with-microsoft-graph",level:3},{value:"Best Practices",id:"best-practices",level:2},{value:"Security Recommendations",id:"security-recommendations",level:3},{value:"Role Design Principles",id:"role-design-principles",level:3},{value:"Docker-Specific Recommendations",id:"docker-specific-recommendations",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Authorization Denied for Valid User",id:"authorization-denied-for-valid-user",level:3},{value:"Configuration Files Not Found",id:"configuration-files-not-found",level:3},{value:"Microsoft Graph Integration Not Working",id:"microsoft-graph-integration-not-working",level:3},{value:"Debugging Authorization Issues",id:"debugging-authorization-issues",level:3},{value:"Getting Help",id:"getting-help",level:3},{value:"Conclusion",id:"conclusion",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"This guide walks you through configuring Role-Based Access Control (RBAC) in a Docker installation for Agent Mesh. You will learn how to control access to Agent Mesh Enterprise features and resources based on user roles and permissions."}),"\n",(0,r.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#understanding-rbac-in-agent-mesh-enterprise",children:"Understanding RBAC in Agent Mesh Enterprise"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#planning-your-rbac-configuration",children:"Planning Your RBAC Configuration"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#setting-up-rbac-in-docker",children:"Setting Up RBAC in Docker"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#understanding-configuration-files",children:"Understanding Configuration Files"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#advanced-configuration-options",children:"Advanced Configuration Options"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#best-practices",children:"Best Practices"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"#troubleshooting",children:"Troubleshooting"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"understanding-rbac-in-agent-mesh-enterprise",children:"Understanding RBAC in Agent Mesh Enterprise"}),"\n",(0,r.jsx)(n.p,{children:"Before you configure RBAC, you need to understand how the system works. Agent Mesh Enterprise uses a three-tier authorization model that separates identity, roles, and permissions."}),"\n",(0,r.jsx)(n.h3,{id:"the-three-components",children:"The Three Components"}),"\n",(0,r.jsx)(n.p,{children:"RBAC in Agent Mesh Enterprise consists of three interconnected components:"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Users"})," represent identities in your system. Each user has a unique identifier, typically an email address. When a user attempts to access a feature or resource, Agent Mesh Enterprise checks their assigned roles to determine what they can do."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Roles"}),' are collections of permissions that you assign to users. Instead of granting permissions directly to individual users, you create roles that represent job functions or responsibilities. For example, you might create a "data_analyst" role for users who need to work with data tools and artifacts. This approach simplifies administration because you can modify a role\'s permissions once and affect all users assigned to that role.']}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Scopes"})," are the actual permissions that grant access to specific features or resources. Each scope follows a pattern that identifies what it controls. For example, the scope ",(0,r.jsx)(n.code,{children:"tool:data:read"})," grants permission to read data tools, while ",(0,r.jsx)(n.code,{children:"artifact:create"})," allows creating artifacts. Scopes use wildcards to grant broader permissions. For example, the scope ",(0,r.jsx)(n.code,{children:"tool:data:*"})," grants all permissions for data tools."]}),"\n",(0,r.jsx)(n.h3,{id:"how-authorization-works",children:"How Authorization Works"}),"\n",(0,r.jsx)(n.p,{children:"When a user attempts an action in Agent Mesh Enterprise, the system follows this authorization flow:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"The system identifies the user based on their authentication credentials"}),"\n",(0,r.jsx)(n.li,{children:"It retrieves all roles assigned to that user"}),"\n",(0,r.jsx)(n.li,{children:"For each role, it collects all associated scopes (permissions)"}),"\n",(0,r.jsx)(n.li,{children:"It checks if any of the user's scopes match the permission required for the requested action"}),"\n",(0,r.jsx)(n.li,{children:"If a matching scope exists, the system allows the action; otherwise, it denies access"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"This model implements the principle of least privilege: users receive only the permissions they need to perform their job functions."}),"\n",(0,r.jsx)(n.h2,{id:"planning-your-rbac-configuration",children:"Planning Your RBAC Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Before you create configuration files, you should plan your RBAC structure. This planning phase helps you design a system that meets your organization's needs while remaining maintainable."}),"\n",(0,r.jsx)(n.h3,{id:"identifying-user-types",children:"Identifying User Types"}),"\n",(0,r.jsx)(n.p,{children:"Start by identifying the different types of users in your organization. Consider their job functions and what they need to accomplish with Agent Mesh Enterprise. Common user types include:"}),"\n",(0,r.jsx)(n.p,{children:"Administrators need full access to all features and resources. They manage the system, configure settings, and troubleshoot issues. You typically assign these users a role with wildcard permissions."}),"\n",(0,r.jsx)(n.p,{children:"Operators perform day-to-day tasks such as running tools, creating artifacts, and monitoring system activity. They need broad access to operational features but not administrative capabilities."}),"\n",(0,r.jsx)(n.p,{children:"Analysts work with data and reports. They need access to data tools, artifact creation, and monitoring capabilities, but they do not need access to system configuration or advanced tools."}),"\n",(0,r.jsx)(n.p,{children:"Viewers need read-only access to monitor system activity and view artifacts. They cannot create, modify, or delete resources."}),"\n",(0,r.jsx)(n.h3,{id:"designing-roles",children:"Designing Roles"}),"\n",(0,r.jsx)(n.p,{children:"Once you identify user types, design roles that match their needs. Each role should represent a specific job function and include only the scopes necessary for that function."}),"\n",(0,r.jsx)(n.p,{children:'Consider creating a role hierarchy where some roles inherit permissions from others. For example, an "operator" role might inherit all permissions from a "viewer" role and add additional capabilities. This approach reduces duplication and makes your configuration easier to maintain.'}),"\n",(0,r.jsx)(n.h3,{id:"mapping-scopes-to-features",children:"Mapping Scopes to Features"}),"\n",(0,r.jsx)(n.p,{children:"Understanding available scopes helps you design effective roles. Agent Mesh Enterprise uses a hierarchical scope naming convention:"}),"\n",(0,r.jsxs)(n.p,{children:["Tool scopes control access to tools and follow the pattern ",(0,r.jsx)(n.code,{children:"tool:<category>:<action>"}),". For example, ",(0,r.jsx)(n.code,{children:"tool:basic:read"})," grants permission to read basic tools, while ",(0,r.jsx)(n.code,{children:"tool:data:*"})," grants all permissions for data tools."]}),"\n",(0,r.jsxs)(n.p,{children:["Artifact scopes control access to artifacts (files and data created by the system) and use the pattern ",(0,r.jsx)(n.code,{children:"artifact:<action>"}),". Common artifact scopes include ",(0,r.jsx)(n.code,{children:"artifact:read"}),", ",(0,r.jsx)(n.code,{children:"artifact:create"}),", and ",(0,r.jsx)(n.code,{children:"artifact:delete"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["Monitoring scopes control access to system monitoring features and follow the pattern ",(0,r.jsx)(n.code,{children:"monitor/namespace/<namespace>:a2a_messages:subscribe"}),". These scopes allow users to observe message traffic in specific namespaces."]}),"\n",(0,r.jsxs)(n.p,{children:["The wildcard scope ",(0,r.jsx)(n.code,{children:"*"})," grants all permissions and should only be used for administrator roles."]}),"\n",(0,r.jsx)(n.h2,{id:"setting-up-rbac-in-docker",children:"Setting Up RBAC in Docker"}),"\n",(0,r.jsx)(n.p,{children:"Now that you understand RBAC concepts and have planned your configuration, you can set up RBAC in your Docker environment. This process involves creating configuration files, setting up the Docker container, and verifying that everything works correctly."}),"\n",(0,r.jsx)(n.h3,{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.jsx)(n.li,{children:"Docker installed and running on your system"}),"\n",(0,r.jsxs)(n.li,{children:["The Agent Mesh Enterprise Docker image (",(0,r.jsx)(n.code,{children:"solace-agent-mesh-enterprise"}),")"]}),"\n",(0,r.jsx)(n.li,{children:"A text editor for creating configuration files"}),"\n",(0,r.jsx)(n.li,{children:"Basic familiarity with YAML file format"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"creating-the-configuration-directory-structure",children:"Creating the Configuration Directory Structure"}),"\n",(0,r.jsx)(n.p,{children:"You need to create a directory structure on your host system to store RBAC configuration files. The Docker container will mount this directory to access your configurations."}),"\n",(0,r.jsx)(n.p,{children:"Create the directory structure as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir -p sam-enterprise/config/auth\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This command creates a ",(0,r.jsx)(n.code,{children:"sam-enterprise"})," directory with a nested ",(0,r.jsx)(n.code,{children:"config/auth"})," subdirectory. The ",(0,r.jsx)(n.code,{children:"auth"})," subdirectory will contain your RBAC configuration files."]}),"\n",(0,r.jsx)(n.h3,{id:"defining-roles-and-permissions",children:"Defining Roles and Permissions"}),"\n",(0,r.jsxs)(n.p,{children:["Create a file named ",(0,r.jsx)(n.code,{children:"role-to-scope-definitions.yaml"})," in the ",(0,r.jsx)(n.code,{children:"sam-enterprise/config/auth"})," directory.\nThis file defines all roles in your system and the scopes (permissions) associated with each role."]}),"\n",(0,r.jsx)(n.p,{children:"Here is an example configuration that defines three roles:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# role-to-scope-definitions.yaml\nroles:\n enterprise_admin:\n description: "Full access for enterprise administrators"\n scopes:\n - "*" # Wildcard grants all permissions\n \n data_analyst:\n description: "Data analysis and visualization specialist"\n scopes:\n - "tool:data:*" # All data tools\n - "artifact:read"\n - "artifact:create"\n - "monitor/namespace/*:a2a_messages:subscribe" # Can monitor any namespace\n \n standard_user:\n description: "Standard user with basic access"\n scopes:\n - "artifact:read"\n - "tool:basic:read"\n - "tool:basic:search"\n'})}),"\n",(0,r.jsx)(n.p,{children:"This configuration creates three distinct roles:"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"enterprise_admin"})," role receives the wildcard scope ",(0,r.jsx)(n.code,{children:"*"}),", which grants all permissions in the system. You should assign this role only to trusted administrators who need complete control over Agent Mesh Enterprise."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"data_analyst"})," role receives permissions tailored for data analysis work. The scope ",(0,r.jsx)(n.code,{children:"tool:data:*"})," grants all permissions for data-related tools (read, write, execute). The ",(0,r.jsx)(n.code,{children:"artifact:read"})," and ",(0,r.jsx)(n.code,{children:"artifact:create"})," scopes allow analysts to view existing artifacts and create new ones. The monitoring scope ",(0,r.jsx)(n.code,{children:"monitor/namespace/*:a2a_messages:subscribe"})," enables analysts to observe message traffic across all namespaces, which helps them understand data flows."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"standard_user"})," role provides minimal permissions for basic operations. Users with this role can read artifacts and perform basic tool operations but cannot create new artifacts or access advanced features."]}),"\n",(0,r.jsx)(n.h3,{id:"assigning-users-to-roles",children:"Assigning Users to Roles"}),"\n",(0,r.jsxs)(n.p,{children:["Create a file named ",(0,r.jsx)(n.code,{children:"user-to-role-assignments.yaml"})," in the ",(0,r.jsx)(n.code,{children:"sam-enterprise/config/auth"})," directory. This file maps user identities to roles."]}),"\n",(0,r.jsx)(n.p,{children:"Here is an example configuration:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# user-to-role-assignments.yaml\nusers:\n admin@example.com:\n roles: ["enterprise_admin"]\n description: "Enterprise Administrator Account"\n \n data.analyst@example.com:\n roles: ["data_analyst"]\n description: "Senior Data Analyst"\n \n user1@example.com:\n roles: ["standard_user"]\n description: "Standard Enterprise User"\n'})}),"\n",(0,r.jsx)(n.p,{children:"Each entry in this file maps a user identity (typically an email address) to one or more roles. The user identity must match exactly what your authentication system provides because Agent Mesh Enterprise performs case-sensitive matching."}),"\n",(0,r.jsxs)(n.p,{children:["You can assign multiple roles to a single user by listing them in the ",(0,r.jsx)(n.code,{children:"roles"})," array. When a user has multiple roles, they receive the combined permissions from all assigned roles. For example, if you assign both ",(0,r.jsx)(n.code,{children:"data_analyst"})," and ",(0,r.jsx)(n.code,{children:"standard_user"})," roles to a user, they receive all scopes from both roles."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"description"})," field is optional but recommended. It helps you document the purpose of each user account, which is valuable when reviewing or auditing your RBAC configuration."]}),"\n",(0,r.jsx)(n.h3,{id:"creating-the-enterprise-configuration",children:"Creating the Enterprise Configuration"}),"\n",(0,r.jsxs)(n.p,{children:["Create a file named ",(0,r.jsx)(n.code,{children:"enterprise_config.yaml"})," in the ",(0,r.jsx)(n.code,{children:"sam-enterprise/config"})," directory (not in the ",(0,r.jsx)(n.code,{children:"auth"})," subdirectory). This file tells Agent Mesh Enterprise where to find your RBAC configuration files and how to use them."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# enterprise_config.yaml\nauthorization_service:\n type: "default_rbac"\n role_to_scope_definitions_path: "config/auth/role-to-scope-definitions.yaml"\n user_to_role_assignments_path: "config/auth/user-to-role-assignments.yaml"\n\nnamespace: "enterprise_prod"\ngateway_id: "enterprise_gateway"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"authorization_service"})," section configures the RBAC system. The ",(0,r.jsx)(n.code,{children:"type"})," field specifies ",(0,r.jsx)(n.code,{children:"default_rbac"}),", which tells Agent Mesh Enterprise to use the file-based RBAC system. The two path fields point to your RBAC configuration files\u2014these paths are relative to the container's working directory, not your host system."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"namespace"})," and ",(0,r.jsx)(n.code,{children:"gateway_id"})," fields configure the Agent Mesh Enterprise instance. The namespace isolates this instance from others, while the gateway ID identifies the web interface gateway."]}),"\n",(0,r.jsx)(n.h3,{id:"running-the-docker-container",children:"Running the Docker Container"}),"\n",(0,r.jsxs)(n.p,{children:["Now you can start the Docker container with your RBAC configuration.\nNavigate to your ",(0,r.jsx)(n.code,{children:"sam-enterprise"})," directory and run:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'cd sam-enterprise\n\ndocker run -d \\\n --name sam-enterprise \\\n -p 8001:8000 \\\n -v "$(pwd):/app" \\\n -e SAM_AUTHORIZATION_CONFIG="/app/config/auth/enterprise_config.yaml" \\\n -e NAMESPACE=enterprise_prod \\\n -e WEBUI_GATEWAY_ID=enterprise_gateway \\\n -e ... list here all other necessary env vars ...\n solace-agent-mesh-enterprise:<tagname>\n'})}),"\n",(0,r.jsx)(n.h3,{id:"verifying-your-configuration",children:"Verifying Your Configuration"}),"\n",(0,r.jsx)(n.p,{children:"After starting the container, you should verify that RBAC is working correctly. Follow these steps:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Open your web browser and navigate to ",(0,r.jsx)(n.code,{children:"http://localhost:8001"})]}),"\n",(0,r.jsxs)(n.li,{children:["Log in using one of the user identities defined in your ",(0,r.jsx)(n.code,{children:"user-to-role-assignments.yaml"})," file"]}),"\n",(0,r.jsx)(n.li,{children:"Attempt to access features that the user should have permission to use"}),"\n",(0,r.jsx)(n.li,{children:"Attempt to access features that the user should not have permission to use"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"If RBAC is configured correctly, the user can access permitted features and receives authorization errors when attempting to access restricted features."}),"\n",(0,r.jsx)(n.p,{children:"You can also check the container logs to verify that Agent Mesh Enterprise loaded your configuration files:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker logs sam-enterprise\n"})}),"\n",(0,r.jsx)(n.p,{children:"Look for log messages that indicate successful configuration loading. You should see messages similar to:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"INFO:solace_ai_connector:[ConfigurableRbacAuthSvc] Successfully loaded role-to-scope definitions from: /app/config/auth/role-to-scope-definitions.yaml\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'enterprise_admin' loaded with 1 direct scopes, 1 resolved scopes.\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'data_analyst' loaded with 4 direct scopes, 4 resolved scopes.\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'standard_user' loaded with 3 direct scopes, 3 resolved scopes.\n"})}),"\n",(0,r.jsx)(n.p,{children:"These messages confirm that Agent Mesh Enterprise found and parsed your configuration files correctly."}),"\n",(0,r.jsx)(n.h2,{id:"understanding-configuration-files",children:"Understanding Configuration Files"}),"\n",(0,r.jsx)(n.p,{children:"Now that you have a working RBAC configuration, you should understand the full structure and capabilities of each configuration file. This knowledge helps you customize the configuration to meet your specific needs."}),"\n",(0,r.jsx)(n.h3,{id:"role-to-scope-definitions-structure",children:"Role-to-Scope Definitions Structure"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"role-to-scope-definitions.yaml"})," file supports several features beyond the basic examples shown earlier. Here is the complete structure:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'roles:\n role_name:\n description: "Role description"\n scopes:\n - "scope1"\n - "scope2"\n inherits: # Optional - inherit scopes from other roles\n - "parent_role1"\n - "parent_role2"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"inherits"})," field allows you to create role hierarchies. When a role inherits from another role, it receives all scopes from the parent role in addition to its own scopes. This feature reduces duplication and makes your configuration easier to maintain."]}),"\n",(0,r.jsx)(n.p,{children:'For example, you might create a base "viewer" role with read-only permissions, then create an "operator" role that inherits from "viewer" and adds write permissions:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'roles:\n viewer:\n description: "Read-only access"\n scopes:\n - "tool:basic:read"\n - "artifact:read"\n \n operator:\n description: "Operational access"\n inherits:\n - "viewer"\n scopes:\n - "tool:basic:*"\n - "artifact:create"\n'})}),"\n",(0,r.jsxs)(n.p,{children:['In this example, the "operator" role receives all scopes from "viewer" (',(0,r.jsx)(n.code,{children:"tool:basic:read"})," and ",(0,r.jsx)(n.code,{children:"artifact:read"}),") plus its own scopes (",(0,r.jsx)(n.code,{children:"tool:basic:*"})," and ",(0,r.jsx)(n.code,{children:"artifact:create"}),"). Note that ",(0,r.jsx)(n.code,{children:"tool:basic:*"})," includes ",(0,r.jsx)(n.code,{children:"tool:basic:read"}),", so there is some overlap. Agent Mesh Enterprise handles this correctly by deduplicating scopes."]}),"\n",(0,r.jsx)(n.h3,{id:"user-to-role-assignments-structure",children:"User-to-Role Assignments Structure"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"user-to-role-assignments.yaml"})," file supports both global user identities and gateway-specific identities. Here is the complete structure:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'users:\n user_identity:\n roles: ["role1", "role2"]\n description: "User description"\n\n# Optional: Gateway-specific user identities\ngateway_specific_identities:\n gateway_id:user_identity:\n roles: ["role1", "role2"]\n description: "User with specific roles on this gateway"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"users"})," section defines global user identities that apply across all gateways. Most configurations only need this section."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"gateway_specific_identities"})," section allows you to assign different roles to the same user identity on different gateways. This feature is useful in multi-gateway deployments where you want to grant different permissions based on which gateway a user accesses. The key format is ",(0,r.jsx)(n.code,{children:"gateway_id:user_identity"}),", where ",(0,r.jsx)(n.code,{children:"gateway_id"})," matches the gateway ID in your enterprise configuration."]}),"\n",(0,r.jsx)(n.h3,{id:"enterprise-configuration-structure",children:"Enterprise Configuration Structure"}),"\n",(0,r.jsx)(n.p,{children:"The enterprise configuration file supports multiple authorization service types. Here is the complete structure for the file-based RBAC system:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'authorization_service:\n type: "default_rbac"\n role_to_scope_definitions_path: "path/to/role-to-scope-definitions.yaml"\n user_to_role_assignments_path: "path/to/user-to-role-assignments.yaml"\n'})}),"\n",(0,r.jsx)(n.h2,{id:"advanced-configuration-options",children:"Advanced Configuration Options"}),"\n",(0,r.jsx)(n.p,{children:"After you have a basic RBAC configuration working, you might want to explore advanced options that provide additional flexibility and integration capabilities."}),"\n",(0,r.jsx)(n.h3,{id:"production-ready-role-configuration",children:"Production-Ready Role Configuration"}),"\n",(0,r.jsx)(n.p,{children:"A production environment typically needs more sophisticated role definitions than the basic examples\n. Here is a comprehensive configuration that demonstrates best practices:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# role-to-scope-definitions.yaml\nroles:\n admin:\n description: "Administrator with full access"\n scopes:\n - "*"\n \n operator:\n description: "System operator"\n scopes:\n - "tool:basic:*"\n - "tool:advanced:read"\n - "artifact:read"\n - "artifact:create"\n - "monitor/namespace/*:a2a_messages:subscribe"\n \n viewer:\n description: "Read-only access"\n scopes:\n - "tool:basic:read"\n - "artifact:read"\n - "monitor/namespace/*:a2a_messages:subscribe"\n'})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# user-to-role-assignments.yaml\nusers:\n admin@company.com:\n roles: ["admin"]\n description: "System Administrator"\n \n operator@company.com:\n roles: ["operator"]\n description: "System Operator"\n \n viewer@company.com:\n roles: ["viewer"]\n description: "Read-only User"\n'})}),"\n",(0,r.jsx)(n.p,{children:"This configuration creates a clear hierarchy of access levels. The admin role has unrestricted access, the operator role can perform most operational tasks, and the viewer role provides read-only access for monitoring and auditing purposes."}),"\n",(0,r.jsx)(n.h3,{id:"integrating-with-microsoft-graph",children:"Integrating with Microsoft Graph"}),"\n",(0,r.jsx)(n.p,{children:"For enterprise environments that use Microsoft Entra ID (formerly Azure AD) for user management, you can integrate Agent Mesh Enterprise with Microsoft Graph. This integration allows you to manage user role assignments through Microsoft Graph instead of maintaining a separate YAML file."}),"\n",(0,r.jsxs)(n.p,{children:["To configure Microsoft Graph integration, modify your ",(0,r.jsx)(n.code,{children:"enterprise_config.yaml"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# enterprise_config.yaml\nauthorization_service:\n type: "default_rbac"\n role_to_scope_definitions_path: "config/auth/role-to-scope-definitions.yaml"\n user_to_role_provider: "ms_graph"\n \n ms_graph_config:\n ms_graph_tenant_id: ${MS_GRAPH_TENANT_ID}\n ms_graph_client_id: ${MS_GRAPH_CLIENT_ID}\n ms_graph_client_secret: ${MS_GRAPH_CLIENT_SECRET}\n'})}),"\n",(0,r.jsxs)(n.p,{children:["This configuration tells Agent Mesh Enterprise to retrieve user role assignments from Microsoft Graph instead of reading them from a YAML file. The ",(0,r.jsx)(n.code,{children:"${...}"})," syntax indicates that these values come from environment variables, which keeps sensitive credentials out of your configuration files."]}),"\n",(0,r.jsxs)(n.p,{children:["When you use Microsoft Graph integration, you still define roles in the ",(0,r.jsx)(n.code,{children:"role-to-scope-definitions.yaml"})," file, but you manage user-to-role assignments through Microsoft Graph groups or attributes."]}),"\n",(0,r.jsx)(n.p,{children:"Run the Docker container with the Microsoft Graph credentials:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'docker run -d \\\n --name sam-enterprise \\\n -p 8000:8001 \\\n -v "$(pwd):/app" \\\n -e MS_GRAPH_TENANT_ID=your-tenant-id \\\n -e MS_GRAPH_CLIENT_ID=your-client-id \\\n -e MS_GRAPH_CLIENT_SECRET=your-client-secret \\\n -e NAMESPACE=enterprise_prod \\\n -e WEBUI_GATEWAY_ID=enterprise_gateway \\\n solace-agent-mesh-enterprise:<tag>\n'})}),"\n",(0,r.jsx)(n.p,{children:"The Microsoft Graph integration requires that you configure an application registration in Microsoft Entra ID with appropriate permissions to read user and group information. The tenant ID identifies your Microsoft Entra ID tenant, the client ID identifies your application registration, and the client secret authenticates your application."}),"\n",(0,r.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,r.jsx)(n.p,{children:"Following best practices helps you create a secure, maintainable RBAC configuration that scales with your organization's needs."}),"\n",(0,r.jsx)(n.h3,{id:"security-recommendations",children:"Security Recommendations"}),"\n",(0,r.jsx)(n.p,{children:"You should implement these security practices to protect your Agent Mesh Enterprise deployment:"}),"\n",(0,r.jsx)(n.p,{children:"Apply the principle of least privilege by assigning users only the minimum permissions necessary for their tasks. Start with restrictive permissions and add more as needed, rather than starting with broad permissions and removing them later. This approach reduces the risk of unauthorized access."}),"\n",(0,r.jsx)(n.p,{children:"Conduct regular audits of your role assignments and permissions. Review who has access to what features and verify that access levels remain appropriate as job responsibilities change. Remove access for users who no longer need it."}),"\n",(0,r.jsx)(n.p,{children:"Protect your RBAC configuration files with appropriate file permissions on your host system. These files control access to your entire Agent Mesh Enterprise deployment, so you should restrict read and write access to authorized administrators only."}),"\n",(0,r.jsx)(n.p,{children:"Store sensitive information like Microsoft Graph credentials as environment variables rather than hardcoding them in configuration files. Environment variables provide better security because they do not appear in version control systems or configuration backups."}),"\n",(0,r.jsx)(n.p,{children:"Never use development configurations in production environments. Development configurations often include test accounts with elevated permissions or relaxed security settings that are inappropriate for production use."}),"\n",(0,r.jsx)(n.h3,{id:"role-design-principles",children:"Role Design Principles"}),"\n",(0,r.jsx)(n.p,{children:"Well-designed roles make your RBAC configuration easier to understand and maintain:"}),"\n",(0,r.jsx)(n.p,{children:"Create roles that align with job functions in your organization. Each role should represent a specific type of work that users perform. This alignment makes it easier to determine which role to assign to new users."}),"\n",(0,r.jsx)(n.p,{children:"Use role inheritance to build a logical hierarchy. If one role needs all the permissions of another role plus additional permissions, use inheritance rather than duplicating scopes. This approach reduces configuration size and makes updates easier."}),"\n",(0,r.jsx)(n.p,{children:'Use clear, descriptive names for roles that indicate their purpose. Names like "data_analyst" or "system_operator" are more meaningful than generic names like "role1" or "user_type_a".'}),"\n",(0,r.jsx)(n.p,{children:"Document the purpose and scope of each role in the description field. This documentation helps other administrators understand your RBAC configuration and makes it easier to maintain over time."}),"\n",(0,r.jsxs)(n.p,{children:["Minimize wildcard usage in scope definitions. While wildcards like ",(0,r.jsx)(n.code,{children:"*"})," or ",(0,r.jsx)(n.code,{children:"tool:*:*"})," are convenient, they grant broad permissions that might include features you did not intend to allow. Use specific scopes whenever possible, and reserve wildcards for administrator roles."]}),"\n",(0,r.jsx)(n.h3,{id:"docker-specific-recommendations",children:"Docker-Specific Recommendations"}),"\n",(0,r.jsx)(n.p,{children:"When you run Agent Mesh Enterprise in Docker, follow these recommendations:"}),"\n",(0,r.jsx)(n.p,{children:"Use Docker volumes for persistent configuration storage. The volume mount approach shown in this guide ensures that your configuration persists even if you remove and recreate the container."}),"\n",(0,r.jsx)(n.p,{children:"Create separate configuration files for different environments (development, staging, production). This separation prevents accidental use of inappropriate configurations and makes it easier to maintain environment-specific settings."}),"\n",(0,r.jsx)(n.p,{children:"Implement health checks to verify that RBAC is functioning correctly. You can add a health check to your Docker run command that periodically tests whether the container is responding correctly."}),"\n",(0,r.jsx)(n.p,{children:"Regularly backup your RBAC configuration files. Store backups in a secure location separate from your Docker host. If you lose your configuration files, you lose control over who can access your Agent Mesh Enterprise deployment."}),"\n",(0,r.jsx)(n.p,{children:"Follow Docker security best practices such as running containers as non-root users and using read-only filesystems where possible. These practices reduce the impact of potential security vulnerabilities."}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsx)(n.p,{children:"When you encounter issues with your RBAC configuration, systematic troubleshooting helps you identify and resolve problems quickly."}),"\n",(0,r.jsx)(n.h3,{id:"authorization-denied-for-valid-user",children:"Authorization Denied for Valid User"}),"\n",(0,r.jsx)(n.p,{children:"If a user cannot access features they should have permission to use, you might see authorization denied messages in the logs or user interface."}),"\n",(0,r.jsxs)(n.p,{children:["To resolve this issue, first verify that the user identity matches exactly what appears in your ",(0,r.jsx)(n.code,{children:"user-to-role-assignments.yaml"})," file. Agent Mesh Enterprise performs case-sensitive matching, so ",(0,r.jsx)(n.code,{children:"user@example.com"})," and ",(0,r.jsx)(n.code,{children:"User@example.com"})," are different identities."]}),"\n",(0,r.jsxs)(n.p,{children:["Next, check that the role assigned to the user has the necessary scopes. Review the ",(0,r.jsx)(n.code,{children:"role-to-scope-definitions.yaml"})," file and verify that the role includes scopes for the features the user is trying to access."]}),"\n",(0,r.jsx)(n.p,{children:"Ensure that your configuration files are correctly mounted in the Docker container. You can verify the mount by running:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker exec -it sam-enterprise ls -la /app/config/auth\n"})}),"\n",(0,r.jsxs)(n.p,{children:["This command lists the files in the mounted directory. You should see your ",(0,r.jsx)(n.code,{children:"role-to-scope-definitions.yaml"})," and ",(0,r.jsx)(n.code,{children:"user-to-role-assignments.yaml"})," files."]}),"\n",(0,r.jsx)(n.p,{children:"Check the container logs for authorization service errors:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker logs sam-enterprise\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Look for messages with the ",(0,r.jsx)(n.code,{children:"[ConfigurableRbacAuthSvc]"})," prefix. These messages indicate whether Agent Mesh Enterprise successfully loaded your configuration files and how it resolved roles and scopes. You should see messages like:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"INFO:solace_ai_connector:[ConfigurableRbacAuthSvc] Successfully loaded role-to-scope definitions from: /app/config/auth/role-to-scope-definitions.yaml\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'enterprise_admin' loaded with 1 direct scopes, 1 resolved scopes.\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'data_analyst' loaded with 4 direct scopes, 4 resolved scopes.\nDEBUG:solace_ai_connector:[ConfigurableRbacAuthSvc] Role 'standard_user' loaded with 1 direct scopes, 1 resolved scopes.\n"})}),"\n",(0,r.jsx)(n.h3,{id:"configuration-files-not-found",children:"Configuration Files Not Found"}),"\n",(0,r.jsx)(n.p,{children:"If you see error messages about missing configuration files or the system uses default authorization behavior, the container cannot find your configuration files."}),"\n",(0,r.jsxs)(n.p,{children:["Check that the volume mount in your Docker run command is correct. The mount should map your host directory to ",(0,r.jsx)(n.code,{children:"/app"})," in the container. Verify that you are using the correct path on your host system."]}),"\n",(0,r.jsx)(n.p,{children:"Ensure that file permissions allow the container user to read the files. On Linux systems, you might need to adjust file permissions:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"chmod 644 sam-enterprise/config/auth/*.yaml\n"})}),"\n",(0,r.jsx)(n.p,{children:"Check for typos in file names or paths. The file names are case-sensitive, and even small typos prevent Agent Mesh Enterprise from finding your configuration files."}),"\n",(0,r.jsx)(n.h3,{id:"microsoft-graph-integration-not-working",children:"Microsoft Graph Integration Not Working"}),"\n",(0,r.jsx)(n.p,{children:"If users cannot authenticate when you use Microsoft Graph integration, or you see error messages related to Microsoft Graph in the logs, several issues might be causing the problem."}),"\n",(0,r.jsx)(n.p,{children:"Verify that your Microsoft Graph credentials are correct. Double-check the tenant ID, client ID, and client secret against your Microsoft Entra ID application registration."}),"\n",(0,r.jsx)(n.p,{children:"Check that environment variables are properly set in your Docker run command. You can verify environment variables inside the container:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker exec -it sam-enterprise env | grep MS_GRAPH\n"})}),"\n",(0,r.jsx)(n.p,{children:"Ensure that your Microsoft Graph application has the necessary permissions. The application needs permissions to read user and group information from Microsoft Entra ID."}),"\n",(0,r.jsxs)(n.p,{children:["Check network connectivity from the container to Microsoft Graph endpoints. The container must be able to reach ",(0,r.jsx)(n.code,{children:"graph.microsoft.com"})," over HTTPS. Firewall rules or network policies might block this connectivity."]}),"\n",(0,r.jsx)(n.h3,{id:"debugging-authorization-issues",children:"Debugging Authorization Issues"}),"\n",(0,r.jsx)(n.p,{children:"When you need to investigate authorization problems in detail, follow these debugging steps:"}),"\n",(0,r.jsxs)(n.p,{children:["Enable debug logging by adding a log level setting to your ",(0,r.jsx)(n.code,{children:"enterprise_config.yaml"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# Add to your enterprise_config.yaml\nlog_level: "DEBUG"\n'})}),"\n",(0,r.jsx)(n.p,{children:"Debug logging provides detailed information about authorization decisions, including which scopes the system checked and why it allowed or denied access."}),"\n",(0,r.jsx)(n.p,{children:"Check the container logs for detailed information:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker logs sam-enterprise\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Look for log messages with the ",(0,r.jsx)(n.code,{children:"[EnterpriseConfigResolverImpl]"})," or ",(0,r.jsx)(n.code,{children:"[ConfigurableRbacAuthSvc]"})," prefixes. These messages show how Agent Mesh Enterprise loaded and processed your configuration."]}),"\n",(0,r.jsx)(n.p,{children:"Temporarily assign the user to an administrator role to verify whether the issue is permission-related. If the user can access features when assigned to an admin role, the problem is with the scopes assigned to their original role."}),"\n",(0,r.jsx)(n.p,{children:"Inspect the mounted configuration files inside the container to verify that they contain the expected content:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker exec -it sam-enterprise cat /app/config/auth/role-to-scope-definitions.yaml\ndocker exec -it sam-enterprise cat /app/config/auth/user-to-role-assignments.yaml\n"})}),"\n",(0,r.jsx)(n.p,{children:"This verification ensures that the files inside the container match your host files and that the volume mount is working correctly."}),"\n",(0,r.jsx)(n.h3,{id:"getting-help",children:"Getting Help"}),"\n",(0,r.jsx)(n.p,{children:"If you continue to experience issues after following these troubleshooting steps, you can get additional help:"}),"\n",(0,r.jsx)(n.p,{children:"Check the Agent Mesh Enterprise documentation for updates or additional information about RBAC configuration."}),"\n",(0,r.jsx)(n.p,{children:"Review the container logs for specific error messages. Error messages often include details about what went wrong and how to fix it."}),"\n",(0,r.jsx)(n.p,{children:"Contact Solace support with details of your configuration and the issues you are experiencing. Include relevant log excerpts and describe the steps you have already taken to troubleshoot the problem."}),"\n",(0,r.jsx)(n.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,r.jsx)(n.p,{children:"Setting up Role-Based Access Control in your Agent Mesh Enterprise Docker installation provides enhanced security and granular access control. This guide has walked you through understanding RBAC concepts, planning your configuration, creating configuration files, and troubleshooting common issues."}),"\n",(0,r.jsx)(n.p,{children:"You now have the knowledge to configure RBAC to meet your organization's specific requirements while maintaining a secure and manageable environment. Remember to regularly review and update your RBAC configuration as your organization's needs evolve, and always follow security best practices when managing access control."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(6540);const r={},t=i.createContext(r);function o(e){const n=i.useContext(t);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(t.Provider,{value:n},e.children)}}}]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[9257],{4074:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"documentation/getting-started/getting-started","title":"Getting Started","description":"Agent Mesh is an open-source framework for building event-driven multi-agent AI systems that solve complex problems through intelligent collaboration. You can use it to create teams of specialized AI agents that work together seamlessly, each bringing unique capabilities while communicating through Solace\'s proven event-driven architecture.","source":"@site/docs/documentation/getting-started/getting-started.md","sourceDirName":"documentation/getting-started","slug":"/documentation/getting-started/","permalink":"/solace-agent-mesh/docs/documentation/getting-started/","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/getting-started/getting-started.md","tags":[],"version":"current","sidebarPosition":12,"frontMatter":{"title":"Getting Started","sidebar_position":12},"sidebar":"docSidebar","next":{"title":"What is Agent Mesh?","permalink":"/solace-agent-mesh/docs/documentation/getting-started/introduction"}}');var o=n(4848),i=n(8453);const a={title:"Getting Started",sidebar_position:12},r="Get Started with Agent Mesh",c={},l=[{value:"Understanding Agent Mesh",id:"understanding-agent-mesh",level:2},{value:"Getting Started Quickly",id:"getting-started-quickly",level:2},{value:"Building with Agent Mesh",id:"building-with-agent-mesh",level:2},{value:"Core Components",id:"core-components",level:2},{value:"Advanced Capabilities",id:"advanced-capabilities",level:2},{value:"Learning Through Examples",id:"learning-through-examples",level:2},{value:"Additional Resources",id:"additional-resources",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"get-started-with-agent-mesh",children:"Get Started with Agent Mesh"})}),"\n",(0,o.jsx)(t.p,{children:"Agent Mesh is an open-source framework for building event-driven multi-agent AI systems that solve complex problems through intelligent collaboration. You can use it to create teams of specialized AI agents that work together seamlessly, each bringing unique capabilities while communicating through Solace's proven event-driven architecture."}),"\n",(0,o.jsx)(t.p,{children:"Whether you're building intelligent automation systems, creating sophisticated AI workflows, or integrating AI capabilities across your enterprise, Agent Mesh provides the foundation you need. The framework handles agent communication automatically, so you can focus on building powerful AI experiences that scale with your needs."}),"\n",(0,o.jsx)(t.h2,{id:"understanding-agent-mesh",children:"Understanding Agent Mesh"}),"\n",(0,o.jsxs)(t.p,{children:["Before diving into implementation, it's helpful to understand what makes Agent Mesh unique. The framework combines the power of Google's Agent Development Kit with Solace's event-driven messaging platform, creating a robust foundation for multi-agent AI systems. To learn about the core concepts and architectural principles that drive the framework's design, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/introduction",children:"What is Agent Mesh?"})]}),"\n",(0,o.jsxs)(t.p,{children:["The system's event-driven architecture enables true scalability and reliability, allowing agents to communicate asynchronously while maintaining loose coupling between components. For detailed insights into how these components work together to create a cohesive AI ecosystem, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/architecture",children:"Architecture Overview"})]}),"\n",(0,o.jsxs)(t.p,{children:["To see how all the pieces fit together, you can explore the key building blocks that make up every Agent Mesh deployment. For more information, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/",children:"Components Overview"})]}),"\n",(0,o.jsx)(t.h2,{id:"getting-started-quickly",children:"Getting Started Quickly"}),"\n",(0,o.jsxs)(t.p,{children:["The fastest way to experience Agent Mesh is through our pre-configured Docker setup that gets you up and running with a working system in minutes. This approach lets you explore the framework's capabilities immediately without any installation or complex configuration. To get started right away, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/try-agent-mesh",children:"Try Agent Mesh"})]}),"\n",(0,o.jsxs)(t.p,{children:["Once you've explored the basic functionality and want to set up your own development environment, you'll need to install the CLI and framework tools. The installation process supports multiple approaches including pip, uv, and Docker, making it easy to integrate with your existing workflow. For complete setup instructions, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/installation",children:"Installation"})]}),"\n",(0,o.jsxs)(t.p,{children:["For those ready to build their own projects from scratch, comprehensive guidance is available for creating and configuring custom deployments with full control over your agent mesh. This approach provides the flexibility needed for serious development work and production environments. To learn about project creation and configuration, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/run-project",children:"Creating and Running an Agent Mesh Project"})]}),"\n",(0,o.jsx)(t.h2,{id:"building-with-agent-mesh",children:"Building with Agent Mesh"}),"\n",(0,o.jsx)(t.p,{children:"Creating effective AI systems requires understanding how to design and implement the right components for your use case. The framework provides several key building blocks that you can combine and customize to meet your specific needs."}),"\n",(0,o.jsxs)(t.p,{children:["Specialized AI components can perform specific tasks, access particular data sources, or integrate with external systems, with each agent bringing its own capabilities while participating in the larger collaborative ecosystem. To learn how to build these components, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents",children:"Creating Agents"})]}),"\n",(0,o.jsxs)(t.p,{children:["Interfaces that connect your agent mesh to the outside world enable integration through REST APIs, web interfaces, chat platforms, or custom integrations. For guidance on building these connection points, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-gateways",children:"Creating Gateways"})]}),"\n",(0,o.jsxs)(t.p,{children:["Custom tools extend functionality beyond the built-in capabilities, allowing agents to interact with databases, APIs, file systems, or any other resources your applications require. To understand how to add these extensions, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/creating-python-tools",children:"Creating Python Tools"})]}),"\n",(0,o.jsx)(t.h2,{id:"core-components",children:"Core Components"}),"\n",(0,o.jsx)(t.p,{children:"Agent Mesh is built around several fundamental components that work together to create intelligent, collaborative systems. Understanding these components helps you design effective solutions and troubleshoot issues when they arise."}),"\n",(0,o.jsxs)(t.p,{children:["The intelligent workers of your system are powered by AI models and equipped with specialized tools, capable of analyzing data, generating content, making decisions, and delegating tasks to other agents when needed. For more information, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/agents",children:"Agents"})]}),"\n",(0,o.jsxs)(t.p,{children:["Bridges between your agent mesh and external systems translate requests from users, applications, or other systems into the standardized communication protocol that agents understand. To learn about these interface components, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/gateways",children:"Gateways"})]}),"\n",(0,o.jsxs)(t.p,{children:["The conductor of your agent symphony breaks down complex requests into manageable tasks and coordinates the work of multiple agents to achieve sophisticated outcomes. For details about this coordination system, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/orchestrator",children:"Orchestrator"})]}),"\n",(0,o.jsxs)(t.p,{children:["A powerful extension mechanism lets you add new capabilities to your system without modifying core components, making it easy to integrate with existing tools and services. To understand how to extend your system, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins",children:"Plugins"})]}),"\n",(0,o.jsxs)(t.p,{children:["Comprehensive command-line tools manage your projects from initial setup through deployment and ongoing maintenance. For information about these development tools, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/cli",children:"CLI"})]}),"\n",(0,o.jsx)(t.h2,{id:"advanced-capabilities",children:"Advanced Capabilities"}),"\n",(0,o.jsx)(t.p,{children:"As your AI systems grow in complexity and scale, Agent Mesh provides advanced features to support enterprise deployments and sophisticated use cases."}),"\n",(0,o.jsxs)(t.p,{children:["Various approaches for running Agent Mesh in production range from single-machine setups to distributed enterprise deployments across multiple environments. To explore your deployment options, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/deployment-options",children:"Deployment Options"})]}),"\n",(0,o.jsxs)(t.p,{children:["Real-time monitoring capabilities help you track performance metrics and debug issues when they occur, with the framework's event-driven architecture providing natural visibility into all system interactions. For guidance on system monitoring, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability",children:"Observability"})]}),"\n",(0,o.jsxs)(t.p,{children:["Organizations with specific security and governance requirements can leverage advanced capabilities including role-based access control, single sign-on integration, and enterprise-grade security features. To learn about these advanced features, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/",children:"Enterprise Features"})]}),"\n",(0,o.jsx)(t.h2,{id:"learning-through-examples",children:"Learning Through Examples"}),"\n",(0,o.jsx)(t.p,{children:"Practical tutorials help you understand how to apply Agent Mesh to real-world scenarios. These hands-on guides walk you through building complete solutions that demonstrate the framework's capabilities."}),"\n",(0,o.jsxs)(t.p,{children:["Creating agents that can query databases and provide intelligent responses based on your organization's data demonstrates how to integrate with existing data sources. For a complete walkthrough, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/sql-database",children:"SQL Database Integration"})]}),"\n",(0,o.jsxs)(t.p,{children:["Building a gateway that lets users interact with your agent mesh directly through Slack brings AI capabilities into existing workflows and communication platforms. To learn how to set this up, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/slack-integration",children:"Slack Integration"})]}),"\n",(0,o.jsxs)(t.p,{children:["Creating a specialized agent from scratch, including tool integration and configuration, shows you the complete development process for custom components. For step-by-step guidance, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/custom-agent",children:"Custom Agent Tutorial"})]}),"\n",(0,o.jsxs)(t.p,{children:["Incorporating Model Context Protocol servers into your agent mesh extends capabilities through standardized integrations with external tools and services. To understand this integration approach, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/mcp-integration",children:"MCP Integration"})]}),"\n",(0,o.jsx)(t.h2,{id:"additional-resources",children:"Additional Resources"}),"\n",(0,o.jsxs)(t.p,{children:["Beyond the core documentation, several resources can help you get the most out of Agent Mesh. The latest source code, example configurations, and community discussions are available in the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh",children:"GitHub repository"})]}),"\n",(0,o.jsxs)(t.p,{children:["Pre-built functionality for common use cases provides tested integrations that you can incorporate into your own projects. You can find these extensions in the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins",children:"official plugins repository"})]}),"\n",(0,o.jsxs)(t.p,{children:["Participating in the project's development is possible through reporting issues, suggesting improvements, or contributing code. To learn how you can get involved, see the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(6540);const o={},i=s.createContext(o);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]);
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[9257],{4074:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"documentation/getting-started/getting-started","title":"Getting Started","description":"Agent Mesh is an open-source framework for building event-driven multi-agent AI systems that solve complex problems through intelligent collaboration. You can use it to create teams of specialized AI agents that work together seamlessly, each bringing unique capabilities while communicating through Solace\'s proven event-driven architecture.","source":"@site/docs/documentation/getting-started/getting-started.md","sourceDirName":"documentation/getting-started","slug":"/documentation/getting-started/","permalink":"/solace-agent-mesh/docs/documentation/getting-started/","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/getting-started/getting-started.md","tags":[],"version":"current","sidebarPosition":12,"frontMatter":{"title":"Getting Started","sidebar_position":12},"sidebar":"docSidebar","next":{"title":"What is Agent Mesh?","permalink":"/solace-agent-mesh/docs/documentation/getting-started/introduction"}}');var o=n(4848),i=n(8453);const a={title:"Getting Started",sidebar_position:12},r="Get Started with Agent Mesh",c={},l=[{value:"Understanding Agent Mesh",id:"understanding-agent-mesh",level:2},{value:"Getting Started Quickly",id:"getting-started-quickly",level:2},{value:"Building with Agent Mesh",id:"building-with-agent-mesh",level:2},{value:"Core Components",id:"core-components",level:2},{value:"Advanced Capabilities",id:"advanced-capabilities",level:2},{value:"Learning Through Examples",id:"learning-through-examples",level:2},{value:"Additional Resources",id:"additional-resources",level:2}];function d(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"get-started-with-agent-mesh",children:"Get Started with Agent Mesh"})}),"\n",(0,o.jsx)(t.p,{children:"Agent Mesh is an open-source framework for building event-driven multi-agent AI systems that solve complex problems through intelligent collaboration. You can use it to create teams of specialized AI agents that work together seamlessly, each bringing unique capabilities while communicating through Solace's proven event-driven architecture."}),"\n",(0,o.jsx)(t.p,{children:"Whether you're building intelligent automation systems, creating sophisticated AI workflows, or integrating AI capabilities across your enterprise, Agent Mesh provides the foundation you need. The framework handles agent communication automatically, so you can focus on building powerful AI experiences that scale with your needs."}),"\n",(0,o.jsx)(t.h2,{id:"understanding-agent-mesh",children:"Understanding Agent Mesh"}),"\n",(0,o.jsxs)(t.p,{children:["Before diving into implementation, it's helpful to understand what makes Agent Mesh unique. The framework combines the power of Google's Agent Development Kit with Solace's event-driven messaging platform, creating a robust foundation for multi-agent AI systems. To learn about the core concepts and architectural principles that drive the framework's design, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/introduction",children:"What is Agent Mesh?"})]}),"\n",(0,o.jsxs)(t.p,{children:["The system's event-driven architecture enables true scalability and reliability, allowing agents to communicate asynchronously while maintaining loose coupling between components. For detailed insights into how these components work together to create a cohesive AI ecosystem, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/architecture",children:"Architecture Overview"})]}),"\n",(0,o.jsxs)(t.p,{children:["To see how all the pieces fit together, you can explore the key building blocks that make up every Agent Mesh deployment. For more information, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/",children:"Components Overview"})]}),"\n",(0,o.jsx)(t.h2,{id:"getting-started-quickly",children:"Getting Started Quickly"}),"\n",(0,o.jsxs)(t.p,{children:["The fastest way to experience Agent Mesh is through our pre-configured Docker setup that gets you up and running with a working system in minutes. This approach lets you explore the framework's capabilities immediately without any installation or complex configuration. To get started right away, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/try-agent-mesh",children:"Try Agent Mesh"})]}),"\n",(0,o.jsxs)(t.p,{children:["Once you've explored the basic functionality and want to set up your own development environment, you'll need to install the CLI and framework tools. The installation process supports multiple approaches including pip, uv, and Docker, making it easy to integrate with your existing workflow. For complete setup instructions, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/installation",children:"Installation"})]}),"\n",(0,o.jsxs)(t.p,{children:["For those ready to build their own projects from scratch, comprehensive guidance is available for creating and configuring custom deployments with full control over your agent mesh. This approach provides the flexibility needed for serious development work and production environments. To learn about project creation and configuration, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/run-project",children:"Creating and Running an Agent Mesh Project"})]}),"\n",(0,o.jsx)(t.h2,{id:"building-with-agent-mesh",children:"Building with Agent Mesh"}),"\n",(0,o.jsx)(t.p,{children:"Creating effective AI systems requires understanding how to design and implement the right components for your use case. The framework provides several key building blocks that you can combine and customize to meet your specific needs."}),"\n",(0,o.jsxs)(t.p,{children:["Specialized AI components can perform specific tasks, access particular data sources, or integrate with external systems, with each agent bringing its own capabilities while participating in the larger collaborative ecosystem. To learn how to build these components, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents",children:"Creating Agents"})]}),"\n",(0,o.jsxs)(t.p,{children:["Interfaces that connect your agent mesh to the outside world enable integration through REST APIs, web interfaces, chat platforms, or custom integrations. For guidance on building these connection points, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-gateways",children:"Creating Gateways"})]}),"\n",(0,o.jsxs)(t.p,{children:["Custom tools extend functionality beyond the built-in capabilities, allowing agents to interact with databases, APIs, file systems, or any other resources your applications require. To understand how to add these extensions, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/creating-python-tools",children:"Creating Python Tools"})]}),"\n",(0,o.jsx)(t.h2,{id:"core-components",children:"Core Components"}),"\n",(0,o.jsx)(t.p,{children:"Agent Mesh is built around several fundamental components that work together to create intelligent, collaborative systems. Understanding these components helps you design effective solutions and troubleshoot issues when they arise."}),"\n",(0,o.jsxs)(t.p,{children:["The intelligent workers of your system are powered by AI models and equipped with specialized tools, capable of analyzing data, generating content, making decisions, and delegating tasks to other agents when needed. For more information, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/agents",children:"Agents"})]}),"\n",(0,o.jsxs)(t.p,{children:["Bridges between your agent mesh and external systems translate requests from users, applications, or other systems into the standardized communication protocol that agents understand. To learn about these interface components, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/gateways",children:"Gateways"})]}),"\n",(0,o.jsxs)(t.p,{children:["The conductor of your agent symphony breaks down complex requests into manageable tasks and coordinates the work of multiple agents to achieve sophisticated outcomes. For details about this coordination system, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/orchestrator",children:"Orchestrator"})]}),"\n",(0,o.jsxs)(t.p,{children:["A powerful extension mechanism lets you add new capabilities to your system without modifying core components, making it easy to integrate with existing tools and services. To understand how to extend your system, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins",children:"Plugins"})]}),"\n",(0,o.jsxs)(t.p,{children:["Comprehensive command-line tools manage your projects from initial setup through deployment and ongoing maintenance. For information about these development tools, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/components/cli",children:"CLI"})]}),"\n",(0,o.jsx)(t.h2,{id:"advanced-capabilities",children:"Advanced Capabilities"}),"\n",(0,o.jsx)(t.p,{children:"As your AI systems grow in complexity and scale, Agent Mesh provides advanced features to support enterprise deployments and sophisticated use cases."}),"\n",(0,o.jsxs)(t.p,{children:["Various approaches for running Agent Mesh in production range from single-machine setups to distributed enterprise deployments across multiple environments. To explore your deployment options, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/deployment-options",children:"Deployment Options"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["For comprehensive guidance on deploying to Kubernetes with Helm charts and enterprise configurations, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/kubernetes-deployment",children:"Kubernetes"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Real-time monitoring capabilities help you track performance metrics and debug issues when they occur, with the framework's event-driven architecture providing natural visibility into all system interactions. For guidance on system monitoring, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability",children:"Observability"})]}),"\n",(0,o.jsxs)(t.p,{children:["Organizations with specific security and governance requirements can leverage advanced capabilities including role-based access control, single sign-on integration, and enterprise-grade security features. To learn about these advanced features, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/enterprise/",children:"Enterprise Features"})]}),"\n",(0,o.jsx)(t.h2,{id:"learning-through-examples",children:"Learning Through Examples"}),"\n",(0,o.jsx)(t.p,{children:"Practical tutorials help you understand how to apply Agent Mesh to real-world scenarios. These hands-on guides walk you through building complete solutions that demonstrate the framework's capabilities."}),"\n",(0,o.jsxs)(t.p,{children:["Creating agents that can query databases and provide intelligent responses based on your organization's data demonstrates how to integrate with existing data sources. For a complete walkthrough, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/sql-database",children:"SQL Database Integration"})]}),"\n",(0,o.jsxs)(t.p,{children:["Building a gateway that lets users interact with your agent mesh directly through Slack brings AI capabilities into existing workflows and communication platforms. To learn how to set this up, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/slack-integration",children:"Slack Integration"})]}),"\n",(0,o.jsxs)(t.p,{children:["Creating a specialized agent from scratch, including tool integration and configuration, shows you the complete development process for custom components. For step-by-step guidance, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/custom-agent",children:"Custom Agent Tutorial"})]}),"\n",(0,o.jsxs)(t.p,{children:["Incorporating Model Context Protocol servers into your agent mesh extends capabilities through standardized integrations with external tools and services. To understand this integration approach, see ",(0,o.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/developing/tutorials/mcp-integration",children:"MCP Integration"})]}),"\n",(0,o.jsx)(t.h2,{id:"additional-resources",children:"Additional Resources"}),"\n",(0,o.jsxs)(t.p,{children:["Beyond the core documentation, several resources can help you get the most out of Agent Mesh. The latest source code, example configurations, and community discussions are available in the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh",children:"GitHub repository"})]}),"\n",(0,o.jsxs)(t.p,{children:["Pre-built functionality for common use cases provides tested integrations that you can incorporate into your own projects. You can find these extensions in the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins",children:"official plugins repository"})]}),"\n",(0,o.jsxs)(t.p,{children:["Participating in the project's development is possible through reporting issues, suggesting improvements, or contributing code. To learn how you can get involved, see the ",(0,o.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh/blob/main/CONTRIBUTING.md",children:"Contributing Guide"})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(6540);const o={},i=s.createContext(o);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1625],{2585:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/installing-and-configuring/session-storage","title":"Session Storage","description":"This guide explains how to configure session storage in Agent Mesh, enabling user conversations to persist across restarts and providing rich conversation history for both the WebUI Gateway and individual agents.","source":"@site/docs/documentation/installing-and-configuring/session-storage.md","sourceDirName":"documentation/installing-and-configuring","slug":"/documentation/installing-and-configuring/session-storage","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/installing-and-configuring/session-storage.md","tags":[],"version":"current","sidebarPosition":350,"frontMatter":{"title":"Session Storage","sidebar_position":350},"sidebar":"docSidebar","previous":{"title":"User Feedback","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/user-feedback"},"next":{"title":"Artifact Storage","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/artifact-storage"}}');var a=s(4848),t=s(8453);const r={title:"Session Storage",sidebar_position:350},o="Configuring Session Storage",l={},c=[{value:"Understanding Session Storage Architecture",id:"understanding-session-storage-architecture",level:2},{value:"How Session Storage Works",id:"how-session-storage-works",level:3},{value:"Where Data Is Stored",id:"where-data-is-stored",level:3},{value:"Session Storage Scenarios",id:"session-storage-scenarios",level:2},{value:"Scenario A: Both WebUI Gateway and Agents Have Persistence (Recommended)",id:"scenario-a-both-webui-gateway-and-agents-have-persistence-recommended",level:3},{value:"Scenario B: Neither Has Persistence (Ephemeral Only)",id:"scenario-b-neither-has-persistence-ephemeral-only",level:3},{value:"Scenario C: Only Agents Have Persistence (Limited Experience)",id:"scenario-c-only-agents-have-persistence-limited-experience",level:3},{value:"Scenario D: Only WebUI Gateway Has Persistence (Broken Experience)",id:"scenario-d-only-webui-gateway-has-persistence-broken-experience",level:3},{value:"Configuring WebUI Gateway Session Storage",id:"configuring-webui-gateway-session-storage",level:2},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Gateway Configuration File",id:"gateway-configuration-file",level:3},{value:"Database Backend Options",id:"database-backend-options",level:3},{value:"SQLite (Development)",id:"sqlite-development",level:4},{value:"PostgreSQL (Production)",id:"postgresql-production",level:4},{value:"MySQL/MariaDB (Production)",id:"mysqlmariadb-production",level:4},{value:"Configuring Agent Session Storage",id:"configuring-agent-session-storage",level:2},{value:"Agent Configuration File",id:"agent-configuration-file",level:3},{value:"Environment Variables",id:"environment-variables-1",level:3},{value:"Database Isolation Between Agents",id:"database-isolation-between-agents",level:3},{value:"Shared Configuration Pattern",id:"shared-configuration-pattern",level:3},{value:"Migrating from Ephemeral to Persistent",id:"migrating-from-ephemeral-to-persistent",level:2},{value:"Step 1: Configure WebUI Gateway Database",id:"step-1-configure-webui-gateway-database",level:3},{value:"Step 2: Configure Agent Databases",id:"step-2-configure-agent-databases",level:3},{value:"Step 3: Restart Application",id:"step-3-restart-application",level:3},{value:"Step 4: Verify Migration",id:"step-4-verify-migration",level:3},{value:"Migration Considerations",id:"migration-considerations",level:3},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"configuring-session-storage",children:"Configuring Session Storage"})}),"\n",(0,a.jsx)(n.p,{children:"This guide explains how to configure session storage in Agent Mesh, enabling user conversations to persist across restarts and providing rich conversation history for both the WebUI Gateway and individual agents."}),"\n",(0,a.jsx)(n.h2,{id:"understanding-session-storage-architecture",children:"Understanding Session Storage Architecture"}),"\n",(0,a.jsx)(n.p,{children:"Agent Mesh uses a distributed session architecture where the WebUI Gateway and agents maintain separate but coordinated session storage systems connected via session IDs."}),"\n",(0,a.jsx)(n.h3,{id:"how-session-storage-works",children:"How Session Storage Works"}),"\n",(0,a.jsx)(n.p,{children:"When a user starts a conversation:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["The WebUI Gateway generates a session ID (",(0,a.jsx)(n.code,{children:"web-session-<UUID>"}),")"]}),"\n",(0,a.jsx)(n.li,{children:"The WebUI Gateway sends the session ID to the agent with each message"}),"\n",(0,a.jsx)(n.li,{children:"The agent receives the session ID and uses it to look up or store its own session context"}),"\n",(0,a.jsx)(n.li,{children:"The WebUI Gateway and agent store different data in their own databases"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"This architecture allows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"The WebUI Gateway to show conversation history in the user interface"}),"\n",(0,a.jsx)(n.li,{children:"Agents to maintain their own conversation context and memory"}),"\n",(0,a.jsx)(n.li,{children:"Multiple agents in a conversation to share the same session ID while maintaining isolated storage"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"where-data-is-stored",children:"Where Data Is Stored"}),"\n",(0,a.jsx)(n.p,{children:"The WebUI Gateway database stores:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Session metadata (session ID, user ID, timestamps)"}),"\n",(0,a.jsx)(n.li,{children:"Chat history displayed in the UI"}),"\n",(0,a.jsx)(n.li,{children:"Message bubbles and formatted responses"}),"\n",(0,a.jsx)(n.li,{children:"Task metadata (agent names, status, feedback)"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Each agent database stores:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Agent's conversation context and memory"}),"\n",(0,a.jsx)(n.li,{children:"Message history from the agent's perspective"}),"\n",(0,a.jsx)(n.li,{children:"Agent internal state and tool execution history"}),"\n",(0,a.jsx)(n.li,{children:"Session events and actions"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"These are separate databases. Each agent has its own independent database (with separate credentials), and the WebUI Gateway has its own database. They coordinate via the session ID."}),"\n",(0,a.jsx)(n.h2,{id:"session-storage-scenarios",children:"Session Storage Scenarios"}),"\n",(0,a.jsx)(n.p,{children:"The behavior of your deployment depends on whether the WebUI Gateway and agents have persistent storage enabled. Understanding these scenarios helps you configure correctly for your needs."}),"\n",(0,a.jsx)(n.h3,{id:"scenario-a-both-webui-gateway-and-agents-have-persistence-recommended",children:"Scenario A: Both WebUI Gateway and Agents Have Persistence (Recommended)"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# WebUI Gateway Configuration\nsession_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL}"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent Configuration\nsession_service:\n type: "sql"\n database_url: "${AGENT_DATABASE_URL, sqlite:///agent-session.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.p,{children:"What happens:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"User sees full chat history in the UI after restarts"}),"\n",(0,a.jsx)(n.li,{children:"Agents remember full conversation context across restarts"}),"\n",(0,a.jsx)(n.li,{children:"Multi-turn conversations work perfectly"}),"\n",(0,a.jsx)(n.li,{children:"Browser refresh preserves everything"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use this for:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Production deployments"}),"\n",(0,a.jsx)(n.li,{children:"Multi-turn interactive experiences"}),"\n",(0,a.jsx)(n.li,{children:"Any deployment where users expect conversation continuity"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"scenario-b-neither-has-persistence-ephemeral-only",children:"Scenario B: Neither Has Persistence (Ephemeral Only)"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# WebUI Gateway Configuration\nsession_service:\n type: "memory"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent Configuration\nsession_service:\n type: "memory"\n'})}),"\n",(0,a.jsx)(n.p,{children:"What happens:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Sessions exist only in browser cookies"}),"\n",(0,a.jsx)(n.li,{children:"No conversation history after browser refresh"}),"\n",(0,a.jsx)(n.li,{children:"No persistence across restarts"}),"\n",(0,a.jsx)(n.li,{children:"Everything lost when cookies expire"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use this for:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Local development and testing only"}),"\n",(0,a.jsx)(n.li,{children:"Rapid prototyping"}),"\n",(0,a.jsx)(n.li,{children:"Scenarios where no persistence is needed"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Do not use for:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Production deployments"}),"\n",(0,a.jsx)(n.li,{children:"Multi-turn conversations"}),"\n",(0,a.jsx)(n.li,{children:"Any scenario requiring conversation continuity"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"scenario-c-only-agents-have-persistence-limited-experience",children:"Scenario C: Only Agents Have Persistence (Limited Experience)"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# WebUI Gateway Configuration\nsession_service:\n type: "memory" # No database\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent Configuration\nsession_service:\n type: "sql"\n database_url: "${AGENT_DATABASE_URL}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.p,{children:"What happens:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"User sees no chat history in the UI after browser refresh"}),"\n",(0,a.jsx)(n.li,{children:"Agents maintain conversation context internally"}),"\n",(0,a.jsx)(n.li,{children:"Conversation works but UI does not show history"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use this for:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Rare scenarios where UI history is not needed"}),"\n",(0,a.jsx)(n.li,{children:"Headless or API-only deployments without WebUI"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"scenario-d-only-webui-gateway-has-persistence-broken-experience",children:"Scenario D: Only WebUI Gateway Has Persistence (Broken Experience)"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# WebUI Gateway Configuration\nsession_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL}"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent Configuration\nsession_service:\n type: "memory" # No database\n'})}),"\n",(0,a.jsxs)(n.admonition,{title:"Broken Experience",type:"warning",children:[(0,a.jsx)(n.p,{children:"What happens:"}),(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"User sees full chat history in the UI"}),"\n",(0,a.jsx)(n.li,{children:"Agent receives session ID but has no database to store context"}),"\n",(0,a.jsx)(n.li,{children:"Agent processes current message but forgets previous turns"}),"\n",(0,a.jsx)(n.li,{children:"The UI shows history, but the agent acts like every message is the first one"}),"\n"]}),(0,a.jsx)(n.p,{children:"The UI misleads the user by showing conversation history that the agent cannot actually use. Users get frustrated when the agent does not remember what they just said."}),(0,a.jsx)(n.p,{children:"Avoid this scenario because it creates a confusing and broken user experience."})]}),"\n",(0,a.jsx)(n.h2,{id:"configuring-webui-gateway-session-storage",children:"Configuring WebUI Gateway Session Storage"}),"\n",(0,a.jsx)(n.p,{children:"The WebUI Gateway requires two configuration elements to enable persistent session storage."}),"\n",(0,a.jsx)(n.h3,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"SESSION_SECRET_KEY"})," (Required)"]}),"\n",(0,a.jsx)(n.p,{children:"A secret key used to sign session cookies. This must be the same across all instances if you run multiple pods or processes."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export SESSION_SECRET_KEY="your-secret-key-here"\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"WEB_UI_GATEWAY_DATABASE_URL"})," (Required for persistent mode)"]}),"\n",(0,a.jsx)(n.p,{children:"The database connection string specifying where to store session data."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export WEB_UI_GATEWAY_DATABASE_URL="postgresql://user:pass@host:5432/webui_db"\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"PLATFORM_DATABASE_URL"})," (Optional, required for enterprise features)"]}),"\n",(0,a.jsx)(n.p,{children:"The database connection string for platform features such as agents, connectors, and deployments. If not configured, platform endpoints return 501 (Not Implemented)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export PLATFORM_DATABASE_URL="postgresql://user:pass@host:5432/platform_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"For development, you can use SQLite:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export PLATFORM_DATABASE_URL="sqlite:///platform.db"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"gateway-configuration-file",children:"Gateway Configuration File"}),"\n",(0,a.jsx)(n.p,{children:"Update your WebUI Gateway configuration to use the database:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL}"\n\nplatform_service:\n database_url: "${PLATFORM_DATABASE_URL, sqlite:///platform.db}"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"database-backend-options",children:"Database Backend Options"}),"\n",(0,a.jsx)(n.h4,{id:"sqlite-development",children:"SQLite (Development)"}),"\n",(0,a.jsx)(n.p,{children:"SQLite stores session data in a local file, ideal for development without external infrastructure."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "sqlite:///webui-gateway.db"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export WEB_UI_GATEWAY_DATABASE_URL="sqlite:///webui-gateway.db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Advantages:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"No external dependencies"}),"\n",(0,a.jsx)(n.li,{children:"Instant setup"}),"\n",(0,a.jsx)(n.li,{children:"Perfect for local development"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Limitations:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Not suitable for production"}),"\n",(0,a.jsx)(n.li,{children:"Cannot be shared across multiple instances"}),"\n",(0,a.jsx)(n.li,{children:"No built-in replication or backup"}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"postgresql-production",children:"PostgreSQL (Production)"}),"\n",(0,a.jsx)(n.p,{children:"PostgreSQL provides robust, scalable database suitable for production deployments."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "postgresql://user:password@host:5432/webui_db"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export WEB_UI_GATEWAY_DATABASE_URL="postgresql://webui_user:secure_pass@db.example.com:5432/webui_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Advantages:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Production-grade reliability"}),"\n",(0,a.jsx)(n.li,{children:"Horizontal scalability (multiple instances share same database)"}),"\n",(0,a.jsx)(n.li,{children:"Cloud-managed options (AWS RDS, Google Cloud SQL, Azure Database)"}),"\n",(0,a.jsx)(n.li,{children:"Connection pooling support"}),"\n",(0,a.jsx)(n.li,{children:"ACID compliance"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Connection string format:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"postgresql://[user[:password]@][host][:port]/[dbname][?param1=value1&...]\n"})}),"\n",(0,a.jsx)(n.h4,{id:"mysqlmariadb-production",children:"MySQL/MariaDB (Production)"}),"\n",(0,a.jsx)(n.p,{children:"MySQL and MariaDB are popular open-source databases suitable for production."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "mysql+pymysql://user:password@host:3306/webui_db"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export WEB_UI_GATEWAY_DATABASE_URL="mysql+pymysql://webui_user:secure_pass@db.example.com:3306/webui_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Advantages:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Open-source and widely available"}),"\n",(0,a.jsx)(n.li,{children:"Strong community support"}),"\n",(0,a.jsx)(n.li,{children:"Cloud-managed options available"}),"\n",(0,a.jsx)(n.li,{children:"ACID compliance (with InnoDB)"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Connection string format:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"mysql+pymysql://[user[:password]@][host][:port]/[database]\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Agent Mesh uses ",(0,a.jsx)(n.code,{children:"pymysql"})," as the Python driver."]}),"\n",(0,a.jsx)(n.h2,{id:"configuring-agent-session-storage",children:"Configuring Agent Session Storage"}),"\n",(0,a.jsx)(n.p,{children:"Agents use the ADK (Agent Development Kit) session configuration system. Each agent can be configured independently with its own database."}),"\n",(0,a.jsx)(n.h3,{id:"agent-configuration-file",children:"Agent Configuration File"}),"\n",(0,a.jsxs)(n.p,{children:["Add the ",(0,a.jsx)(n.code,{children:"session_service"})," section to your agent's YAML configuration:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "${AGENT_DATABASE_URL, sqlite:///agent-session.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Parameters:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"type"}),": ",(0,a.jsx)(n.code,{children:'"memory"'})," (ephemeral) or ",(0,a.jsx)(n.code,{children:'"sql"'})," (persistent)"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"database_url"}),": Connection string for the agent's database"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"default_behavior"}),": ",(0,a.jsx)(n.code,{children:'"PERSISTENT"'})," (reuse sessions) or ",(0,a.jsx)(n.code,{children:'"RUN_BASED"'})," (new session per run)"]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"environment-variables-1",children:"Environment Variables"}),"\n",(0,a.jsx)(n.p,{children:"Each agent can have its own database credentials:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export AGENT_DATABASE_URL="postgresql://agent_user:agent_pass@host:5432/agent_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Or use a default with fallback in the YAML:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'database_url: "${AGENT_DATABASE_URL, sqlite:///agent-session.db}"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"database-isolation-between-agents",children:"Database Isolation Between Agents"}),"\n",(0,a.jsx)(n.p,{children:"Each agent should have:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Its own separate database (not just a schema)"}),"\n",(0,a.jsx)(n.li,{children:"Its own separate credentials (username and password)"}),"\n",(0,a.jsx)(n.li,{children:"Complete isolation from other agents' data"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Example for two agents:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent A Configuration\nsession_service:\n type: "sql"\n database_url: "${AGENT_A_DATABASE_URL, sqlite:///agent-a.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Agent B Configuration\nsession_service:\n type: "sql"\n database_url: "${AGENT_B_DATABASE_URL, sqlite:///agent-b.db}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# Environment variables for isolation\nexport AGENT_A_DATABASE_URL="postgresql://agent_a_user:pass@host:5432/agent_a_db"\nexport AGENT_B_DATABASE_URL="postgresql://agent_b_user:pass@host:5432/agent_b_db"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"shared-configuration-pattern",children:"Shared Configuration Pattern"}),"\n",(0,a.jsx)(n.p,{children:"If all agents should use the same session storage configuration, use YAML anchors:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'# Shared configuration\nsession_service: &default_session_service\n type: "sql"\n database_url: "${SESSION_DATABASE_URL, sqlite:///session.db}"\n default_behavior: "PERSISTENT"\n\n# Agent references shared config\nagents:\n - name: agent-a\n session_service: *default_session_service\n\n - name: agent-b\n session_service: *default_session_service\n'})}),"\n",(0,a.jsx)(n.h2,{id:"migrating-from-ephemeral-to-persistent",children:"Migrating from Ephemeral to Persistent"}),"\n",(0,a.jsx)(n.p,{children:"Moving from ephemeral mode to persistent mode can be done without losing active sessions."}),"\n",(0,a.jsx)(n.h3,{id:"step-1-configure-webui-gateway-database",children:"Step 1: Configure WebUI Gateway Database"}),"\n",(0,a.jsx)(n.p,{children:"Set the environment variables:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export SESSION_SECRET_KEY="your-secret-key"\nexport WEB_UI_GATEWAY_DATABASE_URL="postgresql://user:pass@host:5432/webui_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Update your WebUI Gateway configuration:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "${WEB_UI_GATEWAY_DATABASE_URL}"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"step-2-configure-agent-databases",children:"Step 2: Configure Agent Databases"}),"\n",(0,a.jsx)(n.p,{children:"For each agent, set the database URL:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export AGENT_DATABASE_URL="postgresql://agent_user:pass@host:5432/agent_db"\n'})}),"\n",(0,a.jsx)(n.p,{children:"Update agent configuration:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'session_service:\n type: "sql"\n database_url: "${AGENT_DATABASE_URL}"\n default_behavior: "PERSISTENT"\n'})}),"\n",(0,a.jsx)(n.h3,{id:"step-3-restart-application",children:"Step 3: Restart Application"}),"\n",(0,a.jsx)(n.p,{children:"When the application restarts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Database migrations run automatically"}),"\n",(0,a.jsx)(n.li,{children:"Tables are created for session storage"}),"\n",(0,a.jsx)(n.li,{children:"No manual database setup required"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Tables created:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"sessions"})," - Session metadata"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"chat_tasks"})," - Conversation messages"]}),"\n",(0,a.jsx)(n.li,{children:"Supporting indexes for performance"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"step-4-verify-migration",children:"Step 4: Verify Migration"}),"\n",(0,a.jsx)(n.p,{children:"Test that persistence is working:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"Start a conversation with an agent"}),"\n",(0,a.jsx)(n.li,{children:"Send a message"}),"\n",(0,a.jsx)(n.li,{children:"Restart the application"}),"\n",(0,a.jsx)(n.li,{children:"Refresh your browser"}),"\n",(0,a.jsx)(n.li,{children:"Verify conversation history is visible"}),"\n",(0,a.jsx)(n.li,{children:"Send another message to the same agent"}),"\n",(0,a.jsx)(n.li,{children:"Verify agent remembers previous conversation context"}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"migration-considerations",children:"Migration Considerations"}),"\n",(0,a.jsx)(n.p,{children:"Existing cookies remain valid. Sessions stored only in cookies before migration continue to work until cookies expire."}),"\n",(0,a.jsx)(n.p,{children:"Database initialization happens once on first startup. Subsequent restarts connect to the existing database."}),"\n",(0,a.jsx)(n.p,{children:"Migration adds new storage without affecting existing sessions."}),"\n",(0,a.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsx)(n.p,{children:"After configuring session storage, you may want to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Configure ",(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/artifact-storage",children:"Artifact Storage"})," for agent-generated files"]}),"\n",(0,a.jsxs)(n.li,{children:["Review ",(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/deployment-options",children:"deployment options"})," for production considerations"]}),"\n",(0,a.jsxs)(n.li,{children:["Set up ",(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability",children:"monitoring and observability"})," to track session activity"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>o});var i=s(6540);const a={},t=i.createContext(a);function r(e){const n=i.useContext(t);return i.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(a):e.components||a:r(e.components),i.createElement(t.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:"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.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)}}}]);
|