solace-agent-mesh 1.0.6__py3-none-any.whl → 1.0.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (141) hide show
  1. solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
  2. solace_agent_mesh/agent/adk/{filesystem_artifact_service.py → artifacts/filesystem_artifact_service.py} +14 -15
  3. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +440 -0
  4. solace_agent_mesh/agent/adk/callbacks.py +123 -159
  5. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +316 -0
  6. solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +414 -0
  7. solace_agent_mesh/agent/adk/mcp_content_processor.py +665 -0
  8. solace_agent_mesh/agent/adk/services.py +43 -1
  9. solace_agent_mesh/agent/adk/setup.py +85 -45
  10. solace_agent_mesh/agent/adk/tool_wrapper.py +19 -3
  11. solace_agent_mesh/agent/protocol/event_handlers.py +1 -1
  12. solace_agent_mesh/agent/sac/app.py +67 -0
  13. solace_agent_mesh/agent/sac/component.py +14 -86
  14. solace_agent_mesh/assets/docs/404.html +3 -3
  15. solace_agent_mesh/assets/docs/assets/js/04989206.b9dfe831.js +1 -0
  16. solace_agent_mesh/assets/docs/assets/js/0e682baa.b3bbde9a.js +1 -0
  17. solace_agent_mesh/assets/docs/assets/js/1023fc19.364235d5.js +1 -0
  18. solace_agent_mesh/assets/docs/assets/js/1523c6b4.1b0ec6f9.js +1 -0
  19. solace_agent_mesh/assets/docs/assets/js/166ab619.e8f3a7c7.js +1 -0
  20. solace_agent_mesh/assets/docs/assets/js/21ceee5f.3bf39250.js +1 -0
  21. solace_agent_mesh/assets/docs/assets/js/3d406171.7d02a73b.js +1 -0
  22. solace_agent_mesh/assets/docs/assets/js/42b3f8d8.8ccb9901.js +1 -0
  23. solace_agent_mesh/assets/docs/assets/js/442a8107.b3159bb2.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/4c2787c2.fc6804f2.js +1 -0
  25. solace_agent_mesh/assets/docs/assets/js/5b4258a4.0d080cd9.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/75384d09.ccd480c4.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/768e31b0.8b51cd70.js +1 -0
  28. solace_agent_mesh/assets/docs/assets/js/945fb41e.c63791d1.js +1 -0
  29. solace_agent_mesh/assets/docs/assets/js/{9eff14a2.036c35ea.js → 9eff14a2.472b0310.js} +1 -1
  30. solace_agent_mesh/assets/docs/assets/js/a3a92b25.4b7fa6a2.js +1 -0
  31. solace_agent_mesh/assets/docs/assets/js/aba87c2f.76376d7c.js +1 -0
  32. solace_agent_mesh/assets/docs/assets/js/ae4415af.7a2f0bbf.js +1 -0
  33. solace_agent_mesh/assets/docs/assets/js/b7006a3a.73a79653.js +1 -0
  34. solace_agent_mesh/assets/docs/assets/js/beecea0d.ae31f6a7.js +1 -0
  35. solace_agent_mesh/assets/docs/assets/js/c2c06897.587b4af5.js +1 -0
  36. solace_agent_mesh/assets/docs/assets/js/{cd3d4052.ca6eed8c.js → cd3d4052.b6535013.js} +1 -1
  37. solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +1 -0
  38. solace_agent_mesh/assets/docs/assets/js/f897a61a.0aa29dbb.js +1 -0
  39. solace_agent_mesh/assets/docs/assets/js/main.6dba4a66.js +2 -0
  40. solace_agent_mesh/assets/docs/assets/js/runtime~main.6415ad00.js +1 -0
  41. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +28 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +6 -6
  43. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +8 -8
  44. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +5 -5
  45. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +5 -5
  46. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +34 -5
  47. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  48. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +5 -5
  49. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +6 -6
  51. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +72 -0
  52. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +5 -5
  53. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +7 -7
  54. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +35 -16
  55. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +17 -11
  57. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +5 -5
  59. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +6 -6
  61. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +6 -6
  62. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +6 -6
  63. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +8 -8
  65. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +14 -14
  66. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +8 -8
  67. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  68. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +6 -6
  69. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +35 -23
  70. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  71. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +6 -6
  72. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  73. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  74. solace_agent_mesh/assets/docs/lunr-index-1756153049706.json +1 -0
  75. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  76. solace_agent_mesh/assets/docs/search-doc-1756153049706.json +1 -0
  77. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  78. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  79. solace_agent_mesh/cli/__init__.py +1 -1
  80. solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +1 -1
  81. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +67 -10
  82. solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +2 -2
  83. solace_agent_mesh/cli/commands/eval_cmd.py +8 -2
  84. solace_agent_mesh/cli/commands/init_cmd/__init__.py +20 -2
  85. solace_agent_mesh/cli/commands/init_cmd/env_step.py +25 -1
  86. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +45 -1
  87. solace_agent_mesh/cli/utils.py +21 -12
  88. solace_agent_mesh/client/webui/frontend/static/assets/main-BucUdn9m.js +673 -0
  89. solace_agent_mesh/client/webui/frontend/static/index.html +1 -1
  90. solace_agent_mesh/common/a2a_protocol.py +1 -1
  91. solace_agent_mesh/common/utils/mime_helpers.py +60 -1
  92. solace_agent_mesh/config_portal/backend/server.py +1 -1
  93. solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-xSu2leR8.js → _index-MqsrTd6g.js} +9 -9
  94. solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-950eb3be.js → manifest-28271392.js} +1 -1
  95. solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
  96. solace_agent_mesh/core_a2a/core_a2a_llm.txt +1 -1
  97. solace_agent_mesh/core_a2a/service.py +1 -1
  98. solace_agent_mesh/evaluation/run.py +149 -15
  99. solace_agent_mesh/evaluation/summary_builder.py +5 -3
  100. solace_agent_mesh/gateway/http_sse/dependencies.py +1 -1
  101. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +1 -1
  102. solace_agent_mesh/gateway/http_sse/services/task_service.py +1 -1
  103. solace_agent_mesh/llm_detail.txt +2 -2
  104. solace_agent_mesh/templates/agent_template.yaml +1 -1
  105. solace_agent_mesh/templates/plugin_agent_config_template.yaml +3 -3
  106. solace_agent_mesh/templates/plugin_readme_template.md +1 -1
  107. solace_agent_mesh/templates/shared_config.yaml +8 -1
  108. {solace_agent_mesh-1.0.6.dist-info → solace_agent_mesh-1.0.8.dist-info}/METADATA +4 -1
  109. {solace_agent_mesh-1.0.6.dist-info → solace_agent_mesh-1.0.8.dist-info}/RECORD +113 -108
  110. solace_agent_mesh/assets/docs/assets/js/04989206.da8246cd.js +0 -1
  111. solace_agent_mesh/assets/docs/assets/js/0e682baa.79f0ab22.js +0 -1
  112. solace_agent_mesh/assets/docs/assets/js/1023fc19.8e6d174c.js +0 -1
  113. solace_agent_mesh/assets/docs/assets/js/1523c6b4.91c7bc01.js +0 -1
  114. solace_agent_mesh/assets/docs/assets/js/166ab619.7d97ccaf.js +0 -1
  115. solace_agent_mesh/assets/docs/assets/js/21ceee5f.614fa8dd.js +0 -1
  116. solace_agent_mesh/assets/docs/assets/js/3d406171.9b081d5f.js +0 -1
  117. solace_agent_mesh/assets/docs/assets/js/42b3f8d8.36090198.js +0 -1
  118. solace_agent_mesh/assets/docs/assets/js/442a8107.5ba94b65.js +0 -1
  119. solace_agent_mesh/assets/docs/assets/js/4c2787c2.66ee00e9.js +0 -1
  120. solace_agent_mesh/assets/docs/assets/js/5b4258a4.bda20761.js +0 -1
  121. solace_agent_mesh/assets/docs/assets/js/75384d09.c3991823.js +0 -1
  122. solace_agent_mesh/assets/docs/assets/js/768e31b0.a12673db.js +0 -1
  123. solace_agent_mesh/assets/docs/assets/js/945fb41e.74d728aa.js +0 -1
  124. solace_agent_mesh/assets/docs/assets/js/a3a92b25.26ca071f.js +0 -1
  125. solace_agent_mesh/assets/docs/assets/js/aba87c2f.a6b84da6.js +0 -1
  126. solace_agent_mesh/assets/docs/assets/js/ae4415af.96189a93.js +0 -1
  127. solace_agent_mesh/assets/docs/assets/js/b7006a3a.38c0cf3d.js +0 -1
  128. solace_agent_mesh/assets/docs/assets/js/bb2ef573.56931473.js +0 -1
  129. solace_agent_mesh/assets/docs/assets/js/c2c06897.63b76e9e.js +0 -1
  130. solace_agent_mesh/assets/docs/assets/js/f284c35a.5aff74ab.js +0 -1
  131. solace_agent_mesh/assets/docs/assets/js/f897a61a.862b0514.js +0 -1
  132. solace_agent_mesh/assets/docs/assets/js/main.ea9672b6.js +0 -2
  133. solace_agent_mesh/assets/docs/assets/js/runtime~main.aa687c82.js +0 -1
  134. solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +0 -17
  135. solace_agent_mesh/assets/docs/lunr-index-1755285974624.json +0 -1
  136. solace_agent_mesh/assets/docs/search-doc-1755285974624.json +0 -1
  137. solace_agent_mesh/client/webui/frontend/static/assets/main-DzKPMTRs.js +0 -673
  138. /solace_agent_mesh/assets/docs/assets/js/{main.ea9672b6.js.LICENSE.txt → main.6dba4a66.js.LICENSE.txt} +0 -0
  139. {solace_agent_mesh-1.0.6.dist-info → solace_agent_mesh-1.0.8.dist-info}/WHEEL +0 -0
  140. {solace_agent_mesh-1.0.6.dist-info → solace_agent_mesh-1.0.8.dist-info}/entry_points.txt +0 -0
  141. {solace_agent_mesh-1.0.6.dist-info → solace_agent_mesh-1.0.8.dist-info}/licenses/LICENSE +0 -0
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[4777],{3112:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>l,metadata:()=>t,toc:()=>d});const t=JSON.parse('{"id":"documentation/user-guide/builtin-tools/audio-tools","title":"Audio Tools","description":"This guide provides technical documentation for the text-to-speech (TTS) tools available in the Solace Agent Mesh (SAM).","source":"@site/docs/documentation/user-guide/builtin-tools/audio-tools.md","sourceDirName":"documentation/user-guide/builtin-tools","slug":"/documentation/user-guide/builtin-tools/audio-tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/user-guide/builtin-tools/audio-tools.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"title":"Audio Tools","sidebar_position":30},"sidebar":"docSidebar","previous":{"title":"Data Analysis Tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools"},"next":{"title":"Dynamic Embeds","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds"}}');var s=i(4848),o=i(8453);const l={title:"Audio Tools",sidebar_position:30},r="Using Text-to-Speech (TTS) Tools",c={},d=[{value:"1. Overview",id:"1-overview",level:2},{value:"2. Setup and Configuration",id:"2-setup-and-configuration",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Basic Configuration",id:"basic-configuration",level:3},{value:"3. Advanced Configuration",id:"3-advanced-configuration",level:2},{value:"<code>text_to_speech</code> Configuration",id:"text_to_speech-configuration",level:3},{value:"<code>multi_speaker_text_to_speech</code> Configuration",id:"multi_speaker_text_to_speech-configuration",level:3},{value:"4. Features",id:"4-features",level:2},{value:"Intelligent Tone Selection",id:"intelligent-tone-selection",level:3},{value:"Multi-Language Support",id:"multi-language-support",level:3},{value:"5. Usage Examples",id:"5-usage-examples",level:2},{value:"Single-Voice Text-to-Speech (<code>text_to_speech</code>)",id:"single-voice-text-to-speech-text_to_speech",level:3},{value:"Multi-Speaker Text-to-Speech (<code>multi_speaker_text_to_speech</code>)",id:"multi-speaker-text-to-speech-multi_speaker_text_to_speech",level:3},{value:"6. Tool Reference",id:"6-tool-reference",level:2},{value:"<code>text_to_speech</code>",id:"text_to_speech",level:3},{value:"<code>multi_speaker_text_to_speech</code>",id:"multi_speaker_text_to_speech",level:3},{value:"7. Output and Metadata",id:"7-output-and-metadata",level:2},{value:"8. Troubleshooting",id:"8-troubleshooting",level:2}];function a(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-text-to-speech-tts-tools",children:"Using Text-to-Speech (TTS) Tools"})}),"\n",(0,s.jsx)(n.p,{children:"This guide provides technical documentation for the text-to-speech (TTS) tools available in the Solace Agent Mesh (SAM)."}),"\n",(0,s.jsx)(n.h2,{id:"1-overview",children:"1. Overview"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"audio"})," tool group provides two primary TTS tools for generating high-quality audio artifacts:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"text_to_speech"})}),": Converts a string of text to speech using a single voice, featuring intelligent tone selection."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"multi_speaker_text_to_speech"})}),": Converts a conversational script, delineated by speaker, into a multi-speaker audio file."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"2-setup-and-configuration",children:"2. Setup and Configuration"}),"\n",(0,s.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"API Key"}),": A valid Google Gemini API key with access to the TTS model is required."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dependencies"}),": The ",(0,s.jsx)(n.code,{children:"pydub"})," library is necessary for audio processing and format conversion. It can be installed via ",(0,s.jsx)(n.code,{children:"pip install pydub"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-configuration",children:"Basic Configuration"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Environment Variable"}),": The Gemini API key must be set as an environment variable.","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'export GEMINI_API_KEY="your_gemini_api_key_here"\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Enablement"}),": The ",(0,s.jsx)(n.code,{children:"audio"})," tool group must be enabled in the agent's ",(0,s.jsx)(n.code,{children:"app_config.yml"}),".","\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'tools:\n - tool_type: builtin-group\n group_name: "audio"\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"3-advanced-configuration",children:"3. Advanced Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["You can exercise more granular control over the TTS tools by providing a ",(0,s.jsx)(n.code,{children:"tool_config"})," block for each tool in your ",(0,s.jsx)(n.code,{children:"app_config.yml"}),"."]}),"\n",(0,s.jsxs)(n.h3,{id:"text_to_speech-configuration",children:[(0,s.jsx)(n.code,{children:"text_to_speech"})," Configuration"]}),"\n",(0,s.jsx)(n.p,{children:"This example shows how to set a default voice and define the mapping between tones and specific voice models."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'- tool_type: builtin\n tool_name: "text_to_speech"\n tool_config:\n gemini_api_key: ${GEMINI_API_KEY}\n model: "gemini-2.5-flash-preview-tts"\n voice_name: "Kore" # Default voice if no tone is matched\n language: "en-US" # Default language\n output_format: "mp3"\n # Voice selection by tone mapping\n voice_tone_mapping:\n bright: ["Zephyr", "Autonoe"]\n upbeat: ["Puck", "Laomedeia"]\n informative: ["Charon", "Rasalgethi"]\n firm: ["Kore", "Orus", "Alnilam"]\n friendly: ["Achird"]\n casual: ["Zubenelgenubi"]\n warm: ["Sulafar"]\n'})}),"\n",(0,s.jsxs)(n.h3,{id:"multi_speaker_text_to_speech-configuration",children:[(0,s.jsx)(n.code,{children:"multi_speaker_text_to_speech"})," Configuration"]}),"\n",(0,s.jsx)(n.p,{children:"This example defines default voice configurations for up to five speakers."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'- tool_type: builtin\n tool_name: "multi_speaker_text_to_speech"\n tool_config:\n gemini_api_key: ${GEMINI_API_KEY}\n model: "gemini-2.5-flash-preview-tts"\n language: "en-US"\n output_format: "mp3"\n # Default speaker voice configurations\n default_speakers:\n - { name: "Speaker1", voice: "Kore", tone: "firm" }\n - { name: "Speaker2", voice: "Puck", tone: "upbeat" }\n - { name: "Speaker3", voice: "Charon", tone: "informative" }\n - { name: "Speaker4", voice: "Achird", tone: "friendly" }\n - { name: "Speaker5", voice: "Sulafar", tone: "warm" }\n # The voice_tone_mapping can also be included here\n'})}),"\n",(0,s.jsx)(n.h2,{id:"4-features",children:"4. Features"}),"\n",(0,s.jsx)(n.h3,{id:"intelligent-tone-selection",children:"Intelligent Tone Selection"}),"\n",(0,s.jsx)(n.p,{children:"The system supports tone-based voice selection, allowing for dynamic voice choice based on desired emotional or stylistic output, rather than explicit voice names."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Available Tones"}),":\n",(0,s.jsx)(n.code,{children:"bright"}),", ",(0,s.jsx)(n.code,{children:"upbeat"}),", ",(0,s.jsx)(n.code,{children:"informative"}),", ",(0,s.jsx)(n.code,{children:"firm"}),", ",(0,s.jsx)(n.code,{children:"excitable"}),", ",(0,s.jsx)(n.code,{children:"youthful"}),", ",(0,s.jsx)(n.code,{children:"breezy"}),", ",(0,s.jsx)(n.code,{children:"easy-going"}),", ",(0,s.jsx)(n.code,{children:"breathy"}),", ",(0,s.jsx)(n.code,{children:"clear"}),", ",(0,s.jsx)(n.code,{children:"smooth"}),", ",(0,s.jsx)(n.code,{children:"gravelly"}),", ",(0,s.jsx)(n.code,{children:"soft"}),", ",(0,s.jsx)(n.code,{children:"even"}),", ",(0,s.jsx)(n.code,{children:"mature"}),", ",(0,s.jsx)(n.code,{children:"forward"}),", ",(0,s.jsx)(n.code,{children:"friendly"}),", ",(0,s.jsx)(n.code,{children:"casual"}),", ",(0,s.jsx)(n.code,{children:"gentle"}),", ",(0,s.jsx)(n.code,{children:"lively"}),", ",(0,s.jsx)(n.code,{children:"knowledgeable"}),", ",(0,s.jsx)(n.code,{children:"warm"})]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Tone Aliases"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"professional"})," \u2192 ",(0,s.jsx)(n.code,{children:"firm"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"cheerful"})," \u2192 ",(0,s.jsx)(n.code,{children:"upbeat"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"calm"})," \u2192 ",(0,s.jsx)(n.code,{children:"soft"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"conversational"})," \u2192 ",(0,s.jsx)(n.code,{children:"casual"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"multi-language-support",children:"Multi-Language Support"}),"\n",(0,s.jsxs)(n.p,{children:["The tools support over 25 languages, specified via BCP-47 language codes (for example, ",(0,s.jsx)(n.code,{children:"en-US"}),", ",(0,s.jsx)(n.code,{children:"fr-FR"}),", ",(0,s.jsx)(n.code,{children:"es-US"}),", ",(0,s.jsx)(n.code,{children:"ja-JP"}),")."]}),"\n",(0,s.jsx)(n.h2,{id:"5-usage-examples",children:"5. Usage Examples"}),"\n",(0,s.jsxs)(n.h3,{id:"single-voice-text-to-speech-text_to_speech",children:["Single-Voice Text-to-Speech (",(0,s.jsx)(n.code,{children:"text_to_speech"}),")"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Basic Usage"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Convert the following text to speech: "Welcome to the technical briefing on artificial intelligence."\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"With Tone Selection"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'Convert this text to speech with a professional tone: "Thank you for joining today\'s technical review."\n'})}),"\n",(0,s.jsxs)(n.h3,{id:"multi-speaker-text-to-speech-multi_speaker_text_to_speech",children:["Multi-Speaker Text-to-Speech (",(0,s.jsx)(n.code,{children:"multi_speaker_text_to_speech"}),")"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Basic Conversation"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Convert this conversation to speech:\nSpeaker1: Welcome to the podcast.\nSpeaker2: Thank you for having me.\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"With Custom Speaker Tones"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Convert this conversation using specific tones for each speaker:\n- Speaker1 should sound professional\n- Speaker2 should sound friendly\n\nConversation:\nSpeaker1: Good morning, this is the daily security briefing.\nSpeaker2: Hi everyone, let's review the agenda for today's session.\n"})}),"\n",(0,s.jsx)(n.h2,{id:"6-tool-reference",children:"6. Tool Reference"}),"\n",(0,s.jsx)(n.h3,{id:"text_to_speech",children:(0,s.jsx)(n.code,{children:"text_to_speech"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"text"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"The text to be synthesized."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"output_filename"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) A custom MP3 filename."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"voice_name"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) A specific voice name to use."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"tone"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) The desired voice tone."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"language"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) The BCP-47 language code."})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"multi_speaker_text_to_speech",children:(0,s.jsx)(n.code,{children:"multi_speaker_text_to_speech"})}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"conversation_text"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsxs)(n.td,{children:["A string of text with speaker labels (for example, ",(0,s.jsx)(n.code,{children:"S1: ..."}),")."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"output_filename"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) A custom MP3 filename."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"speaker_configs"})}),(0,s.jsx)(n.td,{children:"array"}),(0,s.jsx)(n.td,{children:"(Optional) An array to configure tones for specific speakers."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"language"})}),(0,s.jsx)(n.td,{children:"string"}),(0,s.jsx)(n.td,{children:"(Optional) The BCP-47 language code."})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"7-output-and-metadata",children:"7. Output and Metadata"}),"\n",(0,s.jsx)(n.p,{children:"Both tools generate an MP3 audio artifact that includes a rich set of metadata:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The source text (or a truncated version for long inputs)"}),"\n",(0,s.jsx)(n.li,{children:"The voice(s) and language used for synthesis"}),"\n",(0,s.jsx)(n.li,{children:"The generation timestamp and the specific tool invoked"}),"\n",(0,s.jsx)(n.li,{children:"The requested tone and any speaker-specific configurations"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"8-troubleshooting",children:"8. Troubleshooting"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"Error: GEMINI_API_KEY is required"})}),": This indicates that the ",(0,s.jsx)(n.code,{children:"GEMINI_API_KEY"})," environment variable has not been set correctly."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"Warning: Unknown tone 'xyz'"})}),": The specified tone is not recognized. Refer to the list of supported tones. The system will fall back to a default voice."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"Error: Failed to convert WAV to MP3"})}),": This typically indicates that ",(0,s.jsx)(n.code,{children:"pydub"})," is not installed or that the underlying system is missing necessary audio codecs (for example, ",(0,s.jsx)(n.code,{children:"ffmpeg"}),")."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>r});var t=i(6540);const s={},o=t.createContext(s);function l(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[515],{644:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"documentation/concepts/architecture","title":"Architecture","description":"Overview","source":"@site/docs/documentation/concepts/architecture.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/architecture","permalink":"/solace-agent-mesh/docs/documentation/concepts/architecture","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/architecture.md","tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"title":"Architecture","sidebar_position":4},"sidebar":"docSidebar","previous":{"title":"Component Overview","permalink":"/solace-agent-mesh/docs/documentation/getting-started/component-overview"},"next":{"title":"Solace Agent Mesh CLI","permalink":"/solace-agent-mesh/docs/documentation/concepts/cli"}}');var i=s(4848),r=s(8453);const o={title:"Architecture",sidebar_position:4},a="Solace Agent Mesh Architecture",c={},l=[{value:"Overview",id:"overview",level:2},{value:"Architectural Principles",id:"architectural-principles",level:2},{value:"System Components",id:"system-components",level:2},{value:"Solace PubSub+ Event Broker",id:"solace-pubsub-event-broker",level:3},{value:"Gateways",id:"gateways",level:3},{value:"Agent Hosts",id:"agent-hosts",level:3},{value:"Agents",id:"agents",level:3},{value:"Key Architectural Flows",id:"key-architectural-flows",level:2},{value:"User Task Processing Flow",id:"user-task-processing-flow",level:3},{value:"Agent-to-Agent Delegation Flow",id:"agent-to-agent-delegation-flow",level:3},{value:"Agent Discovery Flow",id:"agent-discovery-flow",level:3},{value:"A2A Protocol and Topic Structure",id:"a2a-protocol-and-topic-structure",level:2}];function d(e){const t={code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"solace-agent-mesh-architecture",children:"Solace Agent Mesh Architecture"})}),"\n",(0,i.jsx)(t.h2,{id:"overview",children:"Overview"}),"\n",(0,i.jsx)(t.p,{children:"The Solace Agent Mesh is an event-driven framework for creating a distributed ecosystem of collaborative AI agents. The architecture is designed to decouple agent logic from communication and orchestration, enabling scalability, resilience, and modularity."}),"\n",(0,i.jsx)(t.p,{children:"It integrates three primary technologies:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Solace PubSub+ Event Broker"}),": Provides the messaging fabric for all asynchronous communication, utilizing topic-based routing for the Agent-to-Agent (A2A) protocol."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Solace AI Connector (SAC)"}),": Serves as the runtime environment for hosting and managing the lifecycle of all system components (Agents and Gateways)."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Google Agent Development Kit (ADK)"}),": Provides the core logic for individual agents, including LLM interaction, tool execution, and state management."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"architectural-principles",children:"Architectural Principles"}),"\n",(0,i.jsx)(t.p,{children:"The design of the Solace Agent Mesh is founded on several key architectural principles:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Event-Driven Architecture (EDA)"}),": All interactions between major components are asynchronous and mediated by the event broker. This eliminates direct dependencies, allowing components to be developed, deployed, and scaled independently."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Component Decoupling"}),": Gateways, Agent Hosts, and other services communicate through standardized A2A protocol messages over the event mesh. They do not require knowledge of each other's network location, implementation language, or internal logic."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Scalability and Resilience"}),": The architecture supports horizontal scaling of Agent Hosts and Gateways. The event broker provides fault tolerance and guaranteed message delivery, ensuring system resilience even if individual components fail or are restarted."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"system-components",children:"System Components"}),"\n",(0,i.jsx)(t.p,{children:"The architecture comprises several distinct types of components that interact through the Solace PubSub+ broker."}),"\n",(0,i.jsx)(t.mermaid,{value:'graph TD\n subgraph External Systems\n direction TB\n UserInterfaces["User Interfaces<br/>(Web UI, Slack, CLI)"]\n APIs["External Systems & APIs"]\n end\n\n subgraph SolaceAgentMesh [Solace Agent Mesh]\n direction TB\n subgraph Gateways\n WebUIGateway["Web UI Gateway"]\n CustomGateway["Custom Gateway"]\n end\n\n Broker["Solace PubSub+ Broker<br/>(A2A Protocol over Topics)"]\n\n subgraph AgentHosts ["Agent Hosts (SAC Applications)"]\n AgentHost1["Agent Host<br/>(Runs Agent A)"]\n AgentHost2["Agent Host<br/>(Runs Agent B)"]\n AgentHostN["..."]\n end\n end\n\n subgraph BackendServices [Backend Services & Tools]\n LLM["Large Language Models"]\n CustomTools["Custom Tools<br/>(Python, MCP)"]\n DataStores["Databases & Vector Stores"]\n ArtifactService["Artifact Service<br/>(Filesystem, Cloud Storage)"]\n end\n\n %% Connections\n UserInterfaces -- Interacts with --\x3e Gateways\n APIs -- Interacts with --\x3e Gateways\n\n Gateways -- Pub/Sub --\x3e Broker\n AgentHosts -- Pub/Sub --\x3e Broker\n\n AgentHost1 -- Uses --\x3e LLM\n AgentHost1 -- Uses --\x3e CustomTools\n AgentHost1 -- Uses --\x3e DataStores\n AgentHost1 -- Uses --\x3e ArtifactService\n\n AgentHost2 -- Uses --\x3e LLM\n AgentHost2 -- Uses --\x3e CustomTools\n AgentHost2 -- Uses --\x3e DataStores\n AgentHost2 -- Uses --\x3e ArtifactService\n\n %% Styling\n classDef external fill:#E3F2FD,stroke:#1976D2,stroke-width:2px,color:#0D47A1;\n classDef gateway fill:#E8F5E8,stroke:#388E3C,stroke-width:2px,color:#1B5E20;\n classDef mesh fill:#FFF8E1,stroke:#F57C00,stroke-width:2px,color:#E65100;\n classDef agent fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100;\n classDef service fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C;\n\n class UserInterfaces,APIs external;\n class WebUIGateway,CustomGateway gateway;\n class Broker,SolaceAgentMesh mesh;\n class AgentHosts,AgentHost1,AgentHost2,AgentHostN agent;\n class LLM,CustomTools,DataStores,ArtifactService service;'}),"\n",(0,i.jsx)(t.h3,{id:"solace-pubsub-event-broker",children:"Solace PubSub+ Event Broker"}),"\n",(0,i.jsx)(t.p,{children:"The broker is the central messaging fabric. It is responsible for routing all A2A protocol messages between components using a hierarchical topic structure. This enables patterns like request/reply, streaming updates, and publish/subscribe for discovery."}),"\n",(0,i.jsx)(t.h3,{id:"gateways",children:"Gateways"}),"\n",(0,i.jsx)(t.p,{children:"Gateways are SAC applications that act as bridges between external systems and the agent mesh. Their primary responsibilities are:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Protocol Translation"}),": Convert external protocols (for example, HTTP, WebSockets, Slack RTM) into the standardized A2A protocol, and vice-versa."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Authentication and Authorization"}),": Authenticate incoming requests and, using a pluggable ",(0,i.jsx)(t.code,{children:"AuthorizationService"}),", retrieve the user's permission scopes."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Session Management"}),": Manage external user sessions and map them to A2A task lifecycles."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Response Handling"}),": Receive asynchronous A2A responses and status updates from agents and deliver them to the external client."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.strong,{children:"Gateway Development Kit (GDK)"})," provides ",(0,i.jsx)(t.code,{children:"BaseGatewayApp"})," and ",(0,i.jsx)(t.code,{children:"BaseGatewayComponent"})," classes to abstract common gateway logic, such as A2A protocol handling, agent discovery, and late-stage embed resolution, simplifying the creation of new gateways."]}),"\n",(0,i.jsx)(t.h3,{id:"agent-hosts",children:"Agent Hosts"}),"\n",(0,i.jsxs)(t.p,{children:["An Agent Host is a SAC application (",(0,i.jsx)(t.code,{children:"SamAgentApp"}),") that hosts a single ADK-based agent. Its key architectural functions include:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Hosting the ADK Runtime"}),": It manages the lifecycle of the ADK ",(0,i.jsx)(t.code,{children:"Runner"})," and ",(0,i.jsx)(t.code,{children:"LlmAgent"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"A2A Protocol Handling"}),": The internal ",(0,i.jsx)(t.code,{children:"SamAgentComponent"})," translates incoming A2A requests into ADK ",(0,i.jsx)(t.code,{children:"Task"})," objects and converts ADK ",(0,i.jsx)(t.code,{children:"Event"})," objects into outgoing A2A ",(0,i.jsx)(t.code,{children:"TaskStatusUpdateEvent"}),", ",(0,i.jsx)(t.code,{children:"TaskArtifactUpdateEvent"}),", or final response messages."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Scope Enforcement"}),": It extracts permission scopes from incoming message properties and filters the agent's available tools accordingly."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Service Initialization"}),": It initializes ADK services like the ",(0,i.jsx)(t.code,{children:"ArtifactService"})," and ",(0,i.jsx)(t.code,{children:"MemoryService"})," based on its configuration."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"agents",children:"Agents"}),"\n",(0,i.jsx)(t.p,{children:"An agent is the logical entity within an Agent Host that performs tasks. It is defined by its configuration, which includes:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Instructions"}),": The base prompt that defines its persona, capabilities, and constraints."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"LLM Configuration"}),": The specific large language model to use."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Toolset"}),": A collection of available tools, which can be built-in, custom Python functions, or MCP Toolsets."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"key-architectural-flows",children:"Key Architectural Flows"}),"\n",(0,i.jsx)(t.h3,{id:"user-task-processing-flow",children:"User Task Processing Flow"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["An external client sends a request to a ",(0,i.jsx)(t.strong,{children:"Gateway"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["The Gateway authenticates the request, retrieves the user's permission scopes via its ",(0,i.jsx)(t.code,{children:"AuthorizationService"}),", and translates the request into an A2A task message. It includes the scopes in the Solace message's user properties."]}),"\n",(0,i.jsxs)(t.li,{children:["The Gateway publishes the message to the target agent's request topic on the ",(0,i.jsx)(t.strong,{children:"Solace Broker"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["The corresponding ",(0,i.jsx)(t.strong,{children:"Agent Host"})," receives the message. The ",(0,i.jsx)(t.code,{children:"SamAgentComponent"})," extracts the scopes and initiates an ADK task."]}),"\n",(0,i.jsxs)(t.li,{children:["The ADK ",(0,i.jsx)(t.code,{children:"LlmAgent"})," processes the task. Before invoking the LLM, a ",(0,i.jsx)(t.code,{children:"before_model_callback"})," filters the available tools based on the user's scopes."]}),"\n",(0,i.jsxs)(t.li,{children:["As the agent executes, the ",(0,i.jsx)(t.code,{children:"SamAgentComponent"})," translates ADK events into A2A status and artifact update messages, publishing them to the originating Gateway's status topic."]}),"\n",(0,i.jsxs)(t.li,{children:["The Gateway receives these streaming updates, performs any necessary late-stage processing (like resolving ",(0,i.jsx)(t.code,{children:"artifact_content"})," embeds), and forwards them to the client."]}),"\n",(0,i.jsx)(t.li,{children:"Upon completion, the Agent Host sends a final A2A response message to the Gateway, which delivers it to the client."}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"agent-to-agent-delegation-flow",children:"Agent-to-Agent Delegation Flow"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Agent A"}),", while processing a task, determines a sub-task should be delegated to ",(0,i.jsx)(t.strong,{children:"Agent B"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["Agent A uses its ",(0,i.jsx)(t.code,{children:"PeerAgentTool"})," to construct a new A2A task request for Agent B. It propagates the original user's permission scopes to maintain the security context."]}),"\n",(0,i.jsx)(t.li,{children:"The request is published to Agent B's request topic."}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Agent B's Host"})," receives and processes the sub-task, enforcing the propagated scopes on its own toolset."]}),"\n",(0,i.jsx)(t.li,{children:"Agent B sends status updates and a final response to topics designated by Agent A."}),"\n",(0,i.jsx)(t.li,{children:"Agent A receives the results and incorporates them into its ongoing task."}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"agent-discovery-flow",children:"Agent Discovery Flow"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["On startup and periodically, each ",(0,i.jsx)(t.strong,{children:"Agent Host"})," publishes an ",(0,i.jsx)(t.code,{children:"AgentCard"})," (a JSON document describing its agent's capabilities) to a well-known discovery topic (for example, ",(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/discovery/agentcards"}),")."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Gateways"})," and other ",(0,i.jsx)(t.strong,{children:"Agent Hosts"})," subscribe to this topic."]}),"\n",(0,i.jsxs)(t.li,{children:["Upon receiving an ",(0,i.jsx)(t.code,{children:"AgentCard"}),", components update their local ",(0,i.jsx)(t.code,{children:"AgentRegistry"}),", making them aware of available agents for user selection (at the Gateway) or peer delegation (at the Agent)."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"a2a-protocol-and-topic-structure",children:"A2A Protocol and Topic Structure"}),"\n",(0,i.jsx)(t.p,{children:"The A2A protocol is based on JSON-RPC 2.0 and defines the message formats for all interactions. Communication is routed via a hierarchical topic structure on the Solace broker."}),"\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Purpose"}),(0,i.jsx)(t.th,{children:"Topic Pattern"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Agent Discovery"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/discovery/agentcards"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Task Requests"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/agent/request/{target_agent_name}"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Status Updates"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/gateway/status/{gateway_id}/{task_id}"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Final Responses"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/gateway/response/{gateway_id}/{task_id}"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Peer Delegation Status"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/agent/status/{delegating_agent_name}/{sub_task_id}"})})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.strong,{children:"Peer Delegation Response"})}),(0,i.jsx)(t.td,{children:(0,i.jsx)(t.code,{children:"{namespace}/a2a/v1/agent/response/{delegating_agent_name}/{sub_task_id}"})})]})]})]}),"\n",(0,i.jsx)(t.p,{children:"This topic structure allows for precise, point-to-point routing in a decoupled, asynchronous environment."})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var n=s(6540);const i={},r=n.createContext(i);function o(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[8423],{8782:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"documentation/concepts/orchestrator","title":"Orchestrator","description":"The A2A (Agent-to-Agent) protocol is the communication backbone of Solace Agent Mesh that enables distributed agent coordination and workflow management. Unlike traditional centralized orchestration, the A2A protocol enables agents to discover each other, delegate tasks, and collaborate directly through standardized message patterns.","source":"@site/docs/documentation/concepts/orchestrator.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/orchestrator","permalink":"/solace-agent-mesh/docs/documentation/concepts/orchestrator","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/orchestrator.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"title":"Orchestrator","sidebar_position":40},"sidebar":"docSidebar","previous":{"title":"Agents","permalink":"/solace-agent-mesh/docs/documentation/concepts/agents"},"next":{"title":"Plugins","permalink":"/solace-agent-mesh/docs/documentation/concepts/plugins"}}');var o=t(4848),a=t(8453);const r={title:"Orchestrator",sidebar_position:40},i="Orchestrator Agent",c={},l=[{value:"Key Functions",id:"key-functions",level:2}];function d(e){const n={admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"orchestrator-agent",children:"Orchestrator Agent"})}),"\n",(0,o.jsx)(n.p,{children:"The A2A (Agent-to-Agent) protocol is the communication backbone of Solace Agent Mesh that enables distributed agent coordination and workflow management. Unlike traditional centralized orchestration, the A2A protocol enables agents to discover each other, delegate tasks, and collaborate directly through standardized message patterns."}),"\n",(0,o.jsxs)(n.p,{children:["The advantages of centralized orchestration such as task breakdown and management, centralized point of communication and session management are still achieved in Solace Agent Mesh through a specialized agent called the ",(0,o.jsx)(n.strong,{children:"OrchestratorAgent"})," that acts as the central coordinator for complex workflows."]}),"\n",(0,o.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,o.jsx)(n.p,{children:"The OrchestratorAgent allows for a centralized workflow management in the Solace Agent Mesh by coordinating tasks and communication between agents."})}),"\n",(0,o.jsx)(n.p,{children:"The system is not limited to a single orchestrator agent, and multiple orchestrator agents can be deployed to handle different workflows or domains. This allows for flexibility and scalability in managing complex tasks."}),"\n",(0,o.jsx)(n.h2,{id:"key-functions",children:"Key Functions"}),"\n",(0,o.jsx)(n.p,{children:"The orchestrator agent provides the following key functions:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Request Analysis and Action Planning"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Receives high-level goals or requests"}),"\n",(0,o.jsx)(n.li,{children:"Analyzes them in the context of available actions registered by agents in the system"}),"\n",(0,o.jsx)(n.li,{children:"Uses state-of-the-art generative AI techniques to plan a sequence of actions to fulfill the request"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Task Creation and Distribution"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Creates tasks based on the action plan"}),"\n",(0,o.jsx)(n.li,{children:"Distributes tasks to appropriate agents"}),"\n",(0,o.jsx)(n.li,{children:"Enables efficient parallel processing and optimal resource utilization"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Workflow Management"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Tracks outstanding tasks"}),"\n",(0,o.jsx)(n.li,{children:"Aggregates responses from various agents"}),"\n",(0,o.jsx)(n.li,{children:"Ensures all parts of a complex request are processed and combined coherently"}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.strong,{children:"Response Formatting"}),":"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"Formats aggregated responses suitable for the gateway"}),"\n",(0,o.jsx)(n.li,{children:"Ensures the final output meets the requirements of the specific use case or interface"}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(6540);const o={},a=s.createContext(o);function r(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
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)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[3974],{6145:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>g,frontMatter:()=>l,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"documentation/user-guide/create-agents","title":"Create Agents","description":"Introduction","source":"@site/docs/documentation/user-guide/create-agents.md","sourceDirName":"documentation/user-guide","slug":"/documentation/user-guide/create-agents","permalink":"/solace-agent-mesh/docs/documentation/user-guide/create-agents","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/user-guide/create-agents.md","tags":[],"version":"current","sidebarPosition":30,"frontMatter":{"title":"Create Agents","sidebar_position":30},"sidebar":"docSidebar","previous":{"title":"Structure","permalink":"/solace-agent-mesh/docs/documentation/user-guide/structure"},"next":{"title":"Create Gateways","permalink":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways"}}');var i=t(4848),s=t(8453);const l={title:"Create Agents",sidebar_position:30},r="Creating Agents",a={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Quick Start: Creating Your First Agent",id:"quick-start-creating-your-first-agent",level:2},{value:"CLI Options",id:"cli-options",level:3},{value:"Core Concepts",id:"core-concepts",level:2},{value:"Tools",id:"tools",level:3},{value:"Configuration File",id:"configuration-file",level:3},{value:"Tool Configuration",id:"tool-configuration",level:3},{value:"ToolContext",id:"toolcontext",level:3},{value:"Lifecycle Functions",id:"lifecycle-functions",level:3},{value:"Step-by-Step Guide",id:"step-by-step-guide",level:2},{value:"Step 1: Initialize your Agent",id:"step-1-initialize-your-agent",level:3},{value:"Step 2: The Tool Function",id:"step-2-the-tool-function",level:3},{value:"Step 3: The Agent Configuration",id:"step-3-the-agent-configuration",level:3},{value:"Step 4: The Lifecycle Function",id:"step-4-the-lifecycle-function",level:3},{value:"Advanced Concepts",id:"advanced-concepts",level:2},{value:"Working with Artifacts",id:"working-with-artifacts",level:3},{value:"Using Multiple Tool Configurations",id:"using-multiple-tool-configurations",level:3},{value:"Running Your Agent",id:"running-your-agent",level:2},{value:"Architecture Overview",id:"architecture-overview",level:2},{value:"Best Practices",id:"best-practices",level:2},{value:"Tool Design",id:"tool-design",level:3},{value:"Configuration",id:"configuration",level:3},{value:"Testing",id:"testing",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"creating-agents",children:"Creating Agents"})}),"\n",(0,i.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["For a more comprehensive tutorial example, see the ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/tutorials/custom-agent",children:"Build Your Own Agent"})," guide.\nThis page provides an in-depth theoretical overview of creating agents in Solace Agent Mesh."]})}),"\n",(0,i.jsxs)(n.p,{children:["Solace Agent Mesh (SAM) is a powerful platform that enables you to create intelligent agents that can communicate with each other and perform complex tasks. At its core, SAM uses a ",(0,i.jsx)(n.strong,{children:"tool-based architecture"})," where LLM-powered agents are equipped with specific capabilities (tools) that they can use to accomplish user requests."]}),"\n",(0,i.jsx)(n.p,{children:"This tutorial guides you through creating your first SAM agent from scratch. You will learn how to:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Define tools as Python functions"}),"\n",(0,i.jsx)(n.li,{children:"Configure an agent using YAML"}),"\n",(0,i.jsx)(n.li,{children:"Set up agent lifecycle functions"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:'By the end of this tutorial, you should have a working "Hello World" agent that demonstrates the fundamental concepts of SAM agent development.'}),"\n",(0,i.jsx)(n.h2,{id:"quick-start-creating-your-first-agent",children:"Quick Start: Creating Your First Agent"}),"\n",(0,i.jsxs)(n.p,{children:["You can create an agent directly using the SAM CLI ",(0,i.jsx)(n.code,{children:"sam add agent"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam add agent my-first-agent\n"})}),"\n",(0,i.jsx)(n.p,{children:"This command:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Launches an interactive setup (or use ",(0,i.jsx)(n.code,{children:"--gui"})," for browser-based configuration)"]}),"\n",(0,i.jsx)(n.li,{children:"Generates the necessary files and configuration"}),"\n",(0,i.jsx)(n.li,{children:"Sets up the basic agent structure"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Note that create agent as plugin is preferred over create agent directly."}),"\n",(0,i.jsx)(n.h3,{id:"cli-options",children:"CLI Options"}),"\n",(0,i.jsx)(n.p,{children:"You can customize the agent creation with provided CLI options."}),"\n",(0,i.jsx)(n.p,{children:"For a complete list of options, run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam add agent --help\n"})}),"\n",(0,i.jsx)(n.h2,{id:"core-concepts",children:"Core Concepts"}),"\n",(0,i.jsx)(n.p,{children:"Before diving into the implementation, it is important to understand the key concepts that make SAM agents work:"}),"\n",(0,i.jsx)(n.h3,{id:"tools",children:"Tools"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Tools are the fundamental building blocks of SAM agents."})," Each tool is implemented as a Python function that performs a specific task. Tools can:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Process text and data"}),"\n",(0,i.jsx)(n.li,{children:"Interact with external APIs"}),"\n",(0,i.jsx)(n.li,{children:"Create and manipulate files"}),"\n",(0,i.jsx)(n.li,{children:"Communicate with other agents"}),"\n",(0,i.jsx)(n.li,{children:"Access databases and services"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The LLM (Large Language Model) orchestrating your agent decides which tools to use based on the user's request and the tool descriptions you provide."}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Solace Agent Mesh provides a set of built-in tools plus built-in support ",(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration",children:"model context protocol (MCP)"})," servers which can be configured in the tools list of your agent configuration"]})}),"\n",(0,i.jsx)(n.h3,{id:"configuration-file",children:"Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.yaml"})," (for plugin template) or ",(0,i.jsx)(n.code,{children:"agent-name.yaml"})," (for agent instances) file is the blueprint of your agent. It defines:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Agent identity"}),": Name, description, and capabilities"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Model configuration"}),": Which LLM to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Tools list"}),": Which tools the agent can access and how they're configured"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Lifecycle functions"}),": Setup and cleanup procedures"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Framework services"}),": Session management, artifact storage, and so on."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Agent card"}),": Metadata describing the agent capabilities, skills and its visibility in the system"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"tool-configuration",children:"Tool Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["Within the ",(0,i.jsx)(n.code,{children:"tools"})," list in your yaml config, each tool can have its own ",(0,i.jsx)(n.code,{children:"tool_config"})," section. This allows you to:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Configure the same tool function for different purposes"}),"\n",(0,i.jsx)(n.li,{children:"Pass specific parameters to tool instances"}),"\n",(0,i.jsx)(n.li,{children:"Customize tool behavior per agent"}),"\n"]}),"\n",(0,i.jsxs)(n.admonition,{type:"info",children:[(0,i.jsxs)(n.p,{children:['For tools of type "python", you can also use the ',(0,i.jsx)(n.code,{children:"tool_name"})," and ",(0,i.jsx)(n.code,{children:"tool_description"})," to overwrite the function name and description in the tool docstring."]}),(0,i.jsx)(n.p,{children:"This is useful when using a generic tool function for multiple purposes, allowing you to provide a more descriptive name and description for each instance."})]}),"\n",(0,i.jsx)(n.h3,{id:"toolcontext",children:"ToolContext"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"ToolContext"})," object (passed as one of the arguments to your tool function) provides your tools with access to SAM core services:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Logging"}),": Structured logging for debugging and monitoring"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Artifact Service"}),": File storage and retrieval"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Session Information"}),": Current user and session context"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Agent State"}),": Shared data between tool calls"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"lifecycle-functions",children:"Lifecycle Functions"}),"\n",(0,i.jsx)(n.p,{children:"Lifecycle functions allow you to manage resources that should persist for the agent's lifetime:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"agent_init_function"})}),": Runs when the agent starts (for example, database connections)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"agent_cleanup_function"})}),": Runs when the agent shuts down (for example, closing connections)"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"step-by-step-guide",children:"Step-by-Step Guide"}),"\n",(0,i.jsx)(n.p,{children:"Create a simple agent that can greet users and demonstrate the core concepts."}),"\n",(0,i.jsxs)(n.p,{children:["You can create an agent either by using the ",(0,i.jsx)(n.code,{children:"sam add agent"})," command or by creating a new plugin of type agent, ",(0,i.jsx)(n.code,{children:"sam plugin create my-hello-agent --type agent"}),"."]}),"\n",(0,i.jsxs)(n.admonition,{title:"Agent as plugin",type:"tip",children:[(0,i.jsx)(n.p,{children:"Agent can be implemented as plugins. This allows you to easily package your agent logic and reuse it across different projects."}),(0,i.jsxs)(n.p,{children:["To create a plugin of type agent, use the ",(0,i.jsx)(n.code,{children:"sam plugin create <your_agent_plugin_name> --type agent"})," command."]}),(0,i.jsx)(n.p,{children:"For a complete list of options, run:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin create --help\n"})}),(0,i.jsxs)(n.p,{children:["To create an agent instance based on plugin, use the ",(0,i.jsx)(n.code,{children:"sam plugin add <your_agent_name> --plugin <your_agent_plugin>"})," command."]}),(0,i.jsx)(n.p,{children:"For a complete list of options, run:"}),(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin add --help\n"})}),(0,i.jsx)(n.p,{children:"Although their directory structure is slightly different, both agents require a yaml configuration file, and a python module with the respective tools and lifecycle functions."})]}),"\n",(0,i.jsx)(n.h3,{id:"step-1-initialize-your-agent",children:"Step 1: Initialize your Agent"}),"\n",(0,i.jsx)(n.p,{children:"In this tutorial, you create a new agent by creating a new plugin of type agent."}),"\n",(0,i.jsx)(n.p,{children:"To create a new agent plugin, run the following command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sam plugin create my-hello-agent --type agent\n"})}),"\n",(0,i.jsx)(n.p,{children:"And follow the prompts to set up your agent. The prompts create a new directory structure for your agent."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"my-hello-agent/\n\u251c\u2500\u2500 src/\n\u2502 \u2514\u2500\u2500 my_hello_agent/\n\u2502 \u251c\u2500\u2500 __init__.py\n\u2502 \u251c\u2500\u2500 tools.py\n\u2502 \u2514\u2500\u2500 lifecycle.py # This file won't be automatically created\n\u251c\u2500\u2500 config.yaml\n\u251c\u2500\u2500 pyproject.toml\n\u2514\u2500\u2500 README.md\n"})}),"\n",(0,i.jsx)(n.mermaid,{value:"graph TD\n A[my-hello-agent/] --\x3e B[src/]\n A --\x3e C[config.yaml]\n A --\x3e D[pyproject.toml]\n A --\x3e E[README.md]\n \n B --\x3e F[my_hello_agent/]\n F --\x3e G[__init__.py]\n F --\x3e H[tools.py]\n F --\x3e I[lifecycle.py]\n \n style C fill:#b60000,stroke:#333,stroke-width:2px\n style H fill:#b60000,stroke:#333,stroke-width:2px\n style I fill:#007000,stroke:#333,stroke-width:2px"}),"\n",(0,i.jsx)(n.h3,{id:"step-2-the-tool-function",children:"Step 2: The Tool Function"}),"\n",(0,i.jsx)(n.p,{children:"Create your first tool function:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_hello_agent/tools.py\n"""\nTools for the Hello World agent.\n"""\n\nfrom typing import Any, Dict, Optional\nfrom google.adk.tools import ToolContext\nfrom solace_ai_connector.common.log import log\n\n\nasync def hello_tool(\n name: str,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Greets a user with a personalized message.\n \n Args:\n name: The name of the person to greet\n tool_context: SAM framework context (provided automatically)\n tool_config: Tool-specific configuration (from config.yaml)\n \n Returns:\n A dictionary with the greeting message\n """\n log_identifier = "[HelloTool]"\n log.info(f"{log_identifier} Greeting user: {name}")\n \n # Get configuration from tool_config\n greeting_prefix = "Hello"\n if tool_config:\n greeting_prefix = tool_config.get("greeting_prefix", "Hello")\n \n # Create the greeting message\n greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!"\n \n log.info(f"{log_identifier} Generated greeting: {greeting_message}")\n \n return {\n "status": "success",\n "message": greeting_message,\n "greeted_name": name\n }\n\n\nasync def farewell_tool(\n name: str,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Says goodbye to a user.\n \n Args:\n name: The name of the person to say goodbye to\n tool_context: SAM framework context (provided automatically)\n tool_config: Tool-specific configuration (from config.yaml)\n \n Returns:\n A dictionary with the farewell message\n """\n log_identifier = "[FarewellTool]"\n log.info(f"{log_identifier} Saying goodbye to user: {name}")\n \n # Get configuration from tool_config\n farewell_prefix = "Goodbye"\n if tool_config:\n farewell_prefix = tool_config.get("farewell_prefix", "Goodbye")\n \n # Create the farewell message\n farewell_message = f"{farewell_prefix}, {name}! Thanks for using Solace Agent Mesh!"\n \n log.info(f"{log_identifier} Generated farewell: {farewell_message}")\n \n return {\n "status": "success",\n "message": farewell_message,\n "farewell_name": name\n }\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Key Points:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Function Signature"}),": All tool functions should be ",(0,i.jsx)(n.code,{children:"async"})," and accept ",(0,i.jsx)(n.code,{children:"tool_context"})," and ",(0,i.jsx)(n.code,{children:"tool_config"})," parameters"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Return Format"}),": Return a dictionary with at least a ",(0,i.jsx)(n.code,{children:"status"})," field"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Logging"}),": Use the SAM logger for consistent logging"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Configuration"}),": Access tool-specific config via the ",(0,i.jsx)(n.code,{children:"tool_config"})," parameter"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-3-the-agent-configuration",children:"Step 3: The Agent Configuration"}),"\n",(0,i.jsx)(n.p,{children:"Create the main configuration file for your agent:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ... (additional services and configurations)\n\napps:\n - name: my-hello-agent\n app_module: solace_agent_mesh.agent.sac.app \n broker:\n <<: *broker_connection\n \n # Agent-specific configuration\n app_config:\n # Basic agent identity\n namespace: ${NAMESPACE} \n supports_streaming: true \n agent_name: "HelloAgent"\n display_name: "Hello World Agent"\n \n # LLM model configuration\n model: *general_model \n \n # Agent instructions (system prompt)\n instruction: |\n You are a friendly Hello World agent. Your purpose is to greet users and \n demonstrate the capabilities of Solace Agent Mesh. You can:\n \n 1. Greet users with personalized messages using the hello_tool\n 2. Say goodbye to users using the farewell_tool\n \n Always be polite and helpful. When greeting someone, ask for their name \n if they haven\'t provided it.\n \n # Lifecycle functions\n agent_init_function:\n module: "my_hello_agent.lifecycle" # This should point to your lifecycle python module\n name: "initialize_hello_agent"\n config:\n startup_message: "Hello Agent is starting up!"\n log_level: "INFO"\n \n agent_cleanup_function:\n module: "my_hello_agent.lifecycle"\n name: "cleanup_hello_agent"\n \n # Tools configuration\n tools:\n # Hello tool with custom greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "greet_user" # Renaming the tool, must use this name in the agent card\n tool_config:\n greeting_prefix: "Hello there"\n \n # Farewell tool with custom farewell\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "farewell_tool"\n tool_name: "say_goodbye"\n tool_config:\n farewell_prefix: "See you later"\n \n # Built-in artifact tools for file operations\n - tool_type: builtin-group\n group_name: "artifact_management"\n \n # Agent card (describes the agent\'s capabilities)\n agent_card:\n description: "A friendly Hello World agent that demonstrates SAM capabilities"\n defaultInputModes: ["text"]\n defaultOutputModes: ["text"]\n skills:\n - id: "greet_user"\n name: "Greet User"\n description: "Greets users with personalized messages"\n - id: "say_goodbye"\n name: "Say Goodbye"\n description: "Says goodbye to users"\n - id: "file_operations"\n name: "File Operations"\n description: "Create, read, and manage files and artifacts"\n \n # Session and artifact services\n session_service: *default_session_service\n artifact_service: *default_artifact_service\n# ... (additional services and configurations)\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Key Sections Explained:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"namespace"})}),": Unique identifier for your agent in the mesh"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"model"})}),": LLM configuration (can be a string or detailed config)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"instruction"})}),": The system prompt that defines your agent's behavior"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"tools"})}),": List of tools your agent can use, with their configurations"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:(0,i.jsx)(n.code,{children:"agent_card"})}),": Metadata describing your agent's capabilities"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"step-4-the-lifecycle-function",children:"Step 4: The Lifecycle Function"}),"\n",(0,i.jsx)(n.p,{children:"Lifecycle functions are completely optional but useful for managing resources. They run when the agent starts and stops."}),"\n",(0,i.jsx)(n.p,{children:"The lifecycle file is not automatically created, so you need to create it manually:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"touch src/my_hello_agent/lifecycle.py\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'# src/my_hello_agent/lifecycle.py\n"""\nLifecycle functions for the Hello World agent.\n"""\n\nfrom typing import Any, Dict\nfrom pydantic import BaseModel, Field\nfrom solace_ai_connector.common.log import log\n\n\nclass HelloAgentInitConfig(BaseModel):\n """\n Configuration model for the Hello Agent initialization.\n """\n startup_message: str = Field(description="Message to log on startup")\n log_level: str = Field(default="INFO", description="Logging level for the agent")\n\n\ndef initialize_hello_agent(host_component: Any, init_config: HelloAgentInitConfig):\n """\n Initializes the Hello World agent.\n \n Args:\n host_component: The agent host component\n init_config: Validated initialization configuration\n """\n log_identifier = f"[{host_component.agent_name}:init]"\n log.info(f"{log_identifier} Starting Hello Agent initialization...")\n \n # Log the startup message from config\n log.info(f"{log_identifier} {init_config.startup_message}")\n \n # You could initialize shared resources here, such as:\n # - Database connections\n # - API clients\n # - Caches or shared data structures\n \n # Store any shared state in the agent\n host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z")\n host_component.set_agent_specific_state("greeting_count", 0)\n \n log.info(f"{log_identifier} Hello Agent initialization completed successfully")\n\n\ndef cleanup_hello_agent(host_component: Any):\n """\n Cleans up resources when the Hello World agent shuts down.\n \n Args:\n host_component: The agent host component\n """\n log_identifier = f"[{host_component.agent_name}:cleanup]"\n log.info(f"{log_identifier} Starting Hello Agent cleanup...")\n \n # Retrieve any shared state\n greeting_count = host_component.get_agent_specific_state("greeting_count", 0)\n log.info(f"{log_identifier} Agent processed {greeting_count} greetings during its lifetime")\n \n # Clean up resources here, such as:\n # - Closing database connections\n # - Shutting down background tasks\n # - Saving final state\n \n log.info(f"{log_identifier} Hello Agent cleanup completed")\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Key Points:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Pydantic Models"}),": Use Pydantic for configuration validation"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Shared State"}),": Store data that persists across tool calls"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Resource Management"}),": Initialize connections in ",(0,i.jsx)(n.code,{children:"init"}),", clean up in ",(0,i.jsx)(n.code,{children:"cleanup"})]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"advanced-concepts",children:"Advanced Concepts"}),"\n",(0,i.jsx)(n.h3,{id:"working-with-artifacts",children:"Working with Artifacts"}),"\n",(0,i.jsx)(n.p,{children:"You can enhance our hello tool to save greetings to a file using SAM's artifact service:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-python",children:'async def hello_tool_with_artifact(\n name: str,\n save_to_file: bool = False,\n tool_context: Optional[ToolContext] = None,\n tool_config: Optional[Dict[str, Any]] = None\n) -> Dict[str, Any]:\n """\n Greets a user and optionally saves the greeting to a file.\n """\n log_identifier = "[HelloToolWithArtifact]"\n \n # Generate greeting (same as before)\n greeting_prefix = tool_config.get("greeting_prefix", "Hello") if tool_config else "Hello"\n greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!"\n \n result = {\n "status": "success",\n "message": greeting_message,\n "greeted_name": name\n }\n \n # Save to artifact if requested\n if save_to_file and tool_context:\n try:\n from datetime import datetime\n timestamp = datetime.now().isoformat()\n \n # Use the artifact service to save the greeting\n artifact_service = tool_context._invocation_context.artifact_service\n if artifact_service:\n filename = f"greeting_{name}_{timestamp}.txt"\n content = f"Greeting: {greeting_message}\\nTimestamp: {timestamp}\\n"\n \n await artifact_service.save_artifact(\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=content.encode(\'utf-8\'),\n mime_type="text/plain"\n )\n \n result["artifact_saved"] = filename\n log.info(f"{log_identifier} Saved greeting to artifact: {filename}")\n \n except Exception as e:\n log.error(f"{log_identifier} Failed to save artifact: {e}")\n result["artifact_error"] = str(e)\n \n return result\n'})}),"\n",(0,i.jsx)(n.h3,{id:"using-multiple-tool-configurations",children:"Using Multiple Tool Configurations"}),"\n",(0,i.jsx)(n.p,{children:"You can configure the same tool function multiple times with different settings:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'tools:\n # Formal greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "formal_greeting"\n tool_config:\n greeting_prefix: "Good day"\n \n # Casual greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "casual_greeting"\n tool_config:\n greeting_prefix: "Hey there"\n \n # Enthusiastic greeting\n - tool_type: python\n component_module: "my_hello_agent.tools"\n function_name: "hello_tool"\n tool_name: "enthusiastic_greeting"\n tool_config:\n greeting_prefix: "Hello and welcome"\n'})}),"\n",(0,i.jsx)(n.p,{children:"This gives your agent multiple greeting styles to choose from based on the context."}),"\n",(0,i.jsx)(n.h2,{id:"running-your-agent",children:"Running Your Agent"}),"\n",(0,i.jsxs)(n.p,{children:["To run a plugin agent, you first need to package and install it as a plugin. But for debugging or isolated development testing, you can run your agent from the ",(0,i.jsx)(n.code,{children:"src"})," directory directly using the SAM CLI."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd src\nsam run ../config.yaml\n"})}),"\n",(0,i.jsxs)(n.p,{children:["By moving to the ",(0,i.jsx)(n.code,{children:"src"})," directory, the module path is set correctly, allowing SAM to find your functions without having to install them in your python environment as a plugin package."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Interact with your agent:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Through the SAM Web UI"}),"\n",(0,i.jsx)(n.li,{children:"Via REST API calls"}),"\n",(0,i.jsx)(n.li,{children:"Through other SAM agents"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"architecture-overview",children:"Architecture Overview"}),"\n",(0,i.jsx)(n.p,{children:"Here is how all the pieces fit together:"}),"\n",(0,i.jsx)(n.mermaid,{value:"graph TD\n subgraph Agent Configuration\n direction LR\n A[config.yaml] --\x3e|Defines| B(Agent Properties);\n A --\x3e|Lists & Configures| C(Tools);\n end\n\n subgraph Agent Host\n direction TB\n D[SAM Host] --\x3e|Loads| A;\n D --\x3e|Instantiates| E[Agent];\n E --\x3e|Initializes with| F[Lifecycle Functions];\n end\n\n subgraph Tool Implementation\n direction LR\n G[Python Module tools.py] --\x3e|Contains| H[Tool Functions];\n end\n\n subgraph Execution Flow\n direction TB\n I[User Request] --\x3e J[LLM Orchestrator];\n J --\x3e|Selects Tool| K{ADKToolWrapper};\n K --\x3e|Calls| H;\n H --\x3e|Accesses| L[ToolContext];\n H --\x3e|Uses| M[tool_config];\n H --\x3e|Returns Result| J;\n end\n\n C --\x3e|Wrapped by| K;\n\n style A fill:#b60000,stroke:#faa,stroke-width:2px\n style H fill:#b60000,stroke:#faa,stroke-width:2px\n style F fill:#007000,stroke:#faa,stroke-width:2px"}),"\n",(0,i.jsx)(n.h2,{id:"best-practices",children:"Best Practices"}),"\n",(0,i.jsx)(n.h3,{id:"tool-design",children:"Tool Design"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Single Responsibility"}),": Each tool should do one thing well"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Clear Documentation"}),": Write detailed docstrings for your tools"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Error Handling"}),": Always return structured error responses"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Logging"}),": Use consistent logging for debugging and monitoring"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"configuration",children:"Configuration"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Environment Variables"}),": Use environment variables for sensitive data"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Validation"}),": Use Pydantic models for configuration validation"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Documentation"}),": Comment your configuration files thoroughly"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"testing",children:"Testing"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Unit Tests"}),": Test your tool functions independently"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Integration Tests"}),": Test your agent with real SAM infrastructure"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mock Dependencies"}),": Mock external services for reliable testing"]}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>r});var o=t(6540);const i={},s=o.createContext(i);function l(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1442],{8376:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>s,toc:()=>r});const s=JSON.parse('{"id":"documentation/concepts/plugins","title":"Plugins","description":"Plugins","source":"@site/docs/documentation/concepts/plugins.md","sourceDirName":"documentation/concepts","slug":"/documentation/concepts/plugins","permalink":"/solace-agent-mesh/docs/documentation/concepts/plugins","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/concepts/plugins.md","tags":[],"version":"current","sidebarPosition":60,"frontMatter":{"title":"Plugins","sidebar_position":60},"sidebar":"docSidebar","previous":{"title":"Orchestrator","permalink":"/solace-agent-mesh/docs/documentation/concepts/orchestrator"},"next":{"title":"Solace AI Event Connector","permalink":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector"}}');var a=i(4848),l=i(8453);const t={title:"Plugins",sidebar_position:60},o=void 0,c={},r=[{value:"Plugins",id:"plugins",level:2},{value:"Official Core Plugins",id:"official-core-plugins",level:3},{value:"Create a Plugin",id:"create-a-plugin",level:2},{value:"Build the Plugin",id:"build-the-plugin",level:3},{value:"Share the Plugin",id:"share-the-plugin",level:3},{value:"Use a Plugin",id:"use-a-plugin",level:2},{value:"Plugin Catalog Dashboard",id:"plugin-catalog-dashboard",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"plugins",children:"Plugins"}),"\n",(0,a.jsx)(n.p,{children:"Plugins provide a mechanism to extend the functionality of Solace Agent Mesh in a modular, shareable, and reusable way. The current plugin ecosystem includes agents, gateways, and specialized integrations."}),"\n",(0,a.jsx)(n.admonition,{title:"In one sentence",type:"tip",children:(0,a.jsx)(n.p,{children:"Plugins are modular Python packages that extend SAM's capabilities through agents, gateways, and specialized integrations."})}),"\n",(0,a.jsxs)(n.p,{children:["Plugins are packaged as Python modules that can be installed using various package managers (",(0,a.jsx)(n.code,{children:"pip"}),", ",(0,a.jsx)(n.code,{children:"uv"}),", ",(0,a.jsx)(n.code,{children:"poetry"}),", ",(0,a.jsx)(n.code,{children:"conda"}),"). They integrate seamlessly with the A2A protocol and can provide:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Agent Plugins"}),": Specialized agents with domain-specific capabilities"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Gateway Plugins"}),": New interface types for external system integration"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Custom Plugins"}),": Custom integrations such as HR providers."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"All plugin interactions (create, build, add) are managed through the SAM CLI."}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["Run ",(0,a.jsx)(n.code,{children:"sam plugin --help"})," to see the list of available commands for plugins."]})}),"\n",(0,a.jsx)(n.h3,{id:"official-core-plugins",children:"Official Core Plugins"}),"\n",(0,a.jsxs)(n.p,{children:["Solace Agent Mesh comes with a set of official core plugins that can be used to extend the functionality of the system. You can find the repository of the official core plugins ",(0,a.jsx)(n.a,{href:"https://github.com/SolaceLabs/solace-agent-mesh-core-plugins",children:"here \ud83d\udd17"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["For more information about how to use the official core plugins, see ",(0,a.jsx)(n.a,{href:"#use-a-plugin",children:"Use Plugins"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"create-a-plugin",children:"Create a Plugin"}),"\n",(0,a.jsxs)(n.p,{children:["To get started, ",(0,a.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/installation",children:"install the SAM CLI"})," and run the following command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin create <plugin-name>\n"})}),"\n",(0,a.jsx)(n.p,{children:"Follow the prompts to create a new plugin. A plugin can be one of the following types:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Agent Plugin"}),": Contains custom agents that can be used in a Solace Agent Mesh project."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Gateway Plugin"}),": Contains custom gateways that can be used in a Solace Agent Mesh project."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Custom Plugin"}),": Contains custom integrations such as HR providers or other specialized functionality."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Solace Agent Mesh (SAM) CLI creates a directory with the provided name and the following structure:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"plugin-name/\n\u251c\u2500 config.yaml\n\u251c\u2500 src/\n\u2502 \u251c\u2500 __init__.py\n\u2502 \u251c\u2500 [...Other type specific python files]\n\u251c\u2500 .gitignore\n\u251c\u2500 pyproject.toml\n\u251c\u2500 README.md\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.code,{children:"src"})," directory contains the python source code."]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.code,{children:"config.yaml"})," file holds the configuration for the plugin, and how to be used in a SAM application."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Once the plugin is created, you can start customizing the config.yaml or the python files."}),"\n",(0,a.jsx)(n.h3,{id:"build-the-plugin",children:"Build the Plugin"}),"\n",(0,a.jsxs)(n.p,{children:["Building the plugin creates a Python wheel package that can be installed using ",(0,a.jsx)(n.code,{children:"pip"})," or other package managers."]}),"\n",(0,a.jsxs)(n.p,{children:["Python ",(0,a.jsx)(n.code,{children:"build"})," package must be installed already since ",(0,a.jsx)(n.code,{children:"sam plugin build"})," command uses ",(0,a.jsx)(n.code,{children:"build"})," package, if not, run ",(0,a.jsx)(n.code,{children:"pip install build"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"To build the plugin, run the following SAM CLI command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin build\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The plugin uses the standard ",(0,a.jsx)(n.code,{children:"pyproject.toml"})," file to build the package."]}),"\n",(0,a.jsx)(n.h3,{id:"share-the-plugin",children:"Share the Plugin"}),"\n",(0,a.jsxs)(n.p,{children:["To share the plugin, you can upload the wheel package to a package repository or share the wheel package directly, or any other valid way to share a ",(0,a.jsx)(n.code,{children:"pyproject"})," project."]}),"\n",(0,a.jsx)(n.h2,{id:"use-a-plugin",children:"Use a Plugin"}),"\n",(0,a.jsxs)(n.p,{children:["To use a plugin in your project, use the ",(0,a.jsx)(n.code,{children:"plugin add"})," command, which performs two steps under-the-hood:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Locates the plugin or installs the plugin package using a Python package manager (like ",(0,a.jsx)(n.code,{children:"pip"})," or ",(0,a.jsx)(n.code,{children:"uv"}),")"]}),"\n",(0,a.jsx)(n.li,{children:"Creates a component instance based on the plugin"}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME>\n"})}),"\n",(0,a.jsx)(n.p,{children:"where:"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"<COMPONENT_NAME>"})," is the name you choose for the component instance in your project."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"<PLUGIN_NAME>"}),", you can use:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Name of the plugin as published to a package manager like ",(0,a.jsx)(n.code,{children:"pypi"}),", for example ",(0,a.jsx)(n.code,{children:"my-plugin"})]}),"\n",(0,a.jsx)(n.li,{children:"Name of the plugin that has been already installed into your Python environment."}),"\n",(0,a.jsxs)(n.li,{children:["A local path to the plugin directory, for example ",(0,a.jsx)(n.code,{children:"./my-plugin"})]}),"\n",(0,a.jsxs)(n.li,{children:["A path to a wheel package, for example ",(0,a.jsx)(n.code,{children:"./my-plugin/dist/my_plugin-0.1.0-py3-none-any.whl"})]}),"\n",(0,a.jsxs)(n.li,{children:["A URL to a git repository, for example ",(0,a.jsx)(n.code,{children:"git+https://github.com/<USERNAME>/<REPOSITORY>"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["If the plugin is in a subdirectory of the repository, you can specify the subdirectory using the ",(0,a.jsx)(n.code,{children:"git+https://github.com/<USERNAME>/<REPOSITORY>#subdirectory=<PLUGIN_NAME>"})," syntax."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The CLI handles both steps automatically, or you can manage the plugin installation yourself using your preferred Python package manager."}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You can also customize the python package manager command used to install the plugin by setting the ",(0,a.jsx)(n.code,{children:"SAM_PLUGIN_INSTALL_COMMAND"})," environment variable or passing the ",(0,a.jsx)(n.code,{children:"--install-command"})," option to the ",(0,a.jsx)(n.code,{children:"plugin add"})," command.\nFor example, to use ",(0,a.jsx)(n.code,{children:"uv"})," as the package manager, you can run:"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}"\n'})}),(0,a.jsx)(n.p,{children:"or"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> --install-command "uv pip install {package}"\n'})})]}),"\n",(0,a.jsxs)(n.p,{children:["This command adds the plugin instance configuration to your ",(0,a.jsx)(n.code,{children:"configs"})," directory."]}),"\n",(0,a.jsx)(n.p,{children:"Depending on the plugin, you may need to update the newly added plugin configuration file. Follow the instructions provided by the plugin author for any specific configurations."}),"\n",(0,a.jsx)(n.h2,{id:"plugin-catalog-dashboard",children:"Plugin Catalog Dashboard"}),"\n",(0,a.jsxs)(n.p,{children:["You can manage available plugins with the ",(0,a.jsx)(n.code,{children:"plugin catalog"})," command, which launches a user-friendly interface."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"solace-agent-mesh plugin catalog\n"})})]})}function h(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>t,x:()=>o});var s=i(6540);const a={},l=s.createContext(a);function t(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[7289],{3089:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"documentation/deployment/deploy","title":"Deployment","description":"Development","source":"@site/docs/documentation/deployment/deploy.md","sourceDirName":"documentation/deployment","slug":"/documentation/deployment/deploy","permalink":"/solace-agent-mesh/docs/documentation/deployment/deploy","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/deployment/deploy.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Deployment","sidebar_position":10},"sidebar":"docSidebar","previous":{"title":"Dynamic Embeds","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds"},"next":{"title":"Observability","permalink":"/solace-agent-mesh/docs/documentation/deployment/observability"}}');var s=t(4848),r=t(8453);const i={title:"Deployment",sidebar_position:10},a="Deployment",c={},l=[{value:"Development",id:"development",level:2},{value:"Production",id:"production",level:2},{value:"Docker Deployment",id:"docker-deployment",level:3},{value:"Kubernetes Deployment",id:"kubernetes-deployment",level:3},{value:"Splitting and Scaling",id:"splitting-and-scaling",level:3},{value:"Storage Considerations",id:"storage-considerations",level:3},{value:"Security Best Practices",id:"security-best-practices",level:3},{value:"Solace Event Broker Configuration",id:"solace-event-broker-configuration",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",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:"deployment",children:"Deployment"})}),"\n",(0,s.jsx)(n.h2,{id:"development",children:"Development"}),"\n",(0,s.jsxs)(n.p,{children:["In a development environment, you can use the Solace Agent Mesh CLI to run the project as a single application. By default, environment variables are loaded from your configuration file (typically a ",(0,s.jsx)(n.code,{children:".env"})," file at the project root):"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sam run\n"})}),"\n",(0,s.jsx)(n.h2,{id:"production",children:"Production"}),"\n",(0,s.jsx)(n.p,{children:"For a production environment, use a containerized and reproducible setup. We recommend Docker or Kubernetes."}),"\n",(0,s.jsxs)(n.p,{children:["If your host system architecture is not ",(0,s.jsx)(n.code,{children:"linux/amd64"}),", add the ",(0,s.jsx)(n.code,{children:"--platform linux/amd64"})," flag when you run the container."]}),"\n",(0,s.jsx)(n.h3,{id:"docker-deployment",children:"Docker Deployment"}),"\n",(0,s.jsx)(n.p,{children:"Below is a sample Dockerfile for a Solace Agent Mesh project:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-Dockerfile",children:'FROM solace/solace-agent-mesh:latest\nWORKDIR /app\n\n# Install Python dependencies\nCOPY ./requirements.txt /app/requirements.txt\nRUN python3.11 -m pip install --no-cache-dir -r /app/requirements.txt\n\n# Copy project files\nCOPY . /app\n\nCMD ["run", "--system-env"]\n\n# To run one specific component, use:\n# CMD ["run", "--system-env", "configs/agents/main_orchestrator.yaml"]\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["And the following ",(0,s.jsx)(n.code,{children:".dockerignore"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:".env\n*.log\ndist\n.git\n.vscode\n.DS_Store\n"})}),"\n",(0,s.jsx)(n.h3,{id:"kubernetes-deployment",children:"Kubernetes Deployment"}),"\n",(0,s.jsxs)(n.p,{children:["For scalable and highly available deployments, Kubernetes is recommended. Below is a minimal ",(0,s.jsx)(n.code,{children:"Deployment"})," configuration:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: solace-agent-mesh\n labels:\n app: solace-agent-mesh\nspec:\n replicas: 1 # Adjust based on load\n selector:\n matchLabels:\n app: solace-agent-mesh\n template:\n metadata:\n labels:\n app: solace-agent-mesh\n spec:\n containers:\n - name: solace-agent-mesh\n image: your-registry/solace-agent-mesh:latest\n \n envFrom:\n - secretRef:\n name: solace-agent-mesh-secrets # Configure secrets in a Kubernetes Secret\n\n command: ["solace-agent-mesh", "run", "--system-env"]\n args:\n - "configs/main_orchestrator.yaml"\n - "configs/gateway/webui.yaml"\n # Add any other components you want to run here\n\n ports:\n - containerPort: 8000 # Adjust based on your service ports\n\n volumeMounts:\n - name: shared-storage\n mountPath: /tmp/solace-agent-mesh\n volumes:\n - name: shared-storage\n emptyDir: {}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"splitting-and-scaling",children:"Splitting and Scaling"}),"\n",(0,s.jsx)(n.p,{children:"For a robust production setup, consider splitting components into separate containers. This practice enhances scalability and ensures that if one process crashes, the rest of the system remains unaffected. Upon restarting, the failed process rejoins the system."}),"\n",(0,s.jsx)(n.p,{children:"To adapt the setup:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Reuse the same Docker image."}),"\n",(0,s.jsx)(n.li,{children:"Adjust the startup command to run only the necessary components."}),"\n",(0,s.jsx)(n.li,{children:"Scale containers independently based on their resource needs."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"storage-considerations",children:"Storage Considerations"}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"If using multiple containers, ensure all instances access the same storage with identical configurations."})}),"\n",(0,s.jsx)(n.h3,{id:"security-best-practices",children:"Security Best Practices"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Environment Variables"}),": Store secrets in a secure vault (for example, AWS Secrets Manager, HashiCorp Vault) rather than in ",(0,s.jsx)(n.code,{children:".env"})," files."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"TLS Encryption"}),": Ensure that communication between components and with the PubSub+ event broker is encrypted using TLS."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Container Security"}),": Regularly update container images and use security scanning tools (for example, Trivy, Clair)."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"solace-event-broker-configuration",children:"Solace Event Broker Configuration"}),"\n",(0,s.jsxs)(n.p,{children:["For production environments, it's recommended to use a cloud-managed PubSub+ event broker (or event broker service). For more information, see ",(0,s.jsx)(n.a,{href:"https://solace.com/products/event-broker/",children:"Solace PubSub+ Cloud"}),"."]})]})}function m(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(6540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[7132],{8097:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>l});const a=JSON.parse('{"id":"documentation/tutorials/rest-gateway","title":"REST Gateway","description":"The Solace Agent Mesh (SAM) REST API Gateway provides a standard, robust, and secure HTTP-based entry point for programmatic and system-to-system integrations. It allows external clients to submit tasks to SAM agents, manage files, and discover agent capabilities using a familiar RESTful interface.","source":"@site/docs/documentation/tutorials/rest-gateway.md","sourceDirName":"documentation/tutorials","slug":"/documentation/tutorials/rest-gateway","permalink":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/tutorials/rest-gateway.md","tags":[],"version":"current","sidebarPosition":15,"frontMatter":{"title":"REST Gateway","sidebar_position":15},"sidebar":"docSidebar","previous":{"title":"MCP Integration","permalink":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration"},"next":{"title":"Event Mesh Gateway","permalink":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway"}}');var s=t(4848),i=t(8453);const o={title:"REST Gateway",sidebar_position:15},r=void 0,c={},l=[{value:"Key Features",id:"key-features",level:2},{value:"Setting Up the Environment",id:"setting-up-the-environment",level:2},{value:"Adding the REST Gateway Plugin",id:"adding-the-rest-gateway-plugin",level:2},{value:"Configuring the REST Gateway",id:"configuring-the-rest-gateway",level:3},{value:"Running the REST Gateway",id:"running-the-rest-gateway",level:2},{value:"Sending a Request via REST API",id:"sending-a-request-via-rest-api",level:2},{value:"Modern API (v2) - Asynchronous",id:"modern-api-v2---asynchronous",level:3},{value:"Legacy API (v1) - Synchronous",id:"legacy-api-v1---synchronous",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",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.p,{children:"The Solace Agent Mesh (SAM) REST API Gateway provides a standard, robust, and secure HTTP-based entry point for programmatic and system-to-system integrations. It allows external clients to submit tasks to SAM agents, manage files, and discover agent capabilities using a familiar RESTful interface."}),"\n",(0,s.jsx)(n.p,{children:"The gateway is designed to be highly configurable and supports two distinct operational modes to cater to both modern, asynchronous workflows and legacy, synchronous systems."}),"\n",(0,s.jsx)(n.h2,{id:"key-features",children:"Key Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dual API Versions"}),": Supports both a modern asynchronous API (v2) and a deprecated synchronous API (v1) for backward compatibility."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Asynchronous by Default"}),': The v2 API uses a "202 Accepted + Poll" pattern, ideal for long-running agent tasks.']}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Delegated Authentication"}),": Integrates with an external authentication service via bearer tokens for secure access."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"File Handling"}),": Supports file uploads for tasks and provides download URLs for generated artifacts."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Dynamic Configuration"}),": All gateway behaviors, including server settings and authentication, are configured via the main SAM Host YAML file."]}),"\n"]}),"\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 the 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"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"adding-the-rest-gateway-plugin",children:"Adding the REST Gateway Plugin"}),"\n",(0,s.jsx)(n.p,{children:"Once you have your project set up, add the REST Gateway plugin:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sam plugin add my-http-rest --plugin sam-rest-gateway\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You can use any name for your agent, in this tutorial we use ",(0,s.jsx)(n.code,{children:"my-http-rest"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This command:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Installs the ",(0,s.jsx)(n.code,{children:"sam-rest-gateway"})," plugin"]}),"\n",(0,s.jsxs)(n.li,{children:["Creates a new gateway configuration named ",(0,s.jsx)(n.code,{children:"my-http-rest"})," in your ",(0,s.jsx)(n.code,{children:"configs/gateways/"})," directory"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"configuring-the-rest-gateway",children:"Configuring the REST Gateway"}),"\n",(0,s.jsxs)(n.p,{children:["For further configuration, you can edit the ",(0,s.jsx)(n.code,{children:"configs/gateways/my-http-rest.yaml"})," file. This file contains the gateway configuration that can be customized for your use case."]}),"\n",(0,s.jsxs)(n.admonition,{title:"Using local Solace PubSub+ Broker container",type:"info",children:[(0,s.jsxs)(n.p,{children:["Solace PubSub+ Broker container uses port 8080. You need to edit the ",(0,s.jsx)(n.code,{children:"rest_api_server_port"})," field and ",(0,s.jsx)(n.code,{children:"external_auth_service_url"})," field in the ",(0,s.jsx)(n.code,{children:"configs/gateways/my-http-rest.yaml"})," file to a free port other than 8080 (for example: 8081)."]}),(0,s.jsxs)(n.p,{children:["You can edit the yaml file directly or add environment variables ",(0,s.jsx)(n.code,{children:"REST_API_PORT=8081"})," and ",(0,s.jsx)(n.code,{children:"EXTERNAL_AUTH_SERVICE_URL=http://localhost:8081"}),"."]}),(0,s.jsx)(n.p,{children:"Make sure you change the REST API gateway to your new port in the following request examples."})]}),"\n",(0,s.jsx)(n.h2,{id:"running-the-rest-gateway",children:"Running the REST Gateway"}),"\n",(0,s.jsx)(n.p,{children:"To run the REST Gateway, use the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"sam run configs/gateways/my-http-rest.yaml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"sending-a-request-via-rest-api",children:"Sending a Request via REST API"}),"\n",(0,s.jsxs)(n.p,{children:["You can also interact with SAM via the ",(0,s.jsx)(n.strong,{children:"REST API"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The REST API gateway runs on ",(0,s.jsx)(n.code,{children:"http://localhost:8080"})," by default. You can use either the legacy v1 API or the modern async v2 API."]}),"\n",(0,s.jsx)(n.h3,{id:"modern-api-v2---asynchronous",children:"Modern API (v2) - Asynchronous"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"# Submit task\ncurl --location 'http://localhost:8080/api/v2/tasks' \\\n--header 'Authorization: Bearer token' \\\n--form 'agent_name=\"OrchestratorAgent\"' \\\n--form 'prompt=\"Hi\\!\"'\n\n# Poll for result using returned task ID\ncurl --location 'http://localhost:8080/api/v2/tasks/{taskId}' \\\n--header 'Authorization: Bearer token'\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["It might take a while for the system to respond. See the ",(0,s.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/deployment/observability",children:"observability"})," page for more information about monitoring the system while it processes the request."]})}),"\n",(0,s.jsx)(n.p,{children:"Sample output:"}),"\n",(0,s.jsxs)(n.p,{children:["From ",(0,s.jsx)(n.code,{children:"api/v2/tasks"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "taskId":"task-6a0e682f4f6c4927a5997e4fd06eea83"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["From ",(0,s.jsx)(n.code,{children:"api/v2/tasks/{taskId}"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": "task-6a0e682f4f6c4927a5997e4fd06eea83",\n "sessionId": "rest-session-4df0c24fcecc45fcb69692db9876bc5c",\n "status": {\n "state": "completed",\n "message": {\n "role": "agent",\n "parts": [{ "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today\'s Perfect Activities (13\xb0C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." }]\n },\n "timestamp": "2025-07-03T16:54:15.273085"\n },\n "artifacts": [],\n "metadata": { "agent_name": "OrchestratorAgent" }\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"legacy-api-v1---synchronous",children:"Legacy API (v1) - Synchronous"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"curl --location 'http://localhost:8080/api/v1/invoke' \\\n--header 'Authorization: Bearer None' \\\n--form 'prompt=\"Suggest some good outdoor activities in London given the season and current weather conditions.\"' \\\n--form 'agent_name=\"OrchestratorAgent\"' \\\n--form 'stream=\"false\"'\n"})}),"\n",(0,s.jsx)(n.p,{children:"Sample output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": "task-9f7d5f465f5a4f1ca799e8e5ecb35a43",\n "sessionId": "rest-session-36b36eeb69b04da7b67708f90e5512dc",\n "status": {\n "state": "completed",\n "message": {\n "role": "agent",\n "parts": [\n { "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today\'s Perfect Activities (13\xb0C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." }\n ]\n },\n "timestamp": "2025-07-03T16:59:37.486480"\n },\n "artifacts": [],\n "metadata": { "agent_name": "OrchestratorAgent" }\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:()=>r});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 r(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 +0,0 @@
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)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1095],{6871:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"documentation/user-guide/builtin-tools/builtin-tools","title":"Configuring Built-in Tools","description":"This guide provides instructions for enabling and configuring the built-in tools provided by the Solace Agent Mesh (SAM) framework.","source":"@site/docs/documentation/user-guide/builtin-tools/builtin-tools.md","sourceDirName":"documentation/user-guide/builtin-tools","slug":"/documentation/user-guide/builtin-tools/","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/user-guide/builtin-tools/builtin-tools.md","tags":[],"version":"current","sidebarPosition":60,"frontMatter":{"title":"Configuring Built-in Tools","sidebar_position":60},"sidebar":"docSidebar","previous":{"title":"Creating Service Providers","permalink":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers"},"next":{"title":"Artifact Management Tools","permalink":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management"}}');var l=i(4848),t=i(8453);const s={title:"Configuring Built-in Tools",sidebar_position:60},r="Configuring Built-in Tools",a={},d=[{value:"Overview",id:"overview",level:2},{value:"Configuration Methods",id:"configuration-methods",level:2},{value:"Method 1: Enabling Tool Groups (Recommended)",id:"method-1-enabling-tool-groups-recommended",level:3},{value:"Method 2: Enabling Individual Tools",id:"method-2-enabling-individual-tools",level:3},{value:"Available Tool Groups and Tools",id:"available-tool-groups-and-tools",level:2},{value:"Artifact Management",id:"artifact-management",level:3},{value:"Data Analysis",id:"data-analysis",level:3},{value:"Web",id:"web",level:3},{value:"Audio",id:"audio",level:3},{value:"Image",id:"image",level:3},{value:"General",id:"general",level:3},{value:"Complete Configuration Example",id:"complete-configuration-example",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(n.header,{children:(0,l.jsx)(n.h1,{id:"configuring-built-in-tools",children:"Configuring Built-in Tools"})}),"\n",(0,l.jsx)(n.p,{children:"This guide provides instructions for enabling and configuring the built-in tools provided by the Solace Agent Mesh (SAM) framework."}),"\n",(0,l.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,l.jsx)(n.p,{children:"Built-in tools are pre-packaged functionalities that can be granted to agents without requiring custom Python code. These tools address common operations such as file management, data analysis, web requests, and multi-modal generation."}),"\n",(0,l.jsxs)(n.p,{children:["The Solace Agent Mesh framework manages these tools through a central ",(0,l.jsx)(n.code,{children:"tool_registry"}),", which is responsible for loading the tools, generating instructional prompts for the Large Language Model (LLM), and handling their execution in a consistent manner."]}),"\n",(0,l.jsx)(n.h2,{id:"configuration-methods",children:"Configuration Methods"}),"\n",(0,l.jsxs)(n.p,{children:["Tool configuration is managed within the ",(0,l.jsx)(n.code,{children:"tools"})," list in an agent's ",(0,l.jsx)(n.code,{children:"app_config"})," block in the corresponding YAML configuration file."]}),"\n",(0,l.jsx)(n.h3,{id:"method-1-enabling-tool-groups-recommended",children:"Method 1: Enabling Tool Groups (Recommended)"}),"\n",(0,l.jsx)(n.p,{children:"For efficient configuration, built-in tools are organized into logical groups. An entire group of related tools can be enabled with a single entry. This is the recommended approach for standard functionalities."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:(0,l.jsx)(n.code,{children:"tool_type"})}),": ",(0,l.jsx)(n.code,{children:"builtin-group"})]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:(0,l.jsx)(n.code,{children:"group_name"})}),": The unique identifier for the tool category."]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Example:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: builtin-group\n group_name: "artifact_management"\n - tool_type: builtin-group\n group_name: "data_analysis"\n'})}),"\n",(0,l.jsx)(n.h3,{id:"method-2-enabling-individual-tools",children:"Method 2: Enabling Individual Tools"}),"\n",(0,l.jsx)(n.p,{children:"For more granular control over an agent's capabilities, specific tools can be enabled individually."}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:(0,l.jsx)(n.code,{children:"tool_type"})}),": ",(0,l.jsx)(n.code,{children:"builtin"})]}),"\n",(0,l.jsxs)(n.li,{children:[(0,l.jsx)(n.strong,{children:(0,l.jsx)(n.code,{children:"tool_name"})}),": The unique, registered name of the tool."]}),"\n"]}),"\n",(0,l.jsx)(n.p,{children:(0,l.jsx)(n.strong,{children:"Example:"})}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s app_config:\ntools:\n - tool_type: builtin\n tool_name: "web_request"\n - tool_type: builtin\n tool_name: "time_delay"\n'})}),"\n",(0,l.jsx)(n.admonition,{title:"Note",type:"info",children:(0,l.jsx)(n.p,{children:"The Solace Agent Mesh framework automatically handles duplicate tool registrations. If a tool group is enabled and a tool from that group is also listed individually, the tool is only loaded once."})}),"\n",(0,l.jsx)(n.h2,{id:"available-tool-groups-and-tools",children:"Available Tool Groups and Tools"}),"\n",(0,l.jsx)(n.p,{children:"The following sections detail the available tool groups and the individual tools they contain."}),"\n",(0,l.jsx)(n.h3,{id:"artifact-management",children:"Artifact Management"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"artifact_management"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": Tools for creating, loading, and managing file artifacts."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"create_artifact"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"append_to_artifact"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"list_artifacts"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"load_artifact"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"signal_artifact_for_return"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"apply_embed_and_create_artifact"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"extract_content_from_artifact"})}),"\n"]}),"\n",(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["For a more in-depth guide on using artifact management tools, refer to the ",(0,l.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management",children:"Artifact Management"})," documentation."]})}),"\n",(0,l.jsx)(n.h3,{id:"data-analysis",children:"Data Analysis"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"data_analysis"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": Tools for querying, transforming, and visualizing data."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"query_data_with_sql"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"create_sqlite_db"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"transform_data_with_jq"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"create_chart_from_plotly_config"})}),"\n"]}),"\n",(0,l.jsx)(n.admonition,{type:"info",children:(0,l.jsxs)(n.p,{children:["For a more in-depth guide on using Data Analysis tools, refer to the ",(0,l.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools",children:"Data Analysis Tools"})," documentation."]})}),"\n",(0,l.jsx)(n.h3,{id:"web",children:"Web"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"web"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": Tools for interacting with web resources."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"web_request"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"audio",children:"Audio"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"audio"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": Tools for generating and transcribing audio content."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"text_to_speech"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"multi_speaker_text_to_speech"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"transcribe_audio"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"image",children:"Image"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"image"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": Tools for generating and analyzing images."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"create_image_from_description"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"describe_image"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"edit_image_with_gemini"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"describe_audio"})}),"\n"]}),"\n",(0,l.jsx)(n.h3,{id:"general",children:"General"}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Group Name"}),": ",(0,l.jsx)(n.code,{children:"general"})]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Description"}),": General-purpose utility tools."]}),"\n",(0,l.jsxs)(n.p,{children:[(0,l.jsx)(n.strong,{children:"Individual Tools"}),":"]}),"\n",(0,l.jsxs)(n.ul,{children:["\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"convert_file_to_markdown"})}),"\n",(0,l.jsx)(n.li,{children:(0,l.jsx)(n.code,{children:"mermaid_diagram_generator"})}),"\n"]}),"\n",(0,l.jsx)(n.h2,{id:"complete-configuration-example",children:"Complete Configuration Example"}),"\n",(0,l.jsxs)(n.p,{children:["Below is a comprehensive example of a well-formed ",(0,l.jsx)(n.code,{children:"app_config"})," that uses the unified method to enable a mix of tool groups and individual tools."]}),"\n",(0,l.jsx)(n.pre,{children:(0,l.jsx)(n.code,{className:"language-yaml",children:'# In your agent\'s YAML file:\napp_config:\n namespace: "myorg/dev"\n agent_name: "DataAndWebAgent"\n model: "gemini-1.5-pro"\n instruction: "You are an agent that can analyze data and browse the web."\n\n # --- Unified Tool Configuration ---\n tools:\n # Enable a group of tools\n - tool_type: builtin-group\n group_name: "data_analysis"\n\n # Enable another group\n - tool_type: builtin-group\n group_name: "artifact_management"\n\n # Enable a single, specific tool\n - tool_type: builtin\n tool_name: "web_request"\n\n # Enable a custom Python tool\n - tool_type: python\n component_module: "my_company.tools.custom_calculators"\n function_name: "calculate_roi"\n\n # ... other service configurations (session_service, artifact_service, etc.)\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,l.jsx)(n,{...e,children:(0,l.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>s,x:()=>r});var o=i(6540);const l={},t=o.createContext(l);function s(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:s(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[1721],{3878:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"documentation/getting-started/introduction","title":"Introduction","description":"Solace Agent Mesh","source":"@site/docs/documentation/getting-started/introduction.md","sourceDirName":"documentation/getting-started","slug":"/documentation/getting-started/introduction","permalink":"/solace-agent-mesh/docs/documentation/getting-started/introduction","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/getting-started/introduction.md","tags":[],"version":"current","sidebarPosition":10,"frontMatter":{"title":"Introduction","sidebar_position":10},"sidebar":"docSidebar","next":{"title":"Installation","permalink":"/solace-agent-mesh/docs/documentation/getting-started/installation"}}');var i=t(4848),r=t(8453);const a={title:"Introduction",sidebar_position:10},o=void 0,l={},c=[{value:"Solace Agent Mesh",id:"solace-agent-mesh",level:2},{value:"What Problems Does the Mesh Solve?",id:"what-problems-does-the-mesh-solve",level:3},{value:"Why Choose Solace Agent Mesh?",id:"why-choose-solace-agent-mesh",level:3},{value:"Real-World Applications",id:"real-world-applications",level:2},{value:"Evolution Through Usage",id:"evolution-through-usage",level:3},{value:"For Developers",id:"for-developers",level:2},{value:"Getting Started",id:"getting-started",level:2}];function d(e){const n={a:"a",br:"br",h2:"h2",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"solace-agent-mesh",children:"Solace Agent Mesh"}),"\n",(0,i.jsx)(n.p,{children:"Modern AI development faces a fundamental challenge: while powerful AI models are readily available, the real complexity lies in connecting them to the data and systems where they can provide value. Data exists in isolated silos - spread across databases, SaaS platforms, APIs, and legacy systems - making it difficult to build AI applications that can work across these boundaries."}),"\n",(0,i.jsx)(n.p,{children:'Solace Agent Mesh (SAM) is an open-source framework that tackles this challenge head-on by integrating the Google Agent Development Kit (ADK) with the Solace AI Connector (SAC) to provide a "Universal A2A Agent Host" that enables scalable, distributed AI agent communication through Solace PubSub+. Whether you\'re an AI enthusiast experimenting with new models, or an enterprise developer building production systems, SAM gives you the tools to:'}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"connect AI agents to real-world data sources and systems through a standardized A2A (Agent-to-Agent) protocol"}),"\n",(0,i.jsx)(n.li,{children:"add gateways to provide event-based integrations or interactive UI connections"}),"\n",(0,i.jsx)(n.li,{children:"monitor and debug AI interactions in real-time through comprehensive observability"}),"\n",(0,i.jsx)(n.li,{children:"deploy solutions that scale from prototype to production with enterprise-grade reliability"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Rather than trying to be a monolithic AI platform, SAM focuses on being an excellent integration layer built on proven event-driven architecture. It brings together specialized agents - whether they're using local databases, accessing cloud APIs, or interfacing with enterprise systems - and helps them collaborate through standardized A2A communication to solve complex problems."}),"\n",(0,i.jsx)(n.p,{children:"Built on event-driven architecture technology from Solace with Google ADK integration, SAM provides the robust foundation needed for both experimental and production deployments."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Solace Agent Mesh Overview",src:t(1351).A+"",width:"2558",height:"1788"})}),"\n",(0,i.jsx)(n.h3,{id:"what-problems-does-the-mesh-solve",children:"What Problems Does the Mesh Solve?"}),"\n",(0,i.jsx)(n.p,{children:"The Solace Agent Mesh tackles the hardest challenges in building collaborative AI systems: agent coordination, system integration, and extensibility at scale. This section reveals the key problems it solves and shows how organizations are using it today."}),"\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:"Event-Driven Architecture at the Core:"}),(0,i.jsx)(n.br,{}),"\n","The beating heart of the Solace Agent Mesh is its event mesh\u2014a neural network for your AI components. This architecture creates a fluid, asynchronous communication layer where messages flow naturally between agents, gateways, and external systems. By decoupling senders from receivers, the mesh dramatically simplifies agent interactions, ensures message delivery even during component failures, and lets you add, remove, or restart components on the fly without disrupting workflows."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Breaking Down AI Silos:"}),(0,i.jsx)(n.br,{}),"\n","Specialized agents operate independently yet collaborate effortlessly\u2014like expert teammates rather than isolated tools."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Orchestrating Complex Workflows:"}),(0,i.jsx)(n.br,{}),"\n","Create sophisticated multi-agent processes where tasks flow naturally between specialists, executing in sequence or parallel based on dynamic needs."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Speaking a Common Language:"}),(0,i.jsx)(n.br,{}),"\n","The A2A protocol creates a universal communication standard, ensuring all agents and gateways understand each other regardless of their internal implementation."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Unifying AI Capabilities:"}),(0,i.jsx)(n.br,{}),"\n","Blend diverse AI models, custom tools (Python functions, MCP tools), and enterprise data sources into a cohesive ecosystem."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Connecting to Your World:"}),(0,i.jsx)(n.br,{}),"\n","Purpose-built gateways bridge the gap between the agent mesh and your existing systems\u2014web interfaces, Slack workspaces, APIs, and event streams."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Handling the Unpredictable:"}),(0,i.jsx)(n.br,{}),"\n","The event-driven backbone gracefully manages long-running tasks and asynchronous patterns that are inherent in AI agent interactions."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Adding Agents to Increase Capabilities"}),":\nEach new agent adds more capabilities to the system. Adding a new agent is not additive\u2014it is exponential. With each agent being able to enhance all other agents as they collaborate for more and more complex tasks."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Adding Gateways to Increase the Supported Use Cases"}),":\nEach new gateway opens up new use cases for the system. A new gateway can provide a new interface to the system, with a different system purpose and response rules."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Enterprise-Ready"}),":\nEngineered from the ground up for production deployment, this solution leverages expertise from Solace in building mission-critical distributed systems."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"why-choose-solace-agent-mesh",children:"Why Choose Solace Agent Mesh?"}),"\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:"Enterprise-Grade Performance:"}),(0,i.jsx)(n.br,{}),"\n","Built on Solace PubSub+ Event Broker, the mesh delivers high-throughput, fault-tolerant messaging that scales with your needs."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Plug-and-Play Extensibility:"}),(0,i.jsx)(n.br,{}),"\n","The event-driven architecture makes adding new capabilities remarkably simple. Deploy a new agent, and it instantly publishes its capabilities to the mesh. Other components discover it automatically\u2014no manual configuration, no downtime, no integration headaches."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Modular by Design:"}),(0,i.jsx)(n.br,{}),"\n","Every component\u2014agents, gateways, tools\u2014is a self-contained module you can reuse, replace, or enhance independently."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Configuration-Driven:"}),(0,i.jsx)(n.br,{}),"\n","YAML-based configuration gives you precise control over agent behavior, service integrations, and security settings without code changes."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Security-First Approach:"}),(0,i.jsx)(n.br,{}),"\n","The built-in authorization framework provides fine-grained access control over agents and tools based on user roles and scopes."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Resilient by Nature:"}),(0,i.jsx)(n.br,{}),"\n","Event-driven design creates responsive, self-healing interactions that recover gracefully from disruptions."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"real-world-applications",children:"Real-World Applications"}),"\n",(0,i.jsx)(n.p,{children:"Organizations are using the Solace Agent Mesh in diverse scenarios:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Intelligent Enterprise Automation:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Customer service systems that route inquiries to specialized agents based on intent and context."}),"\n",(0,i.jsx)(n.li,{children:"Data processing pipelines where specialized agents transform, analyze, and enrich information from multiple sources."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"AI Task Specialization:"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Image analysis workflows where one agent processes visual data and delegates text generation to a language specialist."}),"\n",(0,i.jsx)(n.li,{children:"Document processing systems that extract text, summarize content, and translate results\u2014each step handled by the perfect specialist."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Human-AI Collaboration:"}),(0,i.jsx)(n.br,{}),"\n","Agents that perform complex tasks while keeping humans in the loop for approvals, clarifications, or expert guidance via web or chat interfaces."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Multi-Agent Research:"}),(0,i.jsx)(n.br,{}),"\n","A production-ready platform for exploring agent collaboration patterns, delegation strategies, and distributed AI problem-solving."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Data-Driven Intelligence:"}),(0,i.jsx)(n.br,{}),"\n","Agents that query databases, transform results, and generate visualizations based on natural language requests or system events."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"evolution-through-usage",children:"Evolution Through Usage"}),"\n",(0,i.jsx)(n.p,{children:"Solace Agent Mesh grows with your needs. For example, at Solace we started with basic agents and have continuously expanded the system's capabilities:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Added specialized agents for JIRA and Confluence integration"}),"\n",(0,i.jsx)(n.li,{children:"Implemented multiple interface options including browser-based user interfaces and REST API gateways"}),"\n",(0,i.jsx)(n.li,{children:"Integrated with various AI models and data sources"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"for-developers",children:"For Developers"}),"\n",(0,i.jsx)(n.p,{children:"Solace Agent Mesh is an agentic framework that provides several key technical advantages:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Complete Observability"}),": Because all communication flows through the event broker, you can monitor and debug the entire system in real-time"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Flexible Integration"}),": Built-in support for common enterprise systems and AI frameworks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Plugin Architecture"}),": Easily extend the system with custom agents and gateways"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Developer Tools"}),": Comprehensive CLI and debugging utilities"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"getting-started",children:"Getting Started"}),"\n",(0,i.jsx)(n.p,{children:"Whether you're building a proof-of-concept or planning a production deployment, Solace Agent Mesh provides the foundation you need. For more information, see:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/installation",children:"Installation"}),": For installing and setting up Solace Agent Mesh."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/quick-start",children:"Quick Start"}),": For creating a project, build, and run Solace Agent Mesh."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"/solace-agent-mesh/docs/documentation/getting-started/component-overview",children:"Components Overview"}),": Understand the parts of Solace Agent Mesh."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},1351:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/Solace_AI_Framework_With_Broker-85f0a306a9bcdd20b390b7a949f6d862.png"},8453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(6540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunksolace_agenitc_mesh_docs=self.webpackChunksolace_agenitc_mesh_docs||[]).push([[6634],{1893:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"documentation/getting-started/component-overview","title":"Component Overview","description":"The Solace Agent Mesh (SAM) is built on event-driven architecture principles using the A2A (Agent-to-Agent) protocol, with all components communicating through a standardized protocol over Solace PubSub+. This architectural choice enables loose coupling between components, making the system highly flexible and scalable.","source":"@site/docs/documentation/getting-started/component-overview.md","sourceDirName":"documentation/getting-started","slug":"/documentation/getting-started/component-overview","permalink":"/solace-agent-mesh/docs/documentation/getting-started/component-overview","draft":false,"unlisted":false,"editUrl":"https://github.com/SolaceLabs/solace-agent-mesh/edit/main/docs/docs/documentation/getting-started/component-overview.md","tags":[],"version":"current","sidebarPosition":40,"frontMatter":{"title":"Component Overview","sidebar_position":40},"sidebar":"docSidebar","previous":{"title":"Quick Start","permalink":"/solace-agent-mesh/docs/documentation/getting-started/quick-start"},"next":{"title":"Architecture","permalink":"/solace-agent-mesh/docs/documentation/concepts/architecture"}}');var s=n(4848),i=n(8453);const r={title:"Component Overview",sidebar_position:40},a="Component Overview",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"component-overview",children:"Component Overview"})}),"\n",(0,s.jsx)(t.p,{children:"The Solace Agent Mesh (SAM) is built on event-driven architecture principles using the A2A (Agent-to-Agent) protocol, with all components communicating through a standardized protocol over Solace PubSub+. This architectural choice enables loose coupling between components, making the system highly flexible and scalable."}),"\n",(0,s.jsx)(t.p,{children:'SAM integrates the Google Agent Development Kit (ADK) with a Solace event mesh to provide a "Universal A2A Agent Host" that enables distributed AI agent communication. Each component is designed to perform specific roles while working together seamlessly through the A2A protocol.'}),"\n",(0,s.jsx)(t.p,{children:"The key components that make up SAM are:"}),"\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:"PubSub+ Event Broker or Event Mesh"}),": The central nervous system of the framework, facilitating A2A protocol communication between all components. ",(0,s.jsx)(t.a,{href:"https://solace.com/products/event-broker/",children:"more \ud83d\udd17"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"A2A Protocol & Agent Registry"}),": The standardized communication protocol that enables agent discovery, task delegation, and peer-to-peer communication."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Orchestrator"}),": A specialized agent responsible for breaking down requests into tasks and managing the overall workflow. ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/orchestrator",children:"more \ud83d\udd17"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Gateways"}),": The entry and exit points for the system, providing various interfaces (REST, HTTP SSE, webhooks, event mesh) that translate external requests into A2A protocol messages. ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/gateways",children:"more \ud83d\udd17"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Agents"}),": ADK-powered processing units that communicate through the A2A protocol, each bringing specialized capabilities and tools. ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/concepts/agents",children:"more \ud83d\udd17"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"ADK Runtime"}),": The Google Agent Development Kit provides the core intelligence layer with tool execution, session management, and artifact handling capabilities."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Built-in Tools"}),": Comprehensive tool ecosystem including artifact management, data analysis, web tools, and peer agent delegation capabilities."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Real-time Monitoring and Debugging Component"}),": Enables real-time monitoring of system activities and provides interactive debugging capabilities for administrators. ",(0,s.jsx)(t.a,{href:"/solace-agent-mesh/docs/documentation/deployment/observability",children:"more \ud83d\udd17"})]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(6540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]);