solace-agent-mesh 1.0.1__py3-none-any.whl → 1.0.3__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/__init__.py +5 -0
- solace_agent_mesh/agent/adk/callbacks.py +23 -1
- solace_agent_mesh/agent/adk/filesystem_artifact_service.py +34 -41
- solace_agent_mesh/agent/adk/runner.py +10 -6
- solace_agent_mesh/agent/adk/services.py +141 -60
- solace_agent_mesh/agent/protocol/event_handlers.py +84 -155
- solace_agent_mesh/agent/sac/app.py +12 -2
- solace_agent_mesh/agent/sac/component.py +182 -38
- solace_agent_mesh/agent/sac/task_execution_context.py +15 -6
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +8 -1
- solace_agent_mesh/agent/tools/general_agent_tools.py +4 -2
- solace_agent_mesh/agent/tools/peer_agent_tool.py +97 -88
- solace_agent_mesh/agent/utils/artifact_helpers.py +148 -14
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/{04989206.674a8007.js → 04989206.da8246cd.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/1023fc19.8e6d174c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.a8c5ce5a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{3d406171.f722eaf5.js → 3d406171.9b081d5f.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/75384d09.c3991823.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9eff14a2.036c35ea.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{aba87c2f.d3e2dcc3.js → aba87c2f.a6b84da6.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/{ae4415af.8e279b5d.js → ae4415af.96189a93.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/b7006a3a.38c0cf3d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/bb2ef573.56931473.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{cc969b05.954186d4.js → cc969b05.bd3e0d6c.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5aff74ab.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f897a61a.862b0514.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.dc7db184.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.aa687c82.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +8 -6
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +21 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +140 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/img/solace-logo-text.svg +18 -0
- solace_agent_mesh/assets/docs/lunr-index-1755120326601.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1755120326601.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/init_cmd/env_step.py +8 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +21 -1
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +2 -1
- solace_agent_mesh/cli/commands/run_cmd.py +42 -3
- solace_agent_mesh/cli/main.py +1 -3
- solace_agent_mesh/client/webui/frontend/static/assets/main-BCpII1-0.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-DzKPMTRs.js +673 -0
- solace_agent_mesh/client/webui/frontend/static/index.html +2 -2
- solace_agent_mesh/common/exceptions.py +25 -0
- solace_agent_mesh/common/utils/initializer.py +51 -0
- solace_agent_mesh/common/utils/message_utils.py +79 -0
- solace_agent_mesh/config_portal/backend/common.py +1 -1
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +2 -1
- solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +6 -2
- solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +1 -5
- solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +1 -0
- solace_agent_mesh/config_portal/backend/server.py +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-xSu2leR8.js +48 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d2b54a97.js → manifest-950eb3be.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/gateway/base/component.py +15 -2
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +9 -3
- solace_agent_mesh/gateway/http_sse/sse_manager.py +23 -1
- solace_agent_mesh/templates/gateway_component_template.py +75 -44
- solace_agent_mesh/templates/logging_config_template.ini +64 -0
- solace_agent_mesh/templates/plugin_agent_config_template.yaml +1 -1
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.3.dist-info}/METADATA +56 -46
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.3.dist-info}/RECORD +102 -96
- solace_agent_mesh/assets/docs/assets/js/1023fc19.015679ca.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.23bccffb.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9eff14a2.1bf8f61c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/b7006a3a.40b10c9d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/bb2ef573.207e6990.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.ecc3d195.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f897a61a.2c2e152c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.7ed3319f.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9520ae2.js +0 -1
- solace_agent_mesh/assets/docs/img/Solace_AI_Framework_README.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1753813536522.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1753813536522.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-An0a5j5k.js +0 -663
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bu5-4Bac.css +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DNxCwAGB.js +0 -48
- /solace_agent_mesh/assets/docs/assets/js/{main.7ed3319f.js.LICENSE.txt → main.dc7db184.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.3.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.3.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.0.1.dist-info → solace_agent_mesh-1.0.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1935],{3728:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/concepts/gateways","title":"Gateways","description":"Gateways are a crucial component of the Solace Agent Mesh framework that expose the agent mesh to external systems through various protocols. Built on a common base gateway architecture, they provide the following functions:","source":"@site/docs/documentation/concepts/gateways.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/gateways","permalink":"/solace-agent-mesh/docs/documentation/concepts/gateways","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/gateways.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Gateways","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Solace Agent Mesh CLI","permalink":"/solace-agent-mesh/docs/documentation/concepts/cli"},"next":{"title":"Agents","permalink":"/solace-agent-mesh/docs/documentation/concepts/agents"}}');var s=n(4848),o=n(8453);const i={title:"Gateways",sidebar_position:10},r="Gateways",c={},l=[{value:"Key Functions",id:"key-functions",level:2},{value:"How Gateways Work",id:"how-gateways-work",level:2},{value:"Available Gateways",id:"available-gateways",level:2},{value:"Core Gateways",id:"core-gateways",level:3},{value:"Plugin Gateways",id:"plugin-gateways",level:3},{value:"Create a Gateway",id:"create-a-gateway",level:2},{value:"Gateway from Scratch",id:"gateway-from-scratch",level:3}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",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)(t.header,{children:(0,s.jsx)(t.h1,{id:"gateways",children:"Gateways"})}),"\n",(0,s.jsx)(t.p,{children:"Gateways are a crucial component of the Solace Agent Mesh framework that expose the agent mesh to external systems through various protocols. Built on a common base gateway architecture, they provide the following functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"serve as the primary interface between Solace Agent Mesh and the outside world"}),"\n",(0,s.jsx)(t.li,{children:"manage the flow of information in and out of the system through the A2A protocol"}),"\n",(0,s.jsx)(t.li,{children:"handle authentication, user enrichment, and message processing"}),"\n",(0,s.jsx)(t.li,{children:"support multiple interface types including REST, HTTP SSE, webhooks, and event mesh connectivity"}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{title:"In one sentence",type:"tip",children:(0,s.jsx)(t.p,{children:"Gateways are the external interfaces that connect various systems to the A2A agent mesh through standardized protocols."})}),"\n",(0,s.jsx)(t.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Entry Points"}),": Gateways act as the entry points from the outside world and translate external requests into A2A protocol messages and route them through the Solace event mesh to appropriate agents."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Authentication & Authorization"}),": Common authentication and user enrichment flow across all gateway types, with pluggable identity providers."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Configurable System Purpose"}),": Each gateway has a configurable system purpose that sets the context for all stimuli entering the Solace Agent Mesh through that gateway. This design allows for tailored processing based on the specific use case or domain."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Customizable Output Formatting"}),": Gateways have a configurable output description that controls how stimuli responses are formatted when sent back to the outside world. This configurable output description ensures that the output meets the requirements of the receiving system or user interface."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Multiple Interface Types"}),": Gateways can have different interfaces to accommodate various communication protocols and systems. Some examples include REST APIs, event meshes, Slack integrations, browser-based interfaces, and so on."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"how-gateways-work",children:"How Gateways Work"}),"\n",(0,s.jsx)(t.p,{children:"The following diagram illustrates the complete flow of information through a gateway in Solace Agent Mesh:"}),"\n",(0,s.jsx)(t.mermaid,{value:"sequenceDiagram\n participant External as External System/User\n participant Gateway\n participant Mesh as Solace Agent Mesh\n\n rect rgba(128, 128, 128, 0.2)\n Note over External,Gateway: Authentication Phase [Optional]\n External->>Gateway: Send Request\n Gateway->> Gateway: Authenticate Request\n alt Authentication Failed\n Gateway--\x3e>External: Return Error\n end\n end\n\n rect rgba(128, 128, 128, 0.2)\n Note over Gateway: Authorization Phase [Optional]\n end\n\n rect rgba(128, 128, 128, 0.2)\n Note over Gateway,Mesh: Processing Phase\n Gateway->>Gateway: Apply System Purpose\n Gateway->>Gateway: Attach Format Rules\n Gateway->>Gateway: Format Response\n Gateway->>Gateway: Transform to Stimulus\n Gateway->>Mesh: Send Stimulus\n\n alt Response Expected\n Mesh--\x3e>Gateway: Return Response\n Gateway--\x3e>External: Send Formatted Response\n end\n end"}),"\n",(0,s.jsx)(t.h2,{id:"available-gateways",children:"Available Gateways"}),"\n",(0,s.jsx)(t.p,{children:"Solace Agent Mesh comes with several built-in gateway types:"}),"\n",(0,s.jsx)(t.h3,{id:"core-gateways",children:"Core Gateways"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"HTTP SSE Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Real-time web interface with streaming responses"}),"\n",(0,s.jsx)(t.li,{children:"Server-sent events for live updates"}),"\n",(0,s.jsx)(t.li,{children:"Agent discovery API"}),"\n",(0,s.jsx)(t.li,{children:"File upload and download handling"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"REST Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Task submission with immediate task ID return"}),"\n",(0,s.jsx)(t.li,{children:"Polling-based result retrieval"}),"\n",(0,s.jsx)(t.li,{children:"Authentication integration"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Webhook Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Handles incoming webhook requests"}),"\n",(0,s.jsx)(t.li,{children:"Transforms webhook payloads to A2A messages"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"plugin-gateways",children:"Plugin Gateways"}),"\n",(0,s.jsx)(t.p,{children:"Additional gateway types are available through the plugin ecosystem:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Event Mesh Gateway"}),": External event mesh connectivity with message transformation"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Slack Gateway"}),": Slack bot integration for team collaboration"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Custom Gateways"}),": Create your own gateway implementations"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["For more information about plugins and how to configure them, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins",children:"Plugins"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["One of the official core plugin gateway interfaces is the ",(0,s.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/tree/main/solace-event-mesh",children:"Solace Event Mesh Gateway"}),", which enables communication with the PubSub+ event broker directly as an input interface."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"Each gateway type has its own configuration options and specific features. See the individual gateway documentation pages for detailed information on setup and usage."})}),"\n",(0,s.jsx)(t.h2,{id:"create-a-gateway",children:"Create a Gateway"}),"\n",(0,s.jsxs)(t.p,{children:["To create a gateway, you can either ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugins",children:"use one of the pre-existing plugins"})," or create yours from scratch."]}),"\n",(0,s.jsx)(t.h3,{id:"gateway-from-scratch",children:"Gateway from Scratch"}),"\n",(0,s.jsxs)(t.p,{children:["To create a gateway from scratch, you need to use the CLI ",(0,s.jsx)(t.code,{children:"add gateway"})," command without any interfaces. This command creates a ",(0,s.jsx)(t.em,{children:"python gateway template file"})," which you can then customize to your needs."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-sh",children:"sam add gateway my-interface\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To learn more about creating your own gateway, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/create-gateways",children:"Create Custom Gateways"}),"."]}),"\n",(0,s.jsx)(t.admonition,{title:"Share and Reuse",type:"tip",children:(0,s.jsxs)(t.p,{children:["If you would like to share your custom gateway with the community or re-use it within other projects, you can create a plugin for it. For more information, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#create-a-plugin",children:"Create Plugins"}),"."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(6540);const s={},o=a.createContext(s);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]);
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1935],{3728:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/concepts/gateways","title":"Gateways","description":"Gateways are a crucial component of the Solace Agent Mesh framework that expose the agent mesh to external systems through various protocols. Built on a common base gateway architecture, they provide the following functions:","source":"@site/docs/documentation/concepts/gateways.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/gateways","permalink":"/solace-agent-mesh/docs/documentation/concepts/gateways","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/gateways.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Gateways","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Solace Agent Mesh CLI","permalink":"/solace-agent-mesh/docs/documentation/concepts/cli"},"next":{"title":"Agents","permalink":"/solace-agent-mesh/docs/documentation/concepts/agents"}}');var s=n(4848),o=n(8453);const i={title:"Gateways",sidebar_position:10},r="Gateways",c={},l=[{value:"Key Functions",id:"key-functions",level:2},{value:"How Gateways Work",id:"how-gateways-work",level:2},{value:"Available Gateways",id:"available-gateways",level:2},{value:"Core Gateways",id:"core-gateways",level:3},{value:"Plugin Gateways",id:"plugin-gateways",level:3},{value:"Create a Gateway",id:"create-a-gateway",level:2},{value:"Gateway from Scratch",id:"gateway-from-scratch",level:3}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",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)(t.header,{children:(0,s.jsx)(t.h1,{id:"gateways",children:"Gateways"})}),"\n",(0,s.jsx)(t.p,{children:"Gateways are a crucial component of the Solace Agent Mesh framework that expose the agent mesh to external systems through various protocols. Built on a common base gateway architecture, they provide the following functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"serve as the primary interface between Solace Agent Mesh and the outside world"}),"\n",(0,s.jsx)(t.li,{children:"manage the flow of information in and out of the system through the A2A protocol"}),"\n",(0,s.jsx)(t.li,{children:"handle authentication, user enrichment, and message processing"}),"\n",(0,s.jsx)(t.li,{children:"support multiple interface types including REST, HTTP SSE, webhooks, and event mesh connectivity"}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{title:"In one sentence",type:"tip",children:(0,s.jsx)(t.p,{children:"Gateways are the external interfaces that connect various systems to the A2A agent mesh through standardized protocols."})}),"\n",(0,s.jsx)(t.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Entry Points"}),": Gateways act as the entry points from the outside world and translate external requests into A2A protocol messages and route them through the Solace event mesh to appropriate agents."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Authentication & Authorization"}),": Common authentication and user enrichment flow across all gateway types, with pluggable identity providers."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Configurable System Purpose"}),": Each gateway has a configurable system purpose that sets the context for all stimuli entering the Solace Agent Mesh through that gateway. This design allows for tailored processing based on the specific use case or domain."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Customizable Output Formatting"}),": Gateways have a configurable output description that controls how stimuli responses are formatted when sent back to the outside world. This configurable output description ensures that the output meets the requirements of the receiving system or user interface."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Multiple Interface Types"}),": Gateways can have different interfaces to accommodate various communication protocols and systems. Some examples include REST APIs, event meshes, Slack integrations, browser-based interfaces, and so on."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"how-gateways-work",children:"How Gateways Work"}),"\n",(0,s.jsx)(t.p,{children:"The following diagram illustrates the complete flow of information through a gateway in Solace Agent Mesh:"}),"\n",(0,s.jsx)(t.mermaid,{value:"sequenceDiagram\n participant External as External System/User\n participant Gateway\n participant Mesh as Solace Agent Mesh\n\n rect rgba(128, 128, 128, 0.2)\n Note over External,Gateway: Authentication Phase [Optional]\n External->>Gateway: Send Request\n Gateway->> Gateway: Authenticate Request\n alt Authentication Failed\n Gateway--\x3e>External: Return Error\n end\n end\n\n rect rgba(128, 128, 128, 0.2)\n Note over Gateway: Authorization Phase [Optional]\n end\n\n rect rgba(128, 128, 128, 0.2)\n Note over Gateway,Mesh: Processing Phase\n Gateway->>Gateway: Apply System Purpose\n Gateway->>Gateway: Attach Format Rules\n Gateway->>Gateway: Format Response\n Gateway->>Gateway: Transform to Stimulus\n Gateway->>Mesh: Send Stimulus\n\n alt Response Expected\n Mesh--\x3e>Gateway: Return Response\n Gateway--\x3e>External: Send Formatted Response\n end\n end"}),"\n",(0,s.jsx)(t.h2,{id:"available-gateways",children:"Available Gateways"}),"\n",(0,s.jsx)(t.p,{children:"Solace Agent Mesh comes with several built-in gateway types:"}),"\n",(0,s.jsx)(t.h3,{id:"core-gateways",children:"Core Gateways"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"HTTP SSE Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Real-time web interface with streaming responses"}),"\n",(0,s.jsx)(t.li,{children:"Server-sent events for live updates"}),"\n",(0,s.jsx)(t.li,{children:"Agent discovery API"}),"\n",(0,s.jsx)(t.li,{children:"File upload and download handling"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"REST Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Task submission with immediate task ID return"}),"\n",(0,s.jsx)(t.li,{children:"Polling-based result retrieval"}),"\n",(0,s.jsx)(t.li,{children:"Authentication integration"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Webhook Gateway"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Handles incoming webhook requests"}),"\n",(0,s.jsx)(t.li,{children:"Transforms webhook payloads to A2A messages"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"plugin-gateways",children:"Plugin Gateways"}),"\n",(0,s.jsx)(t.p,{children:"Additional gateway types are available through the plugin ecosystem:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Event Mesh Gateway"}),": External event mesh connectivity with message transformation"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Slack Gateway"}),": Slack bot integration for team collaboration"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Custom Gateways"}),": Create your own gateway implementations"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["For more information about plugins and how to configure them, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins",children:"Plugins"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["One of the official core plugin gateway interfaces is the ",(0,s.jsx)(t.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/tree/main/solace-event-mesh",children:"Solace Event Mesh Gateway"}),", which enables communication with the PubSub+ event broker directly as an input interface."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"Each gateway type has its own configuration options and specific features. See the individual gateway documentation pages for detailed information on setup and usage."})}),"\n",(0,s.jsx)(t.h2,{id:"create-a-gateway",children:"Create a Gateway"}),"\n",(0,s.jsxs)(t.p,{children:["To create a gateway, you can either ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugin",children:"use one of the pre-existing plugins"})," or create yours from scratch."]}),"\n",(0,s.jsx)(t.h3,{id:"gateway-from-scratch",children:"Gateway from Scratch"}),"\n",(0,s.jsxs)(t.p,{children:["To create a gateway from scratch, you need to use the CLI ",(0,s.jsx)(t.code,{children:"add gateway"})," command without any interfaces. This command creates a ",(0,s.jsx)(t.em,{children:"python gateway template file"})," which you can then customize to your needs."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-sh",children:"sam add gateway my-interface\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To learn more about creating your own gateway, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/create-gateways",children:"Create Custom Gateways"}),"."]}),"\n",(0,s.jsx)(t.admonition,{title:"Share and Reuse",type:"tip",children:(0,s.jsxs)(t.p,{children:["If you would like to share your custom gateway with the community or re-use it within other projects, you can create a plugin for it. For more information, see ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#create-a-plugin",children:"Create Plugins"}),"."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(6540);const s={},o=a.createContext(s);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1462],{3519:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"documentation/user-guide/builtin-tools/data-analysis-tools","title":"Data Analysis Tools","description":"Solace Agent Mesh (SAM) includes a suite of optional built-in tools that enable agents to perform data analysis tasks directly on artifacts. These tools provide functionality for SQL querying, JQ transformations, and Plotly chart generation.","source":"@site/docs/documentation/user-guide/builtin-tools/data-analysis-tools.md","sourceDirName":"documentation/user-guide/builtin-tools","slug":"/documentation/user-guide/builtin-tools/data-analysis-tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"title":"Data Analysis Tools","sidebar_position":20},"sidebar":"docSidebar","previous":{"title":"Artifact Management Tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management"},"next":{"title":"Audio Tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools"}}');var s=t(4848),r=t(8453);const a={title:"Data Analysis Tools",sidebar_position:20},o="Data Analysis Tools",l={},d=[{value:"1. Setup and Configuration",id:"1-setup-and-configuration",level:2},{value:"2. Available Tools",id:"2-available-tools",level:2},{value:"<code>query_data_with_sql</code>",id:"query_data_with_sql",level:3},{value:"<code>create_sqlite_db</code>",id:"create_sqlite_db",level:3},{value:"<code>transform_data_with_jq</code>",id:"transform_data_with_jq",level:3},{value:"<code>create_chart_from_plotly_config</code>",id:"create_chart_from_plotly_config",level:3},{value:"3. Example Workflow: Querying a Large CSV",id:"3-example-workflow-querying-a-large-csv",level:2},{value:"4. Technical Considerations",id:"4-technical-considerations",level:2},{value:"Result Handling",id:"result-handling",level:3},{value:"Security",id:"security",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"data-analysis-tools",children:"Data Analysis Tools"})}),"\n",(0,s.jsx)(n.p,{children:"Solace Agent Mesh (SAM) includes a suite of optional built-in tools that enable agents to perform data analysis tasks directly on artifacts. These tools provide functionality for SQL querying, JQ transformations, and Plotly chart generation."}),"\n",(0,s.jsx)(n.h2,{id:"1-setup-and-configuration",children:"1. Setup and Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["Enable the data analysis tool group in the agent's ",(0,s.jsx)(n.code,{children:"app_config.yml"})," file."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: builtin-group\n group_name: "data_analysis"\n\n# Optional: Configure tool behavior\ndata_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)(n.h2,{id:"2-available-tools",children:"2. Available Tools"}),"\n",(0,s.jsx)(n.h3,{id:"query_data_with_sql",children:(0,s.jsx)(n.code,{children:"query_data_with_sql"})}),"\n",(0,s.jsx)(n.admonition,{title:"Enterprise Only",type:"info",children:(0,s.jsx)(n.p,{children:"This feature is available in the Enterprise Edition only."})}),"\n",(0,s.jsx)(n.p,{children:"Executes a SQL query against data stored in a CSV or SQLite artifact."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Parameters"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"input_filename"})," (str): The filename of the input artifact (for example, ",(0,s.jsx)(n.code,{children:"'data.csv'"}),", ",(0,s.jsx)(n.code,{children:"'mydatabase.sqlite'"}),"). Supports versioning (for example, ",(0,s.jsx)(n.code,{children:"'data.csv:2'"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"sql_query"})," (str): The SQL query string to execute."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"output_format"})," (str, optional): The desired format for the output artifact (",(0,s.jsx)(n.code,{children:"'csv'"})," or ",(0,s.jsx)(n.code,{children:"'json'"}),"). Defaults to ",(0,s.jsx)(n.code,{children:"'csv'"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Behavior"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"For CSV Input"}),": The tool loads the CSV data into a temporary in-memory SQLite database table named ",(0,s.jsx)(n.code,{children:"data"})," and executes the query against it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"For SQLite Input"}),": The tool connects directly to the specified SQLite database artifact in ",(0,s.jsx)(n.strong,{children:"read-only mode"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Returns"}),": A dictionary containing the execution status, a preview of the query result, and the ",(0,s.jsx)(n.code,{children:"output_filename"})," where the full result set is stored."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"create_sqlite_db",children:(0,s.jsx)(n.code,{children:"create_sqlite_db"})}),"\n",(0,s.jsx)(n.admonition,{title:"Enterprise Only",type:"info",children:(0,s.jsx)(n.p,{children:"This feature is available in the Enterprise Edition only."})}),"\n",(0,s.jsx)(n.p,{children:"Converts a CSV or JSON artifact into a persistent SQLite database artifact. This is the recommended approach for executing multiple queries on the same dataset, as it avoids repeated parsing of the source file."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Parameters"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"input_filename"})," (str): The filename of the input CSV or JSON artifact."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"output_db_filename"})," (str): The desired filename for the output SQLite database artifact (for example, ",(0,s.jsx)(n.code,{children:"'queryable_dataset.sqlite'"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"table_name"})," (str, optional): The name of the table to be created within the SQLite database. Defaults to ",(0,s.jsx)(n.code,{children:"'data'"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Returns"}),": A dictionary confirming the successful creation of the database artifact and providing its ",(0,s.jsx)(n.code,{children:"output_filename"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"transform_data_with_jq",children:(0,s.jsx)(n.code,{children:"transform_data_with_jq"})}),"\n",(0,s.jsx)(n.admonition,{title:"Enterprise Only",type:"info",children:(0,s.jsx)(n.p,{children:"This feature is available in the Enterprise Edition only."})}),"\n",(0,s.jsx)(n.p,{children:"Applies a JQ expression to transform data from a JSON, YAML, or CSV artifact."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Parameters"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"input_filename"})," (str): The filename of the input artifact."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"jq_expression"})," (str): The JQ filter or transformation expression string (for example, ",(0,s.jsx)(n.code,{children:"'.users[] | {name, id}'"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Returns"}),": A dictionary containing the execution status, a preview of the transformed data, and the ",(0,s.jsx)(n.code,{children:"output_filename"})," where the full JSON result is stored."]}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h3,{id:"create_chart_from_plotly_config",children:(0,s.jsx)(n.code,{children:"create_chart_from_plotly_config"})}),"\n",(0,s.jsx)(n.p,{children:"Generates a static chart image (for example, PNG, JPG, SVG) from a Plotly configuration provided as a string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Parameters"}),":","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"config_content"})," (str): A JSON or YAML formatted string representing the Plotly ",(0,s.jsx)(n.code,{children:"figure"})," dictionary."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"config_format"})," (str): Specifies whether ",(0,s.jsx)(n.code,{children:"config_content"})," is ",(0,s.jsx)(n.code,{children:"'json'"})," or ",(0,s.jsx)(n.code,{children:"'yaml'"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"output_filename"})," (str): The desired filename for the output image artifact (for example, ",(0,s.jsx)(n.code,{children:"'sales_chart.png'"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"output_format"})," (str, optional): The desired image format (",(0,s.jsx)(n.code,{children:"'png'"}),", ",(0,s.jsx)(n.code,{children:"'jpeg'"}),", ",(0,s.jsx)(n.code,{children:"'svg'"}),", etc.). Defaults to ",(0,s.jsx)(n.code,{children:"'png'"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Returns"}),": A dictionary confirming the chart's creation and providing its ",(0,s.jsx)(n.code,{children:"output_filename"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"3-example-workflow-querying-a-large-csv",children:"3. Example Workflow: Querying a Large CSV"}),"\n",(0,s.jsx)(n.p,{children:"The following workflow demonstrates an efficient method for analyzing a large CSV file:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"User Request"}),': "I need to run several queries on ',(0,s.jsx)(n.code,{children:"large_data.csv"}),'."']}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Strategy"}),": The agent determines that converting the CSV to a SQLite database is more performant for subsequent queries."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Call 1"}),": The agent calls ",(0,s.jsx)(n.code,{children:"create_sqlite_db"})," to convert ",(0,s.jsx)(n.code,{children:"large_data.csv"})," into a new artifact, ",(0,s.jsx)(n.code,{children:"queryable_data.sqlite"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Response"}),': "The data has been prepared for querying. What is your first question?"']}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"User Request"}),": \"Find all records where the category is 'Sales'.\""]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Call 2"}),": The agent calls ",(0,s.jsx)(n.code,{children:"query_data_with_sql"}),", targeting the ",(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"queryable_data.sqlite"})})," artifact."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Response"}),": The agent provides the results of the query."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"User Request"}),": \"Now, find the average amount for the 'Marketing' category.\""]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Agent Call 3"}),": The agent calls ",(0,s.jsx)(n.code,{children:"query_data_with_sql"})," again on the ",(0,s.jsxs)(n.strong,{children:["same ",(0,s.jsx)(n.code,{children:"queryable_data.sqlite"})," artifact"]}),", avoiding the overhead of reprocessing the original CSV file."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"4-technical-considerations",children:"4. Technical Considerations"}),"\n",(0,s.jsx)(n.h3,{id:"result-handling",children:"Result Handling"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Previews"}),": For ",(0,s.jsx)(n.code,{children:"query_data_with_sql"})," and ",(0,s.jsx)(n.code,{children:"transform_data_with_jq"}),", the tools return a truncated preview of the result directly to the LLM for immediate context."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Full Results"}),": The complete, untruncated result sets are always saved as new artifacts. The LLM is provided with the filename and version of these artifacts."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Accessing Full Results"}),": To utilize the full results, the agent can employ file management tools (",(0,s.jsx)(n.code,{children:"load_artifact"}),") or ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds",children:"Dynamic Embeds"})," (",(0,s.jsx)(n.code,{children:"\xabartifact_content:...\xbb"}),")."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"security",children:"Security"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"SQL Execution"}),": Queries against existing SQLite artifacts are performed in ",(0,s.jsx)(n.strong,{children:"read-only mode"})," to prevent data modification. Queries against temporary databases generated from CSVs are isolated."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"JQ Execution"}),": JQ expressions are executed within a sandboxed Python library, not via shell execution."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Resource Usage"}),": Complex queries or transformations can be resource-intensive. Monitor performance and resource consumption accordingly."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(6540);const s={},r=i.createContext(s);function a(e){const n=i.useContext(r);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(r.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[2037],{6317:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>l,default:()=>g,frontMatter:()=>r,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"documentation/deployment/debugging","title":"Debugging","description":"Debugging issues in Solace Agent Mesh starts with identifying the problem. You can monitor your system to debug it more effectively. For more information, see Observability.","source":"@site/docs/documentation/deployment/debugging.md","sourceDirName":"documentation/deployment","slug":"/documentation/deployment/debugging","permalink":"/solace-agent-mesh/docs/documentation/deployment/debugging","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/deployment/debugging.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"title":"Debugging","sidebar_position":30},"sidebar":"docSidebar","previous":{"title":"Observability","permalink":"/solace-agent-mesh/docs/documentation/deployment/observability"},"next":{"title":"Build Your Own Agent","permalink":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent"}}');var o=s(4848),t=s(8453);const r={title:"Debugging",sidebar_position:30},l="Debugging",a={},d=[{value:"Isolate Components",id:"isolate-components",level:2},{value:"Examine STIM Files",id:"examine-stim-files",level:2},{value:"Monitor Broker Activity",id:"monitor-broker-activity",level:2},{value:"Debug Mode",id:"debug-mode",level:2},{value:"Debugging in VSCode",id:"debugging-in-vscode",level:3},{value:"Invoke the Agent Directly",id:"invoke-the-agent-directly",level:2},{value:"Tools for Sending Messages",id:"tools-for-sending-messages",level:4},{value:"Message Format",id:"message-format",level:4},{value:"System Logs",id:"system-logs",level:2},{value:"Configuring Log Rotation",id:"configuring-log-rotation",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"debugging",children:"Debugging"})}),"\n",(0,o.jsxs)(n.p,{children:["Debugging issues in Solace Agent Mesh starts with identifying the problem. You can monitor your system to debug it more effectively. For more information, see ",(0,o.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deployment/observability",children:"Observability"}),".\nThe following sections provide common debugging approaches to help you diagnose and resolve issues."]}),"\n",(0,o.jsx)(n.h2,{id:"isolate-components",children:"Isolate Components"}),"\n",(0,o.jsxs)(n.p,{children:["Running only the necessary components in isolation can help pinpoint issues. The ",(0,o.jsx)(n.code,{children:"run"})," Solace Agent Mesh (SAM) CLI command allows you to specify which files to run."]}),"\n",(0,o.jsx)(n.p,{children:"For example:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"sam run configs/agents/my_tool_1.yaml configs/agents/my_tool_2.yaml\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This command runs only the agents defined in ",(0,o.jsx)(n.code,{children:"my_tool_1.yaml"})," and ",(0,o.jsx)(n.code,{children:"my_tool_2.yaml"}),", reducing noise from unrelated components."]}),"\n",(0,o.jsx)(n.h2,{id:"examine-stim-files",children:"Examine STIM Files"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deployment/observability#stimulus-logs",children:"STIM files"})," provide detailed traces of stimulus life cycles. If you have access to the storage location, you can inspect them to analyze message flows."]}),"\n",(0,o.jsxs)(n.p,{children:["Each ",(0,o.jsx)(n.code,{children:".stim"})," file contains all broker events related to a single stimulus, from the initial request to the final response."]}),"\n",(0,o.jsx)(n.h2,{id:"monitor-broker-activity",children:"Monitor Broker Activity"}),"\n",(0,o.jsxs)(n.p,{children:["For insights into message flows and event interactions, see ",(0,o.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deployment/observability#broker-observability",children:"Broker Observability"}),"."]}),"\n",(0,o.jsx)(n.h2,{id:"debug-mode",children:"Debug Mode"}),"\n",(0,o.jsx)(n.p,{children:"Because Solace Agent Mesh is a Python-based framework, you can run it in debug mode using an IDE with breakpoints."}),"\n",(0,o.jsx)(n.h3,{id:"debugging-in-vscode",children:"Debugging in VSCode"}),"\n",(0,o.jsxs)(n.p,{children:["If you're using VSCode, configure debugging in ",(0,o.jsx)(n.code,{children:".vscode/launch.json"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.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,o.jsx)(n.p,{children:"To start debugging:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["Open the ",(0,o.jsx)(n.strong,{children:"RUN AND DEBUG"})," panel on the left sidebar."]}),"\n",(0,o.jsxs)(n.li,{children:["Select ",(0,o.jsx)(n.code,{children:"sam-debug"})," from the dropdown."]}),"\n",(0,o.jsxs)(n.li,{children:["Click the ",(0,o.jsx)(n.strong,{children:"Play"})," to start in debug mode."]}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"Set breakpoints in your code to pause execution and inspect variable states."}),"\n",(0,o.jsx)(n.h2,{id:"invoke-the-agent-directly",children:"Invoke the Agent Directly"}),"\n",(0,o.jsx)(n.p,{children:"For debugging and testing, you can send direct messages to an agent by directly selecting the agent in the web UI agent dropdown or by using the PubSub+ event broker. This requires specifying the appropriate topic, user properties, and payload."}),"\n",(0,o.jsx)(n.h4,{id:"tools-for-sending-messages",children:"Tools for Sending Messages"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.strong,{children:(0,o.jsx)(n.a,{href:"https://marketplace.visualstudio.com/items?itemName=solace-tools.solace-try-me-vsc-extension",children:"Solace Try Me VSCode Extension"})})}),"\n",(0,o.jsx)(n.li,{children:(0,o.jsx)(n.strong,{children:(0,o.jsx)(n.a,{href:"https://github.com/SolaceLabs/solace-tryme-cli",children:"Solace Try Me (STM) CLI Tool"})})}),"\n"]}),"\n",(0,o.jsx)(n.h4,{id:"message-format",children:"Message Format"}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Topic"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"[NAME_SPACES]a2a/v1/agent/request/<agent_name>\n"})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"User Properties"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"userId: test-0000\nclientId: test-0000\nreplyTo: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000\na2aUserConfig: {}\n"})}),"\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Payload"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.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,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Response Topic"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"[NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000\n"})}),"\n",(0,o.jsx)(n.p,{children:"By sending a request and observing the response, you can verify an agent's behavior in isolation, making it easier to identify issues."}),"\n",(0,o.jsx)(n.h2,{id:"system-logs",children:"System Logs"}),"\n",(0,o.jsxs)(n.p,{children:["System logs provide detailed insights into the system's behavior. The logging behavior is configured in the ",(0,o.jsx)(n.code,{children:"configs/logging_config.ini"})," file, which controls both console (STDOUT) and file-based logging."]}),"\n",(0,o.jsx)(n.p,{children:"By default, the system is configured to:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Output logs with a severity of ",(0,o.jsx)(n.code,{children:"INFO"})," and higher to the console (STDOUT)."]}),"\n",(0,o.jsxs)(n.li,{children:["Write more detailed logs with a severity of ",(0,o.jsx)(n.code,{children:"DEBUG"})," and higher to a rotating log file named ",(0,o.jsx)(n.code,{children:"sam.log"})," in the project's root directory."]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"configuring-log-rotation",children:"Configuring Log Rotation"}),"\n",(0,o.jsxs)(n.p,{children:["The log file rotation is managed by the ",(0,o.jsx)(n.code,{children:"rotatingFileHandler"})," in ",(0,o.jsx)(n.code,{children:"configs/logging_config.ini"}),". You can customize its behavior by modifying the ",(0,o.jsx)(n.code,{children:"args"})," line:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-ini",children:"[handler_rotatingFileHandler]\nclass=logging.handlers.RotatingFileHandler\nlevel=DEBUG\nformatter=simpleFormatter\nargs=('sam.log', 'a', 52428800, 10)\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"args"})," tuple is defined as follows:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"'sam.log'"}),": The name of the log file."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"'a'"}),": The file mode (append)."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"52428800"}),": The maximum size of the log file in bytes before it is rotated. In this case, it's 50 MB."]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.code,{children:"10"}),": The number of backup log files to keep."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["For example, to change the log file size to 20 MB and keep 5 backup files, you would modify the line to:\n",(0,o.jsx)(n.code,{children:"args=('sam.log', 'a', 20971520, 5)"})]}),"\n",(0,o.jsx)(n.p,{children:"This level of configuration allows you to manage log verbosity and disk space usage according to your needs."})]})}function g(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var i=s(6540);const o={},t=i.createContext(o);function r(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8357],{3960:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/tutorials/custom-agent","title":"Build Your Own Agent","description":"This tutorial shows you how to build a sophisticated weather agent using the Solace Agent Mesh framework. Learn how to integrate with external APIs, manage resources properly, and create production-ready agents.","source":"@site/docs/documentation/tutorials/custom-agent.md","sourceDirName":"documentation/tutorials","slug":"/documentation/tutorials/custom-agent","permalink":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/tutorials/custom-agent.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Build Your Own Agent","sidebar_position":5},"sidebar":"docSidebar","previous":{"title":"Debugging","permalink":"/solace-agent-mesh/docs/documentation/deployment/debugging"},"next":{"title":"MCP Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration"}}');var r=t(4848),i=t(8453);const o={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 7: Environment Setup",id:"step-7-environment-setup",level:2},{value:"Step 8: Running the Agent",id:"step-8-running-the-agent",level:2},{value:"Step 9: Testing the Weather Agent",id:"step-9-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,i.R)(),...e.components};return(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 Solace 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/user-guide/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 for later reference"]}),"\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.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.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 SAM, 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/user-guide/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\nimport asyncio\nfrom typing import Dict, Any, Optional, List\nfrom datetime import datetime\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\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\nfrom .services.weather_service import WeatherService\n\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 tool_context: SAM framework context\n tool_config: Tool-specific configuration\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 tool_context: SAM framework context\n tool_config: Tool-specific configuration\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 from ...agent.utils.artifact_helpers import save_artifact_with_metadata\n from datetime import datetime, timezone\n \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 "type": "weather_report"\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, Dict\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\nasync def 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\nasync def 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 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",(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: "weather_agent.lifecycle"\n name: "initialize_weather_agent"\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: "weather_agent.lifecycle"\n name: "cleanup_weather_agent"\n \n # Tools configuration\n tools:\n # Current weather tool\n - tool_type: python\n component_module: "weather_agent.tools"\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: "weather_agent.tools"\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 config:\n max_file_size: 10485760 # 10MB\n \n session_service: *default_session_service\n artifact_service: *default_artifact_service\n\n artifact_handling_mode: "embed"\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", "data"]\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.jsx)(n.h2,{id:"step-7-environment-setup",children:"Step 7: 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-8-running-the-agent",children:"Step 8: 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 SAM 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:"cd src\nsam run ../configs/agents/weather_agent.yaml\n"})}),"\n",(0,r.jsx)(n.h2,{id:"step-9-testing-the-weather-agent",children:"Step 9: 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,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var a=t(6540);const r={},i=a.createContext(r);function o(e){const n=a.useContext(i);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:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]);
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8357],{3960:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/tutorials/custom-agent","title":"Build Your Own Agent","description":"This tutorial shows you how to build a sophisticated weather agent using the Solace Agent Mesh framework. Learn how to integrate with external APIs, manage resources properly, and create production-ready agents.","source":"@site/docs/documentation/tutorials/custom-agent.md","sourceDirName":"documentation/tutorials","slug":"/documentation/tutorials/custom-agent","permalink":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/tutorials/custom-agent.md","tags":[],"version":"current","sidebarPosition":5,"frontMatter":{"title":"Build Your Own Agent","sidebar_position":5},"sidebar":"docSidebar","previous":{"title":"Debugging","permalink":"/solace-agent-mesh/docs/documentation/deployment/debugging"},"next":{"title":"MCP Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration"}}');var r=t(4848),i=t(8453);const o={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 7: Environment Setup",id:"step-7-environment-setup",level:2},{value:"Step 8: Running the Agent",id:"step-8-running-the-agent",level:2},{value:"Step 9: Testing the Weather Agent",id:"step-9-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,i.R)(),...e.components};return(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 Solace 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/user-guide/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 for later reference"]}),"\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.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.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 SAM, 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/user-guide/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\nimport asyncio\nfrom typing import Dict, Any, Optional, List\nfrom datetime import datetime\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\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\nfrom .services.weather_service import WeatherService\n\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 tool_context: SAM framework context\n tool_config: Tool-specific configuration\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 tool_context: SAM framework context\n tool_config: Tool-specific configuration\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 from ...agent.utils.artifact_helpers import save_artifact_with_metadata\n from datetime import datetime, timezone\n \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 "type": "weather_report"\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, Dict\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\nasync def 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\nasync def 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 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",(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: "weather_agent.lifecycle"\n name: "initialize_weather_agent"\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: "weather_agent.lifecycle"\n name: "cleanup_weather_agent"\n \n # Tools configuration\n tools:\n # Current weather tool\n - tool_type: python\n component_module: "weather_agent.tools"\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: "weather_agent.tools"\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 config:\n max_file_size: 10485760 # 10MB\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", "data"]\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.jsx)(n.h2,{id:"step-7-environment-setup",children:"Step 7: 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-8-running-the-agent",children:"Step 8: 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 SAM 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:"cd src\nsam run ../configs/agents/weather_agent.yaml\n"})}),"\n",(0,r.jsx)(n.h2,{id:"step-9-testing-the-weather-agent",children:"Step 9: 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,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var a=t(6540);const r={},i=a.createContext(r);function o(e){const n=a.useContext(i);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:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8055],{5343:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"documentation/tutorials/rag-integration","title":"RAG Integration","description":"This tutorial guides you through setting up and configuring the Solace Agent Mesh (SAM) Retrieval Augmented Generation (RAG) plugin. The RAG plugin enables your agents to answer questions by retrieving information from a knowledge base of your documents.","source":"@site/docs/documentation/tutorials/rag-integration.md","sourceDirName":"documentation/tutorials","slug":"/documentation/tutorials/rag-integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/tutorials/rag-integration.md","tags":[],"version":"current","sidebarPosition":70,"frontMatter":{"title":"RAG Integration","sidebar_position":70,"toc_max_heading_level":4},"sidebar":"docSidebar","previous":{"title":"Slack Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration"},"next":{"title":"Enterprise","permalink":"/solace-agent-mesh/docs/documentation/enterprise"}}');var a=t(4848),r=t(8453);const o={title:"RAG Integration",sidebar_position:70,toc_max_heading_level:4},s="RAG Integration",l={},c=[{value:"What is SAM RAG?",id:"what-is-sam-rag",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Adding the RAG Plugin",id:"adding-the-rag-plugin",level:2},{value:"Configuring the RAG Agent",id:"configuring-the-rag-agent",level:2},{value:"Shared Configuration",id:"shared-configuration",level:3},{value:"RAG Pipeline Configuration",id:"rag-pipeline-configuration",level:3},{value:"1. Scanner Configuration",id:"1-scanner-configuration",level:4},{value:"2. Preprocessor Configuration",id:"2-preprocessor-configuration",level:4},{value:"3. Splitter Configuration",id:"3-splitter-configuration",level:4},{value:"4. Embedding Configuration",id:"4-embedding-configuration",level:4},{value:"5. Vector Database Configuration",id:"5-vector-database-configuration",level:4},{value:"6. LLM Configuration",id:"6-llm-configuration",level:4},{value:"7. Retrieval Configuration",id:"7-retrieval-configuration",level:4},{value:"Environment Variables",id:"environment-variables",level:3},{value:"Running the RAG Agent",id:"running-the-rag-agent",level:2},{value:"Testing the RAG Agent",id:"testing-the-rag-agent",level:2},{value:"Ingesting Documents",id:"ingesting-documents",level:3},{value:"Option 1: Automatic Scanning (Batch Ingestion)",id:"option-1-automatic-scanning-batch-ingestion",level:4},{value:"Option 2: Manual Upload via Gateway",id:"option-2-manual-upload-via-gateway",level:4},{value:"Querying the Knowledge Base",id:"querying-the-knowledge-base",level:3},{value:"Troubleshooting",id:"troubleshooting",level:2}];function d(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"rag-integration",children:"RAG Integration"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial guides you through setting up and configuring the Solace Agent Mesh (SAM) Retrieval Augmented Generation (RAG) plugin. The RAG plugin enables your agents to answer questions by retrieving information from a knowledge base of your documents."}),"\n",(0,a.jsx)(n.h2,{id:"what-is-sam-rag",children:"What is SAM RAG?"}),"\n",(0,a.jsx)(n.p,{children:"The SAM RAG plugin enhances your agents with the ability to perform retrieval-augmented generation. This means the agent can:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Scan"})," documents from various sources (local filesystem, Google Drive, etc.)."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Preprocess"})," and ",(0,a.jsx)(n.strong,{children:"split"})," the text into manageable chunks."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Embed"})," these chunks into vectors and store them in a vector database."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Retrieve"})," relevant chunks of text based on a user's query."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Generate"})," an answer using a large language model (LLM) augmented with the retrieved information."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"This allows you to build agents that can answer questions about your own private data."}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before you begin, ensure you have:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/installation",children:"Installed Solace Agent Mesh and the SAM CLI"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/quick-start",children:"Created a new Solace Agent Mesh project"}),"."]}),"\n",(0,a.jsx)(n.li,{children:"Access to a vector database (for example, Qdrant, Chroma, and Pinecone)."}),"\n",(0,a.jsx)(n.li,{children:"Access to an LLM for generation and an embedding model."}),"\n",(0,a.jsx)(n.li,{children:"A directory with some documents for the agent to ingest."}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"adding-the-rag-plugin",children:"Adding the RAG Plugin"}),"\n",(0,a.jsx)(n.p,{children:"To add the RAG plugin to your SAM project, run the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sam plugin add my-rag-agent --plugin sam-rag\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Replace ",(0,a.jsx)(n.code,{children:"my-rag-agent"})," with your preferred agent name. This command:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Installs the ",(0,a.jsx)(n.code,{children:"sam-rag"})," plugin."]}),"\n",(0,a.jsxs)(n.li,{children:["Creates a new agent configuration file at ",(0,a.jsx)(n.code,{children:"configs/agents/my-rag-agent.yaml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"configuring-the-rag-agent",children:"Configuring the RAG Agent"}),"\n",(0,a.jsxs)(n.p,{children:["The RAG agent requires a detailed configuration. Open ",(0,a.jsx)(n.code,{children:"configs/agents/my-rag-agent.yaml"})," to configure the following sections:"]}),"\n",(0,a.jsx)(n.h3,{id:"shared-configuration",children:"Shared Configuration"}),"\n",(0,a.jsxs)(n.p,{children:["Like other agents, the RAG agent needs a connection to the Solace broker and a configured LLM. This is typically done in a ",(0,a.jsx)(n.code,{children:"shared_config.yaml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"# configs/shared_config.yaml\nshared_config:\n - broker_connection: &broker_connection\n dev_mode: ${SOLACE_DEV_MODE, false}\n broker_url: ${SOLACE_BROKER_URL, ws://localhost:8080}\n broker_username: ${SOLACE_BROKER_USERNAME, default}\n broker_password: ${SOLACE_BROKER_PASSWORD, default}\n broker_vpn: ${SOLACE_BROKER_VPN, default}\n temporary_queue: ${USE_TEMPORARY_QUEUES, true}\n\n - models:\n general: &general_model\n model: ${LLM_SERVICE_GENERAL_MODEL_NAME}\n api_base: ${LLM_SERVICE_ENDPOINT}\n api_key: ${LLM_SERVICE_API_KEY}\n"})}),"\n",(0,a.jsx)(n.h3,{id:"rag-pipeline-configuration",children:"RAG Pipeline Configuration"}),"\n",(0,a.jsxs)(n.p,{children:["The RAG pipeline has several stages, each with its own configuration block within the ",(0,a.jsx)(n.code,{children:"app_config"})," section of your ",(0,a.jsx)(n.code,{children:"my-rag-agent.yaml"})," file."]}),"\n",(0,a.jsx)(n.h4,{id:"1-scanner-configuration",children:"1. Scanner Configuration"}),"\n",(0,a.jsx)(n.p,{children:"The scanner discovers documents to be ingested. You can configure it to scan a local filesystem or cloud sources."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Local Filesystem Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'scanner:\n batch: true\n use_memory_storage: true\n source:\n type: filesystem\n directories:\n - "/path/to/your/documents" # Important: Replace with your actual document directory path\n filters:\n file_formats:\n - ".txt"\n - ".pdf"\n - ".md"\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Multi-Cloud Source Example:"}),"\nYou can also configure multiple sources, including Google Drive, OneDrive, and S3."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'scanner:\n batch: true\n use_memory_storage: true\n sources:\n - type: filesystem\n directories: ["${LOCAL_DOCUMENTS_PATH}"]\n - type: google_drive\n credentials_path: "${GOOGLE_DRIVE_CREDENTIALS_PATH}"\n folders:\n - folder_id: "${GOOGLE_DRIVE_FOLDER_ID_1}"\n name: "Documents"\n recursive: true\n'})}),"\n",(0,a.jsx)(n.h4,{id:"2-preprocessor-configuration",children:"2. Preprocessor Configuration"}),"\n",(0,a.jsx)(n.p,{children:"The preprocessor cleans the text extracted from documents."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"preprocessor:\n default_preprocessor:\n type: enhanced\n params:\n lowercase: true\n normalize_whitespace: true\n remove_urls: true\n preprocessors:\n pdf: \n type: document\n params:\n lowercase: true\n normalize_whitespace: true\n remove_non_ascii: true\n remove_urls: true\n"})}),"\n",(0,a.jsx)(n.h4,{id:"3-splitter-configuration",children:"3. Splitter Configuration"}),"\n",(0,a.jsx)(n.p,{children:"The splitter breaks down large documents into smaller chunks. Different splitters are available for different file types."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"splitter:\n default_splitter:\n type: recursive_character\n params:\n chunk_size: 2048\n chunk_overlap: 400\n splitters:\n markdown:\n type: markdown\n params:\n chunk_size: 2048\n chunk_overlap: 400\n pdf:\n type: token\n params:\n chunk_size: 500\n chunk_overlap: 100\n"})}),"\n",(0,a.jsx)(n.h4,{id:"4-embedding-configuration",children:"4. Embedding Configuration"}),"\n",(0,a.jsx)(n.p,{children:"This section defines the model used to create vector embeddings from the text chunks."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'embedding:\n embedder_type: "openai"\n embedder_params:\n model: "${OPENAI_EMBEDDING_MODEL}"\n api_key: "${OPENAI_API_KEY}"\n api_base: "${OPENAI_API_ENDPOINT}"\n normalize_embeddings: true\n'})}),"\n",(0,a.jsx)(n.h4,{id:"5-vector-database-configuration",children:"5. Vector Database Configuration"}),"\n",(0,a.jsx)(n.p,{children:"Configure the connection to your vector database where the embeddings are stored."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Qdrant Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'vector_db:\n db_type: "qdrant"\n db_params:\n url: "${QDRANT_URL}"\n api_key: "${QDRANT_API_KEY}"\n collection_name: "${QDRANT_COLLECTION}"\n embedding_dimension: ${QDRANT_EMBEDDING_DIMENSION}\n'})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Chroma Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'vector_db:\n db_type: "chroma"\n db_params:\n host: "${CHROMA_HOST}"\n port: "${CHROMA_PORT}"\n collection_name: "${CHROMA_COLLECTION}"\n'})}),"\n",(0,a.jsx)(n.h4,{id:"6-llm-configuration",children:"6. LLM Configuration"}),"\n",(0,a.jsx)(n.p,{children:"Configure the LLM that is used to generate answers based on the retrieved context."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:'llm:\n load_balancer:\n - model_name: "gpt-4o"\n litellm_params:\n model: "openai/${OPENAI_MODEL_NAME}"\n api_key: "${OPENAI_API_KEY}"\n api_base: "${OPENAI_API_ENDPOINT}"\n'})}),"\n",(0,a.jsx)(n.h4,{id:"7-retrieval-configuration",children:"7. Retrieval Configuration"}),"\n",(0,a.jsx)(n.p,{children:"This defines how many document chunks are retrieved to answer a query."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yaml",children:"retrieval:\n top_k: 7\n"})}),"\n",(0,a.jsx)(n.h3,{id:"environment-variables",children:"Environment Variables"}),"\n",(0,a.jsxs)(n.p,{children:["The RAG agent relies heavily on environment variables. Here are some of the most important ones you'll need to set in your ",(0,a.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'# Solace Connection\nSOLACE_BROKER_URL=ws://localhost:8080\nSOLACE_BROKER_VPN=default\nSOLACE_BROKER_USERNAME=default\nSOLACE_BROKER_PASSWORD=default\nNAMESPACE=my-org/dev\n\n# LLM and Embedding Models\nOPENAI_API_KEY="your-openai-api-key"\nOPENAI_API_ENDPOINT="your-openai-api-endpoint"\nOPENAI_MODEL_NAME="model name. E.g., gpt-4o"\nOPENAI_EMBEDDING_MODEL="embedding model name. E.g., text-embedding-3-small"\n\n# Vector Database (Qdrant example)\nQDRANT_URL="Qdrant url"\nQDRANT_API_KEY="API key"\nQDRANT_COLLECTION="my-rag-collection"\nQDRANT_EMBEDDING_DIMENSION=1536 # Depends on your embedding model\n\n# Scanner\nLOCAL_DOCUMENTS_PATH="./my_documents" # Relative path to your documents folder\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Create a directory named ",(0,a.jsx)(n.code,{children:"my_documents"})," in your project root and place some text or markdown files inside it."]}),"\n",(0,a.jsx)(n.h2,{id:"running-the-rag-agent",children:"Running the RAG Agent"}),"\n",(0,a.jsx)(n.p,{children:"Once you have configured your agent and set the environment variables, you can run it:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sam run configs/agents/my-rag-agent.yaml\n"})}),"\n",(0,a.jsx)(n.p,{children:"When the agent starts, it begins scanning the documents in the configured source, processing and ingesting them into your vector database. This process may take some time, depending on the number and size of your documents."}),"\n",(0,a.jsx)(n.h2,{id:"testing-the-rag-agent",children:"Testing the RAG Agent"}),"\n",(0,a.jsx)(n.p,{children:"Once your agent is running, you can test its retrieval capabilities and ingest new documents."}),"\n",(0,a.jsx)(n.h3,{id:"ingesting-documents",children:"Ingesting Documents"}),"\n",(0,a.jsx)(n.p,{children:"There are two primary ways to ingest documents into your RAG agent's knowledge base:"}),"\n",(0,a.jsx)(n.h4,{id:"option-1-automatic-scanning-batch-ingestion",children:"Option 1: Automatic Scanning (Batch Ingestion)"}),"\n",(0,a.jsxs)(n.p,{children:["This method uses the configured ",(0,a.jsx)(n.code,{children:"scanner"})," component. The agent automatically ingests documents from the directories specified in your configuration upon startup."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 1: Create a Document"})}),"\n",(0,a.jsxs)(n.p,{children:["First, create a simple text file named ",(0,a.jsx)(n.code,{children:"sam_features.txt"})," and add some content to it. For example:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-text",children:"Solace Agent Mesh (SAM) is a powerful framework for building AI agents.\nKey features of SAM include:\n- A flexible plugin architecture.\n- Integration with various LLMs and vector databases.\n- Scalable gateways for different communication protocols.\n- An event-driven design based on Solace PubSub+.\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 2: Place the Document in the Scanned Directory"})}),"\n",(0,a.jsxs)(n.p,{children:['In the "Environment Variables" section, we configured ',(0,a.jsx)(n.code,{children:"LOCAL_DOCUMENTS_PATH"})," to point to a directory (e.g., ",(0,a.jsx)(n.code,{children:"./my_documents"}),")."]}),"\n",(0,a.jsxs)(n.p,{children:["Create this directory in your project's root folder if you haven't already, and move your ",(0,a.jsx)(n.code,{children:"sam_features.txt"})," file into it."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"mkdir -p my_documents\nmv sam_features.txt my_documents/\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 3: Run the Agent to Trigger Ingestion"})}),"\n",(0,a.jsx)(n.p,{children:"If your agent is already running, you'll need to restart it to trigger the batch scan. If it's not running, start it now:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sam run configs/agents/my-rag-agent.yaml\n"})}),"\n",(0,a.jsx)(n.p,{children:"You will see logs indicating that the file is being processed. Once the agent is running and the initial scan is complete, the document is successfully ingested and ready for retrieval."}),"\n",(0,a.jsx)(n.h4,{id:"option-2-manual-upload-via-gateway",children:"Option 2: Manual Upload via Gateway"}),"\n",(0,a.jsx)(n.p,{children:"You can also ingest documents dynamically by uploading them directly through a gateway, like the Web UI. This is useful for adding single documents without restarting the agent. The RAG agent exposes a tool for this purpose."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 1: Start the RAG Agent and Web UI"})}),"\n",(0,a.jsx)(n.p,{children:"Ensure both your RAG agent and the Web UI gateway are running."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 2: Upload a Document in the Web UI"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Open the Web UI (usually at ",(0,a.jsx)(n.a,{href:"http://localhost:8000",children:"http://localhost:8000"}),", or check your gateway configuration for the correct URL) and start a chat with your RAG agent."]}),"\n",(0,a.jsx)(n.li,{children:"Use the file attachment button to select a document from your local machine."}),"\n",(0,a.jsxs)(n.li,{children:["Send a prompt along with the file, instructing the agent to ingest it. For example:","\n",(0,a.jsxs)(n.blockquote,{children:["\n",(0,a.jsx)(n.p,{children:'"Please ingest the attached document into your knowledge base."'}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The RAG agent uses its ",(0,a.jsx)(n.code,{children:"built-in"})," ingest_document tool to process the file you uploaded. The file goes through the same preprocessing, splitting, and embedding pipeline as the documents from the automatic scan."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Step 3: Confirm Ingestion"})}),"\n",(0,a.jsx)(n.p,{children:"After the agent confirms that the document has been ingested, you can immediately ask questions about its content."}),"\n",(0,a.jsx)(n.h3,{id:"querying-the-knowledge-base",children:"Querying the Knowledge Base"}),"\n",(0,a.jsx)(n.p,{children:"You can interact with your RAG agent through any gateway, such as the Web UI gateway."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"Make sure you have a Web UI gateway running (or add one to your project)."}),"\n",(0,a.jsxs)(n.li,{children:["Open the Web UI (usually at ",(0,a.jsx)(n.code,{children:"http://localhost:8000"}),")."]}),"\n",(0,a.jsxs)(n.li,{children:["Start a conversation with ",(0,a.jsx)(n.code,{children:"my-rag-agent"}),"."]}),"\n",(0,a.jsx)(n.li,{children:"Ask a question related to the content of the documents you provided during the initial scan."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"For example, if you have a document about product features, you could ask:"}),"\n",(0,a.jsxs)(n.blockquote,{children:["\n",(0,a.jsx)(n.p,{children:'"What are the key features of Product X?"'}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The agent searches its knowledge base, finds the relevant information, and generates an answer based on the content of your documents."}),"\n",(0,a.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Connection Errors"}),": Double-check all your URLs, API keys, and credentials for your LLM and vector database."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Ingestion Issues"}),": Check the agent logs for errors during the scanning, preprocessing, or embedding stages. Ensure the file formats are supported and the paths are correct."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"No Answers"}),": If the agent can't answer, it might be because the information is not in the documents, or the ",(0,a.jsx)(n.code,{children:"top_k"})," retrieval setting is too low."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>s});var i=t(6540);const a={},r=i.createContext(a);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(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([[9639],{2888:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>c});const a=JSON.parse('{"id":"documentation/tutorials/slack-integration","title":"Slack Integration","description":"This tutorial integrates a Slack interface into Solace Agent Mesh, enabling interaction with the system directly from your Slack workspace and channels.","source":"@site/docs/documentation/tutorials/slack-integration.md","sourceDirName":"documentation/tutorials","slug":"/documentation/tutorials/slack-integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/tutorials/slack-integration.md","tags":[],"version":"current","sidebarPosition":60,"frontMatter":{"title":"Slack Integration","sidebar_position":60},"sidebar":"docSidebar","previous":{"title":"MongoDB Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration"},"next":{"title":"RAG Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration"}}');var s=t(4848),i=t(8453);const o={title:"Slack Integration",sidebar_position:60},l="Slack Integration",r={},c=[{value:"Setting Up the Environment",id:"setting-up-the-environment",level:2},{value:"Creating the Slack App",id:"creating-the-slack-app",level:2},{value:"App-Level Tokens",id:"app-level-tokens",level:3},{value:"Installing the App in Your Slack Workspace",id:"installing-the-app-in-your-slack-workspace",level:3},{value:"Installing the Slack Gateway",id:"installing-the-slack-gateway",level:2},{value:"Running the Slack Gateway",id:"running-the-slack-gateway",level:2},{value:"Testing the Installation",id:"testing-the-installation",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"slack-integration",children:"Slack Integration"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial integrates a Slack interface into Solace Agent Mesh, enabling interaction with the system directly from your Slack workspace and channels."}),"\n",(0,s.jsx)(n.admonition,{title:"Learn about gateways",type:"info",children:(0,s.jsxs)(n.p,{children:["Read about ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/concepts/gateways",children:"Gateways"})," before you start this tutorial."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-the-environment",children:"Setting Up the Environment"}),"\n",(0,s.jsxs)(n.p,{children:["First, you need to ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/installation",children:"install Solace Agent Mesh and Solace Mesh Agent (SAM) CLI"}),", and then ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/quick-start",children:"create a new Solace Agent Mesh project"})," or ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#create-a-plugin",children:"create a new gateway plugin"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"creating-the-slack-app",children:"Creating the Slack App"}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a ",(0,s.jsx)(n.a,{href:"https://api.slack.com/apps",children:"Slack Application"})," in your workspace."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Go to the ",(0,s.jsx)(n.a,{href:"https://api.slack.com/apps",children:"Slack Application"})," website."]}),"\n",(0,s.jsxs)(n.li,{children:["Select ",(0,s.jsx)(n.strong,{children:"Your Apps"})," and click ",(0,s.jsx)(n.strong,{children:"Create New App"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Choose ",(0,s.jsx)(n.strong,{children:"From a manifest"})," and apply the following configuration.","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"You can customize the name and description, but keep the rest of the configuration and settings unchanged."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:"display_information:\n name: solace-agent-mesh-bot\n description: An app to integrate with Solace Agent Mesh\nfeatures:\n app_home:\n home_tab_enabled: false\n messages_tab_enabled: true\n messages_tab_read_only_enabled: false\n bot_user:\n display_name: Solace Agent Mesh\n always_online: false\noauth_config:\n scopes:\n bot:\n - app_mentions:read\n - bookmarks:read\n - channels:history\n - channels:join\n - channels:manage\n - channels:read\n - chat:write\n - chat:write.customize\n - chat:write.public\n - files:read\n - files:write\n - groups:history\n - groups:read\n - groups:write\n - im:history\n - im:read\n - im:write\n - links:read\n - links:write\n - mpim:history\n - mpim:read\n - mpim:write\n - pins:read\n - pins:write\n - reactions:read\n - reactions:write\n - reminders:read\n - reminders:write\n - team:read\n - usergroups:read\n - usergroups:write\n - users.profile:read\n - users:read.email\n - users:read\n - users:write\n - conversations.connect:read\n - conversations.connect:write\n - incoming-webhook\nsettings:\n event_subscriptions:\n bot_events:\n - app_mention\n - message.groups\n - message.im\n interactivity:\n is_enabled: true\n org_deploy_enabled: false\n socket_mode_enabled: true\n token_rotation_enabled: false\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Then select ",(0,s.jsx)(n.code,{children:"Create"})," to create your new App."]}),"\n",(0,s.jsx)(n.h3,{id:"app-level-tokens",children:"App-Level Tokens"}),"\n",(0,s.jsxs)(n.p,{children:["In your created App, select ",(0,s.jsx)(n.code,{children:"Basic Information"})," under ",(0,s.jsx)(n.code,{children:"Settings"}),". Scroll down to ",(0,s.jsx)(n.code,{children:"App-Level Tokens"})," and click ",(0,s.jsx)(n.code,{children:"Generate Token and Scopes"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Provide your token a name, add all available scopes, and then click ",(0,s.jsx)(n.code,{children:"Generate"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Make note of the resulting application token (beginning with ",(0,s.jsx)(n.code,{children:"xapp-"}),") - you need it in a future step."]}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-app-in-your-slack-workspace",children:"Installing the App in Your Slack Workspace"}),"\n",(0,s.jsxs)(n.p,{children:["Next, select ",(0,s.jsx)(n.strong,{children:"Install App"})," under ",(0,s.jsx)(n.strong,{children:"Settings"})," and follow the installation flow to install the App in your workspace."]}),"\n",(0,s.jsxs)(n.p,{children:["After installation, the bot token (beginning with ",(0,s.jsx)(n.code,{children:"xoxb-"}),") is visible. Make note of this token."]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-slack-gateway",children:"Installing the Slack Gateway"}),"\n",(0,s.jsx)(n.p,{children:"After configuring your Slack App, the next step is to add the Slack gateway to Solace Agent Mesh."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Add the gateway plugin using the Solace Agent Mesh (SAM) CLI:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sam plugin add slack-bot --plugin sam-slack\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You can change ",(0,s.jsx)(n.code,{children:"slack-bot"})," to any name you prefer for your gateway."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Configure the required environment variables:"}),"\n",(0,s.jsxs)(n.p,{children:["The Slack interface requires two authentication tokens. Add these to your ",(0,s.jsx)(n.code,{children:".env"})," file in the project root directory using the tokens generated during Slack App setup:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-env",children:"SLACK_BOT_TOKEN=xoxb-xxxxxxxxxx\nSLACK_APP_TOKEN=xapp-xxxxxxxxxx\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["You can further customize the Slack gateway by updating the ",(0,s.jsx)(n.code,{children:"configs/gateways/slack-bot.yaml"})," file. This file contains the configuration for the Slack gateway, including the initial status message, the gateway system purpose, and response format."]})}),"\n",(0,s.jsx)(n.h2,{id:"running-the-slack-gateway",children:"Running the Slack Gateway"}),"\n",(0,s.jsx)(n.p,{children:"Launch the Slack gateway with:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sam run configs/gateways/slack-bot.yaml\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For detailed information about available SAM CLI commands, see ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/concepts/cli",children:"Solace Agent Mesh CLI"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-installation",children:"Testing the Installation"}),"\n",(0,s.jsx)(n.p,{children:"To test your installation:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Open your Slack workspace in the desktop app or browser."}),"\n",(0,s.jsxs)(n.li,{children:["Find and click on the ",(0,s.jsx)(n.strong,{children:"Solace Agent Mesh"})," app under the ",(0,s.jsx)(n.strong,{children:"Apps"})," section."]}),"\n",(0,s.jsxs)(n.li,{children:["Send a test message by typing ",(0,s.jsx)(n.code,{children:"hello"})," and click ",(0,s.jsx)(n.strong,{children:"Enter"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["You should see:","\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'A "Chatbot is thinking..." status message'}),"\n",(0,s.jsx)(n.li,{children:"A response from the chatbot within a few seconds"}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.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:()=>o,x:()=>l});var a=t(6540);const s={},i=a.createContext(s);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[4651],{5923:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"documentation/concepts/agents","title":"Agents","description":"Agents are specialized processing units within the Solace Agent Mesh framework that are built around the Google Agent Development Kit (ADK) and provide the core intelligence layer. They:","source":"@site/docs/documentation/concepts/agents.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/agents","permalink":"/solace-agent-mesh/docs/documentation/concepts/agents","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/agents.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"title":"Agents","sidebar_position":20},"sidebar":"docSidebar","previous":{"title":"Gateways","permalink":"/solace-agent-mesh/docs/documentation/concepts/gateways"},"next":{"title":"Orchestrator","permalink":"/solace-agent-mesh/docs/documentation/concepts/orchestrator"}}');var i=s(4848),a=s(8453);const o={title:"Agents",sidebar_position:20},l="Agents",r={},c=[{value:"Key Functions",id:"key-functions",level:2},{value:"Agent Design",id:"agent-design",level:2},{value:"The Agent Lifecycle",id:"the-agent-lifecycle",level:3},{value:"Potential Agent Examples",id:"potential-agent-examples",level:3},{value:"Built-In Tools",id:"built-in-tools",level:2},{value:"Artifact Tools",id:"artifact-tools",level:3},{value:"Data Analysis Tools",id:"data-analysis-tools",level:3},{value:"Web Tools",id:"web-tools",level:3},{value:"Communication Tools",id:"communication-tools",level:3},{value:"User-Defined Agents",id:"user-defined-agents",level:2},{value:"Agent Plugins",id:"agent-plugins",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"agents",children:"Agents"})}),"\n",(0,i.jsx)(n.p,{children:"Agents are specialized processing units within the Solace Agent Mesh framework that are built around the Google Agent Development Kit (ADK) and provide the core intelligence layer. They:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"perform specific tasks or provide domain-specific knowledge or capabilities"}),"\n",(0,i.jsx)(n.li,{children:"integrate with the ADK runtime for advanced AI capabilities including tool usage, memory management, and session handling"}),"\n",(0,i.jsx)(n.li,{children:"play a crucial role in the system's ability to handle a wide range of tasks and adapt to various domains"}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,i.jsx)(n.p,{children:"Agents are intelligence units that communicate through the A2A protocol to provide system capabilities beyond basic orchestrator capabilities."})}),"\n",(0,i.jsx)(n.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ADK Integration"}),": Agents are built using the Google Agent Development Kit, providing advanced AI capabilities including tool usage, memory management, and artifact handling."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"AI-Enabled"}),": Agents come packaged with access to large language models (LLMs) and can utilize various tools."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Dynamic Discovery"}),": New agents can self-register/deregister and be discovered dynamically through broadcast messages without requiring changes to the running system."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Tool Ecosystem"}),": Agents have access to built-in tools for artifact management, data analysis, web scraping, and peer-to-peer delegation."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Session Management"}),": Agents support conversation continuity through ADK's session management capabilities."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Independence"}),": Agents are modularized and can be updated or replaced independently of other components."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"agent-design",children:"Agent Design"}),"\n",(0,i.jsx)(n.p,{children:"Agents in Solace Agent Mesh are built around the Solace AI Connector (SAC) component with ADK. Agent Mesh agents are complete self-contained units that can carry out specific tasks or provide domain-specific knowledge or capabilities. Each agent is defined by a YAML configuration file."}),"\n",(0,i.jsx)(n.p,{children:"Each agent integrates with:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ADK Runtime"}),": For AI model access, tool execution, and session management"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"A2A Protocol"}),": For standardized agent-to-agent communication"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Tool Registry"}),": Access to built-in and custom tools"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Artifact Service"}),": For file handling and management"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For example, an agent configured with SQL database tools can execute queries, perform data analysis, and generate visualizations through the integrated tool ecosystem, all while maintaining conversation context through its session management."}),"\n",(0,i.jsx)(n.h3,{id:"the-agent-lifecycle",children:"The Agent Lifecycle"}),"\n",(0,i.jsx)(n.p,{children:"Agents in Solace Agent Mesh follow the A2A protocol lifecycle and interact with the agent registry:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Discovery"}),": Agents start broadcasting discovery messages on startup to announce their availability and capabilities to the agent mesh."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Active"}),": The agent listens for A2A protocol messages on its designated topics and processes incoming tasks through the ADK runtime."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Execution"}),": The agent works on a task. They can also delegate tasks to other agents through the peer-to-peer A2A communication protocol."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Cleanup"}),": When shutting down, agents perform session cleanup and deregister from the agent mesh."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"potential-agent-examples",children:"Potential Agent Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"RAG (Retrieval Augmented Generation) Agent"}),": An agent that can retrieve information based on a natural language query using an embedding model and vector database, and then generate a response using a language model."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"External API Bridge"}),": An agent that acts as a bridge to external APIs, retrieving information from third-party services such as weather APIs or product information databases."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Internal System Lookup"}),": An agent that performs lookups in internal systems, such as a ticket management system or a customer relationship management (CRM) database."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Natural Language Processing Agent"}),": An agent that can perform tasks like sentiment analysis, named entity recognition, or language translation."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"built-in-tools",children:"Built-In Tools"}),"\n",(0,i.jsx)(n.p,{children:"Solace Agent Mesh comes with a comprehensive set of built-in tools that agents can use. These tools are automatically available to all agents and provide essential capabilities, and can be added through the agent configuration file."}),"\n",(0,i.jsx)(n.h3,{id:"artifact-tools",children:"Artifact Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Create Artifact"}),": Create and manage files with automatic metadata injection"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Load Artifact"}),": Retrieve and process existing artifacts"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Append to Artifact"}),": Add content to existing files"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Extract Content"}),": Extract and analyze content from various file types"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"List Artifacts"}),": Browse available artifacts in the system"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"data-analysis-tools",children:"Data Analysis Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"SQL Query"}),": Execute SQL queries against databases"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"JQ Transform"}),": Transform JSON data using JQ expressions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Plotly Charts"}),": Generate interactive charts and visualizations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"SQLite Database"}),": Create and query SQLite databases"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"web-tools",children:"Web Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Web Scraping"}),": Extract content from web pages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"HTTP Requests"}),": Make API calls and web requests"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"communication-tools",children:"Communication Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Peer Agent Tool"}),": Delegate tasks to other agents in the agent mesh"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Audio Tools"}),": Process and analyze audio content"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Image Tools"}),": Handle image processing and analysis"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"user-defined-agents",children:"User-Defined Agents"}),"\n",(0,i.jsx)(n.p,{children:"Using Solace Agent Mesh and the SAM CLI, you can create your own agents. Agents are configured through YAML files that specify:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Agent name and instructions"}),"\n",(0,i.jsx)(n.li,{children:"LLM model configuration"}),"\n",(0,i.jsx)(n.li,{children:"Available tools and capabilities"}),"\n",(0,i.jsx)(n.li,{children:"Artifact and session management settings"}),"\n",(0,i.jsx)(n.li,{children:"Discovery settings"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The following SAM CLI command creates an agent configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"sam add agent my-agent [--gui]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For more information, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/create-agents",children:"Creating Custom Agents"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"agent-plugins",children:"Agent Plugins"}),"\n",(0,i.jsx)(n.p,{children:"You can also use agents built by the community or Solace directly in your app with little to no configuration."}),"\n",(0,i.jsxs)(n.p,{children:["For more information, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugins",children:"Use a Plugin"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var t=s(6540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);
|
|
1
|
+
"use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[4651],{5923:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>t,toc:()=>c});const t=JSON.parse('{"id":"documentation/concepts/agents","title":"Agents","description":"Agents are specialized processing units within the Solace Agent Mesh framework that are built around the Google Agent Development Kit (ADK) and provide the core intelligence layer. They:","source":"@site/docs/documentation/concepts/agents.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/agents","permalink":"/solace-agent-mesh/docs/documentation/concepts/agents","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/agents.md","tags":[],"version":"current","sidebarPosition":20,"frontMatter":{"title":"Agents","sidebar_position":20},"sidebar":"docSidebar","previous":{"title":"Gateways","permalink":"/solace-agent-mesh/docs/documentation/concepts/gateways"},"next":{"title":"Orchestrator","permalink":"/solace-agent-mesh/docs/documentation/concepts/orchestrator"}}');var i=s(4848),a=s(8453);const o={title:"Agents",sidebar_position:20},l="Agents",r={},c=[{value:"Key Functions",id:"key-functions",level:2},{value:"Agent Design",id:"agent-design",level:2},{value:"The Agent Lifecycle",id:"the-agent-lifecycle",level:3},{value:"Potential Agent Examples",id:"potential-agent-examples",level:3},{value:"Built-In Tools",id:"built-in-tools",level:2},{value:"Artifact Tools",id:"artifact-tools",level:3},{value:"Data Analysis Tools",id:"data-analysis-tools",level:3},{value:"Web Tools",id:"web-tools",level:3},{value:"Communication Tools",id:"communication-tools",level:3},{value:"User-Defined Agents",id:"user-defined-agents",level:2},{value:"Agent Plugins",id:"agent-plugins",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"agents",children:"Agents"})}),"\n",(0,i.jsx)(n.p,{children:"Agents are specialized processing units within the Solace Agent Mesh framework that are built around the Google Agent Development Kit (ADK) and provide the core intelligence layer. They:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"perform specific tasks or provide domain-specific knowledge or capabilities"}),"\n",(0,i.jsx)(n.li,{children:"integrate with the ADK runtime for advanced AI capabilities including tool usage, memory management, and session handling"}),"\n",(0,i.jsx)(n.li,{children:"play a crucial role in the system's ability to handle a wide range of tasks and adapt to various domains"}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,i.jsx)(n.p,{children:"Agents are intelligence units that communicate through the A2A protocol to provide system capabilities beyond basic orchestrator capabilities."})}),"\n",(0,i.jsx)(n.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"ADK Integration"}),": Agents are built using the Google Agent Development Kit, providing advanced AI capabilities including tool usage, memory management, and artifact handling."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"AI-Enabled"}),": Agents come packaged with access to large language models (LLMs) and can utilize various tools."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Dynamic Discovery"}),": New agents can self-register/deregister and be discovered dynamically through broadcast messages without requiring changes to the running system."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Tool Ecosystem"}),": Agents have access to built-in tools for artifact management, data analysis, web scraping, and peer-to-peer delegation."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Session Management"}),": Agents support conversation continuity through ADK's session management capabilities."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Independence"}),": Agents are modularized and can be updated or replaced independently of other components."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"agent-design",children:"Agent Design"}),"\n",(0,i.jsx)(n.p,{children:"Agents in Solace Agent Mesh are built around the Solace AI Connector (SAC) component with ADK. Agent Mesh agents are complete self-contained units that can carry out specific tasks or provide domain-specific knowledge or capabilities. Each agent is defined by a YAML configuration file."}),"\n",(0,i.jsx)(n.p,{children:"Each agent integrates with:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"ADK Runtime"}),": For AI model access, tool execution, and session management"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"A2A Protocol"}),": For standardized agent-to-agent communication"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Tool Registry"}),": Access to built-in and custom tools"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Artifact Service"}),": For file handling and management"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"For example, an agent configured with SQL database tools can execute queries, perform data analysis, and generate visualizations through the integrated tool ecosystem, all while maintaining conversation context through its session management."}),"\n",(0,i.jsx)(n.h3,{id:"the-agent-lifecycle",children:"The Agent Lifecycle"}),"\n",(0,i.jsx)(n.p,{children:"Agents in Solace Agent Mesh follow the A2A protocol lifecycle and interact with the agent registry:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Discovery"}),": Agents start broadcasting discovery messages on startup to announce their availability and capabilities to the agent mesh."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Active"}),": The agent listens for A2A protocol messages on its designated topics and processes incoming tasks through the ADK runtime."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Execution"}),": The agent works on a task. They can also delegate tasks to other agents through the peer-to-peer A2A communication protocol."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Cleanup"}),": When shutting down, agents perform session cleanup and deregister from the agent mesh."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"potential-agent-examples",children:"Potential Agent Examples"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"RAG (Retrieval Augmented Generation) Agent"}),": An agent that can retrieve information based on a natural language query using an embedding model and vector database, and then generate a response using a language model."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"External API Bridge"}),": An agent that acts as a bridge to external APIs, retrieving information from third-party services such as weather APIs or product information databases."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Internal System Lookup"}),": An agent that performs lookups in internal systems, such as a ticket management system or a customer relationship management (CRM) database."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Natural Language Processing Agent"}),": An agent that can perform tasks like sentiment analysis, named entity recognition, or language translation."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"built-in-tools",children:"Built-In Tools"}),"\n",(0,i.jsx)(n.p,{children:"Solace Agent Mesh comes with a comprehensive set of built-in tools that agents can use. These tools are automatically available to all agents and provide essential capabilities, and can be added through the agent configuration file."}),"\n",(0,i.jsx)(n.h3,{id:"artifact-tools",children:"Artifact Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Create Artifact"}),": Create and manage files with automatic metadata injection"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Load Artifact"}),": Retrieve and process existing artifacts"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Append to Artifact"}),": Add content to existing files"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Extract Content"}),": Extract and analyze content from various file types"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"List Artifacts"}),": Browse available artifacts in the system"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"data-analysis-tools",children:"Data Analysis Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"SQL Query"}),": Execute SQL queries against databases"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"JQ Transform"}),": Transform JSON data using JQ expressions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Plotly Charts"}),": Generate interactive charts and visualizations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"SQLite Database"}),": Create and query SQLite databases"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"web-tools",children:"Web Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Web Scraping"}),": Extract content from web pages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"HTTP Requests"}),": Make API calls and web requests"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"communication-tools",children:"Communication Tools"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Peer Agent Tool"}),": Delegate tasks to other agents in the agent mesh"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Audio Tools"}),": Process and analyze audio content"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Image Tools"}),": Handle image processing and analysis"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"user-defined-agents",children:"User-Defined Agents"}),"\n",(0,i.jsx)(n.p,{children:"Using Solace Agent Mesh and the SAM CLI, you can create your own agents. Agents are configured through YAML files that specify:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Agent name and instructions"}),"\n",(0,i.jsx)(n.li,{children:"LLM model configuration"}),"\n",(0,i.jsx)(n.li,{children:"Available tools and capabilities"}),"\n",(0,i.jsx)(n.li,{children:"Artifact and session management settings"}),"\n",(0,i.jsx)(n.li,{children:"Discovery settings"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The following SAM CLI command creates an agent configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"sam add agent my-agent [--gui]\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For more information, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/create-agents",children:"Creating Custom Agents"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"agent-plugins",children:"Agent Plugins"}),"\n",(0,i.jsx)(n.p,{children:"You can also use agents built by the community or Solace directly in your app with little to no configuration."}),"\n",(0,i.jsxs)(n.p,{children:["For more information, see ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugin",children:"Use a Plugin"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var t=s(6540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]);
|