solace-agent-mesh 1.6.3__py3-none-any.whl → 1.7.1__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/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.f213fe0c.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 +4 -4
- 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-1762283454666.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.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 +0 -14
- solace_agent_mesh/gateway/http_sse/component.py +17 -56
- 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 +23 -5
- 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.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/METADATA +3 -5
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/RECORD +218 -175
- 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.3b883666.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.ed05b14d.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.a8a75e0b.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761744323675.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761744323675.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.ed05b14d.js.LICENSE.txt → main.f213fe0c.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[9324],{305:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/components/plugins","title":"Plugins","description":"Plugins provide a mechanism to extend the functionality of Agent Mesh in a modular, shareable, and reusable way. The current plugin ecosystem includes agents, gateways, and specialized integrations.","source":"@site/docs/documentation/components/plugins.md","sourceDirName":"documentation/components","slug":"/documentation/components/plugins","permalink":"/solace-agent-mesh/docs/documentation/components/plugins","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/components/plugins.md","tags":[],"version":"current","sidebarPosition":270,"frontMatter":{"title":"Plugins","sidebar_position":270},"sidebar":"docSidebar","previous":{"title":"Gateways","permalink":"/solace-agent-mesh/docs/documentation/components/gateways"},"next":{"title":"Projects","permalink":"/solace-agent-mesh/docs/documentation/components/projects"}}');var s=t(4848),l=t(8453);const a={title:"Plugins",sidebar_position:270},o=void 0,r={},c=[{value:"Official Core Plugins",id:"official-core-plugins",level:3},{value:"Create a Plugin",id:"create-a-plugin",level:2},{value:"Build the Plugin",id:"build-the-plugin",level:3},{value:"Share the Plugin",id:"share-the-plugin",level:3},{value:"Use a Plugin",id:"use-a-plugin",level:2},{value:"Plugin Catalog Dashboard",id:"plugin-catalog-dashboard",level:2},{value:"Agent or Plugin: Which To Use?",id:"agent-or-plugin-which-to-use",level:2},{value:"When To Use a Standalone Agent",id:"when-to-use-a-standalone-agent",level:3},{value:"When To Use an Agent Plugin",id:"when-to-use-an-agent-plugin",level:3},{value:"Recommendation",id:"recommendation",level:3}];function d(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,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"Plugins provide a mechanism to extend the functionality of Agent Mesh in a modular, shareable, and reusable way. The current plugin ecosystem includes agents, gateways, and specialized integrations."}),"\n",(0,s.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,s.jsx)(n.p,{children:"Plugins are modular Python packages that extend Solace the capabilities of Agent Mesh through agents, gateways, and specialized integrations."})}),"\n",(0,s.jsxs)(n.p,{children:["Plugins are packaged as Python modules that can be installed using various package managers (",(0,s.jsx)(n.code,{children:"pip"}),", ",(0,s.jsx)(n.code,{children:"uv"}),", ",(0,s.jsx)(n.code,{children:"poetry"}),", ",(0,s.jsx)(n.code,{children:"conda"}),"). They integrate seamlessly with the A2A protocol and can provide:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Plugins"}),": Specialized agents with domain-specific capabilities"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Gateway Plugins"}),": New interface types for external system integration"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom Plugins"}),": Custom integrations such as HR providers."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"All plugin interactions (create, build, add) are managed through the Agent Mesh CLI."}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["Run ",(0,s.jsx)(n.code,{children:"sam plugin --help"})," to see the list of available commands for plugins."]})}),"\n",(0,s.jsx)(n.h3,{id:"official-core-plugins",children:"Official Core Plugins"}),"\n",(0,s.jsxs)(n.p,{children:["Agent Mesh comes with a set of official core plugins that can be used to extend the functionality of the system. You can find the repository of the official core plugins ",(0,s.jsx)(n.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins",children:"here \ud83d\udd17"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["For more information about how to use the official core plugins, see ",(0,s.jsx)(n.a,{href:"#use-a-plugin",children:"Use Plugins"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"create-a-plugin",children:"Create a Plugin"}),"\n",(0,s.jsxs)(n.p,{children:["To get started, ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/installation",children:"install the Agent Mesh CLI"})," and run the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin create <plugin-name>\n"})}),"\n",(0,s.jsx)(n.p,{children:"Follow the prompts to create a new plugin. A plugin can be one of the following types:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Plugin"}),": Contains custom agents that can be used in a Agent Mesh project."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Gateway Plugin"}),": Contains custom gateways that can be used in a Agent Mesh project."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Custom Plugin"}),": Contains custom integrations such as HR providers or other specialized functionality."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The Agent Mesh CLI creates a directory with the provided name and the following structure:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"plugin-name/\n\u251c\u2500 config.yaml\n\u251c\u2500 src/\n\u2502 \u251c\u2500 __init__.py\n\u2502 \u251c\u2500 [...Other type specific python files]\n\u251c\u2500 .gitignore\n\u251c\u2500 pyproject.toml\n\u251c\u2500 README.md\n"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"src"})," directory contains the python source code."]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.code,{children:"config.yaml"})," file holds the configuration for the plugin, and how to be used in a Agent Mesh application."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the plugin is created, you can start customizing the config.yaml or the python files."}),"\n",(0,s.jsx)(n.h3,{id:"build-the-plugin",children:"Build the Plugin"}),"\n",(0,s.jsxs)(n.p,{children:["Building the plugin creates a Python wheel package that can be installed using ",(0,s.jsx)(n.code,{children:"pip"})," or other package managers."]}),"\n",(0,s.jsxs)(n.p,{children:["Python ",(0,s.jsx)(n.code,{children:"build"})," package must be installed already since ",(0,s.jsx)(n.code,{children:"sam plugin build"})," command uses ",(0,s.jsx)(n.code,{children:"build"})," package, if not, run ",(0,s.jsx)(n.code,{children:"pip install build"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"To build the plugin, run the following Agent Mesh CLI command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin build\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The plugin uses the standard ",(0,s.jsx)(n.code,{children:"pyproject.toml"})," file to build the package."]}),"\n",(0,s.jsx)(n.h3,{id:"share-the-plugin",children:"Share the Plugin"}),"\n",(0,s.jsxs)(n.p,{children:["To share the plugin, you can upload the wheel package to a package repository or share the wheel package directly, or any other valid way to share a ",(0,s.jsx)(n.code,{children:"pyproject"})," project."]}),"\n",(0,s.jsx)(n.h2,{id:"use-a-plugin",children:"Use a Plugin"}),"\n",(0,s.jsxs)(n.p,{children:["To use a plugin in your project, use the ",(0,s.jsx)(n.code,{children:"plugin add"})," command, which performs two steps under-the-hood:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Locates the plugin or installs the plugin package using a Python package manager (like ",(0,s.jsx)(n.code,{children:"pip"})," or ",(0,s.jsx)(n.code,{children:"uv"}),")"]}),"\n",(0,s.jsx)(n.li,{children:"Creates a component instance based on the plugin"}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME>\n"})}),"\n",(0,s.jsx)(n.p,{children:"where:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"<COMPONENT_NAME>"})," is the name you choose for the component instance in your project."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"<PLUGIN_NAME>"}),", you can use:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Name of the plugin as published to a package manager like ",(0,s.jsx)(n.code,{children:"pypi"}),", for example ",(0,s.jsx)(n.code,{children:"my-plugin"})]}),"\n",(0,s.jsx)(n.li,{children:"Name of the plugin that has been already installed into your Python environment."}),"\n",(0,s.jsxs)(n.li,{children:["A local path to the plugin directory, for example ",(0,s.jsx)(n.code,{children:"./my-plugin"})]}),"\n",(0,s.jsxs)(n.li,{children:["A path to a wheel package, for example ",(0,s.jsx)(n.code,{children:"./my-plugin/dist/my_plugin-0.1.0-py3-none-any.whl"})]}),"\n",(0,s.jsxs)(n.li,{children:["A URL to a git repository, for example ",(0,s.jsx)(n.code,{children:"git+https://github.com/<USERNAME>/<REPOSITORY>"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the plugin is in a subdirectory of the repository, you can specify the subdirectory using the ",(0,s.jsx)(n.code,{children:"git+https://github.com/<USERNAME>/<REPOSITORY>#subdirectory=<PLUGIN_NAME>"})," syntax."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CLI handles both steps automatically, or you can manage the plugin installation yourself using your preferred Python package manager."}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["You can also customize the python package manager command used to install the plugin by setting the ",(0,s.jsx)(n.code,{children:"SAM_PLUGIN_INSTALL_COMMAND"})," environment variable or passing the ",(0,s.jsx)(n.code,{children:"--install-command"})," option to the ",(0,s.jsx)(n.code,{children:"plugin add"})," command.\nFor example, to use ",(0,s.jsx)(n.code,{children:"uv"})," as the package manager, you can run:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}"\n'})}),(0,s.jsx)(n.p,{children:"or"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> --install-command "uv pip install {package}"\n'})})]}),"\n",(0,s.jsxs)(n.p,{children:["This command adds the plugin instance configuration to your ",(0,s.jsx)(n.code,{children:"configs"})," directory."]}),"\n",(0,s.jsx)(n.p,{children:"Depending on the plugin, you may need to update the newly added plugin configuration file. Follow the instructions provided by the plugin author for any specific configurations."}),"\n",(0,s.jsx)(n.h2,{id:"plugin-catalog-dashboard",children:"Plugin Catalog Dashboard"}),"\n",(0,s.jsxs)(n.p,{children:["You can manage available plugins with the ",(0,s.jsx)(n.code,{children:"plugin catalog"})," command, which launches a user-friendly interface."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin catalog\n"})}),"\n",(0,s.jsx)(n.h2,{id:"agent-or-plugin-which-to-use",children:"Agent or Plugin: Which To Use?"}),"\n",(0,s.jsx)(n.p,{children:"In simple terms, plugins of type agent are just packaged agents. However, there are distinct advantages to each approach, and choosing the right one depends on your use case."}),"\n",(0,s.jsx)(n.p,{children:"Here\u2019s a detailed comparison to help you decide."}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{style:{textAlign:"left"},children:"Feature"}),(0,s.jsxs)(n.th,{style:{textAlign:"left"},children:["Standalone Agent (",(0,s.jsx)(n.code,{children:"sam add agent"}),")"]}),(0,s.jsxs)(n.th,{style:{textAlign:"left"},children:["Agent Plugin (",(0,s.jsx)(n.code,{children:"sam plugin create"}),")"]})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Creation"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"A single command creates a configuration file in your project."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Creates a complete, standard Python project structure."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Structure"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Consists of a YAML configuration file and associated Python tool files within a Agent Mesh project."}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["A self-contained Python package with ",(0,s.jsx)(n.code,{children:"pyproject.toml"}),", a ",(0,s.jsx)(n.code,{children:"src"})," directory, and configuration templates."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Packaging"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Not packaged. It exists as a component within a larger Agent Mesh project."}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["Packaged into a standard Python wheel (",(0,s.jsx)(n.code,{children:".whl"}),") file using ",(0,s.jsx)(n.code,{children:"sam plugin build"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Distribution"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Shared by copying files or sharing the entire project."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Easily distributed as a wheel file, via a Git repository, or published to a package index like PyPI."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Reusability"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Primarily for use within the project where it was created."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Designed for high reusability across different projects, teams, and communities."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Installation"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"No installation needed. The agent is configured and run as part of the main project."}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["Installed into the Python environment using ",(0,s.jsx)(n.code,{children:"sam plugin add"}),", which handles the package installation."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Versioning"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Versioned along with the main project."}),(0,s.jsxs)(n.td,{style:{textAlign:"left"},children:["Can be versioned independently according to Python packaging standards (e.g., ",(0,s.jsx)(n.code,{children:"v0.1.0"}),", ",(0,s.jsx)(n.code,{children:"v0.2.0"}),")."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{style:{textAlign:"left"},children:(0,s.jsx)(n.strong,{children:"Development"})}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Simple and direct. Edit files and run. Ideal for rapid prototyping."}),(0,s.jsx)(n.td,{style:{textAlign:"left"},children:"Involves a build/install cycle. Better for structured, long-term development."})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"when-to-use-a-standalone-agent",children:"When To Use a Standalone Agent"}),"\n",(0,s.jsx)(n.p,{children:"Create a standalone agent when:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"You need to quickly test an idea or build a proof-of-concept."}),"\n",(0,s.jsx)(n.li,{children:"The agent is tightly coupled to a single project and is not intended for reuse."}),"\n",(0,s.jsx)(n.li,{children:"You want the most straightforward path to adding a simple agent without the overhead of a full package structure."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"when-to-use-an-agent-plugin",children:"When To Use an Agent Plugin"}),"\n",(0,s.jsx)(n.p,{children:"Create an agent as a plugin when:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"You plan to use the same agent in multiple projects."}),"\n",(0,s.jsx)(n.li,{children:"You want to share your agent with other developers, teams, or the open-source community."}),"\n",(0,s.jsx)(n.li,{children:"You are building a robust, production-ready agent that benefits from a formal package structure, dependency management, and versioning."}),"\n",(0,s.jsx)(n.li,{children:"You are building a collection of standardized agents for your organization."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"recommendation",children:"Recommendation"}),"\n",(0,s.jsx)(n.p,{children:"The choice of how to build your agent depends on your goals and the requirements of your project:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Standalone Agents"})," should be viewed as tactical tools for rapid, isolated prototyping. They serve immediate, project-specific needs but do not contribute to a scalable, long-term asset library."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Agent Plugins"})," are the foundation for building a robust, governable, and reusable AI ecosystem. This model treats AI capabilities as enterprise assets, promoting standardization, reducing redundant development costs, and accelerating innovation across the organization. For any capability intended for broader use or long-term value, the plugin framework is the mandated path to maximize return on investment and ensure architectural integrity."]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,l.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:()=>a,x:()=>o});var i=t(6540);const s={},l=i.createContext(s);function a(e){const n=i.useContext(l);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(s):e.components||s:a(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[5236],{4473:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>r,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/deploying/deployment-options","title":"Choosing Deployment Options","description":"Agent Mesh offers flexible deployment options designed to meet different operational requirements. Understanding these options helps you choose the right approach for your specific environment and scale needs.","source":"@site/docs/documentation/deploying/deployment-options.md","sourceDirName":"documentation/deploying","slug":"/documentation/deploying/deployment-options","permalink":"/solace-agent-mesh/docs/documentation/deploying/deployment-options","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/deploying/deployment-options.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Choosing Deployment Options","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Deploying Agent Mesh","permalink":"/solace-agent-mesh/docs/documentation/deploying/"},"next":{"title":"Kubernetes","permalink":"/solace-agent-mesh/docs/documentation/deploying/kubernetes-deployment"}}');var s=t(4848),o=t(8453);const r={title:"Choosing Deployment Options",sidebar_position:10},a="Choosing Deployment Options",l={},c=[{value:"Development Environment",id:"development-environment",level:2},{value:"Production Environment",id:"production-environment",level:2},{value:"Deploying with Docker",id:"deploying-with-docker",level:3},{value:"Deploying with Kubernetes",id:"deploying-with-kubernetes",level:3},{value:"Separating and Scaling Components",id:"separating-and-scaling-components",level:3},{value:"Managing Storage Requirements",id:"managing-storage-requirements",level:3},{value:"Implementing Security Best Practices",id:"implementing-security-best-practices",level:3},{value:"Configuring Solace Event Broker",id:"configuring-solace-event-broker",level:3},{value:"Setting up Queue Templates",id:"setting-up-queue-templates",level:3}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"choosing-deployment-options",children:"Choosing Deployment Options"})}),"\n",(0,s.jsx)(n.p,{children:"Agent Mesh offers flexible deployment options designed to meet different operational requirements. Understanding these options helps you choose the right approach for your specific environment and scale needs."}),"\n",(0,s.jsx)(n.h2,{id:"development-environment",children:"Development Environment"}),"\n",(0,s.jsx)(n.p,{children:"During development, simplicity and rapid iteration are key priorities. The Agent Mesh CLI provides a streamlined way to run your entire project as a single application, making it easy to test changes and debug issues locally."}),"\n",(0,s.jsxs)(n.p,{children:["The development setup automatically loads environment variables from your configuration file (typically a ",(0,s.jsx)(n.code,{children:".env"})," file at the project root), eliminating the need for complex environment management:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sam run\n"})}),"\n",(0,s.jsx)(n.p,{children:"This command starts all configured components together, providing immediate feedback and allowing you to see how different agents interact within your mesh."}),"\n",(0,s.jsx)(n.h2,{id:"production-environment",children:"Production Environment"}),"\n",(0,s.jsx)(n.p,{children:"Production deployments require different considerations than development environments. You need reproducible builds, scalable infrastructure, and robust monitoring capabilities. Containerization addresses these requirements by providing consistent runtime environments and enabling modern orchestration platforms."}),"\n",(0,s.jsx)(n.p,{children:"We recommend using Docker for single-node deployments or Kubernetes for multi-node, scalable deployments. These technologies ensure your application runs consistently across different environments and can scale to meet demand."}),"\n",(0,s.jsx)(n.admonition,{title:"Platform Compatibility",type:"note",children:(0,s.jsxs)(n.p,{children:["If your host system architecture is not ",(0,s.jsx)(n.code,{children:"linux/amd64"}),", add the ",(0,s.jsx)(n.code,{children:"--platform linux/amd64"})," flag when you run the container to ensure compatibility with the pre-built images."]})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-with-docker",children:"Deploying with Docker"}),"\n",(0,s.jsx)(n.p,{children:"Docker provides an excellent foundation for production deployments because it packages your application with all its dependencies into a portable container. This approach ensures consistent behavior across different environments and simplifies deployment processes."}),"\n",(0,s.jsx)(n.p,{children:"The following Dockerfile demonstrates how to containerize an Agent Mesh project:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-Dockerfile",children:'FROM solace/solace-agent-mesh:latest\nWORKDIR /app\n\n# Install Python dependencies\nCOPY ./requirements.txt /app/requirements.txt\nRUN python3.11 -m pip install --no-cache-dir -r /app/requirements.txt\n\n# Copy project files\nCOPY . /app\n\nCMD ["run", "--system-env"]\n\n# To run one specific component, use:\n# CMD ["run", "--system-env", "configs/agents/main_orchestrator.yaml"]\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["To optimize build performance and security, create a ",(0,s.jsx)(n.code,{children:".dockerignore"})," file that excludes unnecessary files from the Docker build context:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:".env\n*.log\ndist\n.git\n.vscode\n.DS_Store\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-with-kubernetes",children:"Deploying with Kubernetes"}),"\n",(0,s.jsx)(n.p,{children:"Kubernetes excels at managing containerized applications at scale, providing features like automatic scaling, rolling updates, and self-healing capabilities. When your Agent Mesh deployment needs to handle varying loads or requires high availability, Kubernetes becomes the preferred orchestration platform."}),"\n",(0,s.jsxs)(n.p,{children:["Agent Mesh provides Helm charts for Kubernetes deployments that handle resource management, scaling, and configuration. For prerequisites, Helm setup, and production configurations, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/kubernetes-deployment",children:"Kubernetes"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"separating-and-scaling-components",children:"Separating and Scaling Components"}),"\n",(0,s.jsx)(n.p,{children:"A microservices approach to deployment offers significant advantages for production systems. By splitting your Agent Mesh components into separate containers, you achieve better fault isolation, independent scaling, and more granular resource management."}),"\n",(0,s.jsx)(n.p,{children:"This architectural pattern ensures that if one component experiences issues, the rest of your system continues operating normally. When the failed component restarts, it automatically rejoins the mesh through the Solace event broker, maintaining system resilience."}),"\n",(0,s.jsx)(n.p,{children:"To implement component separation:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Reuse the same Docker image"}),": Your base container image remains consistent across all components, simplifying maintenance and ensuring compatibility."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Customize startup commands"}),": Each container runs only the components it needs by specifying different configuration files in the startup command."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Scale independently"}),": Components with higher resource demands or traffic can be scaled separately, optimizing resource utilization and cost."]}),"\n",(0,s.jsx)(n.p,{children:"For example, you might run your main orchestrator in one deployment while scaling your specialized tool agents in separate deployments based on demand."}),"\n",(0,s.jsx)(n.h3,{id:"managing-storage-requirements",children:"Managing Storage Requirements"}),"\n",(0,s.jsx)(n.p,{children:"When deploying multiple containers, shared storage becomes critical for maintaining consistency across your Agent Mesh deployment. All container instances must access the same storage location with identical configurations to ensure proper operation."}),"\n",(0,s.jsx)(n.admonition,{title:"Shared Storage Requirement",type:"warning",children:(0,s.jsx)(n.p,{children:"If using multiple containers, ensure all instances access the same storage with identical configurations. Inconsistent storage configurations can lead to data synchronization issues and unpredictable behavior."})}),"\n",(0,s.jsx)(n.p,{children:"Consider using persistent volumes in Kubernetes or shared file systems in Docker deployments to meet this requirement."}),"\n",(0,s.jsx)(n.h3,{id:"implementing-security-best-practices",children:"Implementing Security Best Practices"}),"\n",(0,s.jsx)(n.p,{children:"Production deployments require robust security measures to protect sensitive data and ensure system integrity. Implementing these practices helps safeguard your Agent Mesh deployment against common security threats."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Environment Variables and Secrets Management"}),": Never store sensitive information like API keys, passwords, or certificates in ",(0,s.jsx)(n.code,{children:".env"})," files or container images. Instead, use dedicated secret management solutions such as AWS Secrets Manager, HashiCorp Vault, or Kubernetes Secrets. These tools provide encryption at rest, access controls, and audit trails for sensitive data."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"TLS Encryption"}),": All communication channels should use TLS encryption to protect data in transit. This includes communication between Agent Mesh components and connections to the Solace event broker. TLS prevents eavesdropping and ensures data integrity during transmission."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Container Security"}),": Maintain security throughout your container lifecycle by regularly updating base images to include the latest security patches. Implement security scanning tools like Trivy or Clair in your CI/CD pipeline to identify vulnerabilities before deployment. Additionally, run containers with minimal privileges and avoid running processes as root when possible."]}),"\n",(0,s.jsx)(n.h3,{id:"configuring-solace-event-broker",children:"Configuring Solace Event Broker"}),"\n",(0,s.jsx)(n.p,{children:"The Solace event broker serves as the communication backbone for your agent mesh, handling all message routing and delivery between components. For production environments, using a Solace Cloud-managed event broker provides significant advantages over self-managed installations."}),"\n",(0,s.jsx)(n.p,{children:"Solace Cloud-managed event brokers offer built-in high availability, automatic scaling, security updates, and professional support. These managed services eliminate the operational overhead of maintaining event broker infrastructure while providing enterprise-grade reliability and performance."}),"\n",(0,s.jsxs)(n.p,{children:["For more information about cloud-managed options, see ",(0,s.jsx)(n.a,{href:"https://solace.com/products/event-broker/",children:"Solace Cloud"}),". For detailed configuration instructions, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations#event-broker-connection",children:"Configuring the Event Broker Connection"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"setting-up-queue-templates",children:"Setting up Queue Templates"}),"\n",(0,s.jsxs)(n.p,{children:["When the ",(0,s.jsx)(n.code,{children:"app.broker.temporary_queue"})," parameter is set to ",(0,s.jsx)(n.code,{children:"true"})," (default), the system uses ",(0,s.jsx)(n.a,{href:"https://docs.solace.com/Messaging/Guaranteed-Msg/Endpoints.htm#temporary-endpoints",children:"temporary endpoints"})," for A2A communication. Temporary queues are automatically created and deleted by the broker, which simplifies management and removes the need for manual cleanup. However, temporary queues do not support multiple client connections to the same queue, which may be limiting in scenarios where you run multiple instances of the same agent or need to start a new instance while an old one is still running."]}),"\n",(0,s.jsxs)(n.p,{children:["If you set ",(0,s.jsx)(n.code,{children:"temporary_queue"})," to ",(0,s.jsx)(n.code,{children:"false"}),", the system will create a durable queue for the client. Durable queues persist beyond the lifetime of a client connection, allowing multiple clients to connect to the same queue and ensuring messages are not lost if the client disconnects. However, this requires manual management of queues, including cleanup of unused ones."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For production environments that are container-managed (for example, Kubernetes), we recommend setting ",(0,s.jsx)(n.code,{children:"temporary_queue"})," to ",(0,s.jsx)(n.code,{children:"false"})," by setting the environment variable ",(0,s.jsx)(n.code,{children:"USE_TEMPORARY_QUEUES=false"}),".",(0,s.jsx)(n.br,{}),"\n","Using temporary queues in these environments can cause startup issues, since a new container may fail to connect if the previous instance is still running and holding the queue. Durable queues avoid this by allowing multiple agent instances to share the same queue."]})}),"\n",(0,s.jsxs)(n.p,{children:["To prevent messages from piling up in a durable queue when an agent is not running, the queue should be configured with a message TTL (time-to-live) and the ",(0,s.jsx)(n.strong,{children:"Respect Message TTL"})," option enabled. To apply these settings automatically for all new queues, you can create a ",(0,s.jsx)(n.a,{href:"https://docs.solace.com/Messaging/Guaranteed-Msg/Configuring-Endpoint-Templates.htm",children:"Queue Template"})," for your Solace Agent Mesh clients."]}),"\n",(0,s.jsx)(n.p,{children:"To create a queue template in the Solace Cloud Console:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Navigate to ",(0,s.jsx)(n.strong,{children:"Message VPNs"})," and select your VPN."]}),"\n",(0,s.jsxs)(n.li,{children:["Go to the ",(0,s.jsx)(n.strong,{children:"Queues"})," page."]}),"\n",(0,s.jsxs)(n.li,{children:["Open the ",(0,s.jsx)(n.strong,{children:"Templates"})," tab."]}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"+ Queue Template"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Use the following settings for the template:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Queue Name Filter"})," = ",(0,s.jsx)(n.code,{children:"{NAMESPACE}q/a2a/>"}),(0,s.jsx)(n.br,{}),"\n","(Replace ",(0,s.jsx)(n.code,{children:"{NAMESPACE}"})," with the namespace defined in your configuration, for example, ",(0,s.jsx)(n.code,{children:"sam/"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Respect TTL"})," = ",(0,s.jsx)(n.code,{children:"true"}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.em,{children:"(Under: Advanced Settings > Message Expiry)"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Maximum TTL (sec)"})," = ",(0,s.jsx)(n.code,{children:"18000"}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.em,{children:"(Under: Advanced Settings > Message Expiry)"})]}),"\n"]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Queue templates are only applied when a new queue is created from the messaging client.",(0,s.jsx)(n.br,{}),"\n","If you have already been running SAM with ",(0,s.jsx)(n.code,{children:"temporary_queue"})," set to ",(0,s.jsx)(n.code,{children:"false"}),", your durable queues were created before the template existed.",(0,s.jsx)(n.br,{}),"\n","To apply TTL settings to those queues, either:"]}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Enable ",(0,s.jsx)(n.strong,{children:"TTL"})," and ",(0,s.jsx)(n.strong,{children:"Respect TTL"})," manually in the Solace console on each queue, or"]}),"\n",(0,s.jsx)(n.li,{children:"Delete the existing queues and restart SAM to have them recreated automatically using the new template."}),"\n"]})]})]})}function u(e={}){const{wrapper:n}={...(0,o.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:()=>r,x:()=>a});var i=t(6540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);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(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1445],{3190:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>g,frontMatter:()=>a,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"documentation/deploying/debugging","title":"Diagnosing and Resolving Problems","description":"Effective debugging in Agent Mesh requires a systematic approach that leverages the platform\'s distributed architecture. Because your system consists of multiple agents communicating through a Solace event broker, issues can arise at various levels\u2014from individual agent logic to inter-component communication patterns.","source":"@site/docs/documentation/deploying/debugging.md","sourceDirName":"documentation/deploying","slug":"/documentation/deploying/debugging","permalink":"/solace-agent-mesh/docs/documentation/deploying/debugging","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/deploying/debugging.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"title":"Diagnosing and Resolving Problems","sidebar_position":30},"sidebar":"docSidebar","previous":{"title":"Monitoring Your Agent Mesh","permalink":"/solace-agent-mesh/docs/documentation/deploying/observability"},"next":{"title":"Logging","permalink":"/solace-agent-mesh/docs/documentation/deploying/logging"}}');var s=i(4848),o=i(8453);const a={title:"Diagnosing and Resolving Problems",sidebar_position:30},r="Diagnosing and Resolving Problems",l={},c=[{value:"Isolating Components",id:"isolating-components",level:2},{value:"Examining STIM Files",id:"examining-stim-files",level:2},{value:"Monitoring Event Broker Activity",id:"monitoring-event-broker-activity",level:2},{value:"Using Debug Mode",id:"using-debug-mode",level:2},{value:"Setting Up VSCode Debugging",id:"setting-up-vscode-debugging",level:3},{value:"Invoking Agents Directly",id:"invoking-agents-directly",level:2},{value:"Using Tools for Direct Message Testing",id:"using-tools-for-direct-message-testing",level:3},{value:"Formatting Messages for Direct Invocation",id:"formatting-messages-for-direct-invocation",level:3},{value:"Analyzing System Logs",id:"analyzing-system-logs",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"diagnosing-and-resolving-problems",children:"Diagnosing and Resolving Problems"})}),"\n",(0,s.jsx)(n.p,{children:"Effective debugging in Agent Mesh requires a systematic approach that leverages the platform's distributed architecture. Because your system consists of multiple agents communicating through a Solace event broker, issues can arise at various levels\u2014from individual agent logic to inter-component communication patterns."}),"\n",(0,s.jsxs)(n.p,{children:["The key to successful debugging lies in understanding where problems might occur and having the right tools to investigate each layer of your system. Agent Mesh provides comprehensive observability features that serve as your foundation for debugging activities. For detailed information about these monitoring capabilities, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability",children:"Observability"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This guide presents proven debugging strategies arranged from simple isolation techniques to advanced diagnostic methods. Each approach targets different types of issues, allowing you to choose the most effective method based on your specific situation."}),"\n",(0,s.jsx)(n.h2,{id:"isolating-components",children:"Isolating Components"}),"\n",(0,s.jsx)(n.p,{children:"When facing complex issues in a multi-agent system, isolation becomes your most powerful debugging technique. By running only the components directly related to your problem, you eliminate variables and focus your investigation on the most likely sources of trouble."}),"\n",(0,s.jsx)(n.p,{children:"Component isolation works because it reduces system complexity to manageable levels. Instead of trying to understand interactions across dozens of agents, you can focus on a small subset and verify their behavior in controlled conditions."}),"\n",(0,s.jsx)(n.p,{children:"The Agent Mesh CLI provides precise control over which components run in your debugging session. You can specify exactly which configuration files to load, creating a minimal environment that includes only the agents you need to investigate."}),"\n",(0,s.jsx)(n.p,{children:"For example, if you're debugging an issue with a specific tool integration, you might run only the orchestrator and the problematic tool agent:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sam run configs/agents/my_tool_1.yaml configs/agents/my_tool_2.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command creates a focused debugging environment that includes only the agents defined in ",(0,s.jsx)(n.code,{children:"my_tool_1.yaml"})," and ",(0,s.jsx)(n.code,{children:"my_tool_2.yaml"}),". By eliminating unrelated components, you reduce log noise and make it easier to trace the specific interactions that might be causing problems."]}),"\n",(0,s.jsx)(n.p,{children:"This isolation approach is particularly effective when you suspect issues with agent-to-agent communication, configuration problems, or logic errors within specific agents."}),"\n",(0,s.jsx)(n.h2,{id:"examining-stim-files",children:"Examining STIM Files"}),"\n",(0,s.jsx)(n.p,{children:"STIM files serve as your detailed forensic evidence when debugging complex issues. These comprehensive traces capture every aspect of how requests flow through your system, making them invaluable for understanding problems that span multiple agents or involve timing-sensitive interactions."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability#examining-stimulus-logs",children:"STIM files"})," provide the most complete picture available of stimulus lifecycles. Unlike real-time monitoring tools that show current activity, STIM files preserve historical data that you can analyze repeatedly and share with team members for collaborative debugging."]}),"\n",(0,s.jsxs)(n.p,{children:["Each ",(0,s.jsx)(n.code,{children:".stim"})," file contains a complete record of all Solace event broker events related to a single stimulus, from the initial user request through every agent interaction to the final response delivery. This comprehensive coverage makes STIM files particularly useful for debugging issues that involve:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Multi-agent workflows where the problem might occur at any step"}),"\n",(0,s.jsx)(n.li,{children:"Timing-related issues where sequence and duration matter"}),"\n",(0,s.jsx)(n.li,{children:"Intermittent problems that are difficult to reproduce in real-time"}),"\n",(0,s.jsx)(n.li,{children:"Performance bottlenecks that require detailed timing analysis"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When examining STIM files, look for patterns in agent response times, unexpected message routing, or missing interactions that should have occurred based on your system design."}),"\n",(0,s.jsx)(n.h2,{id:"monitoring-event-broker-activity",children:"Monitoring Event Broker Activity"}),"\n",(0,s.jsx)(n.p,{children:"Real-time Solace event broker monitoring provides immediate insights into your system's communication patterns and helps identify issues as they occur. This approach complements STIM file analysis by giving you live visibility into message flows and event interactions."}),"\n",(0,s.jsx)(n.p,{children:"Broker-level monitoring is particularly valuable because it shows the actual communication happening between components, regardless of how agents are configured or what they report about their own status. This ground-truth perspective helps identify discrepancies between expected and actual behavior."}),"\n",(0,s.jsxs)(n.p,{children:["For comprehensive guidance on Solace event broker monitoring techniques and tools, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability#monitoring-event-broker-activity",children:"Monitoring Event Broker Activity"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"using-debug-mode",children:"Using Debug Mode"}),"\n",(0,s.jsx)(n.p,{children:"Interactive debugging provides the deepest level of investigation capability by allowing you to pause execution and examine system state in real-time. Because Agent Mesh is built on Python, you can leverage standard Python debugging tools and IDE features to step through code execution and inspect variables."}),"\n",(0,s.jsx)(n.p,{children:"This approach is most effective when you've already isolated the problem to specific components and need to understand exactly what's happening within agent logic or framework code."}),"\n",(0,s.jsx)(n.h3,{id:"setting-up-vscode-debugging",children:"Setting Up VSCode Debugging"}),"\n",(0,s.jsx)(n.p,{children:"VSCode provides an excellent debugging environment for Agent Mesh development. The integrated debugger allows you to set breakpoints, step through code execution, and inspect variables in real-time, making it easier to understand complex agent interactions and identify logic errors."}),"\n",(0,s.jsxs)(n.p,{children:["Configure debugging by creating or updating your ",(0,s.jsx)(n.code,{children:".vscode/launch.json"})," file:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "version": "0.2.0",\n "configurations": [\n {\n "name": "sam-debug",\n "type": "debugpy",\n "request": "launch",\n "module": "solace_agent_mesh.cli.main",\n "console": "integratedTerminal",\n "envFile": "${workspaceFolder}/.env",\n "args": [\n "run",\n "configs/agents/main_orchestrator.yaml",\n "configs/gateways/webui.yaml"\n // Add any other components you want to run here\n ],\n "justMyCode": false\n }\n ]\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:'"justMyCode": false'})," setting is particularly important because it allows you to step into Agent Mesh framework code, not just your custom agent logic. This capability is valuable when debugging issues that might involve framework behavior or when you need to understand how your agents interact with the underlying platform."]}),"\n",(0,s.jsx)(n.p,{children:"To start a debugging session:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Open the ",(0,s.jsx)(n.strong,{children:"RUN AND DEBUG"})," panel in the left sidebar"]}),"\n",(0,s.jsxs)(n.li,{children:["Select ",(0,s.jsx)(n.code,{children:"sam-debug"})," from the configuration dropdown"]}),"\n",(0,s.jsxs)(n.li,{children:["Click the ",(0,s.jsx)(n.strong,{children:"Play"})," button to launch your system in debug mode"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once running, you can set breakpoints in your agent code, framework files, or any Python modules your system uses. When execution hits a breakpoint, you can inspect variable states, evaluate expressions, and step through code line by line to understand exactly what's happening."}),"\n",(0,s.jsx)(n.h2,{id:"invoking-agents-directly",children:"Invoking Agents Directly"}),"\n",(0,s.jsx)(n.p,{children:"Direct agent invocation provides a powerful technique for isolating and testing individual agents outside of normal user workflows. This approach helps you verify that specific agents work correctly in isolation, making it easier to determine whether problems lie within agent logic or in the broader system interactions."}),"\n",(0,s.jsx)(n.p,{children:"You can invoke agents directly through two primary methods: using the web UI's agent selection dropdown for quick testing, or sending messages directly through the Solace event broker for more controlled testing scenarios."}),"\n",(0,s.jsx)(n.p,{children:"The Solace event broker-based approach gives you complete control over message content and timing, making it ideal for testing edge cases, error conditions, or specific message formats that might be difficult to generate through normal user interactions."}),"\n",(0,s.jsx)(n.h3,{id:"using-tools-for-direct-message-testing",children:"Using Tools for Direct Message Testing"}),"\n",(0,s.jsx)(n.p,{children:"Several tools facilitate direct message testing, each suited to different debugging scenarios:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"https://marketplace.visualstudio.com/items?itemName=solace-tools.solace-try-me-vsc-extension",children:"Solace Try Me VSCode Extension"})}),": Integrates directly into your development environment, making it convenient to test messages without switching contexts. This tool is particularly useful during active development when you need to quickly verify agent behavior."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.a,{href:"https://github.com/SolaceLabs/solace-tryme-cli",children:"Solace Try Me (STM) CLI Tool"})}),": Provides command-line access for scripted testing and automation. This tool excels in scenarios where you need to send multiple test messages or integrate testing into automated workflows."]}),"\n",(0,s.jsx)(n.h3,{id:"formatting-messages-for-direct-invocation",children:"Formatting Messages for Direct Invocation"}),"\n",(0,s.jsx)(n.p,{children:"Understanding the exact message format is crucial for successful direct agent testing. The following structure represents how the Agent Mesh framework expects messages to be formatted:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Topic Structure"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[NAME_SPACES]a2a/v1/agent/request/<agent_name>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"<agent_name>"})," with the specific agent you want to test. The namespace prefix should match your system configuration."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Required User Properties"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"userId: test-0000\nclientId: test-0000\nreplyTo: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000\na2aUserConfig: {}\n"})}),"\n",(0,s.jsx)(n.p,{children:"These properties provide essential context that agents expect, including user identification and response routing information."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Message Payload"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": "000000000",\n "method": "tasks/sendSubscribe",\n "params": {\n "id": "task-0000000",\n "sessionId": "web-session-00000000",\n "message": {\n "role": "user",\n "parts": [\n {\n "type": "text",\n "text": "Hello World!"\n }\n ]\n },\n "acceptedOutputModes": [\n "text"\n ],\n "metadata": {\n "system_purpose": "The system is an AI Chatbot with agentic capabilities. It uses the agents available to provide information, reasoning and general assistance for the users in this system. **Always return useful artifacts and files that you create to the user.** Provide a status update before each tool call. Your external name is Agent Mesh.\\n",\n "response_format": "Responses should be clear, concise, and professionally toned. Format responses to the user in Markdown using appropriate formatting.\\n"\n }\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Expected Response Topic"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000\n"})}),"\n",(0,s.jsx)(n.p,{children:"Subscribe to this topic to receive the agent's response. The response will follow the same JSON-RPC format and contain the agent's output."}),"\n",(0,s.jsx)(n.p,{children:"By sending carefully crafted requests and observing responses, you can verify agent behavior in complete isolation. This technique helps distinguish between agent-specific issues and broader system problems, significantly streamlining your debugging process."}),"\n",(0,s.jsx)(n.h2,{id:"analyzing-system-logs",children:"Analyzing System Logs"}),"\n",(0,s.jsx)(n.p,{children:"System logs serve as your comprehensive record of application behavior, capturing everything from routine operations to error conditions. These logs provide a different perspective than STIM files or Solace event broker monitoring\u2014they focus on internal application state and framework behavior rather than message flows."}),"\n",(0,s.jsx)(n.p,{children:"Understanding system logs becomes crucial when debugging issues related to agent initialization, configuration problems, or internal framework errors that might not be visible through other observability tools."}),"\n",(0,s.jsxs)(n.p,{children:["For detailed information about configuring system logs, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/logging",children:"Logging Configuration"}),"."]})]})}function g(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>a,x:()=>r});var t=i(6540);const s={},o=t.createContext(s);function a(e){const n=t.useContext(o);return t.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(s):e.components||s:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[3870],{6247:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"documentation/installing-and-configuring/artifact-storage","title":"Artifact Storage","description":"This guide explains how to configure storage for artifacts\u2014files and data created by your agents\u2014from development to production deployments.","source":"@site/docs/documentation/installing-and-configuring/artifact-storage.md","sourceDirName":"documentation/installing-and-configuring","slug":"/documentation/installing-and-configuring/artifact-storage","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/artifact-storage","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/installing-and-configuring/artifact-storage.md","tags":[],"version":"current","sidebarPosition":360,"frontMatter":{"title":"Artifact Storage","sidebar_position":360},"sidebar":"docSidebar","previous":{"title":"Session Storage","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage"},"next":{"title":"Developing with Agent Mesh","permalink":"/solace-agent-mesh/docs/documentation/developing/"}}');var t=s(4848),r=s(8453);const a={title:"Artifact Storage",sidebar_position:360},c="Configuring Artifact Storage",o={},l=[{value:"Understanding Artifacts",id:"understanding-artifacts",level:2},{value:"Artifact Storage vs Session Storage",id:"artifact-storage-vs-session-storage",level:3},{value:"Artifact Storage Backends",id:"artifact-storage-backends",level:2},{value:"Filesystem Storage (Default)",id:"filesystem-storage-default",level:3},{value:"S3 (AWS)",id:"s3-aws",level:3},{value:"S3-Compatible API Endpoint",id:"s3-compatible-api-endpoint",level:3},{value:"Google Cloud Storage (GCS)",id:"google-cloud-storage-gcs",level:3},{value:"Understanding Artifact Versioning",id:"understanding-artifact-versioning",level:2},{value:"Configuring Artifact Storage",id:"configuring-artifact-storage-1",level:2},{value:"Development Setup",id:"development-setup",level:3},{value:"AWS Production Deployment",id:"aws-production-deployment",level:3},{value:"On-Premises or Private Cloud",id:"on-premises-or-private-cloud",level:3},{value:"Google Cloud Deployment",id:"google-cloud-deployment",level:3},{value:"Migrating Artifact Storage Backends",id:"migrating-artifact-storage-backends",level:2},{value:"Before Migration",id:"before-migration",level:3},{value:"Migration Steps",id:"migration-steps",level:3},{value:"Data Retention for Artifacts",id:"data-retention-for-artifacts",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Backend Connectivity Issues",id:"backend-connectivity-issues",level:3},{value:"Authentication Errors",id:"authentication-errors",level:3},{value:"Artifact Not Found",id:"artifact-not-found",level:3},{value:"Performance Issues",id:"performance-issues",level:3},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",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,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"configuring-artifact-storage",children:"Configuring Artifact Storage"})}),"\n",(0,t.jsx)(n.p,{children:"This guide explains how to configure storage for artifacts\u2014files and data created by your agents\u2014from development to production deployments."}),"\n",(0,t.jsx)(n.h2,{id:"understanding-artifacts",children:"Understanding Artifacts"}),"\n",(0,t.jsx)(n.p,{children:"Artifacts are files and data created by agents during task execution. Examples include generated reports, analysis results, processed documents, or any files that agents produce for users. Agent Mesh provides built-in tools for agents to create, manage, and reference artifacts."}),"\n",(0,t.jsx)(n.p,{children:"Key characteristics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Automatic versioning: Each time an artifact is updated, a new version is created (v0, v1, v2, etc.)"}),"\n",(0,t.jsx)(n.li,{children:"User-scoped: Artifacts belong to specific users and sessions"}),"\n",(0,t.jsx)(n.li,{children:"Retrievable: Users can access, download, and view artifact history"}),"\n",(0,t.jsx)(n.li,{children:"Tool-driven: Agents use built-in tools to create and manage artifacts"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"artifact-storage-vs-session-storage",children:"Artifact Storage vs Session Storage"}),"\n",(0,t.jsx)(n.p,{children:"Unlike session storage (which is separate for WebUI Gateway and each agent), artifact storage is shared across all agents and gateways in your deployment."}),"\n",(0,t.jsx)(n.p,{children:"How it works:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"All agents and gateways connect to the same artifact storage backend"}),"\n",(0,t.jsxs)(n.li,{children:["Artifacts are scoped by ",(0,t.jsx)(n.code,{children:"(user_id, session_id, app_name)"})," to maintain isolation"]}),"\n",(0,t.jsx)(n.li,{children:"Any agent or gateway can access artifacts within their scope"}),"\n",(0,t.jsx)(n.li,{children:"This allows agents to share files and data within a conversation"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'# WebUI Gateway and all agents share this artifact storage\nartifact_service:\n type: "s3"\n bucket_name: "shared-artifacts-bucket"\n region: "us-west-2"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Contrast with session storage:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Session storage: Each agent has its own separate database"}),"\n",(0,t.jsx)(n.li,{children:"Artifact storage: All agents and gateways share the same storage backend"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For session storage configuration, see ",(0,t.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage",children:"Session Storage"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"artifact-storage-backends",children:"Artifact Storage Backends"}),"\n",(0,t.jsx)(n.p,{children:"Agent Mesh supports multiple storage backends for artifacts. Choose based on your deployment environment and requirements."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Backend"}),(0,t.jsx)(n.th,{children:"Best For"}),(0,t.jsx)(n.th,{children:"Production Ready"}),(0,t.jsx)(n.th,{children:"Setup Complexity"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Filesystem"}),(0,t.jsx)(n.td,{children:"Local development"}),(0,t.jsx)(n.td,{children:"\u274c"}),(0,t.jsx)(n.td,{children:"Simple"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"S3 (AWS)"}),(0,t.jsx)(n.td,{children:"AWS deployments"}),(0,t.jsx)(n.td,{children:"\u2705"}),(0,t.jsx)(n.td,{children:"Medium"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"S3-Compatible API"}),(0,t.jsx)(n.td,{children:"On-premises, private cloud"}),(0,t.jsx)(n.td,{children:"\u2705"}),(0,t.jsx)(n.td,{children:"Medium"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"GCS"}),(0,t.jsx)(n.td,{children:"Google Cloud deployments"}),(0,t.jsx)(n.td,{children:"\u2705"}),(0,t.jsx)(n.td,{children:"Medium"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"filesystem-storage-default",children:"Filesystem Storage (Default)"}),"\n",(0,t.jsx)(n.p,{children:"Filesystem storage saves artifacts to local disk directories. This is the default configuration and is suitable for development and local testing."}),"\n",(0,t.jsx)(n.p,{children:"Characteristics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Artifacts stored in transparent directory structure"}),"\n",(0,t.jsx)(n.li,{children:"Data persists across restarts"}),"\n",(0,t.jsx)(n.li,{children:"Single instance only (not shared across pods)"}),"\n",(0,t.jsx)(n.li,{children:"Simple backup (copy directories)"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Use only for local development and single-machine deployments."}),"\n",(0,t.jsx)(n.p,{children:"Configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "filesystem"\n base_path: "/tmp/sam-artifacts"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Storage structure:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"/tmp/sam-artifacts/\n\u251c\u2500\u2500 app-name/\n\u2502 \u2514\u2500\u2500 user-id/\n\u2502 \u251c\u2500\u2500 session-id/\n\u2502 \u2502 \u251c\u2500\u2500 report.pdf/\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 0 (version 0 data)\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 0.metadata (version 0 metadata)\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 1 (version 1 data)\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 1.metadata\n\u2502 \u2502 \u2514\u2500\u2500 data.csv/\n\u2502 \u2502 \u251c\u2500\u2500 0\n\u2502 \u2502 \u2514\u2500\u2500 0.metadata\n\u2502 \u2514\u2500\u2500 user/ (user-scoped artifacts)\n\u2502 \u2514\u2500\u2500 config.json/\n\u2502 \u251c\u2500\u2500 0\n\u2502 \u2514\u2500\u2500 0.metadata\n"})}),"\n",(0,t.jsx)(n.h3,{id:"s3-aws",children:"S3 (AWS)"}),"\n",(0,t.jsx)(n.p,{children:"S3 storage uses Amazon S3 for artifact persistence. This is the recommended production backend for AWS deployments."}),"\n",(0,t.jsx)(n.p,{children:"Characteristics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Highly durable"}),"\n",(0,t.jsx)(n.li,{children:"Scalable to any size"}),"\n",(0,t.jsx)(n.li,{children:"Access from any location"}),"\n",(0,t.jsx)(n.li,{children:"Automatic backups and redundancy"}),"\n",(0,t.jsx)(n.li,{children:"IAM-based security"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "s3"\n bucket_name: "my-artifacts-bucket"\n region: "us-west-2"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Environment variables:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export AWS_ACCESS_KEY_ID="your-access-key"\nexport AWS_SECRET_ACCESS_KEY="your-secret-key"\nexport AWS_REGION="us-west-2"\n'})}),"\n",(0,t.jsx)(n.p,{children:"IAM permissions required:"}),"\n",(0,t.jsx)(n.p,{children:"The credentials must have these permissions for the bucket:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"s3:GetObject"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"s3:PutObject"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"s3:DeleteObject"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"s3:ListBucket"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Example IAM policy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "Version": "2012-10-17",\n "Statement": [\n {\n "Effect": "Allow",\n "Action": [\n "s3:GetObject",\n "s3:PutObject",\n "s3:DeleteObject",\n "s3:ListBucket"\n ],\n "Resource": [\n "arn:aws:s3:::my-artifacts-bucket",\n "arn:aws:s3:::my-artifacts-bucket/*"\n ]\n }\n ]\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"s3-compatible-api-endpoint",children:"S3-Compatible API Endpoint"}),"\n",(0,t.jsx)(n.p,{children:"S3-compatible storage allows any storage service that implements the S3 API to work with Agent Mesh. This includes on-premises solutions and services from cloud providers other than AWS."}),"\n",(0,t.jsx)(n.p,{children:"Characteristics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Works with any S3-compatible API implementation"}),"\n",(0,t.jsx)(n.li,{children:"Custom endpoints for private or on-premises storage"}),"\n",(0,t.jsx)(n.li,{children:"Same versioning and management as AWS S3"}),"\n",(0,t.jsx)(n.li,{children:"Requires compatible storage service"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "s3"\n bucket_name: "my-artifacts-bucket"\n endpoint_url: "${S3_ENDPOINT_URL}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Environment variables:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export S3_ENDPOINT_URL="https://storage.example.com"\nexport S3_ACCESS_KEY_ID="your-access-key"\nexport S3_SECRET_ACCESS_KEY="your-secret-key"\nexport AWS_REGION="us-east-1" # Required but can be arbitrary for S3-compatible endpoints\n'})}),"\n",(0,t.jsx)(n.p,{children:"Supported services:"}),"\n",(0,t.jsx)(n.p,{children:"This configuration works with any S3-compatible storage service, including self-hosted and cloud-provider solutions. Examples include storage services from various cloud providers and on-premises object storage systems."}),"\n",(0,t.jsx)(n.h3,{id:"google-cloud-storage-gcs",children:"Google Cloud Storage (GCS)"}),"\n",(0,t.jsx)(n.p,{children:"GCS storage uses Google Cloud Storage for artifact persistence. This is the recommended backend for Google Cloud deployments."}),"\n",(0,t.jsx)(n.p,{children:"Characteristics:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"High availability and durability"}),"\n",(0,t.jsx)(n.li,{children:"Integration with Google Cloud ecosystem"}),"\n",(0,t.jsx)(n.li,{children:"Scalable and managed by Google"}),"\n",(0,t.jsx)(n.li,{children:"Fine-grained IAM controls"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "gcs"\n bucket_name: "my-artifacts-bucket"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Authentication:"}),"\n",(0,t.jsx)(n.p,{children:"GCS authentication uses Google Cloud Application Default Credentials. Set up via:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Or configure via environment variables if you use workload identity in Kubernetes."}),"\n",(0,t.jsx)(n.p,{children:"Permissions required:"}),"\n",(0,t.jsx)(n.p,{children:"The service account must have these roles on the bucket:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"roles/storage.objectViewer"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"roles/storage.objectCreator"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"roles/storage.objectDeleter"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"understanding-artifact-versioning",children:"Understanding Artifact Versioning"}),"\n",(0,t.jsx)(n.p,{children:"Agent Mesh automatically manages artifact versions, allowing users to access previous versions of files."}),"\n",(0,t.jsx)(n.p,{children:"How versioning works:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"First artifact create: version 0"}),"\n",(0,t.jsx)(n.li,{children:"Append or update: version 1 (automatic increment)"}),"\n",(0,t.jsx)(n.li,{children:"Continue appending: version 2, 3, 4, etc."}),"\n",(0,t.jsx)(n.li,{children:"Versions persist independently"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Example lifecycle:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"Agent creates report.pdf\n \u2192 version 0 created\n\nAgent appends more data to report.pdf\n \u2192 version 1 created (v0 still exists)\n\nAgent appends additional data\n \u2192 version 2 created (v0 and v1 still exist)\n\nUser can access any version:\n- Latest version (automatic)\n- Specific version (v0, v1, v2)\n- Version history (list all versions)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Metadata:"}),"\n",(0,t.jsx)(n.p,{children:"Each artifact version includes metadata:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "filename": "report.pdf",\n "mime_type": "application/pdf",\n "version": 0,\n "size_bytes": 2048,\n "timestamp": "2024-10-29T12:34:56Z"\n}\n'})}),"\n",(0,t.jsx)(n.h2,{id:"configuring-artifact-storage-1",children:"Configuring Artifact Storage"}),"\n",(0,t.jsx)(n.p,{children:"Choose your artifact storage backend based on your deployment environment."}),"\n",(0,t.jsx)(n.h3,{id:"development-setup",children:"Development Setup"}),"\n",(0,t.jsx)(n.p,{children:"For local development and testing, use filesystem storage:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "filesystem"\n base_path: "/tmp/sam-artifacts"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Create the base directory if it doesn't exist:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"mkdir -p /tmp/sam-artifacts\n"})}),"\n",(0,t.jsx)(n.h3,{id:"aws-production-deployment",children:"AWS Production Deployment"}),"\n",(0,t.jsx)(n.p,{children:"For production deployments on AWS:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Create S3 Bucket:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"aws s3 mb s3://my-artifacts-bucket --region us-west-2\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Configure IAM User or Role"})," with required permissions (see IAM Policy above)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Configure Agent Mesh:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "s3"\n bucket_name: "my-artifacts-bucket"\n region: "us-west-2"\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Set Environment Variables:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export AWS_ACCESS_KEY_ID="your-key"\nexport AWS_SECRET_ACCESS_KEY="your-secret"\nexport AWS_REGION="us-west-2"\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"on-premises-or-private-cloud",children:"On-Premises or Private Cloud"}),"\n",(0,t.jsx)(n.p,{children:"For on-premises deployments using S3-compatible storage:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Set Up S3-Compatible Storage"})," (ensure it's running and accessible)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Create Bucket:"})," Use your storage system's administration tools"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Configure Agent Mesh:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "s3"\n bucket_name: "my-bucket"\n endpoint_url: "${S3_ENDPOINT_URL}"\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Set Environment Variables:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export S3_ENDPOINT_URL="https://storage.example.com:9000"\nexport S3_ACCESS_KEY_ID="your-access-key"\nexport S3_SECRET_ACCESS_KEY="your-secret-key"\nexport AWS_REGION="us-east-1"\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"google-cloud-deployment",children:"Google Cloud Deployment"}),"\n",(0,t.jsx)(n.p,{children:"For production deployments on Google Cloud:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Create GCS Bucket:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"gsutil mb gs://my-artifacts-bucket\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Set Up Service Account with required permissions"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Configure Agent Mesh:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "gcs"\n bucket_name: "my-artifacts-bucket"\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Set Up Authentication:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export GOOGLE_APPLICATION_CREDENTIALS="/path/to/service-account.json"\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"migrating-artifact-storage-backends",children:"Migrating Artifact Storage Backends"}),"\n",(0,t.jsx)(n.p,{children:"Moving from one artifact storage backend to another requires no special migration procedure\u2014the system starts fresh with the new backend."}),"\n",(0,t.jsx)(n.h3,{id:"before-migration",children:"Before Migration"}),"\n",(0,t.jsx)(n.p,{children:"Understand the implications:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Existing artifacts stored in the old backend will not be accessible after switching"}),"\n",(0,t.jsx)(n.li,{children:"New artifacts will be stored in the new backend"}),"\n",(0,t.jsx)(n.li,{children:"If you need to preserve existing artifacts, export them first from the old storage"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"migration-steps",children:"Migration Steps"}),"\n",(0,t.jsx)(n.p,{children:"Step 1: Set up new storage backend"}),"\n",(0,t.jsx)(n.p,{children:"Create the new storage location:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["For filesystem: ",(0,t.jsx)(n.code,{children:"mkdir -p /path/to/new/storage"})]}),"\n",(0,t.jsx)(n.li,{children:"For S3: Create bucket and set up credentials"}),"\n",(0,t.jsx)(n.li,{children:"For GCS: Create bucket and set up service account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Step 2: Update configuration"}),"\n",(0,t.jsx)(n.p,{children:"Update your artifact service configuration:"}),"\n",(0,t.jsx)(n.p,{children:"From:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "filesystem"\n base_path: "/old/path"\n'})}),"\n",(0,t.jsx)(n.p,{children:"To:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:'artifact_service:\n type: "s3"\n bucket_name: "my-bucket"\n region: "us-west-2"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Step 3: Set environment variables"}),"\n",(0,t.jsx)(n.p,{children:"Configure credentials for the new backend:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'export AWS_ACCESS_KEY_ID="your-key"\nexport AWS_SECRET_ACCESS_KEY="your-secret"\nexport AWS_REGION="us-west-2"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Step 4: Restart application"}),"\n",(0,t.jsx)(n.p,{children:"When the application restarts, it will use the new backend for all subsequent artifact operations."}),"\n",(0,t.jsx)(n.p,{children:"Step 5: Verify"}),"\n",(0,t.jsx)(n.p,{children:"Test artifact creation and retrieval:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Create a new artifact"}),"\n",(0,t.jsx)(n.li,{children:"Verify it appears in the new storage backend"}),"\n",(0,t.jsx)(n.li,{children:"Retrieve it through the API or agent tools"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"data-retention-for-artifacts",children:"Data Retention for Artifacts"}),"\n",(0,t.jsx)(n.p,{children:"Like session data, artifact storage can be configured with automatic cleanup policies."}),"\n",(0,t.jsx)(n.p,{children:"Configuration:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yaml",children:"data_retention:\n enabled: true\n task_retention_days: 90\n cleanup_interval_hours: 24\n"})}),"\n",(0,t.jsx)(n.p,{children:"How it works:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Artifacts older than ",(0,t.jsx)(n.code,{children:"task_retention_days"})," may be cleaned up"]}),"\n",(0,t.jsxs)(n.li,{children:["Cleanup runs every ",(0,t.jsx)(n.code,{children:"cleanup_interval_hours"})]}),"\n",(0,t.jsx)(n.li,{children:"Prevents unbounded storage growth"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your specific artifact storage backend documentation for retention policies and best practices."}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsx)(n.h3,{id:"backend-connectivity-issues",children:"Backend Connectivity Issues"}),"\n",(0,t.jsxs)(n.p,{children:["Error: ",(0,t.jsx)(n.code,{children:"Failed to access storage"})," or ",(0,t.jsx)(n.code,{children:"Connection refused"})]}),"\n",(0,t.jsx)(n.p,{children:"Solutions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify storage backend is running and accessible"}),"\n",(0,t.jsx)(n.li,{children:"Check network connectivity and firewall rules"}),"\n",(0,t.jsx)(n.li,{children:"Verify endpoint URL is correct (for S3-compatible)"}),"\n",(0,t.jsx)(n.li,{children:"Check credentials and permissions"}),"\n",(0,t.jsx)(n.li,{children:"Review application logs for detailed errors"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"authentication-errors",children:"Authentication Errors"}),"\n",(0,t.jsxs)(n.p,{children:["Error: ",(0,t.jsx)(n.code,{children:"Access Denied"})," or ",(0,t.jsx)(n.code,{children:"Unauthorized"})]}),"\n",(0,t.jsx)(n.p,{children:"Solutions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify AWS/GCS credentials are correct"}),"\n",(0,t.jsx)(n.li,{children:"Confirm IAM/service account has required permissions"}),"\n",(0,t.jsx)(n.li,{children:"Check that credentials are set in environment variables"}),"\n",(0,t.jsx)(n.li,{children:"Verify bucket name is correct and matches configuration"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"artifact-not-found",children:"Artifact Not Found"}),"\n",(0,t.jsxs)(n.p,{children:["Error: ",(0,t.jsx)(n.code,{children:"404 Not Found"})," when retrieving artifact"]}),"\n",(0,t.jsx)(n.p,{children:"Solutions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Verify artifact was successfully created"}),"\n",(0,t.jsx)(n.li,{children:"Check that session ID is correct"}),"\n",(0,t.jsx)(n.li,{children:"Confirm storage backend has the artifact"}),"\n",(0,t.jsx)(n.li,{children:"Verify you're accessing the correct version"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"performance-issues",children:"Performance Issues"}),"\n",(0,t.jsx)(n.p,{children:"Slow artifact creation or retrieval:"}),"\n",(0,t.jsx)(n.p,{children:"Solutions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Check network latency to storage backend"}),"\n",(0,t.jsx)(n.li,{children:"Verify storage backend performance"}),"\n",(0,t.jsx)(n.li,{children:"Check for throttling or rate limiting"}),"\n",(0,t.jsx)(n.li,{children:"Consider object size and any upload/download limits"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsx)(n.p,{children:"After configuring artifact storage, you may want to:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Configure ",(0,t.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage",children:"Session Storage"})," for conversation persistence"]}),"\n",(0,t.jsxs)(n.li,{children:["Explore ",(0,t.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents",children:"agent tools"})," for working with artifacts"]}),"\n",(0,t.jsxs)(n.li,{children:["Review ",(0,t.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/deployment-options",children:"deployment options"})," for production considerations"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up ",(0,t.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deploying/observability",children:"monitoring and observability"})," to track artifact activity"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var i=s(6540);const t={},r=i.createContext(t);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[5957],{5080:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"documentation/enterprise/single-sign-on","title":"Enabling SSO","description":"Overview","source":"@site/docs/documentation/enterprise/single-sign-on.md","sourceDirName":"documentation/enterprise","slug":"/documentation/enterprise/single-sign-on","permalink":"/solace-agent-mesh/docs/documentation/enterprise/single-sign-on","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/enterprise/single-sign-on.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Enabling SSO","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Setting Up RBAC","permalink":"/solace-agent-mesh/docs/documentation/enterprise/rbac-setup-guide"},"next":{"title":"Secure User Delegated Access","permalink":"/solace-agent-mesh/docs/documentation/enterprise/secure-user-delegated-access"}}');var r=t(4848),o=t(8453);const s={title:"Enabling SSO",sidebar_position:10},a=void 0,c={},l=[{value:"Overview",id:"overview",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Understanding the SSO Architecture",id:"understanding-the-sso-architecture",level:2},{value:"Step 1: Create Configuration Files",id:"step-1-create-configuration-files",level:2},{value:"Create oauth2_server.yaml",id:"create-oauth2_serveryaml",level:3},{value:"Create oauth2_config.yaml",id:"create-oauth2_configyaml",level:3},{value:"Update Your WebUI Gateway",id:"update-your-webui-gateway",level:3},{value:"Step 2: Configure Your OAuth2 Provider",id:"step-2-configure-your-oauth2-provider",level:2},{value:"For Azure (Microsoft Entra ID)",id:"for-azure-microsoft-entra-id",level:3},{value:"For Google",id:"for-google",level:3},{value:"For Other Providers",id:"for-other-providers",level:3},{value:"Step 3: Launch the Docker Container",id:"step-3-launch-the-docker-container",level:2},{value:"Understanding the Environment Variables",id:"understanding-the-environment-variables",level:2},{value:"Core Application Settings",id:"core-application-settings",level:3},{value:"Frontend Authentication Settings",id:"frontend-authentication-settings",level:3},{value:"OAuth2 Service Settings",id:"oauth2-service-settings",level:3},{value:"Provider-Specific Credentials",id:"provider-specific-credentials",level:3},{value:"External Authentication Configuration",id:"external-authentication-configuration",level:3},{value:"Port Mapping and Volume Mount",id:"port-mapping-and-volume-mount",level:3},{value:"Verifying Your SSO Configuration",id:"verifying-your-sso-configuration",level:2},{value:"Understanding the OAuth2 Flow and Environment Variables",id:"understanding-the-oauth2-flow-and-environment-variables",level:2},{value:"How the OAuth2 Flow Works",id:"how-the-oauth2-flow-works",level:3},{value:"Common Environment Variables",id:"common-environment-variables",level:3},{value:"Security Considerations for Production",id:"security-considerations-for-production",level:2}];function h(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(n.p,{children:"Single Sign-On (SSO) enables users to authenticate with Agent Mesh Enterprise using their existing organizational credentials through OAuth2 providers such as Azure, Google, Auth0, Okta, or Keycloak. This integration eliminates the need for separate login credentials and leverages your organization's existing identity management infrastructure."}),"\n",(0,r.jsx)(n.p,{children:"This guide walks you through configuring and enabling SSO for Agent Mesh Enterprise running in Docker. You will create configuration files, set up your OAuth2 provider, and launch the container with the appropriate environment variables."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.p,{children:"Before you begin, ensure you have:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"A running instance of your chosen OAuth2 provider (Azure, Google, Auth0, Okta, Keycloak, or another OIDC-compliant provider)"}),"\n",(0,r.jsx)(n.li,{children:"Client credentials (client ID and client secret) from your OAuth2 provider"}),"\n",(0,r.jsx)(n.li,{children:"A Named Docker Volume for storing configuration files"}),"\n",(0,r.jsx)(n.li,{children:"Access to the Agent Mesh Enterprise Docker image"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"understanding-the-sso-architecture",children:"Understanding the SSO Architecture"}),"\n",(0,r.jsx)(n.p,{children:"Agent Mesh Enterprise uses a two-component architecture for SSO:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"The main UI server (default port 8000) handles user interactions and serves the web interface"}),"\n",(0,r.jsx)(n.li,{children:"The OAuth2 authentication service (default port 9000) manages the authentication flow with your identity provider"}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"When a user attempts to access the UI, they are redirected to your OAuth2 provider for authentication. After successful authentication, the provider redirects back to the application with an authorization code, which is then exchanged for access tokens. This separation of concerns keeps authentication logic isolated from the main application."}),"\n",(0,r.jsx)(n.h2,{id:"step-1-create-configuration-files",children:"Step 1: Create Configuration Files"}),"\n",(0,r.jsx)(n.p,{children:"You need to create two YAML configuration files in your Named Docker Volume. These files define how the OAuth2 service operates and which identity provider it connects to."}),"\n",(0,r.jsx)(n.h3,{id:"create-oauth2_serveryaml",children:"Create oauth2_server.yaml"}),"\n",(0,r.jsx)(n.p,{children:"The oauth2_server.yaml file configures the OAuth2 authentication service as a component within Agent Mesh Enterprise. This file tells the system to start the OAuth2 service and specifies where to find its detailed configuration."}),"\n",(0,r.jsxs)(n.p,{children:["Create a file named ",(0,r.jsx)(n.code,{children:"oauth2_server.yaml"})," in the root directory of your Named Docker Volume with the following content:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'---\n# Example gateway configuration with OAuth2 service integration\n# This shows how to configure a gateway to use the OAuth2 authentication service\n\nlog:\n stdout_log_level: INFO\n log_file_level: DEBUG\n log_file: oauth_server.log\n\n!include ../shared_config.yaml\n\nshared_config:\n # OAuth2 service configuration\n - oauth2_config: &oauth2_config\n enabled: true\n config_file: "configs/sso_vol/oauth2_config.yaml"\n host: ${OAUTH2_HOST, localhost}\n port: ${OAUTH2_PORT, 9000}\n ssl_cert: "" # Optional: path to SSL certificate\n ssl_key: "" # Optional: path to SSL private key\n\nflows:\n # Initialize OAuth2 service\n - name: oauth2_service\n components:\n - component_name: oauth2_auth_service\n component_module: solace_agent_mesh_enterprise.components.oauth2_component\n component_config:\n <<: *oauth2_config\n'})}),"\n",(0,r.jsx)(n.p,{children:"This configuration accomplishes several things:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"It sets up logging for the OAuth2 service, directing detailed debug information to oauth_server.log"}),"\n",(0,r.jsx)(n.li,{children:"It references the shared_config.yaml file, which contains common configuration used across multiple components"}),"\n",(0,r.jsx)(n.li,{children:"It defines the OAuth2 service configuration, including where to find the provider-specific settings (oauth2_config.yaml)"}),"\n",(0,r.jsx)(n.li,{children:"It specifies the host and port where the OAuth2 service will listen for requests"}),"\n",(0,r.jsx)(n.li,{children:"It creates a flow that initializes the OAuth2 authentication service component"}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"${OAUTH2_HOST, localhost}"})," syntax means the service will use the OAUTH2_HOST environment variable if provided, otherwise it defaults to localhost. This pattern allows you to override configuration values at runtime without modifying the file."]}),"\n",(0,r.jsx)(n.h3,{id:"create-oauth2_configyaml",children:"Create oauth2_config.yaml"}),"\n",(0,r.jsx)(n.p,{children:"The oauth2_config.yaml file contains provider-specific configuration for your chosen OAuth2 identity provider. This is where you specify which provider to use and provide the necessary credentials and endpoints."}),"\n",(0,r.jsxs)(n.p,{children:["Create a file named ",(0,r.jsx)(n.code,{children:"oauth2_config.yaml"})," in the same directory with the following content:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'---\n# OAuth2 Service Configuration\n# This file configures the OAuth2 authentication service that supports multiple providers\n# All providers now use the unified OIDC approach with automatic endpoint discovery\n\n# Enable or disable the OAuth2 service\nenabled: ${OAUTH2_ENABLED:false}\n\n# Development mode - enables insecure transport and relaxed token scope for local development\n# Set OAUTH2_DEV_MODE=true for local development (NEVER use in production!)\ndevelopment_mode: ${OAUTH2_DEV_MODE:false}\n\n# OAuth2 providers configuration\n# All providers now use the unified OIDCProvider with automatic endpoint discovery\nproviders:\n # Google OAuth2 provider\n # google:\n # # OIDC issuer URL - endpoints will be discovered automatically\n # issuer: "https://accounts.google.com"\n # client_id: ${GOOGLE_CLIENT_ID}\n # client_secret: ${GOOGLE_CLIENT_SECRET}\n # redirect_uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/callback}\n # scope: "openid email profile"\n\n # Azure/Microsoft OAuth2 provider\n azure:\n # Azure OIDC issuer URL includes tenant ID\n issuer: https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0\n client_id: ${AZURE_CLIENT_ID}\n client_secret: ${AZURE_CLIENT_SECRET}\n redirect_uri: ${AZURE_REDIRECT_URI:http://localhost:8080/callback}\n scope: "openid email profile offline_access"\n\n # Auth0 OAuth2 provider\n # auth0:\n # # Auth0 issuer URL\n # issuer: ${AUTH0_ISSUER:https://your-domain.auth0.com/}\n # client_id: ${AUTH0_CLIENT_ID}\n # client_secret: ${AUTH0_CLIENT_SECRET}\n # redirect_uri: ${AUTH0_REDIRECT_URI:http://localhost:8080/callback}\n # scope: "openid email profile"\n # # Optional: Auth0 audience for API access\n # audience: ${AUTH0_AUDIENCE:}\n\n # # Okta OAuth2 provider (example)\n # okta:\n # issuer: ${OKTA_ISSUER:https://your-okta-domain.okta.com/oauth2/default}\n # client_id: ${OKTA_CLIENT_ID}\n # client_secret: ${OKTA_CLIENT_SECRET}\n # redirect_uri: ${OKTA_REDIRECT_URI:http://localhost:8080/callback}\n # scope: "openid email profile"\n\n # # Keycloak OAuth2 provider (example)\n # keycloak:\n # issuer: ${KEYCLOAK_ISSUER:https://your-keycloak.com/auth/realms/your-realm}\n # client_id: ${KEYCLOAK_CLIENT_ID}\n # client_secret: ${KEYCLOAK_CLIENT_SECRET}\n # redirect_uri: ${KEYCLOAK_REDIRECT_URI:http://localhost:8080/callback}\n # scope: "openid email profile"\n\n # # Generic OIDC provider (for any standard OIDC-compliant provider)\n # custom_oidc:\n # # Just provide the issuer URL and the service will discover all endpoints\n # issuer: ${CUSTOM_OIDC_ISSUER:https://your-provider.com}\n # client_id: ${CUSTOM_OIDC_CLIENT_ID}\n # client_secret: ${CUSTOM_OIDC_CLIENT_SECRET}\n # redirect_uri: ${CUSTOM_OIDC_REDIRECT_URI:http://localhost:8080/callback}\n # scope: "openid email profile"\n\n# Logging configuration\nlogging:\n level: ${OAUTH2_LOG_LEVEL:INFO}\n\n# Session configuration\nsession:\n # Session timeout in seconds (default: 1 hour)\n timeout: ${OAUTH2_SESSION_TIMEOUT:3600}\n\n# Security configuration\nsecurity:\n # CORS settings\n cors:\n enabled: ${OAUTH2_CORS_ENABLED:true}\n origins: ${OAUTH2_CORS_ORIGINS:*}\n\n # Rate limiting\n rate_limit:\n enabled: ${OAUTH2_RATE_LIMIT_ENABLED:true}\n requests_per_minute: ${OAUTH2_RATE_LIMIT_RPM:60}\n'})}),"\n",(0,r.jsx)(n.p,{children:"This configuration file provides several important features:"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"enabled"})," setting controls whether the OAuth2 service is active. You can enable it by setting the OAUTH2_ENABLED environment variable to true."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"development_mode"})," setting is crucial for local testing. When enabled, it allows HTTP connections (instead of requiring HTTPS) and relaxes token validation. You must disable this in production environments to maintain security."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"providers"})," section defines multiple OAuth2 providers. By default, Azure is uncommented and active. To use a different provider, comment out the Azure section and uncomment your chosen provider. Each provider requires:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["An ",(0,r.jsx)(n.code,{children:"issuer"})," URL that points to the OAuth2 provider's discovery endpoint"]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"client_id"})," and ",(0,r.jsx)(n.code,{children:"client_secret"})," obtained from your provider's application registration"]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"redirect_uri"})," where the provider sends users after authentication"]}),"\n",(0,r.jsxs)(n.li,{children:["A ",(0,r.jsx)(n.code,{children:"scope"})," that defines what user information the application can access"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The system uses OpenID Connect (OIDC) discovery, which means it automatically finds the authorization, token, and userinfo endpoints from the issuer URL. This simplifies configuration because you only need to provide the base issuer URL rather than individual endpoint URLs."}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"session"})," configuration determines how long authenticated sessions remain valid. The default of 3600 seconds (1 hour) balances security with user convenience."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"security"})," section configures Cross-Origin Resource Sharing (CORS) and rate limiting. CORS allows the web UI to communicate with the OAuth2 service from different origins, while rate limiting prevents abuse by restricting the number of authentication requests per minute."]}),"\n",(0,r.jsx)(n.h3,{id:"update-your-webui-gateway",children:"Update Your WebUI Gateway"}),"\n",(0,r.jsx)(n.p,{children:"Update your WebUI Gateway to configure login as follows:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'# Auth-related (placeholders, functionality depends on backend implementation)\nfrontend_auth_login_url: ${FRONTEND_AUTH_LOGIN_URL}\nfrontend_use_authorization: ${FRONTEND_USE_AUTHORIZATION}\nfrontend_redirect_url: ${FRONTEND_REDIRECT_URL, ""}\n\nexternal_auth_callback_uri: ${EXTERNAL_AUTH_CALLBACK}\nexternal_auth_service_url: ${EXTERNAL_AUTH_SERVICE_URL}\nexternal_auth_provider: ${EXTERNAL_AUTH_PROVIDER}\n'})}),"\n",(0,r.jsx)(n.p,{children:"Your final WebUI Gateway yaml configuration should look like this:"}),"\n",(0,r.jsxs)(t,{children:[(0,r.jsx)("summary",{children:"WebUI Gateway SSO Enabled"}),(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"webUI.yaml"})}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'log:\n stdout_log_level: INFO\n log_file_level: INFO\n log_file: webui_app.log\n\n\n!include ../shared_config.yaml\n\napps:\n - name: a2a_webui_app\n app_base_path: .\n app_module: solace_agent_mesh.gateway.http_sse.app\n\n broker:\n <<: *broker_connection\n\n app_config:\n namespace: ${NAMESPACE}\n session_secret_key: "${SESSION_SECRET_KEY}"\n\n artifact_service: *default_artifact_service\n session_service: \n type: "sql"\n database_url: ${WEB_UI_GATEWAY_DATABASE_URL, sqlite:///webui_gateway.db}\n default_behavior: "PERSISTENT"\n gateway_id: ${WEBUI_GATEWAY_ID}\n fastapi_host: ${FASTAPI_HOST}\n fastapi_port: ${FASTAPI_PORT}\n cors_allowed_origins: \n - "http://localhost:3000" \n - "http://127.0.0.1:3000"\n\n enable_embed_resolution: ${ENABLE_EMBED_RESOLUTION} # Enable late-stage resolution\n gateway_artifact_content_limit_bytes: ${GATEWAY_ARTIFACT_LIMIT_BYTES, 10000000} # Max size for late-stage embeds\n sse_max_queue_size: ${SSE_MAX_QUEUE_SIZE, 200} # Max size of SSE connection queues\n\n system_purpose: >\n The system is an AI Chatbot with agentic capabilities.\n It will use the agents available to provide information,\n reasoning and general assistance for the users in this system.\n **Always return useful artifacts and files that you create to the user.**\n Provide a status update before each tool call.\n Your external name is Agent Mesh.\n\n response_format: >\n Responses should be clear, concise, and professionally toned.\n Format responses to the user in Markdown using appropriate formatting.\n\n # --- Frontend Config Passthrough ---\n frontend_welcome_message: ${FRONTEND_WELCOME_MESSAGE}\n frontend_bot_name: ${FRONTEND_BOT_NAME}\n frontend_collect_feedback: ${FRONTEND_COLLECT_FEEDBACK}\n\n # Auth-related (placeholders, functionality depends on backend implementation)\n frontend_auth_login_url: ${FRONTEND_AUTH_LOGIN_URL}\n frontend_use_authorization: ${FRONTEND_USE_AUTHORIZATION}\n frontend_redirect_url: ${FRONTEND_REDIRECT_URL, ""}\n\n external_auth_callback_uri: ${EXTERNAL_AUTH_CALLBACK}\n external_auth_service_url: ${EXTERNAL_AUTH_SERVICE_URL}\n external_auth_provider: ${EXTERNAL_AUTH_PROVIDER}\n'})})]}),"\n",(0,r.jsx)(n.h2,{id:"step-2-configure-your-oauth2-provider",children:"Step 2: Configure Your OAuth2 Provider"}),"\n",(0,r.jsx)(n.p,{children:"Before running the Docker container, you need to register an application with your chosen OAuth2 provider and obtain the necessary credentials."}),"\n",(0,r.jsx)(n.h3,{id:"for-azure-microsoft-entra-id",children:"For Azure (Microsoft Entra ID)"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Navigate to the Azure Portal and go to Microsoft Entra ID (formerly Azure Active Directory)"}),"\n",(0,r.jsx)(n.li,{children:'Select "App registrations" and create a new registration'}),"\n",(0,r.jsx)(n.li,{children:"Note the Application (client) ID and Directory (tenant) ID"}),"\n",(0,r.jsx)(n.li,{children:'Create a client secret under "Certificates & secrets"'}),"\n",(0,r.jsxs)(n.li,{children:["Add a redirect URI pointing to your callback endpoint (for example, ",(0,r.jsx)(n.a,{href:"http://localhost:8000/api/v1/auth/callback",children:"http://localhost:8000/api/v1/auth/callback"}),")"]}),"\n",(0,r.jsx)(n.li,{children:"Grant the necessary API permissions (typically Microsoft Graph with User.Read)"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"for-google",children:"For Google"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"Go to the Google Cloud Console and create a new project or select an existing one"}),"\n",(0,r.jsx)(n.li,{children:"Enable the Google+ API"}),"\n",(0,r.jsx)(n.li,{children:'Create OAuth2 credentials under "APIs & Services" > "Credentials"'}),"\n",(0,r.jsx)(n.li,{children:"Configure the authorized redirect URIs"}),"\n",(0,r.jsx)(n.li,{children:"Note the client ID and client secret"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"for-other-providers",children:"For Other Providers"}),"\n",(0,r.jsx)(n.p,{children:"Consult your provider's documentation for application registration procedures. You will need to obtain a client ID, client secret, and configure the redirect URI to point to your Agent Mesh Enterprise callback endpoint."}),"\n",(0,r.jsx)(n.h2,{id:"step-3-launch-the-docker-container",children:"Step 3: Launch the Docker Container"}),"\n",(0,r.jsx)(n.p,{children:"With your configuration files in place and provider credentials obtained, you can now launch the Agent Mesh Enterprise container with SSO enabled."}),"\n",(0,r.jsx)(n.p,{children:"The following example demonstrates a production deployment using Azure as the OAuth2 provider:"}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["You may need to include ",(0,r.jsx)(n.code,{children:"--platform linux/amd64"})," depending on the host machine you're using."]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'docker run -itd -p 8000:8000 -p 9000:9000 \\\n -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\\n -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\\n -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\\n -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\\n -e NAMESPACE="<YOUR_NAMESPACE>" \\\n -e SOLACE_DEV_MODE="false" \\\n -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \\\n -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \\\n -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \\\n -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \\\n -e FASTAPI_HOST="0.0.0.0" \\\n -e FASTAPI_PORT="8000" \\\n -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n -e OAUTH2_ENABLED="true" \\\n -e OAUTH2_LOG_LEVEL="DEBUG" \\\n -e OAUTH2_DEV_MODE="true" \\\n -e OAUTH2_HOST="0.0.0.0" \\\n -e OAUTH2_PORT="9000" \\\n -e FRONTEND_USE_AUTHORIZATION="true" \\\n -e FRONTEND_REDIRECT_URL="http://localhost:8000" \\\n -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\\n -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\\n -e EXTERNAL_AUTH_PROVIDER="azure" \\\n -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\\n -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\\n --name sam-ent-prod-sso \\\nsolace-agent-mesh-enterprise:<tag> run config/sso_vol/oauth2_server.yaml config/webui_backend.yaml config/a2a_orchestrator.yaml config/a2a_agents.yaml\n'})}),"\n",(0,r.jsxs)(n.p,{children:["This command starts the container in detached mode with interactive terminal support. The ",(0,r.jsx)(n.code,{children:"-p"})," flags expose both the main UI port (8000) and the OAuth2 service port (9000) to the host machine. The volume mount makes your configuration files available inside the container at the expected location."]}),"\n",(0,r.jsxs)(n.p,{children:["After the container starts successfully, you can access the Agent Mesh Enterprise UI at ",(0,r.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"}),". When you navigate to this URL, the system will redirect you to your OAuth2 provider's login page for authentication."]}),"\n",(0,r.jsx)(n.h2,{id:"understanding-the-environment-variables",children:"Understanding the Environment Variables"}),"\n",(0,r.jsx)(n.p,{children:"The Docker run command includes numerous environment variables that control different aspects of the SSO configuration. Understanding these variables helps you customize the deployment for your specific environment."}),"\n",(0,r.jsx)(n.h3,{id:"core-application-settings",children:"Core Application Settings"}),"\n",(0,r.jsx)(n.p,{children:"These variables configure the main Agent Mesh Enterprise application:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e FASTAPI_HOST="0.0.0.0" \\\n-e FASTAPI_PORT="8000" \\ \n'})}),"\n",(0,r.jsx)(n.p,{children:'The FASTAPI_HOST setting determines which network interfaces the main UI server binds to. Using "0.0.0.0" allows external access to the container, which is necessary for production deployments. The FASTAPI_PORT specifies which port the UI listens on inside the container.'}),"\n",(0,r.jsx)(n.h3,{id:"frontend-authentication-settings",children:"Frontend Authentication Settings"}),"\n",(0,r.jsx)(n.p,{children:"These variables control how the web UI handles authentication:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e FRONTEND_USE_AUTHORIZATION="true" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:'Setting FRONTEND_USE_AUTHORIZATION to "true" enables SSO processing on the frontend. When enabled, the UI will redirect unauthenticated users to the login flow instead of allowing direct access.'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e FRONTEND_REDIRECT_URL="http://localhost:8000" \\\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The FRONTEND_REDIRECT_URL specifies the main URL of your UI. In production, this would be your public-facing domain (for example, ",(0,r.jsx)(n.a,{href:"https://www.example.com",children:"https://www.example.com"}),"). The system uses this URL to construct proper redirect chains during authentication."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:"The FRONTEND_AUTH_LOGIN_URL tells the frontend where to send users who need to authenticate. This endpoint initiates the OAuth2 flow by redirecting to your identity provider."}),"\n",(0,r.jsx)(n.h3,{id:"oauth2-service-settings",children:"OAuth2 Service Settings"}),"\n",(0,r.jsx)(n.p,{children:"These variables configure the OAuth2 authentication service itself:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e OAUTH2_ENABLED="true" \\\n-e OAUTH2_LOG_LEVEL="DEBUG" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:'The OAUTH2_ENABLED variable activates the OAuth2 service. Setting OAUTH2_LOG_LEVEL to "DEBUG" provides detailed logging information, which is helpful during initial setup and troubleshooting. You can change this to "INFO" or "WARNING" in production to reduce log verbosity.'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e OAUTH2_HOST="0.0.0.0" \\\n-e OAUTH2_PORT="9000" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:'These variables specify where the OAuth2 authentication service listens for requests. Using "0.0.0.0" as the host allows external access to the container, which is necessary because the OAuth2 provider needs to reach the callback endpoint. The port must match the port mapping in your Docker run command.'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e OAUTH2_DEV_MODE="true" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:'The OAUTH2_DEV_MODE setting controls whether the OAuth2 service operates in development mode. When set to "true", the service sets these internal environment variables:'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'OAUTHLIB_RELAX_TOKEN_SCOPE="1"\nOAUTHLIB_INSECURE_TRANSPORT="1"\n'})}),"\n",(0,r.jsx)(n.p,{children:'These settings allow HTTP connections (instead of requiring HTTPS) and relax token scope validation. This is convenient for local development and testing, but you must set OAUTH2_DEV_MODE to "false" in production environments to maintain security. Production deployments should always use HTTPS with valid SSL certificates.'}),"\n",(0,r.jsx)(n.h3,{id:"provider-specific-credentials",children:"Provider-Specific Credentials"}),"\n",(0,r.jsx)(n.p,{children:"These variables provide the credentials obtained from your OAuth2 provider. The example shows Azure configuration:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n-e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n-e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:"The required variables depend on which provider you configured in oauth2_config.yaml. For Google, you would use GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. For Auth0, you would use AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, and AUTH0_ISSUER. Refer to the oauth2_config.yaml file to identify the exact variable names for your chosen provider."}),"\n",(0,r.jsx)(n.h3,{id:"external-authentication-configuration",children:"External Authentication Configuration"}),"\n",(0,r.jsx)(n.p,{children:"These variables connect the main UI to the OAuth2 service:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\\n-e EXTERNAL_AUTH_PROVIDER="azure" \\\n'})}),"\n",(0,r.jsx)(n.p,{children:'The EXTERNAL_AUTH_SERVICE_URL specifies the public URL where the OAuth2 service can be reached. This must be accessible from outside the Docker container because your OAuth2 provider will redirect users to this service. The EXTERNAL_AUTH_PROVIDER must match one of the provider names defined in your oauth2_config.yaml file (in this example, "azure").'}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'-e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The EXTERNAL_AUTH_CALLBACK is the URL where your OAuth2 provider redirects users after successful authentication. This URL must be registered with your OAuth2 provider as an authorized redirect URI. In production, this would be your public domain followed by the callback path (for example, ",(0,r.jsx)(n.a,{href:"https://www.example.com/api/v1/auth/callback",children:"https://www.example.com/api/v1/auth/callback"}),")."]}),"\n",(0,r.jsx)(n.h3,{id:"port-mapping-and-volume-mount",children:"Port Mapping and Volume Mount"}),"\n",(0,r.jsx)(n.p,{children:"Two additional configuration elements are essential for SSO to function:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"-p 8000:8000 -p 9000:9000 \\\n"})}),"\n",(0,r.jsx)(n.p,{children:"Both the main UI port (8000) and the OAuth2 service port (9000) must be mapped to the host machine. This allows external access to both services, which is necessary for the authentication flow to complete successfully."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"-v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\\n"})}),"\n",(0,r.jsxs)(n.p,{children:["The volume mount makes your OAuth2 configuration files available inside the container at the expected location. Replace ",(0,r.jsx)(n.code,{children:"<YOUR_NAMED_DOCKER_VOLUME>"})," with the path to your Named Docker Volume containing the oauth2_server.yaml and oauth2_config.yaml files."]}),"\n",(0,r.jsx)(n.h2,{id:"verifying-your-sso-configuration",children:"Verifying Your SSO Configuration"}),"\n",(0,r.jsx)(n.p,{children:"After starting the container, you can verify that SSO is working correctly:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Navigate to ",(0,r.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"})," in your web browser"]}),"\n",(0,r.jsx)(n.li,{children:"You should be automatically redirected to your OAuth2 provider's login page"}),"\n",(0,r.jsx)(n.li,{children:"After entering your credentials, you should be redirected back to the Agent Mesh Enterprise UI"}),"\n",(0,r.jsxs)(n.li,{children:["Check the container logs for any authentication errors: ",(0,r.jsx)(n.code,{children:"docker logs sam-ent-prod-sso"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"If you encounter issues, check that:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Your OAuth2 provider credentials are correct"}),"\n",(0,r.jsx)(n.li,{children:"The redirect URI in your provider's configuration matches the EXTERNAL_AUTH_CALLBACK value"}),"\n",(0,r.jsx)(n.li,{children:"Both ports (8000 and 9000) are accessible from your network"}),"\n",(0,r.jsx)(n.li,{children:"The configuration files are properly mounted in the container"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"understanding-the-oauth2-flow-and-environment-variables",children:"Understanding the OAuth2 Flow and Environment Variables"}),"\n",(0,r.jsx)(n.p,{children:"When using SSO, it\u2019s important to understand how the authentication flow works between the WebUI Gateway, the OAuth2 service, and your identity provider (IdP). This section clarifies the purpose of each variable and common configuration mistakes."}),"\n",(0,r.jsx)(n.h3,{id:"how-the-oauth2-flow-works",children:"How the OAuth2 Flow Works"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["A user opens the frontend application (for example, ",(0,r.jsx)(n.code,{children:"http://localhost:8000"}),").","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The frontend checks whether a valid access token exists (e.g., in local storage or cookies)."}),"\n",(0,r.jsxs)(n.li,{children:["If no valid token is found or the token has expired, the frontend automatically calls the backend endpoint defined by ",(0,r.jsx)(n.code,{children:"FRONTEND_AUTH_LOGIN_URL"})," (for example, ",(0,r.jsx)(n.code,{children:"http://localhost:8000/api/v1/auth/login"}),") to start the authentication process."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["The WebUI Gateway calls the ",(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_SERVICE_URL"})," (typically ",(0,r.jsx)(n.code,{children:"http://localhost:9000"}),") and passes the ",(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_PROVIDER"})," value (such as ",(0,r.jsx)(n.code,{children:"azure"})," or ",(0,r.jsx)(n.code,{children:"keycloak"})," or ",(0,r.jsx)(n.code,{children:"auth0"}),", or ",(0,r.jsx)(n.code,{children:"google"}),")."]}),"\n",(0,r.jsxs)(n.li,{children:["The OAuth2 service looks up the provider in ",(0,r.jsx)(n.code,{children:"oauth2_config.yaml"})," and automatically constructs the correct authorization request using the provider\u2019s ",(0,r.jsx)(n.code,{children:"issuer"}),", ",(0,r.jsx)(n.code,{children:"client_id"}),", ",(0,r.jsx)(n.code,{children:"redirect_uri"}),", and ",(0,r.jsx)(n.code,{children:"scope"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"The user is redirected to the IdP (e.g., Azure AD, Auth0, or Keycloak) for login."}),"\n",(0,r.jsxs)(n.li,{children:["After successful login, the IdP redirects back to ",(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_CALLBACK"})," (for example, ",(0,r.jsx)(n.code,{children:"http://localhost:8000/api/v1/auth/callback"}),")."]}),"\n",(0,r.jsx)(n.li,{children:"The OAuth2 service exchanges the authorization code for tokens and finalizes authentication."}),"\n"]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Note:"}),(0,r.jsx)(n.br,{}),"\n","You do ",(0,r.jsx)(n.em,{children:"not"})," need to manually append ",(0,r.jsx)(n.code,{children:"client_id"}),", ",(0,r.jsx)(n.code,{children:"scope"}),", or ",(0,r.jsx)(n.code,{children:"redirect_uri"})," query parameters to the login URL.",(0,r.jsx)(n.br,{}),"\n","The OAuth2 service automatically handles these based on the selected provider in ",(0,r.jsx)(n.code,{children:"oauth2_config.yaml"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"common-environment-variables",children:"Common Environment Variables"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Variable"}),(0,r.jsx)(n.th,{children:"Purpose"}),(0,r.jsx)(n.th,{children:"Example"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"FRONTEND_AUTH_LOGIN_URL"})}),(0,r.jsxs)(n.td,{children:["The frontend endpoint that triggers authentication. It should ",(0,r.jsx)(n.strong,{children:"not"})," include OAuth query parameters."]}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"http://localhost:8000/api/v1/auth/login"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_SERVICE_URL"})}),(0,r.jsx)(n.td,{children:"URL of the OAuth2 authentication service."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"http://localhost:9000"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_PROVIDER"})}),(0,r.jsxs)(n.td,{children:["The IdP name as defined under ",(0,r.jsx)(n.code,{children:"providers:"})," in ",(0,r.jsx)(n.code,{children:"oauth2_config.yaml"}),"."]}),(0,r.jsxs)(n.td,{children:[(0,r.jsx)(n.code,{children:"azure"})," or ",(0,r.jsx)(n.code,{children:"keycloak"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"EXTERNAL_AUTH_CALLBACK"})}),(0,r.jsx)(n.td,{children:"Callback URI used after login. Must match the redirect URI registered with your IdP."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"http://localhost:8000/api/v1/auth/callback"})})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"FRONTEND_REDIRECT_URL"})}),(0,r.jsx)(n.td,{children:"Where users are redirected after login completes."}),(0,r.jsx)(n.td,{children:(0,r.jsx)(n.code,{children:"http://localhost:8000"})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"security-considerations-for-production",children:"Security Considerations for Production"}),"\n",(0,r.jsx)(n.p,{children:"When deploying SSO in a production environment, follow these security best practices:"}),"\n",(0,r.jsx)(n.p,{children:'Set OAUTH2_DEV_MODE to "false" to disable insecure transport and enforce proper token validation. This ensures that all OAuth2 communication uses HTTPS with valid SSL certificates.'}),"\n",(0,r.jsx)(n.p,{children:"Use HTTPS for all URLs (FRONTEND_REDIRECT_URL, FRONTEND_AUTH_LOGIN_URL, EXTERNAL_AUTH_SERVICE_URL, and EXTERNAL_AUTH_CALLBACK). Configure SSL certificates using the ssl_cert and ssl_key parameters in oauth2_server.yaml."}),"\n",(0,r.jsx)(n.p,{children:'Restrict CORS origins by setting OAUTH2_CORS_ORIGINS to your specific domain instead of using the wildcard "*". This prevents unauthorized websites from making requests to your authentication service.'}),"\n",(0,r.jsx)(n.p,{children:"Regularly rotate your OAuth2 client secrets and update the corresponding environment variables. Store sensitive credentials securely using Docker secrets or a secrets management service rather than passing them directly in the command line."}),"\n",(0,r.jsx)(n.p,{children:"Configure appropriate session timeouts based on your security requirements. Shorter timeouts increase security but may inconvenience users who need to reauthenticate more frequently."}),"\n",(0,r.jsx)(n.p,{children:"Monitor authentication logs for suspicious activity and failed login attempts. The OAuth2 service logs all authentication events, which you can review for security auditing."})]})}function d(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>a});var i=t(6540);const r={},o=i.createContext(r);function s(e){const n=i.useContext(o);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:s(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[6084],{4795:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/developing/tutorials/custom-agent","title":"Build Your Own Agent","description":"This tutorial shows you how to build a sophisticated weather agent using the Agent Mesh framework. Learn how to integrate with external APIs, manage resources properly, and create production-ready agents.","source":"@site/docs/documentation/developing/tutorials/custom-agent.md","sourceDirName":"documentation/developing/tutorials","slug":"/documentation/developing/tutorials/custom-agent","permalink":"/solace-agent-mesh/docs/documentation/developing/tutorials/custom-agent","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/developing/tutorials/custom-agent.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Build Your Own Agent","sidebar_position":5},"sidebar":"docSidebar","previous":{"title":"Evaluating Agents","permalink":"/solace-agent-mesh/docs/documentation/developing/evaluations"},"next":{"title":"MCP Integration","permalink":"/solace-agent-mesh/docs/documentation/developing/tutorials/mcp-integration"}}');var r=t(4848),o=t(8453);const i={title:"Build Your Own Agent",sidebar_position:5},s="Build Your Own Agent",c={},l=[{value:"Overview",id:"overview",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Planning the Weather Agent",id:"planning-the-weather-agent",level:2},{value:"Step 1: Project Structure",id:"step-1-project-structure",level:2},{value:"Step 2: Weather Service Implementation",id:"step-2-weather-service-implementation",level:2},{value:"Step 3: Weather Tools Implementation",id:"step-3-weather-tools-implementation",level:2},{value:"Step 4: Lifecycle Functions",id:"step-4-lifecycle-functions",level:2},{value:"Step 5: Agent Configuration",id:"step-5-agent-configuration",level:2},{value:"Step 6: Environment Setup",id:"step-6-environment-setup",level:2},{value:"Step 7: Running the Agent",id:"step-7-running-the-agent",level:2},{value:"Step 8: Testing the Weather Agent",id:"step-8-testing-the-weather-agent",level:2},{value:"Key Features Demonstrated",id:"key-features-demonstrated",level:2},{value:"1. External API Integration",id:"1-external-api-integration",level:3},{value:"2. Resource Management",id:"2-resource-management",level:3},{value:"3. Configuration Management",id:"3-configuration-management",level:3},{value:"4. Error Handling",id:"4-error-handling",level:3},{value:"5. Artifact Management",id:"5-artifact-management",level:3}];function d(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components},{Details:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Details",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"build-your-own-agent",children:"Build Your Own Agent"})}),"\n",(0,r.jsx)(n.p,{children:"This tutorial shows you how to build a sophisticated weather agent using the Agent Mesh framework. Learn how to integrate with external APIs, manage resources properly, and create production-ready agents."}),"\n",(0,r.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,r.jsx)(n.p,{children:"Our weather agent will demonstrate:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"External API integration (OpenWeatherMap)"}),"\n",(0,r.jsx)(n.li,{children:"Professional service layer architecture"}),"\n",(0,r.jsx)(n.li,{children:"Multiple sophisticated tools"}),"\n",(0,r.jsx)(n.li,{children:"Proper lifecycle management"}),"\n",(0,r.jsx)(n.li,{children:"Error handling and validation"}),"\n",(0,r.jsx)(n.li,{children:"Artifact creation and management"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsx)(n.p,{children:"Before starting this tutorial, make sure you have:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Read the ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents",children:"Create Agent"})," tutorial"]}),"\n",(0,r.jsxs)(n.li,{children:["An OpenWeatherMap API key (free at ",(0,r.jsx)(n.a,{href:"https://openweathermap.org/api",children:"openweathermap.org"}),")"]}),"\n",(0,r.jsx)(n.li,{children:"Basic understanding of Python async/await"}),"\n",(0,r.jsx)(n.li,{children:"Familiarity with HTTP APIs"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"planning-the-weather-agent",children:"Planning the Weather Agent"}),"\n",(0,r.jsx)(n.p,{children:"Our weather agent will have the following capabilities:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Get Current Weather"}),": Fetch current weather conditions for a specified location"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Get Weather Forecast"}),": Retrieve a multi-day weather forecast"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Save Weather Reports"}),": Store weather data as artifacts"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"The agent will demonstrate:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"External API integration"}),"\n",(0,r.jsx)(n.li,{children:"Error handling and validation"}),"\n",(0,r.jsx)(n.li,{children:"Configuration management"}),"\n",(0,r.jsx)(n.li,{children:"Artifact creation"}),"\n",(0,r.jsx)(n.li,{children:"Resource lifecycle management"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"step-1-project-structure",children:"Step 1: Project Structure"}),"\n",(0,r.jsx)(n.p,{children:"Run the following command to create a new custom agent:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sam add agent --gui\n"})}),"\n",(0,r.jsxs)(n.admonition,{type:"tip",children:[(0,r.jsxs)(n.p,{children:["You can create an agent either by using the ",(0,r.jsx)(n.code,{children:"sam add agent"})," command or by creating a new plugin of type agent, ",(0,r.jsx)(n.code,{children:"sam plugin create my-hello-agent --type agent"}),"."]}),(0,r.jsxs)(n.p,{children:["For information and recommendations about these options, see ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/plugins#agent-or-plugin-which-to-use",children:(0,r.jsx)(n.code,{children:"Agent or Plugin: Which To use?"})}),"."]}),(0,r.jsxs)(n.p,{children:["For an example of plugin agents, see the ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents#creating-your-first-agent-step-by-step",children:"Create Agents"})," guide."]})]}),"\n",(0,r.jsx)(n.p,{children:'Follow the steps on the GUI to create a new agent named "Weather Agent". We can update the tools/skills section directly in the configuration file later.'}),"\n",(0,r.jsxs)(n.admonition,{title:"Important Notice",type:"warning",children:[(0,r.jsx)(n.p,{children:"This tutorial is intentionally comprehensive to demonstrate the full flexibility and advanced features available in Agent Mesh agents. For most straightforward use cases, you only need a simple Python function and a corresponding reference in your YAML configuration file."}),(0,r.jsxs)(t,{children:[(0,r.jsx)("summary",{children:"Simple Weather Agent Example"}),(0,r.jsxs)(n.p,{children:["After going through the add agent wizard from ",(0,r.jsx)(n.code,{children:"sam add agent --gui"}),", create the following file under ",(0,r.jsx)(n.code,{children:"src/weather_agent/tools.py"})," directory:"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-py",children:'# src/weather_agent/tools.py\nimport httpx\nfrom typing import Any, Dict, Optional\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\n\n\nasync def get_current_weather(\n location: str,\n units: str = "metric",\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Get current weather conditions for a specified location.\n \n Args:\n location: City name, state, and country (for example, "New York, NY, US")\n units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin"\n """\n log.info("[GetCurrentWeather] Getting current weather for: %s", location)\n base_url = "https://api.openweathermap.org/data/2.5"\n api_key = tool_config.get("api_key") if tool_config else None\n\n url = f"{base_url}/weather"\n params = {\n "q": location,\n "appid": api_key,\n "units": units\n }\n\n try:\n # Fetch weather data\n async with httpx.AsyncClient() as client:\n response = await client.get(url, params=params)\n response.raise_for_status()\n weather_data = response.json()\n \n result = {\n "status": "success",\n "location": location,\n "units": units,\n "data": weather_data\n }\n return result\n \n except Exception as e:\n log.error(f"[GetCurrentWeather] Error getting weather: {e}")\n return {\n "status": "error",\n "message": f"Weather service error: {str(e)}"\n }\n\n\nasync def get_weather_forecast(\n location: str,\n days: int = 5,\n units: str = "metric",\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Get weather forecast for a specified location.\n \n Args:\n location: City name, state, and country\n days: Number of days for forecast (1-5)\n units: Temperature units\n """\n log.info("[GetWeatherForecast] Getting %d-day forecast for: %s", days, location)\n base_url = "https://api.openweathermap.org/data/2.5"\n api_key = tool_config.get("api_key") if tool_config else None\n\n url = f"{base_url}/forecast"\n params = {\n "q": location,\n "appid": api_key,\n "units": units,\n "cnt": min(days * 8, 40) \n }\n\n try:\n # Fetch forecast data\n async with httpx.AsyncClient() as client:\n response = await client.get(url, params=params)\n response.raise_for_status()\n forecast_data = response.json()\n\n result = {\n "status": "success",\n "location": forecast_data["location"],\n "days": days,\n "units": units,\n "data": forecast_data\n }\n return result\n except Exception as e:\n log.error(f"[GetWeatherForecast] Error getting forecast: {e}")\n return {\n "status": "error",\n "message": f"Weather service error: {str(e)}"\n }\n\n'})}),(0,r.jsxs)(n.p,{children:["And update the weather agent config file's tool section under ",(0,r.jsx)(n.code,{children:"configs/agent/weather-agent.yaml"})," as follows:"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:' # Tools configuration\n tools:\n # Current weather tool\n - tool_type: python\n component_module: "src.weather_agent.tools"\n component_base_path: .\n function_name: "get_current_weather"\n tool_description: "Get current weather conditions for a specified location"\n tool_config:\n api_key: ${OPENWEATHER_API_KEY}\n\n # Weather forecast tool\n - tool_type: python\n component_module: "src.weather_agent.tools"\n function_name: "get_weather_forecast"\n component_base_path: .\n tool_description: "Get weather forecast for up to 5 days for a specified location"\n tool_config:\n api_key: ${OPENWEATHER_API_KEY}\n\n'})}),(0,r.jsxs)(n.p,{children:["For better discoverability, update the ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/agents#agent-card",children:"agent card"})," section in the same YAML file as follows:"]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:' # Agent card\n agent_card:\n description: "Professional weather agent providing current conditions, forecasts, and weather comparisons"\n defaultInputModes: ["text"]\n defaultOutputModes: ["text"]\n skills:\n - id: "get_current_weather"\n name: "Get Current Weather"\n description: "Retrieve current weather conditions for any location worldwide"\n - id: "get_weather_forecast"\n name: "Get Weather Forecast"\n description: "Provide detailed weather forecasts up to 5 days ahead"\n'})}),(0,r.jsxs)(n.p,{children:["To run the agent, you can continue following documentation from ",(0,r.jsx)(n.a,{href:"#step-6-environment-setup",children:"Step 6"})," of this tutorial."]})]}),(0,r.jsx)(n.p,{children:"Other concepts mentioned in this page such as lifecycle, services, artifacts are just to showcase more advanced patterns."})]}),"\n",(0,r.jsx)(n.p,{children:"Create the directory structure for the weather agent:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sam-project/\n\u251c\u2500\u2500 src/\n\u2502 \u2514\u2500\u2500 weather_agent/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 tools.py\n\u2502 \u251c\u2500\u2500 lifecycle.py\n\u2502 \u2514\u2500\u2500 services/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u2514\u2500\u2500 weather_service.py\n\u251c\u2500\u2500 configs\n\u2502 \u2514\u2500\u2500 shared_config.yaml\n\u2502 \u2514\u2500\u2500 agents/\n\u2502 \u2514\u2500\u2500 weather_agent.yaml\n...\n"})}),"\n",(0,r.jsxs)(n.admonition,{type:"tip",children:[(0,r.jsxs)(n.p,{children:["In Agent Mesh, you can create an agent either by using the ",(0,r.jsx)(n.code,{children:"sam add agent"})," command or by creating a new plugin of type agent, ",(0,r.jsx)(n.code,{children:"sam plugin create your-agent --type agent"}),"."]}),(0,r.jsxs)(n.p,{children:["This tutorial uses the ",(0,r.jsx)(n.code,{children:"sam add agent"}),' command to create a new agent named "Weather Agent", for an example of creating a custom agent plugin, see the ',(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/developing/create-agents",children:"Create Agents"})," tutorial."]})]}),"\n",(0,r.jsx)(n.h2,{id:"step-2-weather-service-implementation",children:"Step 2: Weather Service Implementation"}),"\n",(0,r.jsx)(n.p,{children:"First, create a service class to handle weather API interactions:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.code,{children:"src/weather_agent/services/weather_service.py"}),":"]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'"""\nWeather service for interacting with external weather APIs.\n"""\n\nimport aiohttp\nfrom typing import Dict, Any, Optional, List\nfrom datetime import datetime, timezone\nfrom solace_ai_connector.common.log import log\n\n\nclass WeatherService:\n """Service for fetching weather data from external APIs."""\n \n def __init__(self, api_key: str, base_url: str = "https://api.openweathermap.org/data/2.5"):\n self.api_key = api_key\n self.base_url = base_url\n self.session: Optional[aiohttp.ClientSession] = None\n self.log_identifier = "[WeatherService]"\n \n async def _get_session(self) -> aiohttp.ClientSession:\n """Get or create an HTTP session."""\n if self.session is None or self.session.closed:\n self.session = aiohttp.ClientSession()\n return self.session\n \n async def close(self):\n """Close the HTTP session."""\n if self.session and not self.session.closed:\n await self.session.close()\n log.info(f"{self.log_identifier} HTTP session closed")\n \n async def get_current_weather(self, location: str, units: str = "metric") -> Dict[str, Any]:\n """\n Get current weather for a location.\n \n Args:\n location: City name, state code, and country code (for example, "London,UK")\n units: Temperature units (metric, imperial, kelvin)\n \n Returns:\n Dictionary containing current weather data\n """\n log.info(f"{self.log_identifier} Fetching current weather for: {location}")\n \n session = await self._get_session()\n url = f"{self.base_url}/weather"\n params = {\n "q": location,\n "appid": self.api_key,\n "units": units\n }\n \n try:\n async with session.get(url, params=params) as response:\n if response.status == 200:\n data = await response.json()\n log.info(f"{self.log_identifier} Successfully fetched weather for {location}")\n return self._format_current_weather(data)\n elif response.status == 404:\n raise ValueError(f"Location \'{location}\' not found")\n else:\n error_data = await response.json()\n raise Exception(f"Weather API error: {error_data.get(\'message\', \'Unknown error\')}")\n \n except aiohttp.ClientError as e:\n log.error(f"{self.log_identifier} Network error fetching weather: {e}")\n raise Exception(f"Network error: {str(e)}")\n \n async def get_weather_forecast(self, location: str, days: int = 5, units: str = "metric") -> Dict[str, Any]:\n """\n Get weather forecast for a location.\n \n Args:\n location: City name, state code, and country code\n days: Number of days for forecast (1-5)\n units: Temperature units\n \n Returns:\n Dictionary containing forecast data\n """\n log.info(f"{self.log_identifier} Fetching {days}-day forecast for: {location}")\n \n session = await self._get_session()\n url = f"{self.base_url}/forecast"\n params = {\n "q": location,\n "appid": self.api_key,\n "units": units,\n "cnt": min(days * 8, 40) # API returns 3-hour intervals, max 40 entries\n }\n \n try:\n async with session.get(url, params=params) as response:\n if response.status == 200:\n data = await response.json()\n log.info(f"{self.log_identifier} Successfully fetched forecast for {location}")\n return self._format_forecast_data(data, days)\n elif response.status == 404:\n raise ValueError(f"Location \'{location}\' not found")\n else:\n error_data = await response.json()\n raise Exception(f"Weather API error: {error_data.get(\'message\', \'Unknown error\')}")\n \n except aiohttp.ClientError as e:\n log.error(f"{self.log_identifier} Network error fetching forecast: {e}")\n raise Exception(f"Network error: {str(e)}")\n \n def _format_current_weather(self, data: Dict) -> Dict[str, Any]:\n """Format current weather data for consistent output."""\n return {\n "location": f"{data[\'name\']}, {data[\'sys\'][\'country\']}",\n "temperature": data[\'main\'][\'temp\'],\n "feels_like": data[\'main\'][\'feels_like\'],\n "humidity": data[\'main\'][\'humidity\'],\n "pressure": data[\'main\'][\'pressure\'],\n "description": data[\'weather\'][0][\'description\'].title(),\n "wind_speed": data.get(\'wind\', {}).get(\'speed\', 0),\n "wind_direction": data.get(\'wind\', {}).get(\'deg\', 0),\n "visibility": data.get(\'visibility\', 0) / 1000, # Convert to km\n "timestamp": datetime.fromtimestamp(data[\'dt\']).isoformat(),\n "sunrise": datetime.fromtimestamp(data[\'sys\'][\'sunrise\']).isoformat(),\n "sunset": datetime.fromtimestamp(data[\'sys\'][\'sunset\']).isoformat()\n }\n \n def _format_forecast_data(self, data: Dict, days: int) -> Dict[str, Any]:\n """Format forecast data for consistent output."""\n forecasts = []\n current_date = None\n daily_data = []\n \n for item in data[\'list\'][:days * 8]:\n forecast_date = datetime.fromtimestamp(item[\'dt\']).date()\n \n if current_date != forecast_date:\n if daily_data:\n forecasts.append(self._aggregate_daily_forecast(daily_data))\n current_date = forecast_date\n daily_data = []\n \n daily_data.append(item)\n \n # Add the last day\'s data\n if daily_data:\n forecasts.append(self._aggregate_daily_forecast(daily_data))\n \n return {\n "location": f"{data[\'city\'][\'name\']}, {data[\'city\'][\'country\']}",\n "forecasts": forecasts[:days]\n }\n \n def _aggregate_daily_forecast(self, daily_data: List[Dict]) -> Dict[str, Any]:\n """Aggregate 3-hour forecasts into daily summary."""\n if not daily_data:\n return {}\n \n # Get temperatures for min/max calculation\n temps = [item[\'main\'][\'temp\'] for item in daily_data]\n \n # Use the forecast closest to noon for general conditions\n noon_forecast = min(daily_data, key=lambda x: abs(\n datetime.fromtimestamp(x[\'dt\']).hour - 12\n ))\n \n return {\n "date": datetime.fromtimestamp(daily_data[0][\'dt\']).date().isoformat(),\n "temperature_min": min(temps),\n "temperature_max": max(temps),\n "description": noon_forecast[\'weather\'][0][\'description\'].title(),\n "humidity": noon_forecast[\'main\'][\'humidity\'],\n "wind_speed": noon_forecast.get(\'wind\', {}).get(\'speed\', 0),\n "precipitation_probability": noon_forecast.get(\'pop\', 0) * 100\n }\n'})}),"\n",(0,r.jsx)(n.h2,{id:"step-3-weather-tools-implementation",children:"Step 3: Weather Tools Implementation"}),"\n",(0,r.jsx)(n.p,{children:"Now create the tool functions:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.code,{children:"src/weather_agent/tools.py"}),":"]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'"""\nWeather agent tools for fetching and processing weather data.\n"""\n\nimport json\nfrom typing import Any, Dict, Optional\nfrom datetime import datetime, timezone\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\nfrom solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata\n\nasync def get_current_weather(\n location: str,\n units: str = "metric",\n save_to_file: bool = False,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Get current weather conditions for a specified location.\n \n Args:\n location: City name, state, and country (for example, "New York, NY, US")\n units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin"\n save_to_file: Whether to save the weather report as an artifact\n \n Returns:\n Dictionary containing current weather information\n """\n log_identifier = "[GetCurrentWeather]"\n log.info(f"{log_identifier} Getting current weather for: {location}")\n \n if not tool_context:\n return {\n "status": "error",\n "message": "Tool context is required for weather operations"\n }\n \n try:\n # Get weather service from agent state\n host_component = getattr(tool_context._invocation_context, "agent", None)\n if host_component:\n host_component = getattr(host_component, "host_component", None)\n \n if not host_component:\n return {\n "status": "error",\n "message": "Could not access agent host component"\n }\n \n weather_service = host_component.get_agent_specific_state("weather_service")\n if not weather_service:\n return {\n "status": "error",\n "message": "Weather service not initialized"\n }\n \n # Fetch weather data\n weather_data = await weather_service.get_current_weather(location, units)\n \n # Create human-readable summary\n summary = _create_weather_summary(weather_data)\n \n result = {\n "status": "success",\n "location": weather_data["location"],\n "summary": summary,\n "data": weather_data\n }\n \n # Save to artifact if requested\n if save_to_file:\n artifact_result = await _save_weather_artifact(\n weather_data, f"current_weather_{location}", tool_context\n )\n result["artifact"] = artifact_result\n \n log.info(f"{log_identifier} Successfully retrieved weather for {location}")\n return result\n \n except ValueError as e:\n log.warning(f"{log_identifier} Invalid location: {e}")\n return {\n "status": "error",\n "message": f"Location error: {str(e)}"\n }\n except Exception as e:\n log.error(f"{log_identifier} Error getting weather: {e}")\n return {\n "status": "error",\n "message": f"Weather service error: {str(e)}"\n }\n\n\nasync def get_weather_forecast(\n location: str,\n days: int = 5,\n units: str = "metric",\n save_to_file: bool = False,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Get weather forecast for a specified location.\n \n Args:\n location: City name, state, and country\n days: Number of days for forecast (1-5)\n units: Temperature units\n save_to_file: Whether to save the forecast as an artifact\n \n Returns:\n Dictionary containing weather forecast information\n """\n log_identifier = "[GetWeatherForecast]"\n log.info(f"{log_identifier} Getting {days}-day forecast for: {location}")\n \n if not tool_context:\n return {\n "status": "error",\n "message": "Tool context is required for weather operations"\n }\n \n # Validate days parameter\n if not 1 <= days <= 5:\n return {\n "status": "error",\n "message": "Days must be between 1 and 5"\n }\n \n try:\n # Get weather service from agent state\n host_component = getattr(tool_context._invocation_context, "agent", None)\n if host_component:\n host_component = getattr(host_component, "host_component", None)\n \n if not host_component:\n return {\n "status": "error",\n "message": "Could not access agent host component"\n }\n \n weather_service = host_component.get_agent_specific_state("weather_service")\n if not weather_service:\n return {\n "status": "error",\n "message": "Weather service not initialized"\n }\n \n # Fetch forecast data\n forecast_data = await weather_service.get_weather_forecast(location, days, units)\n \n # Create human-readable summary\n summary = _create_forecast_summary(forecast_data)\n \n result = {\n "status": "success",\n "location": forecast_data["location"],\n "summary": summary,\n "data": forecast_data\n }\n \n # Save to artifact if requested\n if save_to_file:\n artifact_result = await _save_weather_artifact(\n forecast_data, f"forecast_{location}_{days}day", tool_context\n )\n result["artifact"] = artifact_result\n \n log.info(f"{log_identifier} Successfully retrieved forecast for {location}")\n return result\n \n except ValueError as e:\n log.warning(f"{log_identifier} Invalid location: {e}")\n return {\n "status": "error",\n "message": f"Location error: {str(e)}"\n }\n except Exception as e:\n log.error(f"{log_identifier} Error getting forecast: {e}")\n return {\n "status": "error",\n "message": f"Weather service error: {str(e)}"\n }\n\n\ndef _create_weather_summary(weather_data: Dict[str, Any]) -> str:\n """Create a human-readable weather summary."""\n temp_unit = "\xb0C" # Assuming metric units for summary\n \n summary = f"Current weather in {weather_data[\'location\']}:\\n"\n summary += f"\u2022 Temperature: {weather_data[\'temperature\']}{temp_unit} (feels like {weather_data[\'feels_like\']}{temp_unit})\\n"\n summary += f"\u2022 Conditions: {weather_data[\'description\']}\\n"\n summary += f"\u2022 Humidity: {weather_data[\'humidity\']}%\\n"\n summary += f"\u2022 Wind: {weather_data[\'wind_speed\']} m/s\\n"\n summary += f"\u2022 Visibility: {weather_data[\'visibility\']} km"\n \n return summary\n\n\ndef _create_forecast_summary(forecast_data: Dict[str, Any]) -> str:\n """Create a human-readable forecast summary."""\n summary = f"Weather forecast for {forecast_data[\'location\']}:\\n\\n"\n \n for forecast in forecast_data[\'forecasts\']:\n date = datetime.fromisoformat(forecast[\'date\']).strftime(\'%A, %B %d\')\n summary += f"\u2022 {date}: {forecast[\'description\']}\\n"\n summary += f" High: {forecast[\'temperature_max\']:.1f}\xb0C, Low: {forecast[\'temperature_min\']:.1f}\xb0C\\n"\n if forecast[\'precipitation_probability\'] > 0:\n summary += f" Precipitation: {forecast[\'precipitation_probability\']:.0f}% chance\\n"\n summary += "\\n"\n \n return summary.strip()\n\n\nasync def _save_weather_artifact(\n weather_data: Dict[str, Any],\n filename_base: str,\n tool_context: ToolContext\n) -> Dict[str, Any]:\n """Save weather data as an artifact."""\n try:\n # Prepare content\n content = json.dumps(weather_data, indent=2, default=str)\n timestamp = datetime.now(timezone.utc)\n filename = f"{filename_base}_{timestamp.strftime(\'%Y%m%d_%H%M%S\')}.json"\n \n # Save artifact\n artifact_service = tool_context._invocation_context.artifact_service\n result = await save_artifact_with_metadata(\n artifact_service=artifact_service,\n app_name=tool_context._invocation_context.app_name,\n user_id=tool_context._invocation_context.user_id,\n session_id=tool_context._invocation_context.session.id,\n filename=filename,\n content_bytes=content.encode(\'utf-8\'),\n mime_type="application/json",\n metadata_dict={\n "description": "Weather data report",\n "source": "Weather Agent"\n },\n timestamp=timestamp\n )\n \n return {\n "filename": filename,\n "status": result.get("status", "success")\n }\n \n except Exception as e:\n log.error(f"[WeatherArtifact] Error saving artifact: {e}")\n return {\n "status": "error",\n "message": f"Failed to save artifact: {str(e)}"\n }\n'})}),"\n",(0,r.jsx)(n.h2,{id:"step-4-lifecycle-functions",children:"Step 4: Lifecycle Functions"}),"\n",(0,r.jsx)(n.p,{children:"Create the lifecycle management:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:[(0,r.jsx)(n.code,{children:"src/weather_agent/lifecycle.py"}),":"]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-python",children:'"""\nLifecycle functions for the Weather Agent.\n"""\n\nfrom typing import Any\nimport asyncio\nfrom pydantic import BaseModel, Field, SecretStr\nfrom solace_ai_connector.common.log import log\nfrom .services.weather_service import WeatherService\n\n\nclass WeatherAgentInitConfig(BaseModel):\n """\n Configuration model for Weather Agent initialization.\n """\n api_key: SecretStr = Field(description="OpenWeatherMap API key")\n base_url: str = Field(\n default="https://api.openweathermap.org/data/2.5",\n description="Weather API base URL"\n )\n startup_message: str = Field(\n default="Weather Agent is ready to provide weather information!",\n description="Message to log on startup"\n )\n\n\ndef initialize_weather_agent(host_component: Any, init_config: WeatherAgentInitConfig):\n """\n Initialize the Weather Agent with weather service.\n \n Args:\n host_component: The agent host component\n init_config: Validated initialization configuration\n """\n log_identifier = f"[{host_component.agent_name}:init]"\n log.info(f"{log_identifier} Starting Weather Agent initialization...")\n \n try:\n # Initialize weather service\n weather_service = WeatherService(\n api_key=init_config.api_key.get_secret_value(),\n base_url=init_config.base_url\n )\n \n # Store service in agent state\n host_component.set_agent_specific_state("weather_service", weather_service)\n \n # Log startup message\n log.info(f"{log_identifier} {init_config.startup_message}")\n \n # Store initialization metadata\n host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z")\n host_component.set_agent_specific_state("weather_requests_count", 0)\n \n log.info(f"{log_identifier} Weather Agent initialization completed successfully")\n \n except Exception as e:\n log.error(f"{log_identifier} Failed to initialize Weather Agent: {e}")\n raise\n\n\ndef cleanup_weather_agent(host_component: Any):\n """\n Clean up Weather Agent resources.\n \n Args:\n host_component: The agent host component\n """\n log_identifier = f"[{host_component.agent_name}:cleanup]"\n log.info(f"{log_identifier} Starting Weather Agent cleanup...")\n\n async def cleanup_async(host_component: Any):\n try:\n # Get and close weather service\n weather_service = host_component.get_agent_specific_state("weather_service")\n if weather_service:\n await weather_service.close()\n log.info(f"{log_identifier} Weather service closed successfully")\n \n # Log final statistics\n request_count = host_component.get_agent_specific_state("weather_requests_count", 0)\n log.info(f"{log_identifier} Agent processed {request_count} weather requests during its lifetime")\n \n log.info(f"{log_identifier} Weather Agent cleanup completed")\n \n except Exception as e:\n log.error(f"{log_identifier} Error during cleanup: {e}")\n \n # run cleanup in the event loop\n loop = asyncio.get_event_loop()\n loop.run_until_complete(cleanup_async(host_component))\n log.info(f"{log_identifier} Weather Agent cleanup completed successfully")\n'})}),"\n",(0,r.jsx)(n.h2,{id:"step-5-agent-configuration",children:"Step 5: Agent Configuration"}),"\n",(0,r.jsx)(n.p,{children:"Create the comprehensive YAML configuration:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# Weather Agent Configuration\nlog:\n stdout_log_level: INFO\n log_file_level: DEBUG\n log_file: weather-agent.log\n\n!include ../shared_config.yaml\n\napps:\n - name: weather-agent\n # Broker configuration\n app_module: solace_agent_mesh.agent.sac.app\n broker:\n <<: *broker_connection\n\n app_config:\n namespace: "${NAMESPACE}"\n agent_name: "WeatherAgent"\n display_name: "Weather Information Agent"\n supports_streaming: true\n \n # LLM model configuration\n model: *general_model\n \n # Agent instructions\n instruction: |\n You are a professional weather agent that provides accurate, up-to-date weather information.\n \n Your capabilities include:\n 1. Getting current weather conditions for any location worldwide\n 2. Providing detailed weather forecasts up to 5 days\n 3. Saving weather reports as files for future reference\n \n Guidelines:\n - Always specify the location clearly when providing weather information\n - Include relevant details like temperature, conditions, humidity, and wind\n - Offer to save weather reports when providing detailed information\n - Be helpful in suggesting appropriate clothing or activities based on weather\n - If a location is ambiguous, ask for clarification (city, state/province, country)\n \n When users ask about weather, use the appropriate tools to fetch real-time data.\n Present information in a clear, organized manner that\'s easy to understand.\n \n # Lifecycle functions\n agent_init_function:\n module: "src.weather_agent.lifecycle"\n name: "initialize_weather_agent"\n base_path: .\n config:\n api_key: ${OPENWEATHER_API_KEY}\n base_url: "https://api.openweathermap.org/data/2.5"\n startup_message: "Weather Agent is ready to provide weather information!"\n \n agent_cleanup_function:\n module: "src.weather_agent.lifecycle"\n base_path: .\n name: "cleanup_weather_agent"\n \n # Tools configuration\n tools:\n # Current weather tool\n - tool_type: python\n component_module: "src.weather_agent.tools"\n component_base_path: .\n function_name: "get_current_weather"\n tool_description: "Get current weather conditions for a specified location"\n \n # Weather forecast tool\n - tool_type: python\n component_module: "src.weather_agent.tools"\n component_base_path: .\n function_name: "get_weather_forecast"\n tool_description: "Get weather forecast for up to 5 days for a specified location"\n \n # Built-in artifact tools for file operations\n - tool_type: builtin-group\n group_name: "artifact_management"\n \n session_service: *default_session_service\n artifact_service: *default_artifact_service\n\n artifact_handling_mode: "reference"\n enable_embed_resolution: true\n enable_artifact_content_instruction: true\n # Agent card\n agent_card:\n description: "Professional weather agent providing current conditions, forecasts, and weather comparisons"\n defaultInputModes: ["text"]\n defaultOutputModes: ["text", "file"]\n skills:\n - id: "get_current_weather"\n name: "Get Current Weather"\n description: "Retrieve current weather conditions for any location worldwide"\n - id: "get_weather_forecast"\n name: "Get Weather Forecast"\n description: "Provide detailed weather forecasts up to 5 days ahead"\n \n agent_card_publishing:\n interval_seconds: 30\n\n agent_discovery:\n enabled: false\n\n inter_agent_communication:\n allow_list: []\n request_timeout_seconds: 30\n'})}),"\n",(0,r.jsxs)(n.p,{children:["For more details on agent cards, see the ",(0,r.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/components/agents#agent-card",children:"Agent Card Concepts"})," documentation."]}),"\n",(0,r.jsx)(n.h2,{id:"step-6-environment-setup",children:"Step 6: Environment Setup"}),"\n",(0,r.jsx)(n.p,{children:"Before running your weather agent, you'll need to:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Get an OpenWeatherMap API key"}),":"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["Sign up at ",(0,r.jsx)(n.a,{href:"https://openweathermap.org/api",children:"OpenWeatherMap"})]}),"\n",(0,r.jsx)(n.li,{children:"Get your free API key"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Set environment variables"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:'export OPENWEATHER_API_KEY="your_api_key_here"\n# Other environment variables as needed\n'})}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"step-7-running-the-agent",children:"Step 7: Running the Agent"}),"\n",(0,r.jsxs)(n.p,{children:["To start the agent, it is preferred to build the plugin and then install it with your agent name. But for debugging or isolated development testing, you can run your agent from the ",(0,r.jsx)(n.code,{children:"src"})," directory directly using the Agent Mesh CLI."]}),"\n",(0,r.jsx)(n.p,{children:"Start your weather agent for development purposes run:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sam run\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["To solely run the agent, use ",(0,r.jsx)(n.code,{children:"sam run configs/agents/weather_agent.yaml"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"step-8-testing-the-weather-agent",children:"Step 8: Testing the Weather Agent"}),"\n",(0,r.jsx)(n.p,{children:"You can test your weather agent with these example requests:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Current Weather:"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:'"What\'s the current weather in New York City?"'}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Weather Forecast:"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:'"Can you give me a 5-day forecast for London, UK and save it to a file?"'}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Weather with File Save:"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:'"Get the current weather for Tokyo, Japan and save the report"'}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"key-features-demonstrated",children:"Key Features Demonstrated"}),"\n",(0,r.jsx)(n.h3,{id:"1-external-api-integration",children:"1. External API Integration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Proper HTTP session management"}),"\n",(0,r.jsx)(n.li,{children:"Error handling for network issues"}),"\n",(0,r.jsx)(n.li,{children:"API response transformation"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"2-resource-management",children:"2. Resource Management"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Lifecycle functions for initialization and cleanup"}),"\n",(0,r.jsx)(n.li,{children:"Shared service instances across tool calls"}),"\n",(0,r.jsx)(n.li,{children:"Proper resource disposal"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"3-configuration-management",children:"3. Configuration Management"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Pydantic models for type-safe configuration"}),"\n",(0,r.jsx)(n.li,{children:"Environment variable integration"}),"\n",(0,r.jsx)(n.li,{children:"Flexible tool configuration"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"4-error-handling",children:"4. Error Handling"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Comprehensive exception handling"}),"\n",(0,r.jsx)(n.li,{children:"User-friendly error messages"}),"\n",(0,r.jsx)(n.li,{children:"Logging for debugging"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"5-artifact-management",children:"5. Artifact Management"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Saving structured data as files"}),"\n",(0,r.jsx)(n.li,{children:"Metadata enrichment"}),"\n",(0,r.jsx)(n.li,{children:"File format handling"}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>s});var a=t(6540);const r={},o=a.createContext(r);function i(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[5525],{5822:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/installing-and-configuring/configurations","title":"Configuring Agent Mesh","description":"The shared_config.yaml file is used to define configurations that can be shared across multiple agents or components in Agent Mesh. This centralized approach simplifies management of common configurations such as Solace event broker connections, language model settings, and service definitions.","source":"@site/docs/documentation/installing-and-configuring/configurations.md","sourceDirName":"documentation/installing-and-configuring","slug":"/documentation/installing-and-configuring/configurations","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/configurations","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/installing-and-configuring/configurations.md","tags":[],"version":"current","sidebarPosition":330,"frontMatter":{"title":"Configuring Agent Mesh","sidebar_position":330,"toc_max_heading_level":4},"sidebar":"docSidebar","previous":{"title":"Creating and Running an Agent Mesh Project","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/run-project"},"next":{"title":"Configuring LLMs","permalink":"/solace-agent-mesh/docs/documentation/installing-and-configuring/large_language_models"}}');var s=n(4848),r=n(8453);const l={title:"Configuring Agent Mesh",sidebar_position:330,toc_max_heading_level:4},o=void 0,d={},c=[{value:"Understanding Shared Configuration",id:"understanding-shared-configuration",level:2},{value:"Managing Multiple Shared Configuration Files",id:"managing-multiple-shared-configuration-files",level:3},{value:"Configuration Structure",id:"configuration-structure",level:2},{value:"Event Broker Connection",id:"event-broker-connection",level:2},{value:"LLM Configuration",id:"llm-configuration",level:2},{value:"Model Configuration Parameters",id:"model-configuration-parameters",level:3},{value:"Predefined Model Types",id:"predefined-model-types",level:3},{value:"Service Configuration",id:"service-configuration",level:2},{value:"Session Service",id:"session-service",level:3},{value:"Artifact Service",id:"artifact-service",level:3},{value:"Data Tools Configuration",id:"data-tools-configuration",level:3}];function a(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"shared_config.yaml"})," file is used to define configurations that can be shared across multiple agents or components in Agent Mesh. This centralized approach simplifies management of common configurations such as Solace event broker connections, language model settings, and service definitions."]}),"\n",(0,s.jsx)(t.h2,{id:"understanding-shared-configuration",children:"Understanding Shared Configuration"}),"\n",(0,s.jsxs)(t.p,{children:["All agents and gateways require access to a ",(0,s.jsx)(t.code,{children:"shared_config"})," object. You can provide configuration in the following ways:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"hard-coding configuration values directly within your agent or gateway YAML files. This method works for simple setups or quick prototyping, but it becomes unwieldy as your deployment grows."}),"\n",(0,s.jsxs)(t.li,{children:["using the ",(0,s.jsx)(t.code,{children:"!include"})," directive to reference a centralized configuration file. This approach promotes consistency and simplifies maintenance across your entire project."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["When a plugin is installed, it may come with hard-coded default values. It is a best practice to remove this section and use ",(0,s.jsx)(t.code,{children:"!include"})," to point to the centralized ",(0,s.jsx)(t.code,{children:"shared_config"})," file. This ensures that all components are using the same base configuration."]}),"\n",(0,s.jsx)(t.h3,{id:"managing-multiple-shared-configuration-files",children:"Managing Multiple Shared Configuration Files"}),"\n",(0,s.jsx)(t.p,{children:"You can use multiple shared configuration files to manage different environments or setups (e.g., for different cloud providers), as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["The filename must always begin with ",(0,s.jsx)(t.code,{children:"shared_config"}),", followed by any descriptive suffix that helps identify the configuration's purpose. Examples include ",(0,s.jsx)(t.code,{children:"shared_config_aws.yaml"})," for Amazon Web Services deployments or ",(0,s.jsx)(t.code,{children:"shared_config_production.yaml"})," for production environments. This naming convention ensures the system can locate and process these files correctly."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["You can organize configuration files into subdirectories to further improve project structure. For instance, you might place files in ",(0,s.jsx)(t.code,{children:"configs/agents/shared_config.yaml"})," or ",(0,s.jsx)(t.code,{children:"environments/dev/shared_config_dev.yaml"}),". When you use subdirectories, you must update the ",(0,s.jsx)(t.code,{children:"!include"})," path in your agent or gateway configurations to reflect the correct file location."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The configuration file uses YAML anchors (",(0,s.jsx)(t.code,{children:"&anchor_name"}),") to create reusable configuration blocks, which can then be referenced in agent configuration files."]}),"\n",(0,s.jsx)(t.h2,{id:"configuration-structure",children:"Configuration Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The following example shows the structure of the ",(0,s.jsx)(t.code,{children:"shared_config.yaml"})," configuration file:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"shared_config:\n - broker_connection: &broker_connection\n dev_mode: ${SOLACE_DEV_MODE, false}\n broker_url: ${SOLACE_BROKER_URL, ws://localhost:8008}\n broker_username: ${SOLACE_BROKER_USERNAME, default}\n broker_password: ${SOLACE_BROKER_PASSWORD, default}\n broker_vpn: ${SOLACE_BROKER_VPN, default}\n temporary_queue: ${USE_TEMPORARY_QUEUES, true}\n # Ensure high enough limits if many agents are running\n # max_connection_retries: -1 # Retry forever\n\n - models:\n planning: &planning_model\n # This dictionary structure tells ADK to use the LiteLlm wrapper.\n # 'model' uses the specific model identifier your endpoint expects.\n model: ${LLM_SERVICE_PLANNING_MODEL_NAME} # Use env var for model name\n # 'api_base' tells LiteLLM where to send the request.\n api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL\n # 'api_key' provides authentication.\n api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key\n # Enable parallel tool calls for planning model\n parallel_tool_calls: true\n # Prompt Caching Strategy\n cache_strategy: \"5m\" # none, 5m, 1h\n # max_tokens: ${MAX_TOKENS, 16000} # Set a reasonable max token limit for planning\n # temperature: 0.1 # Lower temperature for more deterministic planning\n \n general: &general_model\n # This dictionary structure tells ADK to use the LiteLlm wrapper.\n # 'model' uses the specific model identifier your endpoint expects.\n model: ${LLM_SERVICE_GENERAL_MODEL_NAME} # Use env var for model name\n # 'api_base' tells LiteLLM where to send the request.\n api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL\n # 'api_key' provides authentication.\n api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key\n\n # ... (similar structure)\n\n - services:\n # Default session service configuration\n session_service: &default_session_service\n type: \"sql\"\n database_url: \"${DATABASE_URL, sqlite:///session.db}\"\n default_behavior: \"PERSISTENT\"\n \n # Default artifact service configuration\n artifact_service: &default_artifact_service\n type: \"filesystem\"\n base_path: \"/tmp/samv2\"\n artifact_scope: namespace\n \n # Default data tools configuration\n data_tools_config: &default_data_tools_config\n sqlite_memory_threshold_mb: 100\n max_result_preview_rows: 50\n max_result_preview_bytes: 4096\n"})}),"\n",(0,s.jsx)(t.h2,{id:"event-broker-connection",children:"Event Broker Connection"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"broker_connection"})," section configures the connection to the Solace event broker. The connection parameters are described in the following table:"]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Environment Variable"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"dev_mode"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"SOLACE_DEV_MODE"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["When set to ",(0,s.jsx)(t.code,{children:"true"}),", uses an in-memory broker for testing."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"false"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"broker_url"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"SOLACE_BROKER_URL"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The URL of the Solace event broker."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"ws://localhost:8008"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"broker_username"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"SOLACE_BROKER_USERNAME"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The username for authenticating with the event broker."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"default"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"broker_password"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"SOLACE_BROKER_PASSWORD"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The password for authenticating with the event broker."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"default"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"broker_vpn"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"SOLACE_BROKER_VPN"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The Message VPN to connect to on the event broker."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"default"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"temporary_queue"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"USE_TEMPORARY_QUEUES"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Whether to use temporary queues for communication. If ",(0,s.jsx)(t.code,{children:"false"}),", a durable queue will be created."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"true"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"max_connection_retries"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"MAX_CONNECTION_RETRIES"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["The maximum number of times to retry connecting to the event broker if the connection fails. A value of ",(0,s.jsx)(t.code,{children:"-1"})," means retry forever."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"-1"})})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsxs)(t.p,{children:["If you need to configure multiple brokers, you can do so by adding additional entries under ",(0,s.jsx)(t.code,{children:"shared_config"})," with a unique name (For example, ",(0,s.jsx)(t.code,{children:"broker_connection_eu: &broker_connection_eu"})," or ",(0,s.jsx)(t.code,{children:"broker_connection_us: &broker_connection_us"}),"). Reference these configurations in your agent files using the appropriate anchor, such as ",(0,s.jsx)(t.code,{children:"<<: *broker_connection_eu"}),"."]})}),"\n",(0,s.jsxs)(t.admonition,{type:"info",children:[(0,s.jsxs)(t.p,{children:["Setting the ",(0,s.jsx)(t.code,{children:"temporary_queue"})," parameter to ",(0,s.jsx)(t.code,{children:"true"})," (default) will use ",(0,s.jsx)(t.a,{href:"https://docs.solace.com/Messaging/Guaranteed-Msg/Endpoints.htm#temporary-endpoints",children:"temporary endpoints"})," for A2A communication. Temporary queues are automatically created and deleted by the broker, which simplifies management and reduces the need for manual cleanup. However, it does not allow for multiple client connections to the same queue, which may be a limitation in some scenarios where you're running multiple instances of the same agent or a new instance needs to be started while an old instance is still running."]}),(0,s.jsxs)(t.p,{children:["If you set ",(0,s.jsx)(t.code,{children:"temporary_queue"})," to ",(0,s.jsx)(t.code,{children:"false"}),", the system will create a durable queue for the client. Durable queues persist beyond the lifetime of the client connection, allowing multiple clients to connect to the same queue and ensuring that messages are not lost if the client disconnects. However, this requires manual management of the queues, including cleanup of unused queues."]}),(0,s.jsxs)(t.p,{children:["Check the ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deploying/deployment-options#setting-up-queue-templates",children:"Setting up Queue Templates"})," section for guidance on configuring queue templates to manage message TTL."]})]}),"\n",(0,s.jsx)(t.h2,{id:"llm-configuration",children:"LLM Configuration"}),"\n",(0,s.jsxs)(t.p,{children:["The models section configures the various Large Language Models and other generative models that power your agents' intelligence. This configuration leverages the ",(0,s.jsx)(t.a,{href:"https://litellm.ai/",children:"LiteLLM"})," library, which provides a standardized interface for interacting with ",(0,s.jsx)(t.a,{href:"https://docs.litellm.ai/docs/providers",children:"different model providers"}),", simplifying the process of switching between or combining multiple AI services."]}),"\n",(0,s.jsx)(t.h3,{id:"model-configuration-parameters",children:"Model Configuration Parameters"}),"\n",(0,s.jsxs)(t.p,{children:["Each model configuration requires specific parameters that tell the system how to communicate with the model provider. The model parameter specifies the exact model identifier in the format expected by your provider, such as ",(0,s.jsx)(t.code,{children:"openai/gpt-4"})," or ",(0,s.jsx)(t.code,{children:"anthropic/claude-3-opus-20240229"}),". The API base URL points to your provider's endpoint, but some providers use default endpoints that don't require explicit specification."]}),"\n",(0,s.jsx)(t.p,{children:"Authentication typically requires an API key, but some providers use alternative authentication mechanisms. Additional parameters control model behavior, such as enabling parallel tool calls for models that support this feature, setting maximum token limits to control response length and costs, and adjusting temperature values to influence response creativity versus determinism."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Environment Variable"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"model"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"LLM_SERVICE_<MODEL_NAME>_MODEL_NAME"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["The specific model identifier that the endpoint expects in the format of ",(0,s.jsx)(t.code,{children:"provider/model"})," (e.g., ",(0,s.jsx)(t.code,{children:"openai/gpt-4"}),", ",(0,s.jsx)(t.code,{children:"anthropic/claude-3-opus-20240229"}),")."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"api_base"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"LLM_SERVICE_ENDPOINT"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The base URL of the LLM provider's API endpoint."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"api_key"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"LLM_SERVICE_API_KEY"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The API key for authenticating with the service."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"parallel_tool_calls"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"}}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Enable parallel tool calls for the model."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"cache_strategy"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"}}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Set the prompt caching strategy (one of: ",(0,s.jsx)(t.code,{children:"none"}),", ",(0,s.jsx)(t.code,{children:"5m"}),", ",(0,s.jsx)(t.code,{children:"1h"}),"). For more details check ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/large_language_models#prompt-caching",children:"LLM Configuration"})," page."]})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"max_tokens"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"MAX_TOKENS"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Set a reasonable max token limit for the model."})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"temperature"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"TEMPERATURE"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Lower temperature for more deterministic planning."})]})]})]}),"\n",(0,s.jsx)(t.p,{children:"For Google's Gemini models, you can use a simplified configuration approach that references the model directly:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"model: gemini-2.5-pro\n"})}),"\n",(0,s.jsxs)(t.p,{children:["For detailed information about configuring Gemini models and setting up the required environment variables, see the ",(0,s.jsx)(t.a,{href:"https://google.github.io/adk-docs/agents/models/#using-google-gemini-models",children:"Gemini model documentation"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"predefined-model-types",children:"Predefined Model Types"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"shared_config.yaml"})," configuration file defines predefined model types that serve as aliases for specific use cases. These aliases allow you to reference models by their intended purpose rather than their technical specifications, making your agent configurations more readable and maintainable. The model types are as follows:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"planning"}),": Used by agents for planning and decision-making. It's configured for deterministic outputs (",(0,s.jsx)(t.code,{children:"temperature: 0.1"}),") and can use tools in parallel."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"general"}),": A general-purpose model for various tasks."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"image_gen"}),": A model for generating images."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"image_describe"}),": A model for describing the content of images."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"audio_transcription"}),": A model for transcribing audio files."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"report_gen"}),": A model specialized for generating reports."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"multimodal"}),": A simple string reference to a multimodal model (e.g., ",(0,s.jsx)(t.code,{children:'"gemini-1.5-flash-latest"'}),")."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["You can define any number of models in this section and reference them in your agent configurations. The system uses only the ",(0,s.jsx)(t.code,{children:"planning"})," and ",(0,s.jsx)(t.code,{children:"general"})," models by default; you don't need to configure the specialized models unless your agents specifically require those capabilities."]}),"\n",(0,s.jsxs)(t.p,{children:["For information about configuring different LLM providers and SSL/TLS security settings, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/large_language_models",children:"Configuring LLMs"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"service-configuration",children:"Service Configuration"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"services"})," section in ",(0,s.jsx)(t.code,{children:"shared_config.yaml"})," is used to configure various services that are available to agents. These services handle concerns such as session persistence, artifact storage, and data processing optimization."]}),"\n",(0,s.jsx)(t.h3,{id:"session-service",children:"Session Service"}),"\n",(0,s.jsxs)(t.p,{children:["The session service manages conversation history and context persistence across agent interactions. This service determines whether your agents remember previous conversations and how long that memory persists. The preset agent configurations default to SQL with SQLite for persistent sessions. For detailed information about session storage backends, architecture, and configuration examples, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage",children:"Session Storage"}),"."]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Options"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"type"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:[(0,s.jsx)(t.code,{children:"memory"}),", ",(0,s.jsx)(t.code,{children:"sql"})]}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["The storage backend for session data. The ",(0,s.jsx)(t.code,{children:"memory"})," option stores sessions in application memory. The ",(0,s.jsx)(t.code,{children:"sql"})," option stores sessions in a database."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"sql"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"database_url"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"Database URL string"}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["The connection string for your database. Required when ",(0,s.jsx)(t.code,{children:"type"})," is ",(0,s.jsx)(t.code,{children:"sql"}),". Supports SQLite (",(0,s.jsx)(t.code,{children:"sqlite:///path/to/db.db"}),") and PostgreSQL (",(0,s.jsx)(t.code,{children:"postgresql://user:pass@host:port/dbname"}),")."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"default_behavior"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:[(0,s.jsx)(t.code,{children:"PERSISTENT"}),", ",(0,s.jsx)(t.code,{children:"RUN_BASED"})]}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["The retention policy for session history. The ",(0,s.jsx)(t.code,{children:"PERSISTENT"})," option keeps session history indefinitely, while ",(0,s.jsx)(t.code,{children:"RUN_BASED"})," clears history between runs."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"PERSISTENT"})})]})]})]}),"\n",(0,s.jsx)(t.admonition,{type:"tip",children:(0,s.jsxs)(t.p,{children:["The preset agent configurations default to SQL with SQLite databases. You can configure PostgreSQL by setting database URL environment variables as described in the ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/session-storage",children:"Session Storage"})," guide."]})}),"\n",(0,s.jsx)(t.h3,{id:"artifact-service",children:"Artifact Service"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"artifact_service"})," is responsible for managing artifacts, which are files or data generated by agents, such as generated documents, processed data files, and intermediate results. For detailed information about artifact storage backends, versioning, and production configurations, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/installing-and-configuring/artifact-storage",children:"Artifact Storage"}),"."]}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Options"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"type"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:[(0,s.jsx)(t.code,{children:"memory"}),", ",(0,s.jsx)(t.code,{children:"gcs"}),", ",(0,s.jsx)(t.code,{children:"filesystem"})]}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Service type for artifact storage. Use ",(0,s.jsx)(t.code,{children:"memory"})," for in-memory, ",(0,s.jsx)(t.code,{children:"gcs"})," for Google Cloud Storage, or ",(0,s.jsx)(t.code,{children:"filesystem"})," for local file storage."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"memory"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"base_path"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"local path"}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Base directory path for storing artifacts. Required only if ",(0,s.jsx)(t.code,{children:"type"})," is ",(0,s.jsx)(t.code,{children:"filesystem"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"bucket_name"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"bucket name"}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Google Cloud Storage bucket name. Required only if ",(0,s.jsx)(t.code,{children:"type"})," is ",(0,s.jsx)(t.code,{children:"gcs"}),"."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"(none)"})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"artifact_scope"})}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:[(0,s.jsx)(t.code,{children:"namespace"}),", ",(0,s.jsx)(t.code,{children:"app"})]}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Scope for artifact sharing. ",(0,s.jsx)(t.code,{children:"namespace"}),": shared by all components in the namespace. ",(0,s.jsx)(t.code,{children:"app"}),": isolated by agent/gateway name. Must be consistent for all components in the same process."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"namespace"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"artifact_scope_value"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"custom scope id"}),(0,s.jsxs)(t.td,{style:{textAlign:"left"},children:["Custom identifier for artifact scope. Required if ",(0,s.jsx)(t.code,{children:"artifact_scope"})," is set to a custom value."]}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"(none)"})]})]})]}),"\n",(0,s.jsx)(t.h3,{id:"data-tools-configuration",children:"Data Tools Configuration"}),"\n",(0,s.jsx)(t.p,{children:"The data tools configuration optimizes how agents handle data analysis and processing tasks. These settings balance performance, memory usage, and user experience when agents work with databases and large datasets."}),"\n",(0,s.jsx)(t.p,{children:"The SQLite memory threshold determines when the system switches from disk-based to memory-based database operations. Lower thresholds favor memory usage for better performance although consume more system RAM. Higher thresholds reduce memory pressure although may slow database operations."}),"\n",(0,s.jsx)(t.p,{children:"Result preview settings control how much data agents display when showing query results or data samples. These limits prevent overwhelming users with massive datasets while ensuring they see enough information to understand the results."}),"\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Parameter"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Type"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Description"}),(0,s.jsx)(t.th,{style:{textAlign:"left"},children:"Default"})]})}),(0,s.jsxs)(t.tbody,{children:[(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"sqlite_memory_threshold_mb"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"integer"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The memory threshold in megabytes for using an in-memory SQLite database."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"100"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"max_result_preview_rows"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"integer"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The maximum number of rows to show in a result preview."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"50"})})]}),(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"max_result_preview_bytes"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"integer"})}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:"The maximum number of bytes to show in a result preview."}),(0,s.jsx)(t.td,{style:{textAlign:"left"},children:(0,s.jsx)(t.code,{children:"4096"})})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>l,x:()=>o});var i=n(6540);const s={},r=i.createContext(s);function l(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]);
|