solace-agent-mesh 1.4.0__py3-none-any.whl → 1.4.1__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (67) hide show
  1. solace_agent_mesh/assets/docs/404.html +3 -3
  2. solace_agent_mesh/assets/docs/assets/js/ae4415af.16cc58d3.js +1 -0
  3. solace_agent_mesh/assets/docs/assets/js/{main.1de3da6a.js → main.9bc1a102.js} +2 -2
  4. solace_agent_mesh/assets/docs/assets/js/{runtime~main.3188e049.js → runtime~main.f2b4ea70.js} +1 -1
  5. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
  6. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +3 -3
  7. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
  8. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
  9. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
  10. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
  11. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +20 -5
  12. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
  13. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
  14. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
  15. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
  16. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
  17. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
  18. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
  19. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
  20. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
  21. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  22. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
  23. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
  24. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
  25. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
  26. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +3 -3
  27. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
  28. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
  29. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
  32. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
  33. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
  39. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
  40. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
  41. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
  42. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
  43. solace_agent_mesh/assets/docs/lunr-index-1758036158289.json +1 -0
  44. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  45. solace_agent_mesh/assets/docs/search-doc-1758036158289.json +1 -0
  46. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  47. solace_agent_mesh/cli/__init__.py +1 -1
  48. solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +2 -0
  49. solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +10 -245
  50. solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +283 -0
  51. solace_agent_mesh/client/webui/frontend/static/assets/{main-Dq4AJNvn.js → main-B6BpuH9K.js} +2 -2
  52. solace_agent_mesh/client/webui/frontend/static/index.html +1 -1
  53. solace_agent_mesh/common/services/identity_service.py +2 -1
  54. solace_agent_mesh/common/services/providers/local_file_identity_service.py +1 -1
  55. solace_agent_mesh/common/utils/pydantic_utils.py +4 -0
  56. solace_agent_mesh/gateway/base/app.py +12 -1
  57. solace_agent_mesh/gateway/http_sse/main.py +337 -375
  58. solace_agent_mesh/templates/webui.yaml +1 -1
  59. {solace_agent_mesh-1.4.0.dist-info → solace_agent_mesh-1.4.1.dist-info}/METADATA +7 -1
  60. {solace_agent_mesh-1.4.0.dist-info → solace_agent_mesh-1.4.1.dist-info}/RECORD +64 -63
  61. solace_agent_mesh/assets/docs/assets/js/ae4415af.24cdc514.js +0 -1
  62. solace_agent_mesh/assets/docs/lunr-index-1757991496554.json +0 -1
  63. solace_agent_mesh/assets/docs/search-doc-1757991496554.json +0 -1
  64. /solace_agent_mesh/assets/docs/assets/js/{main.1de3da6a.js.LICENSE.txt → main.9bc1a102.js.LICENSE.txt} +0 -0
  65. {solace_agent_mesh-1.4.0.dist-info → solace_agent_mesh-1.4.1.dist-info}/WHEEL +0 -0
  66. {solace_agent_mesh-1.4.0.dist-info → solace_agent_mesh-1.4.1.dist-info}/entry_points.txt +0 -0
  67. {solace_agent_mesh-1.4.0.dist-info → solace_agent_mesh-1.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -1 +1 @@
1
- {"searchDocs":[{"title":"Gateways","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/gateways","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#key-functions","content":" Entry Points: Gateways act as the entry points from the outside world and translate external requests into A2A protocol messages and route them through the Solace event mesh to appropriate agents. Authentication & Authorization: Common authentication and user enrichment flow across all gateway types, with pluggable identity providers. Configurable System Purpose: Each gateway has a configurable system purpose that sets the context for all stimuli entering Solace Agent Mesh through that gateway. This design allows for tailored processing based on the specific use case or domain. Customizable Output Formatting: Gateways have a configurable output description that controls how stimuli responses are formatted when sent back to the outside world. This configurable output description ensures that the output meets the requirements of the receiving system or user interface. Multiple Interface Types: Gateways can have different interfaces to accommodate various communication protocols and systems. Some examples include REST APIs, event meshes, Slack integrations, browser-based interfaces, and so on. ","version":"Next","tagName":"h2"},{"title":"How Gateways Work​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#how-gateways-work","content":" The following diagram illustrates the complete flow of information through a gateway in Solace Agent Mesh: ","version":"Next","tagName":"h2"},{"title":"Available Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#available-gateways","content":" Solace Agent Mesh comes with several built-in gateway types: ","version":"Next","tagName":"h2"},{"title":"Core Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#core-gateways","content":" HTTP SSE Gateway Real-time web interface with streaming responsesServer-sent events for live updatesAgent discovery APIFile upload and download handling REST Gateway Task submission with immediate task ID returnPolling-based result retrievalAuthentication integration Webhook Gateway Handles incoming webhook requestsTransforms webhook payloads to A2A messages ","version":"Next","tagName":"h3"},{"title":"Plugin Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#plugin-gateways","content":" Additional gateway types are available through the plugin ecosystem: Event Mesh Gateway: External event mesh connectivity with message transformationSlack Gateway: Slack bot integration for team collaborationCustom Gateways: Create your own gateway implementations For more information about plugins and how to configure them, see Plugins. One of the official core plugin gateway interfaces is the Solace Event Mesh Gateway, which enables communication with the PubSub+ event broker directly as an input interface. note Each gateway type has its own configuration options and specific features. See the individual gateway documentation pages for detailed information on setup and usage. ","version":"Next","tagName":"h3"},{"title":"Create a Gateway​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#create-a-gateway","content":" To create a gateway, you can either use one of the pre-existing plugins or create yours from scratch. ","version":"Next","tagName":"h2"},{"title":"Gateway from Scratch​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#gateway-from-scratch","content":" To create a gateway from scratch, you need to use the CLI add gateway command without any interfaces. This command creates a python gateway template file which you can then customize to your needs. sam add gateway my-interface To learn more about creating your own gateway, see Create Custom Gateways. Share and Reuse If you would like to share your custom gateway with the community or re-use it within other projects, you can create a plugin for it. For more information, see Create Plugins. ","version":"Next","tagName":"h3"},{"title":"Agents","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/agents","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#key-functions","content":" ADK Integration: Agents are built using the Google Agent Development Kit, providing advanced AI capabilities including tool usage, memory management, and artifact handling. AI-Enabled: Agents come packaged with access to large language models (LLMs) and can utilize various tools. Dynamic Discovery: New agents can self-register/deregister and be discovered dynamically through broadcast messages without requiring changes to the running system. Tool Ecosystem: Agents have access to built-in tools for artifact management, data analysis, web scraping, and peer-to-peer delegation. Session Management: Agents support conversation continuity through ADK's session management capabilities. Independence: Agents are modularized and can be updated or replaced independently of other components. ","version":"Next","tagName":"h2"},{"title":"Agent Design​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-design","content":" Agents in Solace Agent Mesh are built around the Solace AI Connector (SAC) component with ADK. Agent Mesh agents are complete self-contained units that can carry out specific tasks or provide domain-specific knowledge or capabilities. Each agent is defined by a YAML configuration file. Each agent integrates with: ADK Runtime: For AI model access, tool execution, and session managementA2A Protocol: For standardized agent-to-agent communicationTool Registry: Access to built-in and custom toolsArtifact Service: For file handling and management For example, an agent configured with SQL database tools can execute queries, perform data analysis, and generate visualizations through the integrated tool ecosystem, all while maintaining conversation context through its session management. ","version":"Next","tagName":"h2"},{"title":"The Agent Lifecycle​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#the-agent-lifecycle","content":" Agents in Solace Agent Mesh follow the A2A protocol lifecycle and interact with the agent registry: Discovery: Agents start broadcasting discovery messages on startup to announce their availability and capabilities to the agent mesh. Active: The agent listens for A2A protocol messages on its designated topics and processes incoming tasks through the ADK runtime. Execution: The agent works on a task. They can also delegate tasks to other agents through the peer-to-peer A2A communication protocol. Cleanup: When shutting down, agents perform session cleanup and deregister from the agent mesh. ","version":"Next","tagName":"h3"},{"title":"Potential Agent Examples​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#potential-agent-examples","content":" RAG (Retrieval Augmented Generation) Agent: An agent that can retrieve information based on a natural language query using an embedding model and vector database, and then generate a response using a language model. External API Bridge: An agent that acts as a bridge to external APIs, retrieving information from third-party services such as weather APIs or product information databases. Internal System Lookup: An agent that performs lookups in internal systems, such as a ticket management system or a customer relationship management (CRM) database. Natural Language Processing Agent: An agent that can perform tasks like sentiment analysis, named entity recognition, or language translation. ","version":"Next","tagName":"h3"},{"title":"Tool Ecosystem​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#tool-ecosystem","content":" Agents perform tasks by using tools. A tool is a specific capability, like querying a database, calling an external API, or generating an image. The Solace Agent Mesh framework provides a flexible and powerful tool ecosystem, allowing you to equip your agents with the right capabilities for any job. There are three primary ways to add tools to an agent: ","version":"Next","tagName":"h2"},{"title":"1. Built-in Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#1-built-in-tools","content":" Solace Agent Mesh includes a rich library of pre-packaged tools for common tasks like data analysis, file management, and web requests. These are the easiest to use and can be enabled with just a few lines of configuration. Use Case: For standard, out-of-the-box functionality.Learn More: See the Built-in Tools Reference for a complete list and configuration details. ","version":"Next","tagName":"h3"},{"title":"2. Custom Python Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#2-custom-python-tools","content":" For unique business logic or specialized tasks, you can create your own tools using Python. This is the most powerful and flexible method, supporting everything from simple functions to advanced, class-based tool factories that can generate multiple tools programmatically. Use Case: For implementing custom logic, integrating with proprietary systems, or creating dynamically configured tools.Learn More: See the Creating Python Tools guide for a complete walkthrough. ","version":"Next","tagName":"h3"},{"title":"3. MCP (Model Context Protocol) Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#3-mcp-model-context-protocol-tools","content":" For integrating with external, standalone tool servers that conform to the Model Context Protocol, you can configure an MCP tool. This allows agents to communicate with tools running in separate processes or on different machines. Use Case: For integrating with existing MCP-compliant tool servers or language-agnostic tool development.Learn More: See the MCP Integration Tutorial. ","version":"Next","tagName":"h3"},{"title":"Agent Card​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-card","content":" The Agent Card is a public-facing profile that describes an agent's identity, capabilities, and how to interact with it. It functions like a digital business card, allowing other agents and clients within Solace Agent Mesh to discover what an agent can do. This information is published by the agent and is crucial for dynamic discovery and interoperability. The Agent Card is defined in the agent's YAML configuration file under the agent_card section. ","version":"Next","tagName":"h2"},{"title":"Key Fields​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#key-fields","content":" You can configure the following fields in the agent card: description: A summary of the agent's purpose and capabilities.defaultInputModes: A list of supported MIME types for input (e.g., ["text/plain", "application/json", "file"]).defaultOutputModes: A list of supported MIME types for output.skills: A list of specific skills the agent possesses. Each skill corresponds to a capability, often backed by a tool. ","version":"Next","tagName":"h3"},{"title":"Skills​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#skills","content":" A skill describes a specific function the agent can perform. It provides granular detail about the agent's abilities. Key attributes of a skill include: id: A unique identifier for the skill, which should match the tool_name if the skill is directly mapped to a tool.name: A human-readable name for the skill.description: A clear explanation of what the skill does, which helps the LLM (and other agents) decide when to use it. ","version":"Next","tagName":"h3"},{"title":"Example Configuration​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#example-configuration","content":" Here is an example of an agent_card configuration for a "Mermaid Diagram Generator" agent: # ... inside app_config ... agent_card: description: "An agent that generates PNG images from Mermaid diagram syntax." defaultInputModes: ["text"] # Expects Mermaid syntax as text defaultOutputModes: ["text", "file"] # Confirms with text, outputs file artifact skills: - id: "mermaid_diagram_generator" name: "Mermaid Diagram Generator" description: "Generates a PNG image from Mermaid diagram syntax. Input: mermaid_syntax (string), output_filename (string, optional)." This card clearly communicates that the agent can take text (the Mermaid syntax) and produce a file (the PNG image), and it details the specific "mermaid_diagram_generator" skill it offers. For more details on creating agents and configuring their cards, see Creating Custom Agents. ","version":"Next","tagName":"h3"},{"title":"User-Defined Agents​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#user-defined-agents","content":" Using Solace Agent Mesh and the Solace Agent Mesh CLI, you can create your own agents. Agents are configured through YAML files that specify: Agent name and instructionsLLM model configurationAvailable tools and capabilitiesArtifact and session management settingsDiscovery settings The following Solace Agent Mesh CLI command creates an agent configuration: sam add agent my-agent [--gui] For more information, see Creating Custom Agents. ","version":"Next","tagName":"h2"},{"title":"Agent Plugins​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-plugins","content":" You can also use agents built by the community or Solace directly in your app with little to no configuration. For more information, see Use a Plugin. ","version":"Next","tagName":"h2"},{"title":"Orchestrator Agent","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/orchestrator","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Orchestrator Agent","url":"/solace-agent-mesh/docs/documentation/concepts/orchestrator#key-functions","content":" The orchestrator agent provides the following key functions: Request Analysis and Action Planning: Receives high-level goals or requestsAnalyzes them in the context of available actions registered by agents in the systemUses state-of-the-art generative AI techniques to plan a sequence of actions to fulfill the request Task Creation and Distribution: Creates tasks based on the action planDistributes tasks to appropriate agentsEnables efficient parallel processing and optimal resource utilization Workflow Management: Tracks outstanding tasksAggregates responses from various agentsEnsures all parts of a complex request are processed and combined coherently Response Formatting: Formats aggregated responses suitable for the gatewayEnsures the final output meets the requirements of the specific use case or interface ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh Architecture","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/architecture","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#overview","content":" 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. It integrates three primary technologies: Solace PubSub+ Event Broker: Provides the messaging fabric for all asynchronous communication, utilizing topic-based routing for the Agent-to-Agent (A2A) protocol.Solace AI Connector (SAC): Serves as the runtime environment for hosting and managing the lifecycle of all system components (Agents and Gateways).Google Agent Development Kit (ADK): Provides the core logic for individual agents, including LLM interaction, tool execution, and state management. ","version":"Next","tagName":"h2"},{"title":"Architectural Principles​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#architectural-principles","content":" The design of Solace Agent Mesh is founded on several key architectural principles: 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.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.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. ","version":"Next","tagName":"h2"},{"title":"System Components​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#system-components","content":" The architecture comprises several distinct types of components that interact through the Solace PubSub+ broker. ","version":"Next","tagName":"h2"},{"title":"Solace PubSub+ Event Broker​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#solace-pubsub-event-broker","content":" 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. ","version":"Next","tagName":"h3"},{"title":"Gateways​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#gateways","content":" Gateways are SAC applications that act as bridges between external systems and the agent mesh. Their primary responsibilities are: Protocol Translation: Convert external protocols (for example, HTTP, WebSockets, Slack RTM) into the standardized A2A protocol, and vice-versa.Authentication and Authorization: Authenticate incoming requests and, using a pluggable AuthorizationService, retrieve the user's permission scopes.Session Management: Manage external user sessions and map them to A2A task lifecycles.Response Handling: Receive asynchronous A2A responses and status updates from agents and deliver them to the external client. The Gateway Development Kit (GDK) provides BaseGatewayApp and 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. ","version":"Next","tagName":"h3"},{"title":"Agent Hosts​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-hosts","content":" An Agent Host is a SAC application (SamAgentApp) that hosts a single ADK-based agent. Its key architectural functions include: Hosting the ADK Runtime: It manages the lifecycle of the ADK Runner and LlmAgent.A2A Protocol Handling: The internal SamAgentComponent translates incoming A2A requests into ADK Task objects and converts ADK Event objects into outgoing A2A TaskStatusUpdateEvent, TaskArtifactUpdateEvent, or final response messages.Scope Enforcement: It extracts permission scopes from incoming message properties and filters the agent's available tools accordingly.Service Initialization: It initializes ADK services like the ArtifactService and MemoryService based on its configuration. ","version":"Next","tagName":"h3"},{"title":"Agents​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agents","content":" An agent is the logical entity within an Agent Host that performs tasks. It is defined by its configuration, which includes: Instructions: The base prompt that defines its persona, capabilities, and constraints.LLM Configuration: The specific large language model to use.Toolset: A collection of available tools, which can be built-in, custom Python functions, or MCP Toolsets. ","version":"Next","tagName":"h3"},{"title":"Key Architectural Flows​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#key-architectural-flows","content":" ","version":"Next","tagName":"h2"},{"title":"User Task Processing Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#user-task-processing-flow","content":" An external client sends a request to a Gateway.The Gateway authenticates the request, retrieves the user's permission scopes via its AuthorizationService, and translates the request into an A2A task message. It includes the scopes in the Solace message's user properties.The Gateway publishes the message to the target agent's request topic on the Solace Broker.The corresponding Agent Host receives the message. The SamAgentComponent extracts the scopes and initiates an ADK task.The ADK LlmAgent processes the task. Before invoking the LLM, a before_model_callback filters the available tools based on the user's scopes.As the agent executes, the SamAgentComponent translates ADK events into A2A status and artifact update messages, publishing them to the originating Gateway's status topic.The Gateway receives these streaming updates, performs any necessary late-stage processing (like resolving artifact_content embeds), and forwards them to the client.Upon completion, the Agent Host sends a final A2A response message to the Gateway, which delivers it to the client. ","version":"Next","tagName":"h3"},{"title":"Agent-to-Agent Delegation Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-to-agent-delegation-flow","content":" Agent A, while processing a task, determines a sub-task should be delegated to Agent B.Agent A uses its PeerAgentTool to construct a new A2A task request for Agent B. It propagates the original user's permission scopes to maintain the security context.The request is published to Agent B's request topic.Agent B's Host receives and processes the sub-task, enforcing the propagated scopes on its own toolset.Agent B sends status updates and a final response to topics designated by Agent A.Agent A receives the results and incorporates them into its ongoing task. ","version":"Next","tagName":"h3"},{"title":"Agent Discovery Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-discovery-flow","content":" On startup and periodically, each Agent Host publishes an AgentCard (a JSON document describing its agent's capabilities) to a well-known discovery topic (for example, {namespace}/a2a/v1/discovery/agentcards).Gateways and other Agent Hosts subscribe to this topic.Upon receiving an AgentCard, components update their local AgentRegistry, making them aware of available agents for user selection (at the Gateway) or peer delegation (at the Agent). ","version":"Next","tagName":"h3"},{"title":"A2A Protocol and Topic Structure​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#a2a-protocol-and-topic-structure","content":" 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. Purpose\tTopic PatternAgent Discovery\t{namespace}/a2a/v1/discovery/agentcards Task Requests\t{namespace}/a2a/v1/agent/request/{target_agent_name} Status Updates\t{namespace}/a2a/v1/gateway/status/{gateway_id}/{task_id} Final Responses\t{namespace}/a2a/v1/gateway/response/{gateway_id}/{task_id} Peer Delegation Status\t{namespace}/a2a/v1/agent/status/{delegating_agent_name}/{sub_task_id} Peer Delegation Response\t{namespace}/a2a/v1/agent/response/{delegating_agent_name}/{sub_task_id} This topic structure allows for precise, point-to-point routing in a decoupled, asynchronous environment. ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh CLI","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/cli","content":"","keywords":"","version":"Next"},{"title":"Installation​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#installation","content":" The Solace Agent Mesh CLI is installed as part of the package for Solace Agent Mesh. For more information, see Installation. CLI Tips The Solace Agent Mesh CLI comes with a short alias of sam which can be used in place of solace-agent-mesh.You can determine the version of the Solace Agent Mesh CLI by running solace-agent-mesh --version.You can get help on any command by running solace-agent-mesh [COMMAND] --help. ","version":"Next","tagName":"h2"},{"title":"Commands​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#commands","content":" ","version":"Next","tagName":"h2"},{"title":"init - Initialize a Solace Agent Mesh Application​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#init---initialize-a-solace-agent-mesh-application","content":" sam init [OPTIONS] When this command is run with no options, it runs in interactive mode. It first prompts you to choose between configuring your project in the terminal or through a browser-based interface. If you choose to use the browser, the Solace Agent Mesh CLI starts a local web configuration portal, available at http://127.0.0.1:5002 You can skip some questions by providing the appropriate options for that step during the Solace Agent Mesh CLI-based setup. Optionally, you can skip all the questions by providing the --skip option. This option uses the provided or default values for all the questions. automated workflows Use the --skip option and provide the necessary options to run the command in non-interactive mode, useful for automated workflows. Options:​ --gui – Launch the browser-based initialization interface directly, skipping the prompt. (Recommended way to configure Solace Agent Mesh applications)--skip – Runs in non-interactive mode, using default values where available.--llm-service-endpoint TEXT – LLM Service Endpoint URL.--llm-service-api-key TEXT – LLM Service API Key.--llm-service-planning-model-name TEXT – LLM Planning Model Name.--llm-service-general-model-name TEXT – LLM General Model Name.--namespace TEXT – Namespace for the project.--broker-type TEXT – Broker type: 1/solace (existing), 2/container (new local), 3/dev (dev mode). Options: 1, 2, 3, solace, container, dev_mode, dev_broker, dev.--broker-url TEXT – Solace broker URL endpoint.--broker-vpn TEXT – Solace broker VPN name.--broker-username TEXT – Solace broker username.--broker-password TEXT – Solace broker password.--container-engine TEXT – Container engine for local broker. Options: podman, docker.--dev-mode – Shortcut to select dev mode for broker (equivalent to --broker-type 3/dev).--agent-name TEXT – Agent name for the main orchestrator.--supports-streaming – Enable streaming support for the agent.--session-service-type TEXT – Session service type. Options: memory, vertex_rag.--session-service-behavior TEXT – Session service behavior. Options: PERSISTENT, RUN_BASED.--artifact-service-type TEXT – Artifact service type. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Artifact service base path (for filesystem type).--artifact-service-scope TEXT – Artifact service scope. Options: namespace, app, custom.--artifact-handling-mode TEXT – Artifact handling mode. Options: ignore, embed, reference.--enable-embed-resolution – Enable embed resolution.--enable-artifact-content-instruction – Enable artifact content instruction.--enable-builtin-artifact-tools – Enable built-in artifact tools.--enable-builtin-data-tools – Enable built-in data tools.--agent-card-description TEXT – Agent card description.--agent-card-default-input-modes TEXT – Agent card default input modes (comma-separated).--agent-card-default-output-modes TEXT – Agent card default output modes (comma-separated).--agent-discovery-enabled – Enable agent discovery.--agent-card-publishing-interval INTEGER – Agent card publishing interval (seconds).--inter-agent-communication-allow-list TEXT – Inter-agent communication allow list (comma-separated, use * for all).--inter-agent-communication-deny-list TEXT – Inter-agent communication deny list (comma-separated).--inter-agent-communication-timeout INTEGER – Inter-agent communication timeout (seconds).--add-webui-gateway – Add a default Web UI gateway configuration.--webui-session-secret-key TEXT – Session secret key for Web UI.--webui-fastapi-host TEXT – Host for Web UI FastAPI server.--webui-fastapi-port INTEGER – Port for Web UI FastAPI server.--webui-enable-embed-resolution – Enable embed resolution for Web UI.--webui-frontend-welcome-message TEXT – Frontend welcome message for Web UI.--webui-frontend-bot-name TEXT – Frontend bot name for Web UI.--webui-frontend-collect-feedback – Enable feedback collection in Web UI.-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"add - Create a New Component​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#add---create-a-new-component","content":" To add a new component, such as an agent or gateway, use the add command with the appropriate options. sam add [agent|gateway] [OPTIONS] NAME Add agent​ Use agent to add an agent component. sam add agent [OPTIONS] [NAME] Options:​ --gui – Launch the browser-based configuration interface for agent setup. (Recommended way to configure agents)--skip – Skip interactive prompts and use defaults (Solace Agent Mesh CLI mode only).--namespace TEXT – namespace (for example, myorg/dev).--supports-streaming BOOLEAN – Enable streaming support.--model-type TEXT – Model type for the agent. Options: planning, general, image_gen, report_gen, multimodal, gemini_pro.--instruction TEXT – Custom instruction for the agent.--session-service-type TEXT – Session service type. Options: memory, vertex_rag.--session-service-behavior TEXT – Session service behavior. Options: PERSISTENT, RUN_BASED.--artifact-service-type TEXT – Artifact service type. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Base path for filesystem artifact service.--artifact-service-scope TEXT – Artifact service scope. Options: namespace, app, custom.--artifact-handling-mode TEXT – Artifact handling mode. Options: ignore, embed, reference.--enable-embed-resolution BOOLEAN – Enable embed resolution.--enable-artifact-content-instruction BOOLEAN – Enable artifact content instruction.--enable-builtin-artifact-tools BOOLEAN – Enable built-in artifact tools.--enable-builtin-data-tools BOOLEAN – Enable built-in data tools.--agent-card-description TEXT – Description for the agent card.--agent-card-default-input-modes-str TEXT – Comma-separated default input modes for agent card.--agent-card-default-output-modes-str TEXT – Comma-separated default output modes for agent card.--agent-card-publishing-interval INTEGER – Agent card publishing interval in seconds.--agent-discovery-enabled BOOLEAN – Enable agent discovery.--inter-agent-communication-allow-list-str TEXT – Comma-separated allow list for inter-agent communication.--inter-agent-communication-deny-list-str TEXT – Comma-separated deny list for inter-agent communication.--inter-agent-communication-timeout INTEGER – Timeout in seconds for inter-agent communication.-h, --help – Displays the help message and exits. For more information, see Agents. Add gateway​ Use gateway to add a gateway component. sam add gateway [OPTIONS] [NAME] Options:​ --gui – Launch the browser-based configuration interface for gateway setup. (Recommended way to configure gateways)--skip – Skip interactive prompts and use defaults (Solace Agent Mesh CLI mode only).--namespace TEXT – namespace for the gateway (for example, myorg/dev).--gateway-id TEXT – Custom Gateway ID for the gateway.--artifact-service-type TEXT – Artifact service type for the gateway. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Base path for filesystem artifact service (if type is 'filesystem').--artifact-service-scope TEXT – Artifact service scope (if not using default shared artifact service). Options: namespace, app, custom.--system-purpose TEXT – System purpose for the gateway (can be multi-line).--response-format TEXT – Response format for the gateway (can be multi-line).-h, --help – Displays the help message and exits. For more information, see Gateways. ","version":"Next","tagName":"h3"},{"title":"run - Run the Solace Agent Mesh Application​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#run---run-the-solace-agent-mesh-application","content":" To run the Solace Agent Mesh application, use the run command. sam run [OPTIONS] [FILES]... Environment variables The sam run command automatically loads environment variables from your configuration file (typically a .env file at the project root) by default. If you want to use your system's environment variables instead, you can add the -u or --system-env option. While running the run command, you can also skip specific files by providing the -s or --skip option. You can provide paths to specific YAML configuration files or directories. When you provide a directory, run will recursively search for and load all .yaml and .yml files within that directory. This allows you to organize your configurations and run them together easily. For example, to run specific files: solace-agent-mesh run configs/agent1.yaml configs/gateway.yaml To run all YAML files within the configs directory: solace-agent-mesh run configs/ Options:​ -u, --system-env – Use system environment variables only; do not load .env file.-s, --skip TEXT – File name(s) to exclude from the run (for example, -s my_agent.yaml).-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"docs - Serve the documentation locally​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#docs---serve-the-documentation-locally","content":" Serves the project documentation on a local web server. sam docs [OPTIONS] This command starts a web server to host the documentation, which is useful for offline viewing or development. By default, it serves the documentation at http://localhost:8585/solace-agent-mesh/ and automatically opens your web browser to the getting started page. If a requested page is not found, it will redirect to the main documentation page. Options:​ -p, --port INTEGER – Port to run the web server on. (default: 8585)-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"plugin - Manage Plugins​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#plugin---manage-plugins","content":" The plugin command allows you to manage plugins for Solace Agent Mesh application. sam plugin [COMMAND] [OPTIONS] For more information, see Plugins. create - Create a Plugin​ Initializes and creates a new plugin with customizable options. sam plugin create [OPTIONS] NAME When this command is run with no options, it runs in interactive mode and prompts you to provide the necessary information to set up the plugin for Solace Agent Mesh You can skip some questions by providing the appropriate options for that step. Optionally, you can skip all the questions by providing the --skip option. This option uses the provided or default values for all the questions, which is useful for automated workflows. Options:​ --type TEXT – Plugin type. Options: agent, gateway, custom.--author-name TEXT – Author's name.--author-email TEXT – Author's email.--description TEXT – Plugin description.--version TEXT – Initial plugin version.--skip – Skip interactive prompts and use defaults or provided flags.-h, --help – Displays the help message and exits. build - Build the Plugin​ Compiles and prepares the plugin for use. sam plugin build [PLUGIN_PATH] Builds the Solace Agent Mesh plugin in the specified directory (defaults to current directory). Options:​ PLUGIN_PATH – Path to the plugin directory (defaults to current directory).-h, --help – Displays the help message and exits. add - Add an Existing Plugin​ Creates a new component instance from a specified plugin source. sam plugin add [OPTIONS] COMPONENT_NAME Options:​ --plugin TEXT – Plugin source: installed module name, local path, or Git URL. (Required)--install-command TEXT – Command to use to install a python package. Must follow the format command {package} args, by default pip3 install {package}. Can also be set through the environment variable SAM_PLUGIN_INSTALL_COMMAND.-h, --help – Displays the help message and exits. catalog - Launch Plugin Catalog​ Launch the Solace Agent Mesh Plugin Catalog web interface. sam plugin catalog [OPTIONS] Options:​ --port INTEGER – Port to run the plugin catalog web server on. (default: 5003)--install-command TEXT – Command to use to install a python package. Must follow the format command {package} args.-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"Debugging","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/debugging","content":"","keywords":"","version":"Next"},{"title":"Isolate Components​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#isolate-components","content":" Running only the necessary components in isolation can help pinpoint issues. The run Solace Agent Mesh CLI command allows you to specify which files to run. For example: sam run configs/agents/my_tool_1.yaml configs/agents/my_tool_2.yaml This command runs only the agents defined in my_tool_1.yaml and my_tool_2.yaml, reducing noise from unrelated components. ","version":"Next","tagName":"h2"},{"title":"Examine STIM Files​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#examine-stim-files","content":" STIM files provide detailed traces of stimulus life cycles. If you have access to the storage location, you can inspect them to analyze message flows. Each .stim file contains all broker events related to a single stimulus, from the initial request to the final response. ","version":"Next","tagName":"h2"},{"title":"Monitor Broker Activity​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#monitor-broker-activity","content":" For insights into message flows and event interactions, see Broker Observability. ","version":"Next","tagName":"h2"},{"title":"Debug Mode​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#debug-mode","content":" Because Solace Agent Mesh is a Python-based framework, you can run it in debug mode using an IDE with breakpoints. ","version":"Next","tagName":"h2"},{"title":"Debugging in VSCode​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#debugging-in-vscode","content":" If you're using VSCode, configure debugging in .vscode/launch.json: { "version": "0.2.0", "configurations": [ { "name": "sam-debug", "type": "debugpy", "request": "launch", "module": "solace_agent_mesh.cli.main", "console": "integratedTerminal", "envFile": "${workspaceFolder}/.env", "args": [ "run", "configs/agents/main_orchestrator.yaml", "configs/gateways/webui.yaml" // Add any other components you want to run here ], "justMyCode": false } ] } To start debugging: Open the RUN AND DEBUG panel on the left sidebar.Select sam-debug from the dropdown.Click the Play to start in debug mode. Set breakpoints in your code to pause execution and inspect variable states. ","version":"Next","tagName":"h3"},{"title":"Invoke the Agent Directly​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#invoke-the-agent-directly","content":" For debugging and testing, you can send direct messages to an agent by directly selecting the agent in the web UI agent dropdown or by using the PubSub+ event broker. This requires specifying the appropriate topic, user properties, and payload. Tools for Sending Messages​ Solace Try Me VSCode ExtensionSolace Try Me (STM) CLI Tool Message Format​ Topic: [NAME_SPACES]a2a/v1/agent/request/<agent_name> User Properties: userId: test-0000 clientId: test-0000 replyTo: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000 a2aUserConfig: {} Payload: { "jsonrpc": "2.0", "id": "000000000", "method": "tasks/sendSubscribe", "params": { "id": "task-0000000", "sessionId": "web-session-00000000", "message": { "role": "user", "parts": [ { "type": "text", "text": "Hello World!" } ] }, "acceptedOutputModes": [ "text" ], "metadata": { "system_purpose": "The system is an AI Chatbot with agentic capabilities. It uses the agents available to provide information, reasoning and general assistance for the users in this system. **Always return useful artifacts and files that you create to the user.** Provide a status update before each tool call. Your external name is Agent Mesh.\\n", "response_format": "Responses should be clear, concise, and professionally toned. Format responses to the user in Markdown using appropriate formatting.\\n" } } } Response Topic: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000 By sending a request and observing the response, you can verify an agent's behavior in isolation, making it easier to identify issues. ","version":"Next","tagName":"h2"},{"title":"System Logs​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#system-logs","content":" System logs provide detailed insights into the system's behavior. The logging behavior is configured in the configs/logging_config.ini file, which controls both console (STDOUT) and file-based logging. By default, the system is configured to: Output logs with a severity of INFO and higher to the console (STDOUT).Write more detailed logs with a severity of DEBUG and higher to a rotating log file named sam.log in the project's root directory. ","version":"Next","tagName":"h2"},{"title":"Configuring Log Rotation​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#configuring-log-rotation","content":" The log file rotation is managed by the rotatingFileHandler in configs/logging_config.ini. You can customize its behavior by modifying the args line: [handler_rotatingFileHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=simpleFormatter args=('sam.log', 'a', 52428800, 10) The args tuple is defined as follows: 'sam.log': The name of the log file.'a': The file mode (append).52428800: The maximum size of the log file in bytes before it is rotated. In this case, it's 50 MB.10: The number of backup log files to keep. For example, to change the log file size to 20 MB and keep 5 backup files, you would modify the line to:args=('sam.log', 'a', 20971520, 5) This level of configuration allows you to manage log verbosity and disk space usage according to your needs. ","version":"Next","tagName":"h3"},{"title":"Plugins","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/plugins","content":"","keywords":"","version":"Next"},{"title":"Plugins​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#plugins","content":" 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. In one sentence Plugins are modular Python packages that extend Solace Agent Mesh's capabilities through agents, gateways, and specialized integrations. Plugins are packaged as Python modules that can be installed using various package managers (pip, uv, poetry, conda). They integrate seamlessly with the A2A protocol and can provide: Agent Plugins: Specialized agents with domain-specific capabilitiesGateway Plugins: New interface types for external system integrationCustom Plugins: Custom integrations such as HR providers. All plugin interactions (create, build, add) are managed through the Solace Agent Mesh CLI. info Run sam plugin --help to see the list of available commands for plugins. ","version":"Next","tagName":"h2"},{"title":"Official Core Plugins​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#official-core-plugins","content":" 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 here 🔗. For more information about how to use the official core plugins, see Use Plugins. ","version":"Next","tagName":"h3"},{"title":"Create a Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#create-a-plugin","content":" To get started, install the Solace Agent Mesh CLI and run the following command: solace-agent-mesh plugin create <plugin-name> Follow the prompts to create a new plugin. A plugin can be one of the following types: Agent Plugin: Contains custom agents that can be used in a Solace Agent Mesh project.Gateway Plugin: Contains custom gateways that can be used in a Solace Agent Mesh project.Custom Plugin: Contains custom integrations such as HR providers or other specialized functionality. Solace Agent Mesh CLI creates a directory with the provided name and the following structure: plugin-name/ ├─ config.yaml ├─ src/ │ ├─ __init__.py │ ├─ [...Other type specific python files] ├─ .gitignore ├─ pyproject.toml ├─ README.md The src directory contains the python source code.The config.yaml file holds the configuration for the plugin, and how to be used in a Solace Agent Mesh application. Once the plugin is created, you can start customizing the config.yaml or the python files. ","version":"Next","tagName":"h2"},{"title":"Build the Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#build-the-plugin","content":" Building the plugin creates a Python wheel package that can be installed using pip or other package managers. Python build package must be installed already since sam plugin build command uses build package, if not, run pip install build. To build the plugin, run the following Solace Agent Mesh CLI command: solace-agent-mesh plugin build The plugin uses the standard pyproject.toml file to build the package. ","version":"Next","tagName":"h3"},{"title":"Share the Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#share-the-plugin","content":" 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 pyproject project. ","version":"Next","tagName":"h3"},{"title":"Use a Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugin","content":" To use a plugin in your project, use the plugin add command, which performs two steps under-the-hood: Locates the plugin or installs the plugin package using a Python package manager (like pip or uv)Creates a component instance based on the plugin solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> where: <COMPONENT_NAME> is the name you choose for the component instance in your project. <PLUGIN_NAME>, you can use: Name of the plugin as published to a package manager like pypi, for example my-pluginName of the plugin that has been already installed into your Python environment.A local path to the plugin directory, for example ./my-pluginA path to a wheel package, for example ./my-plugin/dist/my_plugin-0.1.0-py3-none-any.whlA URL to a git repository, for example git+https://github.com/<USERNAME>/<REPOSITORY> If the plugin is in a subdirectory of the repository, you can specify the subdirectory using the git+https://github.com/<USERNAME>/<REPOSITORY>#subdirectory=<PLUGIN_NAME> syntax. The CLI handles both steps automatically, or you can manage the plugin installation yourself using your preferred Python package manager. tip You can also customize the python package manager command used to install the plugin by setting the SAM_PLUGIN_INSTALL_COMMAND environment variable or passing the --install-command option to the plugin add command. For example, to use uv as the package manager, you can run: export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" or solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> --install-command "uv pip install {package}" This command adds the plugin instance configuration to your configs directory. 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. ","version":"Next","tagName":"h2"},{"title":"Plugin Catalog Dashboard​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#plugin-catalog-dashboard","content":" You can manage available plugins with the plugin catalog command, which launches a user-friendly interface. solace-agent-mesh plugin catalog ","version":"Next","tagName":"h2"},{"title":"Agent or Plugin: Which To Use?​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#agent-or-plugin-which-to-use","content":" In simple terms, plugins of type agent are just packaged agents. However, there are distinct advantages to each approach, and choosing the right one depends on your use case. Here’s a detailed comparison to help you decide. Feature\tStandalone Agent (sam add agent)\tAgent Plugin (sam plugin create)Creation\tA single command creates a configuration file in your project.\tCreates a complete, standard Python project structure. Structure\tConsists of a YAML configuration file and associated Python tool files within a Solace Agent Mesh project.\tA self-contained Python package with pyproject.toml, a src directory, and configuration templates. Packaging\tNot packaged. It exists as a component within a larger Solace Agent Mesh project.\tPackaged into a standard Python wheel (.whl) file using sam plugin build. Distribution\tShared by copying files or sharing the entire project.\tEasily distributed as a wheel file, via a Git repository, or published to a package index like PyPI. Reusability\tPrimarily for use within the project where it was created.\tDesigned for high reusability across different projects, teams, and communities. Installation\tNo installation needed. The agent is configured and run as part of the main project.\tInstalled into the Python environment using sam plugin add, which handles the package installation. Versioning\tVersioned along with the main project.\tCan be versioned independently according to Python packaging standards (e.g., v0.1.0, v0.2.0). Development\tSimple and direct. Edit files and run. Ideal for rapid prototyping.\tInvolves a build/install cycle. Better for structured, long-term development. ","version":"Next","tagName":"h2"},{"title":"When To Use a Standalone Agent​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#when-to-use-a-standalone-agent","content":" Create a standalone agent when: You need to quickly test an idea or build a proof-of-concept.The agent is tightly coupled to a single project and is not intended for reuse.You want the most straightforward path to adding a simple agent without the overhead of a full package structure. ","version":"Next","tagName":"h3"},{"title":"When To Use an Agent Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#when-to-use-an-agent-plugin","content":" Create an agent as a plugin when: You plan to use the same agent in multiple projects.You want to share your agent with other developers, teams, or the open-source community.You are building a robust, production-ready agent that benefits from a formal package structure, dependency management, and versioning.You are building a collection of standardized agents for your organization. ","version":"Next","tagName":"h3"},{"title":"Recommendation​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#recommendation","content":" The choice of how to build your agent depends on your goals and the requirements of your project: Standalone Agents should be viewed as tactical tools for rapid, isolated prototyping. They serve immediate, project-specific needs but do not contribute to a scalable, long-term asset library. Agent Plugins are the foundation for building a robust, governable, and reusable AI ecosystem. This model treats AI capabilities as enterprise assets, promoting standardization, reducing redundant development costs, and accelerating innovation across the organization. For any capability intended for broader use or long-term value, the plugin framework is the mandated path to maximize return on investment and ensure architectural integrity. ","version":"Next","tagName":"h3"},{"title":"Deployment","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/deploy","content":"","keywords":"","version":"Next"},{"title":"Development​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#development","content":" In a development environment, you can use Solace Agent Mesh CLI to run the project as a single application. By default, environment variables are loaded from your configuration file (typically a .env file at the project root): sam run ","version":"Next","tagName":"h2"},{"title":"Production​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#production","content":" For a production environment, use a containerized and reproducible setup. We recommend Docker or Kubernetes. If your host system architecture is not linux/amd64, add the --platform linux/amd64 flag when you run the container. ","version":"Next","tagName":"h2"},{"title":"Docker Deployment​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#docker-deployment","content":" Below is a sample Dockerfile for a Solace Agent Mesh project: FROM solace/solace-agent-mesh:latest WORKDIR /app # Install Python dependencies COPY ./requirements.txt /app/requirements.txt RUN python3.11 -m pip install --no-cache-dir -r /app/requirements.txt # Copy project files COPY . /app CMD ["run", "--system-env"] # To run one specific component, use: # CMD ["run", "--system-env", "configs/agents/main_orchestrator.yaml"] And the following .dockerignore .env *.log dist .git .vscode .DS_Store ","version":"Next","tagName":"h3"},{"title":"Kubernetes Deployment​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#kubernetes-deployment","content":" For scalable and highly available deployments, Kubernetes is recommended. Below is a minimal Deployment configuration: apiVersion: apps/v1 kind: Deployment metadata: name: solace-agent-mesh labels: app: solace-agent-mesh spec: replicas: 1 # Adjust based on load selector: matchLabels: app: solace-agent-mesh template: metadata: labels: app: solace-agent-mesh spec: containers: - name: solace-agent-mesh image: your-registry/solace-agent-mesh:latest envFrom: - secretRef: name: solace-agent-mesh-secrets # Configure secrets in a Kubernetes Secret command: ["solace-agent-mesh", "run", "--system-env"] args: - "configs/main_orchestrator.yaml" - "configs/gateway/webui.yaml" # Add any other components you want to run here ports: - containerPort: 8000 # Adjust based on your service ports volumeMounts: - name: shared-storage mountPath: /tmp/solace-agent-mesh volumes: - name: shared-storage emptyDir: {} ","version":"Next","tagName":"h3"},{"title":"Splitting and Scaling​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#splitting-and-scaling","content":" 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. To adapt the setup: Reuse the same Docker image.Adjust the startup command to run only the necessary components.Scale containers independently based on their resource needs. ","version":"Next","tagName":"h3"},{"title":"Storage Considerations​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#storage-considerations","content":" warning If using multiple containers, ensure all instances access the same storage with identical configurations. ","version":"Next","tagName":"h3"},{"title":"Security Best Practices​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#security-best-practices","content":" Environment Variables: Store secrets in a secure vault (for example, AWS Secrets Manager, HashiCorp Vault) rather than in .env files.TLS Encryption: Ensure that communication between components and with the PubSub+ event broker is encrypted using TLS.Container Security: Regularly update container images and use security scanning tools (for example, Trivy, Clair). ","version":"Next","tagName":"h3"},{"title":"Solace Event Broker Configuration​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#solace-event-broker-configuration","content":" For production environments, it's recommended to use a cloud-managed PubSub+ event broker (or event broker service). For more information, see Solace PubSub+ Cloud. ","version":"Next","tagName":"h3"},{"title":"Installation","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation","content":"","keywords":"","version":"Next"},{"title":"Prepare the Enterprise Image​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#prepare-the-enterprise-image","content":" Download the latest enterprise docker image tarball from the Solace Product Portal. Load the image using Docker with the following command. docker load -i solace-agent-mesh-enterprise-<tag>.tar Once loaded, you can verify the image locally using the following command: docker images ","version":"Next","tagName":"h2"},{"title":"Running Solace Agent Mesh Enterprise​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#running-solace-agent-mesh-enterprise","content":" Here are two examples of Docker run commands for both a development use case as well as a production use case: tip You may need to include --platform linux/amd64 depending on the host machine you’re using. ","version":"Next","tagName":"h2"},{"title":"Development Use Case​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#development-use-case","content":" docker run -itd -p 8000:8000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="true" \\ --name sam-ent-dev \\ solace-agent-mesh-enterprise:<tag> ","version":"Next","tagName":"h3"},{"title":"Production Use Case​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#production-use-case","content":" docker run -itd -p 8000:8000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="false" \\ -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \\ -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \\ -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \\ -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \\ --name sam-ent-prod \\ solace-agent-mesh-enterprise:<tag> You can then access Solace Agent Mesh Enterprise UI through http://localhost:8000 ","version":"Next","tagName":"h3"},{"title":"Component Overview","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/component-overview","content":"Component Overview Solace Agent Mesh 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. Solace Agent Mesh 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. The key components that make up Solace Agent Mesh are: PubSub+ Event Broker or Event Mesh: The central nervous system of the framework, facilitating A2A protocol communication between all components. more 🔗 A2A Protocol & Agent Registry: The standardized communication protocol that enables agent discovery, task delegation, and peer-to-peer communication. Orchestrator: A specialized agent responsible for breaking down requests into tasks and managing the overall workflow. more 🔗 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. more 🔗 Agents: ADK-powered processing units that communicate through the A2A protocol, each bringing specialized capabilities and tools. more 🔗 ADK Runtime: The Google Agent Development Kit provides the core intelligence layer with tool execution, session management, and artifact handling capabilities. Built-in Tools: Comprehensive tool ecosystem including artifact management, data analysis, web tools, and peer agent delegation capabilities. Real-time Monitoring and Debugging Component: Enables real-time monitoring of system activities and provides interactive debugging capabilities for administrators. more 🔗","keywords":"","version":"Next"},{"title":"Observability","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/observability","content":"","keywords":"","version":"Next"},{"title":"Workflow Viewer​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#workflow-viewer","content":" The Solace Agent Mesh web UI includes a built-in workflow viewer, which provides an interactive web-based UI for each user query and its corresponding response. This visualizer allows you to: Track the complete life cycle of a stimulus (request) as it moves through the system.Visualize the flow of requests/responses among agents, the user gateway and LLM.Monitor all participating agents and their activity in real-time. To launch the workflow viewer for a specific query/response pair, click the View Agent Workflow icon located at the bottom left of the final response. The complete workflow chart appears in the side panel on the right. ","version":"Next","tagName":"h2"},{"title":"Agents View​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#agents-view","content":" The Solace Agent Mesh web UI also includes an Agents view, which provides a comprehensive overview of all registered agents in the system in real-time. This view allows you to: See all agents currently registered in the system.View agents description, capabilities, and skillsView agent hierarchical topology and relationships. To access the Agents view, open the web interface in your browser and switch to the Agents tab. ","version":"Next","tagName":"h2"},{"title":"Broker Observability​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#broker-observability","content":" Solace Agent Mesh relies on a PubSub+ event broker for all its communication. Various tools are available to monitor the event broker’s activity and message flows: PubSub+ Broker Manager – A web-based interface where you can use the Try Me! tab to send and receive messages interactively.Solace Try Me VSCode Extension – A convenient way to test message flows within Visual Studio Code.Solace Try Me (STM) CLI Tool – A command-line tool for sending and receiving messages. To observe all message flows within the event broker, subscribe to the following topic: [NAME_SPACES]a2a/v1/> Replace [NAME_SPACES] with the namespace you are using. If none, omit the [NAME_SPACES] part. tip Agents periodically send registration messages, which may clutter your UI if you're using the STM VSCode extension. To filter out these messages, you can add the following topic to the ignore list: [NAME_SPACES]/a2a/v1/discovery/agentcards ","version":"Next","tagName":"h2"},{"title":"Stimulus Logs​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#stimulus-logs","content":" Solace Agent Mesh includes a default monitor that records each request (stimulus) life cycle. These logs are stored as .stim files. Each .stim file captures a complete trace of a stimulus, including: Every component it passed through.Timing and sequencing details.Additional contextual metadata. These logs provide a valuable data source for further visualization, troubleshooting, and performance analysis. By default, .stim files are written to the /tmp/solace-agent-mesh/ directory. ","version":"Next","tagName":"h2"},{"title":"Prerequisites","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/installation","content":"Prerequisites Before you begin, make sure you have the following: Python 3.10.16+pip (usually included with Python) or uv (install uv)Operating System: macOS, Linux, or Windows (via WSL)LLM API key from any major provider or your own custom endpoint. Installation Solace Agent Mesh Module comes with two components: Solace Agent Mesh CLI: To create, build, run, and extend Solace Agent Mesh.Solace Agent Mesh framework: A Python-based framework that you can build upon to customize and extend the capabilities of Solace Agent Mesh. Installing the PyPi package installs both the Solace Agent Mesh CLI and the framework (which is built on the Python SDK). tip We recommend that you install the package in a virtual environment to avoid conflicts with other Python packages. Creating a Virtual Environment Using PIP Create a virtual environment. python3 -m venv .venv Activate the environment. To activate on Linux or Unix platforms: source .venv/bin/activate To activate on Windows: .venv\\Scripts\\activate Using UV Create a virtual environment. uv venv .venv Activate the environment. To activate on Linux or Unix platforms: source .venv/bin/activate To activate on Windows: .venv\\Scripts\\activate Expose the following environment variables: On Linux or Unix platforms: export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" On Windows: set SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" Install Solace Agent Mesh The following command installs Solace Agent Mesh CLI in your environment: Using PIP pip install solace-agent-mesh Using UV uv pip install solace-agent-mesh Docker Alternative Alternatively, you can use our pre-built Docker image to run Solace Agent Mesh CLI commands without a local Python installation. This is useful for quick tasks or CI/CD environments. Note that the pre-built Docker image is configured with group solaceai and non-root user solaceai. To verify the installation using Docker, you can run: docker run --rm solace/solace-agent-mesh:latest --version This command pulls the latest image (if not already present) and executes solace-agent-mesh --version inside the container. The --rm flag ensures the container is removed after execution. If the OS architecture on your host is not linux/amd64, you would need to add --platform linux/amd64 when running container. For more complex operations like building a project, you'll need to mount your project directory into the container. See the Quick Start guide for an example. Browser Requirement The Mermaid agent requires a browser with headless mode support to be installed (it uses headless mode to render diagrams). Use playwright to install the browser dependencies. If you are using the Docker image, this is already included. To install the browser dependencies, run: playwright install Run the following Solace Agent Mesh CLI command (solace-agent-mesh) to verify your installation: solace-agent-mesh --version tip For easier access to the Solace Agent Mesh CLI, it also comes with the sam alias. sam --version To get the list of available commands, run: solace-agent-mesh --help ","keywords":"","version":"Next"},{"title":"SSO","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on","content":"","keywords":"","version":"Next"},{"title":"How to enable SSO​","type":1,"pageTitle":"SSO","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on#how-to-enable-sso","content":" Before running the Docker container, create two configuration files for SSO under the root directory in your Named Docker Volume. Use the content provided below for each file: Configuration files for SSO oauth2_server.yaml --- # Example gateway configuration with OAuth2 service integration # This shows how to configure a gateway to use the OAuth2 authentication service log: stdout_log_level: INFO log_file_level: DEBUG log_file: oauth_server.log !include ../shared_config.yaml shared_config: # OAuth2 service configuration - oauth2_config: &oauth2_config enabled: true config_file: "config/sso_vol/oauth2_config.yaml" host: ${OAUTH2_HOST, localhost} port: ${OAUTH2_PORT, 9000} ssl_cert: "" # Optional: path to SSL certificate ssl_key: "" # Optional: path to SSL private key flows: # Initialize OAuth2 service - name: oauth2_service components: - component_name: oauth2_auth_service component_module: src.components.oauth2_component component_config: <<: *oauth2_config oauth2_config.yaml In the oauth2_config.yaml file, uncomment the authentication provider you want to use. Note that the Azure provider is configured as the default option. --- # OAuth2 Service Configuration # This file configures the OAuth2 authentication service that supports multiple providers # All providers now use the unified OIDC approach with automatic endpoint discovery # Enable or disable the OAuth2 service enabled: ${OAUTH2_ENABLED:false} # Development mode - enables insecure transport and relaxed token scope for local development # Set OAUTH2_DEV_MODE=true for local development (NEVER use in production!) development_mode: ${OAUTH2_DEV_MODE:false} # OAuth2 providers configuration # All providers now use the unified OIDCProvider with automatic endpoint discovery providers: # Google OAuth2 provider # google: # # OIDC issuer URL - endpoints will be discovered automatically # issuer: "https://accounts.google.com" # client_id: ${GOOGLE_CLIENT_ID} # client_secret: ${GOOGLE_CLIENT_SECRET} # redirect_uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # Azure/Microsoft OAuth2 provider azure: # Azure OIDC issuer URL includes tenant ID issuer: https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0 client_id: ${AZURE_CLIENT_ID} client_secret: ${AZURE_CLIENT_SECRET} redirect_uri: ${AZURE_REDIRECT_URI:http://localhost:8080/callback} scope: "openid email profile offline_access" # Auth0 OAuth2 provider # auth0: # # Auth0 issuer URL # issuer: ${AUTH0_ISSUER:https://your-domain.auth0.com/} # client_id: ${AUTH0_CLIENT_ID} # client_secret: ${AUTH0_CLIENT_SECRET} # redirect_uri: ${AUTH0_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Optional: Auth0 audience for API access # audience: ${AUTH0_AUDIENCE:} # # Okta OAuth2 provider (example) # okta: # issuer: ${OKTA_ISSUER:https://your-okta-domain.okta.com/oauth2/default} # client_id: ${OKTA_CLIENT_ID} # client_secret: ${OKTA_CLIENT_SECRET} # redirect_uri: ${OKTA_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Keycloak OAuth2 provider (example) # keycloak: # issuer: ${KEYCLOAK_ISSUER:https://your-keycloak.com/auth/realms/your-realm} # client_id: ${KEYCLOAK_CLIENT_ID} # client_secret: ${KEYCLOAK_CLIENT_SECRET} # redirect_uri: ${KEYCLOAK_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Generic OIDC provider (for any standard OIDC-compliant provider) # custom_oidc: # # Just provide the issuer URL and the service will discover all endpoints # issuer: ${CUSTOM_OIDC_ISSUER:https://your-provider.com} # client_id: ${CUSTOM_OIDC_CLIENT_ID} # client_secret: ${CUSTOM_OIDC_CLIENT_SECRET} # redirect_uri: ${CUSTOM_OIDC_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # Logging configuration logging: level: ${OAUTH2_LOG_LEVEL:INFO} # Session configuration session: # Session timeout in seconds (default: 1 hour) timeout: ${OAUTH2_SESSION_TIMEOUT:3600} # Security configuration security: # CORS settings cors: enabled: ${OAUTH2_CORS_ENABLED:true} origins: ${OAUTH2_CORS_ORIGINS:*} # Rate limiting rate_limit: enabled: ${OAUTH2_RATE_LIMIT_ENABLED:true} requests_per_minute: ${OAUTH2_RATE_LIMIT_RPM:60} ","version":"Next","tagName":"h2"},{"title":"Running Solace Agent Mesh Enterprise with SSO enabled​","type":1,"pageTitle":"SSO","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on#running-solace-agent-mesh-enterprise-with-sso-enabled","content":" Here is an example of Docker run command with Azure SSO provider for production use case: tip You may need to include --platform linux/amd64 depending on the host machine you’re using. docker run -itd -p 8000:8000 -p 9000:9000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="false" \\ -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \\ -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \\ -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \\ -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \\ -e FASTAPI_HOST="0.0.0.0" \\ -e FASTAPI_PORT="8000" \\ -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e OAUTH2_ENABLED="true" \\ -e OAUTH2_LOG_LEVEL="DEBUG" \\ -e OAUTH2_DEV_MODE="true" \\ -e OAUTH2_HOST="0.0.0.0" \\ -e OAUTH2_PORT="9000" \\ -e FRONTEND_USE_AUTHORIZATION="true" \\ -e FRONTEND_REDIRECT_URL="http://localhost:8000" \\ -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\ -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\ -e EXTERNAL_AUTH_PROVIDER="azure" \\ -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\ -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\ --name sam-ent-prod-sso \\ solace-agent-mesh-enterprise:<tag> run config/sso_vol/oauth2_server.yaml config/webui_backend.yaml config/a2a_orchestrator.yaml config/a2a_agents.yaml You can then access Solace Agent Mesh Enterprise UI through http://localhost:8000 Configuration Options Specify the hostname and port for the UI running in the docker container. The main UI runs on port 8000 by default. Using 0.0.0.0 as the host allows external access to the container. -e FASTAPI_HOST="0.0.0.0" \\ -e FASTAPI_PORT="8000" \\ Enable single sign-on processing on the frontend. -e FRONTEND_USE_AUTHORIZATION="true" \\ Specify the main URL of the UI. For instance, this could be https://www.example.com -e FRONTEND_REDIRECT_URL="http://localhost:8000" \\ Set the login URL used by the main UI. For instance, this could be https://www.example.com/api/v1/auth/login -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\ Enable the OAUTH2 server and set the log level -e OAUTH2_ENABLED="true" \\ -e OAUTH2_LOG_LEVEL="DEBUG" \\ Specify the hostname and port for the authorization server running in the docker container. Using 0.0.0.0 as the host allows external access to the container. -e OAUTH2_HOST="0.0.0.0" \\ -e OAUTH2_PORT="9000" \\ Specify whether the Oauth2 checks use dev mode. When dev mode is true the following environment variables are added to allow http access and relax the token scope. This MUST be set false in a production environment. -e OAUTH2_DEV_MODE="true" \\ OAUTHLIB_RELAX_TOKEN_SCOPE="1" OAUTHLIB_INSECURE_TRANSPORT="1" Configure the environment variables for your chosen authentication provider. Refer to the oauth2_config.yaml file to identify the required variables. For example, with Azure set the following -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ Configure the authorization server's public URL (accessible from outside the Docker container) and specify the OAuth2 provider’s name from oauth2_config.yaml (this example uses the azure profile): -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\ -e EXTERNAL_AUTH_PROVIDER="azure" \\ Lastly, set the callback URL that your auth provider will use to redirect with the auth code. For instance, this could be https://www.example.com/api/v1/auth/callback -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\ Note that both the main UI and authorization server ports must be mapped to the host machine, as shown in the Docker run command above: -p 8000:8000 -p 9000:9000 \\ The oauth 2 configuration files must be mounted inside the container: -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\ ","version":"Next","tagName":"h2"},{"title":"Quick Start","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start","content":"","keywords":"","version":"Next"},{"title":"Use Preset Agents​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#use-preset-agents","content":" ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#prerequisites","content":" You must have Docker (or Podman) installed.You must have an available AI provider and API key. For best results, use a state-of-the-art AI model like Anthropic Claude Sonnet 4, Google Gemini 2.5 pro, or OpenAI GPT-5. ","version":"Next","tagName":"h3"},{"title":"Run Preset Agents​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#run-preset-agents","content":" You can run pre-made Solace Agent Mesh agents to quickly get started with Solace Agent Mesh without needing to set up a project from scratch. docker run --rm -it -p 8000:8000 --platform linux/amd64 --env-file <your-env-file-path> solace/solace-agent-mesh:latest Provide the required environment variables. You can also pass them as command-line arguments using the -e flag. Alternatively, you can combine your project with the preset app or only run specific agents from it. You can find a list of all available preset apps in the Solace Agent Mesh GitHub repository. tip To run your custom agent without creating a new project, you can use the Docker image as follows: docker run --rm -it --platform linux/amd64 -p 8000:8000 -v $(pwd):/app \\ -e LLM_SERVICE_ENDPOINT=<your-llm-endpoint> \\ -e LLM_SERVICE_API_KEY=<your-llm-api-key> \\ -e LLM_SERVICE_PLANNING_MODEL_NAME=<your-llm-planning-model-name> \\ -e LLM_SERVICE_GENERAL_MODEL_NAME=<your-llm-general-model-name> \\ solace/solace-agent-mesh:latest run /preset/agents/basic /app/my-agent You can update /app/my-agent with the path to your agent YAML config. Note: You will still need either a shared_config.yaml file or to hard code the settings in your agent configuration./preset/agents/basic only runs the required agents, you can use /preset/agents to load all agents.This example command only has the minimum required environment variables. ","version":"Next","tagName":"h3"},{"title":"Create a Project​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#create-a-project","content":" Plugins Looking to get started with plugins? For more information, see the Plugins. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#prerequisites-1","content":" You must have installed the Solace Agent Mesh CLI. If not, see the Installation page.You must have activated the virtual environment you created following the Installation page. For containerized deployment such as Docker, ignore this prerequisite.You must have an available AI provider and API key. For best results, use a state-of-the-art AI model like Anthropic Claude Sonnet 4, Google Gemini 2.5 pro, or OpenAI GPT-5. Create a directory for your project and navigate to it. mkdir my-agent-mesh cd my-agent-mesh Run the init command and follow the prompts to create your project. solace-agent-mesh init During initialization, you can choose to configure your project directly in the terminal or through a web-based interface launched at http://127.0.0.1:5002. You are asked for your preference once you run solace-agent-mesh init. Alternatively, you can use the --gui flag to skip the prompt and directly open the web-based configuration interface: solace-agent-mesh init --gui Docker Alternative for Initialization You can also initialize your Solace Agent Mesh project using the official Docker image. This is helpful if you want to avoid local Python/Solace Agent Mesh CLI installation or prefer a containerized workflow from the start. docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 5002:5002 solace/solace-agent-mesh:latest init --gui If the OS architecture on your host is not linux/amd64, you must add --platform linux/amd64 when you run the container. For Broker Setup, do not select the Broker Type New local Solace PubSub+ broker container. This option is incompatible with Docker deployments because the Download and Run Container action attempts to download a container image from within the already running container, which causes the operation to fail. Non-Interactive Mode You can run the init command in a non-interactive mode by passing --skip and all the other configurations as arguments. To get a list of all the available options, run solace-agent-mesh init --help Model name format Browser-based Configurations You need to select the LLM Provider first and supported models are populated under LLM Model Name. If you're using a non-openai model but hosting it on a custom API that follows the OpenAI standards, like Ollama or LiteLLM, you can select the OpenAI Compatible Provider. CLI-based Configurations You need to explicitly specify the model in the format provider/name. For example, openai/gpt-4o. If you're using a non-openai model but hosting it on a custom API that follows the OpenAI standards, like Ollama or LiteLLM, you can still use the openai provider. For example: openai/llama-3.3-7b This is the case for all the model names, such as LLMs, image generators, embedding models, etc. ","version":"Next","tagName":"h3"},{"title":"Running the Project​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#running-the-project","content":" To run the project, you can use the run command to execute all the components in a single, multi-threaded application. It's possible to split the components into separate processes. See the deployment page for more information. solace-agent-mesh run tip Environment variables are loaded from your configuration file (typically a .env file at the project root) by default. To use system environment variables instead, use the -u or --system-env option. To learn more about the other CLI commands, see the CLI documentation. Docker Alternative for Running the Project You can also run your Solace Agent Mesh project using the official Docker image. This is helpful if you want to avoid local Python/Solace Agent Mesh CLI installation or prefer a containerized workflow from the start. docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 8000:8000 solace/solace-agent-mesh:latest run If your host system architecture is not linux/amd64, add the --platform linux/amd64 flag when you run the container. Required Configurations For deployments that use the official Docker image, ensure the following: Do not use a local Solace PubSub+ broker container.Set the environment variables FASTAPI_HOST="0.0.0.0" in your .env file or system environment variables. This is necessary to expose the FastAPI server to the host machine. warning If you are using third-party Python packages or Solace Agent Mesh plugins, you need to build a custom Docker image off the official image and install the required packages there, and then run that custom image instead. FROM solace/solace-agent-mesh:latest # Option 1: Install a specific package RUN python3.11 -m pip install --no-cache-dir <your-package> # Option 2: use a requirements.txt file COPY requirements.txt . RUN python3.11 -m pip install --no-cache-dir -r requirements.txt ENTRYPOINT ["solace-agent-mesh"] Then build and run your custom image: docker build --platform linux/amd64 -t my-custom-image . docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 8000:8000 my-custom-image run ","version":"Next","tagName":"h2"},{"title":"Interacting with Solace Agent Mesh​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#interacting-with-solace-agent-mesh","content":" You can use different gateway interfaces to communicate with the system such as REST, Web UI, Slack, MS Teams, and so on. To keep it simple for this demo, we use the browser UI. To access the browser UI, navigate to http://localhost:8000 in your web browser. If you specified a different port during the init step, use that port instead. For Docker deployments with custom port mappings (using the -p flag), use the host port specified in your port mapping configuration. Try some commands like Suggest some good outdoor activities in London given the season and current weather conditions.. ","version":"Next","tagName":"h2"},{"title":"Try a Tutorial​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#try-a-tutorial","content":" Try adding a new agent to the system by following the tutorial on adding an SQL database agent. This tutorial guides you through the process of adding the SQL agent plugin and adding some sample data to the database. ","version":"Next","tagName":"h2"},{"title":"Next Steps​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#next-steps","content":" Solace Agent Mesh uses two main types of components, agents and gateways. The system comes with a built-in orchestrator agent and a web user interface gateway (which you enabled during the init step). You can learn more about gateways. Alternatively, you can learn about using plugins or creating your own new gateways. Also, you can learn more about agents or about creating your own agents. ","version":"Next","tagName":"h2"},{"title":"Introduction","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction","content":"","keywords":"","version":"Next"},{"title":"Solace Agent Mesh​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#solace-agent-mesh","content":" 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. Solace Agent Mesh 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, Solace Agent Mesh gives you the tools to: connect AI agents to real-world data sources and systems through a standardized A2A (Agent-to-Agent) protocoladd gateways to provide event-based integrations or interactive UI connectionsmonitor and debug AI interactions in real-time through comprehensive observabilitydeploy solutions that scale from prototype to production with enterprise-grade reliability Rather than trying to be a monolithic AI platform, Solace Agent Mesh 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. Built on event-driven architecture technology from Solace with Google ADK integration, Solace Agent Mesh provides the robust foundation needed for both experimental and production deployments. ","version":"Next","tagName":"h2"},{"title":"What Problems Does the Mesh Solve?​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#what-problems-does-the-mesh-solve","content":" 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. Event-Driven Architecture at the Core: The beating heart of Solace Agent Mesh is its event mesh—a 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. Breaking Down AI Silos: Specialized agents operate independently yet collaborate effortlessly—like expert teammates rather than isolated tools. Orchestrating Complex Workflows: Create sophisticated multi-agent processes where tasks flow naturally between specialists, executing in sequence or parallel based on dynamic needs. Speaking a Common Language: The A2A protocol creates a universal communication standard, ensuring all agents and gateways understand each other regardless of their internal implementation. Unifying AI Capabilities: Blend diverse AI models, custom tools (Python functions, MCP tools), and enterprise data sources into a cohesive ecosystem. Connecting to Your World: Purpose-built gateways bridge the gap between the agent mesh and your existing systems—web interfaces, Slack workspaces, APIs, and event streams. Handling the Unpredictable: The event-driven backbone gracefully manages long-running tasks and asynchronous patterns that are inherent in AI agent interactions. Adding Agents to Increase Capabilities: Each new agent adds more capabilities to the system. Adding a new agent is not additive—it is exponential. With each agent being able to enhance all other agents as they collaborate for more and more complex tasks. Adding Gateways to Increase the Supported Use Cases: Each 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. Enterprise-Ready: Engineered from the ground up for production deployment, this solution leverages expertise from Solace in building mission-critical distributed systems. ","version":"Next","tagName":"h3"},{"title":"Why Choose Solace Agent Mesh?​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#why-choose-solace-agent-mesh","content":" Enterprise-Grade Performance: Built on Solace PubSub+ Event Broker, the mesh delivers high-throughput, fault-tolerant messaging that scales with your needs. Plug-and-Play Extensibility: 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—no manual configuration, no downtime, no integration headaches. Modular by Design: Every component—agents, gateways, tools—is a self-contained module you can reuse, replace, or enhance independently. Configuration-Driven: YAML-based configuration gives you precise control over agent behavior, service integrations, and security settings without code changes. Security-First Approach: The built-in authorization framework provides fine-grained access control over agents and tools based on user roles and scopes. Resilient by Nature: Event-driven design creates responsive, self-healing interactions that recover gracefully from disruptions. ","version":"Next","tagName":"h3"},{"title":"Real-World Applications​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#real-world-applications","content":" Organizations are using Solace Agent Mesh in diverse scenarios: Intelligent Enterprise Automation: Customer service systems that route inquiries to specialized agents based on intent and context.Data processing pipelines where specialized agents transform, analyze, and enrich information from multiple sources. AI Task Specialization: Image analysis workflows where one agent processes visual data and delegates text generation to a language specialist.Document processing systems that extract text, summarize content, and translate results—each step handled by the perfect specialist. Human-AI Collaboration: Agents that perform complex tasks while keeping humans in the loop for approvals, clarifications, or expert guidance via web or chat interfaces. Multi-Agent Research: A production-ready platform for exploring agent collaboration patterns, delegation strategies, and distributed AI problem-solving. Data-Driven Intelligence: Agents that query databases, transform results, and generate visualizations based on natural language requests or system events. ","version":"Next","tagName":"h2"},{"title":"Evolution Through Usage​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#evolution-through-usage","content":" Solace Agent Mesh grows with your needs. For example, at Solace we started with basic agents and have continuously expanded the system's capabilities: Added specialized agents for JIRA and Confluence integrationImplemented multiple interface options including browser-based user interfaces and REST API gatewaysIntegrated with various AI models and data sources ","version":"Next","tagName":"h3"},{"title":"For Developers​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#for-developers","content":" Solace Agent Mesh is an agentic framework that provides several key technical advantages: Complete Observability: Because all communication flows through the event broker, you can monitor and debug the entire system in real-timeFlexible Integration: Built-in support for common enterprise systems and AI frameworksPlugin Architecture: Easily extend the system with custom agents and gatewaysDeveloper Tools: Comprehensive CLI and debugging utilities ","version":"Next","tagName":"h2"},{"title":"Getting Started​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#getting-started","content":" 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: Installation: For installing and setting up Solace Agent Mesh.Quick Start: For creating a project, build, and run Solace Agent Mesh.Components Overview: Understand the parts of Solace Agent Mesh. ","version":"Next","tagName":"h2"},{"title":"Configurations","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations","content":"","keywords":"","version":"Next"},{"title":"Shared Configurations​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#shared-configurations","content":" The shared_config.yaml file is used to define configurations that can be shared across multiple agents or components in Solace Agent Mesh. This allows for centralized management of common settings like broker connections and language model configurations. ","version":"Next","tagName":"h2"},{"title":"Using Shared Configurations​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#using-shared-configurations","content":" All agents and gateways require access to a shared_config object. You can provide configuration in the following ways: Hard-coding values: You can directly embed the shared_config values within your agent or gateway YAML files.Using !include: For better project consistency and management, you can use the !include directive to load a shared configuration file. When a plugin is installed, it may come with hard-coded default values. It is a best practice to remove this section and use !include to point to the centralized shared_config file. This ensures that all components are using the same base configuration. ","version":"Next","tagName":"h3"},{"title":"Managing Multiple Shared Configuration Files​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#managing-multiple-shared-configuration-files","content":" You can use multiple shared configuration files to manage different environments or setups (e.g., for different cloud providers). You must follow these rules: Filename: The filename must always start with shared_config (e.g., shared_config_aws.yaml, shared_config_gcp.yaml).Sub-directories: You can organize these files into sub-directories (e.g., configs/agents/shared_config.yaml). When you do this, you must update the !include path in your agent or gateway configurations to point to the correct location. The file uses YAML anchors (&anchor_name) to create reusable configuration blocks, which can then be referenced in agent configuration files. ","version":"Next","tagName":"h3"},{"title":"Parameters​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#parameters","content":" Example shared_config.yaml​ shared_config: - broker_connection: &broker_connection dev_mode: ${SOLACE_DEV_MODE, false} broker_url: ${SOLACE_BROKER_URL, ws://localhost:8080} broker_username: ${SOLACE_BROKER_USERNAME, default} broker_password: ${SOLACE_BROKER_PASSWORD, default} broker_vpn: ${SOLACE_BROKER_VPN, default} temporary_queue: ${USE_TEMPORARY_QUEUES, true} # Ensure high enough limits if many agents are running # max_connection_retries: -1 # Retry forever - models: planning: &planning_model # This dictionary structure tells ADK to use the LiteLlm wrapper. # 'model' uses the specific model identifier your endpoint expects. model: ${LLM_SERVICE_PLANNING_MODEL_NAME} # Use env var for model name # 'api_base' tells LiteLLM where to send the request. api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL # 'api_key' provides authentication. api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key # Enable parallel tool calls for planning model parallel_tool_calls: true # max_tokens: ${MAX_TOKENS, 16000} # Set a reasonable max token limit for planning # temperature: 0.1 # Lower temperature for more deterministic planning general: &general_model # This dictionary structure tells ADK to use the LiteLlm wrapper. # 'model' uses the specific model identifier your endpoint expects. model: ${LLM_SERVICE_GENERAL_MODEL_NAME} # Use env var for model name # 'api_base' tells LiteLLM where to send the request. api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL # 'api_key' provides authentication. api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key # ... (similar structure) - services: # Default session service configuration session_service: &default_session_service type: "memory" default_behavior: "PERSISTENT" # Default artifact service configuration artifact_service: &default_artifact_service type: "filesystem" base_path: "/tmp/samv2" artifact_scope: namespace # Default data tools configuration data_tools_config: &default_data_tools_config sqlite_memory_threshold_mb: 100 max_result_preview_rows: 50 max_result_preview_bytes: 4096 Broker Connection​ The broker_connection section configures the connection to the Solace PubSub+ event broker. The connection parameters are described in the following table: Parameter\tEnvironment Variable\tDescription\tDefaultdev_mode\tSOLACE_DEV_MODE\tWhen set to true, uses an in-memory broker for testing.\tfalse broker_url\tSOLACE_BROKER_URL\tThe URL of the Solace broker.\tws://localhost:8080 broker_username\tSOLACE_BROKER_USERNAME\tThe username for authenticating with the broker.\tdefault broker_password\tSOLACE_BROKER_PASSWORD\tThe password for authenticating with the broker.\tdefault broker_vpn\tSOLACE_BROKER_VPN\tThe Message VPN to connect to on the broker.\tdefault temporary_queue\tUSE_TEMPORARY_QUEUES\tWhether to use temporary queues for communication. If false, a durable queue will be created.\ttrue max_connection_retries\tMAX_CONNECTION_RETRIES\tThe maximum number of times to retry connecting to the broker if the connection fails. A value of -1 means retry forever.\t-1 tip If you need to configure multiple brokers, you can do so by adding additional entries under shared_config with a unique name (For example, broker_connection_eu: &broker_connection_eu or broker_connection_us: &broker_connection_us) and then use the proper reference in your agent configurations. (Example: <<: *broker_connection_eu) Models​ The models section is used to configure the various Large Language Models (LLMs) and other generative models used by the agents. The configuration uses the LiteLLM library, which provides a standardized way to interact with different model providers. Model Configuration Structure​ The following table describes the parameters that tell the system how to interact with the model: Parameter\tEnvironment Variable\tDescriptionmodel\tLLM_SERVICE_<MODEL_NAME>_MODEL_NAME\tThe specific model identifier that the endpoint expects in the format of provider/model (e.g., openai/gpt-4, anthropic/claude-3-opus-20240229). api_base\tLLM_SERVICE_ENDPOINT\tThe base URL of the LLM provider's API endpoint. api_key\tLLM_SERVICE_API_KEY\tThe API key for authenticating with the service. parallel_tool_calls\tPARALLEL_TOOL_CALLS\tEnable parallel tool calls for the model. max_tokens\tMAX_TOKENS\tSet a reasonable max token limit for the model. temperature\tTEMPERATURE\tLower temperature for more deterministic planning. Alternatively, you can use Gemini models directly through Google Studio AI or Vertex AI: model: gemini-2.5-pro See the documentation for details on setting the environment for Gemini models. Pre-Defined Model Types​ The shared_config.yaml example defines several models for different purposes. A pre-defined model serves as an alias for the model configuration. This alias allows you to refer to a configuration by its use case rather than its specific parameters. planning: Used by agents for planning and decision-making. It's configured for deterministic outputs (temperature: 0.1) and can use tools in parallel.general: A general-purpose model for various tasks.image_gen: A model for generating images.image_describe: A model for describing the content of images.audio_transcription: A model for transcribing audio files.report_gen: A model specialized for generating reports.multimodal: A simple string reference to a multimodal model (e.g., "gemini-1.5-flash-latest"). You can define any number of models in this section and reference them in your agent configurations. By default, the system only uses the planning and the general models. No need to fill the other fields Services​ The services section in shared_config.yaml is used to configure various services that are available to agents. Session Service​ The parameters are described in the following table: Parameter\tOptions\tDescription\tDefaulttype\tmemory, vertex_rag\tConfiguration for ADK Session Service\tmemory default_behavior\tPERSISTENT, RUN_BASED\tThe default behavior of keeping the session history\tPERSISTENT Artifact Service​ The artifact_service is responsible for managing artifacts, which are files or data generated by agents. Parameter\tOptions\tDescription\tDefaulttype\tmemory, gcs, filesystem\tService type for artifact storage. Use memory for in-memory, gcs for Google Cloud Storage, or filesystem for local file storage.\tmemory base_path\tlocal path\tBase directory path for storing artifacts. Required only if type is filesystem.\t(none) bucket_name\tbucket name\tGoogle Cloud Storage bucket name. Required only if type is gcs.\t(none) artifact_scope\tnamespace, app\tScope for artifact sharing. namespace: shared by all components in the namespace. app: isolated by agent/gateway name. Must be consistent for all components in the same process.\tnamespace artifact_scope_value\tcustom scope id\tCustom identifier for artifact scope. Required if artifact_scope is set to a custom value.\t(none) Data Tools Config​ The data_tools_config section configures the behavior of data analysis tools. Parameter\tType\tDescription\tDefaultsqlite_memory_threshold_mb\tinteger\tThe memory threshold in megabytes for using an in-memory SQLite database.\t100 max_result_preview_rows\tinteger\tThe maximum number of rows to show in a result preview.\t50 max_result_preview_bytes\tinteger\tThe maximum number of bytes to show in a result preview.\t4096 ","version":"Next","tagName":"h3"},{"title":"System Logs​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#system-logs","content":" For details on how to configure system logging, including log rotation and verbosity levels, please see the System Logs section in the debugging documentation. ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0","content":"","keywords":"","version":"Next"},{"title":"1. Why the Change?​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#1-why-the-change","content":" The migration from our legacy A2A implementation to the official a2a-sdk is a foundational improvement with several key benefits: Protocol Compliance: Ensures your gateway is fully interoperable with any A2A-compliant agent or system.Standardization: Replaces bespoke code with a community-supported standard, reducing technical debt.Improved Maintainability: Insulates your gateway from future A2A specification changes. The a2a-sdk will be updated, not your core logic.Future-Proofing: Positions your gateway to easily adopt new features as the A2A protocol evolves. ","version":"Next","tagName":"h2"},{"title":"2. Core Conceptual Changes​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#2-core-conceptual-changes","content":" The upgrade introduces a few key changes in how you interact with A2A objects. ","version":"Next","tagName":"h2"},{"title":"The a2a Helper Layer: The New Best Practice​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#the-a2a-helper-layer-the-new-best-practice","content":" The most significant change is the introduction of a new abstraction layer located at solace_agent_mesh.common.a2a. You should no longer instantiate a2a.types models directly or access their properties by hand. Instead, use the provided helper functions. This layer is designed to simplify development and protect your code from future SDK changes. Example: # BEFORE: Direct instantiation and property access from solace_agent_mesh.common.types import TextPart, Task my_part = TextPart(text="Hello") task_id = my_task.id # AFTER: Using the a2a helper layer from solace_agent_mesh.common import a2a my_part = a2a.create_text_part(text="Hello") task_id = a2a.get_task_id(my_task) ","version":"Next","tagName":"h3"},{"title":"Type System Migration​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#type-system-migration","content":" The legacy types in solace_agent_mesh.common.types (like A2APart, FileContent) are deprecated.All A2A models now come from the a2a.types library.The type hint for a list of message parts has changed from List[A2APart] to List[ContentPart]. ContentPart is a simple alias for the union of TextPart, DataPart, and FilePart. ","version":"Next","tagName":"h3"},{"title":"Accessing Object Properties​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#accessing-object-properties","content":" Field names on many A2A objects have changed. Always use the a2a helper functions for safe and future-proof access. Action\tOld Pattern\tNew Pattern (Recommended)Get Task ID\ttask.id\ta2a.get_task_id(task) Get Task Status\ttask.status.state\ta2a.get_task_status(task) Get Event's Task ID\tevent.id\tevent.task_id Get Message Parts\tmessage.parts\ta2a.get_parts_from_message(message) Get Error Message\terror.message\ta2a.get_error_message(error) Get Error Code\terror.code\ta2a.get_error_code(error) Get Error Data\terror.data\ta2a.get_error_data(error) ","version":"Next","tagName":"h3"},{"title":"Changes to BaseGatewayComponent​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#changes-to-basegatewaycomponent","content":" The BaseGatewayComponent has been significantly improved. It now handles more of the A2A protocol complexity, simplifying gateway implementations. Artifact Handling: The base class can now automatically handle artifact URIs, converting them to embedded bytes before sending them to your gateway's _send_... methods. This is controlled by the resolve_artifact_uris_in_gateway parameter in the constructor.Message Publishing: The base class now manages the details of preparing and publishing the A2A request message in submit_a2a_task.Asynchronous Model: The underlying threading model has been removed in favor of a more direct asyncio implementation, simplifying the component lifecycle. It is highly recommended to review the latest BaseGatewayComponent and re-base your custom gateway on it to inherit these benefits and reduce boilerplate code. ","version":"Next","tagName":"h3"},{"title":"3. Practical Migration Checklist​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#3-practical-migration-checklist","content":" Follow these steps to update your gateway code. Update Imports: Remove imports from solace_agent_mesh.common.types.Add imports from a2a.types for specific models if needed.Add from solace_agent_mesh.common import a2a.Add from solace_agent_mesh.common.a2a import ContentPart. Update Type Hints: Find all instances of List[A2APart] and change them to List[ContentPart]. Refactor Object Creation: Replace direct model instantiation like TextPart(...) or FilePart(...) with their corresponding helper functions: a2a.create_text_part(...), a2a.create_file_part_from_uri(...), etc. Refactor Property Access: Replace direct property access (task.id, error.message) with calls to the a2a helper functions (a2a.get_task_id(task), a2a.get_error_message(error)). Review Base Class Integration: If you have a custom gateway, compare it against the latest BaseGatewayComponent. Consider refactoring to delegate more responsibility (like artifact handling and message submission) to the base class. Test Thoroughly: Once refactored, run your integration tests to ensure the gateway correctly translates inputs and processes outputs in the new format. ","version":"Next","tagName":"h2"},{"title":"4. Code Examples: Before & After​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#4-code-examples-before--after","content":" Here are some common patterns you will encounter during the migration. ","version":"Next","tagName":"h2"},{"title":"Example 1: Translating External Input​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#example-1-translating-external-input","content":" This example shows how to create A2A parts from an external event. _translate_external_input Before: from solace_agent_mesh.common.types import Part as A2APart, TextPart, FilePart, FileContent async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[A2APart], Dict[str, Any]]: # ... a2a_parts: List[A2APart] = [] # Create a file part with a URI uri = "artifact://..." a2a_parts.append( FilePart( file=FileContent(name="report.pdf", uri=uri) ) ) # Create a text part prompt = "Summarize the attached file." a2a_parts.append(TextPart(text=prompt)) return "summary_agent", a2a_parts, {} After: from solace_agent_mesh.common import a2a from solace_agent_mesh.common.a2a import ContentPart async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[ContentPart], Dict[str, Any]]: # ... a2a_parts: List[ContentPart] = [] # Create a file part with a URI using the helper uri = "artifact://..." file_part = a2a.create_file_part_from_uri(uri=uri, name="report.pdf") a2a_parts.append(file_part) # Create a text part using the helper prompt = "Summarize the attached file." text_part = a2a.create_text_part(text=prompt) a2a_parts.append(text_part) return "summary_agent", a2a_parts, {} ","version":"Next","tagName":"h3"},{"title":"Example 2: Sending a Final Response​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#example-2-sending-a-final-response","content":" This example shows how to process a final Task object. _send_final_response_to_external Before: from solace_agent_mesh.common.types import Task, TaskState, TextPart async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = task_data.id final_status_text = ":checkered_flag: Task complete." if task_data.status.state == TaskState.FAILED: error_message_text = "" if task_data.status.message and task_data.status.message.parts: for part in task_data.status.message.parts: if isinstance(part, TextPart): error_message_text = part.text break final_status_text = f":x: Error: Task failed. {error_message_text}".strip() # ... use final_status_text and task_id After: from solace_agent_mesh.common import a2a from a2a.types import Task, TaskState async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: # Use helpers to safely access properties task_id = a2a.get_task_id(task_data) task_status = a2a.get_task_status(task_data) final_status_text = ":checkered_flag: Task complete." if task_status == TaskState.failed: error_message_text = "" if task_data.status and task_data.status.message: # Use helper to extract all text from the message error_message_text = a2a.get_text_from_message(task_data.status.message) final_status_text = f":x: Error: Task failed. {error_message_text}".strip() # ... use final_status_text and task_id ","version":"Next","tagName":"h3"},{"title":"Amazon Bedrock Agents Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents","content":"","keywords":"","version":"Next"},{"title":"What are Amazon Bedrock Agents and Flows?​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#what-are-amazon-bedrock-agents-and-flows","content":" Amazon Bedrock Agents are AI assistants that can be customized to perform specific tasks using foundation models (FMs). They can connect to enterprise systems and data sources, allowing them to take actions on behalf of users. Amazon Bedrock Flows are visual workflows that orchestrate multiple foundation models to solve complex problems. They allow you to chain together different AI capabilities without writing code. By integrating these services with Solace Agent Mesh, you can: Use the extensible Solace Agent Mesh framework to combine Bedrock agents and flows with other agents.Create conversational interfaces that leverage Bedrock agents and flows.Connect your Solace Agent Mesh agents to enterprise data sources through Bedrock.Maintain a consistent experience across different agent providers by centralizing them in Solace Agent Mesh. Learn about Bedrock Agents and Flows Check the official documentation for Amazon Bedrock Agents and Amazon Bedrock Flows to learn more about these features. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#setting-up-the-environment","content":" ","version":"Next","tagName":"h2"},{"title":"Create Bedrock Agents and Flows​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#create-bedrock-agents-and-flows","content":" Follow these steps to create your Bedrock resources: Log in to your AWS console Navigate to the Amazon Bedrock service Create Bedrock Agents Go to the Agents tab in the Bedrock consoleClick "Create agent"Follow the wizard to configure your agent: Select a foundation modelDefine the agent's instructionsConfigure knowledge bases (optional)Set up action groups (if needed) Once created, create an alias for your agent by selecting it and clicking "Create alias"Copy the Agent ID and Alias ID from the agent details page - you'll need these for the Solace Agent Mesh configuration Create Bedrock Flows Go to the Flows tab in the Bedrock consoleClick "Create flow"Use the visual editor to design your flowConnect nodes to create your workflowTest and publish your flowCreate an alias for your flowCopy the Flow ID and Alias ID - you'll need these for the Solace Agent Mesh configuration Set up IAM permissions Ensure your IAM user or role has the following permissions: bedrock:InvokeAgentbedrock:InvokeFlowAny other permissions required by your specific Bedrock configuration ","version":"Next","tagName":"h3"},{"title":"Create a Solace Agent Mesh Project​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#create-a-solace-agent-mesh-project","content":" You must install Solace Agent Mesh and Solace Mesh Agent CLI, and then you'll want to create a new Solace Agent Mesh project. ","version":"Next","tagName":"h3"},{"title":"Integrating Bedrock with Solace Agent Mesh​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#integrating-bedrock-with-solace-agent-mesh","content":" ","version":"Next","tagName":"h2"},{"title":"Adding the Bedrock Agent Plugin​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#adding-the-bedrock-agent-plugin","content":" The sam-bedrock-agent plugin from the solace-agent-mesh-core-plugins repository creates a bridge between Solace Agent Mesh and Amazon Bedrock services. This plugin allows your Solace Agent Mesh agents to invoke Bedrock Agents and Flows as tools. Add the plugin to your Solace Agent Mesh project: sam plugin add aws-agent --plugin sam-bedrock-agent Replace aws-agent with a descriptive name for your agent, such as bedrock-summarizer or bedrock-customer-service. This command: Installs the sam-bedrock-agent pluginCreates a new agent configuration file in configs/agents/aws-agent.yaml Locate the configuration file: The command creates an aws-agent.yaml file in the configs/agents/ directory of your Solace Agent Mesh project. Naming Convention Choose a descriptive name that reflects the purpose of your Bedrock integration. This name is used to reference the agent in your Solace Agent Mesh project. ","version":"Next","tagName":"h3"},{"title":"Configuring the Bedrock Agent​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#configuring-the-bedrock-agent","content":" The configuration file you created needs to be edited to connect to your specific Amazon Bedrock resources. This section explains each part of the configuration and how to customize it. ","version":"Next","tagName":"h2"},{"title":"Understanding the Configuration Structure​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#understanding-the-configuration-structure","content":" Open the aws-agent.yaml file in your editor. The core of the agent's configuration consists of: amazon_bedrock_runtime_config: AWS connection settingstools: List of Bedrock agents and flows to expose as toolsagent_card: Agent capabilities and skills definition ","version":"Next","tagName":"h3"},{"title":"Example Configuration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#example-configuration","content":" Here's an annotated example based on the actual plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: aws-agent.log !include ../shared_config.yaml apps: - name: aws-agent-app app_base_path: . app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} supports_streaming: true agent_name: "AwsAgent" display_name: "AwsAgent Component" model: *general_model instruction: | You're AwsAgent responsible for handling user queries by interacting with Amazon Bedrock agents or flows. # AWS Connection Configuration amazon_bedrock_runtime_config: &amazon_bedrock_runtime_config endpoint_url: # Optional: Custom AWS endpoint URL boto3_config: region_name: "us-east-1" # AWS region where your Bedrock resources are located aws_access_key_id: # Your AWS access key (or use profiles/env vars) aws_secret_access_key: # Your AWS secret key tools: # Bedrock Agent Tool - tool_type: python component_module: sam_bedrock_agent.bedrock_agent component_base_path: . function_name: invoke_bedrock_agent tool_name: "text_transformer" # Customizable, Name exposed to the LLM tool_description: "Transforms text using the Text Transformer agent which summarizes the given text and extracts key points." # Customizable, Optional description tool_config: amazon_bedrock_runtime_config: *amazon_bedrock_runtime_config bedrock_agent_id: "XXXXXXXXXX" # Your actual Bedrock agent ID bedrock_agent_alias_id: "XXXXXXXXXX" # Your actual Bedrock agent alias ID allow_files: true # Whether to allow file uploads (5 files, 10MB total max) # Bedrock Flow Tool - tool_type: python component_module: sam_bedrock_agent.bedrock_flow component_base_path: . function_name: invoke_bedrock_flow tool_name: "poem_writer" # Name exposed to the LLM tool_config: amazon_bedrock_runtime_config: *amazon_bedrock_runtime_config bedrock_flow_id: "XXXXXXXXXX" # Your actual Bedrock flow ID bedrock_flow_alias_id: "XXXXXXXXXX" # Your actual Bedrock flow alias ID # Agent capabilities agent_card: description: "Agent that integrates with Amazon Bedrock agents and flows for various AI tasks." defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "text_transformer" name: "Text Transformer" description: "Transforms text using the Text Transformer agent." - id: "poem_writer" name: "Poem Writer" description: "Generates poems based on user input." # A2A Protocol settings agent_card_publishing: { interval_seconds: 10 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 30 ","version":"Next","tagName":"h3"},{"title":"Customizing Your Configuration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#customizing-your-configuration","content":" Follow these steps to customize your configuration: Configure AWS Connection: Set the region_name to the AWS region where your Bedrock resources are locatedChoose one of these authentication methods: Set aws_access_key_id and aws_secret_access_key directly in the config.Use AWS profiles by removing these fields and configuring your AWS CLI profile.Use environment variables (see Environment Variables section below). Check the boto3 documentation for more details. Configure Bedrock Agent Tools: For each Bedrock agent you want to expose, add a tool entry: Set a descriptive tool_name (for example, text_summarizer, content_generator).Provide a clear tool_description of what the agent does.Replace bedrock_agent_id with your actual Bedrock agent ID.Replace bedrock_agent_alias_id with your actual Bedrock agent alias ID.Set allow_files to true if your agent can process file uploads. Configure Bedrock Flow Tools: For each Bedrock flow you want to expose, add a tool entry: Set a descriptive tool_name for the flow.Provide a clear tool_description of what the flow does (optional).Replace bedrock_flow_id with your actual Bedrock flow ID.Replace bedrock_flow_alias_id with your actual Bedrock flow alias ID. Update Agent Card Skills: Update the agent_card.description to reflect the purpose of your Bedrock agent (This is what other agents see).For each tool you add, create a corresponding skill entry in the agent_card.skills section.Use the same id as the tool_name.Provide a user-friendly name and description. Update Agent Instructions: Modify the instruction field to provide clear guidance on how the agent should respond to user queries.This instruction is used by the Agent's LLM to understand its role and capabilities. info You must provide at least one Bedrock agent or flow tool. You can mix and match agents and flows in the same configuration. ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#environment-variables","content":" The Bedrock agent integration requires standard Solace connection variables and can use AWS environment variables for authentication. Required Solace Variables:​ SOLACE_BROKER_URL: URL of your Solace brokerSOLACE_BROKER_USERNAME: Username for Solace broker authenticationSOLACE_BROKER_PASSWORD: Password for Solace broker authenticationSOLACE_BROKER_VPN: Solace message VPN nameSOLACE_AGENT_MESH_NAMESPACE: Namespace for your Solace Agent Mesh project Optional AWS Variables:​ If you prefer to use environment variables for AWS authentication instead of configuration in the YAML file: AWS_ACCESS_KEY_ID: Your AWS access keyAWS_SECRET_ACCESS_KEY: Your AWS secret keyAWS_SESSION_TOKEN: If using temporary credentialsAWS_REGION or AWS_DEFAULT_REGION: AWS region for Bedrock services AWS Credentials Precedence AWS credentials are loaded in this order: Explicit credentials in the YAML configurationEnvironment variablesAWS configuration files (~/.aws/credentials)EC2/ECS instance profiles (if running on AWS) ","version":"Next","tagName":"h3"},{"title":"Running and Testing Your Integration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#running-and-testing-your-integration","content":" ","version":"Next","tagName":"h2"},{"title":"Starting Your Solace Agent Mesh Project​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#starting-your-solace-agent-mesh-project","content":" After configuring your Bedrock agent integration, run your Solace Agent Mesh project: sam run configs/agents/aws-agent.yaml This command starts the Bedrock agent with your specific configuration. ","version":"Next","tagName":"h3"},{"title":"Testing the Integration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#testing-the-integration","content":" You can test your Bedrock agent integration through any gateway in your Solace Agent Mesh project: Using the Web UI Gateway​ Ensure you have a Web UI gateway running (typically at http://localhost:8000)Start a conversation with your agentAsk a question that would trigger your Bedrock agent or flow Example: If you configured a Bedrock agent for text transformation: Transform this text: "The quick brown fox jumps over the lazy dog. The lazy dog did not chase the fox. The fox was brown and quick, while the dog was lazy and slow. Despite their differences, they both enjoyed the sunny day in the meadow." Example: If you configured a Bedrock flow for poem writing: Write a poem about a sunset over the ocean. Testing with File Uploads​ If you have enabled file uploads for your Bedrock agent (allow_files: true), you can test file processing: In the Web UI, use the file upload button to attach a supported fileInclude a prompt that references the file, such as "Analyze this document" or "Summarize the content of this file"The file is sent to the Bedrock agent along with your prompt Example with file upload: Please analyze the attached document and provide key insights. Supported File Types Bedrock agents support these file types for uploads: PDF documents (.pdf)Text files (.txt)Word documents (.doc, .docx)CSV files (.csv)Excel spreadsheets (.xls, .xlsx) There's a limit of 5 files with a total size of 10MB per request. ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues and Solutions​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#common-issues-and-solutions","content":" Authentication Errors​ Issue: "Unable to locate credentials" or "Access denied" errorsSolution: Verify your AWS credentials are correctly configuredCheck that your IAM user/role has the necessary permissionsTry using AWS CLI to test your credentials: aws bedrock list-foundation-models Configuration Errors​ Issue: "Invalid agent ID" or "Invalid flow ID" errorsSolution: Double-check your Bedrock agent and flow IDs in the configurationEnsure you've created aliases for your agents and flowsVerify the region in your configuration matches where your Bedrock resources are located Connection Issues​ Issue: Solace Agent Mesh can't connect to Bedrock servicesSolution: Check your network connectivityVerify that Bedrock services are available in your configured regionCheck for any VPC or firewall restrictions File Upload Issues​ Issue: Files aren't being processed by the Bedrock agentSolution: Verify allow_files is set to true in your configurationCheck that your file type is supportedEnsure the file size is under the 10MB limitCheck the model context length ","version":"Next","tagName":"h3"},{"title":"A2A Technical Migration Map","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map","content":"","keywords":"","version":"Next"},{"title":"1. Core Concept Changes​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#1-core-concept-changes","content":" Session vs. Context: The concept of a session, previously Task.sessionId, is now attached to the Message via Message.contextId. The Task also has a contextId, but it's primarily for grouping. Code that relied on Task.sessionId for conversation history must now use Message.contextId.Request/Response Structure: The structure of JSON-RPC requests and responses is now strictly defined by the SDK's Pydantic models (e.g., SendMessageRequest, JSONRPCResponse as a discriminated union). Direct dictionary manipulation is replaced by model instantiation and validation.Status Signaling: The practice of embedding custom status signals (e.g., tool_invocation_start) in the metadata field of a message is deprecated. The new standard is to use a dedicated, structured DataPart within a multi-part Message. ","version":"Next","tagName":"h2"},{"title":"2. Import & Type Mapping​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#2-import--type-mapping","content":" ","version":"Next","tagName":"h2"},{"title":"Import Paths​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#import-paths","content":" Old Import Path\tNew Import Path(s)\tNotessolace_agent_mesh.common.types\ta2a.types, solace_agent_mesh.common.a2a, solace_agent_mesh.common.a2a.types\tLegacy types are removed. Use SDK types and the a2a helper layer. solace_agent_mesh.common.a2a_protocol\tsolace_agent_mesh.common.a2a\tProtocol helpers (topic builders, etc.) are now in the main a2a helper package. ","version":"Next","tagName":"h3"},{"title":"Type Hints​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#type-hints","content":" Old Type Hint\tNew Type Hint\tNotesA2APart\tContentPart\tContentPart is an alias for Union[TextPart, DataPart, FilePart]. List[A2APart]\tList[ContentPart]\tStandard type hint for a list of message parts. FileContent\tUnion[FileWithBytes, FileWithUri]\tThe file attribute of a FilePart is now a discriminated union. ","version":"Next","tagName":"h3"},{"title":"3. Object Creation & Property Access Mapping​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#3-object-creation--property-access-mapping","content":" This table maps common legacy patterns to their new equivalents using the a2a helper layer. Action\tOld Pattern (Legacy)\tNew Pattern (a2a-sdk + Helpers)Part Creation Create Text Part\tTextPart(text=...)\ta2a.create_text_part(text=...) Create File Part (URI)\tFilePart(file=FileContent(name=..., uri=...))\ta2a.create_file_part_from_uri(uri=..., name=...) Create File Part (Bytes)\tFilePart(file=FileContent(bytes=...))\ta2a.create_file_part_from_bytes(content_bytes=...) Create Data Part\tDataPart(data=...)\ta2a.create_data_part(data=...) Task/Event Access Get Task ID\ttask.id\ta2a.get_task_id(task) Get Task Status\ttask.status.state\ta2a.get_task_status(task) Get Task Context ID\ttask.sessionId\ta2a.get_task_context_id(task) Get Event's Task ID\tevent.id\tevent.task_id Message Access Get Message Parts\tmessage.parts\ta2a.get_parts_from_message(message) Get Text from Message\t(manual loop over parts)\ta2a.get_text_from_message(message) Get Data Parts\t(manual loop over parts)\ta2a.get_data_parts_from_message(message) Error Access Get Error Message\terror.message\ta2a.get_error_message(error) Get Error Code\terror.code\ta2a.get_error_code(error) Get Error Data\terror.data\ta2a.get_error_data(error) Protocol/RPC Create RPC Success\tJSONRPCResponse(id=..., result=...)\ta2a.create_success_response(result=..., request_id=...) Create RPC Error\tJSONRPCResponse(id=..., error=...)\ta2a.create_error_response(error=..., request_id=...) Validate RPC Payload\tJSONRPCResponse(**payload)\tJSONRPCResponse.model_validate(payload) Topic Matching\t_topic_matches_subscription(...)\ta2a.topic_matches_subscription(...) Extract Task ID from Topic\t_extract_task_id_from_topic(...)\ta2a.extract_task_id_from_topic(...) ","version":"Next","tagName":"h2"},{"title":"4. Full Method Examples​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#4-full-method-examples","content":" These examples provide larger, "before and after" contexts for the refactoring patterns. ","version":"Next","tagName":"h2"},{"title":"Example 1: _translate_external_input​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-1-_translate_external_input","content":" Before: from solace_agent_mesh.common.types import Part as A2APart, TextPart, FilePart, FileContent async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[A2APart], Dict[str, Any]]: # ... a2a_parts: List[A2APart] = [] # ... artifact_uri = f"artifact://{self.gateway_id}/{user_id}/{a2a_session_id}/{filename}?version={version}" file_content_a2a = FileContent(name=filename, mimeType=mime_type, uri=artifact_uri) a2a_parts.append(FilePart(file=file_content_a2a)) # ... a2a_parts.append(TextPart(text=processed_text_for_a2a)) return "agent_name", a2a_parts, {} After: from solace_agent_mesh.common import a2a from solace_agent_mesh.common.a2a import ContentPart async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[ContentPart], Dict[str, Any]]: # ... a2a_parts: List[ContentPart] = [] # ... artifact_uri = f"artifact://{self.gateway_id}/{user_id}/{a2a_session_id}/{filename}?version={version}" file_part = a2a.create_file_part_from_uri(uri=artifact_uri, name=filename, mime_type=mime_type) a2a_parts.append(file_part) # ... text_part = a2a.create_text_part(text=processed_text_for_a2a) a2a_parts.append(text_part) return "agent_name", a2a_parts, {} ","version":"Next","tagName":"h3"},{"title":"Example 2: _send_update_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-2-_send_update_to_external","content":" Before: from solace_agent_mesh.common.types import TaskStatusUpdateEvent, TextPart, DataPart async def _send_update_to_external(self, context: Dict, event_data: TaskStatusUpdateEvent, is_final: bool) -> None: task_id = event_data.id # ... if event_data.status and event_data.status.message and event_data.status.message.parts: for part in event_data.status.message.parts: if isinstance(part, TextPart): # process part.text elif isinstance(part, DataPart): # process part.data After: from a2a.types import TaskStatusUpdateEvent, TextPart, DataPart from solace_agent_mesh.common import a2a async def _send_update_to_external(self, context: Dict, event_data: TaskStatusUpdateEvent, is_final: bool) -> None: task_id = event_data.task_id # ... message = a2a.get_message_from_status_update(event_data) if message: parts = a2a.get_parts_from_message(message) for part in parts: if isinstance(part, TextPart): # process part.text elif isinstance(part, DataPart): # process part.data ","version":"Next","tagName":"h3"},{"title":"Example 3: _send_final_response_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-3-_send_final_response_to_external","content":" Before: from solace_agent_mesh.common.types import Task, TaskState async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = task_data.id if task_data.status.state == TaskState.FAILED: # ... After: from a2a.types import Task, TaskState from solace_agent_mesh.common import a2a async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = a2a.get_task_id(task_data) task_status = a2a.get_task_status(task_data) if task_status == TaskState.failed: # ... ","version":"Next","tagName":"h3"},{"title":"Example 4: _send_error_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-4-_send_error_to_external","content":" Before: from solace_agent_mesh.common.types import JSONRPCError async def _send_error_to_external(self, context: Dict, error_data: JSONRPCError) -> None: error_text = f"Error: {error_data.message} (Code: {error_data.code})" if error_data.data: # process error_data.data After: from a2a.types import JSONRPCError from solace_agent_mesh.common import a2a async def _send_error_to_external(self, context: Dict, error_data: JSONRPCError) -> None: error_message = a2a.get_error_message(error_data) error_code = a2a.get_error_code(error_data) error_details = a2a.get_error_data(error_data) error_text = f"Error: {error_message} (Code: {error_code})" if error_details: # process error_details ","version":"Next","tagName":"h3"},{"title":"Event Mesh Gateway","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway","content":"","keywords":"","version":"Next"},{"title":"Benefits of Integrating with an Event Mesh​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#benefits-of-integrating-with-an-event-mesh","content":" Seamless Communication: Solace Agent Mesh can subscribe to and publish events across the entire event meshEvent-Driven Automation: Intelligent event processing based on patterns and AI-driven insightsScalability: Solace Agent Mesh can dynamically participate in large-scale event-driven systems The Event Mesh Gateway connects Solace Agent Mesh to your existing event mesh infrastructure. Through its asynchronous interfaces, applications within your event mesh can seamlessly access and utilize Solace Agent Mesh capabilities. This tutorial shows you how to build an Event Mesh Gateway that automatically generates and adds concise summaries to Jira bug reports, making them easier to understand at a glance. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#prerequisites","content":" This tutorial assumes you have an existing Jira application integrated with your event mesh that: Publishes a "jira_created" event to topic jira/issue/created/<jira_id> when a new Jira issue is createdListens for "jira_update" events on topic jira/issue/update to update existing issues Create an Event Mesh Gateway that: Monitors for new Jira issuesAutomatically generates a concise summaryCreates an event to update the original Jira issue with this summary This creates a streamlined workflow where bug reports are automatically enhanced with clear, AI-generated summaries. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and the Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. For this tutorial, you need to create or use an existing Solace Event Broker or event mesh created using PubSub+ event brokers. ","version":"Next","tagName":"h2"},{"title":"Adding the Event Mesh Gateway Plugin​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#adding-the-event-mesh-gateway-plugin","content":" Once you have your project set up, add the Event Mesh Gateway plugin: sam plugin add jira-event-mesh --plugin sam-event-mesh-gateway You can use any name for your agent, in this tutorial we use jira-event-mesh. This command: Installs the sam-event-mesh-gateway pluginCreates a new gateway configuration named jira-event-mesh in your configs/gateways/ directory Configuring the Event Mesh Gateway​ After adding the plugin, you can see a new configuration file in configs/gateways/jira-event-mesh.yaml. This file contains the gateway configuration that needs to be customized for your Jira integration use case. Environment Variables​ First, set up the required environment variables for the data plane connection: # Data plane Solace broker connection (can be same or different from control plane) export JIRA_EVENT_MESH_SOLACE_BROKER_URL="ws://localhost:8080" export JIRA_EVENT_MESH_SOLACE_BROKER_VPN="default" export JIRA_EVENT_MESH_SOLACE_BROKER_USERNAME="default" export JIRA_EVENT_MESH_SOLACE_BROKER_PASSWORD="default" ","version":"Next","tagName":"h2"},{"title":"Gateway Configuration​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#gateway-configuration","content":" The main configuration includes several key sections: Event Handlers​ Configure the event handler to listen for new Jira issues and generate summaries: event_handlers: - name: "jira_issue_handler" subscriptions: - topic: "jira/issue/created/>" qos: 1 input_expression: "template:Create a concise summary for the newly created Jira issue: Title: {{text://input.payload:title}}, Body: {{text://input.payload:body}}, ID: {{text://input.payload:id}}. Return a JSON object with fields 'id', 'type' (value should be 'summary'), and 'summary'." payload_encoding: "utf-8" payload_format: "json" target_agent_name: "OrchestratorAgent" on_success: "jira_summary_handler" on_error: "error_response_handler" forward_context: jira_id: "input.payload:id" correlation_id: "input.user_properties:correlation_id" Output Handlers​ Configure output handlers to publish the summary back to the event mesh: output_handlers: - name: "jira_summary_handler" topic_expression: "static:jira/issue/update" payload_expression: "task_response:text" payload_encoding: "utf-8" payload_format: "json" - name: "error_response_handler" topic_expression: "template:jira/issue/error/{{text://user_data.forward_context:jira_id}}" payload_expression: "task_response:a2a_task_response.error" payload_encoding: "utf-8" payload_format: "json" ","version":"Next","tagName":"h3"},{"title":"Complete Configuration Example​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#complete-configuration-example","content":" Here is a complete configuration file based on the plugin template: log: stdout_log_level: INFO log_file_level: DEBUG log_file: jira-event-mesh.log !include ../shared_config.yaml apps: - name: jira-event-mesh-app app_module: sam_event_mesh_gateway.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} gateway_id: "jira-event-mesh-gw-01" artifact_service: *default_artifact_service authorization_service: type: "none" # Or "default_rbac" default_user_identity: "anonymous_event_mesh_user" # If no identity from event # Data plane connection event_mesh_broker_config: broker_url: ${JIRA_EVENT_MESH_SOLACE_BROKER_URL} broker_vpn: ${JIRA_EVENT_MESH_SOLACE_BROKER_VPN} broker_username: ${JIRA_EVENT_MESH_SOLACE_BROKER_USERNAME} broker_password: ${JIRA_EVENT_MESH_SOLACE_BROKER_PASSWORD} event_handlers: - name: "jira_issue_handler" subscriptions: - topic: "jira/issue/created/>" qos: 1 input_expression: "template:Create a concise summary for the newly created Jira issue: Title: {{text://input.payload:title}}, Body: {{text://input.payload:body}}, ID: {{text://input.payload:id}}. Return a JSON object with fields 'id', 'type' (value should be 'summary'), and 'summary'." payload_encoding: "utf-8" payload_format: "json" target_agent_name: "OrchestratorAgent" on_success: "jira_summary_handler" on_error: "error_response_handler" forward_context: jira_id: "input.payload:id" output_handlers: - name: "jira_summary_handler" topic_expression: "static:jira/issue/update" payload_expression: "task_response:text" payload_encoding: "utf-8" payload_format: "json" - name: "error_response_handler" topic_expression: "template:jira/issue/error/{{text://user_data.forward_context:jira_id}}" payload_expression: "task_response:a2a_task_response.error" payload_encoding: "utf-8" payload_format: "json" ","version":"Next","tagName":"h3"},{"title":"Running the Event Mesh Gateway​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#running-the-event-mesh-gateway","content":" Now you can run the Event Mesh Gateway: sam run configs/gateways/jira-event-mesh.yaml The gateway: Connects to both the A2A control plane and the data plane event meshSubscribes to the configured topics on the data planeStarts processing incoming events and routing them to agents ","version":"Next","tagName":"h2"},{"title":"Testing the Event Mesh Gateway​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#testing-the-event-mesh-gateway","content":" Now that the system is running, let's test the Event Mesh Gateway. ","version":"Next","tagName":"h2"},{"title":"Using Solace PubSub+ Broker Manager​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#using-solace-pubsub-broker-manager","content":" Open the Try Me! tab of the Solace PubSub+ Broker Manager Connect both the Publisher and Subscriber panels by clicking their respective Connect buttons In the Subscriber panel: Enter jira/issue/update in the Topic Subscriber fieldClick Subscribe In the Publisher panel: Use the topic jira/issue/created/JIRA-143321In the Message Content field, enter: { "id": "JIRA-143321", "title": "Exception when reading customer record", "body": "I got a DatabaseReadException when trying to get the data for customer ABC. The error indicated that the customer didn't exist, while they are our biggest customer!" } Click Publish After a few seconds, you can see a new message in the Subscriber messages with the topic jira/issue/update and a body similar to: { "id": "JIRA-143321", "type": "summary", "summary": "Database read error: Unable to retrieve record for key customer ABC despite confirmed existence" } ","version":"Next","tagName":"h3"},{"title":"Advanced Features​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#advanced-features","content":" The Event Mesh Gateway supports several advanced features: ","version":"Next","tagName":"h2"},{"title":"Artifact Processing​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#artifact-processing","content":" You can configure the gateway to automatically create artifacts from incoming message payloads before sending them to agents. This is useful for processing files, images, or other binary data embedded in events. ","version":"Next","tagName":"h3"},{"title":"Dynamic Agent Routing​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#dynamic-agent-routing","content":" Instead of using a static target_agent_name, you can use target_agent_name_expression to dynamically determine which agent should process each event based on the message content. ","version":"Next","tagName":"h3"},{"title":"Context Forwarding​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#context-forwarding","content":" The forward_context configuration allows you to extract data from incoming messages and make it available when generating outgoing responses, enabling request-reply patterns and correlation tracking. ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#error-handling","content":" Configure separate output handlers for success and error scenarios to ensure proper error reporting and system monitoring. ","version":"Next","tagName":"h3"},{"title":"MCP Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration","content":"","keywords":"","version":"Next"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#setting-up-the-environment","content":" You must install Solace Agent Mesh and Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. For this tutorial using the filesystem MCP server, you also need Node.js and NPM installed. ","version":"Next","tagName":"h2"},{"title":"Adding MCP Tools to an Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#adding-mcp-tools-to-an-agent","content":" MCP integration is accomplished by adding MCP tools directly to your agent configuration. There are three main connection types supported: ","version":"Next","tagName":"h2"},{"title":"1. Stdio Connection (Local MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#1-stdio-connection-local-mcp-servers","content":" This is the most common method for connecting to MCP servers that run as local processes: tools: - tool_type: mcp connection_params: type: stdio command: "npx" args: - "-y" - "@modelcontextprotocol/server-filesystem" - "/tmp/samv2" ","version":"Next","tagName":"h3"},{"title":"2. SSE Connection (Remote MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#2-sse-connection-remote-mcp-servers","content":" For connecting to remote MCP servers using Server-Sent Events: tools: - tool_type: mcp connection_params: type: sse url: "https://mcp.example.com/v1/sse" headers: Authorization: "Bearer ${MCP_AUTH_TOKEN}" ","version":"Next","tagName":"h3"},{"title":"3. Docker Connection (Containerized MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#3-docker-connection-containerized-mcp-servers","content":" For running MCP servers in Docker containers: tools: - tool_type: mcp connection_params: type: stdio command: "docker" args: - "run" - "-i" - "--rm" - "-e" - "API_KEY" - "mcp-server-image:latest" environment_variables: API_KEY: ${MY_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Complete Example: Filesystem MCP Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#complete-example-filesystem-mcp-agent","content":" Here is a complete example of an agent that uses the filesystem MCP server: # configs/agents/filesystem_agent.yaml log: stdout_log_level: INFO log_file_level: DEBUG log_file: filesystem_agent.log !include ../shared_config.yaml apps: - name: filesystem_mcp_agent_app app_base_path: . app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} supports_streaming: true agent_name: "FileSystemAgent" display_name: "File System" model: *general_model instruction: | You can interact with the local filesystem using MCP tools. Use the available tools to read, write, and manage files as requested. tools: - tool_type: mcp connection_params: type: stdio command: "npx" args: - "-y" - "@modelcontextprotocol/server-filesystem" - "/tmp/samv2" - tool_type: builtin-group group_name: "artifact_management" session_service: *default_session_service artifact_service: *default_artifact_service # Agent discovery and communication agent_card: description: "An agent that interacts with the local filesystem via MCP." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: [] agent_card_publishing: { interval_seconds: 10 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 30 ","version":"Next","tagName":"h2"},{"title":"Configuration Options​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#configuration-options","content":" ","version":"Next","tagName":"h2"},{"title":"Tool-Specific Configuration​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#tool-specific-configuration","content":" You can limit which tools from an MCP server are available by specifying a specific tool name: tools: - tool_type: mcp tool_name: "read_file" # Only expose the read_file tool connection_params: type: stdio command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/samv2"] ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#environment-variables","content":" Pass environment variables to MCP servers using the environment_variables block: tools: - tool_type: mcp connection_params: type: stdio command: "my-mcp-server" environment_variables: API_KEY: ${MY_API_KEY} DEBUG_MODE: "true" CONFIG_PATH: "/etc/myconfig" ","version":"Next","tagName":"h3"},{"title":"Running Your MCP-Enabled Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#running-your-mcp-enabled-agent","content":" Create the working directory (for filesystem example): mkdir -p /tmp/samv2 echo "Hello MCP!" > /tmp/samv2/test.txt Set required environment variables: export NAMESPACE="myorg/dev" export SOLACE_BROKER_URL="ws://localhost:8080" # ... other Solace broker settings Run the agent: sam run configs/agents/filesystem_agent.yaml ","version":"Next","tagName":"h2"},{"title":"How MCP Integration Works​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#how-mcp-integration-works","content":" When your agent starts: Connection: The framework establishes a connection to the MCP server using the specified connection parametersDiscovery: It queries the MCP server for available tools, resources, and promptsRegistration: Available capabilities are registered as agent tools.Communication: The agent can use these tools through the standard A2A protocol, with the framework handling MCP protocol translation ","version":"Next","tagName":"h2"},{"title":"Testing Your MCP Integration​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#testing-your-mcp-integration","content":" Once your MCP-enabled agent is running, you can test it through any gateway in your project (such as the Web UI gateway): Access your gateway (for example, Web UI at http://localhost:8000)Send a request to test the MCP functionality: "List the files in the directory""Create a simple text file with some content""Read the contents of test.txt" The agent uses the MCP tools to interact with the filesystem and provide responses through the A2A protocol. ","version":"Next","tagName":"h2"},{"title":"MongoDB Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration","content":"","keywords":"","version":"Next"},{"title":"Prerequisites​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#prerequisites","content":" Before starting this tutorial, ensure that you have installed and configured Solace Agent Mesh: Installed Solace Agent Mesh and the Solace Agent Mesh CLICreated a new Solace Agent Mesh projectAccess to a MongoDB database (local or remote) ","version":"Next","tagName":"h2"},{"title":"Adding the MongoDB Plugin​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#adding-the-mongodb-plugin","content":" Add the MongoDB plugin to your Solace Agent Mesh project: sam plugin add coffee-shop-mongo --plugin sam-mongodb You can use any name for your agent, in this tutorial we use coffee-shop-mongo. This command: Installs the sam-mongodb pluginCreates a new agent configuration file at configs/agents/coffee-shop-mongo.yaml Setting Up Your MongoDB Database​ This tutorial assumes you have a MongoDB database with a collection containing coffee shop data. You can use any MongoDB database, but here is an example structure for a coffee shop: Example Document Structure​ { "_id": "64a1b2c3d4e5f6789012345", "order_id": "ORD-2024-001", "customer": { "name": "John Doe", "email": "john.doe@example.com", "phone": "+1-555-0123" }, "items": [ { "product": "Espresso", "quantity": 2, "price": 3.50, "category": "Coffee" }, { "product": "Croissant", "quantity": 1, "price": 2.75, "category": "Pastry" } ], "total_amount": 9.75, "order_date": "2024-01-15T10:30:00Z", "status": "completed", "payment_method": "credit_card", "location": "Downtown Store" } ","version":"Next","tagName":"h2"},{"title":"Configuring the Agent​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#configuring-the-agent","content":" Open the configs/agents/coffee-shop-mongo.yaml file and modify the agent_init_function.config section to connect to your MongoDB database. Here is what you need to modify in the configuration file: # Find the agent_init_function section and update the config: agent_init_function: module: "sam_mongodb.lifecycle" name: "initialize_mongo_agent" config: db_host: "${COFFEE_SHOP_MONGO_MONGO_HOST}" db_port: ${COFFEE_SHOP_MONGO_MONGO_PORT} db_user: "${COFFEE_SHOP_MONGO_MONGO_USER}" db_password: "${COFFEE_SHOP_MONGO_MONGO_PASSWORD}" db_name: "${COFFEE_SHOP_MONGO_MONGO_DB}" database_collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" database_purpose: "${COFFEE_SHOP_MONGO_DB_PURPOSE}" data_description: "${COFFEE_SHOP_MONGO_DB_DESCRIPTION}" auto_detect_schema: true max_inline_results: 10 Setting the Environment Variables​ The MongoDB agent requires several environment variables. Create or update your .env file with the following variables: # MongoDB Connection Settings COFFEE_SHOP_MONGO_MONGO_HOST=localhost COFFEE_SHOP_MONGO_MONGO_PORT=27017 COFFEE_SHOP_MONGO_MONGO_USER=your_username COFFEE_SHOP_MONGO_MONGO_PASSWORD=your_password COFFEE_SHOP_MONGO_MONGO_DB=coffee_shop COFFEE_SHOP_MONGO_MONGO_COLLECTION=orders # Database Description COFFEE_SHOP_MONGO_DB_PURPOSE="Coffee shop order management database" COFFEE_SHOP_MONGO_DB_DESCRIPTION="Contains customer orders, product information, sales data, and transaction history for a coffee shop business." # Optional Settings AUTO_DETECT_SCHEMA=true MAX_INLINE_RESULTS=10 MongoDB Connection Options​ Local MongoDB: Use localhost as the host and default port 27017MongoDB Atlas: Use your Atlas connection string formatAuthentication: Provide username and password if your MongoDB requires authenticationNo Authentication: Leave username and password empty for local development databases ","version":"Next","tagName":"h2"},{"title":"Running the Agent​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#running-the-agent","content":" Now you can start your MongoDB agent: sam run configs/agents/coffee-shop-mongo.yaml The agent: Connects to the A2A control planeInitializes the MongoDB connectionDetects the database schema automaticallyRegisters its capabilities with the agent discovery system ","version":"Next","tagName":"h2"},{"title":"Interacting with the Database​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#interacting-with-the-database","content":" After your MongoDB agent is running, you can interact with the database through any gateway in your Solace Agent Mesh project (such as the Web UI gateway at http://localhost:8000). You can ask natural language questions about your MongoDB database, such as: "How many orders were placed today?""What are the most popular coffee products?""Show me all orders from customers in New York""What's the average order value this month?""Find all incomplete orders""Group orders by payment method and show totals" Try creating reports by asking questions such as: "Create a sales report for the last 7 days""Generate a summary of customer preferences""Show me the top 10 customers by total spending" The MongoDB agent converts your natural language questions into MongoDB aggregation pipelines, executes them against the database, and returns the results. For large result sets, the agent automatically saves the results as artifacts that you can download. ","version":"Next","tagName":"h2"},{"title":"Advanced Configuration​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#advanced-configuration","content":" The MongoDB plugin supports many advanced configuration options. Here is a complete example based on the plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: coffee-shop-mongo.log !include ../shared_config.yaml apps: - name: coffee-shop-mongo-app app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} agent_name: "CoffeeShopMongo" display_name: "Coffee Shop MongoDB Agent" supports_streaming: false model: *general_model instruction: | You are an expert MongoDB assistant for the coffee shop database. Your primary goal is to translate user questions into accurate MongoDB aggregation pipelines. When asked to query the database, generate the pipeline and call the query tool. If the tool returns an error, analyze the error message and the original pipeline, then try to correct the pipeline and call the tool again. Always provide clear explanations of the results you find. # Agent initialization with database setup agent_init_function: module: "sam_mongodb.lifecycle" name: "initialize_mongo_agent" config: db_host: "${COFFEE_SHOP_MONGO_MONGO_HOST}" db_port: ${COFFEE_SHOP_MONGO_MONGO_PORT} db_user: "${COFFEE_SHOP_MONGO_MONGO_USER}" db_password: "${COFFEE_SHOP_MONGO_MONGO_PASSWORD}" db_name: "${COFFEE_SHOP_MONGO_MONGO_DB}" database_collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" database_purpose: "${COFFEE_SHOP_MONGO_DB_PURPOSE}" data_description: "${COFFEE_SHOP_MONGO_DB_DESCRIPTION}" auto_detect_schema: true max_inline_results: 10 agent_cleanup_function: module: "sam_mongodb.lifecycle" name: "cleanup_mongo_agent_resources" # MongoDB query tool tools: - tool_type: builtin-group group_name: "artifact_management" - tool_type: builtin-group group_name: "data_analysis" - tool_type: python component_module: "sam_mongodb.search_query" function_name: "mongo_query" tool_config: collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" session_service: *default_session_service artifact_service: *default_artifact_service # Artifact handling artifact_handling_mode: "reference" enable_embed_resolution: true enable_artifact_content_instruction: true # Agent capabilities - This is what other agents see during discovery agent_card: description: "Coffee Shop MongoDB Agent - Access to comprehensive coffee shop order data including customer information, product details, sales transactions, and order history. Can answer questions about sales analytics, customer behavior, product performance, and business metrics." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "mongo_query" name: "Coffee Shop MongoDB Query" description: "Queries coffee shop MongoDB database containing customer orders, product catalog, payment transactions, and order history using aggregation pipelines." # A2A Protocol settings agent_card_publishing: { interval_seconds: 30 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 60 ","version":"Next","tagName":"h2"},{"title":"Customizing the Agent Card​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#customizing-the-agent-card","content":" The agent_card section is crucial as it defines how other agents in your Solace Agent Mesh ecosystem discover and understand this MongoDB agent's capabilities. When other agents use agent discovery, they can see this information to decide whether to delegate tasks to your database agent. ","version":"Next","tagName":"h2"},{"title":"Key Agent Card Elements​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#key-agent-card-elements","content":" Description: Clearly describe what data the agent has access to and what types of questions it can answerSkills: List specific capabilities with concrete examples that show the scope of data availableData Context: Mention the business domain, data types, and scope of information available ","version":"Next","tagName":"h3"},{"title":"Example of a Well-Configured Agent Card​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#example-of-a-well-configured-agent-card","content":" agent_card: description: "Coffee Shop MongoDB Agent - Access to comprehensive coffee shop order data including customer information, product details, sales transactions, and order history. Can answer questions about sales analytics, customer behavior, product performance, and business metrics." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "mongo_query" name: "Coffee Shop MongoDB Query" description: "Queries coffee shop MongoDB database containing customer orders, product catalog, payment transactions, and order history using aggregation pipelines." This detailed information helps other agents understand: What business domain this agent covers (coffee shop operations)What types of data are available (orders, customers, products, payments)What kinds of questions can be answered (analytics, behavior, performance, metrics)Specific examples of queries that work well with MongoDB aggregation pipelines When configuring your own MongoDB agent, customize the description and examples to match your specific data structure and use cases. ","version":"Next","tagName":"h3"},{"title":"MongoDB Query Features​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#mongodb-query-features","content":" The MongoDB agent supports various types of queries through natural language: ","version":"Next","tagName":"h2"},{"title":"Aggregation Queries​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#aggregation-queries","content":" "Show me the top 5 products by sales volume""Calculate the average order value by customer segment""Group orders by month and show revenue trends" ","version":"Next","tagName":"h3"},{"title":"Filtering and Search​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#filtering-and-search","content":" "Find all orders placed in the last 24 hours""Show me orders with a total amount greater than $50""Find customers who ordered espresso drinks" ","version":"Next","tagName":"h3"},{"title":"Complex Analytics​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#complex-analytics","content":" "What's the conversion rate from browsing to purchase?""Show me the busiest hours of the day""Calculate customer lifetime value" ","version":"Next","tagName":"h3"},{"title":"Output Formats​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#output-formats","content":" The agent supports multiple output formats: JSON: Default format, good for structured dataYAML: Human-readable formatCSV: Suitable for spreadsheet importMarkdown: Formatted for documentation You can specify the format in your query: "Show me today's sales in CSV format" ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues and Solutions​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#common-issues-and-solutions","content":" Connection Errors​ Issue: "Unable to connect to MongoDB" errorsSolution: Verify your MongoDB server is runningCheck connection parameters (host, port, credentials)Ensure network connectivity and firewall settingsTest connection using MongoDB client tools Authentication Errors​ Issue: "Authentication failed" errorsSolution: Verify username and password are correctCheck that the user has appropriate database permissionsEnsure the authentication database is correct Query Errors​ Issue: "Invalid aggregation pipeline" errorsSolution: The agent automatically retries with corrected pipelinesCheck that your natural language query is clear and specificVerify that referenced fields exist in your collection Schema Detection Issues​ Issue: Agent does not understand your data structureSolution: Ensure auto_detect_schema is set to trueProvide detailed data_description in your configurationCheck that your collection has representative sample documents ","version":"Next","tagName":"h3"},{"title":"RAG Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration","content":"","keywords":"","version":"Next"},{"title":"What is Solace Agent Mesh RAG?​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#what-is-solace-agent-mesh-rag","content":" The Solace Agent Mesh RAG plugin enhances your agents with the ability to perform retrieval-augmented generation. This means the agent can: Scan documents from various sources (local filesystem, Google Drive, etc.).Preprocess and split the text into manageable chunks.Embed these chunks into vectors and store them in a vector database.Retrieve relevant chunks of text based on a user's query.Generate an answer using a large language model (LLM) augmented with the retrieved information. This allows you to build agents that can answer questions about your own private data. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#prerequisites","content":" Before you begin, ensure you have: Installed Solace Agent Mesh and the Solace Agent Mesh CLI.Created a new Solace Agent Mesh project.Access to a vector database (for example, Qdrant, Chroma, and Pinecone).Access to an LLM for generation and an embedding model.A directory with some documents for the agent to ingest. ","version":"Next","tagName":"h2"},{"title":"Adding the RAG Plugin​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#adding-the-rag-plugin","content":" To add the RAG plugin to your Solace Agent Mesh project, run the following command: sam plugin add my-rag-agent --plugin sam-rag Replace my-rag-agent with your preferred agent name. This command: Installs the sam-rag plugin.Creates a new agent configuration file at configs/agents/my-rag-agent.yaml. ","version":"Next","tagName":"h2"},{"title":"Configuring the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#configuring-the-rag-agent","content":" The RAG agent requires a detailed configuration. Open configs/agents/my-rag-agent.yaml to configure the following sections: ","version":"Next","tagName":"h2"},{"title":"Shared Configuration​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#shared-configuration","content":" Like other agents, the RAG agent needs a connection to the Solace broker and a configured LLM. This is typically done in a shared_config.yaml file. # configs/shared_config.yaml shared_config: - broker_connection: &broker_connection dev_mode: ${SOLACE_DEV_MODE, false} broker_url: ${SOLACE_BROKER_URL, ws://localhost:8080} broker_username: ${SOLACE_BROKER_USERNAME, default} broker_password: ${SOLACE_BROKER_PASSWORD, default} broker_vpn: ${SOLACE_BROKER_VPN, default} temporary_queue: ${USE_TEMPORARY_QUEUES, true} - models: general: &general_model model: ${LLM_SERVICE_GENERAL_MODEL_NAME} api_base: ${LLM_SERVICE_ENDPOINT} api_key: ${LLM_SERVICE_API_KEY} ","version":"Next","tagName":"h3"},{"title":"RAG Pipeline Configuration​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#rag-pipeline-configuration","content":" The RAG pipeline has several stages, each with its own configuration block within the app_config section of your my-rag-agent.yaml file. 1. Scanner Configuration​ The scanner discovers documents to be ingested. You can configure it to scan a local filesystem or cloud sources. Local Filesystem Example: scanner: batch: true use_memory_storage: true source: type: filesystem directories: - "/path/to/your/documents" # Important: Replace with your actual document directory path filters: file_formats: - ".txt" - ".pdf" - ".md" Multi-Cloud Source Example:You can also configure multiple sources, including Google Drive, OneDrive, and S3. scanner: batch: true use_memory_storage: true sources: - type: filesystem directories: ["${LOCAL_DOCUMENTS_PATH}"] - type: google_drive credentials_path: "${GOOGLE_DRIVE_CREDENTIALS_PATH}" folders: - folder_id: "${GOOGLE_DRIVE_FOLDER_ID_1}" name: "Documents" recursive: true 2. Preprocessor Configuration​ The preprocessor cleans the text extracted from documents. preprocessor: default_preprocessor: type: enhanced params: lowercase: true normalize_whitespace: true remove_urls: true preprocessors: pdf: type: document params: lowercase: true normalize_whitespace: true remove_non_ascii: true remove_urls: true 3. Splitter Configuration​ The splitter breaks down large documents into smaller chunks. Different splitters are available for different file types. splitter: default_splitter: type: recursive_character params: chunk_size: 2048 chunk_overlap: 400 splitters: markdown: type: markdown params: chunk_size: 2048 chunk_overlap: 400 pdf: type: token params: chunk_size: 500 chunk_overlap: 100 4. Embedding Configuration​ This section defines the model used to create vector embeddings from the text chunks. embedding: embedder_type: "openai" embedder_params: model: "${OPENAI_EMBEDDING_MODEL}" api_key: "${OPENAI_API_KEY}" api_base: "${OPENAI_API_ENDPOINT}" normalize_embeddings: true 5. Vector Database Configuration​ Configure the connection to your vector database where the embeddings are stored. Qdrant Example: vector_db: db_type: "qdrant" db_params: url: "${QDRANT_URL}" api_key: "${QDRANT_API_KEY}" collection_name: "${QDRANT_COLLECTION}" embedding_dimension: ${QDRANT_EMBEDDING_DIMENSION} Chroma Example: vector_db: db_type: "chroma" db_params: host: "${CHROMA_HOST}" port: "${CHROMA_PORT}" collection_name: "${CHROMA_COLLECTION}" 6. LLM Configuration​ Configure the LLM that is used to generate answers based on the retrieved context. llm: load_balancer: - model_name: "gpt-4o" litellm_params: model: "openai/${OPENAI_MODEL_NAME}" api_key: "${OPENAI_API_KEY}" api_base: "${OPENAI_API_ENDPOINT}" 7. Retrieval Configuration​ This defines how many document chunks are retrieved to answer a query. retrieval: top_k: 7 ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#environment-variables","content":" The RAG agent relies heavily on environment variables. Here are some of the most important ones you'll need to set in your .env file: # Solace Connection SOLACE_BROKER_URL=ws://localhost:8080 SOLACE_BROKER_VPN=default SOLACE_BROKER_USERNAME=default SOLACE_BROKER_PASSWORD=default NAMESPACE=my-org/dev # LLM and Embedding Models OPENAI_API_KEY="your-openai-api-key" OPENAI_API_ENDPOINT="your-openai-api-endpoint" OPENAI_MODEL_NAME="model name. E.g., gpt-4o" OPENAI_EMBEDDING_MODEL="embedding model name. E.g., text-embedding-3-small" # Vector Database (Qdrant example) QDRANT_URL="Qdrant url" QDRANT_API_KEY="API key" QDRANT_COLLECTION="my-rag-collection" QDRANT_EMBEDDING_DIMENSION=1536 # Depends on your embedding model # Scanner LOCAL_DOCUMENTS_PATH="./my_documents" # Relative path to your documents folder Create a directory named my_documents in your project root and place some text or markdown files inside it. ","version":"Next","tagName":"h3"},{"title":"Running the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#running-the-rag-agent","content":" Once you have configured your agent and set the environment variables, you can run it: sam run configs/agents/my-rag-agent.yaml 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. ","version":"Next","tagName":"h2"},{"title":"Testing the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#testing-the-rag-agent","content":" Once your agent is running, you can test its retrieval capabilities and ingest new documents. ","version":"Next","tagName":"h2"},{"title":"Ingesting Documents​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#ingesting-documents","content":" There are two primary ways to ingest documents into your RAG agent's knowledge base: Option 1: Automatic Scanning (Batch Ingestion)​ This method uses the configured scanner component. The agent automatically ingests documents from the directories specified in your configuration upon startup. Step 1: Create a Document First, create a simple text file named sam_features.txt and add some content to it. For example: Solace Agent Mesh is a powerful framework for building AI agents. Key features of Solace Agent Mesh include: - A flexible plugin architecture. - Integration with various LLMs and vector databases. - Scalable gateways for different communication protocols. - An event-driven design based on Solace PubSub+. Step 2: Place the Document in the Scanned Directory In the "Environment Variables" section, we configured LOCAL_DOCUMENTS_PATH to point to a directory (e.g., ./my_documents). Create this directory in your project's root folder if you haven't already, and move your sam_features.txt file into it. mkdir -p my_documents mv sam_features.txt my_documents/ Step 3: Run the Agent to Trigger Ingestion 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: sam run configs/agents/my-rag-agent.yaml 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. Option 2: Manual Upload via Gateway​ 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. Step 1: Start the RAG Agent and Web UI Ensure both your RAG agent and the Web UI gateway are running. Step 2: Upload a Document in the Web UI Open the Web UI (usually at http://localhost:8000, or check your gateway configuration for the correct URL) and start a chat with your RAG agent.Use the file attachment button to select a document from your local machine.Send a prompt along with the file, instructing the agent to ingest it. For example: "Please ingest the attached document into your knowledge base." The RAG agent uses its 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. Step 3: Confirm Ingestion After the agent confirms that the document has been ingested, you can immediately ask questions about its content. ","version":"Next","tagName":"h3"},{"title":"Querying the Knowledge Base​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#querying-the-knowledge-base","content":" You can interact with your RAG agent through any gateway, such as the Web UI gateway. Make sure you have a Web UI gateway running (or add one to your project).Open the Web UI (usually at http://localhost:8000).Start a conversation with my-rag-agent.Ask a question related to the content of the documents you provided during the initial scan. For example, if you have a document about product features, you could ask: "What are the key features of Product X?" The agent searches its knowledge base, finds the relevant information, and generates an answer based on the content of your documents. ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#troubleshooting","content":" Connection Errors: Double-check all your URLs, API keys, and credentials for your LLM and vector database.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.No Answers: If the agent can't answer, it might be because the information is not in the documents, or the top_k retrieval setting is too low. ","version":"Next","tagName":"h2"},{"title":"REST Gateway","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway","content":"","keywords":"","version":"Next"},{"title":"Key Features​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#key-features","content":" Dual API Versions: Supports both a modern asynchronous API (v2) and a deprecated synchronous API (v1) for backward compatibility.Asynchronous by Default: The v2 API uses a "202 Accepted + Poll" pattern, ideal for long-running agent tasks.Delegated Authentication: Integrates with an external authentication service via bearer tokens for secure access.File Handling: Supports file uploads for tasks and provides download URLs for generated artifacts.Dynamic Configuration: All gateway behaviors, including server settings and authentication, are configured via the main Solace Agent Mesh Host YAML file. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and the Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. ","version":"Next","tagName":"h2"},{"title":"Adding the REST Gateway Plugin​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#adding-the-rest-gateway-plugin","content":" Once you have your project set up, add the REST Gateway plugin: sam plugin add my-http-rest --plugin sam-rest-gateway You can use any name for your agent, in this tutorial we use my-http-rest. This command: Installs the sam-rest-gateway pluginCreates a new gateway configuration named my-http-rest in your configs/gateways/ directory ","version":"Next","tagName":"h2"},{"title":"Configuring the REST Gateway​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#configuring-the-rest-gateway","content":" For further configuration, you can edit the configs/gateways/my-http-rest.yaml file. This file contains the gateway configuration that can be customized for your use case. Using local Solace PubSub+ Broker container Solace PubSub+ Broker container uses port 8080. You need to edit the rest_api_server_port field and external_auth_service_url field in the configs/gateways/my-http-rest.yaml file to a free port other than 8080 (for example: 8081). You can edit the YAML file directly or add environment variables REST_API_PORT=8081 and EXTERNAL_AUTH_SERVICE_URL=http://localhost:8081. Make sure you change the REST API gateway to your new port in the following request examples. ","version":"Next","tagName":"h3"},{"title":"Running the REST Gateway​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#running-the-rest-gateway","content":" To run the REST Gateway, use the following command: sam run configs/gateways/my-http-rest.yaml ","version":"Next","tagName":"h2"},{"title":"Sending a Request via REST API​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#sending-a-request-via-rest-api","content":" You can also interact with Solace Agent Mesh via the REST API. The REST API gateway runs on http://localhost:8080 by default. You can use either the legacy v1 API or the modern async v2 API. ","version":"Next","tagName":"h2"},{"title":"Modern API (v2) - Asynchronous​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#modern-api-v2---asynchronous","content":" # Submit task curl --location 'http://localhost:8080/api/v2/tasks' \\ --header 'Authorization: Bearer token' \\ --form 'agent_name="OrchestratorAgent"' \\ --form 'prompt="Hi\\!"' # Poll for result using returned task ID curl --location 'http://localhost:8080/api/v2/tasks/{taskId}' \\ --header 'Authorization: Bearer token' warning It might take a while for the system to respond. See the observability page for more information about monitoring the system while it processes the request. Sample output: From api/v2/tasks { "taskId":"task-6a0e682f4f6c4927a5997e4fd06eea83" } From api/v2/tasks/{taskId} { "id": "task-6a0e682f4f6c4927a5997e4fd06eea83", "sessionId": "rest-session-4df0c24fcecc45fcb69692db9876bc5c", "status": { "state": "completed", "message": { "role": "agent", "parts": [{ "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today's Perfect Activities (13°C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." }] }, "timestamp": "2025-07-03T16:54:15.273085" }, "artifacts": [], "metadata": { "agent_name": "OrchestratorAgent" } } ","version":"Next","tagName":"h3"},{"title":"Legacy API (v1) - Synchronous​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#legacy-api-v1---synchronous","content":" curl --location 'http://localhost:8080/api/v1/invoke' \\ --header 'Authorization: Bearer None' \\ --form 'prompt="Suggest some good outdoor activities in London given the season and current weather conditions."' \\ --form 'agent_name="OrchestratorAgent"' \\ --form 'stream="false"' Sample output: { "id": "task-9f7d5f465f5a4f1ca799e8e5ecb35a43", "sessionId": "rest-session-36b36eeb69b04da7b67708f90e5512dc", "status": { "state": "completed", "message": { "role": "agent", "parts": [ { "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today's Perfect Activities (13°C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." } ] }, "timestamp": "2025-07-03T16:59:37.486480" }, "artifacts": [], "metadata": { "agent_name": "OrchestratorAgent" } } ","version":"Next","tagName":"h3"},{"title":"Slack Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration","content":"","keywords":"","version":"Next"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and Solace Mesh Agent CLI, and then create a new Solace Agent Mesh project or create a new gateway plugin. ","version":"Next","tagName":"h2"},{"title":"Creating the Slack App​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#creating-the-slack-app","content":" Next, create a Slack Application in your workspace. Go to the Slack Application website.Select Your Apps and click Create New App.Choose From a manifest and apply the following configuration. You can customize the name and description, but keep the rest of the configuration and settings unchanged. display_information: name: solace-agent-mesh-bot description: An app to integrate with Solace Agent Mesh features: app_home: home_tab_enabled: false messages_tab_enabled: true messages_tab_read_only_enabled: false bot_user: display_name: Solace Agent Mesh always_online: false oauth_config: scopes: bot: - app_mentions:read - bookmarks:read - channels:history - channels:join - channels:manage - channels:read - chat:write - chat:write.customize - chat:write.public - files:read - files:write - groups:history - groups:read - groups:write - im:history - im:read - im:write - links:read - links:write - mpim:history - mpim:read - mpim:write - pins:read - pins:write - reactions:read - reactions:write - reminders:read - reminders:write - team:read - usergroups:read - usergroups:write - users.profile:read - users:read.email - users:read - users:write - conversations.connect:read - conversations.connect:write - incoming-webhook settings: event_subscriptions: bot_events: - app_mention - message.groups - message.im interactivity: is_enabled: true org_deploy_enabled: false socket_mode_enabled: true token_rotation_enabled: false Then select Create to create your new App. ","version":"Next","tagName":"h2"},{"title":"App-Level Tokens​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#app-level-tokens","content":" In your created App, select Basic Information under Settings. Scroll down to App-Level Tokens and click Generate Token and Scopes. Provide your token a name, add all available scopes, and then click Generate. Make note of the resulting application token (beginning with xapp-) - you need it in a future step. ","version":"Next","tagName":"h3"},{"title":"Installing the App in Your Slack Workspace​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#installing-the-app-in-your-slack-workspace","content":" Next, select Install App under Settings and follow the installation flow to install the App in your workspace. After installation, the bot token (beginning with xoxb-) is visible. Make note of this token. ","version":"Next","tagName":"h3"},{"title":"Installing the Slack Gateway​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#installing-the-slack-gateway","content":" After configuring your Slack App, the next step is to add the Slack gateway to Solace Agent Mesh. Add the gateway plugin using Solace Agent Mesh CLI: sam plugin add slack-bot --plugin sam-slack You can change slack-bot to any name you prefer for your gateway. Configure the required environment variables: The Slack interface requires two authentication tokens. Add these to your .env file in the project root directory using the tokens generated during Slack App setup: SLACK_BOT_TOKEN=xoxb-xxxxxxxxxx SLACK_APP_TOKEN=xapp-xxxxxxxxxx tip You can further customize the Slack gateway by updating the configs/gateways/slack-bot.yaml file. This file contains the configuration for the Slack gateway, including the initial status message, the gateway system purpose, and response format. ","version":"Next","tagName":"h2"},{"title":"Running the Slack Gateway​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#running-the-slack-gateway","content":" Launch the Slack gateway with: sam run configs/gateways/slack-bot.yaml For detailed information about available Solace Agent Mesh CLI commands, see the Solace Agent Mesh CLI. ","version":"Next","tagName":"h2"},{"title":"Testing the Installation​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#testing-the-installation","content":" To test your installation: Open your Slack workspace in the desktop app or browser.Find and click on the Solace Agent Mesh app under the Apps section.Send a test message by typing hello and click Enter.You should see: A "Chatbot is thinking..." status messageA response from the chatbot within a few seconds ","version":"Next","tagName":"h2"},{"title":"Configuring Built-in Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#overview","content":" 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. The Solace Agent Mesh framework manages these tools through a central 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. ","version":"Next","tagName":"h2"},{"title":"Configuration Methods​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#configuration-methods","content":" Tool configuration is managed within the tools list in an agent's app_config block in the corresponding YAML configuration file. ","version":"Next","tagName":"h2"},{"title":"Method 1: Enabling Tool Groups (Recommended)​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#method-1-enabling-tool-groups-recommended","content":" 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. tool_type: builtin-groupgroup_name: The unique identifier for the tool category. Example: # In your agent's app_config: tools: - tool_type: builtin-group group_name: "artifact_management" - tool_type: builtin-group group_name: "data_analysis" ","version":"Next","tagName":"h3"},{"title":"Method 2: Enabling Individual Tools​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#method-2-enabling-individual-tools","content":" For more granular control over an agent's capabilities, specific tools can be enabled individually. tool_type: builtintool_name: The unique, registered name of the tool. Example: # In your agent's app_config: tools: - tool_type: builtin tool_name: "web_request" - tool_type: builtin tool_name: "time_delay" Note 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. ","version":"Next","tagName":"h3"},{"title":"Available Tool Groups and Tools​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#available-tool-groups-and-tools","content":" The following sections detail the available tool groups and the individual tools they contain. ","version":"Next","tagName":"h2"},{"title":"Artifact Management​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#artifact-management","content":" Group Name: artifact_management Description: Tools for creating, loading, and managing file artifacts. Individual Tools: create_artifactappend_to_artifactlist_artifactsload_artifactsignal_artifact_for_returnapply_embed_and_create_artifactextract_content_from_artifact info For a more in-depth guide on using artifact management tools, refer to the Artifact Management documentation. ","version":"Next","tagName":"h3"},{"title":"Data Analysis​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#data-analysis","content":" Group Name: data_analysis Description: Tools for querying, transforming, and visualizing data. Individual Tools: query_data_with_sqlcreate_sqlite_dbtransform_data_with_jqcreate_chart_from_plotly_config info For a more in-depth guide on using Data Analysis tools, refer to the Data Analysis Tools documentation. ","version":"Next","tagName":"h3"},{"title":"Web​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#web","content":" Group Name: web Description: Tools for interacting with web resources. Individual Tools: web_request ","version":"Next","tagName":"h3"},{"title":"Audio​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#audio","content":" Group Name: audio Description: Tools for generating and transcribing audio content. Individual Tools: text_to_speechmulti_speaker_text_to_speechtranscribe_audio ","version":"Next","tagName":"h3"},{"title":"Image​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#image","content":" Group Name: image Description: Tools for generating and analyzing images. Individual Tools: create_image_from_descriptiondescribe_imageedit_image_with_geminidescribe_audio ","version":"Next","tagName":"h3"},{"title":"General​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#general","content":" Group Name: general Description: General-purpose utility tools. Individual Tools: convert_file_to_markdownmermaid_diagram_generator ","version":"Next","tagName":"h3"},{"title":"Complete Configuration Example​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#complete-configuration-example","content":" Below is a comprehensive example of a well-formed app_config that uses the unified method to enable a mix of tool groups and individual tools. # In your agent's YAML file: app_config: namespace: "myorg/dev" agent_name: "DataAndWebAgent" model: "gemini-1.5-pro" instruction: "You are an agent that can analyze data and browse the web." # --- Unified Tool Configuration --- tools: # Enable a group of tools - tool_type: builtin-group group_name: "data_analysis" # Enable another group - tool_type: builtin-group group_name: "artifact_management" # Enable a single, specific tool - tool_type: builtin tool_name: "web_request" # Enable a custom Python tool - tool_type: python component_module: "my_company.tools.custom_calculators" function_name: "calculate_roi" # ... other service configurations (session_service, artifact_service, etc.) ","version":"Next","tagName":"h2"},{"title":"SQL Database Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database","content":"","keywords":"","version":"Next"},{"title":"Prerequisites​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#prerequisites","content":" Before starting this tutorial, ensure that you have installed and configured Solace Agent Mesh: Installed Solace Agent Mesh and the Solace Agent Mesh CLICreated a new Solace Agent Mesh projectAccess to a SQL database (local or remote) ","version":"Next","tagName":"h2"},{"title":"Adding the SQL Database Plugin​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#adding-the-sql-database-plugin","content":" Add the SQL Database plugin to your Solace Agent Mesh project: sam plugin add abc-coffee-info --plugin sam-sql-database You can use any name for your agent, in this tutorial we use abc-coffee-info. This command: Installs the sam-sql-database pluginCreates a new agent configuration file at configs/agents/abc-coffee-info.yaml ","version":"Next","tagName":"h2"},{"title":"Downloading Example Data​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#downloading-example-data","content":" For this tutorial, you can use a sample SQLite database for a fictional coffee company called ABC Coffee Co. First, download the example data. You can either visit this link to download with your browser: https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip Or you can use the command line to download the ZIP file: Using wget​ wget https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip Using curl​ curl -LO https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip After downloading the ZIP file, extract it to a directory of your choice. You can use the following command to extract the ZIP file: unzip abc_coffee_co.zip ","version":"Next","tagName":"h2"},{"title":"Configuring the Agent​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#configuring-the-agent","content":" Now, update the agent configuration to use the SQLite database and import the CSV files. Open the configs/agents/abc-coffee-info.yaml file and modify the agent_init_function.config section to specify the CSV directory. Here is what you need to modify in the configuration file: # Find the agent_init_function section and update the config: agent_init_function: module: "sam_sql_database.lifecycle" name: "initialize_sql_agent" config: db_type: "${ABC_COFFEE_INFO_DB_TYPE}" db_name: "${ABC_COFFEE_INFO_DB_NAME}" database_purpose: "${ABC_COFFEE_INFO_DB_PURPOSE}" data_description: "${ABC_COFFEE_INFO_DB_DESCRIPTION}" # Add the CSV directory path csv_directories: - /path/to/your/unzipped/data Ensure you replace /path/to/your/unzipped/data with the path where you extracted the example data. For example, if you put the ZIP file in the root directory of your Solace Agent Mesh project, you can use abc_coffee_co. ","version":"Next","tagName":"h2"},{"title":"Setting the Environment Variables​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#setting-the-environment-variables","content":" The SQL Database agent requires that you configure several environment variables. You must create or update your .env file with the following variables for this tutorial: ABC_COFFEE_INFO_DB_TYPE=sqlite ABC_COFFEE_INFO_DB_NAME=abc_coffee.db ABC_COFFEE_INFO_DB_PURPOSE="ABC Coffee Co. sales and operations database" ABC_COFFEE_INFO_DB_DESCRIPTION="Contains information about ABC Coffee Co. products, sales, customers, employees, and store locations." # You can leave other environment variables as unset or empty SQLite stores the database in a local file and doesn't require a username or password for access. If you're using a database such as MySQL or PostgreSQL, you'll need to provide the appropriate environment variables for them. ","version":"Next","tagName":"h2"},{"title":"Running the Agent​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#running-the-agent","content":" Now, you can start your SQL database agent: sam run configs/agents/abc-coffee-info.yaml The agent: Connects to the A2A control planeInitializes the SQLite database and imports CSV data from the specified directoryDetects the database schema automaticallyRegisters its capabilities with the agent discovery system ","version":"Next","tagName":"h2"},{"title":"Interacting with the Database​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#interacting-with-the-database","content":" After your SQL database agent is running, you can interact with the ABC Coffee database through any gateway in your Solace Agent Mesh project (such as the Web UI gateway at http://localhost:8000). You can ask natural language questions about the ABC Coffee Co. database, such as: "How many customers does ABC Coffee have?""What are the top-selling products?""Show me the sales by region""List all orders from the last 30 days""What products are currently low in inventory?" Try creating reports by asking questions such as: "Create a report of our sales in 2024""Generate a summary of customer demographics" The SQL Database agent converts your natural language questions into SQL queries, executes them against the database, and returns the results. For large result sets, the agent automatically saves the results as artifacts that you can download. ","version":"Next","tagName":"h2"},{"title":"Advanced Configuration​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#advanced-configuration","content":" The SQL Database plugin supports many advanced configuration options. Here is a complete example based on the plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: abc-coffee-info.log !include ../shared_config.yaml apps: - name: abc-coffee-info-app app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} agent_name: "AbcCoffeeInfo" display_name: "ABC Coffee Database Agent" supports_streaming: false model: *general_model instruction: | You are an expert SQL assistant for the ABC Coffee Co. database. The database schema and query examples are provided to you. Your primary goal is to translate user questions into accurate SQL queries. If a user asks to query the database, generate the SQL and call the 'execute_sql_query' tool. If the 'execute_sql_query' tool returns an error, analyze the error message and the original SQL, then try to correct the SQL query and call the tool again. If the results are large and the tool indicates they were saved as an artifact, inform the user about the artifact. Always use the 'execute_sql_query' tool to interact with the database. # Agent initialization with database setup agent_init_function: module: "sam_sql_database.lifecycle" name: "initialize_sql_agent" config: db_type: "${ABC_COFFEE_INFO_DB_TYPE}" db_name: "${ABC_COFFEE_INFO_DB_NAME}" database_purpose: "${ABC_COFFEE_INFO_DB_PURPOSE}" data_description: "${ABC_COFFEE_INFO_DB_DESCRIPTION}" auto_detect_schema: true csv_directories: - "abc_coffee_co" # Path to your extracted data query_examples: - natural_language: "Show all customers from New York" sql_query: "SELECT * FROM customers WHERE city = 'New York';" - natural_language: "What are the top 5 best-selling products?" sql_query: "SELECT product_name, SUM(quantity) as total_sold FROM order_items JOIN products ON order_items.product_id = products.id GROUP BY product_name ORDER BY total_sold DESC LIMIT 5;" agent_cleanup_function: module: "sam_sql_database.lifecycle" name: "cleanup_sql_agent_resources" # SQL query tool tools: - tool_type: python component_module: "sam_sql_database.tools" function_name: "execute_sql_query" session_service: *default_session_service artifact_service: *default_artifact_service # Agent capabilities - This is what other agents see during discovery agent_card: description: "ABC Coffee Co. Database Agent - Access to comprehensive coffee shop data including customers, orders, products, inventory, and sales history. Can answer questions about business metrics, customer analytics, product performance, and operational data." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "sql_query" name: "Coffee Shop Database Query" description: "Queries ABC Coffee Co. database containing customer orders, product catalog, inventory levels, sales history, and employee data." # A2A Protocol settings agent_card_publishing: { interval_seconds: 30 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 60 ","version":"Next","tagName":"h2"},{"title":"Customizing the Agent Card​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#customizing-the-agent-card","content":" The agent_card section is crucial as it defines how other agents in your Solace Agent Mesh ecosystem discover and understand this database agent's capabilities. When other agents use agent discovery, they can see this information to decide whether to delegate tasks to your database agent. ","version":"Next","tagName":"h2"},{"title":"Key Agent Card Elements​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#key-agent-card-elements","content":" Description: Clearly describe what data the agent has access to and what types of questions it can answerSkills: List specific capabilities with concrete examples that show the scope of data availableData Context: Mention the business domain, data types, and scope of information available ","version":"Next","tagName":"h3"},{"title":"Example of a Well-Configured Agent Card​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#example-of-a-well-configured-agent-card","content":" agent_card: description: "ABC Coffee Co. Database Agent - Access to comprehensive coffee shop data including customers, orders, products, inventory, and sales history. Can answer questions about business metrics, customer analytics, product performance, and operational data." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "sql_query" name: "Coffee Shop Database Query" description: "Queries ABC Coffee Co. database containing customer orders, product catalog, inventory levels, sales history, and employee data." This detailed information helps other agents understand: What business domain this agent covers (coffee shop operations)What types of data are available (customers, orders, products, inventory, sales)What kinds of questions can be answered (metrics, analytics, performance data)Specific examples of queries that work well When configuring your own database agent, customize the description and examples to match your specific data and use cases. ","version":"Next","tagName":"h3"},{"title":"Artifact Management Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management","content":"","keywords":"","version":"Next"},{"title":"The Metadata-Aware Workflow​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#the-metadata-aware-workflow","content":" Rather than automatically bundling all created artifacts in the final response, the agent follows a structured workflow: Create & Describe: The agent invokes the create_artifact tool to persist a file. Rich metadata, such as descriptions, sources, and inferred schemas, is stored alongside the artifact.Inject & Inform: This metadata is automatically injected into the conversation history, providing the agent with immediate context regarding the new file.List & Discover: The agent can call list_artifacts at any point to retrieve a summary of all available artifacts and their associated metadata.Load & Analyze: The agent can use load_artifact to read the content of a text-based artifact or inspect the detailed metadata of any artifact (for example, to ascertain the schema of a CSV file).Return on Request: To transmit an artifact to the user or a calling application, the agent must explicitly invoke signal_artifact_for_return. Artifacts are not returned automatically. ","version":"Next","tagName":"h2"},{"title":"Configuration​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#configuration","content":" The file management tools are encapsulated within the artifact_management tool group. ","version":"Next","tagName":"h2"},{"title":"Enabling the Tools​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#enabling-the-tools","content":" Enable the tool group within the agent's app_config.yml: # In your agent's app_config: tools: - tool_type: builtin-group group_name: "artifact_management" ","version":"Next","tagName":"h3"},{"title":"Configuring Artifact Return Behavior​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#configuring-artifact-return-behavior","content":" The artifact_handling_mode setting in your app_config dictates the behavior when signal_artifact_for_return is called: ignore (Default): The request is logged, but no artifact is transmitted.embed: The artifact content is base64-encoded and embedded within the TaskArtifactUpdateEvent payload. This is suitable for smaller files.reference: A URI pointing to the artifact is sent in the event payload. This approach requires a separate service to host the file at the specified URI. # In your agent's app_config: artifact_handling_mode: "reference" ","version":"Next","tagName":"h3"},{"title":"Tool Reference​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#tool-reference","content":" ","version":"Next","tagName":"h2"},{"title":"create_artifact​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#create_artifact","content":" Creates a new file artifact and its corresponding metadata. Parameters: filename (str): The designated name for the artifact (for example, "report.pdf").content (str): The file content. For binary file types (for example, images, PDFs), this content must be base64-encoded.mime_type (str): The standard MIME type of the content (for example, "text/plain", "image/png").metadata (dict, optional): A dictionary containing custom metadata (for example, {"description": "Monthly sales data"}). Returns: A dictionary confirming the successful persistence of the artifact.Key Feature: Upon successful execution of this tool, a summary of the artifact's metadata is automatically injected into the conversation history, informing the agent of the new file's context. ","version":"Next","tagName":"h3"},{"title":"list_artifacts​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#list_artifacts","content":" Lists all available artifacts within the current session. Parameters: None.Returns: A list of file objects, each containing the filename, available versions, and a metadata_summary for the latest version. ","version":"Next","tagName":"h3"},{"title":"load_artifact​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#load_artifact","content":" Loads the content or detailed metadata of a specific version of an artifact. Parameters: filename (str): The name of the artifact to be loaded.version (int): The specific version number of the artifact to load.load_metadata_only (bool, optional): If True, the tool returns the complete, detailed metadata dictionary instead of the artifact's content. This is useful for inspecting schemas or other metadata fields. Returns: If load_metadata_only=False: The artifact's content (for text-based files) or a basic information dictionary (for binary files).If load_metadata_only=True: The complete metadata dictionary for the specified artifact version. ","version":"Next","tagName":"h3"},{"title":"signal_artifact_for_return​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#signal_artifact_for_return","content":" Instructs the system to transmit a specific artifact version to the caller. Parameters: filename (str): The name of the artifact to be returned.version (int): The specific version number of the artifact to return. Returns: A dictionary confirming that the request has been received.Note: This tool functions as a signal. The actual transmission of the artifact is handled by the system in accordance with the configured artifact_handling_mode. ","version":"Next","tagName":"h3"},{"title":"Key Concepts​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#key-concepts","content":" Explicit Control: Agents possess full, explicit control over the entire artifact lifecycle.Metadata-Driven Context: The automatic injection and summarization of metadata are fundamental to providing agents with situational awareness.Signaled Return: Artifacts are transmitted to the user only upon an explicit request from the agent via the signal_artifact_for_return tool.Synergy with Embeds: These tools can be used in conjunction with Dynamic Embeds, such as «artifact_meta:report.csv», for more efficient file handling. ","version":"Next","tagName":"h2"},{"title":"Using Text-to-Speech (TTS) Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#overview","content":" The audio tool group provides two primary TTS tools for generating high-quality audio artifacts: text_to_speech: Converts a string of text to speech using a single voice, featuring intelligent tone selection.multi_speaker_text_to_speech: Converts a conversational script, delineated by speaker, into a multi-speaker audio file. ","version":"Next","tagName":"h2"},{"title":"Setup and Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#setup-and-configuration","content":" ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#prerequisites","content":" API Key: A valid Google Gemini API key with access to the TTS model is required.Dependencies: The pydub library is necessary for audio processing and format conversion. It can be installed via pip install pydub. ","version":"Next","tagName":"h3"},{"title":"Basic Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#basic-configuration","content":" Environment Variable: The Gemini API key must be set as an environment variable. export GEMINI_API_KEY="your_gemini_api_key_here" Enablement: The audio tool group must be enabled in the agent's app_config.yml. tools: - tool_type: builtin-group group_name: "audio" ","version":"Next","tagName":"h3"},{"title":"Advanced Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#advanced-configuration","content":" You can exercise more granular control over the TTS tools by providing a tool_config block for each tool in your app_config.yml. ","version":"Next","tagName":"h2"},{"title":"text_to_speech Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#text_to_speech-configuration","content":" This example shows how to set a default voice and define the mapping between tones and specific voice models. - tool_type: builtin tool_name: "text_to_speech" tool_config: gemini_api_key: ${GEMINI_API_KEY} model: "gemini-2.5-flash-preview-tts" voice_name: "Kore" # Default voice if no tone is matched language: "en-US" # Default language output_format: "mp3" # Voice selection by tone mapping voice_tone_mapping: bright: ["Zephyr", "Autonoe"] upbeat: ["Puck", "Laomedeia"] informative: ["Charon", "Rasalgethi"] firm: ["Kore", "Orus", "Alnilam"] friendly: ["Achird"] casual: ["Zubenelgenubi"] warm: ["Sulafar"] ","version":"Next","tagName":"h3"},{"title":"multi_speaker_text_to_speech Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi_speaker_text_to_speech-configuration","content":" This example defines default voice configurations for up to five speakers. - tool_type: builtin tool_name: "multi_speaker_text_to_speech" tool_config: gemini_api_key: ${GEMINI_API_KEY} model: "gemini-2.5-flash-preview-tts" language: "en-US" output_format: "mp3" # Default speaker voice configurations default_speakers: - { name: "Speaker1", voice: "Kore", tone: "firm" } - { name: "Speaker2", voice: "Puck", tone: "upbeat" } - { name: "Speaker3", voice: "Charon", tone: "informative" } - { name: "Speaker4", voice: "Achird", tone: "friendly" } - { name: "Speaker5", voice: "Sulafar", tone: "warm" } # The voice_tone_mapping can also be included here ","version":"Next","tagName":"h3"},{"title":"Features​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#features","content":" ","version":"Next","tagName":"h2"},{"title":"Intelligent Tone Selection​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#intelligent-tone-selection","content":" The system supports tone-based voice selection, allowing for dynamic voice choice based on desired emotional or stylistic output, rather than explicit voice names. Available Tones:bright, upbeat, informative, firm, excitable, youthful, breezy, easy-going, breathy, clear, smooth, gravelly, soft, even, mature, forward, friendly, casual, gentle, lively, knowledgeable, warm Tone Aliases: professional → firmcheerful → upbeatcalm → softconversational → casual ","version":"Next","tagName":"h3"},{"title":"Multi-Language Support​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi-language-support","content":" The tools support over 25 languages, specified via BCP-47 language codes (for example, en-US, fr-FR, es-US, ja-JP). ","version":"Next","tagName":"h3"},{"title":"Usage Examples​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#usage-examples","content":" ","version":"Next","tagName":"h2"},{"title":"Single-Voice Text-to-Speech (text_to_speech)​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#single-voice-text-to-speech-text_to_speech","content":" Basic Usage Convert the following text to speech: "Welcome to the technical briefing on artificial intelligence." With Tone Selection Convert this text to speech with a professional tone: "Thank you for joining today's technical review." ","version":"Next","tagName":"h3"},{"title":"Multi-Speaker Text-to-Speech (multi_speaker_text_to_speech)​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi-speaker-text-to-speech-multi_speaker_text_to_speech","content":" Basic Conversation Convert this conversation to speech: Speaker1: Welcome to the podcast. Speaker2: Thank you for having me. With Custom Speaker Tones Convert this conversation using specific tones for each speaker: - Speaker1 should sound professional - Speaker2 should sound friendly Conversation: Speaker1: Good morning, this is the daily security briefing. Speaker2: Hi everyone, let's review the agenda for today's session. ","version":"Next","tagName":"h3"},{"title":"Tool Reference​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#tool-reference","content":" ","version":"Next","tagName":"h2"},{"title":"text_to_speech​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#text_to_speech","content":" Parameter\tType\tDescriptiontext\tstring\tThe text to be synthesized. output_filename\tstring\t(Optional) A custom MP3 filename. voice_name\tstring\t(Optional) A specific voice name to use. tone\tstring\t(Optional) The desired voice tone. language\tstring\t(Optional) The BCP-47 language code. ","version":"Next","tagName":"h3"},{"title":"multi_speaker_text_to_speech​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi_speaker_text_to_speech","content":" Parameter\tType\tDescriptionconversation_text\tstring\tA string of text with speaker labels (for example, S1: ...). output_filename\tstring\t(Optional) A custom MP3 filename. speaker_configs\tarray\t(Optional) An array to configure tones for specific speakers. language\tstring\t(Optional) The BCP-47 language code. ","version":"Next","tagName":"h3"},{"title":"Output and Metadata​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#output-and-metadata","content":" Both tools generate an MP3 audio artifact that includes a rich set of metadata: The source text (or a truncated version for long inputs)The voice(s) and language used for synthesisThe generation timestamp and the specific tool invokedThe requested tone and any speaker-specific configurations ","version":"Next","tagName":"h2"},{"title":"Troubleshooting​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#troubleshooting","content":" Error: GEMINI_API_KEY is required: This indicates that the GEMINI_API_KEY environment variable has not been set correctly.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.Error: Failed to convert WAV to MP3: This typically indicates that pydub is not installed or that the underlying system is missing necessary audio codecs (for example, ffmpeg). ","version":"Next","tagName":"h2"},{"title":"Data Analysis Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools","content":"","keywords":"","version":"Next"},{"title":"Setup and Configuration​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#setup-and-configuration","content":" Enable the data analysis tool group in the agent's app_config.yml file. # In your agent's app_config: tools: - tool_type: builtin-group group_name: "data_analysis" # Optional: Configure tool behavior data_tools_config: sqlite_memory_threshold_mb: 100 max_result_preview_rows: 50 max_result_preview_bytes: 4096 ","version":"Next","tagName":"h2"},{"title":"Available Tools​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#available-tools","content":" ","version":"Next","tagName":"h2"},{"title":"query_data_with_sql​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#query_data_with_sql","content":" Enterprise Only This feature is available in the Enterprise Edition only. Executes a SQL query against data stored in a CSV or SQLite artifact. Parameters: input_filename (str): The filename of the input artifact (for example, 'data.csv', 'mydatabase.sqlite'). Supports versioning (for example, 'data.csv:2').sql_query (str): The SQL query string to execute.output_format (str, optional): The desired format for the output artifact ('csv' or 'json'). Defaults to 'csv'. Behavior: For CSV Input: The tool loads the CSV data into a temporary in-memory SQLite database table named data and executes the query against it.For SQLite Input: The tool connects directly to the specified SQLite database artifact in read-only mode. Returns: A dictionary containing the execution status, a preview of the query result, and the output_filename where the full result set is stored. ","version":"Next","tagName":"h3"},{"title":"create_sqlite_db​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#create_sqlite_db","content":" Enterprise Only This feature is available in the Enterprise Edition only. Converts a CSV or JSON artifact into a persistent SQLite database artifact. This is the recommended approach for executing multiple queries on the same dataset, as it avoids repeated parsing of the source file. Parameters: input_filename (str): The filename of the input CSV or JSON artifact.output_db_filename (str): The desired filename for the output SQLite database artifact (for example, 'queryable_dataset.sqlite').table_name (str, optional): The name of the table to be created within the SQLite database. Defaults to 'data'. Returns: A dictionary confirming the successful creation of the database artifact and providing its output_filename. ","version":"Next","tagName":"h3"},{"title":"transform_data_with_jq​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#transform_data_with_jq","content":" Enterprise Only This feature is available in the Enterprise Edition only. Applies a JQ expression to transform data from a JSON, YAML, or CSV artifact. Parameters: input_filename (str): The filename of the input artifact.jq_expression (str): The JQ filter or transformation expression string (for example, '.users[] | {name, id}'). Returns: A dictionary containing the execution status, a preview of the transformed data, and the output_filename where the full JSON result is stored. ","version":"Next","tagName":"h3"},{"title":"create_chart_from_plotly_config​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#create_chart_from_plotly_config","content":" Generates a static chart image (for example, PNG, JPG, SVG) from a Plotly configuration provided as a string. Parameters: config_content (str): A JSON or YAML formatted string representing the Plotly figure dictionary.config_format (str): Specifies whether config_content is 'json' or 'yaml'.output_filename (str): The desired filename for the output image artifact (for example, 'sales_chart.png').output_format (str, optional): The desired image format ('png', 'jpeg', 'svg', etc.). Defaults to 'png'. Returns: A dictionary confirming the chart's creation and providing its output_filename. ","version":"Next","tagName":"h3"},{"title":"Example Workflow: Querying a Large CSV​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#example-workflow-querying-a-large-csv","content":" The following workflow demonstrates an efficient method for analyzing a large CSV file: User Request: "I need to run several queries on large_data.csv."Agent Strategy: The agent determines that converting the CSV to a SQLite database is more performant for subsequent queries.Agent Call 1: The agent calls create_sqlite_db to convert large_data.csv into a new artifact, queryable_data.sqlite.Agent Response: "The data has been prepared for querying. What is your first question?"User Request: "Find all records where the category is 'Sales'."Agent Call 2: The agent calls query_data_with_sql, targeting the queryable_data.sqlite artifact.Agent Response: The agent provides the results of the query.User Request: "Now, find the average amount for the 'Marketing' category."Agent Call 3: The agent calls query_data_with_sql again on the same queryable_data.sqlite artifact, avoiding the overhead of reprocessing the original CSV file. ","version":"Next","tagName":"h2"},{"title":"Technical Considerations​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#technical-considerations","content":" ","version":"Next","tagName":"h2"},{"title":"Result Handling​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#result-handling","content":" Previews: For query_data_with_sql and transform_data_with_jq, the tools return a truncated preview of the result directly to the LLM for immediate context.Full Results: The complete, untruncated result sets are always saved as new artifacts. The LLM is provided with the filename and version of these artifacts.Accessing Full Results: To utilize the full results, the agent can employ file management tools (load_artifact) or Dynamic Embeds («artifact_content:...»). ","version":"Next","tagName":"h3"},{"title":"Security​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#security","content":" SQL Execution: Queries against existing SQLite artifacts are performed in read-only mode to prevent data modification. Queries against temporary databases generated from CSVs are isolated.JQ Execution: JQ expressions are executed within a sandboxed Python library, not via shell execution.Resource Usage: Complex queries or transformations can be resource-intensive. Monitor performance and resource consumption accordingly. ","version":"Next","tagName":"h3"},{"title":"Dynamic Embeds","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds","content":"","keywords":"","version":"Next"},{"title":"Dynamic Embeds​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#dynamic-embeds","content":" Dynamic embeds provide a mechanism for agents to insert context-dependent information into their text responses or tool parameters using a specialized «...» syntax. This feature allows for the dynamic retrieval and formatting of data without requiring explicit tool calls for simple data retrieval or calculations. ","version":"Next","tagName":"h2"},{"title":"Overview​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#overview","content":" Dynamic embeds allow an agent to defer the inclusion of data until it is needed, resolving the value just before the final response is sent to the user. Standard Approach: "The current time is [call get_time tool]."With Dynamic Embeds: "The current time is «datetime:%H:%M»." The system resolves the embed directive, a dynamic placeholder for data that gets computed at runtime, replacing it with the evaluated result (for example, "The current time is 10:45."). ","version":"Next","tagName":"h3"},{"title":"Syntax​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#syntax","content":" There are two primary syntaxes for embed directives. Simple Syntax​ This syntax is used for most general-purpose embeds. «type:expression | format_spec» type: A keyword indicating the type of information to embed (for example, state, math, datetime).expression: The specific data to retrieve or the expression to evaluate.format_spec: (Optional) A specifier for formatting the output value (for example, a number precision .2f or a strftime string %Y-%m-%d). Chain Syntax​ This syntax is used exclusively for the artifact_content embed type to apply a sequence of transformations. «artifact_content:spec >>> modifier1 >>> modifier2 >>> format:output_format» artifact_spec: The artifact identifier (filename[:version]).>>>: The chain delimiter, separating transformation steps.modifier: A transformation to apply to the data (for example, jsonpath, grep, slice_lines).format: A required final step that specifies the output format (for example, text, json, datauri). ","version":"Next","tagName":"h3"},{"title":"Available Embed Types​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#available-embed-types","content":" General Purpose Embeds​ These are typically resolved by the agent host during execution. Type\tDescription\tExamplestate\tAccesses a session state variable.\t«state:user_name» math\tEvaluates a mathematical expression.\t«math:100 * 0.05 | .2f» (Result: 5.00) datetime\tInserts the current date and/or time.\t«datetime:%Y-%m-%d» (Result: 2023-10-27) uuid\tInserts a random Version 4 UUID.\t«uuid:» status_update\tSignals a temporary status update to the UI.\t«status_update:Searching knowledge base...» Artifact-Related Embeds​ artifact_meta​ Retrieves a JSON string containing the full metadata of a specified artifact. Syntax: «artifact_meta:filename[:version]»Example: «artifact_meta:report.csv» artifact_content​ Embeds the content of an artifact, with support for a chain of transformations. This is the most advanced embed type. Modifiers (Data Transformations)Modifiers are applied sequentially to transform the data. Modifier\tDescriptionjsonpath:<expr>\tApplies a JSONPath query to JSON data. select_cols:<c1,c2>\tSelects specific columns from CSV data. filter_rows_eq:<col>:<val>\tFilters CSV rows where a column's value equals the specified value. slice_rows:<start>:<end>\tSelects a slice of rows from CSV data. slice_lines:<start>:<end>\tSelects a slice of lines from text data. grep:<pattern>\tFilters lines matching a regular expression in text data. head:<N> / tail:<N>\tReturns the first or last N lines of text data. select_fields:<f1,f2>\tSelects specific fields from a list of dictionaries. apply_to_template:<file>\tRenders data using a Mustache template artifact. See the Templates Guide. Formatters (Final Output)This is the required final step in an artifact_content chain, defining the output format. Formatter\tDescriptiontext\tPlain text, decoded as UTF-8. json / json_pretty\tA compact or indented JSON string. csv\tA CSV formatted string. datauri\tA Base64-encoded data URI, typically for images (data:image/png;base64,...). artifact_content Examples: To embed an image for display in a UI:«artifact_content:logo.png >>> format:datauri»To extract and format specific data from a JSON file:«artifact_content:results.json >>> jsonpath:$.data[*].name >>> format:json»To get the last 10 lines of a log file:«artifact_content:debug.log >>> tail:10 >>> format:text»To filter a CSV file and render it using an HTML template:«artifact_content:users.csv >>> filter_rows_eq:Status:Active >>> apply_to_template:active_users.html >>> format:text» ","version":"Next","tagName":"h3"},{"title":"Technical Details​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#technical-details","content":" Resolution Stages​ Embeds are resolved in two distinct stages, depending on where the required data is available: Early Stage (Agent Host): Resolved by the agent runtime itself. This stage handles simple, context-local embeds like state, math, and datetime.Late Stage (Gateway): Resolved by the Gateway component before the final message is sent to the client. This is necessary for artifact_content embeds, which may involve large files or transformations that are too resource-intensive for the agent host. Configuration​ Enabling/Disabling: Embed resolution is enabled by default. It can be disabled in the app_config of the agent host or gateway by setting enable_embed_resolution: false.Resource Limits: The gateway enforces configurable limits to prevent abuse, including gateway_artifact_content_limit_bytes (default: 32KB) and gateway_recursive_embed_depth (default: 3). ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#error-handling","content":" If an embed directive fails during parsing or evaluation, it is replaced with a descriptive error message in the final output. Parsing Error: [Error: Invalid modifier format: 'badmodifier']Evaluation Error: [Error: State variable 'user_id' not found]Limit Exceeded: [Error: Artifact 'large_file.zip' exceeds size limit] ","version":"Next","tagName":"h3"},{"title":"Templates​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#templates","content":" ","version":"Next","tagName":"h2"},{"title":"Using Templates for Formatted Output​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#using-templates-for-formatted-output","content":" The apply_to_template modifier, used within an «artifact_content:...» embed directive, enables an agent to render structured data using a Mustache template. This mechanism allows for the separation of data and presentation, enabling the agent to control the output format (for example, HTML, Markdown) without generating the formatting markup itself. ","version":"Next","tagName":"h3"},{"title":"The Templating Workflow​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#the-templating-workflow","content":" The process involves three distinct steps: Template Creation: Author a Mustache template file that defines the desired output structure.Artifact Storage: Persist the template file as an artifact in the agent's artifact storage using the create_artifact tool.Template Rendering: Utilize an «artifact_content:...» embed chain to process a data artifact and then apply the stored template to the result. Step 1: Create a Mustache Template​ Mustache is a logic-less template syntax. Templates are created as text files (for example, user_table.html.mustache) containing placeholders for data injection. Key Mustache Syntax: {{variable}}: A variable placeholder. It is replaced with the corresponding value from the data context.{{#section}}...{{/section}}: A section tag. The enclosed block is rendered for each item in a list or if the section variable is a non-empty object or truthy value.{{^section}}...{{/section}}: An inverted section tag. The enclosed block is rendered only if the section variable is false, null, or an empty list.{{! comment }}: A comment tag. The content is ignored during rendering. Example: user_table.html.mustacheThis template generates an HTML table from a list of user objects. <h2>User List</h2> {{#items}} <table> <thead> <tr> <th>Name</th> <th>Status</th> </tr> </thead> <tbody> {{#.}} <tr> <td>{{name}}</td> <td>{{status}}</td> </tr> {{/.}} </tbody> </table> {{/items}} {{^items}} <p>No users found.</p> {{/items}} Step 2: Store the Template as an Artifact​ The template must be stored as an artifact to be accessible by the Gateway during the late-stage embed resolution process. This is accomplished using the create_artifact tool. Example Agent Interaction: User: "Please create an HTML template to display a list of users."Agent: "Acknowledged. I will create the template artifact user_table.html.mustache."(The agent then invokes the create_artifact tool with the specified filename and the HTML content from Step 1.) Step 3: Render the Template with an Embed​ With the data and template artifacts stored, the agent can construct an artifact_content embed chain to perform the rendering. Syntax: ... >>> apply_to_template:template_filename[:version] >>> ...Data Context: The data provided to the template engine is the output of the preceding modifier in the chain. If the data is a list, it is automatically wrapped in a dictionary of the form {'items': your_list}. The template should use {{#items}} to iterate over this list.If the data is a dictionary, it is used directly as the rendering context. Output Format: It is mandatory to terminate the chain with a format: step (for example, format:text) to specify the MIME type of the final rendered output. Complete Example: The following embed chain processes a JSON file and renders its content using the HTML template created in Step 1. «artifact_content:user_data.json >>> jsonpath:$.users[*] >>> select_fields:name,status >>> apply_to_template:user_table.html.mustache >>> format:text» Execution Flow: artifact_content:user_data.json: Loads the raw data from the user_data.json artifact.jsonpath:$.users[*]: Applies a JSONPath expression to extract the list of user objects.select_fields:name,status: Filters each object in the list to retain only the name and status fields.apply_to_template:user_table.html.mustache: Renders the resulting list of users using the specified Mustache template. ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#error-handling-1","content":" Template Not Found: If the specified template artifact does not exist, the embed resolves to [Error: Template artifact '...' not found].Rendering Error: If the data structure is incompatible with the template's expectations, the embed resolves to [Error: Error rendering template '...']. ","version":"Next","tagName":"h3"},{"title":"Build Your Own Agent","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#overview","content":" Our weather agent will demonstrate: External API integration (OpenWeatherMap)Professional service layer architectureMultiple sophisticated toolsProper lifecycle managementError handling and validationArtifact creation and management ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#prerequisites","content":" Before starting this tutorial, make sure you have: Read the Create Agent tutorialAn OpenWeatherMap API key (free at openweathermap.org)Basic understanding of Python async/awaitFamiliarity with HTTP APIs ","version":"Next","tagName":"h2"},{"title":"Planning the Weather Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#planning-the-weather-agent","content":" Our weather agent will have the following capabilities: Get Current Weather: Fetch current weather conditions for a specified locationGet Weather Forecast: Retrieve a multi-day weather forecastSave Weather Reports: Store weather data as artifacts The agent will demonstrate: External API integrationError handling and validationConfiguration managementArtifact creationResource lifecycle management ","version":"Next","tagName":"h2"},{"title":"Step 1: Project Structure​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-1-project-structure","content":" Run the following command to create a new custom agent: sam add agent --gui tip You can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create my-hello-agent --type agent. For information and recommendations about these options, see Agent or Plugin: Which To use?. For an example of plugin agents, see the Create Agents guide. 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. Important Notice This tutorial is intentionally comprehensive to demonstrate the full flexibility and advanced features available in Solace Agent Mesh agents. For most straightforward use cases, you only need a simple Python function and a corresponding reference in your YAML configuration file. Simple Weather Agent Example After going through the add agent wizard from sam add agent --gui, create the following file under src/weather_agent/tools.py directory: # src/weather_agent/tools.py import httpx from typing import Any, Dict, Optional from google.adk.tools import ToolContext from solace_ai_connector.common.log import log async def get_current_weather( location: str, units: str = "metric", tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get current weather conditions for a specified location. Args: location: City name, state, and country (for example, "New York, NY, US") units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin" """ log.info("[GetCurrentWeather] Getting current weather for: %s", location) base_url = "https://api.openweathermap.org/data/2.5" api_key = tool_config.get("api_key") if tool_config else None url = f"{base_url}/weather" params = { "q": location, "appid": api_key, "units": units } try: # Fetch weather data async with httpx.AsyncClient() as client: response = await client.get(url, params=params) response.raise_for_status() weather_data = response.json() result = { "status": "success", "location": location, "units": units, "data": weather_data } return result except Exception as e: log.error(f"[GetCurrentWeather] Error getting weather: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } async def get_weather_forecast( location: str, days: int = 5, units: str = "metric", tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get weather forecast for a specified location. Args: location: City name, state, and country days: Number of days for forecast (1-5) units: Temperature units """ log.info("[GetWeatherForecast] Getting %d-day forecast for: %s", days, location) base_url = "https://api.openweathermap.org/data/2.5" api_key = tool_config.get("api_key") if tool_config else None url = f"{base_url}/forecast" params = { "q": location, "appid": api_key, "units": units, "cnt": min(days * 8, 40) } try: # Fetch forecast data async with httpx.AsyncClient() as client: response = await client.get(url, params=params) response.raise_for_status() forecast_data = response.json() result = { "status": "success", "location": forecast_data["location"], "days": days, "units": units, "data": forecast_data } return result except Exception as e: log.error(f"[GetWeatherForecast] Error getting forecast: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } And update the weather agent config file's tool section under configs/agent/weather-agent.yaml as follows: # Tools configuration tools: # Current weather tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_current_weather" tool_description: "Get current weather conditions for a specified location" tool_config: api_key: ${OPENWEATHER_API_KEY} # Weather forecast tool - tool_type: python component_module: "src.weather_agent.tools" function_name: "get_weather_forecast" component_base_path: . tool_description: "Get weather forecast for up to 5 days for a specified location" tool_config: api_key: ${OPENWEATHER_API_KEY} For better discoverability, update the agent card section in the same YAML file as follows: # Agent card agent_card: description: "Professional weather agent providing current conditions, forecasts, and weather comparisons" defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "get_current_weather" name: "Get Current Weather" description: "Retrieve current weather conditions for any location worldwide" - id: "get_weather_forecast" name: "Get Weather Forecast" description: "Provide detailed weather forecasts up to 5 days ahead" To run the agent, you can continue following documentation from Step 6 of this tutorial. Other concepts mentioned in this page such as lifecycle, services, artifacts are just to showcase more advanced patterns. Create the directory structure for the weather agent: sam-project/ ├── src/ │ └── weather_agent/ │ ├── __init__.py │ ├── tools.py │ ├── lifecycle.py │ └── services/ │ ├── __init__.py │ └── weather_service.py ├── configs │ └── shared_config.yaml │ └── agents/ │ └── weather_agent.yaml ... tip IN Solace Agent Mesh, you can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create your-agent --type agent. This tutorial uses the sam add agent command to create a new agent named "Weather Agent", for an example of creating a custom agent plugin, see the Create Agents tutorial. ","version":"Next","tagName":"h2"},{"title":"Step 2: Weather Service Implementation​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-2-weather-service-implementation","content":" First, create a service class to handle weather API interactions: src/weather_agent/services/weather_service.py: """ Weather service for interacting with external weather APIs. """ import aiohttp from typing import Dict, Any, Optional, List from datetime import datetime, timezone from solace_ai_connector.common.log import log class WeatherService: """Service for fetching weather data from external APIs.""" def __init__(self, api_key: str, base_url: str = "https://api.openweathermap.org/data/2.5"): self.api_key = api_key self.base_url = base_url self.session: Optional[aiohttp.ClientSession] = None self.log_identifier = "[WeatherService]" async def _get_session(self) -> aiohttp.ClientSession: """Get or create an HTTP session.""" if self.session is None or self.session.closed: self.session = aiohttp.ClientSession() return self.session async def close(self): """Close the HTTP session.""" if self.session and not self.session.closed: await self.session.close() log.info(f"{self.log_identifier} HTTP session closed") async def get_current_weather(self, location: str, units: str = "metric") -> Dict[str, Any]: """ Get current weather for a location. Args: location: City name, state code, and country code (for example, "London,UK") units: Temperature units (metric, imperial, kelvin) Returns: Dictionary containing current weather data """ log.info(f"{self.log_identifier} Fetching current weather for: {location}") session = await self._get_session() url = f"{self.base_url}/weather" params = { "q": location, "appid": self.api_key, "units": units } try: async with session.get(url, params=params) as response: if response.status == 200: data = await response.json() log.info(f"{self.log_identifier} Successfully fetched weather for {location}") return self._format_current_weather(data) elif response.status == 404: raise ValueError(f"Location '{location}' not found") else: error_data = await response.json() raise Exception(f"Weather API error: {error_data.get('message', 'Unknown error')}") except aiohttp.ClientError as e: log.error(f"{self.log_identifier} Network error fetching weather: {e}") raise Exception(f"Network error: {str(e)}") async def get_weather_forecast(self, location: str, days: int = 5, units: str = "metric") -> Dict[str, Any]: """ Get weather forecast for a location. Args: location: City name, state code, and country code days: Number of days for forecast (1-5) units: Temperature units Returns: Dictionary containing forecast data """ log.info(f"{self.log_identifier} Fetching {days}-day forecast for: {location}") session = await self._get_session() url = f"{self.base_url}/forecast" params = { "q": location, "appid": self.api_key, "units": units, "cnt": min(days * 8, 40) # API returns 3-hour intervals, max 40 entries } try: async with session.get(url, params=params) as response: if response.status == 200: data = await response.json() log.info(f"{self.log_identifier} Successfully fetched forecast for {location}") return self._format_forecast_data(data, days) elif response.status == 404: raise ValueError(f"Location '{location}' not found") else: error_data = await response.json() raise Exception(f"Weather API error: {error_data.get('message', 'Unknown error')}") except aiohttp.ClientError as e: log.error(f"{self.log_identifier} Network error fetching forecast: {e}") raise Exception(f"Network error: {str(e)}") def _format_current_weather(self, data: Dict) -> Dict[str, Any]: """Format current weather data for consistent output.""" return { "location": f"{data['name']}, {data['sys']['country']}", "temperature": data['main']['temp'], "feels_like": data['main']['feels_like'], "humidity": data['main']['humidity'], "pressure": data['main']['pressure'], "description": data['weather'][0]['description'].title(), "wind_speed": data.get('wind', {}).get('speed', 0), "wind_direction": data.get('wind', {}).get('deg', 0), "visibility": data.get('visibility', 0) / 1000, # Convert to km "timestamp": datetime.fromtimestamp(data['dt']).isoformat(), "sunrise": datetime.fromtimestamp(data['sys']['sunrise']).isoformat(), "sunset": datetime.fromtimestamp(data['sys']['sunset']).isoformat() } def _format_forecast_data(self, data: Dict, days: int) -> Dict[str, Any]: """Format forecast data for consistent output.""" forecasts = [] current_date = None daily_data = [] for item in data['list'][:days * 8]: forecast_date = datetime.fromtimestamp(item['dt']).date() if current_date != forecast_date: if daily_data: forecasts.append(self._aggregate_daily_forecast(daily_data)) current_date = forecast_date daily_data = [] daily_data.append(item) # Add the last day's data if daily_data: forecasts.append(self._aggregate_daily_forecast(daily_data)) return { "location": f"{data['city']['name']}, {data['city']['country']}", "forecasts": forecasts[:days] } def _aggregate_daily_forecast(self, daily_data: List[Dict]) -> Dict[str, Any]: """Aggregate 3-hour forecasts into daily summary.""" if not daily_data: return {} # Get temperatures for min/max calculation temps = [item['main']['temp'] for item in daily_data] # Use the forecast closest to noon for general conditions noon_forecast = min(daily_data, key=lambda x: abs( datetime.fromtimestamp(x['dt']).hour - 12 )) return { "date": datetime.fromtimestamp(daily_data[0]['dt']).date().isoformat(), "temperature_min": min(temps), "temperature_max": max(temps), "description": noon_forecast['weather'][0]['description'].title(), "humidity": noon_forecast['main']['humidity'], "wind_speed": noon_forecast.get('wind', {}).get('speed', 0), "precipitation_probability": noon_forecast.get('pop', 0) * 100 } ","version":"Next","tagName":"h2"},{"title":"Step 3: Weather Tools Implementation​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-3-weather-tools-implementation","content":" Now create the tool functions: src/weather_agent/tools.py: """ Weather agent tools for fetching and processing weather data. """ import json from typing import Any, Dict, Optional from datetime import datetime, timezone from google.adk.tools import ToolContext from solace_ai_connector.common.log import log from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata async def get_current_weather( location: str, units: str = "metric", save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get current weather conditions for a specified location. Args: location: City name, state, and country (for example, "New York, NY, US") units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin" save_to_file: Whether to save the weather report as an artifact Returns: Dictionary containing current weather information """ log_identifier = "[GetCurrentWeather]" log.info(f"{log_identifier} Getting current weather for: {location}") if not tool_context: return { "status": "error", "message": "Tool context is required for weather operations" } try: # Get weather service from agent state host_component = getattr(tool_context._invocation_context, "agent", None) if host_component: host_component = getattr(host_component, "host_component", None) if not host_component: return { "status": "error", "message": "Could not access agent host component" } weather_service = host_component.get_agent_specific_state("weather_service") if not weather_service: return { "status": "error", "message": "Weather service not initialized" } # Fetch weather data weather_data = await weather_service.get_current_weather(location, units) # Create human-readable summary summary = _create_weather_summary(weather_data) result = { "status": "success", "location": weather_data["location"], "summary": summary, "data": weather_data } # Save to artifact if requested if save_to_file: artifact_result = await _save_weather_artifact( weather_data, f"current_weather_{location}", tool_context ) result["artifact"] = artifact_result log.info(f"{log_identifier} Successfully retrieved weather for {location}") return result except ValueError as e: log.warning(f"{log_identifier} Invalid location: {e}") return { "status": "error", "message": f"Location error: {str(e)}" } except Exception as e: log.error(f"{log_identifier} Error getting weather: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } async def get_weather_forecast( location: str, days: int = 5, units: str = "metric", save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get weather forecast for a specified location. Args: location: City name, state, and country days: Number of days for forecast (1-5) units: Temperature units save_to_file: Whether to save the forecast as an artifact Returns: Dictionary containing weather forecast information """ log_identifier = "[GetWeatherForecast]" log.info(f"{log_identifier} Getting {days}-day forecast for: {location}") if not tool_context: return { "status": "error", "message": "Tool context is required for weather operations" } # Validate days parameter if not 1 <= days <= 5: return { "status": "error", "message": "Days must be between 1 and 5" } try: # Get weather service from agent state host_component = getattr(tool_context._invocation_context, "agent", None) if host_component: host_component = getattr(host_component, "host_component", None) if not host_component: return { "status": "error", "message": "Could not access agent host component" } weather_service = host_component.get_agent_specific_state("weather_service") if not weather_service: return { "status": "error", "message": "Weather service not initialized" } # Fetch forecast data forecast_data = await weather_service.get_weather_forecast(location, days, units) # Create human-readable summary summary = _create_forecast_summary(forecast_data) result = { "status": "success", "location": forecast_data["location"], "summary": summary, "data": forecast_data } # Save to artifact if requested if save_to_file: artifact_result = await _save_weather_artifact( forecast_data, f"forecast_{location}_{days}day", tool_context ) result["artifact"] = artifact_result log.info(f"{log_identifier} Successfully retrieved forecast for {location}") return result except ValueError as e: log.warning(f"{log_identifier} Invalid location: {e}") return { "status": "error", "message": f"Location error: {str(e)}" } except Exception as e: log.error(f"{log_identifier} Error getting forecast: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } def _create_weather_summary(weather_data: Dict[str, Any]) -> str: """Create a human-readable weather summary.""" temp_unit = "°C" # Assuming metric units for summary summary = f"Current weather in {weather_data['location']}:\\n" summary += f"• Temperature: {weather_data['temperature']}{temp_unit} (feels like {weather_data['feels_like']}{temp_unit})\\n" summary += f"• Conditions: {weather_data['description']}\\n" summary += f"• Humidity: {weather_data['humidity']}%\\n" summary += f"• Wind: {weather_data['wind_speed']} m/s\\n" summary += f"• Visibility: {weather_data['visibility']} km" return summary def _create_forecast_summary(forecast_data: Dict[str, Any]) -> str: """Create a human-readable forecast summary.""" summary = f"Weather forecast for {forecast_data['location']}:\\n\\n" for forecast in forecast_data['forecasts']: date = datetime.fromisoformat(forecast['date']).strftime('%A, %B %d') summary += f"• {date}: {forecast['description']}\\n" summary += f" High: {forecast['temperature_max']:.1f}°C, Low: {forecast['temperature_min']:.1f}°C\\n" if forecast['precipitation_probability'] > 0: summary += f" Precipitation: {forecast['precipitation_probability']:.0f}% chance\\n" summary += "\\n" return summary.strip() async def _save_weather_artifact( weather_data: Dict[str, Any], filename_base: str, tool_context: ToolContext ) -> Dict[str, Any]: """Save weather data as an artifact.""" try: # Prepare content content = json.dumps(weather_data, indent=2, default=str) timestamp = datetime.now(timezone.utc) filename = f"{filename_base}_{timestamp.strftime('%Y%m%d_%H%M%S')}.json" # Save artifact artifact_service = tool_context._invocation_context.artifact_service result = await save_artifact_with_metadata( artifact_service=artifact_service, app_name=tool_context._invocation_context.app_name, user_id=tool_context._invocation_context.user_id, session_id=tool_context._invocation_context.session.id, filename=filename, content_bytes=content.encode('utf-8'), mime_type="application/json", metadata_dict={ "description": "Weather data report", "source": "Weather Agent" }, timestamp=timestamp ) return { "filename": filename, "status": result.get("status", "success") } except Exception as e: log.error(f"[WeatherArtifact] Error saving artifact: {e}") return { "status": "error", "message": f"Failed to save artifact: {str(e)}" } ","version":"Next","tagName":"h2"},{"title":"Step 4: Lifecycle Functions​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-4-lifecycle-functions","content":" Create the lifecycle management: src/weather_agent/lifecycle.py: """ Lifecycle functions for the Weather Agent. """ from typing import Any import asyncio from pydantic import BaseModel, Field, SecretStr from solace_ai_connector.common.log import log from .services.weather_service import WeatherService class WeatherAgentInitConfig(BaseModel): """ Configuration model for Weather Agent initialization. """ api_key: SecretStr = Field(description="OpenWeatherMap API key") base_url: str = Field( default="https://api.openweathermap.org/data/2.5", description="Weather API base URL" ) startup_message: str = Field( default="Weather Agent is ready to provide weather information!", description="Message to log on startup" ) def initialize_weather_agent(host_component: Any, init_config: WeatherAgentInitConfig): """ Initialize the Weather Agent with weather service. Args: host_component: The agent host component init_config: Validated initialization configuration """ log_identifier = f"[{host_component.agent_name}:init]" log.info(f"{log_identifier} Starting Weather Agent initialization...") try: # Initialize weather service weather_service = WeatherService( api_key=init_config.api_key.get_secret_value(), base_url=init_config.base_url ) # Store service in agent state host_component.set_agent_specific_state("weather_service", weather_service) # Log startup message log.info(f"{log_identifier} {init_config.startup_message}") # Store initialization metadata host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z") host_component.set_agent_specific_state("weather_requests_count", 0) log.info(f"{log_identifier} Weather Agent initialization completed successfully") except Exception as e: log.error(f"{log_identifier} Failed to initialize Weather Agent: {e}") raise def cleanup_weather_agent(host_component: Any): """ Clean up Weather Agent resources. Args: host_component: The agent host component """ log_identifier = f"[{host_component.agent_name}:cleanup]" log.info(f"{log_identifier} Starting Weather Agent cleanup...") async def cleanup_async(host_component: Any): try: # Get and close weather service weather_service = host_component.get_agent_specific_state("weather_service") if weather_service: await weather_service.close() log.info(f"{log_identifier} Weather service closed successfully") # Log final statistics request_count = host_component.get_agent_specific_state("weather_requests_count", 0) log.info(f"{log_identifier} Agent processed {request_count} weather requests during its lifetime") log.info(f"{log_identifier} Weather Agent cleanup completed") except Exception as e: log.error(f"{log_identifier} Error during cleanup: {e}") # run cleanup in the event loop loop = asyncio.get_event_loop() loop.run_until_complete(cleanup_async(host_component)) log.info(f"{log_identifier} Weather Agent cleanup completed successfully") ","version":"Next","tagName":"h2"},{"title":"Step 5: Agent Configuration​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-5-agent-configuration","content":" Create the comprehensive YAML configuration: # Weather Agent Configuration log: stdout_log_level: INFO log_file_level: DEBUG log_file: weather-agent.log !include ../shared_config.yaml apps: - name: weather-agent # Broker configuration app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: "${NAMESPACE}" agent_name: "WeatherAgent" display_name: "Weather Information Agent" supports_streaming: true # LLM model configuration model: *general_model # Agent instructions instruction: | You are a professional weather agent that provides accurate, up-to-date weather information. Your capabilities include: 1. Getting current weather conditions for any location worldwide 2. Providing detailed weather forecasts up to 5 days 3. Saving weather reports as files for future reference Guidelines: - Always specify the location clearly when providing weather information - Include relevant details like temperature, conditions, humidity, and wind - Offer to save weather reports when providing detailed information - Be helpful in suggesting appropriate clothing or activities based on weather - If a location is ambiguous, ask for clarification (city, state/province, country) When users ask about weather, use the appropriate tools to fetch real-time data. Present information in a clear, organized manner that's easy to understand. # Lifecycle functions agent_init_function: module: "src.weather_agent.lifecycle" name: "initialize_weather_agent" base_path: . config: api_key: ${OPENWEATHER_API_KEY} base_url: "https://api.openweathermap.org/data/2.5" startup_message: "Weather Agent is ready to provide weather information!" agent_cleanup_function: module: "src.weather_agent.lifecycle" base_path: . name: "cleanup_weather_agent" # Tools configuration tools: # Current weather tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_current_weather" tool_description: "Get current weather conditions for a specified location" # Weather forecast tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_weather_forecast" tool_description: "Get weather forecast for up to 5 days for a specified location" # Built-in artifact tools for file operations - tool_type: builtin-group group_name: "artifact_management" session_service: *default_session_service artifact_service: *default_artifact_service artifact_handling_mode: "reference" enable_embed_resolution: true enable_artifact_content_instruction: true # Agent card agent_card: description: "Professional weather agent providing current conditions, forecasts, and weather comparisons" defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "get_current_weather" name: "Get Current Weather" description: "Retrieve current weather conditions for any location worldwide" - id: "get_weather_forecast" name: "Get Weather Forecast" description: "Provide detailed weather forecasts up to 5 days ahead" agent_card_publishing: interval_seconds: 30 agent_discovery: enabled: false inter_agent_communication: allow_list: [] request_timeout_seconds: 30 For more details on agent cards, see the Agent Card Concepts documentation. ","version":"Next","tagName":"h2"},{"title":"Step 6: Environment Setup​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-6-environment-setup","content":" Before running your weather agent, you'll need to: Get an OpenWeatherMap API key: Sign up at OpenWeatherMapGet your free API key Set environment variables: export OPENWEATHER_API_KEY="your_api_key_here" # Other environment variables as needed ","version":"Next","tagName":"h2"},{"title":"Step 7: Running the Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-7-running-the-agent","content":" 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 src directory directly using the Solace Agent Mesh CLI. Start your weather agent for development purposes run: sam run To solely run the agent, use sam run configs/agents/weather_agent.yaml ","version":"Next","tagName":"h2"},{"title":"Step 8: Testing the Weather Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-8-testing-the-weather-agent","content":" You can test your weather agent with these example requests: Current Weather: "What's the current weather in New York City?" Weather Forecast: "Can you give me a 5-day forecast for London, UK and save it to a file?" Weather with File Save: "Get the current weather for Tokyo, Japan and save the report" ","version":"Next","tagName":"h2"},{"title":"Key Features Demonstrated​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#key-features-demonstrated","content":" ","version":"Next","tagName":"h2"},{"title":"1. External API Integration​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#1-external-api-integration","content":" Proper HTTP session managementError handling for network issuesAPI response transformation ","version":"Next","tagName":"h3"},{"title":"2. Resource Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#2-resource-management","content":" Lifecycle functions for initialization and cleanupShared service instances across tool callsProper resource disposal ","version":"Next","tagName":"h3"},{"title":"3. Configuration Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#3-configuration-management","content":" Pydantic models for type-safe configurationEnvironment variable integrationFlexible tool configuration ","version":"Next","tagName":"h3"},{"title":"4. Error Handling​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#4-error-handling","content":" Comprehensive exception handlingUser-friendly error messagesLogging for debugging ","version":"Next","tagName":"h3"},{"title":"5. Artifact Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#5-artifact-management","content":" Saving structured data as filesMetadata enrichmentFile format handling ","version":"Next","tagName":"h3"},{"title":"Creating Agents","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents","content":"","keywords":"","version":"Next"},{"title":"Introduction​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#introduction","content":" tip For a more comprehensive tutorial example, see the Build Your Own Agent guide. This page provides an in-depth theoretical overview of creating agents in Solace Agent Mesh. Solace Agent Mesh is a powerful platform that enables you to create intelligent agents that can communicate with each other and perform complex tasks. At its core, Solace Agent Mesh uses a tool-based architecture where LLM-powered agents are equipped with specific capabilities (tools) that they can use to accomplish user requests. Before continuing with this tutorial, make sure you are familiar with the basic agent concept. This tutorial guides you through creating your first Solace Agent Mesh agent from scratch. You will learn how to: Define tools as Python functionsConfigure an agent using YAMLSet up agent lifecycle functions By the end of this tutorial, you should have a working "Hello World" agent that demonstrates the fundamental concepts of Solace Agent Mesh agent development. ","version":"Next","tagName":"h2"},{"title":"Quick Start: Creating Your First Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#quick-start-creating-your-first-agent","content":" You can create an agent directly using the Solace Agent Mesh CLI sam add agent: sam add agent my-first-agent This command: Launches an interactive setup (or use --gui for browser-based configuration)Generates the necessary files and configurationSets up the basic agent structure Note that create agent as plugin is preferred over create agent directly. ","version":"Next","tagName":"h2"},{"title":"CLI Options​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#cli-options","content":" You can customize the agent creation with provided CLI options. For a complete list of options, run: sam add agent --help ","version":"Next","tagName":"h3"},{"title":"Core Concepts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#core-concepts","content":" Before diving into the implementation, it is important to understand the key concepts that make Solace Agent Mesh agents work: ","version":"Next","tagName":"h2"},{"title":"Tools​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tools","content":" Tools are the fundamental building blocks of Solace Agent Mesh agents. Each tool is implemented as a Python function that performs a specific task. Tools can: Process text and dataInteract with external APIsCreate and manipulate filesCommunicate with other agentsAccess databases and services 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. tip Solace Agent Mesh provides a set of built-in tools plus support for model context protocol (MCP) servers, which can be configured in the tools list of your agent configuration. ","version":"Next","tagName":"h3"},{"title":"Configuration File​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#configuration-file","content":" The config.yaml (for plugin template) or agent-name.yaml (for agent instances) file is the blueprint of your agent. It defines: Agent identity: Name, description, and capabilitiesModel configuration: Which LLM to useTools list: Defines which tools the agent can access and how they're configuredLifecycle functions: Setup and cleanup proceduresFramework services: Session management, artifact storage, and so on.Agent card: Metadata describing the agent capabilities, skills and its visibility in the system ","version":"Next","tagName":"h3"},{"title":"Tool Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tool-configuration","content":" Within the tools list in your YAML config, each tool can have its own tool_config section. This allows you to: Configure the same tool function for different purposesPass specific parameters to tool instancesCustomize tool behavior per agent info For tools of type "python", you can also use the tool_name and tool_description to overwrite the function name and description in the tool docstring. 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. ","version":"Next","tagName":"h3"},{"title":"ToolContext​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#toolcontext","content":" The ToolContext object (passed as one of the arguments to your tool function) provides your tools with access to Solace Agent Mesh core services: Logging: Structured logging for debugging and monitoringArtifact Service: File storage and retrievalSession Information: Current user and session contextAgent State: Shared data between tool calls ","version":"Next","tagName":"h3"},{"title":"Lifecycle Functions​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#lifecycle-functions","content":" Lifecycle functions allow you to manage resources that should persist for the agent's lifetime: agent_init_function: Runs when the agent starts (for example, database connections)agent_cleanup_function: Runs when the agent shuts down (for example, closing connections) note Lifecycle functions are optional but recommended for managing resources effectively. ","version":"Next","tagName":"h3"},{"title":"Creating an Agent Plugin: Step-by-Step​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#creating-an-agent-plugin-step-by-step","content":" Create a simple agent that can greet users and demonstrate the core concepts. You can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create my-hello-agent --type agent. tip For information and recommendations about these options, see Agent or Plugin: Which To use?. ","version":"Next","tagName":"h2"},{"title":"Step 1: Initialize your Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-1-initialize-your-agent","content":" In this tutorial, you create a new agent by creating a new plugin of type agent. For an example of custom agents, see Build Your Own Agent guide. Although the directory structure for plugins is slightly different than the one for agents, both require a YAML configuration file, and a python module with the tools and lifecycle functions you want. To create a new agent plugin, run the following command: sam plugin create my-hello-agent --type agent And follow the prompts to set up your agent. The prompts create a new directory structure for your agent. my-hello-agent/ ├── src/ │ └── my_hello_agent/ │ ├── __init__.py │ ├── tools.py │ └── lifecycle.py # This file won't be automatically created ├── config.yaml ├── pyproject.toml └── README.md ","version":"Next","tagName":"h3"},{"title":"Step 2: The Tool Function​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-2-the-tool-function","content":" Create your first tool function: The following arguments are provided by the framework: tool_context: Solace Agent Mesh framework contexttool_config: Tool-specific configuration (from config.yaml) For a complete guide on creating python tools, see our Creating Python Tools documentation. # src/my_hello_agent/tools.py """ Tools for the Hello World agent. """ from typing import Any, Dict, Optional from google.adk.tools import ToolContext from solace_ai_connector.common.log import log async def hello_tool( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user with a personalized message. Args: name: The name of the person to greet Returns: A dictionary with the greeting message """ log_identifier = "[HelloTool]" log.info(f"{log_identifier} Greeting user: {name}") # Get configuration from tool_config greeting_prefix = "Hello" if tool_config: greeting_prefix = tool_config.get("greeting_prefix", "Hello") # Create the greeting message greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" log.info(f"{log_identifier} Generated greeting: {greeting_message}") return { "status": "success", "message": greeting_message, "greeted_name": name } async def farewell_tool( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Says goodbye to a user. Args: name: The name of the person to say goodbye to Returns: A dictionary with the farewell message """ log_identifier = "[FarewellTool]" log.info(f"{log_identifier} Saying goodbye to user: {name}") # Get configuration from tool_config farewell_prefix = "Goodbye" if tool_config: farewell_prefix = tool_config.get("farewell_prefix", "Goodbye") # Create the farewell message farewell_message = f"{farewell_prefix}, {name}! Thanks for using Solace Agent Mesh!" log.info(f"{log_identifier} Generated farewell: {farewell_message}") return { "status": "success", "message": farewell_message, "farewell_name": name } Key Points: Function Signature: All tool functions should be async and accept tool_context and tool_config parametersReturn Format: Return a dictionary with at least a status fieldLogging: Use the Solace Agent Mesh logger for consistent loggingConfiguration: Access tool-specific config via the tool_config parameter ","version":"Next","tagName":"h3"},{"title":"Step 3: The Agent Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-3-the-agent-configuration","content":" Create the main configuration file for your agent: # File: config.yaml (at root of project directory) # ... (additional services and configurations) apps: - name: my-hello-agent app_module: solace_agent_mesh.agent.sac.app broker: # Can be found in configs/shared_config.yaml after running sam init <<: *broker_connection # Agent-specific configuration app_config: # Basic agent identity namespace: ${NAMESPACE} supports_streaming: true agent_name: "HelloAgent" display_name: "Hello World Agent" # LLM model configuration model: *general_model # Agent instructions (system prompt) instruction: | You are a friendly Hello World agent. Your purpose is to greet users and demonstrate the capabilities of Solace Agent Mesh. You can: 1. Greet users with personalized messages using the hello_tool 2. Say goodbye to users using the farewell_tool Always be polite and helpful. When greeting someone, ask for their name if they haven't provided it. # Lifecycle functions agent_init_function: module: "my_hello_agent.lifecycle" # This should point to your lifecycle python module name: "initialize_hello_agent" base_path: . config: startup_message: "Hello Agent is starting up!" log_level: "INFO" agent_cleanup_function: module: "my_hello_agent.lifecycle" base_path: . name: "cleanup_hello_agent" # Tools configuration tools: # Hello tool with custom greeting - tool_type: python component_module: "my_hello_agent.tools" component_base_path: . function_name: "hello_tool" tool_name: "greet_user" # Renaming the tool, must use this name in the agent card tool_config: greeting_prefix: "Hello there" # Farewell tool with custom farewell - tool_type: python component_module: "my_hello_agent.tools" component_base_path: . function_name: "farewell_tool" tool_name: "say_goodbye" tool_config: farewell_prefix: "See you later" # Built-in artifact tools for file operations - tool_type: builtin-group group_name: "artifact_management" # Agent card (describes the agent's capabilities) agent_card: description: "A friendly Hello World agent that demonstrates Solace Agent Mesh capabilities" defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "greet_user" name: "Greet User" description: "Greets users with personalized messages" - id: "say_goodbye" name: "Say Goodbye" description: "Says goodbye to users" - id: "file_operations" name: "File Operations" description: "Create, read, and manage files and artifacts" # Session and artifact services session_service: *default_session_service artifact_service: *default_artifact_service # ... (additional services and configurations) Key Sections Explained: namespace: Unique identifier for your agent in the meshmodel: LLM configuration (can be a string or detailed config)instruction: The system prompt that defines your agent's behaviortools: List of tools your agent can use, with their configurationsagent_card: Metadata describing your agent's capabilities ","version":"Next","tagName":"h3"},{"title":"Step 4: The Lifecycle Function​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-4-the-lifecycle-function","content":" Lifecycle functions are completely optional but useful for managing resources. They run when the agent starts and stops. The lifecycle file is not automatically created, so you need to create it manually: touch src/my_hello_agent/lifecycle.py # src/my_hello_agent/lifecycle.py """ Lifecycle functions for the Hello World agent. """ from typing import Any, Dict from pydantic import BaseModel, Field from solace_ai_connector.common.log import log class HelloAgentInitConfig(BaseModel): """ Configuration model for the Hello Agent initialization. """ startup_message: str = Field(description="Message to log on startup") log_level: str = Field(default="INFO", description="Logging level for the agent") def initialize_hello_agent(host_component: Any, init_config: HelloAgentInitConfig): """ Initializes the Hello World agent. Args: host_component: The agent host component init_config: Validated initialization configuration """ log_identifier = f"[{host_component.agent_name}:init]" log.info(f"{log_identifier} Starting Hello Agent initialization...") # Log the startup message from config log.info(f"{log_identifier} {init_config.startup_message}") # You could initialize shared resources here, such as: # - Database connections # - API clients # - Caches or shared data structures # Store any shared state in the agent host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z") host_component.set_agent_specific_state("greeting_count", 0) log.info(f"{log_identifier} Hello Agent initialization completed successfully") def cleanup_hello_agent(host_component: Any): """ Cleans up resources when the Hello World agent shuts down. Args: host_component: The agent host component """ log_identifier = f"[{host_component.agent_name}:cleanup]" log.info(f"{log_identifier} Starting Hello Agent cleanup...") # Retrieve any shared state greeting_count = host_component.get_agent_specific_state("greeting_count", 0) log.info(f"{log_identifier} Agent processed {greeting_count} greetings during its lifetime") # Clean up resources here, such as: # - Closing database connections # - Shutting down background tasks # - Saving final state log.info(f"{log_identifier} Hello Agent cleanup completed") Key Points: Pydantic Models: Use Pydantic for configuration validationShared State: Store data that persists across tool callsResource Management: Initialize connections in init, clean up in cleanup ","version":"Next","tagName":"h3"},{"title":"Advanced Concepts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#advanced-concepts","content":" ","version":"Next","tagName":"h2"},{"title":"Working with Artifacts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#working-with-artifacts","content":" You can enhance our hello tool to save greetings to a file using Solace Agent Mesh's artifact service: from datetime import datetime from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata async def hello_tool_with_artifact( name: str, save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user and optionally saves the greeting to a file. """ log_identifier = "[HelloToolWithArtifact]" # Generate greeting (same as before) greeting_prefix = tool_config.get("greeting_prefix", "Hello") if tool_config else "Hello" greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" result = { "status": "success", "message": greeting_message, "greeted_name": name } # Save to artifact if requested if save_to_file and tool_context: try: # Prepare content timestamp = datetime.now(timezone.utc) filename = f"greeting_{name}_{timestamp}.txt" content = f"Greeting: {greeting_message}\\nTimestamp: {timestamp}\\n" # Save artifact artifact_service = tool_context._invocation_context.artifact_service await save_artifact_with_metadata( artifact_service=artifact_service, app_name=tool_context._invocation_context.app_name, user_id=tool_context._invocation_context.user_id, session_id=tool_context._invocation_context.session.id, filename=filename, content_bytes=content.encode('utf-8'), mime_type="application/json", metadata_dict={ "description": "Greeting message", "source": "Greeting Agent", }, timestamp=timestamp ) result["artifact_saved"] = filename log.info(f"{log_identifier} Saved greeting to artifact: {filename}") except Exception as e: log.error(f"{log_identifier} Failed to save artifact: {e}") result["artifact_error"] = str(e) return result ","version":"Next","tagName":"h3"},{"title":"Using Multiple Tool Configurations​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#using-multiple-tool-configurations","content":" You can configure the same tool function multiple times with different settings: tools: # Formal greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "formal_greeting" tool_config: greeting_prefix: "Good day" # Casual greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "casual_greeting" tool_config: greeting_prefix: "Hey there" # Enthusiastic greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "enthusiastic_greeting" tool_config: greeting_prefix: "Hello and welcome" This gives your agent multiple greeting styles to choose from based on the context. ","version":"Next","tagName":"h3"},{"title":"Running Your Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#running-your-agent","content":" To run a plugin agent, you first need to package and install it as a plugin. Quick Debug For debugging or isolated development testing, you can run your agent from the src directory directly using the Solace Agent Mesh CLI. cd src sam run ../config.yaml Changing to the src directory allows the module path to be set correctly so that Solace Agent Mesh can find your functions without your having to install them in your python environment as a plugin package. To properly instantiate your plugin agent, first build the plugin. The following command will produce a python wheel file under dist directory: sam plugin build Check into your Solace Agent Mesh project directory, and add the plugin wheel with a given name: sam plugin add my-first-weather-agent --plugin PATH/TO/weather-agent/dist/weather-agent.whl note Using the sam plugin add command installs your plugin as a python dependency into your python environment. This also means changing the source code without reinstalling the plugin will not reflect the changes. Now, you can run the complete Solace Agent Mesh application along with your newly added agent: sam run Alternatively, only run the newly added agent using sam run configs/agents/my-first-weather-agent.yaml ","version":"Next","tagName":"h2"},{"title":"Architecture Overview​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#architecture-overview","content":" Here is how all the pieces fit together: ","version":"Next","tagName":"h2"},{"title":"Best Practices​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#best-practices","content":" ","version":"Next","tagName":"h2"},{"title":"Tool Design​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tool-design","content":" Single Responsibility: Each tool should do one thing wellClear Documentation: Write detailed docstrings for your toolsError Handling: Always return structured error responsesLogging: Use consistent logging for debugging and monitoring ","version":"Next","tagName":"h3"},{"title":"Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#configuration","content":" Environment Variables: Use environment variables for sensitive dataValidation: Use Pydantic models for configuration validationDocumentation: Comment your configuration files thoroughly ","version":"Next","tagName":"h3"},{"title":"Testing​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#testing","content":" Unit Tests: Test your tool functions independentlyIntegration Tests: Test your agent with real Solace Agent Mesh infrastructureMock Dependencies: Mock external services for reliable testing ","version":"Next","tagName":"h3"},{"title":"Solace AI Event Connector","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector","content":"","keywords":"","version":"Next"},{"title":"Key Features​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#key-features","content":" Event Processing Pipeline: Creates flows consisting of input components, processing components, and output components.AI Model Integration: Built on LangChain and LiteLLM supporting various AI models and providers.Extensible Architecture: Supports custom plugins and components for specialized processing needs.Resilient Processing: Ensures reliable event handling with acknowledgment-based processing.Scalable Design: Supports parallel processing and multiple component instances. ","version":"Next","tagName":"h2"},{"title":"How It Works​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#how-it-works","content":" Solace AI Event Connector operates through a series of interconnected components: Flow Structure Each flow has one input componentMultiple processing componentsOne output componentComponents are connected via queues for buffering Component Processing Each component runs in its own threadProcesses one message at a timeSupports input transforms and selectionsCan be scaled with multiple instances for parallel processing Event Management Tracks events throughout the processing pipelineUses acknowledgment system for reliable deliveryEnsures no event loss during processing ","version":"Next","tagName":"h2"},{"title":"Configuration​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#configuration","content":" The Solace AI Event Connector is configured through YAML files that allow you to: Define flow components and their sequenceSet queue depths between componentsConfigure the number of parallel instancesSpecify input/output parametersDefine processing logic and transformationsPass the source path for the custom python components For more information about the connector, see Solace AI Event Connector. ","version":"Next","tagName":"h2"},{"title":"Creating Service Providers","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers","content":"","keywords":"","version":"Next"},{"title":"Understanding Service Providers​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#understanding-service-providers","content":" Service Providers function as the abstraction layer between Solace Agent Mesh and enterprise data sources. They are implemented as Python classes that adhere to a specific abstract base class, enabling standardized interaction between Solace Agent Mesh components (Gateways and Agents) and the underlying data. There are two primary service provider interfaces: BaseIdentityService: Responsible for identity enrichment. This service is utilized by Gateways to augment the profile of an authenticated user with additional details (for example, full name, job title) based on their initial authentication claims.BaseEmployeeService: Responsible for general directory querying. This service is utilized by agents (for example, the EmployeeAgent) to execute lookups across the entire employee directory. ","version":"Next","tagName":"h2"},{"title":"The \"Dual-Role Provider\" Pattern​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#the-dual-role-provider-pattern","content":" In many enterprise systems, particularly HR platforms, the data source for identity enrichment and general employee queries is identical. To optimize development, Solace Agent Mesh promotes a "Dual-Role Provider" pattern. This pattern involves creating a single class that inherits from both BaseIdentityService and BaseEmployeeService. This consolidated class can then be configured to fulfill either or both roles, thereby reducing code duplication. ","version":"Next","tagName":"h2"},{"title":"Step-by-Step Implementation Guide​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-by-step-implementation-guide","content":" This section provides a walkthrough for creating a new provider for a fictional "CorpHR" system. ","version":"Next","tagName":"h2"},{"title":"Step 1: Establish the Plugin Structure​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-1-establish-the-plugin-structure","content":" The recommended structure for a custom service provider plugin should include a pyproject.toml for packaging and a src directory for the source code. sam plugin create my_corp_hr_provider --type custom ","version":"Next","tagName":"h3"},{"title":"Step 2: Define the Provider Class​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-2-define-the-provider-class","content":" Create a provider.py module and define the provider class, ensuring it inherits from both base service classes. # my_corp_hr_provider/provider.py # Import base classes from the Solace Agent Mesh framework try: from solace_agent_mesh.common.services.identity_service import BaseIdentityService from solace_agent_mesh.common.services.employee_service import BaseEmployeeService except ImportError: # Fallback for local development environments from src.solace_agent_mesh.common.services.identity_service import BaseIdentityService from src.solace_agent_mesh.common.services.employee_service import BaseEmployeeService # Import any other necessary libraries, such as 'requests' or a proprietary SDK # from .corp_hr_sdk import CorpHR_SDK class CorpHRProvider(BaseIdentityService, BaseEmployeeService): """ A dual-role provider for the CorpHR system, implementing methods for both identity enrichment and employee directory services. """ def __init__(self, config): super().__init__(config) # Initialize the backend service/SDK client here. # It is best practice to implement this as a singleton to share # connection pools and cache. # self.corp_hr_sdk = CorpHR_SDK(api_key=config.get("api_key")) # --- BaseIdentityService Method Implementations --- async def get_user_profile(self, auth_claims): """Enrich the current user's profile based on their auth claims.""" # TODO: Implement logic to fetch user data from CorpHR pass async def search_users(self, query, limit=10): """Search for users, for features like @-mentions.""" # TODO: Implement user search logic against CorpHR pass # --- BaseEmployeeService Method Implementations --- async def get_employee_dataframe(self): """Return all employees as a pandas DataFrame for directory-wide queries.""" # TODO: Fetch all employee data and return as a DataFrame pass async def get_employee_profile(self, employee_id): """Get a single employee's full profile by their ID.""" # Note: This is a general directory lookup, distinct from get_user_profile. # TODO: Implement single employee lookup pass async def get_time_off_data(self, employee_id): """Get an employee's raw time off data.""" # Example return format: # return [{'start': '2025-07-04', 'end': '2025-07-04', 'type': 'Holiday'}] # TODO: Implement time off data retrieval pass async def get_employee_profile_picture(self, employee_id): """Fetch a profile picture as a data URI string.""" # Example return format: "data:image/jpeg;base64,..." # TODO: Implement profile picture fetching pass ","version":"Next","tagName":"h3"},{"title":"Step 3: Map to the Canonical Employee Schema​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-3-map-to-the-canonical-employee-schema","content":" When implementing the service methods, it is mandatory to map the data from the source system to Solace Agent Mesh's canonical employee schema. This ensures data consistency and interoperability with all tools and components across the mesh. Field Name\tData Type\tDescriptionid\tstring\tA unique, stable, and lowercase identifier (e.g., email, GUID). displayName\tstring\tThe employee's full name for display purposes. workEmail\tstring\tThe employee's primary work email address. jobTitle\tstring\tThe employee's official job title. department\tstring\tThe department to which the employee belongs. location\tstring\tThe physical or regional location of the employee. supervisorId\tstring\tThe unique id of the employee's direct manager. hireDate\tstring\tThe date the employee was hired (ISO 8601: YYYY-MM-DD). mobilePhone\tstring\tThe employee's mobile phone number (optional). info If a field is not available in the source system, return None or omit the key from the returned dictionary. ","version":"Next","tagName":"h3"},{"title":"Step 4: Register the Plugin​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-4-register-the-plugin","content":" To make the provider discoverable by Solace Agent Mesh, it must be registered as a plugin via entry points. 1. Add an entry point in pyproject.toml:The key assigned here (corphr) is used as the type identifier in YAML configurations. [project.entry-points."solace_agent_mesh.plugins"] corphr = "my_corp_hr_provider:info" 2. Define the info object in the plugin's __init__.py:This object points to the provider's class path and provides a brief description. # my_corp_hr_provider/__init__.py info = { "class_path": "my_corp_hr_provider.provider.CorpHRProvider", "description": "Identity and People Service provider for CorpHR.", } ","version":"Next","tagName":"h3"},{"title":"Configuring the Provider​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#configuring-the-provider","content":" Once the plugin is created and installed (for example, via pip install .), it can be configured in any Gateway or Agent app_config.yml. For a Gateway (Identity Service Role): app_config: identity_service: type: "corphr" # Matches the key in pyproject.toml api_key: "${CORPHR_API_KEY}" lookup_key: "email" # The field from auth_claims to use for lookup For an Agent (Employee Service Role):This example demonstrates configuring the provider for the employee_tools group. app_config: tools: - tool_type: builtin-group group_name: "employee_tools" config: type: "corphr" # Same provider, different role api_key: "${CORPHR_API_KEY}" ","version":"Next","tagName":"h2"},{"title":"Structure","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/structure","content":"","keywords":"","version":"Next"},{"title":"Project Structure​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#project-structure","content":" A fresh Solace Agent Mesh project follows this structure: my-sam-project/ ├── configs/ │ ├── shared_config.yaml # Shared broker, models, and services config │ ├── agents/ │ │ └── main_orchestrator.yaml # Default orchestrator agent │ └── gateways/ │ │ └── webui.yaml # Default web UI gateway │ ├── plugins/ ├── src/ # Custom Python components (optional) │ └── __init__.py ","version":"Next","tagName":"h2"},{"title":"Configuration Organization​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#configuration-organization","content":" ","version":"Next","tagName":"h2"},{"title":"Directory Structure​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#directory-structure","content":" The configs/ directory uses a logical organization: agents/ - Contains agent configuration filesgateways/ - Contains gateway configuration filesplugins/ - Contains plugin configuration files (created when plugins are added) Further subdirectories can be created within agents/, gateways/, and plugins/ to organize configurations by functionality or purpose. File Discovery The CLI automatically crawls through the configs directory to find configuration files. Files that start with _ (underscore) or shared_config are ignored and not processed by the CLI. For example: _example_agent.yaml is ignoredshared_config_for_db_agents.yaml is ignored (Can still be included in other config files using !include directive) ","version":"Next","tagName":"h3"},{"title":"Shared Configuration​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#shared-configuration","content":" The shared_config.yaml file is the foundation of your project configuration. It contains common elements that are reused across all agents and gateways using YAML anchors: Broker Connection: Solace PubSub+ broker settings for A2A communicationModel Definitions: LLM model configurations (planning, general, multimodal, etc.)Services: Artifact service, session service, and data tools configuration This shared configuration approach eliminates duplication and ensures consistency across your entire project. Each agent and gateway configuration file references these shared elements using YAML anchor syntax (*reference_name). Further values can be added to the shared configuration file as needed, and they are available to all agents and gateways that include it. ","version":"Next","tagName":"h3"},{"title":"YAML Configuration Files​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#yaml-configuration-files","content":" Each configuration file defines one [recommended] or more applications that can be run independently. The framework supports: Agent Applications: A2A-enabled agents that use Google ADK runtime and Solace Agent Mesh frameworkGateway Applications: Protocol translators that bridge external interfaces to adopted A2A protocolPlugin Applications: Specialized components that extend framework capabilities ","version":"Next","tagName":"h2"},{"title":"Configuration Management​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#configuration-management","content":" Environment Variables: Configuration values use environment variables for flexibility across environmentsShared Configuration: Common settings are defined once in shared_config.yaml and referenced using YAML anchors (& and *)Automatic Generation: The sam add agent, sam add gateway, and sam plugin add commands automatically generate appropriate configuration filesStandalone Execution: Each configuration file can be run independently using sam run <config-file> ","version":"Next","tagName":"h2"},{"title":"Python Components​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#python-components","content":" While most functionality is configured through YAML, custom Python components can be added to the src/ directory when needed. The framework provides base classes for extending functionality such as custom agent tools, gateway protocol handlers, and service providers. ","version":"Next","tagName":"h2"},{"title":"Creating Python Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools","content":"","keywords":"","version":"Next"},{"title":"Tool Creation Patterns​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#tool-creation-patterns","content":" There are three primary patterns for creating Python tools, ranging from simple to advanced. You can choose the best pattern for your needs, and even mix and match them within the same project. Pattern\tBest For\tKey FeatureFunction-Based\tSimple, self-contained tools with static inputs.\tQuick and easy; uses function signature. Single DynamicTool Class\tTools that require complex logic or a programmatically defined interface.\tFull control over the tool's definition. DynamicToolProvider Class\tGenerating multiple related tools from a single, configurable source.\tMaximum scalability and code reuse. All three patterns are configured in your agent's YAML file under the tools list with tool_type: python. ","version":"Next","tagName":"h2"},{"title":"Pattern 1: Simple Function-Based Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-1-simple-function-based-tools","content":" This is the most straightforward way to create a custom tool. You define a standard Python async function, and Solace Agent Mesh automatically introspects its signature and docstring to create the tool definition for the LLM. ","version":"Next","tagName":"h2"},{"title":"Step 1: Write the Tool Function​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-write-the-tool-function","content":" Create a Python file (e.g., src/my_agent/tools.py) and define your tool. # src/my_agent/tools.py from typing import Any, Dict, Optional from google.adk.tools import ToolContext async def greet_user( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user with a personalized message. Args: name: The name of the person to greet. Returns: A dictionary with the greeting message. """ greeting_prefix = "Hello" if tool_config: greeting_prefix = tool_config.get("greeting_prefix", "Hello") greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" return { "status": "success", "message": greeting_message } Key Requirements: The function must be async def.The function's docstring is used as the tool's description for the LLM.Type hints (str, int, bool) are used to generate the parameter schema.The function should accept tool_context and tool_config as optional keyword arguments to receive framework context and YAML configuration. ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Tool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-tool","content":" In your agent's YAML configuration, add a tool_type: python block and point it to your function. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.tools" function_name: "greet_user" tool_config: greeting_prefix: "Greetings" component_module: The Python module path to your tools file.function_name: The exact name of the function to load.tool_config: An optional dictionary passed to your tool at runtime. ","version":"Next","tagName":"h3"},{"title":"Pattern 2: Advanced Single-Class Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-2-advanced-single-class-tools","content":" For tools that require more complex logic—such as defining their interface programmatically based on configuration—you can use a class that inherits from DynamicTool. ","version":"Next","tagName":"h2"},{"title":"Step 1: Create the DynamicTool Class​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-create-the-dynamictool-class","content":" Instead of a function, define a class that implements the DynamicTool abstract base class. # src/my_agent/tools.py from typing import Optional, Dict, Any from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool class WeatherTool(DynamicTool): """A dynamic tool that fetches current weather information.""" @property def tool_name(self) -> str: return "get_current_weather" @property def tool_description(self) -> str: return "Get the current weather for a specified location." @property def parameters_schema(self) -> adk_types.Schema: # Programmatically define the tool's parameters return adk_types.Schema( type=adk_types.Type.OBJECT, properties={ "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."), "units": adk_types.Schema(type=adk_types.Type.STRING, enum=["celsius", "fahrenheit"], nullable=True), }, required=["location"], ) async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]: location = args["location"] # Access config via self.tool_config api_key = self.tool_config.get("api_key") if not api_key: return {"status": "error", "message": "API key not configured"} # ... implementation to call weather API ... return {"status": "success", "weather": "Sunny"} ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Tool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-tool-1","content":" The YAML configuration is very similar. You can either specify the class_name or let Solace Agent Mesh auto-discover it if it's the only DynamicTool in the module. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.tools" # class_name: WeatherTool # Optional if it's the only one tool_config: api_key: ${WEATHER_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Pattern 3: The Tool Provider Factory​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-3-the-tool-provider-factory","content":" This is the most powerful pattern, designed for generating multiple, related tools from a single module and configuration block. It's perfect for creating toolsets based on external schemas, database tables, or other dynamic sources. ","version":"Next","tagName":"h2"},{"title":"Step 1: Create the Provider and Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-create-the-provider-and-tools","content":" In your tools module, you define your DynamicTool classes as before, but you also create a provider class that inherits from DynamicToolProvider. This provider acts as a factory. You can also use the @register_tool decorator on simple functions to have them automatically included by the provider. # src/my_agent/database_tools.py from typing import Optional, Dict, Any, List from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider # --- Tool Implementations --- class DatabaseQueryTool(DynamicTool): # ... (implementation as in previous examples) ... pass class DatabaseSchemaTool(DynamicTool): # ... (implementation as in previous examples) ... pass # --- Tool Provider Implementation --- class DatabaseToolProvider(DynamicToolProvider): """A factory that creates all database-related tools.""" # Use a decorator for a simple, function-based tool def create_tools(self, tool_config: Optional[dict] = None) -> List[DynamicTool]: """ Generates a list of all database tools, passing the shared configuration to each one. """ # 1. Create tools from any decorated functions in this module tools = self._create_tools_from_decorators(tool_config) # 2. Programmatically create and add more complex tools if tool_config and tool_config.get("connection_string"): tools.append(DatabaseQueryTool(tool_config=tool_config)) tools.append(DatabaseSchemaTool(tool_config=tool_config)) return tools # NOTE that you must use the decorator outside of any class with the provider's class name. @DatabaseToolProvider.register_tool async def get_database_server_version(tool_config: dict, **kwargs) -> dict: """Returns the version of the connected PostgreSQL server.""" # ... implementation ... return {"version": "PostgreSQL 15.3"} ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Provider​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-provider","content":" You only need a single YAML block. Solace Agent Mesh will automatically detect the DynamicToolProvider and use it to load all the tools it generates. # In your agent's app_config: tools: # This single block loads get_database_server_version, # execute_database_query, and get_database_schema. - tool_type: python component_module: "my_agent.database_tools" tool_config: connection_string: ${DB_CONNECTION_STRING} max_rows: 1000 This approach is incredibly scalable, as one configuration entry can bootstrap an entire suite of dynamically generated tools. ","version":"Next","tagName":"h3"},{"title":"Managing Tool Lifecycles with init and cleanup​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#managing-tool-lifecycles-with-init-and-cleanup","content":" For tools that need to manage resources—such as database connections, API clients, or temporary files—Solace Agent Mesh provides optional init and cleanup lifecycle hooks. These allow you to run code when the agent starts up and shuts down, ensuring that resources are acquired and released gracefully. There are two ways to define these hooks: YAML-based (init_function, cleanup_function): A flexible method that works for any Python tool, including simple function-based ones.Class-based (init, cleanup methods): The idiomatic and recommended way for DynamicTool and DynamicToolProvider classes. ","version":"Next","tagName":"h2"},{"title":"YAML-Based Lifecycle Hooks​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#yaml-based-lifecycle-hooks","content":" You can add init_function and cleanup_function to any Python tool's configuration in your agent's YAML. The lifecycle functions must be defined in the same module as the tool itself. Step 1: Define the Tool and Hook Functions​ In your tool's Python file (e.g., src/my_agent/db_tools.py), define the tool function and its corresponding init and cleanup functions. These functions must be async and will receive the agent component instance and the tool's configuration model object as arguments. # src/my_agent/db_tools.py from solace_agent_mesh.agent.sac.component import SamAgentComponent from solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig from google.adk.tools import ToolContext from typing import Dict, Any # --- Lifecycle Hooks --- async def initialize_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig): """Initializes a database connection and stores it for the agent to use.""" print("INFO: Initializing database connection...") # In a real scenario, you would create a client instance db_client = {"connection_string": tool_config_model.tool_config.get("connection_string")} # Store the client in a shared state accessible by the component component.set_agent_specific_state("db_client", db_client) print("INFO: Database client initialized.") async def close_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig): """Retrieves and closes the database connection.""" print("INFO: Closing database connection...") db_client = component.get_agent_specific_state("db_client") if db_client: # In a real scenario, you would call db_client.close() print("INFO: Database connection closed.") # --- Tool Function --- async def query_database(query: str, tool_context: ToolContext, **kwargs) -> Dict[str, Any]: """Queries the database using the initialized connection.""" host_component = tool_context._invocation_context.agent.host_component db_client = host_component.get_agent_specific_state("db_client") if not db_client: return {"error": "Database connection not initialized."} # ... use db_client to run query ... return {"result": "some data"} Step 2: Configure the Hooks in YAML​ In your YAML configuration, reference the lifecycle functions by name. The framework will automatically look for them in the component_module. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.db_tools" function_name: "query_database" tool_config: connection_string: "postgresql://user:pass@host/db" # Initialize the tool on startup init_function: "initialize_db_connection" # Clean up the tool on shutdown cleanup_function: "close_db_connection" ","version":"Next","tagName":"h3"},{"title":"Class-Based Lifecycle Methods (for DynamicTool)​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#class-based-lifecycle-methods-for-dynamictool","content":" For tools built with DynamicTool or DynamicToolProvider, the recommended approach is to override the init and cleanup methods directly within the class. This co-locates the entire tool's logic and improves encapsulation. Example: Adding Lifecycle Methods to a DynamicTool Here, we extend a DynamicTool to manage its own API client. # src/my_agent/api_tool.py from solace_agent_mesh.agent.sac.component import SamAgentComponent from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool from solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig # Assume WeatherApiClient is a custom class for an external service from my_agent.api_client import WeatherApiClient class WeatherTool(DynamicTool): """A dynamic tool that fetches weather and manages its own API client.""" async def init(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None: """Initializes the API client when the agent starts.""" print("INFO: Initializing Weather API client...") # self.tool_config is the validated Pydantic model or dict from YAML api_key = self.tool_config.get("api_key") self.api_client = WeatherApiClient(api_key=api_key) print("INFO: Weather API client initialized.") async def cleanup(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None: """Closes the API client connection when the agent shuts down.""" print("INFO: Closing Weather API client...") if hasattr(self, "api_client"): await self.api_client.close() print("INFO: Weather API client closed.") # ... other required properties like tool_name, tool_description, etc. ... async def _run_async_impl(self, args: dict, **kwargs) -> dict: """Uses the initialized client to perform its task.""" location = args.get("location") if not hasattr(self, "api_client"): return {"error": "API client not initialized. Check lifecycle hooks."} weather_data = await self.api_client.get_weather(location) return {"weather": weather_data} The YAML configuration remains simple, as the lifecycle logic is now part of the tool's code. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.api_tool" class_name: "WeatherTool" tool_config: api_key: ${WEATHER_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Execution Order and Guarantees​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#execution-order-and-guarantees","content":" It's important to understand the order in which lifecycle hooks are executed, especially if you mix both YAML-based and class-based methods for a single tool. Initialization (init): All init hooks are awaited during agent startup. A failure in any init hook will prevent the agent from starting. The YAML-based init_function is executed first.The class-based init() method is executed second. Cleanup (cleanup): All registered cleanup hooks are executed during agent shutdown. They run in LIFO (Last-In, First-Out) order relative to initialization. The class-based cleanup() method is executed first.The YAML-based cleanup_function is executed second. This LIFO order for cleanup is intuitive: the resource that was initialized last is the first one to be torn down. ","version":"Next","tagName":"h3"},{"title":"Adding Validated Configuration to Dynamic Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#adding-validated-configuration-to-dynamic-tools","content":" For any class-based tool (DynamicTool or DynamicToolProvider) that requires configuration, this is the recommended pattern. By linking a Pydantic model to your tool class, you can add automatic validation and type safety to your tool_config. This provides several key benefits: Automatic Validation: The agent will fail to start if the YAML configuration doesn't match your model, providing clear error messages.Type Safety: Inside your tool, self.tool_config is a fully typed Pydantic object, not a dictionary, enabling autocompletion and preventing common errors.Self-Documentation: The Pydantic model itself serves as clear, machine-readable documentation for your tool's required configuration. ","version":"Next","tagName":"h2"},{"title":"Example 1: Using a Pydantic Model with a Single DynamicTool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#example-1-using-a-pydantic-model-with-a-single-dynamictool","content":" This example shows how to add a validated configuration to a standalone DynamicTool class. Step 1: Define the Model and Tool Class​ In your tools file, define a pydantic.BaseModel for your configuration. Then, in your DynamicTool class, link to it using the config_model class attribute. # src/my_agent/weather_tools.py from typing import Dict, Any from pydantic import BaseModel, Field from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool # 1. Define the configuration model class WeatherConfig(BaseModel): api_key: str = Field(..., description="The API key for the weather service.") default_unit: str = Field(default="celsius", description="The default temperature unit.") # 2. Create a tool and link the config model class GetCurrentWeatherTool(DynamicTool): config_model = WeatherConfig def __init__(self, tool_config: WeatherConfig): super().__init__(tool_config) # self.tool_config is now a validated WeatherConfig instance # You can safely access attributes with type safety self.api_key = self.tool_config.api_key self.unit = self.tool_config.default_unit @property def tool_name(self) -> str: return "get_current_weather" @property def tool_description(self) -> str: return f"Get the current weather. The default unit is {self.unit}." @property def parameters_schema(self) -> adk_types.Schema: return adk_types.Schema( type=adk_types.Type.OBJECT, properties={ "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."), }, required=["location"], ) async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]: # ... implementation using self.api_key ... return {"weather": f"Sunny in {args['location']}"} Step 2: Configure the Tool in YAML​ The YAML configuration remains simple. The framework handles the validation against your Pydantic model automatically. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.weather_tools" # The framework will auto-discover the GetCurrentWeatherTool class tool_config: api_key: ${WEATHER_API_KEY} default_unit: "fahrenheit" # Optional, overrides the model's default If you were to forget api_key in the YAML, the agent would fail to start and print a clear error message indicating that the api_key field is required, making debugging configuration issues much easier. ","version":"Next","tagName":"h3"},{"title":"Example 2: Using a Pydantic Model with a DynamicToolProvider​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#example-2-using-a-pydantic-model-with-a-dynamictoolprovider","content":" The same pattern applies to tool providers, allowing you to pass a validated, type-safe configuration object to your tool factory. Step 1: Define the Model and Provider Class​ # src/my_agent/weather_tools_provider.py from typing import List from pydantic import BaseModel, Field from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider # ... assume GetCurrentWeatherTool is defined in this file or imported ... # 1. Define the configuration model class WeatherProviderConfig(BaseModel): api_key: str = Field(..., description="The API key for the weather service.") default_unit: str = Field(default="celsius", description="The default temperature unit.") # 2. Create a provider and link the config model class WeatherToolProvider(DynamicToolProvider): config_model = WeatherProviderConfig def create_tools(self, tool_config: WeatherProviderConfig) -> List[DynamicTool]: # The framework passes a validated WeatherProviderConfig instance here return [ GetCurrentWeatherTool(tool_config=tool_config) # You could create other tools here that also use the config ] Step 2: Configure the Provider in YAML​ # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.weather_tools_provider" # The framework will auto-discover the WeatherToolProvider tool_config: api_key: ${WEATHER_API_KEY} default_unit: "fahrenheit" # Optional, overrides the model's default ","version":"Next","tagName":"h3"},{"title":"Create Gateways","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways","content":"","keywords":"","version":"Next"},{"title":"What Are Gateways?​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#what-are-gateways","content":" A gateway acts as a translator and coordinator that: Receives events, messages, or data from external systemsAuthenticates and authorizes external interactionsTranslates external data into standardized A2A Task formatSubmits tasks to target A2A agents for processingReceives responses and status updates from agentsTranslates A2A responses back to external system formatSends results back to the originating external system ","version":"Next","tagName":"h2"},{"title":"Quick Start: Creating Your First Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#quick-start-creating-your-first-gateway","content":" You can create a gateway directly using the Solace Agent Mesh CLI sam add gateway: sam add gateway my-custom-gateway This command: Launches an interactive setup (or use --gui for browser-based configuration)Generates the necessary files and configurationSets up the basic gateway structure ","version":"Next","tagName":"h2"},{"title":"CLI Options​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#cli-options","content":" You can customize the gateway creation with these options: sam add gateway my-gateway \\ --namespace "myorg/dev" \\ --gateway-id "my-custom-gw-id" \\ --artifact-service-type "filesystem" \\ --artifact-service-base-path "var/data/my-gateway-artifacts" \\ --system-purpose "This gateway processes external data feeds" \\ --response-format "Agents should respond with structured JSON" For a complete list of options, run: sam add gateway --help ","version":"Next","tagName":"h3"},{"title":"Gateway Architecture​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-architecture","content":" Every Solace Agent Mesh gateway consists of two main components: ","version":"Next","tagName":"h2"},{"title":"Gateway App​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-app","content":" Gateway App (app.py): Defines configuration schemaManages gateway-level settingsLinks to the gateway component ","version":"Next","tagName":"h3"},{"title":"Gateway Component​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-component","content":" Gateway Component (component.py): Contains the core business logicHandles external system integrationImplements required abstract methods ","version":"Next","tagName":"h3"},{"title":"Step-by-Step Tutorial​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-by-step-tutorial","content":" Let's create a practical example, Directory Monitor Gateway, a gateway that monitors a directory for new files and sends them to agents for processing. You can create a gateway using either sam add gateway <your_gateway_name> command directly or sam plugin create <your_gateway_plugin_name> --type gateway command as gateway plugin. Gateway as plugin Gateways can also be implemented as plugins. This allows you to easily package your gateway logic and reuse it across different projects. To create a plugin of type gateway, use the sam plugin create <your_gateway_plugin_name> --type gateway command. For a complete list of options, run: sam plugin create --help To create a gateway instance based on a plugin, use the sam plugin add <your_gateway_name> --plugin <your_gateway_plugin> command. For a complete list of options, run: sam plugin add --help Although the specific directory structure may differ from standalone gateways, the core concepts remain the same. The core files remain the same: app.py, component.py, and the YAML configuration file. ","version":"Next","tagName":"h2"},{"title":"Step 1: Generate the Gateway Structure​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-1-generate-the-gateway-structure","content":" This tutorial shows you how to create a new gateway with the sam add gateway command. sam add gateway dir-monitor This creates: configs/gateways/dir_monitor_config.yaml - Configuration filesrc/dir_monitor/app.py - Gateway app classsrc/dir_monitor/component.py - Gateway component class ","version":"Next","tagName":"h3"},{"title":"Step 2: Define Configuration Schema​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-2-define-configuration-schema","content":" Define Configuration Schema (app.py) # src/dir_monitor/app.py from typing import Any, Dict, List, Type from solace_ai_connector.common.log import log from solace_agent_mesh.gateway.base.app import BaseGatewayApp from solace_agent_mesh.gateway.base.component import BaseGatewayComponent from .component import DirMonitorGatewayComponent # Module info required by SAC info = { "class_name": "DirMonitorGatewayApp", "description": "Custom App class for the A2A DirMonitor Gateway.", } class DirMonitorGatewayApp(BaseGatewayApp): """ Directory Monitor Gateway App Extends BaseGatewayApp with directory monitoring specific configuration. """ # Define gateway-specific configuration parameters SPECIFIC_APP_SCHEMA_PARAMS: List[Dict[str, Any]] = [ { "name": "directory_path", "required": True, "type": "string", "description": "The directory path to monitor for changes.", }, { "name": "target_agent_name", "required": False, "type": "string", "default": "OrchestratorAgent", "description": "The A2A agent to send tasks to.", }, { "name": "default_user_identity", "required": False, "type": "string", "default": "dir_monitor_user", "description": "Default user identity for A2A tasks.", }, { "name": "error_directory_path", "required": True, "type": "string", "description": "Directory to move files if processing fails.", }, ] def __init__(self, app_info: Dict[str, Any], **kwargs): log_prefix = app_info.get("name", "DirMonitorGatewayApp") log.info("[%s] Initializing Directory Monitor Gateway App...", log_prefix) super().__init__(app_info=app_info, **kwargs) log.info("[%s] Directory Monitor Gateway App initialized.", self.name) def _get_gateway_component_class(self) -> Type[BaseGatewayComponent]: """Returns the gateway component class for this app.""" return DirMonitorGatewayComponent ","version":"Next","tagName":"h3"},{"title":"Step 3: Implement Core Logic​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-3-implement-core-logic","content":" Implement Core Logic (component.py) # src/dir_monitor/component.py import asyncio import os import shutil import mimetypes import threading from typing import Any, Dict, List, Optional, Tuple, Union from datetime import datetime, timezone from solace_ai_connector.common.log import log # Import watchdog for file system monitoring try: from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler WATCHDOG_AVAILABLE = True except ImportError: WATCHDOG_AVAILABLE = False Observer = None FileSystemEventHandler = None from solace_agent_mesh.gateway.base.component import BaseGatewayComponent from solace_agent_mesh.common.types import ( Part as A2APart, TextPart, FilePart, Task, TaskStatusUpdateEvent, TaskArtifactUpdateEvent, JSONRPCError, FileContent, ) from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata # Component info info = { "class_name": "DirMonitorGatewayComponent", "description": "Monitors directories for new files and processes them via A2A agents.", } class DirMonitorGatewayComponent(BaseGatewayComponent): """ Directory Monitor Gateway Component Watches a directory and creates A2A tasks for new files. """ def __init__(self, **kwargs: Any): super().__init__(**kwargs) log.info("%s Initializing Directory Monitor Gateway Component...", self.log_identifier) # Check if watchdog is available if not WATCHDOG_AVAILABLE: log.error("%s Watchdog library not found. Install with: pip install watchdog", self.log_identifier) raise ImportError("Watchdog library required for directory monitoring") # Load configuration try: self.directory_path = self.get_config("directory_path") self.target_agent_name = self.get_config("target_agent_name", "OrchestratorAgent") self.default_user_identity_id = self.get_config("default_user_identity", "dir_monitor_user") self.error_directory_path = self.get_config("error_directory_path") # Validate directories if not os.path.isdir(self.directory_path): raise ValueError(f"Monitor directory not found: {self.directory_path}") os.makedirs(self.error_directory_path, exist_ok=True) log.info("%s Monitoring: %s, Error dir: %s", self.log_identifier, self.directory_path, self.error_directory_path) except Exception as e: log.error("%s Configuration error: %s", self.log_identifier, e) raise # Initialize monitoring components self.observer: Optional[Observer] = None self.watchdog_thread: Optional[threading.Thread] = None log.info("%s Directory Monitor Gateway Component initialized.", self.log_identifier) class DirWatchEventHandler(FileSystemEventHandler): """Handles file system events from Watchdog.""" def __init__(self, component_ref: 'DirMonitorGatewayComponent'): super().__init__() self.component_ref = component_ref self.log_identifier = f"{component_ref.log_identifier}[FileHandler]" def on_created(self, event): if event.is_directory: return file_path = event.src_path log.info("%s New file detected: %s", self.log_identifier, file_path) # Bridge to async loop if self.component_ref.async_loop and self.component_ref.async_loop.is_running(): asyncio.run_coroutine_threadsafe( self.component_ref._process_new_file(file_path), self.component_ref.async_loop ) else: log.error("%s Async loop not available for file: %s", self.log_identifier, file_path) def generate_uuid(self) -> str: """Generate a unique identifier.""" import uuid return str(uuid.uuid4()) def _start_listener(self) -> None: """Start the directory monitoring listener.""" log_id_prefix = f"{self.log_identifier}[StartListener]" log.info("%s Starting directory monitor for: %s", log_id_prefix, self.directory_path) if not WATCHDOG_AVAILABLE: log.error("%s Watchdog not available", log_id_prefix) self.stop_signal.set() return # Set up file system observer self.observer = Observer() event_handler = self.DirWatchEventHandler(self) self.observer.schedule(event_handler, self.directory_path, recursive=False) # Start observer in separate thread self.watchdog_thread = threading.Thread( target=self._run_observer, name=f"{self.name}_WatchdogThread", daemon=True ) self.watchdog_thread.start() log.info("%s Directory monitor started", log_id_prefix) def _run_observer(self): """Run the watchdog observer.""" if not self.observer: return log_id_prefix = f"{self.log_identifier}[Observer]" try: log.info("%s Starting file system observer...", log_id_prefix) self.observer.start() # Wait for stop signal while not self.stop_signal.is_set() and self.observer.is_alive(): self.stop_signal.wait(timeout=1) log.info("%s Observer loop exiting", log_id_prefix) except Exception as e: log.exception("%s Observer error: %s", log_id_prefix, e) self.stop_signal.set() finally: if self.observer.is_alive(): self.observer.stop() self.observer.join() log.info("%s Observer stopped", log_id_prefix) def _stop_listener(self) -> None: """Stop the directory monitoring listener.""" log_id_prefix = f"{self.log_identifier}[StopListener]" log.info("%s Stopping directory monitor...", log_id_prefix) if self.observer and self.observer.is_alive(): log.info("%s Stopping observer...", log_id_prefix) self.observer.stop() if self.watchdog_thread and self.watchdog_thread.is_alive(): log.info("%s Joining observer thread...", log_id_prefix) self.watchdog_thread.join(timeout=5) if self.watchdog_thread.is_alive(): log.warning("%s Observer thread did not join cleanly", log_id_prefix) log.info("%s Directory monitor stopped", log_id_prefix) async def _process_new_file(self, file_path: str): """Process a newly detected file.""" log_id_prefix = f"{self.log_identifier}[ProcessFile:{os.path.basename(file_path)}]" log.info("%s Processing new file: %s", log_id_prefix, file_path) error_context = { "file_path": file_path, "a2a_session_id": f"dir_monitor-error-{self.generate_uuid()}" } try: # Step 1: Authenticate and enrich user user_identity_profile = await self.authenticate_and_enrich_user(file_path) if not user_identity_profile: log.error("%s Authentication failed for file: %s", log_id_prefix, file_path) error_obj = JSONRPCError(code=-32001, message="Authentication failed") await self._send_error_to_external(error_context, error_obj) return # Step 2: Translate external input to A2A format target_agent_name, a2a_parts, external_request_context = await self._translate_external_input( file_path, user_identity_profile ) if not target_agent_name or not a2a_parts: log.error("%s Failed to translate file to A2A task: %s", log_id_prefix, file_path) error_obj = JSONRPCError(code=-32002, message="Failed to translate file to A2A task") final_error_context = {**error_context, **external_request_context} await self._send_error_to_external(final_error_context, error_obj) return # Step 3: Submit A2A task log.info("%s Submitting A2A task for file: %s to agent: %s", log_id_prefix, file_path, target_agent_name) await self.submit_a2a_task( target_agent_name=target_agent_name, a2a_parts=a2a_parts, external_request_context=external_request_context, user_identity=user_identity_profile ) log.info("%s A2A task submitted for file: %s", log_id_prefix, file_path) except FileNotFoundError: log.error("%s File not found during processing: %s", log_id_prefix, file_path) except Exception as e: log.exception("%s Unexpected error processing file %s: %s", log_id_prefix, file_path, e) error_obj = JSONRPCError(code=-32000, message=f"Unexpected error: {e}") await self._send_error_to_external(error_context, error_obj) async def _extract_initial_claims(self, external_event_data: Any) -> Optional[Dict[str, Any]]: """Extract user identity claims from file event.""" file_path = str(external_event_data) log_id_prefix = f"{self.log_identifier}[ExtractClaims:{os.path.basename(file_path)}]" claims = { "id": self.default_user_identity_id, "source": "dir_monitor", "file_path": file_path } log.debug("%s Extracted claims for file %s: %s", log_id_prefix, file_path, claims) return claims async def _translate_external_input( self, external_event_data: Any, authenticated_user_identity: Dict[str, Any] ) -> Tuple[Optional[str], List[A2APart], Dict[str, Any]]: """Translate file event to A2A task format.""" file_path = str(external_event_data) log_id_prefix = f"{self.log_identifier}[TranslateInput:{os.path.basename(file_path)}]" user_id_for_a2a = authenticated_user_identity.get("id", self.default_user_identity_id) a2a_session_id = f"dir_monitor-session-{self.generate_uuid()}" # Prepare external request context external_request_context: Dict[str, Any] = { "file_path": file_path, "user_id_for_a2a": user_id_for_a2a, "app_name_for_artifacts": self.gateway_id, "user_id_for_artifacts": user_id_for_a2a, "a2a_session_id": a2a_session_id, } a2a_parts: List[A2APart] = [] try: # Check if file exists if not os.path.exists(file_path): log.error("%s File does not exist: %s", log_id_prefix, file_path) raise FileNotFoundError(f"File not found: {file_path}") # Read file content with open(file_path, "rb") as f: content_bytes = f.read() # Determine MIME type mime_type, _ = mimetypes.guess_type(file_path) if mime_type is None: mime_type = "application/octet-stream" # Save file as artifact if not self.shared_artifact_service: log.error("%s Artifact service not available for file: %s", log_id_prefix, os.path.basename(file_path)) return None, [], external_request_context artifact_metadata = { "source": "dir_monitor_gateway", "original_filename": os.path.basename(file_path), "detected_mime_type": mime_type, "processing_timestamp_utc": datetime.now(timezone.utc).isoformat(), } log.debug("%s Saving artifact for file: %s", log_id_prefix, file_path) save_result = await save_artifact_with_metadata( artifact_service=self.shared_artifact_service, app_name=self.gateway_id, user_id=str(user_id_for_a2a), session_id=a2a_session_id, filename=os.path.basename(file_path), content_bytes=content_bytes, mime_type=mime_type, metadata_dict=artifact_metadata, timestamp=datetime.now(timezone.utc), ) if save_result["status"] not in ["success", "partial_success"]: log.error("%s Failed to save file as artifact: %s", log_id_prefix, save_result.get("message")) return None, [], external_request_context # Create artifact URI data_version = save_result.get("data_version", 0) artifact_uri = f"artifact://{self.gateway_id}/{str(user_id_for_a2a)}/{a2a_session_id}/{os.path.basename(file_path)}?version={data_version}" log.info("%s Saved file as artifact: %s", log_id_prefix, artifact_uri) # Create A2A parts file_content_obj = FileContent( name=os.path.basename(file_path), uri=artifact_uri, mimeType=mime_type ) a2a_parts.append(FilePart(file=file_content_obj)) a2a_parts.append(TextPart( text=f"Please analyze and summarize the content of: {os.path.basename(file_path)}" )) log.info("%s Successfully translated file %s into A2A parts", log_id_prefix, file_path) return self.target_agent_name, a2a_parts, external_request_context except Exception as e: log.exception("%s Error translating file %s: %s", log_id_prefix, file_path, e) return None, [], external_request_context async def _send_final_response_to_external( self, external_request_context: Dict[str, Any], task_data: Task ) -> None: """Handle final response from A2A agent.""" log_id_prefix = f"{self.log_identifier}[SendFinalResponse]" file_path = external_request_context.get("file_path", "Unknown file") task_id = task_data.id # Extract summary from response summary_text = "Summary not available." if task_data.status and task_data.status.message and task_data.status.message.parts: for part in task_data.status.message.parts: if isinstance(part, TextPart): summary_text = part.text break log.info("%s Task %s completed for file '%s'. Status: %s", log_id_prefix, task_id, os.path.basename(file_path), task_data.status.state if task_data.status else "Unknown") log.info("%s Summary: %s", log_id_prefix, summary_text[:200] + "..." if len(summary_text) > 200 else summary_text) async def _send_error_to_external( self, external_request_context: Dict[str, Any], error_data: JSONRPCError ) -> None: """Handle errors by moving files to error directory.""" log_id_prefix = f"{self.log_identifier}[SendError]" file_path = external_request_context.get("file_path") log.error("%s A2A Error for file '%s'. Code: %s, Message: %s", log_id_prefix, os.path.basename(file_path) if file_path else "Unknown file", error_data.code, error_data.message) # Move problematic file to error directory if file_path and os.path.exists(file_path): try: os.makedirs(self.error_directory_path, exist_ok=True) base_name = os.path.basename(file_path) error_file_path = os.path.join(self.error_directory_path, base_name) # Handle filename conflicts counter = 0 while os.path.exists(error_file_path): counter += 1 name, ext = os.path.splitext(base_name) error_file_path = os.path.join(self.error_directory_path, f"{name}_error_{counter}{ext}") shutil.move(file_path, error_file_path) log.info("%s Moved problematic file %s to %s", log_id_prefix, file_path, error_file_path) except Exception as e: log.exception("%s Failed to move file %s to error directory: %s", log_id_prefix, file_path, e) async def _send_update_to_external( self, external_request_context: Dict[str, Any], event_data: Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent], is_final_chunk_of_update: bool, ) -> None: """Handle intermediate updates (optional for this gateway).""" log_id_prefix = f"{self.log_identifier}[SendUpdate]" task_id = event_data.id file_path = external_request_context.get("file_path", "Unknown file") log.debug("%s Received update for task %s (file %s). Updates not processed by this gateway.", log_id_prefix, task_id, os.path.basename(file_path)) def cleanup(self): """Clean up resources.""" log.info("%s Cleaning up Directory Monitor Gateway Component...", self.log_identifier) super().cleanup() log.info("%s Directory Monitor Gateway Component cleanup finished.", self.log_identifier) ","version":"Next","tagName":"h3"},{"title":"Step 4: Configure the Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-4-configure-the-gateway","content":" Configure the Gateway (dir_monitor_config.yaml) # configs/gateways/dir_monitor_config.yaml log: stdout_log_level: INFO log_file_level: DEBUG log_file: "dir_monitor_gateway.log" !include ../shared_config.yaml apps: - name: dir_monitor_gateway_app app_base_path: . app_module: src.dir_monitor.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} gateway_id: dir-monitor-gateway # Artifact service configuration artifact_service: *default_artifact_service # Authorization service authorization_service: type: "none" # System purpose for A2A context system_purpose: > This system monitors directories for new files and processes them automatically. Analyze and summarize file contents. Always provide useful insights about the files. Your external name is Directory Monitor Agent. response_format: > Responses should be clear, concise, and professionally formatted. Provide structured analysis of file contents in Markdown format. # Gateway-specific configuration directory_path: /path/to/monitor/directory error_directory_path: /path/to/error/directory target_agent_name: "OrchestratorAgent" default_user_identity: "dir_monitor_system" ","version":"Next","tagName":"h3"},{"title":"Step 5: Install Dependencies​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-5-install-dependencies","content":" Add required dependencies to your project: pip install watchdog ","version":"Next","tagName":"h3"},{"title":"Step 6: Run Your Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-6-run-your-gateway","content":" sam run configs/gateways/dir_monitor_config.yaml ","version":"Next","tagName":"h3"},{"title":"Advanced Gateway Patterns​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#advanced-gateway-patterns","content":" ","version":"Next","tagName":"h2"},{"title":"Authentication and Authorization​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#authentication-and-authorization","content":" Gateways can implement sophisticated authentication: async def _extract_initial_claims(self, external_event_data: Any) -> Optional[Dict[str, Any]]: """Extract user claims with API key validation.""" request = external_event_data.get("request") # Validate API key api_key = request.headers.get("X-API-Key") if not api_key or not self._validate_api_key(api_key): return None # Extract user information user_id = request.headers.get("X-User-ID", "anonymous") return { "id": user_id, "source": "api_gateway", "api_key_hash": hashlib.sha256(api_key.encode()).hexdigest()[:8], "roles": self._get_user_roles(user_id) } ","version":"Next","tagName":"h3"},{"title":"File Handling with Artifacts​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#file-handling-with-artifacts","content":" For gateways that handle files: async def _save_file_as_artifact(self, file_content: bytes, filename: str, mime_type: str, session_id: str) -> Optional[str]: """Save file content as artifact and return URI.""" if not self.shared_artifact_service: return None try: save_result = await save_artifact_with_metadata( artifact_service=self.shared_artifact_service, app_name=self.gateway_id, user_id="system", session_id=session_id, filename=filename, content_bytes=file_content, mime_type=mime_type, metadata_dict={ "source": "my_gateway", "upload_timestamp": datetime.now(timezone.utc).isoformat() }, timestamp=datetime.now(timezone.utc) ) if save_result["status"] in ["success", "partial_success"]: version = save_result.get("data_version", 0) return f"artifact://{self.gateway_id}/system/{session_id}/{filename}?version={version}" except Exception as e: log.error("Failed to save artifact: %s", e) return None ","version":"Next","tagName":"h3"},{"title":"Streaming Responses​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#streaming-responses","content":" Handle streaming responses from agents: async def _send_update_to_external( self, external_request_context: Dict[str, Any], event_data: Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent], is_final_chunk_of_update: bool ) -> None: """Send streaming updates to external system.""" if isinstance(event_data, TaskStatusUpdateEvent): if event_data.status and event_data.status.message: for part in event_data.status.message.parts: if isinstance(part, TextPart): # Send partial text to external system await self._send_partial_response( external_request_context, part.text, is_final=is_final_chunk_of_update ) ","version":"Next","tagName":"h3"},{"title":"Error Handling and Retry Logic​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#error-handling-and-retry-logic","content":" Implement robust error handling: async def _process_with_retry(self, data: Any, max_retries: int = 3): """Process data with retry logic.""" for attempt in range(max_retries): try: return await self._process_data(data) except TemporaryError as e: if attempt < max_retries - 1: wait_time = 2 ** attempt # Exponential backoff log.warning("Attempt %d failed, retrying in %ds: %s", attempt + 1, wait_time, e) await asyncio.sleep(wait_time) else: raise except PermanentError: # Don't retry permanent errors raise ","version":"Next","tagName":"h3"},{"title":"Best Practices​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#best-practices","content":" ","version":"Next","tagName":"h2"},{"title":"1. Configuration Management​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#1-configuration-management","content":" Use environment variables for sensitive dataProvide sensible defaultsValidate configuration at startup ","version":"Next","tagName":"h3"},{"title":"2. Error Handling​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#2-error-handling","content":" Implement comprehensive error handlingUse appropriate HTTP status codesLog errors with sufficient contextProvide meaningful error messages ","version":"Next","tagName":"h3"},{"title":"3. Security​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#3-security","content":" Validate all external inputsUse secure authentication methodsImplement rate limiting where appropriateStore secrets securely (use environment variables)Follow principle of least privilege ","version":"Next","tagName":"h3"},{"title":"4. Performance​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#4-performance","content":" Use async/await for I/O operationsImplement connection pooling for external APIsMonitor resource usageHandle backpressure appropriately ","version":"Next","tagName":"h3"},{"title":"5. Monitoring and Logging​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#5-monitoring-and-logging","content":" Use structured loggingInclude correlation IDsMonitor key metrics (latency, error rates, throughput)Set up health checks ","version":"Next","tagName":"h3"},{"title":"Common Gateway Patterns​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#common-gateway-patterns","content":" ","version":"Next","tagName":"h2"},{"title":"HTTP/REST API Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#httprest-api-gateway","content":" For HTTP-based integrations: from fastapi import FastAPI, HTTPException, Depends from fastapi.security import HTTPBearer class HTTPAPIGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.app = FastAPI() self.security = HTTPBearer() self._setup_routes() def _setup_routes(self): @self.app.post("/webhook/{endpoint_id}") async def webhook_handler(endpoint_id: str, request: Request, token: str = Depends(self.security)): # Authenticate request user_identity = await self.authenticate_and_enrich_user({ "token": token, "endpoint_id": endpoint_id, "request": request }) if not user_identity: raise HTTPException(status_code=401, detail="Unauthorized") # Process webhook body = await request.json() target_agent, parts, context = await self._translate_external_input( body, user_identity ) task_id = await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) return {"task_id": task_id, "status": "accepted"} ","version":"Next","tagName":"h3"},{"title":"WebSocket Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#websocket-gateway","content":" For real-time bidirectional communication: import websockets import json class WebSocketGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.connections = {} async def _start_listener(self): """Start WebSocket server.""" self.server = await websockets.serve( self.handle_websocket, self.get_config("websocket_host", "localhost"), self.get_config("websocket_port", 8765) ) log.info("%s WebSocket server started", self.log_identifier) async def handle_websocket(self, websocket, path): """Handle WebSocket connections.""" connection_id = self.generate_uuid() self.connections[connection_id] = websocket try: async for message in websocket: data = json.loads(message) await self.process_websocket_message(connection_id, data) except websockets.exceptions.ConnectionClosed: log.info("%s WebSocket connection closed: %s", self.log_identifier, connection_id) finally: self.connections.pop(connection_id, None) async def process_websocket_message(self, connection_id: str, data: dict): """Process incoming WebSocket message.""" user_identity = await self.authenticate_and_enrich_user({ "connection_id": connection_id, "data": data }) if user_identity: target_agent, parts, context = await self._translate_external_input( data, user_identity ) context["connection_id"] = connection_id await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) async def _send_final_response_to_external(self, context: Dict[str, Any], task_data: Task): """Send response back via WebSocket.""" connection_id = context.get("connection_id") websocket = self.connections.get(connection_id) if websocket: response = { "task_id": task_data.id, "status": task_data.status.state.value if task_data.status else "unknown", "result": self._extract_text_from_task(task_data) } await websocket.send(json.dumps(response)) ","version":"Next","tagName":"h3"},{"title":"Message Queue Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#message-queue-gateway","content":" For integration with message queues: import asyncio import aio_pika class MessageQueueGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.connection = None self.channel = None async def _start_listener(self): """Connect to message queue and start consuming.""" connection_url = self.get_config("rabbitmq_url") queue_name = self.get_config("input_queue_name") self.connection = await aio_pika.connect_robust(connection_url) self.channel = await self.connection.channel() queue = await self.channel.declare_queue(queue_name, durable=True) await queue.consume(self.process_message) log.info("%s Started consuming from queue: %s", self.log_identifier, queue_name) async def process_message(self, message: aio_pika.IncomingMessage): """Process incoming queue message.""" async with message.process(): try: data = json.loads(message.body.decode()) user_identity = await self.authenticate_and_enrich_user(data) if not user_identity: log.warning("%s Authentication failed for message", self.log_identifier) return target_agent, parts, context = await self._translate_external_input( data, user_identity ) context["message_id"] = message.message_id context["reply_to"] = message.reply_to await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) except Exception as e: log.exception("%s Error processing message: %s", self.log_identifier, e) async def _send_final_response_to_external(self, context: Dict[str, Any], task_data: Task): """Send response back to reply queue.""" reply_to = context.get("reply_to") if reply_to and self.channel: response = { "task_id": task_data.id, "status": task_data.status.state.value if task_data.status else "unknown", "result": self._extract_text_from_task(task_data) } await self.channel.default_exchange.publish( aio_pika.Message(json.dumps(response).encode()), routing_key=reply_to ) ","version":"Next","tagName":"h3"},{"title":"Packaging as a Plugin​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#packaging-as-a-plugin","content":" For distribution and reusability, package your gateway as a plugin: ","version":"Next","tagName":"h2"},{"title":"1. Create Plugin Structure​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#1-create-plugin-structure","content":" The following structure is created when running the sam plugin create my-gateway-plugin --type gateway command: my-gateway-plugin/ ├── pyproject.toml ├── README.md ├── src/ │ └── sam_my_gateway/ │ ├── __init__.py │ ├── app.py │ ├── component.py ├── config.yaml └── examples/ └── my_gateway_example.yaml ","version":"Next","tagName":"h3"},{"title":"2. Configure pyproject.toml​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#2-configure-pyprojecttoml","content":" Update the pyproject.toml file to include your gateway dependencies: ... dependencies = [ "watchdog>=3.0.0", # Add your specific dependencies ] ... ","version":"Next","tagName":"h3"},{"title":"3. Build and Install​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#3-build-and-install","content":" # Build the plugin sam plugin build # Install plugin from local wheel file sam plugin add my-gateway --plugin dist/sam_my_gateway-0.1.0-py3-none-any.whl ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#common-issues","content":" Gateway Fails to Start​ Check configuration schema validationVerify all required parameters are providedEnsure external dependencies are installed Tasks Not Reaching Agents​ Verify namespace configuration matches agentsCheck Solace broker connectivityConfirm agent names are correct Authentication Failures​ Validate user identity extraction logicCheck authorization service configurationVerify claims format matches expectations File/Artifact Issues​ Ensure artifact service is properly configuredCheck file permissions and pathsVerify artifact URI construction ","version":"Next","tagName":"h3"},{"title":"Debugging Tips​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#debugging-tips","content":" Enable Debug Logging: log: stdout_log_level: DEBUG log_file_level: DEBUG Use Test Agents: Create simple echo agents for testing gateway integration Monitor Solace Topics: Use Solace monitoring tools to trace message flow Add Correlation IDs: Include unique identifiers in logs for request tracing ","version":"Next","tagName":"h3"}],"options":{"id":"default"}}
1
+ {"searchDocs":[{"title":"Agents","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/agents","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#key-functions","content":" ADK Integration: Agents are built using the Google Agent Development Kit, providing advanced AI capabilities including tool usage, memory management, and artifact handling. AI-Enabled: Agents come packaged with access to large language models (LLMs) and can utilize various tools. Dynamic Discovery: New agents can self-register/deregister and be discovered dynamically through broadcast messages without requiring changes to the running system. Tool Ecosystem: Agents have access to built-in tools for artifact management, data analysis, web scraping, and peer-to-peer delegation. Session Management: Agents support conversation continuity through ADK's session management capabilities. Independence: Agents are modularized and can be updated or replaced independently of other components. ","version":"Next","tagName":"h2"},{"title":"Agent Design​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-design","content":" Agents in Solace Agent Mesh are built around the Solace AI Connector (SAC) component with ADK. Agent Mesh agents are complete self-contained units that can carry out specific tasks or provide domain-specific knowledge or capabilities. Each agent is defined by a YAML configuration file. Each agent integrates with: ADK Runtime: For AI model access, tool execution, and session managementA2A Protocol: For standardized agent-to-agent communicationTool Registry: Access to built-in and custom toolsArtifact Service: For file handling and management For example, an agent configured with SQL database tools can execute queries, perform data analysis, and generate visualizations through the integrated tool ecosystem, all while maintaining conversation context through its session management. ","version":"Next","tagName":"h2"},{"title":"The Agent Lifecycle​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#the-agent-lifecycle","content":" Agents in Solace Agent Mesh follow the A2A protocol lifecycle and interact with the agent registry: Discovery: Agents start broadcasting discovery messages on startup to announce their availability and capabilities to the agent mesh. Active: The agent listens for A2A protocol messages on its designated topics and processes incoming tasks through the ADK runtime. Execution: The agent works on a task. They can also delegate tasks to other agents through the peer-to-peer A2A communication protocol. Cleanup: When shutting down, agents perform session cleanup and deregister from the agent mesh. ","version":"Next","tagName":"h3"},{"title":"Potential Agent Examples​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#potential-agent-examples","content":" RAG (Retrieval Augmented Generation) Agent: An agent that can retrieve information based on a natural language query using an embedding model and vector database, and then generate a response using a language model. External API Bridge: An agent that acts as a bridge to external APIs, retrieving information from third-party services such as weather APIs or product information databases. Internal System Lookup: An agent that performs lookups in internal systems, such as a ticket management system or a customer relationship management (CRM) database. Natural Language Processing Agent: An agent that can perform tasks like sentiment analysis, named entity recognition, or language translation. ","version":"Next","tagName":"h3"},{"title":"Tool Ecosystem​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#tool-ecosystem","content":" Agents perform tasks by using tools. A tool is a specific capability, like querying a database, calling an external API, or generating an image. The Solace Agent Mesh framework provides a flexible and powerful tool ecosystem, allowing you to equip your agents with the right capabilities for any job. There are three primary ways to add tools to an agent: ","version":"Next","tagName":"h2"},{"title":"1. Built-in Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#1-built-in-tools","content":" Solace Agent Mesh includes a rich library of pre-packaged tools for common tasks like data analysis, file management, and web requests. These are the easiest to use and can be enabled with just a few lines of configuration. Use Case: For standard, out-of-the-box functionality.Learn More: See the Built-in Tools Reference for a complete list and configuration details. ","version":"Next","tagName":"h3"},{"title":"2. Custom Python Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#2-custom-python-tools","content":" For unique business logic or specialized tasks, you can create your own tools using Python. This is the most powerful and flexible method, supporting everything from simple functions to advanced, class-based tool factories that can generate multiple tools programmatically. Use Case: For implementing custom logic, integrating with proprietary systems, or creating dynamically configured tools.Learn More: See the Creating Python Tools guide for a complete walkthrough. ","version":"Next","tagName":"h3"},{"title":"3. MCP (Model Context Protocol) Tools​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#3-mcp-model-context-protocol-tools","content":" For integrating with external, standalone tool servers that conform to the Model Context Protocol, you can configure an MCP tool. This allows agents to communicate with tools running in separate processes or on different machines. Use Case: For integrating with existing MCP-compliant tool servers or language-agnostic tool development.Learn More: See the MCP Integration Tutorial. ","version":"Next","tagName":"h3"},{"title":"Agent Card​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-card","content":" The Agent Card is a public-facing profile that describes an agent's identity, capabilities, and how to interact with it. It functions like a digital business card, allowing other agents and clients within Solace Agent Mesh to discover what an agent can do. This information is published by the agent and is crucial for dynamic discovery and interoperability. The Agent Card is defined in the agent's YAML configuration file under the agent_card section. ","version":"Next","tagName":"h2"},{"title":"Key Fields​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#key-fields","content":" You can configure the following fields in the agent card: description: A summary of the agent's purpose and capabilities.defaultInputModes: A list of supported MIME types for input (e.g., ["text/plain", "application/json", "file"]).defaultOutputModes: A list of supported MIME types for output.skills: A list of specific skills the agent possesses. Each skill corresponds to a capability, often backed by a tool. ","version":"Next","tagName":"h3"},{"title":"Skills​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#skills","content":" A skill describes a specific function the agent can perform. It provides granular detail about the agent's abilities. Key attributes of a skill include: id: A unique identifier for the skill, which should match the tool_name if the skill is directly mapped to a tool.name: A human-readable name for the skill.description: A clear explanation of what the skill does, which helps the LLM (and other agents) decide when to use it. ","version":"Next","tagName":"h3"},{"title":"Example Configuration​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#example-configuration","content":" Here is an example of an agent_card configuration for a "Mermaid Diagram Generator" agent: # ... inside app_config ... agent_card: description: "An agent that generates PNG images from Mermaid diagram syntax." defaultInputModes: ["text"] # Expects Mermaid syntax as text defaultOutputModes: ["text", "file"] # Confirms with text, outputs file artifact skills: - id: "mermaid_diagram_generator" name: "Mermaid Diagram Generator" description: "Generates a PNG image from Mermaid diagram syntax. Input: mermaid_syntax (string), output_filename (string, optional)." This card clearly communicates that the agent can take text (the Mermaid syntax) and produce a file (the PNG image), and it details the specific "mermaid_diagram_generator" skill it offers. For more details on creating agents and configuring their cards, see Creating Custom Agents. ","version":"Next","tagName":"h3"},{"title":"User-Defined Agents​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#user-defined-agents","content":" Using Solace Agent Mesh and the Solace Agent Mesh CLI, you can create your own agents. Agents are configured through YAML files that specify: Agent name and instructionsLLM model configurationAvailable tools and capabilitiesArtifact and session management settingsDiscovery settings The following Solace Agent Mesh CLI command creates an agent configuration: sam add agent my-agent [--gui] For more information, see Creating Custom Agents. ","version":"Next","tagName":"h2"},{"title":"Agent Plugins​","type":1,"pageTitle":"Agents","url":"/solace-agent-mesh/docs/documentation/concepts/agents#agent-plugins","content":" You can also use agents built by the community or Solace directly in your app with little to no configuration. For more information, see Use a Plugin. ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh Architecture","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/architecture","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#overview","content":" 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. It integrates three primary technologies: Solace PubSub+ Event Broker: Provides the messaging fabric for all asynchronous communication, utilizing topic-based routing for the Agent-to-Agent (A2A) protocol.Solace AI Connector (SAC): Serves as the runtime environment for hosting and managing the lifecycle of all system components (Agents and Gateways).Google Agent Development Kit (ADK): Provides the core logic for individual agents, including LLM interaction, tool execution, and state management. ","version":"Next","tagName":"h2"},{"title":"Architectural Principles​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#architectural-principles","content":" The design of Solace Agent Mesh is founded on several key architectural principles: 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.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.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. ","version":"Next","tagName":"h2"},{"title":"System Components​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#system-components","content":" The architecture comprises several distinct types of components that interact through the Solace PubSub+ broker. ","version":"Next","tagName":"h2"},{"title":"Solace PubSub+ Event Broker​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#solace-pubsub-event-broker","content":" 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. ","version":"Next","tagName":"h3"},{"title":"Gateways​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#gateways","content":" Gateways are SAC applications that act as bridges between external systems and the agent mesh. Their primary responsibilities are: Protocol Translation: Convert external protocols (for example, HTTP, WebSockets, Slack RTM) into the standardized A2A protocol, and vice-versa.Authentication and Authorization: Authenticate incoming requests and, using a pluggable AuthorizationService, retrieve the user's permission scopes.Session Management: Manage external user sessions and map them to A2A task lifecycles.Response Handling: Receive asynchronous A2A responses and status updates from agents and deliver them to the external client. The Gateway Development Kit (GDK) provides BaseGatewayApp and 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. ","version":"Next","tagName":"h3"},{"title":"Agent Hosts​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-hosts","content":" An Agent Host is a SAC application (SamAgentApp) that hosts a single ADK-based agent. Its key architectural functions include: Hosting the ADK Runtime: It manages the lifecycle of the ADK Runner and LlmAgent.A2A Protocol Handling: The internal SamAgentComponent translates incoming A2A requests into ADK Task objects and converts ADK Event objects into outgoing A2A TaskStatusUpdateEvent, TaskArtifactUpdateEvent, or final response messages.Scope Enforcement: It extracts permission scopes from incoming message properties and filters the agent's available tools accordingly.Service Initialization: It initializes ADK services like the ArtifactService and MemoryService based on its configuration. ","version":"Next","tagName":"h3"},{"title":"Agents​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agents","content":" An agent is the logical entity within an Agent Host that performs tasks. It is defined by its configuration, which includes: Instructions: The base prompt that defines its persona, capabilities, and constraints.LLM Configuration: The specific large language model to use.Toolset: A collection of available tools, which can be built-in, custom Python functions, or MCP Toolsets. ","version":"Next","tagName":"h3"},{"title":"Key Architectural Flows​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#key-architectural-flows","content":" ","version":"Next","tagName":"h2"},{"title":"User Task Processing Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#user-task-processing-flow","content":" An external client sends a request to a Gateway.The Gateway authenticates the request, retrieves the user's permission scopes via its AuthorizationService, and translates the request into an A2A task message. It includes the scopes in the Solace message's user properties.The Gateway publishes the message to the target agent's request topic on the Solace Broker.The corresponding Agent Host receives the message. The SamAgentComponent extracts the scopes and initiates an ADK task.The ADK LlmAgent processes the task. Before invoking the LLM, a before_model_callback filters the available tools based on the user's scopes.As the agent executes, the SamAgentComponent translates ADK events into A2A status and artifact update messages, publishing them to the originating Gateway's status topic.The Gateway receives these streaming updates, performs any necessary late-stage processing (like resolving artifact_content embeds), and forwards them to the client.Upon completion, the Agent Host sends a final A2A response message to the Gateway, which delivers it to the client. ","version":"Next","tagName":"h3"},{"title":"Agent-to-Agent Delegation Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-to-agent-delegation-flow","content":" Agent A, while processing a task, determines a sub-task should be delegated to Agent B.Agent A uses its PeerAgentTool to construct a new A2A task request for Agent B. It propagates the original user's permission scopes to maintain the security context.The request is published to Agent B's request topic.Agent B's Host receives and processes the sub-task, enforcing the propagated scopes on its own toolset.Agent B sends status updates and a final response to topics designated by Agent A.Agent A receives the results and incorporates them into its ongoing task. ","version":"Next","tagName":"h3"},{"title":"Agent Discovery Flow​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#agent-discovery-flow","content":" On startup and periodically, each Agent Host publishes an AgentCard (a JSON document describing its agent's capabilities) to a well-known discovery topic (for example, {namespace}/a2a/v1/discovery/agentcards).Gateways and other Agent Hosts subscribe to this topic.Upon receiving an AgentCard, components update their local AgentRegistry, making them aware of available agents for user selection (at the Gateway) or peer delegation (at the Agent). ","version":"Next","tagName":"h3"},{"title":"A2A Protocol and Topic Structure​","type":1,"pageTitle":"Solace Agent Mesh Architecture","url":"/solace-agent-mesh/docs/documentation/concepts/architecture#a2a-protocol-and-topic-structure","content":" 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. Purpose\tTopic PatternAgent Discovery\t{namespace}/a2a/v1/discovery/agentcards Task Requests\t{namespace}/a2a/v1/agent/request/{target_agent_name} Status Updates\t{namespace}/a2a/v1/gateway/status/{gateway_id}/{task_id} Final Responses\t{namespace}/a2a/v1/gateway/response/{gateway_id}/{task_id} Peer Delegation Status\t{namespace}/a2a/v1/agent/status/{delegating_agent_name}/{sub_task_id} Peer Delegation Response\t{namespace}/a2a/v1/agent/response/{delegating_agent_name}/{sub_task_id} This topic structure allows for precise, point-to-point routing in a decoupled, asynchronous environment. ","version":"Next","tagName":"h2"},{"title":"Gateways","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/gateways","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#key-functions","content":" Entry Points: Gateways act as the entry points from the outside world and translate external requests into A2A protocol messages and route them through the Solace event mesh to appropriate agents. Authentication & Authorization: Common authentication and user enrichment flow across all gateway types, with pluggable identity providers. Configurable System Purpose: Each gateway has a configurable system purpose that sets the context for all stimuli entering Solace Agent Mesh through that gateway. This design allows for tailored processing based on the specific use case or domain. Customizable Output Formatting: Gateways have a configurable output description that controls how stimuli responses are formatted when sent back to the outside world. This configurable output description ensures that the output meets the requirements of the receiving system or user interface. Multiple Interface Types: Gateways can have different interfaces to accommodate various communication protocols and systems. Some examples include REST APIs, event meshes, Slack integrations, browser-based interfaces, and so on. ","version":"Next","tagName":"h2"},{"title":"How Gateways Work​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#how-gateways-work","content":" The following diagram illustrates the complete flow of information through a gateway in Solace Agent Mesh: ","version":"Next","tagName":"h2"},{"title":"Available Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#available-gateways","content":" Solace Agent Mesh comes with several built-in gateway types: ","version":"Next","tagName":"h2"},{"title":"Core Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#core-gateways","content":" HTTP SSE Gateway Real-time web interface with streaming responsesServer-sent events for live updatesAgent discovery APIFile upload and download handling REST Gateway Task submission with immediate task ID returnPolling-based result retrievalAuthentication integration Webhook Gateway Handles incoming webhook requestsTransforms webhook payloads to A2A messages ","version":"Next","tagName":"h3"},{"title":"Plugin Gateways​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#plugin-gateways","content":" Additional gateway types are available through the plugin ecosystem: Event Mesh Gateway: External event mesh connectivity with message transformationSlack Gateway: Slack bot integration for team collaborationCustom Gateways: Create your own gateway implementations For more information about plugins and how to configure them, see Plugins. One of the official core plugin gateway interfaces is the Solace Event Mesh Gateway, which enables communication with the PubSub+ event broker directly as an input interface. note Each gateway type has its own configuration options and specific features. See the individual gateway documentation pages for detailed information on setup and usage. ","version":"Next","tagName":"h3"},{"title":"Create a Gateway​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#create-a-gateway","content":" To create a gateway, you can either use one of the pre-existing plugins or create yours from scratch. ","version":"Next","tagName":"h2"},{"title":"Gateway from Scratch​","type":1,"pageTitle":"Gateways","url":"/solace-agent-mesh/docs/documentation/concepts/gateways#gateway-from-scratch","content":" To create a gateway from scratch, you need to use the CLI add gateway command without any interfaces. This command creates a python gateway template file which you can then customize to your needs. sam add gateway my-interface To learn more about creating your own gateway, see Create Custom Gateways. Share and Reuse If you would like to share your custom gateway with the community or re-use it within other projects, you can create a plugin for it. For more information, see Create Plugins. ","version":"Next","tagName":"h3"},{"title":"Orchestrator Agent","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/orchestrator","content":"","keywords":"","version":"Next"},{"title":"Key Functions​","type":1,"pageTitle":"Orchestrator Agent","url":"/solace-agent-mesh/docs/documentation/concepts/orchestrator#key-functions","content":" The orchestrator agent provides the following key functions: Request Analysis and Action Planning: Receives high-level goals or requestsAnalyzes them in the context of available actions registered by agents in the systemUses state-of-the-art generative AI techniques to plan a sequence of actions to fulfill the request Task Creation and Distribution: Creates tasks based on the action planDistributes tasks to appropriate agentsEnables efficient parallel processing and optimal resource utilization Workflow Management: Tracks outstanding tasksAggregates responses from various agentsEnsures all parts of a complex request are processed and combined coherently Response Formatting: Formats aggregated responses suitable for the gatewayEnsures the final output meets the requirements of the specific use case or interface ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh CLI","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/cli","content":"","keywords":"","version":"Next"},{"title":"Installation​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#installation","content":" The Solace Agent Mesh CLI is installed as part of the package for Solace Agent Mesh. For more information, see Installation. CLI Tips The Solace Agent Mesh CLI comes with a short alias of sam which can be used in place of solace-agent-mesh.You can determine the version of the Solace Agent Mesh CLI by running solace-agent-mesh --version.You can get help on any command by running solace-agent-mesh [COMMAND] --help. ","version":"Next","tagName":"h2"},{"title":"Commands​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#commands","content":" ","version":"Next","tagName":"h2"},{"title":"init - Initialize a Solace Agent Mesh Application​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#init---initialize-a-solace-agent-mesh-application","content":" sam init [OPTIONS] When this command is run with no options, it runs in interactive mode. It first prompts you to choose between configuring your project in the terminal or through a browser-based interface. If you choose to use the browser, the Solace Agent Mesh CLI starts a local web configuration portal, available at http://127.0.0.1:5002 You can skip some questions by providing the appropriate options for that step during the Solace Agent Mesh CLI-based setup. Optionally, you can skip all the questions by providing the --skip option. This option uses the provided or default values for all the questions. automated workflows Use the --skip option and provide the necessary options to run the command in non-interactive mode, useful for automated workflows. Options:​ --gui – Launch the browser-based initialization interface directly, skipping the prompt. (Recommended way to configure Solace Agent Mesh applications)--skip – Runs in non-interactive mode, using default values where available.--llm-service-endpoint TEXT – LLM Service Endpoint URL.--llm-service-api-key TEXT – LLM Service API Key.--llm-service-planning-model-name TEXT – LLM Planning Model Name.--llm-service-general-model-name TEXT – LLM General Model Name.--namespace TEXT – Namespace for the project.--broker-type TEXT – Broker type: 1/solace (existing), 2/container (new local), 3/dev (dev mode). Options: 1, 2, 3, solace, container, dev_mode, dev_broker, dev.--broker-url TEXT – Solace broker URL endpoint.--broker-vpn TEXT – Solace broker VPN name.--broker-username TEXT – Solace broker username.--broker-password TEXT – Solace broker password.--container-engine TEXT – Container engine for local broker. Options: podman, docker.--dev-mode – Shortcut to select dev mode for broker (equivalent to --broker-type 3/dev).--agent-name TEXT – Agent name for the main orchestrator.--supports-streaming – Enable streaming support for the agent.--session-service-type TEXT – Session service type. Options: memory, vertex_rag.--session-service-behavior TEXT – Session service behavior. Options: PERSISTENT, RUN_BASED.--artifact-service-type TEXT – Artifact service type. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Artifact service base path (for filesystem type).--artifact-service-scope TEXT – Artifact service scope. Options: namespace, app, custom.--artifact-handling-mode TEXT – Artifact handling mode. Options: ignore, embed, reference.--enable-embed-resolution – Enable embed resolution.--enable-artifact-content-instruction – Enable artifact content instruction.--enable-builtin-artifact-tools – Enable built-in artifact tools.--enable-builtin-data-tools – Enable built-in data tools.--agent-card-description TEXT – Agent card description.--agent-card-default-input-modes TEXT – Agent card default input modes (comma-separated).--agent-card-default-output-modes TEXT – Agent card default output modes (comma-separated).--agent-discovery-enabled – Enable agent discovery.--agent-card-publishing-interval INTEGER – Agent card publishing interval (seconds).--inter-agent-communication-allow-list TEXT – Inter-agent communication allow list (comma-separated, use * for all).--inter-agent-communication-deny-list TEXT – Inter-agent communication deny list (comma-separated).--inter-agent-communication-timeout INTEGER – Inter-agent communication timeout (seconds).--add-webui-gateway – Add a default Web UI gateway configuration.--webui-session-secret-key TEXT – Session secret key for Web UI.--webui-fastapi-host TEXT – Host for Web UI FastAPI server.--webui-fastapi-port INTEGER – Port for Web UI FastAPI server.--webui-enable-embed-resolution – Enable embed resolution for Web UI.--webui-frontend-welcome-message TEXT – Frontend welcome message for Web UI.--webui-frontend-bot-name TEXT – Frontend bot name for Web UI.--webui-frontend-collect-feedback – Enable feedback collection in Web UI.-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"add - Create a New Component​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#add---create-a-new-component","content":" To add a new component, such as an agent or gateway, use the add command with the appropriate options. sam add [agent|gateway] [OPTIONS] NAME Add agent​ Use agent to add an agent component. sam add agent [OPTIONS] [NAME] Options:​ --gui – Launch the browser-based configuration interface for agent setup. (Recommended way to configure agents)--skip – Skip interactive prompts and use defaults (Solace Agent Mesh CLI mode only).--namespace TEXT – namespace (for example, myorg/dev).--supports-streaming BOOLEAN – Enable streaming support.--model-type TEXT – Model type for the agent. Options: planning, general, image_gen, report_gen, multimodal, gemini_pro.--instruction TEXT – Custom instruction for the agent.--session-service-type TEXT – Session service type. Options: memory, vertex_rag.--session-service-behavior TEXT – Session service behavior. Options: PERSISTENT, RUN_BASED.--artifact-service-type TEXT – Artifact service type. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Base path for filesystem artifact service.--artifact-service-scope TEXT – Artifact service scope. Options: namespace, app, custom.--artifact-handling-mode TEXT – Artifact handling mode. Options: ignore, embed, reference.--enable-embed-resolution BOOLEAN – Enable embed resolution.--enable-artifact-content-instruction BOOLEAN – Enable artifact content instruction.--enable-builtin-artifact-tools BOOLEAN – Enable built-in artifact tools.--enable-builtin-data-tools BOOLEAN – Enable built-in data tools.--agent-card-description TEXT – Description for the agent card.--agent-card-default-input-modes-str TEXT – Comma-separated default input modes for agent card.--agent-card-default-output-modes-str TEXT – Comma-separated default output modes for agent card.--agent-card-publishing-interval INTEGER – Agent card publishing interval in seconds.--agent-discovery-enabled BOOLEAN – Enable agent discovery.--inter-agent-communication-allow-list-str TEXT – Comma-separated allow list for inter-agent communication.--inter-agent-communication-deny-list-str TEXT – Comma-separated deny list for inter-agent communication.--inter-agent-communication-timeout INTEGER – Timeout in seconds for inter-agent communication.-h, --help – Displays the help message and exits. For more information, see Agents. Add gateway​ Use gateway to add a gateway component. sam add gateway [OPTIONS] [NAME] Options:​ --gui – Launch the browser-based configuration interface for gateway setup. (Recommended way to configure gateways)--skip – Skip interactive prompts and use defaults (Solace Agent Mesh CLI mode only).--namespace TEXT – namespace for the gateway (for example, myorg/dev).--gateway-id TEXT – Custom Gateway ID for the gateway.--artifact-service-type TEXT – Artifact service type for the gateway. Options: memory, filesystem, gcs.--artifact-service-base-path TEXT – Base path for filesystem artifact service (if type is 'filesystem').--artifact-service-scope TEXT – Artifact service scope (if not using default shared artifact service). Options: namespace, app, custom.--system-purpose TEXT – System purpose for the gateway (can be multi-line).--response-format TEXT – Response format for the gateway (can be multi-line).-h, --help – Displays the help message and exits. For more information, see Gateways. ","version":"Next","tagName":"h3"},{"title":"run - Run the Solace Agent Mesh Application​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#run---run-the-solace-agent-mesh-application","content":" To run the Solace Agent Mesh application, use the run command. sam run [OPTIONS] [FILES]... Environment variables The sam run command automatically loads environment variables from your configuration file (typically a .env file at the project root) by default. If you want to use your system's environment variables instead, you can add the -u or --system-env option. While running the run command, you can also skip specific files by providing the -s or --skip option. You can provide paths to specific YAML configuration files or directories. When you provide a directory, run will recursively search for and load all .yaml and .yml files within that directory. This allows you to organize your configurations and run them together easily. For example, to run specific files: solace-agent-mesh run configs/agent1.yaml configs/gateway.yaml To run all YAML files within the configs directory: solace-agent-mesh run configs/ Options:​ -u, --system-env – Use system environment variables only; do not load .env file.-s, --skip TEXT – File name(s) to exclude from the run (for example, -s my_agent.yaml).-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"docs - Serve the documentation locally​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#docs---serve-the-documentation-locally","content":" Serves the project documentation on a local web server. sam docs [OPTIONS] This command starts a web server to host the documentation, which is useful for offline viewing or development. By default, it serves the documentation at http://localhost:8585/solace-agent-mesh/ and automatically opens your web browser to the getting started page. If a requested page is not found, it will redirect to the main documentation page. Options:​ -p, --port INTEGER – Port to run the web server on. (default: 8585)-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"plugin - Manage Plugins​","type":1,"pageTitle":"Solace Agent Mesh CLI","url":"/solace-agent-mesh/docs/documentation/concepts/cli#plugin---manage-plugins","content":" The plugin command allows you to manage plugins for Solace Agent Mesh application. sam plugin [COMMAND] [OPTIONS] For more information, see Plugins. create - Create a Plugin​ Initializes and creates a new plugin with customizable options. sam plugin create [OPTIONS] NAME When this command is run with no options, it runs in interactive mode and prompts you to provide the necessary information to set up the plugin for Solace Agent Mesh You can skip some questions by providing the appropriate options for that step. Optionally, you can skip all the questions by providing the --skip option. This option uses the provided or default values for all the questions, which is useful for automated workflows. Options:​ --type TEXT – Plugin type. Options: agent, gateway, custom.--author-name TEXT – Author's name.--author-email TEXT – Author's email.--description TEXT – Plugin description.--version TEXT – Initial plugin version.--skip – Skip interactive prompts and use defaults or provided flags.-h, --help – Displays the help message and exits. build - Build the Plugin​ Compiles and prepares the plugin for use. sam plugin build [PLUGIN_PATH] Builds the Solace Agent Mesh plugin in the specified directory (defaults to current directory). Options:​ PLUGIN_PATH – Path to the plugin directory (defaults to current directory).-h, --help – Displays the help message and exits. add - Add an Existing Plugin​ Installs the plugins and creates a new component instance from a specified plugin source. sam plugin add [OPTIONS] COMPONENT_NAME Options:​ --plugin TEXT – Plugin source: installed module name, local path, or Git URL. (Required)--install-command TEXT – Command to use to install a python package. Must follow the format command {package} args, by default pip3 install {package}. Can also be set through the environment variable SAM_PLUGIN_INSTALL_COMMAND.-h, --help – Displays the help message and exits. installs - Installs a Plugin​ Installs a plugin from a specified plugin source. sam plugin install [OPTIONS] PLUGIN_SOURCE PLUGIN_SOURCE can be: A local path to a directory (e.g., '/path/to/plugin')A local path to a wheel file (e.g., '/path/to/plugin.whl')A Git URL (e.g., 'https://github.com/user/repo.git')The name of the plugin from https://github.com/SolaceLabs/solace-agent-mesh-core-plugins Options:​ --install-command TEXT – Command to use to install a python package. Must follow the format command {package} args, by default pip3 install {package}. Can also be set through the environment variable SAM_PLUGIN_INSTALL_COMMAND.-h, --help – Displays the help message and exits. catalog - Launch Plugin Catalog​ Launch the Solace Agent Mesh Plugin Catalog web interface. sam plugin catalog [OPTIONS] Options:​ --port INTEGER – Port to run the plugin catalog web server on. (default: 5003)--install-command TEXT – Command to use to install a python package. Must follow the format command {package} args.-h, --help – Displays the help message and exits. ","version":"Next","tagName":"h3"},{"title":"Deployment","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/deploy","content":"","keywords":"","version":"Next"},{"title":"Development​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#development","content":" In a development environment, you can use Solace Agent Mesh CLI to run the project as a single application. By default, environment variables are loaded from your configuration file (typically a .env file at the project root): sam run ","version":"Next","tagName":"h2"},{"title":"Production​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#production","content":" For a production environment, use a containerized and reproducible setup. We recommend Docker or Kubernetes. If your host system architecture is not linux/amd64, add the --platform linux/amd64 flag when you run the container. ","version":"Next","tagName":"h2"},{"title":"Docker Deployment​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#docker-deployment","content":" Below is a sample Dockerfile for a Solace Agent Mesh project: FROM solace/solace-agent-mesh:latest WORKDIR /app # Install Python dependencies COPY ./requirements.txt /app/requirements.txt RUN python3.11 -m pip install --no-cache-dir -r /app/requirements.txt # Copy project files COPY . /app CMD ["run", "--system-env"] # To run one specific component, use: # CMD ["run", "--system-env", "configs/agents/main_orchestrator.yaml"] And the following .dockerignore .env *.log dist .git .vscode .DS_Store ","version":"Next","tagName":"h3"},{"title":"Kubernetes Deployment​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#kubernetes-deployment","content":" For scalable and highly available deployments, Kubernetes is recommended. Below is a minimal Deployment configuration: apiVersion: apps/v1 kind: Deployment metadata: name: solace-agent-mesh labels: app: solace-agent-mesh spec: replicas: 1 # Adjust based on load selector: matchLabels: app: solace-agent-mesh template: metadata: labels: app: solace-agent-mesh spec: containers: - name: solace-agent-mesh image: your-registry/solace-agent-mesh:latest envFrom: - secretRef: name: solace-agent-mesh-secrets # Configure secrets in a Kubernetes Secret command: ["solace-agent-mesh", "run", "--system-env"] args: - "configs/main_orchestrator.yaml" - "configs/gateway/webui.yaml" # Add any other components you want to run here ports: - containerPort: 8000 # Adjust based on your service ports volumeMounts: - name: shared-storage mountPath: /tmp/solace-agent-mesh volumes: - name: shared-storage emptyDir: {} ","version":"Next","tagName":"h3"},{"title":"Splitting and Scaling​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#splitting-and-scaling","content":" 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. To adapt the setup: Reuse the same Docker image.Adjust the startup command to run only the necessary components.Scale containers independently based on their resource needs. ","version":"Next","tagName":"h3"},{"title":"Storage Considerations​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#storage-considerations","content":" warning If using multiple containers, ensure all instances access the same storage with identical configurations. ","version":"Next","tagName":"h3"},{"title":"Security Best Practices​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#security-best-practices","content":" Environment Variables: Store secrets in a secure vault (for example, AWS Secrets Manager, HashiCorp Vault) rather than in .env files.TLS Encryption: Ensure that communication between components and with the PubSub+ event broker is encrypted using TLS.Container Security: Regularly update container images and use security scanning tools (for example, Trivy, Clair). ","version":"Next","tagName":"h3"},{"title":"Solace Event Broker Configuration​","type":1,"pageTitle":"Deployment","url":"/solace-agent-mesh/docs/documentation/deployment/deploy#solace-event-broker-configuration","content":" For production environments, it's recommended to use a cloud-managed PubSub+ event broker (or event broker service). For more information, see Solace PubSub+ Cloud. ","version":"Next","tagName":"h3"},{"title":"Plugins","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/concepts/plugins","content":"","keywords":"","version":"Next"},{"title":"Plugins​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#plugins","content":" 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. In one sentence Plugins are modular Python packages that extend Solace Agent Mesh's capabilities through agents, gateways, and specialized integrations. Plugins are packaged as Python modules that can be installed using various package managers (pip, uv, poetry, conda). They integrate seamlessly with the A2A protocol and can provide: Agent Plugins: Specialized agents with domain-specific capabilitiesGateway Plugins: New interface types for external system integrationCustom Plugins: Custom integrations such as HR providers. All plugin interactions (create, build, add) are managed through the Solace Agent Mesh CLI. info Run sam plugin --help to see the list of available commands for plugins. ","version":"Next","tagName":"h2"},{"title":"Official Core Plugins​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#official-core-plugins","content":" 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 here 🔗. For more information about how to use the official core plugins, see Use Plugins. ","version":"Next","tagName":"h3"},{"title":"Create a Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#create-a-plugin","content":" To get started, install the Solace Agent Mesh CLI and run the following command: solace-agent-mesh plugin create <plugin-name> Follow the prompts to create a new plugin. A plugin can be one of the following types: Agent Plugin: Contains custom agents that can be used in a Solace Agent Mesh project.Gateway Plugin: Contains custom gateways that can be used in a Solace Agent Mesh project.Custom Plugin: Contains custom integrations such as HR providers or other specialized functionality. Solace Agent Mesh CLI creates a directory with the provided name and the following structure: plugin-name/ ├─ config.yaml ├─ src/ │ ├─ __init__.py │ ├─ [...Other type specific python files] ├─ .gitignore ├─ pyproject.toml ├─ README.md The src directory contains the python source code.The config.yaml file holds the configuration for the plugin, and how to be used in a Solace Agent Mesh application. Once the plugin is created, you can start customizing the config.yaml or the python files. ","version":"Next","tagName":"h2"},{"title":"Build the Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#build-the-plugin","content":" Building the plugin creates a Python wheel package that can be installed using pip or other package managers. Python build package must be installed already since sam plugin build command uses build package, if not, run pip install build. To build the plugin, run the following Solace Agent Mesh CLI command: solace-agent-mesh plugin build The plugin uses the standard pyproject.toml file to build the package. ","version":"Next","tagName":"h3"},{"title":"Share the Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#share-the-plugin","content":" 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 pyproject project. ","version":"Next","tagName":"h3"},{"title":"Use a Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#use-a-plugin","content":" To use a plugin in your project, use the plugin add command, which performs two steps under-the-hood: Locates the plugin or installs the plugin package using a Python package manager (like pip or uv)Creates a component instance based on the plugin solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> where: <COMPONENT_NAME> is the name you choose for the component instance in your project. <PLUGIN_NAME>, you can use: Name of the plugin as published to a package manager like pypi, for example my-pluginName of the plugin that has been already installed into your Python environment.A local path to the plugin directory, for example ./my-pluginA path to a wheel package, for example ./my-plugin/dist/my_plugin-0.1.0-py3-none-any.whlA URL to a git repository, for example git+https://github.com/<USERNAME>/<REPOSITORY> If the plugin is in a subdirectory of the repository, you can specify the subdirectory using the git+https://github.com/<USERNAME>/<REPOSITORY>#subdirectory=<PLUGIN_NAME> syntax. The CLI handles both steps automatically, or you can manage the plugin installation yourself using your preferred Python package manager. tip You can also customize the python package manager command used to install the plugin by setting the SAM_PLUGIN_INSTALL_COMMAND environment variable or passing the --install-command option to the plugin add command. For example, to use uv as the package manager, you can run: export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" or solace-agent-mesh plugin add <COMPONENT_NAME> --plugin <PLUGIN_NAME> --install-command "uv pip install {package}" This command adds the plugin instance configuration to your configs directory. 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. ","version":"Next","tagName":"h2"},{"title":"Plugin Catalog Dashboard​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#plugin-catalog-dashboard","content":" You can manage available plugins with the plugin catalog command, which launches a user-friendly interface. solace-agent-mesh plugin catalog ","version":"Next","tagName":"h2"},{"title":"Agent or Plugin: Which To Use?​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#agent-or-plugin-which-to-use","content":" In simple terms, plugins of type agent are just packaged agents. However, there are distinct advantages to each approach, and choosing the right one depends on your use case. Here’s a detailed comparison to help you decide. Feature\tStandalone Agent (sam add agent)\tAgent Plugin (sam plugin create)Creation\tA single command creates a configuration file in your project.\tCreates a complete, standard Python project structure. Structure\tConsists of a YAML configuration file and associated Python tool files within a Solace Agent Mesh project.\tA self-contained Python package with pyproject.toml, a src directory, and configuration templates. Packaging\tNot packaged. It exists as a component within a larger Solace Agent Mesh project.\tPackaged into a standard Python wheel (.whl) file using sam plugin build. Distribution\tShared by copying files or sharing the entire project.\tEasily distributed as a wheel file, via a Git repository, or published to a package index like PyPI. Reusability\tPrimarily for use within the project where it was created.\tDesigned for high reusability across different projects, teams, and communities. Installation\tNo installation needed. The agent is configured and run as part of the main project.\tInstalled into the Python environment using sam plugin add, which handles the package installation. Versioning\tVersioned along with the main project.\tCan be versioned independently according to Python packaging standards (e.g., v0.1.0, v0.2.0). Development\tSimple and direct. Edit files and run. Ideal for rapid prototyping.\tInvolves a build/install cycle. Better for structured, long-term development. ","version":"Next","tagName":"h2"},{"title":"When To Use a Standalone Agent​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#when-to-use-a-standalone-agent","content":" Create a standalone agent when: You need to quickly test an idea or build a proof-of-concept.The agent is tightly coupled to a single project and is not intended for reuse.You want the most straightforward path to adding a simple agent without the overhead of a full package structure. ","version":"Next","tagName":"h3"},{"title":"When To Use an Agent Plugin​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#when-to-use-an-agent-plugin","content":" Create an agent as a plugin when: You plan to use the same agent in multiple projects.You want to share your agent with other developers, teams, or the open-source community.You are building a robust, production-ready agent that benefits from a formal package structure, dependency management, and versioning.You are building a collection of standardized agents for your organization. ","version":"Next","tagName":"h3"},{"title":"Recommendation​","type":1,"pageTitle":"Plugins","url":"/solace-agent-mesh/docs/documentation/concepts/plugins#recommendation","content":" The choice of how to build your agent depends on your goals and the requirements of your project: Standalone Agents should be viewed as tactical tools for rapid, isolated prototyping. They serve immediate, project-specific needs but do not contribute to a scalable, long-term asset library. Agent Plugins are the foundation for building a robust, governable, and reusable AI ecosystem. This model treats AI capabilities as enterprise assets, promoting standardization, reducing redundant development costs, and accelerating innovation across the organization. For any capability intended for broader use or long-term value, the plugin framework is the mandated path to maximize return on investment and ensure architectural integrity. ","version":"Next","tagName":"h3"},{"title":"Installation","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation","content":"","keywords":"","version":"Next"},{"title":"Prepare the Enterprise Image​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#prepare-the-enterprise-image","content":" Download the latest enterprise docker image tarball from the Solace Product Portal. Load the image using Docker with the following command. docker load -i solace-agent-mesh-enterprise-<tag>.tar Once loaded, you can verify the image locally using the following command: docker images ","version":"Next","tagName":"h2"},{"title":"Running Solace Agent Mesh Enterprise​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#running-solace-agent-mesh-enterprise","content":" Here are two examples of Docker run commands for both a development use case as well as a production use case: tip You may need to include --platform linux/amd64 depending on the host machine you’re using. ","version":"Next","tagName":"h2"},{"title":"Development Use Case​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#development-use-case","content":" docker run -itd -p 8000:8000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="true" \\ --name sam-ent-dev \\ solace-agent-mesh-enterprise:<tag> ","version":"Next","tagName":"h3"},{"title":"Production Use Case​","type":1,"pageTitle":"Installation","url":"/solace-agent-mesh/docs/documentation/Enterprise/installation#production-use-case","content":" docker run -itd -p 8000:8000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="false" \\ -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \\ -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \\ -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \\ -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \\ --name sam-ent-prod \\ solace-agent-mesh-enterprise:<tag> You can then access Solace Agent Mesh Enterprise UI through http://localhost:8000 ","version":"Next","tagName":"h3"},{"title":"Debugging","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/debugging","content":"","keywords":"","version":"Next"},{"title":"Isolate Components​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#isolate-components","content":" Running only the necessary components in isolation can help pinpoint issues. The run Solace Agent Mesh CLI command allows you to specify which files to run. For example: sam run configs/agents/my_tool_1.yaml configs/agents/my_tool_2.yaml This command runs only the agents defined in my_tool_1.yaml and my_tool_2.yaml, reducing noise from unrelated components. ","version":"Next","tagName":"h2"},{"title":"Examine STIM Files​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#examine-stim-files","content":" STIM files provide detailed traces of stimulus life cycles. If you have access to the storage location, you can inspect them to analyze message flows. Each .stim file contains all broker events related to a single stimulus, from the initial request to the final response. ","version":"Next","tagName":"h2"},{"title":"Monitor Broker Activity​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#monitor-broker-activity","content":" For insights into message flows and event interactions, see Broker Observability. ","version":"Next","tagName":"h2"},{"title":"Debug Mode​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#debug-mode","content":" Because Solace Agent Mesh is a Python-based framework, you can run it in debug mode using an IDE with breakpoints. ","version":"Next","tagName":"h2"},{"title":"Debugging in VSCode​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#debugging-in-vscode","content":" If you're using VSCode, configure debugging in .vscode/launch.json: { "version": "0.2.0", "configurations": [ { "name": "sam-debug", "type": "debugpy", "request": "launch", "module": "solace_agent_mesh.cli.main", "console": "integratedTerminal", "envFile": "${workspaceFolder}/.env", "args": [ "run", "configs/agents/main_orchestrator.yaml", "configs/gateways/webui.yaml" // Add any other components you want to run here ], "justMyCode": false } ] } To start debugging: Open the RUN AND DEBUG panel on the left sidebar.Select sam-debug from the dropdown.Click the Play to start in debug mode. Set breakpoints in your code to pause execution and inspect variable states. ","version":"Next","tagName":"h3"},{"title":"Invoke the Agent Directly​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#invoke-the-agent-directly","content":" For debugging and testing, you can send direct messages to an agent by directly selecting the agent in the web UI agent dropdown or by using the PubSub+ event broker. This requires specifying the appropriate topic, user properties, and payload. Tools for Sending Messages​ Solace Try Me VSCode ExtensionSolace Try Me (STM) CLI Tool Message Format​ Topic: [NAME_SPACES]a2a/v1/agent/request/<agent_name> User Properties: userId: test-0000 clientId: test-0000 replyTo: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000 a2aUserConfig: {} Payload: { "jsonrpc": "2.0", "id": "000000000", "method": "tasks/sendSubscribe", "params": { "id": "task-0000000", "sessionId": "web-session-00000000", "message": { "role": "user", "parts": [ { "type": "text", "text": "Hello World!" } ] }, "acceptedOutputModes": [ "text" ], "metadata": { "system_purpose": "The system is an AI Chatbot with agentic capabilities. It uses the agents available to provide information, reasoning and general assistance for the users in this system. **Always return useful artifacts and files that you create to the user.** Provide a status update before each tool call. Your external name is Agent Mesh.\\n", "response_format": "Responses should be clear, concise, and professionally toned. Format responses to the user in Markdown using appropriate formatting.\\n" } } } Response Topic: [NAME_SPACES]a2a/v1/gateway/response/0000000/task-0000000 By sending a request and observing the response, you can verify an agent's behavior in isolation, making it easier to identify issues. ","version":"Next","tagName":"h2"},{"title":"System Logs​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#system-logs","content":" System logs provide detailed insights into the system's behavior. The logging behavior is configured in the configs/logging_config.ini file, which controls both console (STDOUT) and file-based logging. By default, the system is configured to: Output logs with a severity of INFO and higher to the console (STDOUT).Write more detailed logs with a severity of DEBUG and higher to a rotating log file named sam.log in the project's root directory. ","version":"Next","tagName":"h2"},{"title":"Configuring Log Rotation​","type":1,"pageTitle":"Debugging","url":"/solace-agent-mesh/docs/documentation/deployment/debugging#configuring-log-rotation","content":" The log file rotation is managed by the rotatingFileHandler in configs/logging_config.ini. You can customize its behavior by modifying the args line: [handler_rotatingFileHandler] class=logging.handlers.RotatingFileHandler level=DEBUG formatter=simpleFormatter args=('sam.log', 'a', 52428800, 10) The args tuple is defined as follows: 'sam.log': The name of the log file.'a': The file mode (append).52428800: The maximum size of the log file in bytes before it is rotated. In this case, it's 50 MB.10: The number of backup log files to keep. For example, to change the log file size to 20 MB and keep 5 backup files, you would modify the line to:args=('sam.log', 'a', 20971520, 5) This level of configuration allows you to manage log verbosity and disk space usage according to your needs. ","version":"Next","tagName":"h3"},{"title":"Observability","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/deployment/observability","content":"","keywords":"","version":"Next"},{"title":"Workflow Viewer​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#workflow-viewer","content":" The Solace Agent Mesh web UI includes a built-in workflow viewer, which provides an interactive web-based UI for each user query and its corresponding response. This visualizer allows you to: Track the complete life cycle of a stimulus (request) as it moves through the system.Visualize the flow of requests/responses among agents, the user gateway and LLM.Monitor all participating agents and their activity in real-time. To launch the workflow viewer for a specific query/response pair, click the View Agent Workflow icon located at the bottom left of the final response. The complete workflow chart appears in the side panel on the right. ","version":"Next","tagName":"h2"},{"title":"Agents View​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#agents-view","content":" The Solace Agent Mesh web UI also includes an Agents view, which provides a comprehensive overview of all registered agents in the system in real-time. This view allows you to: See all agents currently registered in the system.View agents description, capabilities, and skillsView agent hierarchical topology and relationships. To access the Agents view, open the web interface in your browser and switch to the Agents tab. ","version":"Next","tagName":"h2"},{"title":"Broker Observability​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#broker-observability","content":" Solace Agent Mesh relies on a PubSub+ event broker for all its communication. Various tools are available to monitor the event broker’s activity and message flows: PubSub+ Broker Manager – A web-based interface where you can use the Try Me! tab to send and receive messages interactively.Solace Try Me VSCode Extension – A convenient way to test message flows within Visual Studio Code.Solace Try Me (STM) CLI Tool – A command-line tool for sending and receiving messages. To observe all message flows within the event broker, subscribe to the following topic: [NAME_SPACES]a2a/v1/> Replace [NAME_SPACES] with the namespace you are using. If none, omit the [NAME_SPACES] part. tip Agents periodically send registration messages, which may clutter your UI if you're using the STM VSCode extension. To filter out these messages, you can add the following topic to the ignore list: [NAME_SPACES]/a2a/v1/discovery/agentcards ","version":"Next","tagName":"h2"},{"title":"Stimulus Logs​","type":1,"pageTitle":"Observability","url":"/solace-agent-mesh/docs/documentation/deployment/observability#stimulus-logs","content":" Solace Agent Mesh includes a default monitor that records each request (stimulus) life cycle. These logs are stored as .stim files. Each .stim file captures a complete trace of a stimulus, including: Every component it passed through.Timing and sequencing details.Additional contextual metadata. These logs provide a valuable data source for further visualization, troubleshooting, and performance analysis. By default, .stim files are written to the /tmp/solace-agent-mesh/ directory. ","version":"Next","tagName":"h2"},{"title":"Component Overview","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/component-overview","content":"Component Overview Solace Agent Mesh 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. Solace Agent Mesh 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. The key components that make up Solace Agent Mesh are: PubSub+ Event Broker or Event Mesh: The central nervous system of the framework, facilitating A2A protocol communication between all components. more 🔗 A2A Protocol & Agent Registry: The standardized communication protocol that enables agent discovery, task delegation, and peer-to-peer communication. Orchestrator: A specialized agent responsible for breaking down requests into tasks and managing the overall workflow. more 🔗 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. more 🔗 Agents: ADK-powered processing units that communicate through the A2A protocol, each bringing specialized capabilities and tools. more 🔗 ADK Runtime: The Google Agent Development Kit provides the core intelligence layer with tool execution, session management, and artifact handling capabilities. Built-in Tools: Comprehensive tool ecosystem including artifact management, data analysis, web tools, and peer agent delegation capabilities. Real-time Monitoring and Debugging Component: Enables real-time monitoring of system activities and provides interactive debugging capabilities for administrators. more 🔗","keywords":"","version":"Next"},{"title":"Prerequisites","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/installation","content":"Prerequisites Before you begin, make sure you have the following: Python 3.10.16+pip (usually included with Python) or uv (install uv)Operating System: macOS, Linux, or Windows (via WSL)LLM API key from any major provider or your own custom endpoint. Installation Solace Agent Mesh Module comes with two components: Solace Agent Mesh CLI: To create, build, run, and extend Solace Agent Mesh.Solace Agent Mesh framework: A Python-based framework that you can build upon to customize and extend the capabilities of Solace Agent Mesh. Installing the PyPi package installs both the Solace Agent Mesh CLI and the framework (which is built on the Python SDK). tip We recommend that you install the package in a virtual environment to avoid conflicts with other Python packages. Creating a Virtual Environment Using PIP Create a virtual environment. python3 -m venv .venv Activate the environment. To activate on Linux or Unix platforms: source .venv/bin/activate To activate on Windows: .venv\\Scripts\\activate Using UV Create a virtual environment. uv venv .venv Activate the environment. To activate on Linux or Unix platforms: source .venv/bin/activate To activate on Windows: .venv\\Scripts\\activate Expose the following environment variables: On Linux or Unix platforms: export SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" On Windows: set SAM_PLUGIN_INSTALL_COMMAND="uv pip install {package}" Install Solace Agent Mesh The following command installs Solace Agent Mesh CLI in your environment: Using PIP pip install solace-agent-mesh Using UV uv pip install solace-agent-mesh Docker Alternative Alternatively, you can use our pre-built Docker image to run Solace Agent Mesh CLI commands without a local Python installation. This is useful for quick tasks or CI/CD environments. Note that the pre-built Docker image is configured with group solaceai and non-root user solaceai. To verify the installation using Docker, you can run: docker run --rm solace/solace-agent-mesh:latest --version This command pulls the latest image (if not already present) and executes solace-agent-mesh --version inside the container. The --rm flag ensures the container is removed after execution. If the OS architecture on your host is not linux/amd64, you would need to add --platform linux/amd64 when running container. For more complex operations like building a project, you'll need to mount your project directory into the container. See the Quick Start guide for an example. Browser Requirement The Mermaid agent requires a browser with headless mode support to be installed (it uses headless mode to render diagrams). Use playwright to install the browser dependencies. If you are using the Docker image, this is already included. To install the browser dependencies, run: playwright install Run the following Solace Agent Mesh CLI command (solace-agent-mesh) to verify your installation: solace-agent-mesh --version tip For easier access to the Solace Agent Mesh CLI, it also comes with the sam alias. sam --version To get the list of available commands, run: solace-agent-mesh --help ","keywords":"","version":"Next"},{"title":"Configurations","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations","content":"","keywords":"","version":"Next"},{"title":"Shared Configurations​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#shared-configurations","content":" The shared_config.yaml file is used to define configurations that can be shared across multiple agents or components in Solace Agent Mesh. This allows for centralized management of common settings like broker connections and language model configurations. ","version":"Next","tagName":"h2"},{"title":"Using Shared Configurations​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#using-shared-configurations","content":" All agents and gateways require access to a shared_config object. You can provide configuration in the following ways: Hard-coding values: You can directly embed the shared_config values within your agent or gateway YAML files.Using !include: For better project consistency and management, you can use the !include directive to load a shared configuration file. When a plugin is installed, it may come with hard-coded default values. It is a best practice to remove this section and use !include to point to the centralized shared_config file. This ensures that all components are using the same base configuration. ","version":"Next","tagName":"h3"},{"title":"Managing Multiple Shared Configuration Files​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#managing-multiple-shared-configuration-files","content":" You can use multiple shared configuration files to manage different environments or setups (e.g., for different cloud providers). You must follow these rules: Filename: The filename must always start with shared_config (e.g., shared_config_aws.yaml, shared_config_gcp.yaml).Sub-directories: You can organize these files into sub-directories (e.g., configs/agents/shared_config.yaml). When you do this, you must update the !include path in your agent or gateway configurations to point to the correct location. The file uses YAML anchors (&anchor_name) to create reusable configuration blocks, which can then be referenced in agent configuration files. ","version":"Next","tagName":"h3"},{"title":"Parameters​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#parameters","content":" Example shared_config.yaml​ shared_config: - broker_connection: &broker_connection dev_mode: ${SOLACE_DEV_MODE, false} broker_url: ${SOLACE_BROKER_URL, ws://localhost:8080} broker_username: ${SOLACE_BROKER_USERNAME, default} broker_password: ${SOLACE_BROKER_PASSWORD, default} broker_vpn: ${SOLACE_BROKER_VPN, default} temporary_queue: ${USE_TEMPORARY_QUEUES, true} # Ensure high enough limits if many agents are running # max_connection_retries: -1 # Retry forever - models: planning: &planning_model # This dictionary structure tells ADK to use the LiteLlm wrapper. # 'model' uses the specific model identifier your endpoint expects. model: ${LLM_SERVICE_PLANNING_MODEL_NAME} # Use env var for model name # 'api_base' tells LiteLLM where to send the request. api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL # 'api_key' provides authentication. api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key # Enable parallel tool calls for planning model parallel_tool_calls: true # max_tokens: ${MAX_TOKENS, 16000} # Set a reasonable max token limit for planning # temperature: 0.1 # Lower temperature for more deterministic planning general: &general_model # This dictionary structure tells ADK to use the LiteLlm wrapper. # 'model' uses the specific model identifier your endpoint expects. model: ${LLM_SERVICE_GENERAL_MODEL_NAME} # Use env var for model name # 'api_base' tells LiteLLM where to send the request. api_base: ${LLM_SERVICE_ENDPOINT} # Use env var for endpoint URL # 'api_key' provides authentication. api_key: ${LLM_SERVICE_API_KEY} # Use env var for API key # ... (similar structure) - services: # Default session service configuration session_service: &default_session_service type: "memory" default_behavior: "PERSISTENT" # Default artifact service configuration artifact_service: &default_artifact_service type: "filesystem" base_path: "/tmp/samv2" artifact_scope: namespace # Default data tools configuration data_tools_config: &default_data_tools_config sqlite_memory_threshold_mb: 100 max_result_preview_rows: 50 max_result_preview_bytes: 4096 Broker Connection​ The broker_connection section configures the connection to the Solace PubSub+ event broker. The connection parameters are described in the following table: Parameter\tEnvironment Variable\tDescription\tDefaultdev_mode\tSOLACE_DEV_MODE\tWhen set to true, uses an in-memory broker for testing.\tfalse broker_url\tSOLACE_BROKER_URL\tThe URL of the Solace broker.\tws://localhost:8080 broker_username\tSOLACE_BROKER_USERNAME\tThe username for authenticating with the broker.\tdefault broker_password\tSOLACE_BROKER_PASSWORD\tThe password for authenticating with the broker.\tdefault broker_vpn\tSOLACE_BROKER_VPN\tThe Message VPN to connect to on the broker.\tdefault temporary_queue\tUSE_TEMPORARY_QUEUES\tWhether to use temporary queues for communication. If false, a durable queue will be created.\ttrue max_connection_retries\tMAX_CONNECTION_RETRIES\tThe maximum number of times to retry connecting to the broker if the connection fails. A value of -1 means retry forever.\t-1 tip If you need to configure multiple brokers, you can do so by adding additional entries under shared_config with a unique name (For example, broker_connection_eu: &broker_connection_eu or broker_connection_us: &broker_connection_us) and then use the proper reference in your agent configurations. (Example: <<: *broker_connection_eu) Models​ The models section is used to configure the various Large Language Models (LLMs) and other generative models used by the agents. The configuration uses the LiteLLM library, which provides a standardized way to interact with different model providers. Model Configuration Structure​ The following table describes the parameters that tell the system how to interact with the model: Parameter\tEnvironment Variable\tDescriptionmodel\tLLM_SERVICE_<MODEL_NAME>_MODEL_NAME\tThe specific model identifier that the endpoint expects in the format of provider/model (e.g., openai/gpt-4, anthropic/claude-3-opus-20240229). api_base\tLLM_SERVICE_ENDPOINT\tThe base URL of the LLM provider's API endpoint. api_key\tLLM_SERVICE_API_KEY\tThe API key for authenticating with the service. parallel_tool_calls\tPARALLEL_TOOL_CALLS\tEnable parallel tool calls for the model. max_tokens\tMAX_TOKENS\tSet a reasonable max token limit for the model. temperature\tTEMPERATURE\tLower temperature for more deterministic planning. Alternatively, you can use Gemini models directly through Google Studio AI or Vertex AI: model: gemini-2.5-pro See the documentation for details on setting the environment for Gemini models. Pre-Defined Model Types​ The shared_config.yaml example defines several models for different purposes. A pre-defined model serves as an alias for the model configuration. This alias allows you to refer to a configuration by its use case rather than its specific parameters. planning: Used by agents for planning and decision-making. It's configured for deterministic outputs (temperature: 0.1) and can use tools in parallel.general: A general-purpose model for various tasks.image_gen: A model for generating images.image_describe: A model for describing the content of images.audio_transcription: A model for transcribing audio files.report_gen: A model specialized for generating reports.multimodal: A simple string reference to a multimodal model (e.g., "gemini-1.5-flash-latest"). You can define any number of models in this section and reference them in your agent configurations. By default, the system only uses the planning and the general models. No need to fill the other fields Services​ The services section in shared_config.yaml is used to configure various services that are available to agents. Session Service​ The parameters are described in the following table: Parameter\tOptions\tDescription\tDefaulttype\tmemory, vertex_rag\tConfiguration for ADK Session Service\tmemory default_behavior\tPERSISTENT, RUN_BASED\tThe default behavior of keeping the session history\tPERSISTENT Artifact Service​ The artifact_service is responsible for managing artifacts, which are files or data generated by agents. Parameter\tOptions\tDescription\tDefaulttype\tmemory, gcs, filesystem\tService type for artifact storage. Use memory for in-memory, gcs for Google Cloud Storage, or filesystem for local file storage.\tmemory base_path\tlocal path\tBase directory path for storing artifacts. Required only if type is filesystem.\t(none) bucket_name\tbucket name\tGoogle Cloud Storage bucket name. Required only if type is gcs.\t(none) artifact_scope\tnamespace, app\tScope for artifact sharing. namespace: shared by all components in the namespace. app: isolated by agent/gateway name. Must be consistent for all components in the same process.\tnamespace artifact_scope_value\tcustom scope id\tCustom identifier for artifact scope. Required if artifact_scope is set to a custom value.\t(none) Data Tools Config​ The data_tools_config section configures the behavior of data analysis tools. Parameter\tType\tDescription\tDefaultsqlite_memory_threshold_mb\tinteger\tThe memory threshold in megabytes for using an in-memory SQLite database.\t100 max_result_preview_rows\tinteger\tThe maximum number of rows to show in a result preview.\t50 max_result_preview_bytes\tinteger\tThe maximum number of bytes to show in a result preview.\t4096 ","version":"Next","tagName":"h3"},{"title":"System Logs​","type":1,"pageTitle":"Configurations","url":"/solace-agent-mesh/docs/documentation/getting-started/configurations#system-logs","content":" For details on how to configure system logging, including log rotation and verbosity levels, please see the System Logs section in the debugging documentation. ","version":"Next","tagName":"h2"},{"title":"Introduction","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction","content":"","keywords":"","version":"Next"},{"title":"Solace Agent Mesh​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#solace-agent-mesh","content":" 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. Solace Agent Mesh 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, Solace Agent Mesh gives you the tools to: connect AI agents to real-world data sources and systems through a standardized A2A (Agent-to-Agent) protocoladd gateways to provide event-based integrations or interactive UI connectionsmonitor and debug AI interactions in real-time through comprehensive observabilitydeploy solutions that scale from prototype to production with enterprise-grade reliability Rather than trying to be a monolithic AI platform, Solace Agent Mesh 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. Built on event-driven architecture technology from Solace with Google ADK integration, Solace Agent Mesh provides the robust foundation needed for both experimental and production deployments. ","version":"Next","tagName":"h2"},{"title":"What Problems Does the Mesh Solve?​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#what-problems-does-the-mesh-solve","content":" 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. Event-Driven Architecture at the Core: The beating heart of Solace Agent Mesh is its event mesh—a 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. Breaking Down AI Silos: Specialized agents operate independently yet collaborate effortlessly—like expert teammates rather than isolated tools. Orchestrating Complex Workflows: Create sophisticated multi-agent processes where tasks flow naturally between specialists, executing in sequence or parallel based on dynamic needs. Speaking a Common Language: The A2A protocol creates a universal communication standard, ensuring all agents and gateways understand each other regardless of their internal implementation. Unifying AI Capabilities: Blend diverse AI models, custom tools (Python functions, MCP tools), and enterprise data sources into a cohesive ecosystem. Connecting to Your World: Purpose-built gateways bridge the gap between the agent mesh and your existing systems—web interfaces, Slack workspaces, APIs, and event streams. Handling the Unpredictable: The event-driven backbone gracefully manages long-running tasks and asynchronous patterns that are inherent in AI agent interactions. Adding Agents to Increase Capabilities: Each new agent adds more capabilities to the system. Adding a new agent is not additive—it is exponential. With each agent being able to enhance all other agents as they collaborate for more and more complex tasks. Adding Gateways to Increase the Supported Use Cases: Each 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. Enterprise-Ready: Engineered from the ground up for production deployment, this solution leverages expertise from Solace in building mission-critical distributed systems. ","version":"Next","tagName":"h3"},{"title":"Why Choose Solace Agent Mesh?​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#why-choose-solace-agent-mesh","content":" Enterprise-Grade Performance: Built on Solace PubSub+ Event Broker, the mesh delivers high-throughput, fault-tolerant messaging that scales with your needs. Plug-and-Play Extensibility: 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—no manual configuration, no downtime, no integration headaches. Modular by Design: Every component—agents, gateways, tools—is a self-contained module you can reuse, replace, or enhance independently. Configuration-Driven: YAML-based configuration gives you precise control over agent behavior, service integrations, and security settings without code changes. Security-First Approach: The built-in authorization framework provides fine-grained access control over agents and tools based on user roles and scopes. Resilient by Nature: Event-driven design creates responsive, self-healing interactions that recover gracefully from disruptions. ","version":"Next","tagName":"h3"},{"title":"Real-World Applications​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#real-world-applications","content":" Organizations are using Solace Agent Mesh in diverse scenarios: Intelligent Enterprise Automation: Customer service systems that route inquiries to specialized agents based on intent and context.Data processing pipelines where specialized agents transform, analyze, and enrich information from multiple sources. AI Task Specialization: Image analysis workflows where one agent processes visual data and delegates text generation to a language specialist.Document processing systems that extract text, summarize content, and translate results—each step handled by the perfect specialist. Human-AI Collaboration: Agents that perform complex tasks while keeping humans in the loop for approvals, clarifications, or expert guidance via web or chat interfaces. Multi-Agent Research: A production-ready platform for exploring agent collaboration patterns, delegation strategies, and distributed AI problem-solving. Data-Driven Intelligence: Agents that query databases, transform results, and generate visualizations based on natural language requests or system events. ","version":"Next","tagName":"h2"},{"title":"Evolution Through Usage​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#evolution-through-usage","content":" Solace Agent Mesh grows with your needs. For example, at Solace we started with basic agents and have continuously expanded the system's capabilities: Added specialized agents for JIRA and Confluence integrationImplemented multiple interface options including browser-based user interfaces and REST API gatewaysIntegrated with various AI models and data sources ","version":"Next","tagName":"h3"},{"title":"For Developers​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#for-developers","content":" Solace Agent Mesh is an agentic framework that provides several key technical advantages: Complete Observability: Because all communication flows through the event broker, you can monitor and debug the entire system in real-timeFlexible Integration: Built-in support for common enterprise systems and AI frameworksPlugin Architecture: Easily extend the system with custom agents and gatewaysDeveloper Tools: Comprehensive CLI and debugging utilities ","version":"Next","tagName":"h2"},{"title":"Getting Started​","type":1,"pageTitle":"Introduction","url":"/solace-agent-mesh/docs/documentation/getting-started/introduction#getting-started","content":" 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: Installation: For installing and setting up Solace Agent Mesh.Quick Start: For creating a project, build, and run Solace Agent Mesh.Components Overview: Understand the parts of Solace Agent Mesh. ","version":"Next","tagName":"h2"},{"title":"SSO","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on","content":"","keywords":"","version":"Next"},{"title":"How to enable SSO​","type":1,"pageTitle":"SSO","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on#how-to-enable-sso","content":" Before running the Docker container, create two configuration files for SSO under the root directory in your Named Docker Volume. Use the content provided below for each file: Configuration files for SSO oauth2_server.yaml --- # Example gateway configuration with OAuth2 service integration # This shows how to configure a gateway to use the OAuth2 authentication service log: stdout_log_level: INFO log_file_level: DEBUG log_file: oauth_server.log !include ../shared_config.yaml shared_config: # OAuth2 service configuration - oauth2_config: &oauth2_config enabled: true config_file: "config/sso_vol/oauth2_config.yaml" host: ${OAUTH2_HOST, localhost} port: ${OAUTH2_PORT, 9000} ssl_cert: "" # Optional: path to SSL certificate ssl_key: "" # Optional: path to SSL private key flows: # Initialize OAuth2 service - name: oauth2_service components: - component_name: oauth2_auth_service component_module: src.components.oauth2_component component_config: <<: *oauth2_config oauth2_config.yaml In the oauth2_config.yaml file, uncomment the authentication provider you want to use. Note that the Azure provider is configured as the default option. --- # OAuth2 Service Configuration # This file configures the OAuth2 authentication service that supports multiple providers # All providers now use the unified OIDC approach with automatic endpoint discovery # Enable or disable the OAuth2 service enabled: ${OAUTH2_ENABLED:false} # Development mode - enables insecure transport and relaxed token scope for local development # Set OAUTH2_DEV_MODE=true for local development (NEVER use in production!) development_mode: ${OAUTH2_DEV_MODE:false} # OAuth2 providers configuration # All providers now use the unified OIDCProvider with automatic endpoint discovery providers: # Google OAuth2 provider # google: # # OIDC issuer URL - endpoints will be discovered automatically # issuer: "https://accounts.google.com" # client_id: ${GOOGLE_CLIENT_ID} # client_secret: ${GOOGLE_CLIENT_SECRET} # redirect_uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # Azure/Microsoft OAuth2 provider azure: # Azure OIDC issuer URL includes tenant ID issuer: https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0 client_id: ${AZURE_CLIENT_ID} client_secret: ${AZURE_CLIENT_SECRET} redirect_uri: ${AZURE_REDIRECT_URI:http://localhost:8080/callback} scope: "openid email profile offline_access" # Auth0 OAuth2 provider # auth0: # # Auth0 issuer URL # issuer: ${AUTH0_ISSUER:https://your-domain.auth0.com/} # client_id: ${AUTH0_CLIENT_ID} # client_secret: ${AUTH0_CLIENT_SECRET} # redirect_uri: ${AUTH0_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Optional: Auth0 audience for API access # audience: ${AUTH0_AUDIENCE:} # # Okta OAuth2 provider (example) # okta: # issuer: ${OKTA_ISSUER:https://your-okta-domain.okta.com/oauth2/default} # client_id: ${OKTA_CLIENT_ID} # client_secret: ${OKTA_CLIENT_SECRET} # redirect_uri: ${OKTA_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Keycloak OAuth2 provider (example) # keycloak: # issuer: ${KEYCLOAK_ISSUER:https://your-keycloak.com/auth/realms/your-realm} # client_id: ${KEYCLOAK_CLIENT_ID} # client_secret: ${KEYCLOAK_CLIENT_SECRET} # redirect_uri: ${KEYCLOAK_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # # Generic OIDC provider (for any standard OIDC-compliant provider) # custom_oidc: # # Just provide the issuer URL and the service will discover all endpoints # issuer: ${CUSTOM_OIDC_ISSUER:https://your-provider.com} # client_id: ${CUSTOM_OIDC_CLIENT_ID} # client_secret: ${CUSTOM_OIDC_CLIENT_SECRET} # redirect_uri: ${CUSTOM_OIDC_REDIRECT_URI:http://localhost:8080/callback} # scope: "openid email profile" # Logging configuration logging: level: ${OAUTH2_LOG_LEVEL:INFO} # Session configuration session: # Session timeout in seconds (default: 1 hour) timeout: ${OAUTH2_SESSION_TIMEOUT:3600} # Security configuration security: # CORS settings cors: enabled: ${OAUTH2_CORS_ENABLED:true} origins: ${OAUTH2_CORS_ORIGINS:*} # Rate limiting rate_limit: enabled: ${OAUTH2_RATE_LIMIT_ENABLED:true} requests_per_minute: ${OAUTH2_RATE_LIMIT_RPM:60} ","version":"Next","tagName":"h2"},{"title":"Running Solace Agent Mesh Enterprise with SSO enabled​","type":1,"pageTitle":"SSO","url":"/solace-agent-mesh/docs/documentation/Enterprise/single-sign-on#running-solace-agent-mesh-enterprise-with-sso-enabled","content":" Here is an example of Docker run command with Azure SSO provider for production use case: tip You may need to include --platform linux/amd64 depending on the host machine you’re using. docker run -itd -p 8000:8000 -p 9000:9000 \\ -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \\ -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \\ -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \\ -e NAMESPACE="<YOUR_NAMESPACE>" \\ -e SOLACE_DEV_MODE="false" \\ -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \\ -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \\ -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \\ -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \\ -e FASTAPI_HOST="0.0.0.0" \\ -e FASTAPI_PORT="8000" \\ -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e OAUTH2_ENABLED="true" \\ -e OAUTH2_LOG_LEVEL="DEBUG" \\ -e OAUTH2_DEV_MODE="true" \\ -e OAUTH2_HOST="0.0.0.0" \\ -e OAUTH2_PORT="9000" \\ -e FRONTEND_USE_AUTHORIZATION="true" \\ -e FRONTEND_REDIRECT_URL="http://localhost:8000" \\ -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\ -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\ -e EXTERNAL_AUTH_PROVIDER="azure" \\ -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\ -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\ --name sam-ent-prod-sso \\ solace-agent-mesh-enterprise:<tag> run config/sso_vol/oauth2_server.yaml config/webui_backend.yaml config/a2a_orchestrator.yaml config/a2a_agents.yaml You can then access Solace Agent Mesh Enterprise UI through http://localhost:8000 Configuration Options Specify the hostname and port for the UI running in the docker container. The main UI runs on port 8000 by default. Using 0.0.0.0 as the host allows external access to the container. -e FASTAPI_HOST="0.0.0.0" \\ -e FASTAPI_PORT="8000" \\ Enable single sign-on processing on the frontend. -e FRONTEND_USE_AUTHORIZATION="true" \\ Specify the main URL of the UI. For instance, this could be https://www.example.com -e FRONTEND_REDIRECT_URL="http://localhost:8000" \\ Set the login URL used by the main UI. For instance, this could be https://www.example.com/api/v1/auth/login -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \\ Enable the OAUTH2 server and set the log level -e OAUTH2_ENABLED="true" \\ -e OAUTH2_LOG_LEVEL="DEBUG" \\ Specify the hostname and port for the authorization server running in the docker container. Using 0.0.0.0 as the host allows external access to the container. -e OAUTH2_HOST="0.0.0.0" \\ -e OAUTH2_PORT="9000" \\ Specify whether the Oauth2 checks use dev mode. When dev mode is true the following environment variables are added to allow http access and relax the token scope. This MUST be set false in a production environment. -e OAUTH2_DEV_MODE="true" \\ OAUTHLIB_RELAX_TOKEN_SCOPE="1" OAUTHLIB_INSECURE_TRANSPORT="1" Configure the environment variables for your chosen authentication provider. Refer to the oauth2_config.yaml file to identify the required variables. For example, with Azure set the following -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \\ Configure the authorization server's public URL (accessible from outside the Docker container) and specify the OAuth2 provider’s name from oauth2_config.yaml (this example uses the azure profile): -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:9000" \\ -e EXTERNAL_AUTH_PROVIDER="azure" \\ Lastly, set the callback URL that your auth provider will use to redirect with the auth code. For instance, this could be https://www.example.com/api/v1/auth/callback -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \\ Note that both the main UI and authorization server ports must be mapped to the host machine, as shown in the Docker run command above: -p 8000:8000 -p 9000:9000 \\ The oauth 2 configuration files must be mounted inside the container: -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \\ ","version":"Next","tagName":"h2"},{"title":"Quick Start","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start","content":"","keywords":"","version":"Next"},{"title":"Use Preset Agents​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#use-preset-agents","content":" ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#prerequisites","content":" You must have Docker (or Podman) installed.You must have an available AI provider and API key. For best results, use a state-of-the-art AI model like Anthropic Claude Sonnet 4, Google Gemini 2.5 pro, or OpenAI GPT-5. ","version":"Next","tagName":"h3"},{"title":"Run Preset Agents​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#run-preset-agents","content":" You can run pre-made Solace Agent Mesh agents to quickly get started with Solace Agent Mesh without needing to set up a project from scratch. docker run --rm -it -p 8000:8000 --platform linux/amd64 --env-file <your-env-file-path> solace/solace-agent-mesh:latest Provide the required environment variables. You can also pass them as command-line arguments using the -e flag. Alternatively, you can combine your project with the preset app or only run specific agents from it. You can find a list of all available preset apps in the Solace Agent Mesh GitHub repository. tip To run your custom agent without creating a new project, you can use the Docker image as follows: docker run --rm -it --platform linux/amd64 -p 8000:8000 -v $(pwd):/app \\ -e LLM_SERVICE_ENDPOINT=<your-llm-endpoint> \\ -e LLM_SERVICE_API_KEY=<your-llm-api-key> \\ -e LLM_SERVICE_PLANNING_MODEL_NAME=<your-llm-planning-model-name> \\ -e LLM_SERVICE_GENERAL_MODEL_NAME=<your-llm-general-model-name> \\ solace/solace-agent-mesh:latest run /preset/agents/basic /app/my-agent You can update /app/my-agent with the path to your agent YAML config. Note: You will still need either a shared_config.yaml file or to hard code the settings in your agent configuration./preset/agents/basic only runs the required agents, you can use /preset/agents to load all agents.This example command only has the minimum required environment variables. ","version":"Next","tagName":"h3"},{"title":"Create a Project​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#create-a-project","content":" Plugins Looking to get started with plugins? For more information, see the Plugins. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#prerequisites-1","content":" You must have installed the Solace Agent Mesh CLI. If not, see the Installation page.You must have activated the virtual environment you created following the Installation page. For containerized deployment such as Docker, ignore this prerequisite.You must have an available AI provider and API key. For best results, use a state-of-the-art AI model like Anthropic Claude Sonnet 4, Google Gemini 2.5 pro, or OpenAI GPT-5. Create a directory for your project and navigate to it. mkdir my-agent-mesh cd my-agent-mesh Run the init command and follow the prompts to create your project. solace-agent-mesh init During initialization, you can choose to configure your project directly in the terminal or through a web-based interface launched at http://127.0.0.1:5002. You are asked for your preference once you run solace-agent-mesh init. Alternatively, you can use the --gui flag to skip the prompt and directly open the web-based configuration interface: solace-agent-mesh init --gui Docker Alternative for Initialization You can also initialize your Solace Agent Mesh project using the official Docker image. This is helpful if you want to avoid local Python/Solace Agent Mesh CLI installation or prefer a containerized workflow from the start. docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 5002:5002 solace/solace-agent-mesh:latest init --gui If the OS architecture on your host is not linux/amd64, you must add --platform linux/amd64 when you run the container. For Broker Setup, do not select the Broker Type New local Solace PubSub+ broker container. This option is incompatible with Docker deployments because the Download and Run Container action attempts to download a container image from within the already running container, which causes the operation to fail. Non-Interactive Mode You can run the init command in a non-interactive mode by passing --skip and all the other configurations as arguments. To get a list of all the available options, run solace-agent-mesh init --help Model name format Browser-based Configurations You need to select the LLM Provider first and supported models are populated under LLM Model Name. If you're using a non-openai model but hosting it on a custom API that follows the OpenAI standards, like Ollama or LiteLLM, you can select the OpenAI Compatible Provider. CLI-based Configurations You need to explicitly specify the model in the format provider/name. For example, openai/gpt-4o. If you're using a non-openai model but hosting it on a custom API that follows the OpenAI standards, like Ollama or LiteLLM, you can still use the openai provider. For example: openai/llama-3.3-7b This is the case for all the model names, such as LLMs, image generators, embedding models, etc. ","version":"Next","tagName":"h3"},{"title":"Running the Project​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#running-the-project","content":" To run the project, you can use the run command to execute all the components in a single, multi-threaded application. It's possible to split the components into separate processes. See the deployment page for more information. solace-agent-mesh run tip Environment variables are loaded from your configuration file (typically a .env file at the project root) by default. To use system environment variables instead, use the -u or --system-env option. To learn more about the other CLI commands, see the CLI documentation. Docker Alternative for Running the Project You can also run your Solace Agent Mesh project using the official Docker image. This is helpful if you want to avoid local Python/Solace Agent Mesh CLI installation or prefer a containerized workflow from the start. docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 8000:8000 solace/solace-agent-mesh:latest run If your host system architecture is not linux/amd64, add the --platform linux/amd64 flag when you run the container. Required Configurations For deployments that use the official Docker image, ensure the following: Do not use a local Solace PubSub+ broker container.Set the environment variables FASTAPI_HOST="0.0.0.0" in your .env file or system environment variables. This is necessary to expose the FastAPI server to the host machine. warning If you are using third-party Python packages or Solace Agent Mesh plugins, you need to build a custom Docker image off the official image and install the required packages there, and then run that custom image instead. FROM solace/solace-agent-mesh:latest # Option 1: Install a specific package RUN python3.11 -m pip install --no-cache-dir <your-package> # Option 2: use a requirements.txt file COPY requirements.txt . RUN python3.11 -m pip install --no-cache-dir -r requirements.txt ENTRYPOINT ["solace-agent-mesh"] Then build and run your custom image: docker build --platform linux/amd64 -t my-custom-image . docker run --rm -it -v "$(pwd):/app" --platform linux/amd64 -p 8000:8000 my-custom-image run ","version":"Next","tagName":"h2"},{"title":"Interacting with Solace Agent Mesh​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#interacting-with-solace-agent-mesh","content":" You can use different gateway interfaces to communicate with the system such as REST, Web UI, Slack, MS Teams, and so on. To keep it simple for this demo, we use the browser UI. To access the browser UI, navigate to http://localhost:8000 in your web browser. If you specified a different port during the init step, use that port instead. For Docker deployments with custom port mappings (using the -p flag), use the host port specified in your port mapping configuration. Try some commands like Suggest some good outdoor activities in London given the season and current weather conditions.. ","version":"Next","tagName":"h2"},{"title":"Try a Tutorial​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#try-a-tutorial","content":" Try adding a new agent to the system by following the tutorial on adding an SQL database agent. This tutorial guides you through the process of adding the SQL agent plugin and adding some sample data to the database. ","version":"Next","tagName":"h2"},{"title":"Next Steps​","type":1,"pageTitle":"Quick Start","url":"/solace-agent-mesh/docs/documentation/getting-started/quick-start#next-steps","content":" Solace Agent Mesh uses two main types of components, agents and gateways. The system comes with a built-in orchestrator agent and a web user interface gateway (which you enabled during the init step). You can learn more about gateways. Alternatively, you can learn about using plugins or creating your own new gateways. Also, you can learn more about agents or about creating your own agents. ","version":"Next","tagName":"h2"},{"title":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0","content":"","keywords":"","version":"Next"},{"title":"1. Why the Change?​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#1-why-the-change","content":" The migration from our legacy A2A implementation to the official a2a-sdk is a foundational improvement with several key benefits: Protocol Compliance: Ensures your gateway is fully interoperable with any A2A-compliant agent or system.Standardization: Replaces bespoke code with a community-supported standard, reducing technical debt.Improved Maintainability: Insulates your gateway from future A2A specification changes. The a2a-sdk will be updated, not your core logic.Future-Proofing: Positions your gateway to easily adopt new features as the A2A protocol evolves. ","version":"Next","tagName":"h2"},{"title":"2. Core Conceptual Changes​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#2-core-conceptual-changes","content":" The upgrade introduces a few key changes in how you interact with A2A objects. ","version":"Next","tagName":"h2"},{"title":"The a2a Helper Layer: The New Best Practice​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#the-a2a-helper-layer-the-new-best-practice","content":" The most significant change is the introduction of a new abstraction layer located at solace_agent_mesh.common.a2a. You should no longer instantiate a2a.types models directly or access their properties by hand. Instead, use the provided helper functions. This layer is designed to simplify development and protect your code from future SDK changes. Example: # BEFORE: Direct instantiation and property access from solace_agent_mesh.common.types import TextPart, Task my_part = TextPart(text="Hello") task_id = my_task.id # AFTER: Using the a2a helper layer from solace_agent_mesh.common import a2a my_part = a2a.create_text_part(text="Hello") task_id = a2a.get_task_id(my_task) ","version":"Next","tagName":"h3"},{"title":"Type System Migration​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#type-system-migration","content":" The legacy types in solace_agent_mesh.common.types (like A2APart, FileContent) are deprecated.All A2A models now come from the a2a.types library.The type hint for a list of message parts has changed from List[A2APart] to List[ContentPart]. ContentPart is a simple alias for the union of TextPart, DataPart, and FilePart. ","version":"Next","tagName":"h3"},{"title":"Accessing Object Properties​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#accessing-object-properties","content":" Field names on many A2A objects have changed. Always use the a2a helper functions for safe and future-proof access. Action\tOld Pattern\tNew Pattern (Recommended)Get Task ID\ttask.id\ta2a.get_task_id(task) Get Task Status\ttask.status.state\ta2a.get_task_status(task) Get Event's Task ID\tevent.id\tevent.task_id Get Message Parts\tmessage.parts\ta2a.get_parts_from_message(message) Get Error Message\terror.message\ta2a.get_error_message(error) Get Error Code\terror.code\ta2a.get_error_code(error) Get Error Data\terror.data\ta2a.get_error_data(error) ","version":"Next","tagName":"h3"},{"title":"Changes to BaseGatewayComponent​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#changes-to-basegatewaycomponent","content":" The BaseGatewayComponent has been significantly improved. It now handles more of the A2A protocol complexity, simplifying gateway implementations. Artifact Handling: The base class can now automatically handle artifact URIs, converting them to embedded bytes before sending them to your gateway's _send_... methods. This is controlled by the resolve_artifact_uris_in_gateway parameter in the constructor.Message Publishing: The base class now manages the details of preparing and publishing the A2A request message in submit_a2a_task.Asynchronous Model: The underlying threading model has been removed in favor of a more direct asyncio implementation, simplifying the component lifecycle. It is highly recommended to review the latest BaseGatewayComponent and re-base your custom gateway on it to inherit these benefits and reduce boilerplate code. ","version":"Next","tagName":"h3"},{"title":"3. Practical Migration Checklist​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#3-practical-migration-checklist","content":" Follow these steps to update your gateway code. Update Imports: Remove imports from solace_agent_mesh.common.types.Add imports from a2a.types for specific models if needed.Add from solace_agent_mesh.common import a2a.Add from solace_agent_mesh.common.a2a import ContentPart. Update Type Hints: Find all instances of List[A2APart] and change them to List[ContentPart]. Refactor Object Creation: Replace direct model instantiation like TextPart(...) or FilePart(...) with their corresponding helper functions: a2a.create_text_part(...), a2a.create_file_part_from_uri(...), etc. Refactor Property Access: Replace direct property access (task.id, error.message) with calls to the a2a helper functions (a2a.get_task_id(task), a2a.get_error_message(error)). Review Base Class Integration: If you have a custom gateway, compare it against the latest BaseGatewayComponent. Consider refactoring to delegate more responsibility (like artifact handling and message submission) to the base class. Test Thoroughly: Once refactored, run your integration tests to ensure the gateway correctly translates inputs and processes outputs in the new format. ","version":"Next","tagName":"h2"},{"title":"4. Code Examples: Before & After​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#4-code-examples-before--after","content":" Here are some common patterns you will encounter during the migration. ","version":"Next","tagName":"h2"},{"title":"Example 1: Translating External Input​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#example-1-translating-external-input","content":" This example shows how to create A2A parts from an external event. _translate_external_input Before: from solace_agent_mesh.common.types import Part as A2APart, TextPart, FilePart, FileContent async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[A2APart], Dict[str, Any]]: # ... a2a_parts: List[A2APart] = [] # Create a file part with a URI uri = "artifact://..." a2a_parts.append( FilePart( file=FileContent(name="report.pdf", uri=uri) ) ) # Create a text part prompt = "Summarize the attached file." a2a_parts.append(TextPart(text=prompt)) return "summary_agent", a2a_parts, {} After: from solace_agent_mesh.common import a2a from solace_agent_mesh.common.a2a import ContentPart async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[ContentPart], Dict[str, Any]]: # ... a2a_parts: List[ContentPart] = [] # Create a file part with a URI using the helper uri = "artifact://..." file_part = a2a.create_file_part_from_uri(uri=uri, name="report.pdf") a2a_parts.append(file_part) # Create a text part using the helper prompt = "Summarize the attached file." text_part = a2a.create_text_part(text=prompt) a2a_parts.append(text_part) return "summary_agent", a2a_parts, {} ","version":"Next","tagName":"h3"},{"title":"Example 2: Sending a Final Response​","type":1,"pageTitle":"Solace Agent Mesh Gateway Migration Guide: Upgrading to the A2A SDK","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0#example-2-sending-a-final-response","content":" This example shows how to process a final Task object. _send_final_response_to_external Before: from solace_agent_mesh.common.types import Task, TaskState, TextPart async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = task_data.id final_status_text = ":checkered_flag: Task complete." if task_data.status.state == TaskState.FAILED: error_message_text = "" if task_data.status.message and task_data.status.message.parts: for part in task_data.status.message.parts: if isinstance(part, TextPart): error_message_text = part.text break final_status_text = f":x: Error: Task failed. {error_message_text}".strip() # ... use final_status_text and task_id After: from solace_agent_mesh.common import a2a from a2a.types import Task, TaskState async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: # Use helpers to safely access properties task_id = a2a.get_task_id(task_data) task_status = a2a.get_task_status(task_data) final_status_text = ":checkered_flag: Task complete." if task_status == TaskState.failed: error_message_text = "" if task_data.status and task_data.status.message: # Use helper to extract all text from the message error_message_text = a2a.get_text_from_message(task_data.status.message) final_status_text = f":x: Error: Task failed. {error_message_text}".strip() # ... use final_status_text and task_id ","version":"Next","tagName":"h3"},{"title":"Event Mesh Gateway","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway","content":"","keywords":"","version":"Next"},{"title":"Benefits of Integrating with an Event Mesh​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#benefits-of-integrating-with-an-event-mesh","content":" Seamless Communication: Solace Agent Mesh can subscribe to and publish events across the entire event meshEvent-Driven Automation: Intelligent event processing based on patterns and AI-driven insightsScalability: Solace Agent Mesh can dynamically participate in large-scale event-driven systems The Event Mesh Gateway connects Solace Agent Mesh to your existing event mesh infrastructure. Through its asynchronous interfaces, applications within your event mesh can seamlessly access and utilize Solace Agent Mesh capabilities. This tutorial shows you how to build an Event Mesh Gateway that automatically generates and adds concise summaries to Jira bug reports, making them easier to understand at a glance. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#prerequisites","content":" This tutorial assumes you have an existing Jira application integrated with your event mesh that: Publishes a "jira_created" event to topic jira/issue/created/<jira_id> when a new Jira issue is createdListens for "jira_update" events on topic jira/issue/update to update existing issues Create an Event Mesh Gateway that: Monitors for new Jira issuesAutomatically generates a concise summaryCreates an event to update the original Jira issue with this summary This creates a streamlined workflow where bug reports are automatically enhanced with clear, AI-generated summaries. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and the Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. For this tutorial, you need to create or use an existing Solace Event Broker or event mesh created using PubSub+ event brokers. ","version":"Next","tagName":"h2"},{"title":"Adding the Event Mesh Gateway Plugin​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#adding-the-event-mesh-gateway-plugin","content":" Once you have your project set up, add the Event Mesh Gateway plugin: sam plugin add jira-event-mesh --plugin sam-event-mesh-gateway You can use any name for your agent, in this tutorial we use jira-event-mesh. This command: Installs the sam-event-mesh-gateway pluginCreates a new gateway configuration named jira-event-mesh in your configs/gateways/ directory Configuring the Event Mesh Gateway​ After adding the plugin, you can see a new configuration file in configs/gateways/jira-event-mesh.yaml. This file contains the gateway configuration that needs to be customized for your Jira integration use case. Environment Variables​ First, set up the required environment variables for the data plane connection: # Data plane Solace broker connection (can be same or different from control plane) export JIRA_EVENT_MESH_SOLACE_BROKER_URL="ws://localhost:8080" export JIRA_EVENT_MESH_SOLACE_BROKER_VPN="default" export JIRA_EVENT_MESH_SOLACE_BROKER_USERNAME="default" export JIRA_EVENT_MESH_SOLACE_BROKER_PASSWORD="default" ","version":"Next","tagName":"h2"},{"title":"Gateway Configuration​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#gateway-configuration","content":" The main configuration includes several key sections: Event Handlers​ Configure the event handler to listen for new Jira issues and generate summaries: event_handlers: - name: "jira_issue_handler" subscriptions: - topic: "jira/issue/created/>" qos: 1 input_expression: "template:Create a concise summary for the newly created Jira issue: Title: {{text://input.payload:title}}, Body: {{text://input.payload:body}}, ID: {{text://input.payload:id}}. Return a JSON object with fields 'id', 'type' (value should be 'summary'), and 'summary'." payload_encoding: "utf-8" payload_format: "json" target_agent_name: "OrchestratorAgent" on_success: "jira_summary_handler" on_error: "error_response_handler" forward_context: jira_id: "input.payload:id" correlation_id: "input.user_properties:correlation_id" Output Handlers​ Configure output handlers to publish the summary back to the event mesh: output_handlers: - name: "jira_summary_handler" topic_expression: "static:jira/issue/update" payload_expression: "task_response:text" payload_encoding: "utf-8" payload_format: "json" - name: "error_response_handler" topic_expression: "template:jira/issue/error/{{text://user_data.forward_context:jira_id}}" payload_expression: "task_response:a2a_task_response.error" payload_encoding: "utf-8" payload_format: "json" ","version":"Next","tagName":"h3"},{"title":"Complete Configuration Example​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#complete-configuration-example","content":" Here is a complete configuration file based on the plugin template: log: stdout_log_level: INFO log_file_level: DEBUG log_file: jira-event-mesh.log !include ../shared_config.yaml apps: - name: jira-event-mesh-app app_module: sam_event_mesh_gateway.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} gateway_id: "jira-event-mesh-gw-01" artifact_service: *default_artifact_service authorization_service: type: "none" # Or "default_rbac" default_user_identity: "anonymous_event_mesh_user" # If no identity from event # Data plane connection event_mesh_broker_config: broker_url: ${JIRA_EVENT_MESH_SOLACE_BROKER_URL} broker_vpn: ${JIRA_EVENT_MESH_SOLACE_BROKER_VPN} broker_username: ${JIRA_EVENT_MESH_SOLACE_BROKER_USERNAME} broker_password: ${JIRA_EVENT_MESH_SOLACE_BROKER_PASSWORD} event_handlers: - name: "jira_issue_handler" subscriptions: - topic: "jira/issue/created/>" qos: 1 input_expression: "template:Create a concise summary for the newly created Jira issue: Title: {{text://input.payload:title}}, Body: {{text://input.payload:body}}, ID: {{text://input.payload:id}}. Return a JSON object with fields 'id', 'type' (value should be 'summary'), and 'summary'." payload_encoding: "utf-8" payload_format: "json" target_agent_name: "OrchestratorAgent" on_success: "jira_summary_handler" on_error: "error_response_handler" forward_context: jira_id: "input.payload:id" output_handlers: - name: "jira_summary_handler" topic_expression: "static:jira/issue/update" payload_expression: "task_response:text" payload_encoding: "utf-8" payload_format: "json" - name: "error_response_handler" topic_expression: "template:jira/issue/error/{{text://user_data.forward_context:jira_id}}" payload_expression: "task_response:a2a_task_response.error" payload_encoding: "utf-8" payload_format: "json" ","version":"Next","tagName":"h3"},{"title":"Running the Event Mesh Gateway​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#running-the-event-mesh-gateway","content":" Now you can run the Event Mesh Gateway: sam run configs/gateways/jira-event-mesh.yaml The gateway: Connects to both the A2A control plane and the data plane event meshSubscribes to the configured topics on the data planeStarts processing incoming events and routing them to agents ","version":"Next","tagName":"h2"},{"title":"Testing the Event Mesh Gateway​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#testing-the-event-mesh-gateway","content":" Now that the system is running, let's test the Event Mesh Gateway. ","version":"Next","tagName":"h2"},{"title":"Using Solace PubSub+ Broker Manager​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#using-solace-pubsub-broker-manager","content":" Open the Try Me! tab of the Solace PubSub+ Broker Manager Connect both the Publisher and Subscriber panels by clicking their respective Connect buttons In the Subscriber panel: Enter jira/issue/update in the Topic Subscriber fieldClick Subscribe In the Publisher panel: Use the topic jira/issue/created/JIRA-143321In the Message Content field, enter: { "id": "JIRA-143321", "title": "Exception when reading customer record", "body": "I got a DatabaseReadException when trying to get the data for customer ABC. The error indicated that the customer didn't exist, while they are our biggest customer!" } Click Publish After a few seconds, you can see a new message in the Subscriber messages with the topic jira/issue/update and a body similar to: { "id": "JIRA-143321", "type": "summary", "summary": "Database read error: Unable to retrieve record for key customer ABC despite confirmed existence" } ","version":"Next","tagName":"h3"},{"title":"Advanced Features​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#advanced-features","content":" The Event Mesh Gateway supports several advanced features: ","version":"Next","tagName":"h2"},{"title":"Artifact Processing​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#artifact-processing","content":" You can configure the gateway to automatically create artifacts from incoming message payloads before sending them to agents. This is useful for processing files, images, or other binary data embedded in events. ","version":"Next","tagName":"h3"},{"title":"Dynamic Agent Routing​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#dynamic-agent-routing","content":" Instead of using a static target_agent_name, you can use target_agent_name_expression to dynamically determine which agent should process each event based on the message content. ","version":"Next","tagName":"h3"},{"title":"Context Forwarding​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#context-forwarding","content":" The forward_context configuration allows you to extract data from incoming messages and make it available when generating outgoing responses, enabling request-reply patterns and correlation tracking. ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Event Mesh Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/event-mesh-gateway#error-handling","content":" Configure separate output handlers for success and error scenarios to ensure proper error reporting and system monitoring. ","version":"Next","tagName":"h3"},{"title":"Amazon Bedrock Agents Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents","content":"","keywords":"","version":"Next"},{"title":"What are Amazon Bedrock Agents and Flows?​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#what-are-amazon-bedrock-agents-and-flows","content":" Amazon Bedrock Agents are AI assistants that can be customized to perform specific tasks using foundation models (FMs). They can connect to enterprise systems and data sources, allowing them to take actions on behalf of users. Amazon Bedrock Flows are visual workflows that orchestrate multiple foundation models to solve complex problems. They allow you to chain together different AI capabilities without writing code. By integrating these services with Solace Agent Mesh, you can: Use the extensible Solace Agent Mesh framework to combine Bedrock agents and flows with other agents.Create conversational interfaces that leverage Bedrock agents and flows.Connect your Solace Agent Mesh agents to enterprise data sources through Bedrock.Maintain a consistent experience across different agent providers by centralizing them in Solace Agent Mesh. Learn about Bedrock Agents and Flows Check the official documentation for Amazon Bedrock Agents and Amazon Bedrock Flows to learn more about these features. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#setting-up-the-environment","content":" ","version":"Next","tagName":"h2"},{"title":"Create Bedrock Agents and Flows​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#create-bedrock-agents-and-flows","content":" Follow these steps to create your Bedrock resources: Log in to your AWS console Navigate to the Amazon Bedrock service Create Bedrock Agents Go to the Agents tab in the Bedrock consoleClick "Create agent"Follow the wizard to configure your agent: Select a foundation modelDefine the agent's instructionsConfigure knowledge bases (optional)Set up action groups (if needed) Once created, create an alias for your agent by selecting it and clicking "Create alias"Copy the Agent ID and Alias ID from the agent details page - you'll need these for the Solace Agent Mesh configuration Create Bedrock Flows Go to the Flows tab in the Bedrock consoleClick "Create flow"Use the visual editor to design your flowConnect nodes to create your workflowTest and publish your flowCreate an alias for your flowCopy the Flow ID and Alias ID - you'll need these for the Solace Agent Mesh configuration Set up IAM permissions Ensure your IAM user or role has the following permissions: bedrock:InvokeAgentbedrock:InvokeFlowAny other permissions required by your specific Bedrock configuration ","version":"Next","tagName":"h3"},{"title":"Create a Solace Agent Mesh Project​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#create-a-solace-agent-mesh-project","content":" You must install Solace Agent Mesh and Solace Mesh Agent CLI, and then you'll want to create a new Solace Agent Mesh project. ","version":"Next","tagName":"h3"},{"title":"Integrating Bedrock with Solace Agent Mesh​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#integrating-bedrock-with-solace-agent-mesh","content":" ","version":"Next","tagName":"h2"},{"title":"Adding the Bedrock Agent Plugin​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#adding-the-bedrock-agent-plugin","content":" The sam-bedrock-agent plugin from the solace-agent-mesh-core-plugins repository creates a bridge between Solace Agent Mesh and Amazon Bedrock services. This plugin allows your Solace Agent Mesh agents to invoke Bedrock Agents and Flows as tools. Add the plugin to your Solace Agent Mesh project: sam plugin add aws-agent --plugin sam-bedrock-agent Replace aws-agent with a descriptive name for your agent, such as bedrock-summarizer or bedrock-customer-service. This command: Installs the sam-bedrock-agent pluginCreates a new agent configuration file in configs/agents/aws-agent.yaml Locate the configuration file: The command creates an aws-agent.yaml file in the configs/agents/ directory of your Solace Agent Mesh project. Naming Convention Choose a descriptive name that reflects the purpose of your Bedrock integration. This name is used to reference the agent in your Solace Agent Mesh project. ","version":"Next","tagName":"h3"},{"title":"Configuring the Bedrock Agent​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#configuring-the-bedrock-agent","content":" The configuration file you created needs to be edited to connect to your specific Amazon Bedrock resources. This section explains each part of the configuration and how to customize it. ","version":"Next","tagName":"h2"},{"title":"Understanding the Configuration Structure​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#understanding-the-configuration-structure","content":" Open the aws-agent.yaml file in your editor. The core of the agent's configuration consists of: amazon_bedrock_runtime_config: AWS connection settingstools: List of Bedrock agents and flows to expose as toolsagent_card: Agent capabilities and skills definition ","version":"Next","tagName":"h3"},{"title":"Example Configuration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#example-configuration","content":" Here's an annotated example based on the actual plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: aws-agent.log !include ../shared_config.yaml apps: - name: aws-agent-app app_base_path: . app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} supports_streaming: true agent_name: "AwsAgent" display_name: "AwsAgent Component" model: *general_model instruction: | You're AwsAgent responsible for handling user queries by interacting with Amazon Bedrock agents or flows. # AWS Connection Configuration amazon_bedrock_runtime_config: &amazon_bedrock_runtime_config endpoint_url: # Optional: Custom AWS endpoint URL boto3_config: region_name: "us-east-1" # AWS region where your Bedrock resources are located aws_access_key_id: # Your AWS access key (or use profiles/env vars) aws_secret_access_key: # Your AWS secret key tools: # Bedrock Agent Tool - tool_type: python component_module: sam_bedrock_agent.bedrock_agent component_base_path: . function_name: invoke_bedrock_agent tool_name: "text_transformer" # Customizable, Name exposed to the LLM tool_description: "Transforms text using the Text Transformer agent which summarizes the given text and extracts key points." # Customizable, Optional description tool_config: amazon_bedrock_runtime_config: *amazon_bedrock_runtime_config bedrock_agent_id: "XXXXXXXXXX" # Your actual Bedrock agent ID bedrock_agent_alias_id: "XXXXXXXXXX" # Your actual Bedrock agent alias ID allow_files: true # Whether to allow file uploads (5 files, 10MB total max) # Bedrock Flow Tool - tool_type: python component_module: sam_bedrock_agent.bedrock_flow component_base_path: . function_name: invoke_bedrock_flow tool_name: "poem_writer" # Name exposed to the LLM tool_config: amazon_bedrock_runtime_config: *amazon_bedrock_runtime_config bedrock_flow_id: "XXXXXXXXXX" # Your actual Bedrock flow ID bedrock_flow_alias_id: "XXXXXXXXXX" # Your actual Bedrock flow alias ID # Agent capabilities agent_card: description: "Agent that integrates with Amazon Bedrock agents and flows for various AI tasks." defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "text_transformer" name: "Text Transformer" description: "Transforms text using the Text Transformer agent." - id: "poem_writer" name: "Poem Writer" description: "Generates poems based on user input." # A2A Protocol settings agent_card_publishing: { interval_seconds: 10 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 30 ","version":"Next","tagName":"h3"},{"title":"Customizing Your Configuration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#customizing-your-configuration","content":" Follow these steps to customize your configuration: Configure AWS Connection: Set the region_name to the AWS region where your Bedrock resources are locatedChoose one of these authentication methods: Set aws_access_key_id and aws_secret_access_key directly in the config.Use AWS profiles by removing these fields and configuring your AWS CLI profile.Use environment variables (see Environment Variables section below). Check the boto3 documentation for more details. Configure Bedrock Agent Tools: For each Bedrock agent you want to expose, add a tool entry: Set a descriptive tool_name (for example, text_summarizer, content_generator).Provide a clear tool_description of what the agent does.Replace bedrock_agent_id with your actual Bedrock agent ID.Replace bedrock_agent_alias_id with your actual Bedrock agent alias ID.Set allow_files to true if your agent can process file uploads. Configure Bedrock Flow Tools: For each Bedrock flow you want to expose, add a tool entry: Set a descriptive tool_name for the flow.Provide a clear tool_description of what the flow does (optional).Replace bedrock_flow_id with your actual Bedrock flow ID.Replace bedrock_flow_alias_id with your actual Bedrock flow alias ID. Update Agent Card Skills: Update the agent_card.description to reflect the purpose of your Bedrock agent (This is what other agents see).For each tool you add, create a corresponding skill entry in the agent_card.skills section.Use the same id as the tool_name.Provide a user-friendly name and description. Update Agent Instructions: Modify the instruction field to provide clear guidance on how the agent should respond to user queries.This instruction is used by the Agent's LLM to understand its role and capabilities. info You must provide at least one Bedrock agent or flow tool. You can mix and match agents and flows in the same configuration. ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#environment-variables","content":" The Bedrock agent integration requires standard Solace connection variables and can use AWS environment variables for authentication. Required Solace Variables:​ SOLACE_BROKER_URL: URL of your Solace brokerSOLACE_BROKER_USERNAME: Username for Solace broker authenticationSOLACE_BROKER_PASSWORD: Password for Solace broker authenticationSOLACE_BROKER_VPN: Solace message VPN nameSOLACE_AGENT_MESH_NAMESPACE: Namespace for your Solace Agent Mesh project Optional AWS Variables:​ If you prefer to use environment variables for AWS authentication instead of configuration in the YAML file: AWS_ACCESS_KEY_ID: Your AWS access keyAWS_SECRET_ACCESS_KEY: Your AWS secret keyAWS_SESSION_TOKEN: If using temporary credentialsAWS_REGION or AWS_DEFAULT_REGION: AWS region for Bedrock services AWS Credentials Precedence AWS credentials are loaded in this order: Explicit credentials in the YAML configurationEnvironment variablesAWS configuration files (~/.aws/credentials)EC2/ECS instance profiles (if running on AWS) ","version":"Next","tagName":"h3"},{"title":"Running and Testing Your Integration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#running-and-testing-your-integration","content":" ","version":"Next","tagName":"h2"},{"title":"Starting Your Solace Agent Mesh Project​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#starting-your-solace-agent-mesh-project","content":" After configuring your Bedrock agent integration, run your Solace Agent Mesh project: sam run configs/agents/aws-agent.yaml This command starts the Bedrock agent with your specific configuration. ","version":"Next","tagName":"h3"},{"title":"Testing the Integration​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#testing-the-integration","content":" You can test your Bedrock agent integration through any gateway in your Solace Agent Mesh project: Using the Web UI Gateway​ Ensure you have a Web UI gateway running (typically at http://localhost:8000)Start a conversation with your agentAsk a question that would trigger your Bedrock agent or flow Example: If you configured a Bedrock agent for text transformation: Transform this text: "The quick brown fox jumps over the lazy dog. The lazy dog did not chase the fox. The fox was brown and quick, while the dog was lazy and slow. Despite their differences, they both enjoyed the sunny day in the meadow." Example: If you configured a Bedrock flow for poem writing: Write a poem about a sunset over the ocean. Testing with File Uploads​ If you have enabled file uploads for your Bedrock agent (allow_files: true), you can test file processing: In the Web UI, use the file upload button to attach a supported fileInclude a prompt that references the file, such as "Analyze this document" or "Summarize the content of this file"The file is sent to the Bedrock agent along with your prompt Example with file upload: Please analyze the attached document and provide key insights. Supported File Types Bedrock agents support these file types for uploads: PDF documents (.pdf)Text files (.txt)Word documents (.doc, .docx)CSV files (.csv)Excel spreadsheets (.xls, .xlsx) There's a limit of 5 files with a total size of 10MB per request. ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues and Solutions​","type":1,"pageTitle":"Amazon Bedrock Agents Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/bedrock-agents#common-issues-and-solutions","content":" Authentication Errors​ Issue: "Unable to locate credentials" or "Access denied" errorsSolution: Verify your AWS credentials are correctly configuredCheck that your IAM user/role has the necessary permissionsTry using AWS CLI to test your credentials: aws bedrock list-foundation-models Configuration Errors​ Issue: "Invalid agent ID" or "Invalid flow ID" errorsSolution: Double-check your Bedrock agent and flow IDs in the configurationEnsure you've created aliases for your agents and flowsVerify the region in your configuration matches where your Bedrock resources are located Connection Issues​ Issue: Solace Agent Mesh can't connect to Bedrock servicesSolution: Check your network connectivityVerify that Bedrock services are available in your configured regionCheck for any VPC or firewall restrictions File Upload Issues​ Issue: Files aren't being processed by the Bedrock agentSolution: Verify allow_files is set to true in your configurationCheck that your file type is supportedEnsure the file size is under the 10MB limitCheck the model context length ","version":"Next","tagName":"h3"},{"title":"A2A Technical Migration Map","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map","content":"","keywords":"","version":"Next"},{"title":"1. Core Concept Changes​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#1-core-concept-changes","content":" Session vs. Context: The concept of a session, previously Task.sessionId, is now attached to the Message via Message.contextId. The Task also has a contextId, but it's primarily for grouping. Code that relied on Task.sessionId for conversation history must now use Message.contextId.Request/Response Structure: The structure of JSON-RPC requests and responses is now strictly defined by the SDK's Pydantic models (e.g., SendMessageRequest, JSONRPCResponse as a discriminated union). Direct dictionary manipulation is replaced by model instantiation and validation.Status Signaling: The practice of embedding custom status signals (e.g., tool_invocation_start) in the metadata field of a message is deprecated. The new standard is to use a dedicated, structured DataPart within a multi-part Message. ","version":"Next","tagName":"h2"},{"title":"2. Import & Type Mapping​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#2-import--type-mapping","content":" ","version":"Next","tagName":"h2"},{"title":"Import Paths​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#import-paths","content":" Old Import Path\tNew Import Path(s)\tNotessolace_agent_mesh.common.types\ta2a.types, solace_agent_mesh.common.a2a, solace_agent_mesh.common.a2a.types\tLegacy types are removed. Use SDK types and the a2a helper layer. solace_agent_mesh.common.a2a_protocol\tsolace_agent_mesh.common.a2a\tProtocol helpers (topic builders, etc.) are now in the main a2a helper package. ","version":"Next","tagName":"h3"},{"title":"Type Hints​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#type-hints","content":" Old Type Hint\tNew Type Hint\tNotesA2APart\tContentPart\tContentPart is an alias for Union[TextPart, DataPart, FilePart]. List[A2APart]\tList[ContentPart]\tStandard type hint for a list of message parts. FileContent\tUnion[FileWithBytes, FileWithUri]\tThe file attribute of a FilePart is now a discriminated union. ","version":"Next","tagName":"h3"},{"title":"3. Object Creation & Property Access Mapping​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#3-object-creation--property-access-mapping","content":" This table maps common legacy patterns to their new equivalents using the a2a helper layer. Action\tOld Pattern (Legacy)\tNew Pattern (a2a-sdk + Helpers)Part Creation Create Text Part\tTextPart(text=...)\ta2a.create_text_part(text=...) Create File Part (URI)\tFilePart(file=FileContent(name=..., uri=...))\ta2a.create_file_part_from_uri(uri=..., name=...) Create File Part (Bytes)\tFilePart(file=FileContent(bytes=...))\ta2a.create_file_part_from_bytes(content_bytes=...) Create Data Part\tDataPart(data=...)\ta2a.create_data_part(data=...) Task/Event Access Get Task ID\ttask.id\ta2a.get_task_id(task) Get Task Status\ttask.status.state\ta2a.get_task_status(task) Get Task Context ID\ttask.sessionId\ta2a.get_task_context_id(task) Get Event's Task ID\tevent.id\tevent.task_id Message Access Get Message Parts\tmessage.parts\ta2a.get_parts_from_message(message) Get Text from Message\t(manual loop over parts)\ta2a.get_text_from_message(message) Get Data Parts\t(manual loop over parts)\ta2a.get_data_parts_from_message(message) Error Access Get Error Message\terror.message\ta2a.get_error_message(error) Get Error Code\terror.code\ta2a.get_error_code(error) Get Error Data\terror.data\ta2a.get_error_data(error) Protocol/RPC Create RPC Success\tJSONRPCResponse(id=..., result=...)\ta2a.create_success_response(result=..., request_id=...) Create RPC Error\tJSONRPCResponse(id=..., error=...)\ta2a.create_error_response(error=..., request_id=...) Validate RPC Payload\tJSONRPCResponse(**payload)\tJSONRPCResponse.model_validate(payload) Topic Matching\t_topic_matches_subscription(...)\ta2a.topic_matches_subscription(...) Extract Task ID from Topic\t_extract_task_id_from_topic(...)\ta2a.extract_task_id_from_topic(...) ","version":"Next","tagName":"h2"},{"title":"4. Full Method Examples​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#4-full-method-examples","content":" These examples provide larger, "before and after" contexts for the refactoring patterns. ","version":"Next","tagName":"h2"},{"title":"Example 1: _translate_external_input​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-1-_translate_external_input","content":" Before: from solace_agent_mesh.common.types import Part as A2APart, TextPart, FilePart, FileContent async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[A2APart], Dict[str, Any]]: # ... a2a_parts: List[A2APart] = [] # ... artifact_uri = f"artifact://{self.gateway_id}/{user_id}/{a2a_session_id}/{filename}?version={version}" file_content_a2a = FileContent(name=filename, mimeType=mime_type, uri=artifact_uri) a2a_parts.append(FilePart(file=file_content_a2a)) # ... a2a_parts.append(TextPart(text=processed_text_for_a2a)) return "agent_name", a2a_parts, {} After: from solace_agent_mesh.common import a2a from solace_agent_mesh.common.a2a import ContentPart async def _translate_external_input(self, external_event: Any) -> Tuple[str, List[ContentPart], Dict[str, Any]]: # ... a2a_parts: List[ContentPart] = [] # ... artifact_uri = f"artifact://{self.gateway_id}/{user_id}/{a2a_session_id}/{filename}?version={version}" file_part = a2a.create_file_part_from_uri(uri=artifact_uri, name=filename, mime_type=mime_type) a2a_parts.append(file_part) # ... text_part = a2a.create_text_part(text=processed_text_for_a2a) a2a_parts.append(text_part) return "agent_name", a2a_parts, {} ","version":"Next","tagName":"h3"},{"title":"Example 2: _send_update_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-2-_send_update_to_external","content":" Before: from solace_agent_mesh.common.types import TaskStatusUpdateEvent, TextPart, DataPart async def _send_update_to_external(self, context: Dict, event_data: TaskStatusUpdateEvent, is_final: bool) -> None: task_id = event_data.id # ... if event_data.status and event_data.status.message and event_data.status.message.parts: for part in event_data.status.message.parts: if isinstance(part, TextPart): # process part.text elif isinstance(part, DataPart): # process part.data After: from a2a.types import TaskStatusUpdateEvent, TextPart, DataPart from solace_agent_mesh.common import a2a async def _send_update_to_external(self, context: Dict, event_data: TaskStatusUpdateEvent, is_final: bool) -> None: task_id = event_data.task_id # ... message = a2a.get_message_from_status_update(event_data) if message: parts = a2a.get_parts_from_message(message) for part in parts: if isinstance(part, TextPart): # process part.text elif isinstance(part, DataPart): # process part.data ","version":"Next","tagName":"h3"},{"title":"Example 3: _send_final_response_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-3-_send_final_response_to_external","content":" Before: from solace_agent_mesh.common.types import Task, TaskState async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = task_data.id if task_data.status.state == TaskState.FAILED: # ... After: from a2a.types import Task, TaskState from solace_agent_mesh.common import a2a async def _send_final_response_to_external(self, context: Dict, task_data: Task) -> None: task_id = a2a.get_task_id(task_data) task_status = a2a.get_task_status(task_data) if task_status == TaskState.failed: # ... ","version":"Next","tagName":"h3"},{"title":"Example 4: _send_error_to_external​","type":1,"pageTitle":"A2A Technical Migration Map","url":"/solace-agent-mesh/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map#example-4-_send_error_to_external","content":" Before: from solace_agent_mesh.common.types import JSONRPCError async def _send_error_to_external(self, context: Dict, error_data: JSONRPCError) -> None: error_text = f"Error: {error_data.message} (Code: {error_data.code})" if error_data.data: # process error_data.data After: from a2a.types import JSONRPCError from solace_agent_mesh.common import a2a async def _send_error_to_external(self, context: Dict, error_data: JSONRPCError) -> None: error_message = a2a.get_error_message(error_data) error_code = a2a.get_error_code(error_data) error_details = a2a.get_error_data(error_data) error_text = f"Error: {error_message} (Code: {error_code})" if error_details: # process error_details ","version":"Next","tagName":"h3"},{"title":"MCP Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration","content":"","keywords":"","version":"Next"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#setting-up-the-environment","content":" You must install Solace Agent Mesh and Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. For this tutorial using the filesystem MCP server, you also need Node.js and NPM installed. ","version":"Next","tagName":"h2"},{"title":"Adding MCP Tools to an Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#adding-mcp-tools-to-an-agent","content":" MCP integration is accomplished by adding MCP tools directly to your agent configuration. There are three main connection types supported: ","version":"Next","tagName":"h2"},{"title":"1. Stdio Connection (Local MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#1-stdio-connection-local-mcp-servers","content":" This is the most common method for connecting to MCP servers that run as local processes: tools: - tool_type: mcp connection_params: type: stdio command: "npx" args: - "-y" - "@modelcontextprotocol/server-filesystem" - "/tmp/samv2" ","version":"Next","tagName":"h3"},{"title":"2. SSE Connection (Remote MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#2-sse-connection-remote-mcp-servers","content":" For connecting to remote MCP servers using Server-Sent Events: tools: - tool_type: mcp connection_params: type: sse url: "https://mcp.example.com/v1/sse" headers: Authorization: "Bearer ${MCP_AUTH_TOKEN}" ","version":"Next","tagName":"h3"},{"title":"3. Docker Connection (Containerized MCP Servers)​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#3-docker-connection-containerized-mcp-servers","content":" For running MCP servers in Docker containers: tools: - tool_type: mcp connection_params: type: stdio command: "docker" args: - "run" - "-i" - "--rm" - "-e" - "API_KEY" - "mcp-server-image:latest" environment_variables: API_KEY: ${MY_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Complete Example: Filesystem MCP Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#complete-example-filesystem-mcp-agent","content":" Here is a complete example of an agent that uses the filesystem MCP server: # configs/agents/filesystem_agent.yaml log: stdout_log_level: INFO log_file_level: DEBUG log_file: filesystem_agent.log !include ../shared_config.yaml apps: - name: filesystem_mcp_agent_app app_base_path: . app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} supports_streaming: true agent_name: "FileSystemAgent" display_name: "File System" model: *general_model instruction: | You can interact with the local filesystem using MCP tools. Use the available tools to read, write, and manage files as requested. tools: - tool_type: mcp connection_params: type: stdio command: "npx" args: - "-y" - "@modelcontextprotocol/server-filesystem" - "/tmp/samv2" - tool_type: builtin-group group_name: "artifact_management" session_service: *default_session_service artifact_service: *default_artifact_service # Agent discovery and communication agent_card: description: "An agent that interacts with the local filesystem via MCP." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: [] agent_card_publishing: { interval_seconds: 10 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 30 ","version":"Next","tagName":"h2"},{"title":"Configuration Options​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#configuration-options","content":" ","version":"Next","tagName":"h2"},{"title":"Tool-Specific Configuration​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#tool-specific-configuration","content":" You can limit which tools from an MCP server are available by specifying a specific tool name: tools: - tool_type: mcp tool_name: "read_file" # Only expose the read_file tool connection_params: type: stdio command: "npx" args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/samv2"] ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#environment-variables","content":" Pass environment variables to MCP servers using the environment_variables block: tools: - tool_type: mcp connection_params: type: stdio command: "my-mcp-server" environment_variables: API_KEY: ${MY_API_KEY} DEBUG_MODE: "true" CONFIG_PATH: "/etc/myconfig" ","version":"Next","tagName":"h3"},{"title":"Running Your MCP-Enabled Agent​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#running-your-mcp-enabled-agent","content":" Create the working directory (for filesystem example): mkdir -p /tmp/samv2 echo "Hello MCP!" > /tmp/samv2/test.txt Set required environment variables: export NAMESPACE="myorg/dev" export SOLACE_BROKER_URL="ws://localhost:8080" # ... other Solace broker settings Run the agent: sam run configs/agents/filesystem_agent.yaml ","version":"Next","tagName":"h2"},{"title":"How MCP Integration Works​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#how-mcp-integration-works","content":" When your agent starts: Connection: The framework establishes a connection to the MCP server using the specified connection parametersDiscovery: It queries the MCP server for available tools, resources, and promptsRegistration: Available capabilities are registered as agent tools.Communication: The agent can use these tools through the standard A2A protocol, with the framework handling MCP protocol translation ","version":"Next","tagName":"h2"},{"title":"Testing Your MCP Integration​","type":1,"pageTitle":"MCP Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mcp-integration#testing-your-mcp-integration","content":" Once your MCP-enabled agent is running, you can test it through any gateway in your project (such as the Web UI gateway): Access your gateway (for example, Web UI at http://localhost:8000)Send a request to test the MCP functionality: "List the files in the directory""Create a simple text file with some content""Read the contents of test.txt" The agent uses the MCP tools to interact with the filesystem and provide responses through the A2A protocol. ","version":"Next","tagName":"h2"},{"title":"REST Gateway","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway","content":"","keywords":"","version":"Next"},{"title":"Key Features​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#key-features","content":" Dual API Versions: Supports both a modern asynchronous API (v2) and a deprecated synchronous API (v1) for backward compatibility.Asynchronous by Default: The v2 API uses a "202 Accepted + Poll" pattern, ideal for long-running agent tasks.Delegated Authentication: Integrates with an external authentication service via bearer tokens for secure access.File Handling: Supports file uploads for tasks and provides download URLs for generated artifacts.Dynamic Configuration: All gateway behaviors, including server settings and authentication, are configured via the main Solace Agent Mesh Host YAML file. ","version":"Next","tagName":"h2"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and the Solace Agent Mesh CLI, and then create a new Solace Agent Mesh project. ","version":"Next","tagName":"h2"},{"title":"Adding the REST Gateway Plugin​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#adding-the-rest-gateway-plugin","content":" Once you have your project set up, add the REST Gateway plugin: sam plugin add my-http-rest --plugin sam-rest-gateway You can use any name for your agent, in this tutorial we use my-http-rest. This command: Installs the sam-rest-gateway pluginCreates a new gateway configuration named my-http-rest in your configs/gateways/ directory ","version":"Next","tagName":"h2"},{"title":"Configuring the REST Gateway​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#configuring-the-rest-gateway","content":" For further configuration, you can edit the configs/gateways/my-http-rest.yaml file. This file contains the gateway configuration that can be customized for your use case. Using local Solace PubSub+ Broker container Solace PubSub+ Broker container uses port 8080. You need to edit the rest_api_server_port field and external_auth_service_url field in the configs/gateways/my-http-rest.yaml file to a free port other than 8080 (for example: 8081). You can edit the YAML file directly or add environment variables REST_API_PORT=8081 and EXTERNAL_AUTH_SERVICE_URL=http://localhost:8081. Make sure you change the REST API gateway to your new port in the following request examples. ","version":"Next","tagName":"h3"},{"title":"Running the REST Gateway​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#running-the-rest-gateway","content":" To run the REST Gateway, use the following command: sam run configs/gateways/my-http-rest.yaml ","version":"Next","tagName":"h2"},{"title":"Sending a Request via REST API​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#sending-a-request-via-rest-api","content":" You can also interact with Solace Agent Mesh via the REST API. The REST API gateway runs on http://localhost:8080 by default. You can use either the legacy v1 API or the modern async v2 API. ","version":"Next","tagName":"h2"},{"title":"Modern API (v2) - Asynchronous​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#modern-api-v2---asynchronous","content":" # Submit task curl --location 'http://localhost:8080/api/v2/tasks' \\ --header 'Authorization: Bearer token' \\ --form 'agent_name="OrchestratorAgent"' \\ --form 'prompt="Hi\\!"' # Poll for result using returned task ID curl --location 'http://localhost:8080/api/v2/tasks/{taskId}' \\ --header 'Authorization: Bearer token' warning It might take a while for the system to respond. See the observability page for more information about monitoring the system while it processes the request. Sample output: From api/v2/tasks { "taskId":"task-6a0e682f4f6c4927a5997e4fd06eea83" } From api/v2/tasks/{taskId} { "id": "task-6a0e682f4f6c4927a5997e4fd06eea83", "sessionId": "rest-session-4df0c24fcecc45fcb69692db9876bc5c", "status": { "state": "completed", "message": { "role": "agent", "parts": [{ "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today's Perfect Activities (13°C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." }] }, "timestamp": "2025-07-03T16:54:15.273085" }, "artifacts": [], "metadata": { "agent_name": "OrchestratorAgent" } } ","version":"Next","tagName":"h3"},{"title":"Legacy API (v1) - Synchronous​","type":1,"pageTitle":"REST Gateway","url":"/solace-agent-mesh/docs/documentation/tutorials/rest-gateway#legacy-api-v1---synchronous","content":" curl --location 'http://localhost:8080/api/v1/invoke' \\ --header 'Authorization: Bearer None' \\ --form 'prompt="Suggest some good outdoor activities in London given the season and current weather conditions."' \\ --form 'agent_name="OrchestratorAgent"' \\ --form 'stream="false"' Sample output: { "id": "task-9f7d5f465f5a4f1ca799e8e5ecb35a43", "sessionId": "rest-session-36b36eeb69b04da7b67708f90e5512dc", "status": { "state": "completed", "message": { "role": "agent", "parts": [ { "type": "text", "text": "Outdoor Activities in London: Spring Edition. Today's Perfect Activities (13°C, Light Cloud): - Royal Parks Exploration : Hyde Park and Kensington Gardens..." } ] }, "timestamp": "2025-07-03T16:59:37.486480" }, "artifacts": [], "metadata": { "agent_name": "OrchestratorAgent" } } ","version":"Next","tagName":"h3"},{"title":"MongoDB Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration","content":"","keywords":"","version":"Next"},{"title":"Prerequisites​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#prerequisites","content":" Before starting this tutorial, ensure that you have installed and configured Solace Agent Mesh: Installed Solace Agent Mesh and the Solace Agent Mesh CLICreated a new Solace Agent Mesh projectAccess to a MongoDB database (local or remote) ","version":"Next","tagName":"h2"},{"title":"Adding the MongoDB Plugin​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#adding-the-mongodb-plugin","content":" Add the MongoDB plugin to your Solace Agent Mesh project: sam plugin add coffee-shop-mongo --plugin sam-mongodb You can use any name for your agent, in this tutorial we use coffee-shop-mongo. This command: Installs the sam-mongodb pluginCreates a new agent configuration file at configs/agents/coffee-shop-mongo.yaml Setting Up Your MongoDB Database​ This tutorial assumes you have a MongoDB database with a collection containing coffee shop data. You can use any MongoDB database, but here is an example structure for a coffee shop: Example Document Structure​ { "_id": "64a1b2c3d4e5f6789012345", "order_id": "ORD-2024-001", "customer": { "name": "John Doe", "email": "john.doe@example.com", "phone": "+1-555-0123" }, "items": [ { "product": "Espresso", "quantity": 2, "price": 3.50, "category": "Coffee" }, { "product": "Croissant", "quantity": 1, "price": 2.75, "category": "Pastry" } ], "total_amount": 9.75, "order_date": "2024-01-15T10:30:00Z", "status": "completed", "payment_method": "credit_card", "location": "Downtown Store" } ","version":"Next","tagName":"h2"},{"title":"Configuring the Agent​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#configuring-the-agent","content":" Open the configs/agents/coffee-shop-mongo.yaml file and modify the agent_init_function.config section to connect to your MongoDB database. Here is what you need to modify in the configuration file: # Find the agent_init_function section and update the config: agent_init_function: module: "sam_mongodb.lifecycle" name: "initialize_mongo_agent" config: db_host: "${COFFEE_SHOP_MONGO_MONGO_HOST}" db_port: ${COFFEE_SHOP_MONGO_MONGO_PORT} db_user: "${COFFEE_SHOP_MONGO_MONGO_USER}" db_password: "${COFFEE_SHOP_MONGO_MONGO_PASSWORD}" db_name: "${COFFEE_SHOP_MONGO_MONGO_DB}" database_collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" database_purpose: "${COFFEE_SHOP_MONGO_DB_PURPOSE}" data_description: "${COFFEE_SHOP_MONGO_DB_DESCRIPTION}" auto_detect_schema: true max_inline_results: 10 Setting the Environment Variables​ The MongoDB agent requires several environment variables. Create or update your .env file with the following variables: # MongoDB Connection Settings COFFEE_SHOP_MONGO_MONGO_HOST=localhost COFFEE_SHOP_MONGO_MONGO_PORT=27017 COFFEE_SHOP_MONGO_MONGO_USER=your_username COFFEE_SHOP_MONGO_MONGO_PASSWORD=your_password COFFEE_SHOP_MONGO_MONGO_DB=coffee_shop COFFEE_SHOP_MONGO_MONGO_COLLECTION=orders # Database Description COFFEE_SHOP_MONGO_DB_PURPOSE="Coffee shop order management database" COFFEE_SHOP_MONGO_DB_DESCRIPTION="Contains customer orders, product information, sales data, and transaction history for a coffee shop business." # Optional Settings AUTO_DETECT_SCHEMA=true MAX_INLINE_RESULTS=10 MongoDB Connection Options​ Local MongoDB: Use localhost as the host and default port 27017MongoDB Atlas: Use your Atlas connection string formatAuthentication: Provide username and password if your MongoDB requires authenticationNo Authentication: Leave username and password empty for local development databases ","version":"Next","tagName":"h2"},{"title":"Running the Agent​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#running-the-agent","content":" Now you can start your MongoDB agent: sam run configs/agents/coffee-shop-mongo.yaml The agent: Connects to the A2A control planeInitializes the MongoDB connectionDetects the database schema automaticallyRegisters its capabilities with the agent discovery system ","version":"Next","tagName":"h2"},{"title":"Interacting with the Database​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#interacting-with-the-database","content":" After your MongoDB agent is running, you can interact with the database through any gateway in your Solace Agent Mesh project (such as the Web UI gateway at http://localhost:8000). You can ask natural language questions about your MongoDB database, such as: "How many orders were placed today?""What are the most popular coffee products?""Show me all orders from customers in New York""What's the average order value this month?""Find all incomplete orders""Group orders by payment method and show totals" Try creating reports by asking questions such as: "Create a sales report for the last 7 days""Generate a summary of customer preferences""Show me the top 10 customers by total spending" The MongoDB agent converts your natural language questions into MongoDB aggregation pipelines, executes them against the database, and returns the results. For large result sets, the agent automatically saves the results as artifacts that you can download. ","version":"Next","tagName":"h2"},{"title":"Advanced Configuration​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#advanced-configuration","content":" The MongoDB plugin supports many advanced configuration options. Here is a complete example based on the plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: coffee-shop-mongo.log !include ../shared_config.yaml apps: - name: coffee-shop-mongo-app app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} agent_name: "CoffeeShopMongo" display_name: "Coffee Shop MongoDB Agent" supports_streaming: false model: *general_model instruction: | You are an expert MongoDB assistant for the coffee shop database. Your primary goal is to translate user questions into accurate MongoDB aggregation pipelines. When asked to query the database, generate the pipeline and call the query tool. If the tool returns an error, analyze the error message and the original pipeline, then try to correct the pipeline and call the tool again. Always provide clear explanations of the results you find. # Agent initialization with database setup agent_init_function: module: "sam_mongodb.lifecycle" name: "initialize_mongo_agent" config: db_host: "${COFFEE_SHOP_MONGO_MONGO_HOST}" db_port: ${COFFEE_SHOP_MONGO_MONGO_PORT} db_user: "${COFFEE_SHOP_MONGO_MONGO_USER}" db_password: "${COFFEE_SHOP_MONGO_MONGO_PASSWORD}" db_name: "${COFFEE_SHOP_MONGO_MONGO_DB}" database_collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" database_purpose: "${COFFEE_SHOP_MONGO_DB_PURPOSE}" data_description: "${COFFEE_SHOP_MONGO_DB_DESCRIPTION}" auto_detect_schema: true max_inline_results: 10 agent_cleanup_function: module: "sam_mongodb.lifecycle" name: "cleanup_mongo_agent_resources" # MongoDB query tool tools: - tool_type: builtin-group group_name: "artifact_management" - tool_type: builtin-group group_name: "data_analysis" - tool_type: python component_module: "sam_mongodb.search_query" function_name: "mongo_query" tool_config: collection: "${COFFEE_SHOP_MONGO_MONGO_COLLECTION}" session_service: *default_session_service artifact_service: *default_artifact_service # Artifact handling artifact_handling_mode: "reference" enable_embed_resolution: true enable_artifact_content_instruction: true # Agent capabilities - This is what other agents see during discovery agent_card: description: "Coffee Shop MongoDB Agent - Access to comprehensive coffee shop order data including customer information, product details, sales transactions, and order history. Can answer questions about sales analytics, customer behavior, product performance, and business metrics." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "mongo_query" name: "Coffee Shop MongoDB Query" description: "Queries coffee shop MongoDB database containing customer orders, product catalog, payment transactions, and order history using aggregation pipelines." # A2A Protocol settings agent_card_publishing: { interval_seconds: 30 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 60 ","version":"Next","tagName":"h2"},{"title":"Customizing the Agent Card​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#customizing-the-agent-card","content":" The agent_card section is crucial as it defines how other agents in your Solace Agent Mesh ecosystem discover and understand this MongoDB agent's capabilities. When other agents use agent discovery, they can see this information to decide whether to delegate tasks to your database agent. ","version":"Next","tagName":"h2"},{"title":"Key Agent Card Elements​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#key-agent-card-elements","content":" Description: Clearly describe what data the agent has access to and what types of questions it can answerSkills: List specific capabilities with concrete examples that show the scope of data availableData Context: Mention the business domain, data types, and scope of information available ","version":"Next","tagName":"h3"},{"title":"Example of a Well-Configured Agent Card​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#example-of-a-well-configured-agent-card","content":" agent_card: description: "Coffee Shop MongoDB Agent - Access to comprehensive coffee shop order data including customer information, product details, sales transactions, and order history. Can answer questions about sales analytics, customer behavior, product performance, and business metrics." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "mongo_query" name: "Coffee Shop MongoDB Query" description: "Queries coffee shop MongoDB database containing customer orders, product catalog, payment transactions, and order history using aggregation pipelines." This detailed information helps other agents understand: What business domain this agent covers (coffee shop operations)What types of data are available (orders, customers, products, payments)What kinds of questions can be answered (analytics, behavior, performance, metrics)Specific examples of queries that work well with MongoDB aggregation pipelines When configuring your own MongoDB agent, customize the description and examples to match your specific data structure and use cases. ","version":"Next","tagName":"h3"},{"title":"MongoDB Query Features​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#mongodb-query-features","content":" The MongoDB agent supports various types of queries through natural language: ","version":"Next","tagName":"h2"},{"title":"Aggregation Queries​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#aggregation-queries","content":" "Show me the top 5 products by sales volume""Calculate the average order value by customer segment""Group orders by month and show revenue trends" ","version":"Next","tagName":"h3"},{"title":"Filtering and Search​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#filtering-and-search","content":" "Find all orders placed in the last 24 hours""Show me orders with a total amount greater than $50""Find customers who ordered espresso drinks" ","version":"Next","tagName":"h3"},{"title":"Complex Analytics​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#complex-analytics","content":" "What's the conversion rate from browsing to purchase?""Show me the busiest hours of the day""Calculate customer lifetime value" ","version":"Next","tagName":"h3"},{"title":"Output Formats​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#output-formats","content":" The agent supports multiple output formats: JSON: Default format, good for structured dataYAML: Human-readable formatCSV: Suitable for spreadsheet importMarkdown: Formatted for documentation You can specify the format in your query: "Show me today's sales in CSV format" ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues and Solutions​","type":1,"pageTitle":"MongoDB Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/mongodb-integration#common-issues-and-solutions","content":" Connection Errors​ Issue: "Unable to connect to MongoDB" errorsSolution: Verify your MongoDB server is runningCheck connection parameters (host, port, credentials)Ensure network connectivity and firewall settingsTest connection using MongoDB client tools Authentication Errors​ Issue: "Authentication failed" errorsSolution: Verify username and password are correctCheck that the user has appropriate database permissionsEnsure the authentication database is correct Query Errors​ Issue: "Invalid aggregation pipeline" errorsSolution: The agent automatically retries with corrected pipelinesCheck that your natural language query is clear and specificVerify that referenced fields exist in your collection Schema Detection Issues​ Issue: Agent does not understand your data structureSolution: Ensure auto_detect_schema is set to trueProvide detailed data_description in your configurationCheck that your collection has representative sample documents ","version":"Next","tagName":"h3"},{"title":"RAG Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration","content":"","keywords":"","version":"Next"},{"title":"What is Solace Agent Mesh RAG?​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#what-is-solace-agent-mesh-rag","content":" The Solace Agent Mesh RAG plugin enhances your agents with the ability to perform retrieval-augmented generation. This means the agent can: Scan documents from various sources (local filesystem, Google Drive, etc.).Preprocess and split the text into manageable chunks.Embed these chunks into vectors and store them in a vector database.Retrieve relevant chunks of text based on a user's query.Generate an answer using a large language model (LLM) augmented with the retrieved information. This allows you to build agents that can answer questions about your own private data. ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#prerequisites","content":" Before you begin, ensure you have: Installed Solace Agent Mesh and the Solace Agent Mesh CLI.Created a new Solace Agent Mesh project.Access to a vector database (for example, Qdrant, Chroma, and Pinecone).Access to an LLM for generation and an embedding model.A directory with some documents for the agent to ingest. ","version":"Next","tagName":"h2"},{"title":"Adding the RAG Plugin​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#adding-the-rag-plugin","content":" To add the RAG plugin to your Solace Agent Mesh project, run the following command: sam plugin add my-rag-agent --plugin sam-rag Replace my-rag-agent with your preferred agent name. This command: Installs the sam-rag plugin.Creates a new agent configuration file at configs/agents/my-rag-agent.yaml. ","version":"Next","tagName":"h2"},{"title":"Configuring the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#configuring-the-rag-agent","content":" The RAG agent requires a detailed configuration. Open configs/agents/my-rag-agent.yaml to configure the following sections: ","version":"Next","tagName":"h2"},{"title":"Shared Configuration​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#shared-configuration","content":" Like other agents, the RAG agent needs a connection to the Solace broker and a configured LLM. This is typically done in a shared_config.yaml file. # configs/shared_config.yaml shared_config: - broker_connection: &broker_connection dev_mode: ${SOLACE_DEV_MODE, false} broker_url: ${SOLACE_BROKER_URL, ws://localhost:8080} broker_username: ${SOLACE_BROKER_USERNAME, default} broker_password: ${SOLACE_BROKER_PASSWORD, default} broker_vpn: ${SOLACE_BROKER_VPN, default} temporary_queue: ${USE_TEMPORARY_QUEUES, true} - models: general: &general_model model: ${LLM_SERVICE_GENERAL_MODEL_NAME} api_base: ${LLM_SERVICE_ENDPOINT} api_key: ${LLM_SERVICE_API_KEY} ","version":"Next","tagName":"h3"},{"title":"RAG Pipeline Configuration​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#rag-pipeline-configuration","content":" The RAG pipeline has several stages, each with its own configuration block within the app_config section of your my-rag-agent.yaml file. 1. Scanner Configuration​ The scanner discovers documents to be ingested. You can configure it to scan a local filesystem or cloud sources. Local Filesystem Example: scanner: batch: true use_memory_storage: true source: type: filesystem directories: - "/path/to/your/documents" # Important: Replace with your actual document directory path filters: file_formats: - ".txt" - ".pdf" - ".md" Multi-Cloud Source Example:You can also configure multiple sources, including Google Drive, OneDrive, and S3. scanner: batch: true use_memory_storage: true sources: - type: filesystem directories: ["${LOCAL_DOCUMENTS_PATH}"] - type: google_drive credentials_path: "${GOOGLE_DRIVE_CREDENTIALS_PATH}" folders: - folder_id: "${GOOGLE_DRIVE_FOLDER_ID_1}" name: "Documents" recursive: true 2. Preprocessor Configuration​ The preprocessor cleans the text extracted from documents. preprocessor: default_preprocessor: type: enhanced params: lowercase: true normalize_whitespace: true remove_urls: true preprocessors: pdf: type: document params: lowercase: true normalize_whitespace: true remove_non_ascii: true remove_urls: true 3. Splitter Configuration​ The splitter breaks down large documents into smaller chunks. Different splitters are available for different file types. splitter: default_splitter: type: recursive_character params: chunk_size: 2048 chunk_overlap: 400 splitters: markdown: type: markdown params: chunk_size: 2048 chunk_overlap: 400 pdf: type: token params: chunk_size: 500 chunk_overlap: 100 4. Embedding Configuration​ This section defines the model used to create vector embeddings from the text chunks. embedding: embedder_type: "openai" embedder_params: model: "${OPENAI_EMBEDDING_MODEL}" api_key: "${OPENAI_API_KEY}" api_base: "${OPENAI_API_ENDPOINT}" normalize_embeddings: true 5. Vector Database Configuration​ Configure the connection to your vector database where the embeddings are stored. Qdrant Example: vector_db: db_type: "qdrant" db_params: url: "${QDRANT_URL}" api_key: "${QDRANT_API_KEY}" collection_name: "${QDRANT_COLLECTION}" embedding_dimension: ${QDRANT_EMBEDDING_DIMENSION} Chroma Example: vector_db: db_type: "chroma" db_params: host: "${CHROMA_HOST}" port: "${CHROMA_PORT}" collection_name: "${CHROMA_COLLECTION}" 6. LLM Configuration​ Configure the LLM that is used to generate answers based on the retrieved context. llm: load_balancer: - model_name: "gpt-4o" litellm_params: model: "openai/${OPENAI_MODEL_NAME}" api_key: "${OPENAI_API_KEY}" api_base: "${OPENAI_API_ENDPOINT}" 7. Retrieval Configuration​ This defines how many document chunks are retrieved to answer a query. retrieval: top_k: 7 ","version":"Next","tagName":"h3"},{"title":"Environment Variables​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#environment-variables","content":" The RAG agent relies heavily on environment variables. Here are some of the most important ones you'll need to set in your .env file: # Solace Connection SOLACE_BROKER_URL=ws://localhost:8080 SOLACE_BROKER_VPN=default SOLACE_BROKER_USERNAME=default SOLACE_BROKER_PASSWORD=default NAMESPACE=my-org/dev # LLM and Embedding Models OPENAI_API_KEY="your-openai-api-key" OPENAI_API_ENDPOINT="your-openai-api-endpoint" OPENAI_MODEL_NAME="model name. E.g., gpt-4o" OPENAI_EMBEDDING_MODEL="embedding model name. E.g., text-embedding-3-small" # Vector Database (Qdrant example) QDRANT_URL="Qdrant url" QDRANT_API_KEY="API key" QDRANT_COLLECTION="my-rag-collection" QDRANT_EMBEDDING_DIMENSION=1536 # Depends on your embedding model # Scanner LOCAL_DOCUMENTS_PATH="./my_documents" # Relative path to your documents folder Create a directory named my_documents in your project root and place some text or markdown files inside it. ","version":"Next","tagName":"h3"},{"title":"Running the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#running-the-rag-agent","content":" Once you have configured your agent and set the environment variables, you can run it: sam run configs/agents/my-rag-agent.yaml 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. ","version":"Next","tagName":"h2"},{"title":"Testing the RAG Agent​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#testing-the-rag-agent","content":" Once your agent is running, you can test its retrieval capabilities and ingest new documents. ","version":"Next","tagName":"h2"},{"title":"Ingesting Documents​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#ingesting-documents","content":" There are two primary ways to ingest documents into your RAG agent's knowledge base: Option 1: Automatic Scanning (Batch Ingestion)​ This method uses the configured scanner component. The agent automatically ingests documents from the directories specified in your configuration upon startup. Step 1: Create a Document First, create a simple text file named sam_features.txt and add some content to it. For example: Solace Agent Mesh is a powerful framework for building AI agents. Key features of Solace Agent Mesh include: - A flexible plugin architecture. - Integration with various LLMs and vector databases. - Scalable gateways for different communication protocols. - An event-driven design based on Solace PubSub+. Step 2: Place the Document in the Scanned Directory In the "Environment Variables" section, we configured LOCAL_DOCUMENTS_PATH to point to a directory (e.g., ./my_documents). Create this directory in your project's root folder if you haven't already, and move your sam_features.txt file into it. mkdir -p my_documents mv sam_features.txt my_documents/ Step 3: Run the Agent to Trigger Ingestion 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: sam run configs/agents/my-rag-agent.yaml 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. Option 2: Manual Upload via Gateway​ 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. Step 1: Start the RAG Agent and Web UI Ensure both your RAG agent and the Web UI gateway are running. Step 2: Upload a Document in the Web UI Open the Web UI (usually at http://localhost:8000, or check your gateway configuration for the correct URL) and start a chat with your RAG agent.Use the file attachment button to select a document from your local machine.Send a prompt along with the file, instructing the agent to ingest it. For example: "Please ingest the attached document into your knowledge base." The RAG agent uses its 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. Step 3: Confirm Ingestion After the agent confirms that the document has been ingested, you can immediately ask questions about its content. ","version":"Next","tagName":"h3"},{"title":"Querying the Knowledge Base​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#querying-the-knowledge-base","content":" You can interact with your RAG agent through any gateway, such as the Web UI gateway. Make sure you have a Web UI gateway running (or add one to your project).Open the Web UI (usually at http://localhost:8000).Start a conversation with my-rag-agent.Ask a question related to the content of the documents you provided during the initial scan. For example, if you have a document about product features, you could ask: "What are the key features of Product X?" The agent searches its knowledge base, finds the relevant information, and generates an answer based on the content of your documents. ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"RAG Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/rag-integration#troubleshooting","content":" Connection Errors: Double-check all your URLs, API keys, and credentials for your LLM and vector database.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.No Answers: If the agent can't answer, it might be because the information is not in the documents, or the top_k retrieval setting is too low. ","version":"Next","tagName":"h2"},{"title":"Slack Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration","content":"","keywords":"","version":"Next"},{"title":"Setting Up the Environment​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#setting-up-the-environment","content":" First, you need to install Solace Agent Mesh and Solace Mesh Agent CLI, and then create a new Solace Agent Mesh project or create a new gateway plugin. ","version":"Next","tagName":"h2"},{"title":"Creating the Slack App​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#creating-the-slack-app","content":" Next, create a Slack Application in your workspace. Go to the Slack Application website.Select Your Apps and click Create New App.Choose From a manifest and apply the following configuration. You can customize the name and description, but keep the rest of the configuration and settings unchanged. display_information: name: solace-agent-mesh-bot description: An app to integrate with Solace Agent Mesh features: app_home: home_tab_enabled: false messages_tab_enabled: true messages_tab_read_only_enabled: false bot_user: display_name: Solace Agent Mesh always_online: false oauth_config: scopes: bot: - app_mentions:read - bookmarks:read - channels:history - channels:join - channels:manage - channels:read - chat:write - chat:write.customize - chat:write.public - files:read - files:write - groups:history - groups:read - groups:write - im:history - im:read - im:write - links:read - links:write - mpim:history - mpim:read - mpim:write - pins:read - pins:write - reactions:read - reactions:write - reminders:read - reminders:write - team:read - usergroups:read - usergroups:write - users.profile:read - users:read.email - users:read - users:write - conversations.connect:read - conversations.connect:write - incoming-webhook settings: event_subscriptions: bot_events: - app_mention - message.groups - message.im interactivity: is_enabled: true org_deploy_enabled: false socket_mode_enabled: true token_rotation_enabled: false Then select Create to create your new App. ","version":"Next","tagName":"h2"},{"title":"App-Level Tokens​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#app-level-tokens","content":" In your created App, select Basic Information under Settings. Scroll down to App-Level Tokens and click Generate Token and Scopes. Provide your token a name, add all available scopes, and then click Generate. Make note of the resulting application token (beginning with xapp-) - you need it in a future step. ","version":"Next","tagName":"h3"},{"title":"Installing the App in Your Slack Workspace​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#installing-the-app-in-your-slack-workspace","content":" Next, select Install App under Settings and follow the installation flow to install the App in your workspace. After installation, the bot token (beginning with xoxb-) is visible. Make note of this token. ","version":"Next","tagName":"h3"},{"title":"Installing the Slack Gateway​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#installing-the-slack-gateway","content":" After configuring your Slack App, the next step is to add the Slack gateway to Solace Agent Mesh. Add the gateway plugin using Solace Agent Mesh CLI: sam plugin add slack-bot --plugin sam-slack You can change slack-bot to any name you prefer for your gateway. Configure the required environment variables: The Slack interface requires two authentication tokens. Add these to your .env file in the project root directory using the tokens generated during Slack App setup: SLACK_BOT_TOKEN=xoxb-xxxxxxxxxx SLACK_APP_TOKEN=xapp-xxxxxxxxxx tip You can further customize the Slack gateway by updating the configs/gateways/slack-bot.yaml file. This file contains the configuration for the Slack gateway, including the initial status message, the gateway system purpose, and response format. ","version":"Next","tagName":"h2"},{"title":"Running the Slack Gateway​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#running-the-slack-gateway","content":" Launch the Slack gateway with: sam run configs/gateways/slack-bot.yaml For detailed information about available Solace Agent Mesh CLI commands, see the Solace Agent Mesh CLI. ","version":"Next","tagName":"h2"},{"title":"Testing the Installation​","type":1,"pageTitle":"Slack Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/slack-integration#testing-the-installation","content":" To test your installation: Open your Slack workspace in the desktop app or browser.Find and click on the Solace Agent Mesh app under the Apps section.Send a test message by typing hello and click Enter.You should see: A "Chatbot is thinking..." status messageA response from the chatbot within a few seconds ","version":"Next","tagName":"h2"},{"title":"Artifact Management Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management","content":"","keywords":"","version":"Next"},{"title":"The Metadata-Aware Workflow​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#the-metadata-aware-workflow","content":" Rather than automatically bundling all created artifacts in the final response, the agent follows a structured workflow: Create & Describe: The agent invokes the create_artifact tool to persist a file. Rich metadata, such as descriptions, sources, and inferred schemas, is stored alongside the artifact.Inject & Inform: This metadata is automatically injected into the conversation history, providing the agent with immediate context regarding the new file.List & Discover: The agent can call list_artifacts at any point to retrieve a summary of all available artifacts and their associated metadata.Load & Analyze: The agent can use load_artifact to read the content of a text-based artifact or inspect the detailed metadata of any artifact (for example, to ascertain the schema of a CSV file).Return on Request: To transmit an artifact to the user or a calling application, the agent must explicitly invoke signal_artifact_for_return. Artifacts are not returned automatically. ","version":"Next","tagName":"h2"},{"title":"Configuration​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#configuration","content":" The file management tools are encapsulated within the artifact_management tool group. ","version":"Next","tagName":"h2"},{"title":"Enabling the Tools​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#enabling-the-tools","content":" Enable the tool group within the agent's app_config.yml: # In your agent's app_config: tools: - tool_type: builtin-group group_name: "artifact_management" ","version":"Next","tagName":"h3"},{"title":"Configuring Artifact Return Behavior​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#configuring-artifact-return-behavior","content":" The artifact_handling_mode setting in your app_config dictates the behavior when signal_artifact_for_return is called: ignore (Default): The request is logged, but no artifact is transmitted.embed: The artifact content is base64-encoded and embedded within the TaskArtifactUpdateEvent payload. This is suitable for smaller files.reference: A URI pointing to the artifact is sent in the event payload. This approach requires a separate service to host the file at the specified URI. # In your agent's app_config: artifact_handling_mode: "reference" ","version":"Next","tagName":"h3"},{"title":"Tool Reference​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#tool-reference","content":" ","version":"Next","tagName":"h2"},{"title":"create_artifact​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#create_artifact","content":" Creates a new file artifact and its corresponding metadata. Parameters: filename (str): The designated name for the artifact (for example, "report.pdf").content (str): The file content. For binary file types (for example, images, PDFs), this content must be base64-encoded.mime_type (str): The standard MIME type of the content (for example, "text/plain", "image/png").metadata (dict, optional): A dictionary containing custom metadata (for example, {"description": "Monthly sales data"}). Returns: A dictionary confirming the successful persistence of the artifact.Key Feature: Upon successful execution of this tool, a summary of the artifact's metadata is automatically injected into the conversation history, informing the agent of the new file's context. ","version":"Next","tagName":"h3"},{"title":"list_artifacts​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#list_artifacts","content":" Lists all available artifacts within the current session. Parameters: None.Returns: A list of file objects, each containing the filename, available versions, and a metadata_summary for the latest version. ","version":"Next","tagName":"h3"},{"title":"load_artifact​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#load_artifact","content":" Loads the content or detailed metadata of a specific version of an artifact. Parameters: filename (str): The name of the artifact to be loaded.version (int): The specific version number of the artifact to load.load_metadata_only (bool, optional): If True, the tool returns the complete, detailed metadata dictionary instead of the artifact's content. This is useful for inspecting schemas or other metadata fields. Returns: If load_metadata_only=False: The artifact's content (for text-based files) or a basic information dictionary (for binary files).If load_metadata_only=True: The complete metadata dictionary for the specified artifact version. ","version":"Next","tagName":"h3"},{"title":"signal_artifact_for_return​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#signal_artifact_for_return","content":" Instructs the system to transmit a specific artifact version to the caller. Parameters: filename (str): The name of the artifact to be returned.version (int): The specific version number of the artifact to return. Returns: A dictionary confirming that the request has been received.Note: This tool functions as a signal. The actual transmission of the artifact is handled by the system in accordance with the configured artifact_handling_mode. ","version":"Next","tagName":"h3"},{"title":"Key Concepts​","type":1,"pageTitle":"Artifact Management Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/artifact-management#key-concepts","content":" Explicit Control: Agents possess full, explicit control over the entire artifact lifecycle.Metadata-Driven Context: The automatic injection and summarization of metadata are fundamental to providing agents with situational awareness.Signaled Return: Artifacts are transmitted to the user only upon an explicit request from the agent via the signal_artifact_for_return tool.Synergy with Embeds: These tools can be used in conjunction with Dynamic Embeds, such as «artifact_meta:report.csv», for more efficient file handling. ","version":"Next","tagName":"h2"},{"title":"Configuring Built-in Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#overview","content":" 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. The Solace Agent Mesh framework manages these tools through a central 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. ","version":"Next","tagName":"h2"},{"title":"Configuration Methods​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#configuration-methods","content":" Tool configuration is managed within the tools list in an agent's app_config block in the corresponding YAML configuration file. ","version":"Next","tagName":"h2"},{"title":"Method 1: Enabling Tool Groups (Recommended)​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#method-1-enabling-tool-groups-recommended","content":" 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. tool_type: builtin-groupgroup_name: The unique identifier for the tool category. Example: # In your agent's app_config: tools: - tool_type: builtin-group group_name: "artifact_management" - tool_type: builtin-group group_name: "data_analysis" ","version":"Next","tagName":"h3"},{"title":"Method 2: Enabling Individual Tools​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#method-2-enabling-individual-tools","content":" For more granular control over an agent's capabilities, specific tools can be enabled individually. tool_type: builtintool_name: The unique, registered name of the tool. Example: # In your agent's app_config: tools: - tool_type: builtin tool_name: "web_request" - tool_type: builtin tool_name: "time_delay" Note 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. ","version":"Next","tagName":"h3"},{"title":"Available Tool Groups and Tools​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#available-tool-groups-and-tools","content":" The following sections detail the available tool groups and the individual tools they contain. ","version":"Next","tagName":"h2"},{"title":"Artifact Management​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#artifact-management","content":" Group Name: artifact_management Description: Tools for creating, loading, and managing file artifacts. Individual Tools: create_artifactappend_to_artifactlist_artifactsload_artifactsignal_artifact_for_returnapply_embed_and_create_artifactextract_content_from_artifact info For a more in-depth guide on using artifact management tools, refer to the Artifact Management documentation. ","version":"Next","tagName":"h3"},{"title":"Data Analysis​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#data-analysis","content":" Group Name: data_analysis Description: Tools for querying, transforming, and visualizing data. Individual Tools: query_data_with_sqlcreate_sqlite_dbtransform_data_with_jqcreate_chart_from_plotly_config info For a more in-depth guide on using Data Analysis tools, refer to the Data Analysis Tools documentation. ","version":"Next","tagName":"h3"},{"title":"Web​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#web","content":" Group Name: web Description: Tools for interacting with web resources. Individual Tools: web_request ","version":"Next","tagName":"h3"},{"title":"Audio​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#audio","content":" Group Name: audio Description: Tools for generating and transcribing audio content. Individual Tools: text_to_speechmulti_speaker_text_to_speechtranscribe_audio ","version":"Next","tagName":"h3"},{"title":"Image​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#image","content":" Group Name: image Description: Tools for generating and analyzing images. Individual Tools: create_image_from_descriptiondescribe_imageedit_image_with_geminidescribe_audio ","version":"Next","tagName":"h3"},{"title":"General​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#general","content":" Group Name: general Description: General-purpose utility tools. Individual Tools: convert_file_to_markdownmermaid_diagram_generator ","version":"Next","tagName":"h3"},{"title":"Complete Configuration Example​","type":1,"pageTitle":"Configuring Built-in Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/#complete-configuration-example","content":" Below is a comprehensive example of a well-formed app_config that uses the unified method to enable a mix of tool groups and individual tools. # In your agent's YAML file: app_config: namespace: "myorg/dev" agent_name: "DataAndWebAgent" model: "gemini-1.5-pro" instruction: "You are an agent that can analyze data and browse the web." # --- Unified Tool Configuration --- tools: # Enable a group of tools - tool_type: builtin-group group_name: "data_analysis" # Enable another group - tool_type: builtin-group group_name: "artifact_management" # Enable a single, specific tool - tool_type: builtin tool_name: "web_request" # Enable a custom Python tool - tool_type: python component_module: "my_company.tools.custom_calculators" function_name: "calculate_roi" # ... other service configurations (session_service, artifact_service, etc.) ","version":"Next","tagName":"h2"},{"title":"SQL Database Integration","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database","content":"","keywords":"","version":"Next"},{"title":"Prerequisites​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#prerequisites","content":" Before starting this tutorial, ensure that you have installed and configured Solace Agent Mesh: Installed Solace Agent Mesh and the Solace Agent Mesh CLICreated a new Solace Agent Mesh projectAccess to a SQL database (local or remote) ","version":"Next","tagName":"h2"},{"title":"Adding the SQL Database Plugin​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#adding-the-sql-database-plugin","content":" Add the SQL Database plugin to your Solace Agent Mesh project: sam plugin add abc-coffee-info --plugin sam-sql-database You can use any name for your agent, in this tutorial we use abc-coffee-info. This command: Installs the sam-sql-database pluginCreates a new agent configuration file at configs/agents/abc-coffee-info.yaml ","version":"Next","tagName":"h2"},{"title":"Downloading Example Data​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#downloading-example-data","content":" For this tutorial, you can use a sample SQLite database for a fictional coffee company called ABC Coffee Co. First, download the example data. You can either visit this link to download with your browser: https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip Or you can use the command line to download the ZIP file: Using wget​ wget https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip Using curl​ curl -LO https://github.com/SolaceLabs/solace-agent-mesh-core-plugins/raw/refs/heads/main/sam-sql-database/example-data/abc_coffee_co.zip After downloading the ZIP file, extract it to a directory of your choice. You can use the following command to extract the ZIP file: unzip abc_coffee_co.zip ","version":"Next","tagName":"h2"},{"title":"Configuring the Agent​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#configuring-the-agent","content":" Now, update the agent configuration to use the SQLite database and import the CSV files. Open the configs/agents/abc-coffee-info.yaml file and modify the agent_init_function.config section to specify the CSV directory. Here is what you need to modify in the configuration file: # Find the agent_init_function section and update the config: agent_init_function: module: "sam_sql_database.lifecycle" name: "initialize_sql_agent" config: db_type: "${ABC_COFFEE_INFO_DB_TYPE}" db_name: "${ABC_COFFEE_INFO_DB_NAME}" database_purpose: "${ABC_COFFEE_INFO_DB_PURPOSE}" data_description: "${ABC_COFFEE_INFO_DB_DESCRIPTION}" # Add the CSV directory path csv_directories: - /path/to/your/unzipped/data Ensure you replace /path/to/your/unzipped/data with the path where you extracted the example data. For example, if you put the ZIP file in the root directory of your Solace Agent Mesh project, you can use abc_coffee_co. ","version":"Next","tagName":"h2"},{"title":"Setting the Environment Variables​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#setting-the-environment-variables","content":" The SQL Database agent requires that you configure several environment variables. You must create or update your .env file with the following variables for this tutorial: ABC_COFFEE_INFO_DB_TYPE=sqlite ABC_COFFEE_INFO_DB_NAME=abc_coffee.db ABC_COFFEE_INFO_DB_PURPOSE="ABC Coffee Co. sales and operations database" ABC_COFFEE_INFO_DB_DESCRIPTION="Contains information about ABC Coffee Co. products, sales, customers, employees, and store locations." # You can leave other environment variables as unset or empty SQLite stores the database in a local file and doesn't require a username or password for access. If you're using a database such as MySQL or PostgreSQL, you'll need to provide the appropriate environment variables for them. ","version":"Next","tagName":"h2"},{"title":"Running the Agent​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#running-the-agent","content":" Now, you can start your SQL database agent: sam run configs/agents/abc-coffee-info.yaml The agent: Connects to the A2A control planeInitializes the SQLite database and imports CSV data from the specified directoryDetects the database schema automaticallyRegisters its capabilities with the agent discovery system ","version":"Next","tagName":"h2"},{"title":"Interacting with the Database​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#interacting-with-the-database","content":" After your SQL database agent is running, you can interact with the ABC Coffee database through any gateway in your Solace Agent Mesh project (such as the Web UI gateway at http://localhost:8000). You can ask natural language questions about the ABC Coffee Co. database, such as: "How many customers does ABC Coffee have?""What are the top-selling products?""Show me the sales by region""List all orders from the last 30 days""What products are currently low in inventory?" Try creating reports by asking questions such as: "Create a report of our sales in 2024""Generate a summary of customer demographics" The SQL Database agent converts your natural language questions into SQL queries, executes them against the database, and returns the results. For large result sets, the agent automatically saves the results as artifacts that you can download. ","version":"Next","tagName":"h2"},{"title":"Advanced Configuration​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#advanced-configuration","content":" The SQL Database plugin supports many advanced configuration options. Here is a complete example based on the plugin structure: log: stdout_log_level: INFO log_file_level: DEBUG log_file: abc-coffee-info.log !include ../shared_config.yaml apps: - name: abc-coffee-info-app app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} agent_name: "AbcCoffeeInfo" display_name: "ABC Coffee Database Agent" supports_streaming: false model: *general_model instruction: | You are an expert SQL assistant for the ABC Coffee Co. database. The database schema and query examples are provided to you. Your primary goal is to translate user questions into accurate SQL queries. If a user asks to query the database, generate the SQL and call the 'execute_sql_query' tool. If the 'execute_sql_query' tool returns an error, analyze the error message and the original SQL, then try to correct the SQL query and call the tool again. If the results are large and the tool indicates they were saved as an artifact, inform the user about the artifact. Always use the 'execute_sql_query' tool to interact with the database. # Agent initialization with database setup agent_init_function: module: "sam_sql_database.lifecycle" name: "initialize_sql_agent" config: db_type: "${ABC_COFFEE_INFO_DB_TYPE}" db_name: "${ABC_COFFEE_INFO_DB_NAME}" database_purpose: "${ABC_COFFEE_INFO_DB_PURPOSE}" data_description: "${ABC_COFFEE_INFO_DB_DESCRIPTION}" auto_detect_schema: true csv_directories: - "abc_coffee_co" # Path to your extracted data query_examples: - natural_language: "Show all customers from New York" sql_query: "SELECT * FROM customers WHERE city = 'New York';" - natural_language: "What are the top 5 best-selling products?" sql_query: "SELECT product_name, SUM(quantity) as total_sold FROM order_items JOIN products ON order_items.product_id = products.id GROUP BY product_name ORDER BY total_sold DESC LIMIT 5;" agent_cleanup_function: module: "sam_sql_database.lifecycle" name: "cleanup_sql_agent_resources" # SQL query tool tools: - tool_type: python component_module: "sam_sql_database.tools" function_name: "execute_sql_query" session_service: *default_session_service artifact_service: *default_artifact_service # Agent capabilities - This is what other agents see during discovery agent_card: description: "ABC Coffee Co. Database Agent - Access to comprehensive coffee shop data including customers, orders, products, inventory, and sales history. Can answer questions about business metrics, customer analytics, product performance, and operational data." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "sql_query" name: "Coffee Shop Database Query" description: "Queries ABC Coffee Co. database containing customer orders, product catalog, inventory levels, sales history, and employee data." # A2A Protocol settings agent_card_publishing: { interval_seconds: 30 } agent_discovery: { enabled: true } inter_agent_communication: allow_list: ["*"] request_timeout_seconds: 60 ","version":"Next","tagName":"h2"},{"title":"Customizing the Agent Card​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#customizing-the-agent-card","content":" The agent_card section is crucial as it defines how other agents in your Solace Agent Mesh ecosystem discover and understand this database agent's capabilities. When other agents use agent discovery, they can see this information to decide whether to delegate tasks to your database agent. ","version":"Next","tagName":"h2"},{"title":"Key Agent Card Elements​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#key-agent-card-elements","content":" Description: Clearly describe what data the agent has access to and what types of questions it can answerSkills: List specific capabilities with concrete examples that show the scope of data availableData Context: Mention the business domain, data types, and scope of information available ","version":"Next","tagName":"h3"},{"title":"Example of a Well-Configured Agent Card​","type":1,"pageTitle":"SQL Database Integration","url":"/solace-agent-mesh/docs/documentation/tutorials/sql-database#example-of-a-well-configured-agent-card","content":" agent_card: description: "ABC Coffee Co. Database Agent - Access to comprehensive coffee shop data including customers, orders, products, inventory, and sales history. Can answer questions about business metrics, customer analytics, product performance, and operational data." defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "sql_query" name: "Coffee Shop Database Query" description: "Queries ABC Coffee Co. database containing customer orders, product catalog, inventory levels, sales history, and employee data." This detailed information helps other agents understand: What business domain this agent covers (coffee shop operations)What types of data are available (customers, orders, products, inventory, sales)What kinds of questions can be answered (metrics, analytics, performance data)Specific examples of queries that work well When configuring your own database agent, customize the description and examples to match your specific data and use cases. ","version":"Next","tagName":"h3"},{"title":"Using Text-to-Speech (TTS) Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#overview","content":" The audio tool group provides two primary TTS tools for generating high-quality audio artifacts: text_to_speech: Converts a string of text to speech using a single voice, featuring intelligent tone selection.multi_speaker_text_to_speech: Converts a conversational script, delineated by speaker, into a multi-speaker audio file. ","version":"Next","tagName":"h2"},{"title":"Setup and Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#setup-and-configuration","content":" ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#prerequisites","content":" API Key: A valid Google Gemini API key with access to the TTS model is required.Dependencies: The pydub library is necessary for audio processing and format conversion. It can be installed via pip install pydub. ","version":"Next","tagName":"h3"},{"title":"Basic Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#basic-configuration","content":" Environment Variable: The Gemini API key must be set as an environment variable. export GEMINI_API_KEY="your_gemini_api_key_here" Enablement: The audio tool group must be enabled in the agent's app_config.yml. tools: - tool_type: builtin-group group_name: "audio" ","version":"Next","tagName":"h3"},{"title":"Advanced Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#advanced-configuration","content":" You can exercise more granular control over the TTS tools by providing a tool_config block for each tool in your app_config.yml. ","version":"Next","tagName":"h2"},{"title":"text_to_speech Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#text_to_speech-configuration","content":" This example shows how to set a default voice and define the mapping between tones and specific voice models. - tool_type: builtin tool_name: "text_to_speech" tool_config: gemini_api_key: ${GEMINI_API_KEY} model: "gemini-2.5-flash-preview-tts" voice_name: "Kore" # Default voice if no tone is matched language: "en-US" # Default language output_format: "mp3" # Voice selection by tone mapping voice_tone_mapping: bright: ["Zephyr", "Autonoe"] upbeat: ["Puck", "Laomedeia"] informative: ["Charon", "Rasalgethi"] firm: ["Kore", "Orus", "Alnilam"] friendly: ["Achird"] casual: ["Zubenelgenubi"] warm: ["Sulafar"] ","version":"Next","tagName":"h3"},{"title":"multi_speaker_text_to_speech Configuration​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi_speaker_text_to_speech-configuration","content":" This example defines default voice configurations for up to five speakers. - tool_type: builtin tool_name: "multi_speaker_text_to_speech" tool_config: gemini_api_key: ${GEMINI_API_KEY} model: "gemini-2.5-flash-preview-tts" language: "en-US" output_format: "mp3" # Default speaker voice configurations default_speakers: - { name: "Speaker1", voice: "Kore", tone: "firm" } - { name: "Speaker2", voice: "Puck", tone: "upbeat" } - { name: "Speaker3", voice: "Charon", tone: "informative" } - { name: "Speaker4", voice: "Achird", tone: "friendly" } - { name: "Speaker5", voice: "Sulafar", tone: "warm" } # The voice_tone_mapping can also be included here ","version":"Next","tagName":"h3"},{"title":"Features​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#features","content":" ","version":"Next","tagName":"h2"},{"title":"Intelligent Tone Selection​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#intelligent-tone-selection","content":" The system supports tone-based voice selection, allowing for dynamic voice choice based on desired emotional or stylistic output, rather than explicit voice names. Available Tones:bright, upbeat, informative, firm, excitable, youthful, breezy, easy-going, breathy, clear, smooth, gravelly, soft, even, mature, forward, friendly, casual, gentle, lively, knowledgeable, warm Tone Aliases: professional → firmcheerful → upbeatcalm → softconversational → casual ","version":"Next","tagName":"h3"},{"title":"Multi-Language Support​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi-language-support","content":" The tools support over 25 languages, specified via BCP-47 language codes (for example, en-US, fr-FR, es-US, ja-JP). ","version":"Next","tagName":"h3"},{"title":"Usage Examples​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#usage-examples","content":" ","version":"Next","tagName":"h2"},{"title":"Single-Voice Text-to-Speech (text_to_speech)​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#single-voice-text-to-speech-text_to_speech","content":" Basic Usage Convert the following text to speech: "Welcome to the technical briefing on artificial intelligence." With Tone Selection Convert this text to speech with a professional tone: "Thank you for joining today's technical review." ","version":"Next","tagName":"h3"},{"title":"Multi-Speaker Text-to-Speech (multi_speaker_text_to_speech)​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi-speaker-text-to-speech-multi_speaker_text_to_speech","content":" Basic Conversation Convert this conversation to speech: Speaker1: Welcome to the podcast. Speaker2: Thank you for having me. With Custom Speaker Tones Convert this conversation using specific tones for each speaker: - Speaker1 should sound professional - Speaker2 should sound friendly Conversation: Speaker1: Good morning, this is the daily security briefing. Speaker2: Hi everyone, let's review the agenda for today's session. ","version":"Next","tagName":"h3"},{"title":"Tool Reference​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#tool-reference","content":" ","version":"Next","tagName":"h2"},{"title":"text_to_speech​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#text_to_speech","content":" Parameter\tType\tDescriptiontext\tstring\tThe text to be synthesized. output_filename\tstring\t(Optional) A custom MP3 filename. voice_name\tstring\t(Optional) A specific voice name to use. tone\tstring\t(Optional) The desired voice tone. language\tstring\t(Optional) The BCP-47 language code. ","version":"Next","tagName":"h3"},{"title":"multi_speaker_text_to_speech​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#multi_speaker_text_to_speech","content":" Parameter\tType\tDescriptionconversation_text\tstring\tA string of text with speaker labels (for example, S1: ...). output_filename\tstring\t(Optional) A custom MP3 filename. speaker_configs\tarray\t(Optional) An array to configure tones for specific speakers. language\tstring\t(Optional) The BCP-47 language code. ","version":"Next","tagName":"h3"},{"title":"Output and Metadata​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#output-and-metadata","content":" Both tools generate an MP3 audio artifact that includes a rich set of metadata: The source text (or a truncated version for long inputs)The voice(s) and language used for synthesisThe generation timestamp and the specific tool invokedThe requested tone and any speaker-specific configurations ","version":"Next","tagName":"h2"},{"title":"Troubleshooting​","type":1,"pageTitle":"Using Text-to-Speech (TTS) Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/audio-tools#troubleshooting","content":" Error: GEMINI_API_KEY is required: This indicates that the GEMINI_API_KEY environment variable has not been set correctly.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.Error: Failed to convert WAV to MP3: This typically indicates that pydub is not installed or that the underlying system is missing necessary audio codecs (for example, ffmpeg). ","version":"Next","tagName":"h2"},{"title":"Data Analysis Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools","content":"","keywords":"","version":"Next"},{"title":"Setup and Configuration​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#setup-and-configuration","content":" Enable the data analysis tool group in the agent's app_config.yml file. # In your agent's app_config: tools: - tool_type: builtin-group group_name: "data_analysis" # Optional: Configure tool behavior data_tools_config: sqlite_memory_threshold_mb: 100 max_result_preview_rows: 50 max_result_preview_bytes: 4096 ","version":"Next","tagName":"h2"},{"title":"Available Tools​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#available-tools","content":" ","version":"Next","tagName":"h2"},{"title":"query_data_with_sql​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#query_data_with_sql","content":" Enterprise Only This feature is available in the Enterprise Edition only. Executes a SQL query against data stored in a CSV or SQLite artifact. Parameters: input_filename (str): The filename of the input artifact (for example, 'data.csv', 'mydatabase.sqlite'). Supports versioning (for example, 'data.csv:2').sql_query (str): The SQL query string to execute.output_format (str, optional): The desired format for the output artifact ('csv' or 'json'). Defaults to 'csv'. Behavior: For CSV Input: The tool loads the CSV data into a temporary in-memory SQLite database table named data and executes the query against it.For SQLite Input: The tool connects directly to the specified SQLite database artifact in read-only mode. Returns: A dictionary containing the execution status, a preview of the query result, and the output_filename where the full result set is stored. ","version":"Next","tagName":"h3"},{"title":"create_sqlite_db​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#create_sqlite_db","content":" Enterprise Only This feature is available in the Enterprise Edition only. Converts a CSV or JSON artifact into a persistent SQLite database artifact. This is the recommended approach for executing multiple queries on the same dataset, as it avoids repeated parsing of the source file. Parameters: input_filename (str): The filename of the input CSV or JSON artifact.output_db_filename (str): The desired filename for the output SQLite database artifact (for example, 'queryable_dataset.sqlite').table_name (str, optional): The name of the table to be created within the SQLite database. Defaults to 'data'. Returns: A dictionary confirming the successful creation of the database artifact and providing its output_filename. ","version":"Next","tagName":"h3"},{"title":"transform_data_with_jq​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#transform_data_with_jq","content":" Enterprise Only This feature is available in the Enterprise Edition only. Applies a JQ expression to transform data from a JSON, YAML, or CSV artifact. Parameters: input_filename (str): The filename of the input artifact.jq_expression (str): The JQ filter or transformation expression string (for example, '.users[] | {name, id}'). Returns: A dictionary containing the execution status, a preview of the transformed data, and the output_filename where the full JSON result is stored. ","version":"Next","tagName":"h3"},{"title":"create_chart_from_plotly_config​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#create_chart_from_plotly_config","content":" Generates a static chart image (for example, PNG, JPG, SVG) from a Plotly configuration provided as a string. Parameters: config_content (str): A JSON or YAML formatted string representing the Plotly figure dictionary.config_format (str): Specifies whether config_content is 'json' or 'yaml'.output_filename (str): The desired filename for the output image artifact (for example, 'sales_chart.png').output_format (str, optional): The desired image format ('png', 'jpeg', 'svg', etc.). Defaults to 'png'. Returns: A dictionary confirming the chart's creation and providing its output_filename. ","version":"Next","tagName":"h3"},{"title":"Example Workflow: Querying a Large CSV​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#example-workflow-querying-a-large-csv","content":" The following workflow demonstrates an efficient method for analyzing a large CSV file: User Request: "I need to run several queries on large_data.csv."Agent Strategy: The agent determines that converting the CSV to a SQLite database is more performant for subsequent queries.Agent Call 1: The agent calls create_sqlite_db to convert large_data.csv into a new artifact, queryable_data.sqlite.Agent Response: "The data has been prepared for querying. What is your first question?"User Request: "Find all records where the category is 'Sales'."Agent Call 2: The agent calls query_data_with_sql, targeting the queryable_data.sqlite artifact.Agent Response: The agent provides the results of the query.User Request: "Now, find the average amount for the 'Marketing' category."Agent Call 3: The agent calls query_data_with_sql again on the same queryable_data.sqlite artifact, avoiding the overhead of reprocessing the original CSV file. ","version":"Next","tagName":"h2"},{"title":"Technical Considerations​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#technical-considerations","content":" ","version":"Next","tagName":"h2"},{"title":"Result Handling​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#result-handling","content":" Previews: For query_data_with_sql and transform_data_with_jq, the tools return a truncated preview of the result directly to the LLM for immediate context.Full Results: The complete, untruncated result sets are always saved as new artifacts. The LLM is provided with the filename and version of these artifacts.Accessing Full Results: To utilize the full results, the agent can employ file management tools (load_artifact) or Dynamic Embeds («artifact_content:...»). ","version":"Next","tagName":"h3"},{"title":"Security​","type":1,"pageTitle":"Data Analysis Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/data-analysis-tools#security","content":" SQL Execution: Queries against existing SQLite artifacts are performed in read-only mode to prevent data modification. Queries against temporary databases generated from CSVs are isolated.JQ Execution: JQ expressions are executed within a sandboxed Python library, not via shell execution.Resource Usage: Complex queries or transformations can be resource-intensive. Monitor performance and resource consumption accordingly. ","version":"Next","tagName":"h3"},{"title":"Dynamic Embeds","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds","content":"","keywords":"","version":"Next"},{"title":"Dynamic Embeds​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#dynamic-embeds","content":" Dynamic embeds provide a mechanism for agents to insert context-dependent information into their text responses or tool parameters using a specialized «...» syntax. This feature allows for the dynamic retrieval and formatting of data without requiring explicit tool calls for simple data retrieval or calculations. ","version":"Next","tagName":"h2"},{"title":"Overview​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#overview","content":" Dynamic embeds allow an agent to defer the inclusion of data until it is needed, resolving the value just before the final response is sent to the user. Standard Approach: "The current time is [call get_time tool]."With Dynamic Embeds: "The current time is «datetime:%H:%M»." The system resolves the embed directive, a dynamic placeholder for data that gets computed at runtime, replacing it with the evaluated result (for example, "The current time is 10:45."). ","version":"Next","tagName":"h3"},{"title":"Syntax​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#syntax","content":" There are two primary syntaxes for embed directives. Simple Syntax​ This syntax is used for most general-purpose embeds. «type:expression | format_spec» type: A keyword indicating the type of information to embed (for example, state, math, datetime).expression: The specific data to retrieve or the expression to evaluate.format_spec: (Optional) A specifier for formatting the output value (for example, a number precision .2f or a strftime string %Y-%m-%d). Chain Syntax​ This syntax is used exclusively for the artifact_content embed type to apply a sequence of transformations. «artifact_content:spec >>> modifier1 >>> modifier2 >>> format:output_format» artifact_spec: The artifact identifier (filename[:version]).>>>: The chain delimiter, separating transformation steps.modifier: A transformation to apply to the data (for example, jsonpath, grep, slice_lines).format: A required final step that specifies the output format (for example, text, json, datauri). ","version":"Next","tagName":"h3"},{"title":"Available Embed Types​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#available-embed-types","content":" General Purpose Embeds​ These are typically resolved by the agent host during execution. Type\tDescription\tExamplestate\tAccesses a session state variable.\t«state:user_name» math\tEvaluates a mathematical expression.\t«math:100 * 0.05 | .2f» (Result: 5.00) datetime\tInserts the current date and/or time.\t«datetime:%Y-%m-%d» (Result: 2023-10-27) uuid\tInserts a random Version 4 UUID.\t«uuid:» status_update\tSignals a temporary status update to the UI.\t«status_update:Searching knowledge base...» Artifact-Related Embeds​ artifact_meta​ Retrieves a JSON string containing the full metadata of a specified artifact. Syntax: «artifact_meta:filename[:version]»Example: «artifact_meta:report.csv» artifact_content​ Embeds the content of an artifact, with support for a chain of transformations. This is the most advanced embed type. Modifiers (Data Transformations)Modifiers are applied sequentially to transform the data. Modifier\tDescriptionjsonpath:<expr>\tApplies a JSONPath query to JSON data. select_cols:<c1,c2>\tSelects specific columns from CSV data. filter_rows_eq:<col>:<val>\tFilters CSV rows where a column's value equals the specified value. slice_rows:<start>:<end>\tSelects a slice of rows from CSV data. slice_lines:<start>:<end>\tSelects a slice of lines from text data. grep:<pattern>\tFilters lines matching a regular expression in text data. head:<N> / tail:<N>\tReturns the first or last N lines of text data. select_fields:<f1,f2>\tSelects specific fields from a list of dictionaries. apply_to_template:<file>\tRenders data using a Mustache template artifact. See the Templates Guide. Formatters (Final Output)This is the required final step in an artifact_content chain, defining the output format. Formatter\tDescriptiontext\tPlain text, decoded as UTF-8. json / json_pretty\tA compact or indented JSON string. csv\tA CSV formatted string. datauri\tA Base64-encoded data URI, typically for images (data:image/png;base64,...). artifact_content Examples: To embed an image for display in a UI:«artifact_content:logo.png >>> format:datauri»To extract and format specific data from a JSON file:«artifact_content:results.json >>> jsonpath:$.data[*].name >>> format:json»To get the last 10 lines of a log file:«artifact_content:debug.log >>> tail:10 >>> format:text»To filter a CSV file and render it using an HTML template:«artifact_content:users.csv >>> filter_rows_eq:Status:Active >>> apply_to_template:active_users.html >>> format:text» ","version":"Next","tagName":"h3"},{"title":"Technical Details​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#technical-details","content":" Resolution Stages​ Embeds are resolved in two distinct stages, depending on where the required data is available: Early Stage (Agent Host): Resolved by the agent runtime itself. This stage handles simple, context-local embeds like state, math, and datetime.Late Stage (Gateway): Resolved by the Gateway component before the final message is sent to the client. This is necessary for artifact_content embeds, which may involve large files or transformations that are too resource-intensive for the agent host. Configuration​ Enabling/Disabling: Embed resolution is enabled by default. It can be disabled in the app_config of the agent host or gateway by setting enable_embed_resolution: false.Resource Limits: The gateway enforces configurable limits to prevent abuse, including gateway_artifact_content_limit_bytes (default: 32KB) and gateway_recursive_embed_depth (default: 3). ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#error-handling","content":" If an embed directive fails during parsing or evaluation, it is replaced with a descriptive error message in the final output. Parsing Error: [Error: Invalid modifier format: 'badmodifier']Evaluation Error: [Error: State variable 'user_id' not found]Limit Exceeded: [Error: Artifact 'large_file.zip' exceeds size limit] ","version":"Next","tagName":"h3"},{"title":"Templates​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#templates","content":" ","version":"Next","tagName":"h2"},{"title":"Using Templates for Formatted Output​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#using-templates-for-formatted-output","content":" The apply_to_template modifier, used within an «artifact_content:...» embed directive, enables an agent to render structured data using a Mustache template. This mechanism allows for the separation of data and presentation, enabling the agent to control the output format (for example, HTML, Markdown) without generating the formatting markup itself. ","version":"Next","tagName":"h3"},{"title":"The Templating Workflow​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#the-templating-workflow","content":" The process involves three distinct steps: Template Creation: Author a Mustache template file that defines the desired output structure.Artifact Storage: Persist the template file as an artifact in the agent's artifact storage using the create_artifact tool.Template Rendering: Utilize an «artifact_content:...» embed chain to process a data artifact and then apply the stored template to the result. Step 1: Create a Mustache Template​ Mustache is a logic-less template syntax. Templates are created as text files (for example, user_table.html.mustache) containing placeholders for data injection. Key Mustache Syntax: {{variable}}: A variable placeholder. It is replaced with the corresponding value from the data context.{{#section}}...{{/section}}: A section tag. The enclosed block is rendered for each item in a list or if the section variable is a non-empty object or truthy value.{{^section}}...{{/section}}: An inverted section tag. The enclosed block is rendered only if the section variable is false, null, or an empty list.{{! comment }}: A comment tag. The content is ignored during rendering. Example: user_table.html.mustacheThis template generates an HTML table from a list of user objects. <h2>User List</h2> {{#items}} <table> <thead> <tr> <th>Name</th> <th>Status</th> </tr> </thead> <tbody> {{#.}} <tr> <td>{{name}}</td> <td>{{status}}</td> </tr> {{/.}} </tbody> </table> {{/items}} {{^items}} <p>No users found.</p> {{/items}} Step 2: Store the Template as an Artifact​ The template must be stored as an artifact to be accessible by the Gateway during the late-stage embed resolution process. This is accomplished using the create_artifact tool. Example Agent Interaction: User: "Please create an HTML template to display a list of users."Agent: "Acknowledged. I will create the template artifact user_table.html.mustache."(The agent then invokes the create_artifact tool with the specified filename and the HTML content from Step 1.) Step 3: Render the Template with an Embed​ With the data and template artifacts stored, the agent can construct an artifact_content embed chain to perform the rendering. Syntax: ... >>> apply_to_template:template_filename[:version] >>> ...Data Context: The data provided to the template engine is the output of the preceding modifier in the chain. If the data is a list, it is automatically wrapped in a dictionary of the form {'items': your_list}. The template should use {{#items}} to iterate over this list.If the data is a dictionary, it is used directly as the rendering context. Output Format: It is mandatory to terminate the chain with a format: step (for example, format:text) to specify the MIME type of the final rendered output. Complete Example: The following embed chain processes a JSON file and renders its content using the HTML template created in Step 1. «artifact_content:user_data.json >>> jsonpath:$.users[*] >>> select_fields:name,status >>> apply_to_template:user_table.html.mustache >>> format:text» Execution Flow: artifact_content:user_data.json: Loads the raw data from the user_data.json artifact.jsonpath:$.users[*]: Applies a JSONPath expression to extract the list of user objects.select_fields:name,status: Filters each object in the list to retain only the name and status fields.apply_to_template:user_table.html.mustache: Renders the resulting list of users using the specified Mustache template. ","version":"Next","tagName":"h3"},{"title":"Error Handling​","type":1,"pageTitle":"Dynamic Embeds","url":"/solace-agent-mesh/docs/documentation/user-guide/builtin-tools/embeds#error-handling-1","content":" Template Not Found: If the specified template artifact does not exist, the embed resolves to [Error: Template artifact '...' not found].Rendering Error: If the data structure is incompatible with the template's expectations, the embed resolves to [Error: Error rendering template '...']. ","version":"Next","tagName":"h3"},{"title":"Build Your Own Agent","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent","content":"","keywords":"","version":"Next"},{"title":"Overview​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#overview","content":" Our weather agent will demonstrate: External API integration (OpenWeatherMap)Professional service layer architectureMultiple sophisticated toolsProper lifecycle managementError handling and validationArtifact creation and management ","version":"Next","tagName":"h2"},{"title":"Prerequisites​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#prerequisites","content":" Before starting this tutorial, make sure you have: Read the Create Agent tutorialAn OpenWeatherMap API key (free at openweathermap.org)Basic understanding of Python async/awaitFamiliarity with HTTP APIs ","version":"Next","tagName":"h2"},{"title":"Planning the Weather Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#planning-the-weather-agent","content":" Our weather agent will have the following capabilities: Get Current Weather: Fetch current weather conditions for a specified locationGet Weather Forecast: Retrieve a multi-day weather forecastSave Weather Reports: Store weather data as artifacts The agent will demonstrate: External API integrationError handling and validationConfiguration managementArtifact creationResource lifecycle management ","version":"Next","tagName":"h2"},{"title":"Step 1: Project Structure​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-1-project-structure","content":" Run the following command to create a new custom agent: sam add agent --gui tip You can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create my-hello-agent --type agent. For information and recommendations about these options, see Agent or Plugin: Which To use?. For an example of plugin agents, see the Create Agents guide. 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. Important Notice This tutorial is intentionally comprehensive to demonstrate the full flexibility and advanced features available in Solace Agent Mesh agents. For most straightforward use cases, you only need a simple Python function and a corresponding reference in your YAML configuration file. Simple Weather Agent Example After going through the add agent wizard from sam add agent --gui, create the following file under src/weather_agent/tools.py directory: # src/weather_agent/tools.py import httpx from typing import Any, Dict, Optional from google.adk.tools import ToolContext from solace_ai_connector.common.log import log async def get_current_weather( location: str, units: str = "metric", tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get current weather conditions for a specified location. Args: location: City name, state, and country (for example, "New York, NY, US") units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin" """ log.info("[GetCurrentWeather] Getting current weather for: %s", location) base_url = "https://api.openweathermap.org/data/2.5" api_key = tool_config.get("api_key") if tool_config else None url = f"{base_url}/weather" params = { "q": location, "appid": api_key, "units": units } try: # Fetch weather data async with httpx.AsyncClient() as client: response = await client.get(url, params=params) response.raise_for_status() weather_data = response.json() result = { "status": "success", "location": location, "units": units, "data": weather_data } return result except Exception as e: log.error(f"[GetCurrentWeather] Error getting weather: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } async def get_weather_forecast( location: str, days: int = 5, units: str = "metric", tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get weather forecast for a specified location. Args: location: City name, state, and country days: Number of days for forecast (1-5) units: Temperature units """ log.info("[GetWeatherForecast] Getting %d-day forecast for: %s", days, location) base_url = "https://api.openweathermap.org/data/2.5" api_key = tool_config.get("api_key") if tool_config else None url = f"{base_url}/forecast" params = { "q": location, "appid": api_key, "units": units, "cnt": min(days * 8, 40) } try: # Fetch forecast data async with httpx.AsyncClient() as client: response = await client.get(url, params=params) response.raise_for_status() forecast_data = response.json() result = { "status": "success", "location": forecast_data["location"], "days": days, "units": units, "data": forecast_data } return result except Exception as e: log.error(f"[GetWeatherForecast] Error getting forecast: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } And update the weather agent config file's tool section under configs/agent/weather-agent.yaml as follows: # Tools configuration tools: # Current weather tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_current_weather" tool_description: "Get current weather conditions for a specified location" tool_config: api_key: ${OPENWEATHER_API_KEY} # Weather forecast tool - tool_type: python component_module: "src.weather_agent.tools" function_name: "get_weather_forecast" component_base_path: . tool_description: "Get weather forecast for up to 5 days for a specified location" tool_config: api_key: ${OPENWEATHER_API_KEY} For better discoverability, update the agent card section in the same YAML file as follows: # Agent card agent_card: description: "Professional weather agent providing current conditions, forecasts, and weather comparisons" defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "get_current_weather" name: "Get Current Weather" description: "Retrieve current weather conditions for any location worldwide" - id: "get_weather_forecast" name: "Get Weather Forecast" description: "Provide detailed weather forecasts up to 5 days ahead" To run the agent, you can continue following documentation from Step 6 of this tutorial. Other concepts mentioned in this page such as lifecycle, services, artifacts are just to showcase more advanced patterns. Create the directory structure for the weather agent: sam-project/ ├── src/ │ └── weather_agent/ │ ├── __init__.py │ ├── tools.py │ ├── lifecycle.py │ └── services/ │ ├── __init__.py │ └── weather_service.py ├── configs │ └── shared_config.yaml │ └── agents/ │ └── weather_agent.yaml ... tip IN Solace Agent Mesh, you can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create your-agent --type agent. This tutorial uses the sam add agent command to create a new agent named "Weather Agent", for an example of creating a custom agent plugin, see the Create Agents tutorial. ","version":"Next","tagName":"h2"},{"title":"Step 2: Weather Service Implementation​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-2-weather-service-implementation","content":" First, create a service class to handle weather API interactions: src/weather_agent/services/weather_service.py: """ Weather service for interacting with external weather APIs. """ import aiohttp from typing import Dict, Any, Optional, List from datetime import datetime, timezone from solace_ai_connector.common.log import log class WeatherService: """Service for fetching weather data from external APIs.""" def __init__(self, api_key: str, base_url: str = "https://api.openweathermap.org/data/2.5"): self.api_key = api_key self.base_url = base_url self.session: Optional[aiohttp.ClientSession] = None self.log_identifier = "[WeatherService]" async def _get_session(self) -> aiohttp.ClientSession: """Get or create an HTTP session.""" if self.session is None or self.session.closed: self.session = aiohttp.ClientSession() return self.session async def close(self): """Close the HTTP session.""" if self.session and not self.session.closed: await self.session.close() log.info(f"{self.log_identifier} HTTP session closed") async def get_current_weather(self, location: str, units: str = "metric") -> Dict[str, Any]: """ Get current weather for a location. Args: location: City name, state code, and country code (for example, "London,UK") units: Temperature units (metric, imperial, kelvin) Returns: Dictionary containing current weather data """ log.info(f"{self.log_identifier} Fetching current weather for: {location}") session = await self._get_session() url = f"{self.base_url}/weather" params = { "q": location, "appid": self.api_key, "units": units } try: async with session.get(url, params=params) as response: if response.status == 200: data = await response.json() log.info(f"{self.log_identifier} Successfully fetched weather for {location}") return self._format_current_weather(data) elif response.status == 404: raise ValueError(f"Location '{location}' not found") else: error_data = await response.json() raise Exception(f"Weather API error: {error_data.get('message', 'Unknown error')}") except aiohttp.ClientError as e: log.error(f"{self.log_identifier} Network error fetching weather: {e}") raise Exception(f"Network error: {str(e)}") async def get_weather_forecast(self, location: str, days: int = 5, units: str = "metric") -> Dict[str, Any]: """ Get weather forecast for a location. Args: location: City name, state code, and country code days: Number of days for forecast (1-5) units: Temperature units Returns: Dictionary containing forecast data """ log.info(f"{self.log_identifier} Fetching {days}-day forecast for: {location}") session = await self._get_session() url = f"{self.base_url}/forecast" params = { "q": location, "appid": self.api_key, "units": units, "cnt": min(days * 8, 40) # API returns 3-hour intervals, max 40 entries } try: async with session.get(url, params=params) as response: if response.status == 200: data = await response.json() log.info(f"{self.log_identifier} Successfully fetched forecast for {location}") return self._format_forecast_data(data, days) elif response.status == 404: raise ValueError(f"Location '{location}' not found") else: error_data = await response.json() raise Exception(f"Weather API error: {error_data.get('message', 'Unknown error')}") except aiohttp.ClientError as e: log.error(f"{self.log_identifier} Network error fetching forecast: {e}") raise Exception(f"Network error: {str(e)}") def _format_current_weather(self, data: Dict) -> Dict[str, Any]: """Format current weather data for consistent output.""" return { "location": f"{data['name']}, {data['sys']['country']}", "temperature": data['main']['temp'], "feels_like": data['main']['feels_like'], "humidity": data['main']['humidity'], "pressure": data['main']['pressure'], "description": data['weather'][0]['description'].title(), "wind_speed": data.get('wind', {}).get('speed', 0), "wind_direction": data.get('wind', {}).get('deg', 0), "visibility": data.get('visibility', 0) / 1000, # Convert to km "timestamp": datetime.fromtimestamp(data['dt']).isoformat(), "sunrise": datetime.fromtimestamp(data['sys']['sunrise']).isoformat(), "sunset": datetime.fromtimestamp(data['sys']['sunset']).isoformat() } def _format_forecast_data(self, data: Dict, days: int) -> Dict[str, Any]: """Format forecast data for consistent output.""" forecasts = [] current_date = None daily_data = [] for item in data['list'][:days * 8]: forecast_date = datetime.fromtimestamp(item['dt']).date() if current_date != forecast_date: if daily_data: forecasts.append(self._aggregate_daily_forecast(daily_data)) current_date = forecast_date daily_data = [] daily_data.append(item) # Add the last day's data if daily_data: forecasts.append(self._aggregate_daily_forecast(daily_data)) return { "location": f"{data['city']['name']}, {data['city']['country']}", "forecasts": forecasts[:days] } def _aggregate_daily_forecast(self, daily_data: List[Dict]) -> Dict[str, Any]: """Aggregate 3-hour forecasts into daily summary.""" if not daily_data: return {} # Get temperatures for min/max calculation temps = [item['main']['temp'] for item in daily_data] # Use the forecast closest to noon for general conditions noon_forecast = min(daily_data, key=lambda x: abs( datetime.fromtimestamp(x['dt']).hour - 12 )) return { "date": datetime.fromtimestamp(daily_data[0]['dt']).date().isoformat(), "temperature_min": min(temps), "temperature_max": max(temps), "description": noon_forecast['weather'][0]['description'].title(), "humidity": noon_forecast['main']['humidity'], "wind_speed": noon_forecast.get('wind', {}).get('speed', 0), "precipitation_probability": noon_forecast.get('pop', 0) * 100 } ","version":"Next","tagName":"h2"},{"title":"Step 3: Weather Tools Implementation​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-3-weather-tools-implementation","content":" Now create the tool functions: src/weather_agent/tools.py: """ Weather agent tools for fetching and processing weather data. """ import json from typing import Any, Dict, Optional from datetime import datetime, timezone from google.adk.tools import ToolContext from solace_ai_connector.common.log import log from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata async def get_current_weather( location: str, units: str = "metric", save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get current weather conditions for a specified location. Args: location: City name, state, and country (for example, "New York, NY, US") units: Temperature units - "metric" (Celsius), "imperial" (Fahrenheit), or "kelvin" save_to_file: Whether to save the weather report as an artifact Returns: Dictionary containing current weather information """ log_identifier = "[GetCurrentWeather]" log.info(f"{log_identifier} Getting current weather for: {location}") if not tool_context: return { "status": "error", "message": "Tool context is required for weather operations" } try: # Get weather service from agent state host_component = getattr(tool_context._invocation_context, "agent", None) if host_component: host_component = getattr(host_component, "host_component", None) if not host_component: return { "status": "error", "message": "Could not access agent host component" } weather_service = host_component.get_agent_specific_state("weather_service") if not weather_service: return { "status": "error", "message": "Weather service not initialized" } # Fetch weather data weather_data = await weather_service.get_current_weather(location, units) # Create human-readable summary summary = _create_weather_summary(weather_data) result = { "status": "success", "location": weather_data["location"], "summary": summary, "data": weather_data } # Save to artifact if requested if save_to_file: artifact_result = await _save_weather_artifact( weather_data, f"current_weather_{location}", tool_context ) result["artifact"] = artifact_result log.info(f"{log_identifier} Successfully retrieved weather for {location}") return result except ValueError as e: log.warning(f"{log_identifier} Invalid location: {e}") return { "status": "error", "message": f"Location error: {str(e)}" } except Exception as e: log.error(f"{log_identifier} Error getting weather: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } async def get_weather_forecast( location: str, days: int = 5, units: str = "metric", save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Get weather forecast for a specified location. Args: location: City name, state, and country days: Number of days for forecast (1-5) units: Temperature units save_to_file: Whether to save the forecast as an artifact Returns: Dictionary containing weather forecast information """ log_identifier = "[GetWeatherForecast]" log.info(f"{log_identifier} Getting {days}-day forecast for: {location}") if not tool_context: return { "status": "error", "message": "Tool context is required for weather operations" } # Validate days parameter if not 1 <= days <= 5: return { "status": "error", "message": "Days must be between 1 and 5" } try: # Get weather service from agent state host_component = getattr(tool_context._invocation_context, "agent", None) if host_component: host_component = getattr(host_component, "host_component", None) if not host_component: return { "status": "error", "message": "Could not access agent host component" } weather_service = host_component.get_agent_specific_state("weather_service") if not weather_service: return { "status": "error", "message": "Weather service not initialized" } # Fetch forecast data forecast_data = await weather_service.get_weather_forecast(location, days, units) # Create human-readable summary summary = _create_forecast_summary(forecast_data) result = { "status": "success", "location": forecast_data["location"], "summary": summary, "data": forecast_data } # Save to artifact if requested if save_to_file: artifact_result = await _save_weather_artifact( forecast_data, f"forecast_{location}_{days}day", tool_context ) result["artifact"] = artifact_result log.info(f"{log_identifier} Successfully retrieved forecast for {location}") return result except ValueError as e: log.warning(f"{log_identifier} Invalid location: {e}") return { "status": "error", "message": f"Location error: {str(e)}" } except Exception as e: log.error(f"{log_identifier} Error getting forecast: {e}") return { "status": "error", "message": f"Weather service error: {str(e)}" } def _create_weather_summary(weather_data: Dict[str, Any]) -> str: """Create a human-readable weather summary.""" temp_unit = "°C" # Assuming metric units for summary summary = f"Current weather in {weather_data['location']}:\\n" summary += f"• Temperature: {weather_data['temperature']}{temp_unit} (feels like {weather_data['feels_like']}{temp_unit})\\n" summary += f"• Conditions: {weather_data['description']}\\n" summary += f"• Humidity: {weather_data['humidity']}%\\n" summary += f"• Wind: {weather_data['wind_speed']} m/s\\n" summary += f"• Visibility: {weather_data['visibility']} km" return summary def _create_forecast_summary(forecast_data: Dict[str, Any]) -> str: """Create a human-readable forecast summary.""" summary = f"Weather forecast for {forecast_data['location']}:\\n\\n" for forecast in forecast_data['forecasts']: date = datetime.fromisoformat(forecast['date']).strftime('%A, %B %d') summary += f"• {date}: {forecast['description']}\\n" summary += f" High: {forecast['temperature_max']:.1f}°C, Low: {forecast['temperature_min']:.1f}°C\\n" if forecast['precipitation_probability'] > 0: summary += f" Precipitation: {forecast['precipitation_probability']:.0f}% chance\\n" summary += "\\n" return summary.strip() async def _save_weather_artifact( weather_data: Dict[str, Any], filename_base: str, tool_context: ToolContext ) -> Dict[str, Any]: """Save weather data as an artifact.""" try: # Prepare content content = json.dumps(weather_data, indent=2, default=str) timestamp = datetime.now(timezone.utc) filename = f"{filename_base}_{timestamp.strftime('%Y%m%d_%H%M%S')}.json" # Save artifact artifact_service = tool_context._invocation_context.artifact_service result = await save_artifact_with_metadata( artifact_service=artifact_service, app_name=tool_context._invocation_context.app_name, user_id=tool_context._invocation_context.user_id, session_id=tool_context._invocation_context.session.id, filename=filename, content_bytes=content.encode('utf-8'), mime_type="application/json", metadata_dict={ "description": "Weather data report", "source": "Weather Agent" }, timestamp=timestamp ) return { "filename": filename, "status": result.get("status", "success") } except Exception as e: log.error(f"[WeatherArtifact] Error saving artifact: {e}") return { "status": "error", "message": f"Failed to save artifact: {str(e)}" } ","version":"Next","tagName":"h2"},{"title":"Step 4: Lifecycle Functions​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-4-lifecycle-functions","content":" Create the lifecycle management: src/weather_agent/lifecycle.py: """ Lifecycle functions for the Weather Agent. """ from typing import Any import asyncio from pydantic import BaseModel, Field, SecretStr from solace_ai_connector.common.log import log from .services.weather_service import WeatherService class WeatherAgentInitConfig(BaseModel): """ Configuration model for Weather Agent initialization. """ api_key: SecretStr = Field(description="OpenWeatherMap API key") base_url: str = Field( default="https://api.openweathermap.org/data/2.5", description="Weather API base URL" ) startup_message: str = Field( default="Weather Agent is ready to provide weather information!", description="Message to log on startup" ) def initialize_weather_agent(host_component: Any, init_config: WeatherAgentInitConfig): """ Initialize the Weather Agent with weather service. Args: host_component: The agent host component init_config: Validated initialization configuration """ log_identifier = f"[{host_component.agent_name}:init]" log.info(f"{log_identifier} Starting Weather Agent initialization...") try: # Initialize weather service weather_service = WeatherService( api_key=init_config.api_key.get_secret_value(), base_url=init_config.base_url ) # Store service in agent state host_component.set_agent_specific_state("weather_service", weather_service) # Log startup message log.info(f"{log_identifier} {init_config.startup_message}") # Store initialization metadata host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z") host_component.set_agent_specific_state("weather_requests_count", 0) log.info(f"{log_identifier} Weather Agent initialization completed successfully") except Exception as e: log.error(f"{log_identifier} Failed to initialize Weather Agent: {e}") raise def cleanup_weather_agent(host_component: Any): """ Clean up Weather Agent resources. Args: host_component: The agent host component """ log_identifier = f"[{host_component.agent_name}:cleanup]" log.info(f"{log_identifier} Starting Weather Agent cleanup...") async def cleanup_async(host_component: Any): try: # Get and close weather service weather_service = host_component.get_agent_specific_state("weather_service") if weather_service: await weather_service.close() log.info(f"{log_identifier} Weather service closed successfully") # Log final statistics request_count = host_component.get_agent_specific_state("weather_requests_count", 0) log.info(f"{log_identifier} Agent processed {request_count} weather requests during its lifetime") log.info(f"{log_identifier} Weather Agent cleanup completed") except Exception as e: log.error(f"{log_identifier} Error during cleanup: {e}") # run cleanup in the event loop loop = asyncio.get_event_loop() loop.run_until_complete(cleanup_async(host_component)) log.info(f"{log_identifier} Weather Agent cleanup completed successfully") ","version":"Next","tagName":"h2"},{"title":"Step 5: Agent Configuration​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-5-agent-configuration","content":" Create the comprehensive YAML configuration: # Weather Agent Configuration log: stdout_log_level: INFO log_file_level: DEBUG log_file: weather-agent.log !include ../shared_config.yaml apps: - name: weather-agent # Broker configuration app_module: solace_agent_mesh.agent.sac.app broker: <<: *broker_connection app_config: namespace: "${NAMESPACE}" agent_name: "WeatherAgent" display_name: "Weather Information Agent" supports_streaming: true # LLM model configuration model: *general_model # Agent instructions instruction: | You are a professional weather agent that provides accurate, up-to-date weather information. Your capabilities include: 1. Getting current weather conditions for any location worldwide 2. Providing detailed weather forecasts up to 5 days 3. Saving weather reports as files for future reference Guidelines: - Always specify the location clearly when providing weather information - Include relevant details like temperature, conditions, humidity, and wind - Offer to save weather reports when providing detailed information - Be helpful in suggesting appropriate clothing or activities based on weather - If a location is ambiguous, ask for clarification (city, state/province, country) When users ask about weather, use the appropriate tools to fetch real-time data. Present information in a clear, organized manner that's easy to understand. # Lifecycle functions agent_init_function: module: "src.weather_agent.lifecycle" name: "initialize_weather_agent" base_path: . config: api_key: ${OPENWEATHER_API_KEY} base_url: "https://api.openweathermap.org/data/2.5" startup_message: "Weather Agent is ready to provide weather information!" agent_cleanup_function: module: "src.weather_agent.lifecycle" base_path: . name: "cleanup_weather_agent" # Tools configuration tools: # Current weather tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_current_weather" tool_description: "Get current weather conditions for a specified location" # Weather forecast tool - tool_type: python component_module: "src.weather_agent.tools" component_base_path: . function_name: "get_weather_forecast" tool_description: "Get weather forecast for up to 5 days for a specified location" # Built-in artifact tools for file operations - tool_type: builtin-group group_name: "artifact_management" session_service: *default_session_service artifact_service: *default_artifact_service artifact_handling_mode: "reference" enable_embed_resolution: true enable_artifact_content_instruction: true # Agent card agent_card: description: "Professional weather agent providing current conditions, forecasts, and weather comparisons" defaultInputModes: ["text"] defaultOutputModes: ["text", "file"] skills: - id: "get_current_weather" name: "Get Current Weather" description: "Retrieve current weather conditions for any location worldwide" - id: "get_weather_forecast" name: "Get Weather Forecast" description: "Provide detailed weather forecasts up to 5 days ahead" agent_card_publishing: interval_seconds: 30 agent_discovery: enabled: false inter_agent_communication: allow_list: [] request_timeout_seconds: 30 For more details on agent cards, see the Agent Card Concepts documentation. ","version":"Next","tagName":"h2"},{"title":"Step 6: Environment Setup​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-6-environment-setup","content":" Before running your weather agent, you'll need to: Get an OpenWeatherMap API key: Sign up at OpenWeatherMapGet your free API key Set environment variables: export OPENWEATHER_API_KEY="your_api_key_here" # Other environment variables as needed ","version":"Next","tagName":"h2"},{"title":"Step 7: Running the Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-7-running-the-agent","content":" 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 src directory directly using the Solace Agent Mesh CLI. Start your weather agent for development purposes run: sam run To solely run the agent, use sam run configs/agents/weather_agent.yaml ","version":"Next","tagName":"h2"},{"title":"Step 8: Testing the Weather Agent​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#step-8-testing-the-weather-agent","content":" You can test your weather agent with these example requests: Current Weather: "What's the current weather in New York City?" Weather Forecast: "Can you give me a 5-day forecast for London, UK and save it to a file?" Weather with File Save: "Get the current weather for Tokyo, Japan and save the report" ","version":"Next","tagName":"h2"},{"title":"Key Features Demonstrated​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#key-features-demonstrated","content":" ","version":"Next","tagName":"h2"},{"title":"1. External API Integration​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#1-external-api-integration","content":" Proper HTTP session managementError handling for network issuesAPI response transformation ","version":"Next","tagName":"h3"},{"title":"2. Resource Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#2-resource-management","content":" Lifecycle functions for initialization and cleanupShared service instances across tool callsProper resource disposal ","version":"Next","tagName":"h3"},{"title":"3. Configuration Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#3-configuration-management","content":" Pydantic models for type-safe configurationEnvironment variable integrationFlexible tool configuration ","version":"Next","tagName":"h3"},{"title":"4. Error Handling​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#4-error-handling","content":" Comprehensive exception handlingUser-friendly error messagesLogging for debugging ","version":"Next","tagName":"h3"},{"title":"5. Artifact Management​","type":1,"pageTitle":"Build Your Own Agent","url":"/solace-agent-mesh/docs/documentation/tutorials/custom-agent#5-artifact-management","content":" Saving structured data as filesMetadata enrichmentFile format handling ","version":"Next","tagName":"h3"},{"title":"Creating Agents","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents","content":"","keywords":"","version":"Next"},{"title":"Introduction​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#introduction","content":" tip For a more comprehensive tutorial example, see the Build Your Own Agent guide. This page provides an in-depth theoretical overview of creating agents in Solace Agent Mesh. Solace Agent Mesh is a powerful platform that enables you to create intelligent agents that can communicate with each other and perform complex tasks. At its core, Solace Agent Mesh uses a tool-based architecture where LLM-powered agents are equipped with specific capabilities (tools) that they can use to accomplish user requests. Before continuing with this tutorial, make sure you are familiar with the basic agent concept. This tutorial guides you through creating your first Solace Agent Mesh agent from scratch. You will learn how to: Define tools as Python functionsConfigure an agent using YAMLSet up agent lifecycle functions By the end of this tutorial, you should have a working "Hello World" agent that demonstrates the fundamental concepts of Solace Agent Mesh agent development. ","version":"Next","tagName":"h2"},{"title":"Quick Start: Creating Your First Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#quick-start-creating-your-first-agent","content":" You can create an agent directly using the Solace Agent Mesh CLI sam add agent: sam add agent my-first-agent This command: Launches an interactive setup (or use --gui for browser-based configuration)Generates the necessary files and configurationSets up the basic agent structure Note that create agent as plugin is preferred over create agent directly. ","version":"Next","tagName":"h2"},{"title":"CLI Options​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#cli-options","content":" You can customize the agent creation with provided CLI options. For a complete list of options, run: sam add agent --help ","version":"Next","tagName":"h3"},{"title":"Core Concepts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#core-concepts","content":" Before diving into the implementation, it is important to understand the key concepts that make Solace Agent Mesh agents work: ","version":"Next","tagName":"h2"},{"title":"Tools​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tools","content":" Tools are the fundamental building blocks of Solace Agent Mesh agents. Each tool is implemented as a Python function that performs a specific task. Tools can: Process text and dataInteract with external APIsCreate and manipulate filesCommunicate with other agentsAccess databases and services 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. tip Solace Agent Mesh provides a set of built-in tools plus support for model context protocol (MCP) servers, which can be configured in the tools list of your agent configuration. ","version":"Next","tagName":"h3"},{"title":"Configuration File​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#configuration-file","content":" The config.yaml (for plugin template) or agent-name.yaml (for agent instances) file is the blueprint of your agent. It defines: Agent identity: Name, description, and capabilitiesModel configuration: Which LLM to useTools list: Defines which tools the agent can access and how they're configuredLifecycle functions: Setup and cleanup proceduresFramework services: Session management, artifact storage, and so on.Agent card: Metadata describing the agent capabilities, skills and its visibility in the system ","version":"Next","tagName":"h3"},{"title":"Tool Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tool-configuration","content":" Within the tools list in your YAML config, each tool can have its own tool_config section. This allows you to: Configure the same tool function for different purposesPass specific parameters to tool instancesCustomize tool behavior per agent info For tools of type "python", you can also use the tool_name and tool_description to overwrite the function name and description in the tool docstring. 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. ","version":"Next","tagName":"h3"},{"title":"ToolContext​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#toolcontext","content":" The ToolContext object (passed as one of the arguments to your tool function) provides your tools with access to Solace Agent Mesh core services: Logging: Structured logging for debugging and monitoringArtifact Service: File storage and retrievalSession Information: Current user and session contextAgent State: Shared data between tool calls ","version":"Next","tagName":"h3"},{"title":"Lifecycle Functions​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#lifecycle-functions","content":" Lifecycle functions allow you to manage resources that should persist for the agent's lifetime: agent_init_function: Runs when the agent starts (for example, database connections)agent_cleanup_function: Runs when the agent shuts down (for example, closing connections) note Lifecycle functions are optional but recommended for managing resources effectively. ","version":"Next","tagName":"h3"},{"title":"Creating an Agent Plugin: Step-by-Step​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#creating-an-agent-plugin-step-by-step","content":" Create a simple agent that can greet users and demonstrate the core concepts. You can create an agent either by using the sam add agent command or by creating a new plugin of type agent, sam plugin create my-hello-agent --type agent. tip For information and recommendations about these options, see Agent or Plugin: Which To use?. ","version":"Next","tagName":"h2"},{"title":"Step 1: Initialize your Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-1-initialize-your-agent","content":" In this tutorial, you create a new agent by creating a new plugin of type agent. For an example of custom agents, see Build Your Own Agent guide. Although the directory structure for plugins is slightly different than the one for agents, both require a YAML configuration file, and a python module with the tools and lifecycle functions you want. To create a new agent plugin, run the following command: sam plugin create my-hello-agent --type agent And follow the prompts to set up your agent. The prompts create a new directory structure for your agent. my-hello-agent/ ├── src/ │ └── my_hello_agent/ │ ├── __init__.py │ ├── tools.py │ └── lifecycle.py # This file won't be automatically created ├── config.yaml ├── pyproject.toml └── README.md ","version":"Next","tagName":"h3"},{"title":"Step 2: The Tool Function​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-2-the-tool-function","content":" Create your first tool function: The following arguments are provided by the framework: tool_context: Solace Agent Mesh framework contexttool_config: Tool-specific configuration (from config.yaml) For a complete guide on creating python tools, see our Creating Python Tools documentation. # src/my_hello_agent/tools.py """ Tools for the Hello World agent. """ from typing import Any, Dict, Optional from google.adk.tools import ToolContext from solace_ai_connector.common.log import log async def hello_tool( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user with a personalized message. Args: name: The name of the person to greet Returns: A dictionary with the greeting message """ log_identifier = "[HelloTool]" log.info(f"{log_identifier} Greeting user: {name}") # Get configuration from tool_config greeting_prefix = "Hello" if tool_config: greeting_prefix = tool_config.get("greeting_prefix", "Hello") # Create the greeting message greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" log.info(f"{log_identifier} Generated greeting: {greeting_message}") return { "status": "success", "message": greeting_message, "greeted_name": name } async def farewell_tool( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Says goodbye to a user. Args: name: The name of the person to say goodbye to Returns: A dictionary with the farewell message """ log_identifier = "[FarewellTool]" log.info(f"{log_identifier} Saying goodbye to user: {name}") # Get configuration from tool_config farewell_prefix = "Goodbye" if tool_config: farewell_prefix = tool_config.get("farewell_prefix", "Goodbye") # Create the farewell message farewell_message = f"{farewell_prefix}, {name}! Thanks for using Solace Agent Mesh!" log.info(f"{log_identifier} Generated farewell: {farewell_message}") return { "status": "success", "message": farewell_message, "farewell_name": name } Key Points: Function Signature: All tool functions should be async and accept tool_context and tool_config parametersReturn Format: Return a dictionary with at least a status fieldLogging: Use the Solace Agent Mesh logger for consistent loggingConfiguration: Access tool-specific config via the tool_config parameter ","version":"Next","tagName":"h3"},{"title":"Step 3: The Agent Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-3-the-agent-configuration","content":" Create the main configuration file for your agent: # File: config.yaml (at root of project directory) # ... (additional services and configurations) apps: - name: my-hello-agent app_module: solace_agent_mesh.agent.sac.app broker: # Can be found in configs/shared_config.yaml after running sam init <<: *broker_connection # Agent-specific configuration app_config: # Basic agent identity namespace: ${NAMESPACE} supports_streaming: true agent_name: "HelloAgent" display_name: "Hello World Agent" # LLM model configuration model: *general_model # Agent instructions (system prompt) instruction: | You are a friendly Hello World agent. Your purpose is to greet users and demonstrate the capabilities of Solace Agent Mesh. You can: 1. Greet users with personalized messages using the hello_tool 2. Say goodbye to users using the farewell_tool Always be polite and helpful. When greeting someone, ask for their name if they haven't provided it. # Lifecycle functions agent_init_function: module: "my_hello_agent.lifecycle" # This should point to your lifecycle python module name: "initialize_hello_agent" base_path: . config: startup_message: "Hello Agent is starting up!" log_level: "INFO" agent_cleanup_function: module: "my_hello_agent.lifecycle" base_path: . name: "cleanup_hello_agent" # Tools configuration tools: # Hello tool with custom greeting - tool_type: python component_module: "my_hello_agent.tools" component_base_path: . function_name: "hello_tool" tool_name: "greet_user" # Renaming the tool, must use this name in the agent card tool_config: greeting_prefix: "Hello there" # Farewell tool with custom farewell - tool_type: python component_module: "my_hello_agent.tools" component_base_path: . function_name: "farewell_tool" tool_name: "say_goodbye" tool_config: farewell_prefix: "See you later" # Built-in artifact tools for file operations - tool_type: builtin-group group_name: "artifact_management" # Agent card (describes the agent's capabilities) agent_card: description: "A friendly Hello World agent that demonstrates Solace Agent Mesh capabilities" defaultInputModes: ["text"] defaultOutputModes: ["text"] skills: - id: "greet_user" name: "Greet User" description: "Greets users with personalized messages" - id: "say_goodbye" name: "Say Goodbye" description: "Says goodbye to users" - id: "file_operations" name: "File Operations" description: "Create, read, and manage files and artifacts" # Session and artifact services session_service: *default_session_service artifact_service: *default_artifact_service # ... (additional services and configurations) Key Sections Explained: namespace: Unique identifier for your agent in the meshmodel: LLM configuration (can be a string or detailed config)instruction: The system prompt that defines your agent's behaviortools: List of tools your agent can use, with their configurationsagent_card: Metadata describing your agent's capabilities ","version":"Next","tagName":"h3"},{"title":"Step 4: The Lifecycle Function​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#step-4-the-lifecycle-function","content":" Lifecycle functions are completely optional but useful for managing resources. They run when the agent starts and stops. The lifecycle file is not automatically created, so you need to create it manually: touch src/my_hello_agent/lifecycle.py # src/my_hello_agent/lifecycle.py """ Lifecycle functions for the Hello World agent. """ from typing import Any, Dict from pydantic import BaseModel, Field from solace_ai_connector.common.log import log class HelloAgentInitConfig(BaseModel): """ Configuration model for the Hello Agent initialization. """ startup_message: str = Field(description="Message to log on startup") log_level: str = Field(default="INFO", description="Logging level for the agent") def initialize_hello_agent(host_component: Any, init_config: HelloAgentInitConfig): """ Initializes the Hello World agent. Args: host_component: The agent host component init_config: Validated initialization configuration """ log_identifier = f"[{host_component.agent_name}:init]" log.info(f"{log_identifier} Starting Hello Agent initialization...") # Log the startup message from config log.info(f"{log_identifier} {init_config.startup_message}") # You could initialize shared resources here, such as: # - Database connections # - API clients # - Caches or shared data structures # Store any shared state in the agent host_component.set_agent_specific_state("initialized_at", "2024-01-01T00:00:00Z") host_component.set_agent_specific_state("greeting_count", 0) log.info(f"{log_identifier} Hello Agent initialization completed successfully") def cleanup_hello_agent(host_component: Any): """ Cleans up resources when the Hello World agent shuts down. Args: host_component: The agent host component """ log_identifier = f"[{host_component.agent_name}:cleanup]" log.info(f"{log_identifier} Starting Hello Agent cleanup...") # Retrieve any shared state greeting_count = host_component.get_agent_specific_state("greeting_count", 0) log.info(f"{log_identifier} Agent processed {greeting_count} greetings during its lifetime") # Clean up resources here, such as: # - Closing database connections # - Shutting down background tasks # - Saving final state log.info(f"{log_identifier} Hello Agent cleanup completed") Key Points: Pydantic Models: Use Pydantic for configuration validationShared State: Store data that persists across tool callsResource Management: Initialize connections in init, clean up in cleanup ","version":"Next","tagName":"h3"},{"title":"Advanced Concepts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#advanced-concepts","content":" ","version":"Next","tagName":"h2"},{"title":"Working with Artifacts​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#working-with-artifacts","content":" You can enhance our hello tool to save greetings to a file using Solace Agent Mesh's artifact service: from datetime import datetime from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata async def hello_tool_with_artifact( name: str, save_to_file: bool = False, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user and optionally saves the greeting to a file. """ log_identifier = "[HelloToolWithArtifact]" # Generate greeting (same as before) greeting_prefix = tool_config.get("greeting_prefix", "Hello") if tool_config else "Hello" greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" result = { "status": "success", "message": greeting_message, "greeted_name": name } # Save to artifact if requested if save_to_file and tool_context: try: # Prepare content timestamp = datetime.now(timezone.utc) filename = f"greeting_{name}_{timestamp}.txt" content = f"Greeting: {greeting_message}\\nTimestamp: {timestamp}\\n" # Save artifact artifact_service = tool_context._invocation_context.artifact_service await save_artifact_with_metadata( artifact_service=artifact_service, app_name=tool_context._invocation_context.app_name, user_id=tool_context._invocation_context.user_id, session_id=tool_context._invocation_context.session.id, filename=filename, content_bytes=content.encode('utf-8'), mime_type="application/json", metadata_dict={ "description": "Greeting message", "source": "Greeting Agent", }, timestamp=timestamp ) result["artifact_saved"] = filename log.info(f"{log_identifier} Saved greeting to artifact: {filename}") except Exception as e: log.error(f"{log_identifier} Failed to save artifact: {e}") result["artifact_error"] = str(e) return result ","version":"Next","tagName":"h3"},{"title":"Using Multiple Tool Configurations​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#using-multiple-tool-configurations","content":" You can configure the same tool function multiple times with different settings: tools: # Formal greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "formal_greeting" tool_config: greeting_prefix: "Good day" # Casual greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "casual_greeting" tool_config: greeting_prefix: "Hey there" # Enthusiastic greeting - tool_type: python component_module: "my_hello_agent.tools" function_name: "hello_tool" tool_name: "enthusiastic_greeting" tool_config: greeting_prefix: "Hello and welcome" This gives your agent multiple greeting styles to choose from based on the context. ","version":"Next","tagName":"h3"},{"title":"Running Your Agent​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#running-your-agent","content":" To run a plugin agent, you first need to package and install it as a plugin. Quick Debug For debugging or isolated development testing, you can run your agent from the src directory directly using the Solace Agent Mesh CLI. cd src sam run ../config.yaml Changing to the src directory allows the module path to be set correctly so that Solace Agent Mesh can find your functions without your having to install them in your python environment as a plugin package. To properly instantiate your plugin agent, first build the plugin. The following command will produce a python wheel file under dist directory: sam plugin build Check into your Solace Agent Mesh project directory, and add the plugin wheel with a given name: sam plugin add my-first-weather-agent --plugin PATH/TO/weather-agent/dist/weather-agent.whl note Using the sam plugin add command installs your plugin as a python dependency into your python environment. This also means changing the source code without reinstalling the plugin will not reflect the changes. Now, you can run the complete Solace Agent Mesh application along with your newly added agent: sam run Alternatively, only run the newly added agent using sam run configs/agents/my-first-weather-agent.yaml ","version":"Next","tagName":"h2"},{"title":"Architecture Overview​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#architecture-overview","content":" Here is how all the pieces fit together: ","version":"Next","tagName":"h2"},{"title":"Best Practices​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#best-practices","content":" ","version":"Next","tagName":"h2"},{"title":"Tool Design​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#tool-design","content":" Single Responsibility: Each tool should do one thing wellClear Documentation: Write detailed docstrings for your toolsError Handling: Always return structured error responsesLogging: Use consistent logging for debugging and monitoring ","version":"Next","tagName":"h3"},{"title":"Configuration​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#configuration","content":" Environment Variables: Use environment variables for sensitive dataValidation: Use Pydantic models for configuration validationDocumentation: Comment your configuration files thoroughly ","version":"Next","tagName":"h3"},{"title":"Testing​","type":1,"pageTitle":"Creating Agents","url":"/solace-agent-mesh/docs/documentation/user-guide/create-agents#testing","content":" Unit Tests: Test your tool functions independentlyIntegration Tests: Test your agent with real Solace Agent Mesh infrastructureMock Dependencies: Mock external services for reliable testing ","version":"Next","tagName":"h3"},{"title":"Creating Python Tools","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools","content":"","keywords":"","version":"Next"},{"title":"Tool Creation Patterns​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#tool-creation-patterns","content":" There are three primary patterns for creating Python tools, ranging from simple to advanced. You can choose the best pattern for your needs, and even mix and match them within the same project. Pattern\tBest For\tKey FeatureFunction-Based\tSimple, self-contained tools with static inputs.\tQuick and easy; uses function signature. Single DynamicTool Class\tTools that require complex logic or a programmatically defined interface.\tFull control over the tool's definition. DynamicToolProvider Class\tGenerating multiple related tools from a single, configurable source.\tMaximum scalability and code reuse. All three patterns are configured in your agent's YAML file under the tools list with tool_type: python. ","version":"Next","tagName":"h2"},{"title":"Pattern 1: Simple Function-Based Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-1-simple-function-based-tools","content":" This is the most straightforward way to create a custom tool. You define a standard Python async function, and Solace Agent Mesh automatically introspects its signature and docstring to create the tool definition for the LLM. ","version":"Next","tagName":"h2"},{"title":"Step 1: Write the Tool Function​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-write-the-tool-function","content":" Create a Python file (e.g., src/my_agent/tools.py) and define your tool. # src/my_agent/tools.py from typing import Any, Dict, Optional from google.adk.tools import ToolContext async def greet_user( name: str, tool_context: Optional[ToolContext] = None, tool_config: Optional[Dict[str, Any]] = None ) -> Dict[str, Any]: """ Greets a user with a personalized message. Args: name: The name of the person to greet. Returns: A dictionary with the greeting message. """ greeting_prefix = "Hello" if tool_config: greeting_prefix = tool_config.get("greeting_prefix", "Hello") greeting_message = f"{greeting_prefix}, {name}! Welcome to Solace Agent Mesh!" return { "status": "success", "message": greeting_message } Key Requirements: The function must be async def.The function's docstring is used as the tool's description for the LLM.Type hints (str, int, bool) are used to generate the parameter schema.The function should accept tool_context and tool_config as optional keyword arguments to receive framework context and YAML configuration. ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Tool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-tool","content":" In your agent's YAML configuration, add a tool_type: python block and point it to your function. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.tools" function_name: "greet_user" tool_config: greeting_prefix: "Greetings" component_module: The Python module path to your tools file.function_name: The exact name of the function to load.tool_config: An optional dictionary passed to your tool at runtime. ","version":"Next","tagName":"h3"},{"title":"Pattern 2: Advanced Single-Class Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-2-advanced-single-class-tools","content":" For tools that require more complex logic—such as defining their interface programmatically based on configuration—you can use a class that inherits from DynamicTool. ","version":"Next","tagName":"h2"},{"title":"Step 1: Create the DynamicTool Class​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-create-the-dynamictool-class","content":" Instead of a function, define a class that implements the DynamicTool abstract base class. # src/my_agent/tools.py from typing import Optional, Dict, Any from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool class WeatherTool(DynamicTool): """A dynamic tool that fetches current weather information.""" @property def tool_name(self) -> str: return "get_current_weather" @property def tool_description(self) -> str: return "Get the current weather for a specified location." @property def parameters_schema(self) -> adk_types.Schema: # Programmatically define the tool's parameters return adk_types.Schema( type=adk_types.Type.OBJECT, properties={ "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."), "units": adk_types.Schema(type=adk_types.Type.STRING, enum=["celsius", "fahrenheit"], nullable=True), }, required=["location"], ) async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]: location = args["location"] # Access config via self.tool_config api_key = self.tool_config.get("api_key") if not api_key: return {"status": "error", "message": "API key not configured"} # ... implementation to call weather API ... return {"status": "success", "weather": "Sunny"} ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Tool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-tool-1","content":" The YAML configuration is very similar. You can either specify the class_name or let Solace Agent Mesh auto-discover it if it's the only DynamicTool in the module. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.tools" # class_name: WeatherTool # Optional if it's the only one tool_config: api_key: ${WEATHER_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Pattern 3: The Tool Provider Factory​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#pattern-3-the-tool-provider-factory","content":" This is the most powerful pattern, designed for generating multiple, related tools from a single module and configuration block. It's perfect for creating toolsets based on external schemas, database tables, or other dynamic sources. ","version":"Next","tagName":"h2"},{"title":"Step 1: Create the Provider and Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-1-create-the-provider-and-tools","content":" In your tools module, you define your DynamicTool classes as before, but you also create a provider class that inherits from DynamicToolProvider. This provider acts as a factory. You can also use the @register_tool decorator on simple functions to have them automatically included by the provider. # src/my_agent/database_tools.py from typing import Optional, Dict, Any, List from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider # --- Tool Implementations --- class DatabaseQueryTool(DynamicTool): # ... (implementation as in previous examples) ... pass class DatabaseSchemaTool(DynamicTool): # ... (implementation as in previous examples) ... pass # --- Tool Provider Implementation --- class DatabaseToolProvider(DynamicToolProvider): """A factory that creates all database-related tools.""" # Use a decorator for a simple, function-based tool def create_tools(self, tool_config: Optional[dict] = None) -> List[DynamicTool]: """ Generates a list of all database tools, passing the shared configuration to each one. """ # 1. Create tools from any decorated functions in this module tools = self._create_tools_from_decorators(tool_config) # 2. Programmatically create and add more complex tools if tool_config and tool_config.get("connection_string"): tools.append(DatabaseQueryTool(tool_config=tool_config)) tools.append(DatabaseSchemaTool(tool_config=tool_config)) return tools # NOTE that you must use the decorator outside of any class with the provider's class name. @DatabaseToolProvider.register_tool async def get_database_server_version(tool_config: dict, **kwargs) -> dict: """Returns the version of the connected PostgreSQL server.""" # ... implementation ... return {"version": "PostgreSQL 15.3"} ","version":"Next","tagName":"h3"},{"title":"Step 2: Configure the Provider​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#step-2-configure-the-provider","content":" You only need a single YAML block. Solace Agent Mesh will automatically detect the DynamicToolProvider and use it to load all the tools it generates. # In your agent's app_config: tools: # This single block loads get_database_server_version, # execute_database_query, and get_database_schema. - tool_type: python component_module: "my_agent.database_tools" tool_config: connection_string: ${DB_CONNECTION_STRING} max_rows: 1000 This approach is incredibly scalable, as one configuration entry can bootstrap an entire suite of dynamically generated tools. ","version":"Next","tagName":"h3"},{"title":"Managing Tool Lifecycles with init and cleanup​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#managing-tool-lifecycles-with-init-and-cleanup","content":" For tools that need to manage resources—such as database connections, API clients, or temporary files—Solace Agent Mesh provides optional init and cleanup lifecycle hooks. These allow you to run code when the agent starts up and shuts down, ensuring that resources are acquired and released gracefully. There are two ways to define these hooks: YAML-based (init_function, cleanup_function): A flexible method that works for any Python tool, including simple function-based ones.Class-based (init, cleanup methods): The idiomatic and recommended way for DynamicTool and DynamicToolProvider classes. ","version":"Next","tagName":"h2"},{"title":"YAML-Based Lifecycle Hooks​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#yaml-based-lifecycle-hooks","content":" You can add init_function and cleanup_function to any Python tool's configuration in your agent's YAML. The lifecycle functions must be defined in the same module as the tool itself. Step 1: Define the Tool and Hook Functions​ In your tool's Python file (e.g., src/my_agent/db_tools.py), define the tool function and its corresponding init and cleanup functions. These functions must be async and will receive the agent component instance and the tool's configuration model object as arguments. # src/my_agent/db_tools.py from solace_agent_mesh.agent.sac.component import SamAgentComponent from solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig from google.adk.tools import ToolContext from typing import Dict, Any # --- Lifecycle Hooks --- async def initialize_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig): """Initializes a database connection and stores it for the agent to use.""" print("INFO: Initializing database connection...") # In a real scenario, you would create a client instance db_client = {"connection_string": tool_config_model.tool_config.get("connection_string")} # Store the client in a shared state accessible by the component component.set_agent_specific_state("db_client", db_client) print("INFO: Database client initialized.") async def close_db_connection(component: SamAgentComponent, tool_config_model: AnyToolConfig): """Retrieves and closes the database connection.""" print("INFO: Closing database connection...") db_client = component.get_agent_specific_state("db_client") if db_client: # In a real scenario, you would call db_client.close() print("INFO: Database connection closed.") # --- Tool Function --- async def query_database(query: str, tool_context: ToolContext, **kwargs) -> Dict[str, Any]: """Queries the database using the initialized connection.""" host_component = tool_context._invocation_context.agent.host_component db_client = host_component.get_agent_specific_state("db_client") if not db_client: return {"error": "Database connection not initialized."} # ... use db_client to run query ... return {"result": "some data"} Step 2: Configure the Hooks in YAML​ In your YAML configuration, reference the lifecycle functions by name. The framework will automatically look for them in the component_module. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.db_tools" function_name: "query_database" tool_config: connection_string: "postgresql://user:pass@host/db" # Initialize the tool on startup init_function: "initialize_db_connection" # Clean up the tool on shutdown cleanup_function: "close_db_connection" ","version":"Next","tagName":"h3"},{"title":"Class-Based Lifecycle Methods (for DynamicTool)​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#class-based-lifecycle-methods-for-dynamictool","content":" For tools built with DynamicTool or DynamicToolProvider, the recommended approach is to override the init and cleanup methods directly within the class. This co-locates the entire tool's logic and improves encapsulation. Example: Adding Lifecycle Methods to a DynamicTool Here, we extend a DynamicTool to manage its own API client. # src/my_agent/api_tool.py from solace_agent_mesh.agent.sac.component import SamAgentComponent from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool from solace_agent_mesh.agent.tools.tool_config_types import AnyToolConfig # Assume WeatherApiClient is a custom class for an external service from my_agent.api_client import WeatherApiClient class WeatherTool(DynamicTool): """A dynamic tool that fetches weather and manages its own API client.""" async def init(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None: """Initializes the API client when the agent starts.""" print("INFO: Initializing Weather API client...") # self.tool_config is the validated Pydantic model or dict from YAML api_key = self.tool_config.get("api_key") self.api_client = WeatherApiClient(api_key=api_key) print("INFO: Weather API client initialized.") async def cleanup(self, component: "SamAgentComponent", tool_config: "AnyToolConfig") -> None: """Closes the API client connection when the agent shuts down.""" print("INFO: Closing Weather API client...") if hasattr(self, "api_client"): await self.api_client.close() print("INFO: Weather API client closed.") # ... other required properties like tool_name, tool_description, etc. ... async def _run_async_impl(self, args: dict, **kwargs) -> dict: """Uses the initialized client to perform its task.""" location = args.get("location") if not hasattr(self, "api_client"): return {"error": "API client not initialized. Check lifecycle hooks."} weather_data = await self.api_client.get_weather(location) return {"weather": weather_data} The YAML configuration remains simple, as the lifecycle logic is now part of the tool's code. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.api_tool" class_name: "WeatherTool" tool_config: api_key: ${WEATHER_API_KEY} ","version":"Next","tagName":"h3"},{"title":"Execution Order and Guarantees​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#execution-order-and-guarantees","content":" It's important to understand the order in which lifecycle hooks are executed, especially if you mix both YAML-based and class-based methods for a single tool. Initialization (init): All init hooks are awaited during agent startup. A failure in any init hook will prevent the agent from starting. The YAML-based init_function is executed first.The class-based init() method is executed second. Cleanup (cleanup): All registered cleanup hooks are executed during agent shutdown. They run in LIFO (Last-In, First-Out) order relative to initialization. The class-based cleanup() method is executed first.The YAML-based cleanup_function is executed second. This LIFO order for cleanup is intuitive: the resource that was initialized last is the first one to be torn down. ","version":"Next","tagName":"h3"},{"title":"Adding Validated Configuration to Dynamic Tools​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#adding-validated-configuration-to-dynamic-tools","content":" For any class-based tool (DynamicTool or DynamicToolProvider) that requires configuration, this is the recommended pattern. By linking a Pydantic model to your tool class, you can add automatic validation and type safety to your tool_config. This provides several key benefits: Automatic Validation: The agent will fail to start if the YAML configuration doesn't match your model, providing clear error messages.Type Safety: Inside your tool, self.tool_config is a fully typed Pydantic object, not a dictionary, enabling autocompletion and preventing common errors.Self-Documentation: The Pydantic model itself serves as clear, machine-readable documentation for your tool's required configuration. ","version":"Next","tagName":"h2"},{"title":"Example 1: Using a Pydantic Model with a Single DynamicTool​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#example-1-using-a-pydantic-model-with-a-single-dynamictool","content":" This example shows how to add a validated configuration to a standalone DynamicTool class. Step 1: Define the Model and Tool Class​ In your tools file, define a pydantic.BaseModel for your configuration. Then, in your DynamicTool class, link to it using the config_model class attribute. # src/my_agent/weather_tools.py from typing import Dict, Any from pydantic import BaseModel, Field from google.genai import types as adk_types from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool # 1. Define the configuration model class WeatherConfig(BaseModel): api_key: str = Field(..., description="The API key for the weather service.") default_unit: str = Field(default="celsius", description="The default temperature unit.") # 2. Create a tool and link the config model class GetCurrentWeatherTool(DynamicTool): config_model = WeatherConfig def __init__(self, tool_config: WeatherConfig): super().__init__(tool_config) # self.tool_config is now a validated WeatherConfig instance # You can safely access attributes with type safety self.api_key = self.tool_config.api_key self.unit = self.tool_config.default_unit @property def tool_name(self) -> str: return "get_current_weather" @property def tool_description(self) -> str: return f"Get the current weather. The default unit is {self.unit}." @property def parameters_schema(self) -> adk_types.Schema: return adk_types.Schema( type=adk_types.Type.OBJECT, properties={ "location": adk_types.Schema(type=adk_types.Type.STRING, description="The city and state/country."), }, required=["location"], ) async def _run_async_impl(self, args: Dict[str, Any], **kwargs) -> Dict[str, Any]: # ... implementation using self.api_key ... return {"weather": f"Sunny in {args['location']}"} Step 2: Configure the Tool in YAML​ The YAML configuration remains simple. The framework handles the validation against your Pydantic model automatically. # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.weather_tools" # The framework will auto-discover the GetCurrentWeatherTool class tool_config: api_key: ${WEATHER_API_KEY} default_unit: "fahrenheit" # Optional, overrides the model's default If you were to forget api_key in the YAML, the agent would fail to start and print a clear error message indicating that the api_key field is required, making debugging configuration issues much easier. ","version":"Next","tagName":"h3"},{"title":"Example 2: Using a Pydantic Model with a DynamicToolProvider​","type":1,"pageTitle":"Creating Python Tools","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-python-tools#example-2-using-a-pydantic-model-with-a-dynamictoolprovider","content":" The same pattern applies to tool providers, allowing you to pass a validated, type-safe configuration object to your tool factory. Step 1: Define the Model and Provider Class​ # src/my_agent/weather_tools_provider.py from typing import List from pydantic import BaseModel, Field from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider # ... assume GetCurrentWeatherTool is defined in this file or imported ... # 1. Define the configuration model class WeatherProviderConfig(BaseModel): api_key: str = Field(..., description="The API key for the weather service.") default_unit: str = Field(default="celsius", description="The default temperature unit.") # 2. Create a provider and link the config model class WeatherToolProvider(DynamicToolProvider): config_model = WeatherProviderConfig def create_tools(self, tool_config: WeatherProviderConfig) -> List[DynamicTool]: # The framework passes a validated WeatherProviderConfig instance here return [ GetCurrentWeatherTool(tool_config=tool_config) # You could create other tools here that also use the config ] Step 2: Configure the Provider in YAML​ # In your agent's app_config: tools: - tool_type: python component_module: "my_agent.weather_tools_provider" # The framework will auto-discover the WeatherToolProvider tool_config: api_key: ${WEATHER_API_KEY} default_unit: "fahrenheit" # Optional, overrides the model's default ","version":"Next","tagName":"h3"},{"title":"Creating Service Providers","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers","content":"","keywords":"","version":"Next"},{"title":"Understanding Service Providers​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#understanding-service-providers","content":" Service Providers function as the abstraction layer between Solace Agent Mesh and enterprise data sources. They are implemented as Python classes that adhere to a specific abstract base class, enabling standardized interaction between Solace Agent Mesh components (Gateways and Agents) and the underlying data. There are two primary service provider interfaces: BaseIdentityService: Responsible for identity enrichment. This service is utilized by Gateways to augment the profile of an authenticated user with additional details (for example, full name, job title) based on their initial authentication claims.BaseEmployeeService: Responsible for general directory querying. This service is utilized by agents (for example, the EmployeeAgent) to execute lookups across the entire employee directory. ","version":"Next","tagName":"h2"},{"title":"The \"Dual-Role Provider\" Pattern​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#the-dual-role-provider-pattern","content":" In many enterprise systems, particularly HR platforms, the data source for identity enrichment and general employee queries is identical. To optimize development, Solace Agent Mesh promotes a "Dual-Role Provider" pattern. This pattern involves creating a single class that inherits from both BaseIdentityService and BaseEmployeeService. This consolidated class can then be configured to fulfill either or both roles, thereby reducing code duplication. ","version":"Next","tagName":"h2"},{"title":"Step-by-Step Implementation Guide​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-by-step-implementation-guide","content":" This section provides a walkthrough for creating a new provider for a fictional "CorpHR" system. ","version":"Next","tagName":"h2"},{"title":"Step 1: Establish the Plugin Structure​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-1-establish-the-plugin-structure","content":" The recommended structure for a custom service provider plugin should include a pyproject.toml for packaging and a src directory for the source code. sam plugin create my_corp_hr_provider --type custom ","version":"Next","tagName":"h3"},{"title":"Step 2: Define the Provider Class​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-2-define-the-provider-class","content":" Create a provider.py module and define the provider class, ensuring it inherits from both base service classes. # my_corp_hr_provider/provider.py # Import base classes from the Solace Agent Mesh framework try: from solace_agent_mesh.common.services.identity_service import BaseIdentityService from solace_agent_mesh.common.services.employee_service import BaseEmployeeService except ImportError: # Fallback for local development environments from src.solace_agent_mesh.common.services.identity_service import BaseIdentityService from src.solace_agent_mesh.common.services.employee_service import BaseEmployeeService # Import any other necessary libraries, such as 'requests' or a proprietary SDK # from .corp_hr_sdk import CorpHR_SDK class CorpHRProvider(BaseIdentityService, BaseEmployeeService): """ A dual-role provider for the CorpHR system, implementing methods for both identity enrichment and employee directory services. """ def __init__(self, config): super().__init__(config) # Initialize the backend service/SDK client here. # It is best practice to implement this as a singleton to share # connection pools and cache. # self.corp_hr_sdk = CorpHR_SDK(api_key=config.get("api_key")) # --- BaseIdentityService Method Implementations --- async def get_user_profile(self, auth_claims): """Enrich the current user's profile based on their auth claims.""" # TODO: Implement logic to fetch user data from CorpHR pass async def search_users(self, query, limit=10): """Search for users, for features like @-mentions.""" # TODO: Implement user search logic against CorpHR pass # --- BaseEmployeeService Method Implementations --- async def get_employee_dataframe(self): """Return all employees as a pandas DataFrame for directory-wide queries.""" # TODO: Fetch all employee data and return as a DataFrame pass async def get_employee_profile(self, employee_id): """Get a single employee's full profile by their ID.""" # Note: This is a general directory lookup, distinct from get_user_profile. # TODO: Implement single employee lookup pass async def get_time_off_data(self, employee_id): """Get an employee's raw time off data.""" # Example return format: # return [{'start': '2025-07-04', 'end': '2025-07-04', 'type': 'Holiday'}] # TODO: Implement time off data retrieval pass async def get_employee_profile_picture(self, employee_id): """Fetch a profile picture as a data URI string.""" # Example return format: "data:image/jpeg;base64,..." # TODO: Implement profile picture fetching pass ","version":"Next","tagName":"h3"},{"title":"Step 3: Map to the Canonical Employee Schema​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-3-map-to-the-canonical-employee-schema","content":" When implementing the service methods, it is mandatory to map the data from the source system to Solace Agent Mesh's canonical employee schema. This ensures data consistency and interoperability with all tools and components across the mesh. Field Name\tData Type\tDescriptionid\tstring\tA unique, stable, and lowercase identifier (e.g., email, GUID). displayName\tstring\tThe employee's full name for display purposes. workEmail\tstring\tThe employee's primary work email address. jobTitle\tstring\tThe employee's official job title. department\tstring\tThe department to which the employee belongs. location\tstring\tThe physical or regional location of the employee. supervisorId\tstring\tThe unique id of the employee's direct manager. hireDate\tstring\tThe date the employee was hired (ISO 8601: YYYY-MM-DD). mobilePhone\tstring\tThe employee's mobile phone number (optional). info If a field is not available in the source system, return None or omit the key from the returned dictionary. ","version":"Next","tagName":"h3"},{"title":"Step 4: Register the Plugin​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#step-4-register-the-plugin","content":" To make the provider discoverable by Solace Agent Mesh, it must be registered as a plugin via entry points. 1. Add an entry point in pyproject.toml:The key assigned here (corphr) is used as the type identifier in YAML configurations. [project.entry-points."solace_agent_mesh.plugins"] corphr = "my_corp_hr_provider:info" 2. Define the info object in the plugin's __init__.py:This object points to the provider's class path and provides a brief description. # my_corp_hr_provider/__init__.py info = { "class_path": "my_corp_hr_provider.provider.CorpHRProvider", "description": "Identity and People Service provider for CorpHR.", } ","version":"Next","tagName":"h3"},{"title":"Configuring the Provider​","type":1,"pageTitle":"Creating Service Providers","url":"/solace-agent-mesh/docs/documentation/user-guide/creating-service-providers#configuring-the-provider","content":" Once the plugin is created and installed (for example, via pip install .), it can be configured in any Gateway or Agent app_config.yml. For a Gateway (Identity Service Role): app_config: identity_service: type: "corphr" # Matches the key in pyproject.toml api_key: "${CORPHR_API_KEY}" lookup_key: "email" # The field from auth_claims to use for lookup For an Agent (Employee Service Role):This example demonstrates configuring the provider for the employee_tools group. app_config: tools: - tool_type: builtin-group group_name: "employee_tools" config: type: "corphr" # Same provider, different role api_key: "${CORPHR_API_KEY}" ","version":"Next","tagName":"h2"},{"title":"Solace AI Event Connector","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector","content":"","keywords":"","version":"Next"},{"title":"Key Features​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#key-features","content":" Event Processing Pipeline: Creates flows consisting of input components, processing components, and output components.AI Model Integration: Built on LangChain and LiteLLM supporting various AI models and providers.Extensible Architecture: Supports custom plugins and components for specialized processing needs.Resilient Processing: Ensures reliable event handling with acknowledgment-based processing.Scalable Design: Supports parallel processing and multiple component instances. ","version":"Next","tagName":"h2"},{"title":"How It Works​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#how-it-works","content":" Solace AI Event Connector operates through a series of interconnected components: Flow Structure Each flow has one input componentMultiple processing componentsOne output componentComponents are connected via queues for buffering Component Processing Each component runs in its own threadProcesses one message at a timeSupports input transforms and selectionsCan be scaled with multiple instances for parallel processing Event Management Tracks events throughout the processing pipelineUses acknowledgment system for reliable deliveryEnsures no event loss during processing ","version":"Next","tagName":"h2"},{"title":"Configuration​","type":1,"pageTitle":"Solace AI Event Connector","url":"/solace-agent-mesh/docs/documentation/user-guide/solace-ai-connector#configuration","content":" The Solace AI Event Connector is configured through YAML files that allow you to: Define flow components and their sequenceSet queue depths between componentsConfigure the number of parallel instancesSpecify input/output parametersDefine processing logic and transformationsPass the source path for the custom python components For more information about the connector, see Solace AI Event Connector. ","version":"Next","tagName":"h2"},{"title":"Structure","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/structure","content":"","keywords":"","version":"Next"},{"title":"Project Structure​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#project-structure","content":" A fresh Solace Agent Mesh project follows this structure: my-sam-project/ ├── configs/ │ ├── shared_config.yaml # Shared broker, models, and services config │ ├── agents/ │ │ └── main_orchestrator.yaml # Default orchestrator agent │ └── gateways/ │ │ └── webui.yaml # Default web UI gateway │ ├── plugins/ ├── src/ # Custom Python components (optional) │ └── __init__.py ","version":"Next","tagName":"h2"},{"title":"Configuration Organization​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#configuration-organization","content":" ","version":"Next","tagName":"h2"},{"title":"Directory Structure​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#directory-structure","content":" The configs/ directory uses a logical organization: agents/ - Contains agent configuration filesgateways/ - Contains gateway configuration filesplugins/ - Contains plugin configuration files (created when plugins are added) Further subdirectories can be created within agents/, gateways/, and plugins/ to organize configurations by functionality or purpose. File Discovery The CLI automatically crawls through the configs directory to find configuration files. Files that start with _ (underscore) or shared_config are ignored and not processed by the CLI. For example: _example_agent.yaml is ignoredshared_config_for_db_agents.yaml is ignored (Can still be included in other config files using !include directive) ","version":"Next","tagName":"h3"},{"title":"Shared Configuration​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#shared-configuration","content":" The shared_config.yaml file is the foundation of your project configuration. It contains common elements that are reused across all agents and gateways using YAML anchors: Broker Connection: Solace PubSub+ broker settings for A2A communicationModel Definitions: LLM model configurations (planning, general, multimodal, etc.)Services: Artifact service, session service, and data tools configuration This shared configuration approach eliminates duplication and ensures consistency across your entire project. Each agent and gateway configuration file references these shared elements using YAML anchor syntax (*reference_name). Further values can be added to the shared configuration file as needed, and they are available to all agents and gateways that include it. ","version":"Next","tagName":"h3"},{"title":"YAML Configuration Files​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#yaml-configuration-files","content":" Each configuration file defines one [recommended] or more applications that can be run independently. The framework supports: Agent Applications: A2A-enabled agents that use Google ADK runtime and Solace Agent Mesh frameworkGateway Applications: Protocol translators that bridge external interfaces to adopted A2A protocolPlugin Applications: Specialized components that extend framework capabilities ","version":"Next","tagName":"h2"},{"title":"Configuration Management​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#configuration-management","content":" Environment Variables: Configuration values use environment variables for flexibility across environmentsShared Configuration: Common settings are defined once in shared_config.yaml and referenced using YAML anchors (& and *)Automatic Generation: The sam add agent, sam add gateway, and sam plugin add commands automatically generate appropriate configuration filesStandalone Execution: Each configuration file can be run independently using sam run <config-file> ","version":"Next","tagName":"h2"},{"title":"Python Components​","type":1,"pageTitle":"Structure","url":"/solace-agent-mesh/docs/documentation/user-guide/structure#python-components","content":" While most functionality is configured through YAML, custom Python components can be added to the src/ directory when needed. The framework provides base classes for extending functionality such as custom agent tools, gateway protocol handlers, and service providers. ","version":"Next","tagName":"h2"},{"title":"Create Gateways","type":0,"sectionRef":"#","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways","content":"","keywords":"","version":"Next"},{"title":"What Are Gateways?​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#what-are-gateways","content":" A gateway acts as a translator and coordinator that: Receives events, messages, or data from external systemsAuthenticates and authorizes external interactionsTranslates external data into standardized A2A Task formatSubmits tasks to target A2A agents for processingReceives responses and status updates from agentsTranslates A2A responses back to external system formatSends results back to the originating external system ","version":"Next","tagName":"h2"},{"title":"Quick Start: Creating Your First Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#quick-start-creating-your-first-gateway","content":" You can create a gateway directly using the Solace Agent Mesh CLI sam add gateway: sam add gateway my-custom-gateway This command: Launches an interactive setup (or use --gui for browser-based configuration)Generates the necessary files and configurationSets up the basic gateway structure ","version":"Next","tagName":"h2"},{"title":"CLI Options​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#cli-options","content":" You can customize the gateway creation with these options: sam add gateway my-gateway \\ --namespace "myorg/dev" \\ --gateway-id "my-custom-gw-id" \\ --artifact-service-type "filesystem" \\ --artifact-service-base-path "var/data/my-gateway-artifacts" \\ --system-purpose "This gateway processes external data feeds" \\ --response-format "Agents should respond with structured JSON" For a complete list of options, run: sam add gateway --help ","version":"Next","tagName":"h3"},{"title":"Gateway Architecture​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-architecture","content":" Every Solace Agent Mesh gateway consists of two main components: ","version":"Next","tagName":"h2"},{"title":"Gateway App​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-app","content":" Gateway App (app.py): Defines configuration schemaManages gateway-level settingsLinks to the gateway component ","version":"Next","tagName":"h3"},{"title":"Gateway Component​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#gateway-component","content":" Gateway Component (component.py): Contains the core business logicHandles external system integrationImplements required abstract methods ","version":"Next","tagName":"h3"},{"title":"Step-by-Step Tutorial​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-by-step-tutorial","content":" Let's create a practical example, Directory Monitor Gateway, a gateway that monitors a directory for new files and sends them to agents for processing. You can create a gateway using either sam add gateway <your_gateway_name> command directly or sam plugin create <your_gateway_plugin_name> --type gateway command as gateway plugin. Gateway as plugin Gateways can also be implemented as plugins. This allows you to easily package your gateway logic and reuse it across different projects. To create a plugin of type gateway, use the sam plugin create <your_gateway_plugin_name> --type gateway command. For a complete list of options, run: sam plugin create --help To create a gateway instance based on a plugin, use the sam plugin add <your_gateway_name> --plugin <your_gateway_plugin> command. For a complete list of options, run: sam plugin add --help Although the specific directory structure may differ from standalone gateways, the core concepts remain the same. The core files remain the same: app.py, component.py, and the YAML configuration file. ","version":"Next","tagName":"h2"},{"title":"Step 1: Generate the Gateway Structure​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-1-generate-the-gateway-structure","content":" This tutorial shows you how to create a new gateway with the sam add gateway command. sam add gateway dir-monitor This creates: configs/gateways/dir_monitor_config.yaml - Configuration filesrc/dir_monitor/app.py - Gateway app classsrc/dir_monitor/component.py - Gateway component class ","version":"Next","tagName":"h3"},{"title":"Step 2: Define Configuration Schema​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-2-define-configuration-schema","content":" Define Configuration Schema (app.py) # src/dir_monitor/app.py from typing import Any, Dict, List, Type from solace_ai_connector.common.log import log from solace_agent_mesh.gateway.base.app import BaseGatewayApp from solace_agent_mesh.gateway.base.component import BaseGatewayComponent from .component import DirMonitorGatewayComponent # Module info required by SAC info = { "class_name": "DirMonitorGatewayApp", "description": "Custom App class for the A2A DirMonitor Gateway.", } class DirMonitorGatewayApp(BaseGatewayApp): """ Directory Monitor Gateway App Extends BaseGatewayApp with directory monitoring specific configuration. """ # Define gateway-specific configuration parameters SPECIFIC_APP_SCHEMA_PARAMS: List[Dict[str, Any]] = [ { "name": "directory_path", "required": True, "type": "string", "description": "The directory path to monitor for changes.", }, { "name": "target_agent_name", "required": False, "type": "string", "default": "OrchestratorAgent", "description": "The A2A agent to send tasks to.", }, { "name": "default_user_identity", "required": False, "type": "string", "default": "dir_monitor_user", "description": "Default user identity for A2A tasks.", }, { "name": "error_directory_path", "required": True, "type": "string", "description": "Directory to move files if processing fails.", }, ] def __init__(self, app_info: Dict[str, Any], **kwargs): log_prefix = app_info.get("name", "DirMonitorGatewayApp") log.info("[%s] Initializing Directory Monitor Gateway App...", log_prefix) super().__init__(app_info=app_info, **kwargs) log.info("[%s] Directory Monitor Gateway App initialized.", self.name) def _get_gateway_component_class(self) -> Type[BaseGatewayComponent]: """Returns the gateway component class for this app.""" return DirMonitorGatewayComponent ","version":"Next","tagName":"h3"},{"title":"Step 3: Implement Core Logic​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-3-implement-core-logic","content":" Implement Core Logic (component.py) # src/dir_monitor/component.py import asyncio import os import shutil import mimetypes import threading from typing import Any, Dict, List, Optional, Tuple, Union from datetime import datetime, timezone from solace_ai_connector.common.log import log # Import watchdog for file system monitoring try: from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler WATCHDOG_AVAILABLE = True except ImportError: WATCHDOG_AVAILABLE = False Observer = None FileSystemEventHandler = None from solace_agent_mesh.gateway.base.component import BaseGatewayComponent from solace_agent_mesh.common.types import ( Part as A2APart, TextPart, FilePart, Task, TaskStatusUpdateEvent, TaskArtifactUpdateEvent, JSONRPCError, FileContent, ) from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata # Component info info = { "class_name": "DirMonitorGatewayComponent", "description": "Monitors directories for new files and processes them via A2A agents.", } class DirMonitorGatewayComponent(BaseGatewayComponent): """ Directory Monitor Gateway Component Watches a directory and creates A2A tasks for new files. """ def __init__(self, **kwargs: Any): super().__init__(**kwargs) log.info("%s Initializing Directory Monitor Gateway Component...", self.log_identifier) # Check if watchdog is available if not WATCHDOG_AVAILABLE: log.error("%s Watchdog library not found. Install with: pip install watchdog", self.log_identifier) raise ImportError("Watchdog library required for directory monitoring") # Load configuration try: self.directory_path = self.get_config("directory_path") self.target_agent_name = self.get_config("target_agent_name", "OrchestratorAgent") self.default_user_identity_id = self.get_config("default_user_identity", "dir_monitor_user") self.error_directory_path = self.get_config("error_directory_path") # Validate directories if not os.path.isdir(self.directory_path): raise ValueError(f"Monitor directory not found: {self.directory_path}") os.makedirs(self.error_directory_path, exist_ok=True) log.info("%s Monitoring: %s, Error dir: %s", self.log_identifier, self.directory_path, self.error_directory_path) except Exception as e: log.error("%s Configuration error: %s", self.log_identifier, e) raise # Initialize monitoring components self.observer: Optional[Observer] = None self.watchdog_thread: Optional[threading.Thread] = None log.info("%s Directory Monitor Gateway Component initialized.", self.log_identifier) class DirWatchEventHandler(FileSystemEventHandler): """Handles file system events from Watchdog.""" def __init__(self, component_ref: 'DirMonitorGatewayComponent'): super().__init__() self.component_ref = component_ref self.log_identifier = f"{component_ref.log_identifier}[FileHandler]" def on_created(self, event): if event.is_directory: return file_path = event.src_path log.info("%s New file detected: %s", self.log_identifier, file_path) # Bridge to async loop if self.component_ref.async_loop and self.component_ref.async_loop.is_running(): asyncio.run_coroutine_threadsafe( self.component_ref._process_new_file(file_path), self.component_ref.async_loop ) else: log.error("%s Async loop not available for file: %s", self.log_identifier, file_path) def generate_uuid(self) -> str: """Generate a unique identifier.""" import uuid return str(uuid.uuid4()) def _start_listener(self) -> None: """Start the directory monitoring listener.""" log_id_prefix = f"{self.log_identifier}[StartListener]" log.info("%s Starting directory monitor for: %s", log_id_prefix, self.directory_path) if not WATCHDOG_AVAILABLE: log.error("%s Watchdog not available", log_id_prefix) self.stop_signal.set() return # Set up file system observer self.observer = Observer() event_handler = self.DirWatchEventHandler(self) self.observer.schedule(event_handler, self.directory_path, recursive=False) # Start observer in separate thread self.watchdog_thread = threading.Thread( target=self._run_observer, name=f"{self.name}_WatchdogThread", daemon=True ) self.watchdog_thread.start() log.info("%s Directory monitor started", log_id_prefix) def _run_observer(self): """Run the watchdog observer.""" if not self.observer: return log_id_prefix = f"{self.log_identifier}[Observer]" try: log.info("%s Starting file system observer...", log_id_prefix) self.observer.start() # Wait for stop signal while not self.stop_signal.is_set() and self.observer.is_alive(): self.stop_signal.wait(timeout=1) log.info("%s Observer loop exiting", log_id_prefix) except Exception as e: log.exception("%s Observer error: %s", log_id_prefix, e) self.stop_signal.set() finally: if self.observer.is_alive(): self.observer.stop() self.observer.join() log.info("%s Observer stopped", log_id_prefix) def _stop_listener(self) -> None: """Stop the directory monitoring listener.""" log_id_prefix = f"{self.log_identifier}[StopListener]" log.info("%s Stopping directory monitor...", log_id_prefix) if self.observer and self.observer.is_alive(): log.info("%s Stopping observer...", log_id_prefix) self.observer.stop() if self.watchdog_thread and self.watchdog_thread.is_alive(): log.info("%s Joining observer thread...", log_id_prefix) self.watchdog_thread.join(timeout=5) if self.watchdog_thread.is_alive(): log.warning("%s Observer thread did not join cleanly", log_id_prefix) log.info("%s Directory monitor stopped", log_id_prefix) async def _process_new_file(self, file_path: str): """Process a newly detected file.""" log_id_prefix = f"{self.log_identifier}[ProcessFile:{os.path.basename(file_path)}]" log.info("%s Processing new file: %s", log_id_prefix, file_path) error_context = { "file_path": file_path, "a2a_session_id": f"dir_monitor-error-{self.generate_uuid()}" } try: # Step 1: Authenticate and enrich user user_identity_profile = await self.authenticate_and_enrich_user(file_path) if not user_identity_profile: log.error("%s Authentication failed for file: %s", log_id_prefix, file_path) error_obj = JSONRPCError(code=-32001, message="Authentication failed") await self._send_error_to_external(error_context, error_obj) return # Step 2: Translate external input to A2A format target_agent_name, a2a_parts, external_request_context = await self._translate_external_input( file_path, user_identity_profile ) if not target_agent_name or not a2a_parts: log.error("%s Failed to translate file to A2A task: %s", log_id_prefix, file_path) error_obj = JSONRPCError(code=-32002, message="Failed to translate file to A2A task") final_error_context = {**error_context, **external_request_context} await self._send_error_to_external(final_error_context, error_obj) return # Step 3: Submit A2A task log.info("%s Submitting A2A task for file: %s to agent: %s", log_id_prefix, file_path, target_agent_name) await self.submit_a2a_task( target_agent_name=target_agent_name, a2a_parts=a2a_parts, external_request_context=external_request_context, user_identity=user_identity_profile ) log.info("%s A2A task submitted for file: %s", log_id_prefix, file_path) except FileNotFoundError: log.error("%s File not found during processing: %s", log_id_prefix, file_path) except Exception as e: log.exception("%s Unexpected error processing file %s: %s", log_id_prefix, file_path, e) error_obj = JSONRPCError(code=-32000, message=f"Unexpected error: {e}") await self._send_error_to_external(error_context, error_obj) async def _extract_initial_claims(self, external_event_data: Any) -> Optional[Dict[str, Any]]: """Extract user identity claims from file event.""" file_path = str(external_event_data) log_id_prefix = f"{self.log_identifier}[ExtractClaims:{os.path.basename(file_path)}]" claims = { "id": self.default_user_identity_id, "source": "dir_monitor", "file_path": file_path } log.debug("%s Extracted claims for file %s: %s", log_id_prefix, file_path, claims) return claims async def _translate_external_input( self, external_event_data: Any, authenticated_user_identity: Dict[str, Any] ) -> Tuple[Optional[str], List[A2APart], Dict[str, Any]]: """Translate file event to A2A task format.""" file_path = str(external_event_data) log_id_prefix = f"{self.log_identifier}[TranslateInput:{os.path.basename(file_path)}]" user_id_for_a2a = authenticated_user_identity.get("id", self.default_user_identity_id) a2a_session_id = f"dir_monitor-session-{self.generate_uuid()}" # Prepare external request context external_request_context: Dict[str, Any] = { "file_path": file_path, "user_id_for_a2a": user_id_for_a2a, "app_name_for_artifacts": self.gateway_id, "user_id_for_artifacts": user_id_for_a2a, "a2a_session_id": a2a_session_id, } a2a_parts: List[A2APart] = [] try: # Check if file exists if not os.path.exists(file_path): log.error("%s File does not exist: %s", log_id_prefix, file_path) raise FileNotFoundError(f"File not found: {file_path}") # Read file content with open(file_path, "rb") as f: content_bytes = f.read() # Determine MIME type mime_type, _ = mimetypes.guess_type(file_path) if mime_type is None: mime_type = "application/octet-stream" # Save file as artifact if not self.shared_artifact_service: log.error("%s Artifact service not available for file: %s", log_id_prefix, os.path.basename(file_path)) return None, [], external_request_context artifact_metadata = { "source": "dir_monitor_gateway", "original_filename": os.path.basename(file_path), "detected_mime_type": mime_type, "processing_timestamp_utc": datetime.now(timezone.utc).isoformat(), } log.debug("%s Saving artifact for file: %s", log_id_prefix, file_path) save_result = await save_artifact_with_metadata( artifact_service=self.shared_artifact_service, app_name=self.gateway_id, user_id=str(user_id_for_a2a), session_id=a2a_session_id, filename=os.path.basename(file_path), content_bytes=content_bytes, mime_type=mime_type, metadata_dict=artifact_metadata, timestamp=datetime.now(timezone.utc), ) if save_result["status"] not in ["success", "partial_success"]: log.error("%s Failed to save file as artifact: %s", log_id_prefix, save_result.get("message")) return None, [], external_request_context # Create artifact URI data_version = save_result.get("data_version", 0) artifact_uri = f"artifact://{self.gateway_id}/{str(user_id_for_a2a)}/{a2a_session_id}/{os.path.basename(file_path)}?version={data_version}" log.info("%s Saved file as artifact: %s", log_id_prefix, artifact_uri) # Create A2A parts file_content_obj = FileContent( name=os.path.basename(file_path), uri=artifact_uri, mimeType=mime_type ) a2a_parts.append(FilePart(file=file_content_obj)) a2a_parts.append(TextPart( text=f"Please analyze and summarize the content of: {os.path.basename(file_path)}" )) log.info("%s Successfully translated file %s into A2A parts", log_id_prefix, file_path) return self.target_agent_name, a2a_parts, external_request_context except Exception as e: log.exception("%s Error translating file %s: %s", log_id_prefix, file_path, e) return None, [], external_request_context async def _send_final_response_to_external( self, external_request_context: Dict[str, Any], task_data: Task ) -> None: """Handle final response from A2A agent.""" log_id_prefix = f"{self.log_identifier}[SendFinalResponse]" file_path = external_request_context.get("file_path", "Unknown file") task_id = task_data.id # Extract summary from response summary_text = "Summary not available." if task_data.status and task_data.status.message and task_data.status.message.parts: for part in task_data.status.message.parts: if isinstance(part, TextPart): summary_text = part.text break log.info("%s Task %s completed for file '%s'. Status: %s", log_id_prefix, task_id, os.path.basename(file_path), task_data.status.state if task_data.status else "Unknown") log.info("%s Summary: %s", log_id_prefix, summary_text[:200] + "..." if len(summary_text) > 200 else summary_text) async def _send_error_to_external( self, external_request_context: Dict[str, Any], error_data: JSONRPCError ) -> None: """Handle errors by moving files to error directory.""" log_id_prefix = f"{self.log_identifier}[SendError]" file_path = external_request_context.get("file_path") log.error("%s A2A Error for file '%s'. Code: %s, Message: %s", log_id_prefix, os.path.basename(file_path) if file_path else "Unknown file", error_data.code, error_data.message) # Move problematic file to error directory if file_path and os.path.exists(file_path): try: os.makedirs(self.error_directory_path, exist_ok=True) base_name = os.path.basename(file_path) error_file_path = os.path.join(self.error_directory_path, base_name) # Handle filename conflicts counter = 0 while os.path.exists(error_file_path): counter += 1 name, ext = os.path.splitext(base_name) error_file_path = os.path.join(self.error_directory_path, f"{name}_error_{counter}{ext}") shutil.move(file_path, error_file_path) log.info("%s Moved problematic file %s to %s", log_id_prefix, file_path, error_file_path) except Exception as e: log.exception("%s Failed to move file %s to error directory: %s", log_id_prefix, file_path, e) async def _send_update_to_external( self, external_request_context: Dict[str, Any], event_data: Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent], is_final_chunk_of_update: bool, ) -> None: """Handle intermediate updates (optional for this gateway).""" log_id_prefix = f"{self.log_identifier}[SendUpdate]" task_id = event_data.id file_path = external_request_context.get("file_path", "Unknown file") log.debug("%s Received update for task %s (file %s). Updates not processed by this gateway.", log_id_prefix, task_id, os.path.basename(file_path)) def cleanup(self): """Clean up resources.""" log.info("%s Cleaning up Directory Monitor Gateway Component...", self.log_identifier) super().cleanup() log.info("%s Directory Monitor Gateway Component cleanup finished.", self.log_identifier) ","version":"Next","tagName":"h3"},{"title":"Step 4: Configure the Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-4-configure-the-gateway","content":" Configure the Gateway (dir_monitor_config.yaml) # configs/gateways/dir_monitor_config.yaml log: stdout_log_level: INFO log_file_level: DEBUG log_file: "dir_monitor_gateway.log" !include ../shared_config.yaml apps: - name: dir_monitor_gateway_app app_base_path: . app_module: src.dir_monitor.app broker: <<: *broker_connection app_config: namespace: ${NAMESPACE} gateway_id: dir-monitor-gateway # Artifact service configuration artifact_service: *default_artifact_service # Authorization service authorization_service: type: "none" # System purpose for A2A context system_purpose: > This system monitors directories for new files and processes them automatically. Analyze and summarize file contents. Always provide useful insights about the files. Your external name is Directory Monitor Agent. response_format: > Responses should be clear, concise, and professionally formatted. Provide structured analysis of file contents in Markdown format. # Gateway-specific configuration directory_path: /path/to/monitor/directory error_directory_path: /path/to/error/directory target_agent_name: "OrchestratorAgent" default_user_identity: "dir_monitor_system" ","version":"Next","tagName":"h3"},{"title":"Step 5: Install Dependencies​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-5-install-dependencies","content":" Add required dependencies to your project: pip install watchdog ","version":"Next","tagName":"h3"},{"title":"Step 6: Run Your Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#step-6-run-your-gateway","content":" sam run configs/gateways/dir_monitor_config.yaml ","version":"Next","tagName":"h3"},{"title":"Advanced Gateway Patterns​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#advanced-gateway-patterns","content":" ","version":"Next","tagName":"h2"},{"title":"Authentication and Authorization​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#authentication-and-authorization","content":" Gateways can implement sophisticated authentication: async def _extract_initial_claims(self, external_event_data: Any) -> Optional[Dict[str, Any]]: """Extract user claims with API key validation.""" request = external_event_data.get("request") # Validate API key api_key = request.headers.get("X-API-Key") if not api_key or not self._validate_api_key(api_key): return None # Extract user information user_id = request.headers.get("X-User-ID", "anonymous") return { "id": user_id, "source": "api_gateway", "api_key_hash": hashlib.sha256(api_key.encode()).hexdigest()[:8], "roles": self._get_user_roles(user_id) } ","version":"Next","tagName":"h3"},{"title":"File Handling with Artifacts​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#file-handling-with-artifacts","content":" For gateways that handle files: async def _save_file_as_artifact(self, file_content: bytes, filename: str, mime_type: str, session_id: str) -> Optional[str]: """Save file content as artifact and return URI.""" if not self.shared_artifact_service: return None try: save_result = await save_artifact_with_metadata( artifact_service=self.shared_artifact_service, app_name=self.gateway_id, user_id="system", session_id=session_id, filename=filename, content_bytes=file_content, mime_type=mime_type, metadata_dict={ "source": "my_gateway", "upload_timestamp": datetime.now(timezone.utc).isoformat() }, timestamp=datetime.now(timezone.utc) ) if save_result["status"] in ["success", "partial_success"]: version = save_result.get("data_version", 0) return f"artifact://{self.gateway_id}/system/{session_id}/{filename}?version={version}" except Exception as e: log.error("Failed to save artifact: %s", e) return None ","version":"Next","tagName":"h3"},{"title":"Streaming Responses​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#streaming-responses","content":" Handle streaming responses from agents: async def _send_update_to_external( self, external_request_context: Dict[str, Any], event_data: Union[TaskStatusUpdateEvent, TaskArtifactUpdateEvent], is_final_chunk_of_update: bool ) -> None: """Send streaming updates to external system.""" if isinstance(event_data, TaskStatusUpdateEvent): if event_data.status and event_data.status.message: for part in event_data.status.message.parts: if isinstance(part, TextPart): # Send partial text to external system await self._send_partial_response( external_request_context, part.text, is_final=is_final_chunk_of_update ) ","version":"Next","tagName":"h3"},{"title":"Error Handling and Retry Logic​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#error-handling-and-retry-logic","content":" Implement robust error handling: async def _process_with_retry(self, data: Any, max_retries: int = 3): """Process data with retry logic.""" for attempt in range(max_retries): try: return await self._process_data(data) except TemporaryError as e: if attempt < max_retries - 1: wait_time = 2 ** attempt # Exponential backoff log.warning("Attempt %d failed, retrying in %ds: %s", attempt + 1, wait_time, e) await asyncio.sleep(wait_time) else: raise except PermanentError: # Don't retry permanent errors raise ","version":"Next","tagName":"h3"},{"title":"Best Practices​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#best-practices","content":" ","version":"Next","tagName":"h2"},{"title":"1. Configuration Management​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#1-configuration-management","content":" Use environment variables for sensitive dataProvide sensible defaultsValidate configuration at startup ","version":"Next","tagName":"h3"},{"title":"2. Error Handling​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#2-error-handling","content":" Implement comprehensive error handlingUse appropriate HTTP status codesLog errors with sufficient contextProvide meaningful error messages ","version":"Next","tagName":"h3"},{"title":"3. Security​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#3-security","content":" Validate all external inputsUse secure authentication methodsImplement rate limiting where appropriateStore secrets securely (use environment variables)Follow principle of least privilege ","version":"Next","tagName":"h3"},{"title":"4. Performance​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#4-performance","content":" Use async/await for I/O operationsImplement connection pooling for external APIsMonitor resource usageHandle backpressure appropriately ","version":"Next","tagName":"h3"},{"title":"5. Monitoring and Logging​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#5-monitoring-and-logging","content":" Use structured loggingInclude correlation IDsMonitor key metrics (latency, error rates, throughput)Set up health checks ","version":"Next","tagName":"h3"},{"title":"Common Gateway Patterns​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#common-gateway-patterns","content":" ","version":"Next","tagName":"h2"},{"title":"HTTP/REST API Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#httprest-api-gateway","content":" For HTTP-based integrations: from fastapi import FastAPI, HTTPException, Depends from fastapi.security import HTTPBearer class HTTPAPIGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.app = FastAPI() self.security = HTTPBearer() self._setup_routes() def _setup_routes(self): @self.app.post("/webhook/{endpoint_id}") async def webhook_handler(endpoint_id: str, request: Request, token: str = Depends(self.security)): # Authenticate request user_identity = await self.authenticate_and_enrich_user({ "token": token, "endpoint_id": endpoint_id, "request": request }) if not user_identity: raise HTTPException(status_code=401, detail="Unauthorized") # Process webhook body = await request.json() target_agent, parts, context = await self._translate_external_input( body, user_identity ) task_id = await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) return {"task_id": task_id, "status": "accepted"} ","version":"Next","tagName":"h3"},{"title":"WebSocket Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#websocket-gateway","content":" For real-time bidirectional communication: import websockets import json class WebSocketGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.connections = {} async def _start_listener(self): """Start WebSocket server.""" self.server = await websockets.serve( self.handle_websocket, self.get_config("websocket_host", "localhost"), self.get_config("websocket_port", 8765) ) log.info("%s WebSocket server started", self.log_identifier) async def handle_websocket(self, websocket, path): """Handle WebSocket connections.""" connection_id = self.generate_uuid() self.connections[connection_id] = websocket try: async for message in websocket: data = json.loads(message) await self.process_websocket_message(connection_id, data) except websockets.exceptions.ConnectionClosed: log.info("%s WebSocket connection closed: %s", self.log_identifier, connection_id) finally: self.connections.pop(connection_id, None) async def process_websocket_message(self, connection_id: str, data: dict): """Process incoming WebSocket message.""" user_identity = await self.authenticate_and_enrich_user({ "connection_id": connection_id, "data": data }) if user_identity: target_agent, parts, context = await self._translate_external_input( data, user_identity ) context["connection_id"] = connection_id await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) async def _send_final_response_to_external(self, context: Dict[str, Any], task_data: Task): """Send response back via WebSocket.""" connection_id = context.get("connection_id") websocket = self.connections.get(connection_id) if websocket: response = { "task_id": task_data.id, "status": task_data.status.state.value if task_data.status else "unknown", "result": self._extract_text_from_task(task_data) } await websocket.send(json.dumps(response)) ","version":"Next","tagName":"h3"},{"title":"Message Queue Gateway​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#message-queue-gateway","content":" For integration with message queues: import asyncio import aio_pika class MessageQueueGatewayComponent(BaseGatewayComponent): def __init__(self, **kwargs): super().__init__(**kwargs) self.connection = None self.channel = None async def _start_listener(self): """Connect to message queue and start consuming.""" connection_url = self.get_config("rabbitmq_url") queue_name = self.get_config("input_queue_name") self.connection = await aio_pika.connect_robust(connection_url) self.channel = await self.connection.channel() queue = await self.channel.declare_queue(queue_name, durable=True) await queue.consume(self.process_message) log.info("%s Started consuming from queue: %s", self.log_identifier, queue_name) async def process_message(self, message: aio_pika.IncomingMessage): """Process incoming queue message.""" async with message.process(): try: data = json.loads(message.body.decode()) user_identity = await self.authenticate_and_enrich_user(data) if not user_identity: log.warning("%s Authentication failed for message", self.log_identifier) return target_agent, parts, context = await self._translate_external_input( data, user_identity ) context["message_id"] = message.message_id context["reply_to"] = message.reply_to await self.submit_a2a_task( target_agent_name=target_agent, a2a_parts=parts, external_request_context=context, user_identity=user_identity ) except Exception as e: log.exception("%s Error processing message: %s", self.log_identifier, e) async def _send_final_response_to_external(self, context: Dict[str, Any], task_data: Task): """Send response back to reply queue.""" reply_to = context.get("reply_to") if reply_to and self.channel: response = { "task_id": task_data.id, "status": task_data.status.state.value if task_data.status else "unknown", "result": self._extract_text_from_task(task_data) } await self.channel.default_exchange.publish( aio_pika.Message(json.dumps(response).encode()), routing_key=reply_to ) ","version":"Next","tagName":"h3"},{"title":"Packaging as a Plugin​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#packaging-as-a-plugin","content":" For distribution and reusability, package your gateway as a plugin: ","version":"Next","tagName":"h2"},{"title":"1. Create Plugin Structure​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#1-create-plugin-structure","content":" The following structure is created when running the sam plugin create my-gateway-plugin --type gateway command: my-gateway-plugin/ ├── pyproject.toml ├── README.md ├── src/ │ └── sam_my_gateway/ │ ├── __init__.py │ ├── app.py │ ├── component.py ├── config.yaml └── examples/ └── my_gateway_example.yaml ","version":"Next","tagName":"h3"},{"title":"2. Configure pyproject.toml​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#2-configure-pyprojecttoml","content":" Update the pyproject.toml file to include your gateway dependencies: ... dependencies = [ "watchdog>=3.0.0", # Add your specific dependencies ] ... ","version":"Next","tagName":"h3"},{"title":"3. Build and Install​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#3-build-and-install","content":" # Build the plugin sam plugin build # Install plugin from local wheel file sam plugin add my-gateway --plugin dist/sam_my_gateway-0.1.0-py3-none-any.whl ","version":"Next","tagName":"h3"},{"title":"Troubleshooting​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#troubleshooting","content":" ","version":"Next","tagName":"h2"},{"title":"Common Issues​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#common-issues","content":" Gateway Fails to Start​ Check configuration schema validationVerify all required parameters are providedEnsure external dependencies are installed Tasks Not Reaching Agents​ Verify namespace configuration matches agentsCheck Solace broker connectivityConfirm agent names are correct Authentication Failures​ Validate user identity extraction logicCheck authorization service configurationVerify claims format matches expectations File/Artifact Issues​ Ensure artifact service is properly configuredCheck file permissions and pathsVerify artifact URI construction ","version":"Next","tagName":"h3"},{"title":"Debugging Tips​","type":1,"pageTitle":"Create Gateways","url":"/solace-agent-mesh/docs/documentation/user-guide/create-gateways#debugging-tips","content":" Enable Debug Logging: log: stdout_log_level: DEBUG log_file_level: DEBUG Use Test Agents: Create simple echo agents for testing gateway integration Monitor Solace Topics: Use Solace monitoring tools to trace message flow Add Correlation IDs: Include unique identifiers in logs for request tracing ","version":"Next","tagName":"h3"}],"options":{"id":"default"}}