solace-agent-mesh 1.4.11__py3-none-any.whl → 1.5.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (189) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +3 -4
  2. solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
  3. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
  4. solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +1 -0
  5. solace_agent_mesh/agent/adk/callbacks.py +51 -2
  6. solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
  7. solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
  8. solace_agent_mesh/agent/adk/services.py +30 -15
  9. solace_agent_mesh/agent/adk/setup.py +4 -0
  10. solace_agent_mesh/agent/agent_llm.txt +1 -1
  11. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  12. solace_agent_mesh/agent/protocol/event_handlers.py +2 -13
  13. solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
  14. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  15. solace_agent_mesh/agent/sac/component.py +51 -21
  16. solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
  17. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  18. solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
  19. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  20. solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
  21. solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
  22. solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
  23. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  24. solace_agent_mesh/assets/docs/404.html +3 -3
  25. solace_agent_mesh/assets/docs/assets/js/0e682baa.d54b8668.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/{main.dc155742.js → main.0c149855.js} +2 -2
  28. solace_agent_mesh/assets/docs/assets/js/{runtime~main.0d2ff2b6.js → runtime~main.c66557e4.js} +1 -1
  29. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +8 -4
  32. 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
  33. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
  39. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
  40. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
  41. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
  42. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
  43. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
  44. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
  45. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +3 -3
  46. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
  47. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  48. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +7 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
  54. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
  55. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
  56. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
  57. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
  65. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
  66. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
  67. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
  68. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
  69. solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +1 -0
  70. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  71. solace_agent_mesh/assets/docs/search-doc-1760032255022.json +1 -0
  72. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  73. solace_agent_mesh/cli/__init__.py +1 -1
  74. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
  75. solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
  76. solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +1 -0
  77. solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +339 -0
  78. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
  79. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  80. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  81. solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
  82. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  83. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
  84. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  85. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
  86. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
  87. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
  88. solace_agent_mesh/common/common_llm.txt +24 -39
  89. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  90. solace_agent_mesh/common/data_parts.py +9 -1
  91. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  92. solace_agent_mesh/common/sac/sac_llm.txt +1 -1
  93. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  94. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  95. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  96. solace_agent_mesh/common/services/identity_service.py +7 -4
  97. solace_agent_mesh/common/services/providers/local_file_identity_service.py +4 -2
  98. solace_agent_mesh/common/services/services_llm.txt +57 -6
  99. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  100. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
  101. solace_agent_mesh/common/utils/utils_llm.txt +75 -87
  102. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  103. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  104. solace_agent_mesh/gateway/base/app.py +1 -1
  105. solace_agent_mesh/gateway/base/base_llm.txt +1 -1
  106. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  107. solace_agent_mesh/gateway/base/component.py +1 -1
  108. solace_agent_mesh/gateway/gateway_llm.txt +242 -235
  109. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  110. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
  111. solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
  112. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  113. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
  114. solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
  115. solace_agent_mesh/gateway/http_sse/app.py +148 -2
  116. solace_agent_mesh/gateway/http_sse/component.py +368 -60
  117. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
  118. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +108 -0
  119. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +1 -1
  120. solace_agent_mesh/gateway/http_sse/dependencies.py +116 -26
  121. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
  122. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  123. solace_agent_mesh/gateway/http_sse/main.py +146 -41
  124. solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
  125. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
  126. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
  127. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  128. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
  129. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  130. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
  131. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
  132. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  133. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
  134. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
  135. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
  136. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  137. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  138. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
  139. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
  140. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  141. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
  142. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
  143. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
  144. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
  145. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1 -1
  146. solace_agent_mesh/gateway/http_sse/routers/config.py +26 -4
  147. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
  148. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
  149. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
  150. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
  151. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  152. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
  153. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
  154. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
  155. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  156. solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
  157. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
  158. solace_agent_mesh/gateway/http_sse/routers/sessions.py +220 -40
  159. solace_agent_mesh/gateway/http_sse/routers/tasks.py +168 -42
  160. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +272 -0
  161. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +241 -0
  162. solace_agent_mesh/gateway/http_sse/services/people_service.py +0 -80
  163. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
  164. solace_agent_mesh/gateway/http_sse/services/session_service.py +151 -84
  165. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +317 -0
  166. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
  167. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
  168. solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
  169. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  170. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
  171. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  172. solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
  173. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  174. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/METADATA +1 -1
  175. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/RECORD +179 -131
  176. solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
  177. solace_agent_mesh/assets/docs/assets/js/0e682baa.d054e1d8.js +0 -1
  178. solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
  179. solace_agent_mesh/assets/docs/lunr-index-1759514789087.json +0 -1
  180. solace_agent_mesh/assets/docs/search-doc-1759514789087.json +0 -1
  181. solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
  182. solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
  183. solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
  184. solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
  185. solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
  186. /solace_agent_mesh/assets/docs/assets/js/{main.dc155742.js.LICENSE.txt → main.0c149855.js.LICENSE.txt} +0 -0
  187. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/WHEEL +0 -0
  188. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/entry_points.txt +0 -0
  189. {solace_agent_mesh-1.4.11.dist-info → solace_agent_mesh-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,1702 @@
1
+ # LLM Summary Detail File
2
+
3
+ This file is a concatenation of all individual *llm.txt files found in the 'agent' directory tree. Each section below corresponds to a specific directory's summary file.
4
+
5
+ ================================================================================
6
+
7
+ ## Section 1: solace_agent_mesh/agent/adk/adk_llm.txt
8
+
9
+ **Source file:** `solace_agent_mesh/agent/adk/adk_llm.txt`
10
+
11
+ # DEVELOPER GUIDE for adk directory
12
+
13
+ ## Quick Summary
14
+ The `adk` directory serves as the core integration layer between the Solace AI Connector framework and Google's Agent Development Kit (ADK). It provides the essential components for building, configuring, and running sophisticated AI agents within a Solace messaging environment.
15
+
16
+ The architecture is designed for modularity and extensibility. The `setup.py` module acts as the main configuration hub, using factory functions from `services.py` to initialize pluggable services (like `FilesystemArtifactService` for artifact storage) and loading tools (Python functions, MCP tools) via the `ADKToolWrapper`.
17
+
18
+ Once initialized, the `AppLlmAgent` (a custom agent class) is managed by the `runner.py` module, which handles the asynchronous task execution loop. The agent's behavior is dynamically augmented at runtime by a rich set of callbacks from `callbacks.py`. These callbacks inject dynamic instructions, manage large tool responses, log events to Solace, and handle advanced features like streaming artifact creation and auto-continuation of conversations. The `models/` subdirectory provides the concrete LLM clients, with `LiteLlm` offering broad compatibility with various model providers.
19
+
20
+ ## Files and Subdirectories Overview
21
+ - **Direct files:**
22
+ - `__init__.py`: Standard Python package initializer
23
+ - `adk_llm.txt`: Documentation file containing developer guide content
24
+ - `app_llm_agent.py`: Defines a custom `LlmAgent` subclass that holds a reference to its host component
25
+ - `callbacks.py`: Provides a rich set of ADK callback functions for dynamic instructions, metadata injection, and Solace integration
26
+ - `embed_resolving_mcp_toolset.py`: Custom MCPToolset that resolves embeds in tool parameters before calling MCP tools
27
+ - `filesystem_artifact_service.py`: A local filesystem-based implementation of ADK's `BaseArtifactService`
28
+ - `intelligent_mcp_callbacks.py`: Intelligent MCP callback functions for processing and saving MCP tool responses as typed artifacts
29
+ - `invocation_monitor.py`: A utility for monitoring and logging agent invocations to YAML files for debugging
30
+ - `mcp_content_processor.py`: Intelligent processing of MCP tool responses, converting raw content into appropriately typed artifacts
31
+ - `runner.py`: Manages the asynchronous execution of ADK agent tasks, including cancellation support
32
+ - `services.py`: Contains factory functions for initializing ADK services (session, artifact, memory) based on configuration
33
+ - `setup.py`: Handles the high-level initialization of the ADK agent, tools, and runner
34
+ - `stream_parser.py`: An internal utility for parsing fenced artifact blocks from an LLM's streaming response
35
+ - `tool_wrapper.py`: A wrapper for Python functions to make them compatible with ADK, handling embed resolution and config injection
36
+ - **Subdirectories:**
37
+ - `artifacts/`: Contains filesystem and S3-compatible artifact storage implementations
38
+ - `models/`: Contains concrete `BaseLlm` implementations for interfacing with various LLM providers
39
+
40
+ ## Developer API Reference
41
+
42
+ ### Direct Files
43
+
44
+ #### app_llm_agent.py
45
+ **Purpose:** A custom `LlmAgent` subclass that includes a reference to its hosting component, allowing callbacks and tools to access host-level configurations and services.
46
+ **Import:** `from solace_agent_mesh.agent.adk.app_llm_agent import AppLlmAgent`
47
+
48
+ **Classes/Functions/Constants:**
49
+ - `AppLlmAgent(host_component: Any = None, **kwargs)`: A custom `LlmAgent` that can be linked to a host component. The `host_component` is set post-initialization and is excluded from serialization.
50
+
51
+ #### callbacks.py
52
+ **Purpose:** Provides a suite of ADK callback functions that hook into the agent's lifecycle to inject custom logic. These are typically not called directly but are assigned to the agent during setup.
53
+ **Import:** `from solace_agent_mesh.agent.adk import callbacks`
54
+
55
+ **Classes/Functions/Constants:**
56
+ - `inject_dynamic_instructions_callback(...)`: Injects instructions into the prompt based on host configuration, active tools, and peer agents
57
+ - `manage_large_mcp_tool_responses_callback(...)`: Intercepts large tool responses, saves them as artifacts, and returns a truncated summary to the LLM
58
+ - `after_tool_callback_inject_metadata(...)`: After a tool creates an artifact, this loads its metadata and injects it into the tool response
59
+ - `process_artifact_blocks_callback(...)`: Processes streaming text to identify and save fenced artifact blocks (e.g., `«««save_artifact:...»»»`)
60
+ - `auto_continue_on_max_tokens_callback(...)`: Automatically continues a conversation if the LLM response was interrupted due to token limits
61
+ - `notify_tool_invocation_start_callback(...)`: Sends a status update over Solace when a tool is about to be invoked
62
+ - `solace_llm_invocation_callback(...)`: Sends a status update over Solace when the agent calls the LLM
63
+ - `repair_history_callback(...)`: Proactively checks for and repairs dangling tool calls in conversation history
64
+
65
+ #### embed_resolving_mcp_toolset.py
66
+ **Purpose:** Custom MCPToolset that resolves embeds in tool parameters before calling MCP tools, enabling dynamic content injection.
67
+ **Import:** `from solace_agent_mesh.agent.adk.embed_resolving_mcp_toolset import EmbedResolvingMCPToolset, EmbedResolvingMCPTool`
68
+
69
+ **Classes/Functions/Constants:**
70
+ - `EmbedResolvingMCPToolset(connection_params, tool_filter=None, auth_scheme=None, auth_credential=None, tool_config=None)`: Custom MCPToolset that creates EmbedResolvingMCPTool instances
71
+ - `EmbedResolvingMCPTool(original_mcp_tool, tool_config=None)`: Custom MCPTool that resolves embeds in parameters before calling the actual MCP tool
72
+
73
+ #### filesystem_artifact_service.py
74
+ **Purpose:** An implementation of `BaseArtifactService` that stores artifacts on the local filesystem, organized by scope, user, and session.
75
+ **Import:** `from solace_agent_mesh.agent.adk.filesystem_artifact_service import FilesystemArtifactService`
76
+
77
+ **Classes/Functions/Constants:**
78
+ - `FilesystemArtifactService(base_path: str)`: A service for managing artifacts on the local disk
79
+ - `async save_artifact(...) -> int`: Saves an artifact and returns its version number
80
+ - `async load_artifact(...) -> Optional[adk_types.Part]`: Loads a specific version of an artifact, or the latest if unspecified
81
+ - `async list_artifact_keys(...) -> List[str]`: Lists the names of all artifacts for a given user/session
82
+ - `async delete_artifact(...)`: Deletes an artifact and all its versions
83
+ - `async list_versions(...) -> List[int]`: Lists all version numbers for a specific artifact
84
+
85
+ #### intelligent_mcp_callbacks.py
86
+ **Purpose:** Intelligent MCP callback functions that use intelligent content processing to save MCP tool responses as appropriately typed artifacts.
87
+ **Import:** `from solace_agent_mesh.agent.adk.intelligent_mcp_callbacks import save_mcp_response_as_artifact_intelligent, McpSaveResult, McpSaveStatus`
88
+
89
+ **Classes/Functions/Constants:**
90
+ - `save_mcp_response_as_artifact_intelligent(tool, tool_context, host_component, mcp_response_dict, original_tool_args) -> McpSaveResult`: Intelligently processes and saves MCP tool response content as typed artifacts
91
+ - `McpSaveStatus`: Enumeration for the status of an MCP save operation (SUCCESS, PARTIAL_SUCCESS, ERROR)
92
+ - `McpSaveResult`: The definitive result of an MCP response save operation with status, message, and artifact details
93
+
94
+ #### invocation_monitor.py
95
+ **Purpose:** A debugging utility that logs the entire lifecycle of an agent invocation, from the initial request to the final response, into a structured YAML file.
96
+ **Import:** `from solace_agent_mesh.agent.adk.invocation_monitor import InvocationMonitor`
97
+
98
+ **Classes/Functions/Constants:**
99
+ - `InvocationMonitor()`: A class that monitors and logs agent message flows
100
+ - `log_message_event(direction: str, topic: str, payload: any, ...)`: Logs a single message event
101
+ - `cleanup()`: Finalizes any active logging sessions
102
+
103
+ #### mcp_content_processor.py
104
+ **Purpose:** Intelligent processing of MCP tool responses, converting raw MCP content into appropriately typed and formatted artifacts based on the MCP specification content types.
105
+ **Import:** `from solace_agent_mesh.agent.adk.mcp_content_processor import MCPContentProcessor, MCPContentItem, MCPContentProcessorConfig`
106
+
107
+ **Classes/Functions/Constants:**
108
+ - `MCPContentProcessor(tool_name: str, tool_args: Dict[str, Any])`: Main processor for MCP tool response content
109
+ - `process_mcp_response(mcp_response_dict) -> List[MCPContentItem]`: Process an MCP tool response and extract content items
110
+ - `MCPContentItem`: Represents a processed MCP content item with metadata
111
+ - `MCPContentProcessorConfig`: Configuration for MCP content processing
112
+
113
+ #### runner.py
114
+ **Purpose:** Provides the core asynchronous task execution logic for the ADK agent, including robust cancellation handling.
115
+ **Import:** `from solace_agent_mesh.agent.adk.runner import run_adk_async_task_thread_wrapper, TaskCancelledError`
116
+
117
+ **Classes/Functions/Constants:**
118
+ - `run_adk_async_task_thread_wrapper(component, adk_session, adk_content, ...)`: A high-level wrapper that runs an ADK task in a separate thread and handles all cleanup and error finalization
119
+ - `run_adk_async_task(component, task_context, adk_session, adk_content, run_config, a2a_context) -> bool`: Runs the ADK Runner asynchronously and processes intermediate events
120
+ - `TaskCancelledError(Exception)`: Custom exception raised when an agent task is cancelled externally
121
+
122
+ #### services.py
123
+ **Purpose:** Provides factory functions to initialize the various ADK services based on the agent's configuration file.
124
+ **Import:** `from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service, initialize_memory_service, ScopedArtifactServiceWrapper`
125
+
126
+ **Classes/Functions/Constants:**
127
+ - `initialize_session_service(component) -> BaseSessionService`: Creates a session service (e.g., `InMemorySessionService`)
128
+ - `initialize_artifact_service(component) -> BaseArtifactService`: Creates an artifact service (e.g., `FilesystemArtifactService`, `GcsArtifactService`)
129
+ - `initialize_memory_service(component) -> BaseMemoryService`: Creates a memory service (e.g., `InMemoryMemoryService`)
130
+ - `ScopedArtifactServiceWrapper`: A wrapper that transparently applies configured scope to artifact operations
131
+
132
+ #### setup.py
133
+ **Purpose:** The main entry point for configuring and instantiating the ADK agent and its dependencies. These functions tie all the other modules together.
134
+ **Import:** `from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner`
135
+
136
+ **Classes/Functions/Constants:**
137
+ - `async load_adk_tools(component) -> Tuple[List[Union[BaseTool, Callable]], List[BuiltinTool]]`: Loads all configured tools, including Python functions, MCP tools, and built-ins, wrapping them with `ADKToolWrapper`
138
+ - `initialize_adk_agent(component, loaded_explicit_tools, enabled_builtin_tools) -> AppLlmAgent`: Creates an `AppLlmAgent` instance, assigns all the necessary callbacks from `callbacks.py`, and attaches the tools
139
+ - `initialize_adk_runner(component) -> Runner`: Initializes the ADK Runner with the agent and services
140
+
141
+ #### stream_parser.py
142
+ **Purpose:** A stateful stream parser for identifying and extracting fenced artifact blocks from an LLM's text stream.
143
+ **Import:** `from solace_agent_mesh.agent.adk.stream_parser import FencedBlockStreamParser, BlockStartedEvent, BlockCompletedEvent`
144
+
145
+ **Classes/Functions/Constants:**
146
+ - `FencedBlockStreamParser(progress_update_interval_bytes=4096)`: Processes a stream of text chunks to identify and extract fenced artifact blocks
147
+ - `process_chunk(text_chunk: str) -> ParserResult`: Processes the next chunk of text from the stream
148
+ - `finalize() -> ParserResult`: Call at the end of an LLM turn to handle any unterminated blocks
149
+ - `BlockStartedEvent`, `BlockCompletedEvent`, `BlockProgressedEvent`, `BlockInvalidatedEvent`: Events emitted by the parser
150
+
151
+ #### tool_wrapper.py
152
+ **Purpose:** A wrapper for Python functions to make them compatible with ADK, handling embed resolution and config injection.
153
+ **Import:** `from solace_agent_mesh.agent.adk.tool_wrapper import ADKToolWrapper`
154
+
155
+ **Classes/Functions/Constants:**
156
+ - `ADKToolWrapper(original_func, tool_config, tool_name, origin, raw_string_args=None)`: A consolidated wrapper for ADK tools that handles metadata preservation, embed resolution, config injection, and error handling
157
+
158
+ ### Subdirectory APIs
159
+
160
+ #### artifacts/
161
+ **Purpose:** Contains filesystem and S3-compatible artifact storage implementations for managing artifacts with versioning, user namespacing, and session-based organization
162
+ **Key Exports:** `FilesystemArtifactService`, `S3ArtifactService` classes for local and cloud artifact storage
163
+ **Import Examples:**
164
+ ```python
165
+ from solace_agent_mesh.agent.adk.artifacts.filesystem_artifact_service import FilesystemArtifactService
166
+ from solace_agent_mesh.agent.adk.artifacts.s3_artifact_service import S3ArtifactService
167
+ ```
168
+
169
+ #### models/
170
+ **Purpose:** Contains concrete `BaseLlm` implementations for interfacing with various LLM providers
171
+ **Key Exports:** `LiteLlm` class for broad model provider compatibility
172
+ **Import Examples:**
173
+ ```python
174
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
175
+ ```
176
+
177
+ ## Complete Usage Guide
178
+
179
+ ### 1. Basic ADK Agent Setup
180
+
181
+ ```python
182
+ from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
183
+ from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service, initialize_memory_service
184
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
185
+
186
+ # Initialize services
187
+ session_service = initialize_session_service(component)
188
+ artifact_service = initialize_artifact_service(component)
189
+ memory_service = initialize_memory_service(component)
190
+
191
+ # Load tools
192
+ loaded_tools, builtin_tools, cleanup_hooks = await load_adk_tools(component)
193
+
194
+ # Initialize agent
195
+ agent = initialize_adk_agent(component, loaded_tools, builtin_tools)
196
+
197
+ # Initialize runner
198
+ runner = initialize_adk_runner(component)
199
+ ```
200
+
201
+ ### 2. Custom LLM Model Configuration
202
+
203
+ ```python
204
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
205
+
206
+ # Configure LiteLlm for different providers
207
+ # OpenAI
208
+ llm = LiteLlm(
209
+ model="gpt-4-turbo",
210
+ temperature=0.7,
211
+ max_completion_tokens=1000
212
+ )
213
+
214
+ # Anthropic
215
+ llm = LiteLlm(
216
+ model="claude-3-sonnet-20240229",
217
+ temperature=0.5
218
+ )
219
+
220
+ # Vertex AI
221
+ llm = LiteLlm(
222
+ model="gemini-pro",
223
+ temperature=0.3
224
+ )
225
+ ```
226
+
227
+ ### 3. Artifact Service Usage
228
+
229
+ ```python
230
+ from solace_agent_mesh.agent.adk.artifacts.filesystem_artifact_service import FilesystemArtifactService
231
+ from solace_agent_mesh.agent.adk.artifacts.s3_artifact_service import S3ArtifactService
232
+ from google.genai import types as adk_types
233
+
234
+ # Initialize filesystem artifact service
235
+ artifact_service = FilesystemArtifactService(base_path="/tmp/artifacts")
236
+
237
+ # Or initialize S3 artifact service
238
+ artifact_service = S3ArtifactService(bucket_name="my-artifacts-bucket")
239
+
240
+ # Save an artifact
241
+
242
+ ================================================================================
243
+
244
+ ## Section 2: solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt
245
+
246
+ **Source file:** `solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt`
247
+
248
+ # DEVELOPER GUIDE: artifacts
249
+
250
+ ## Quick Summary
251
+ The artifacts directory provides ADK ArtifactService implementations for the Solace Agent Mesh. It includes filesystem and S3-compatible storage backends for managing artifacts with versioning, user namespacing, and session-based organization.
252
+
253
+ ## Files Overview
254
+ - `__init__.py` - Package initialization for artifact service implementations
255
+ - `filesystem_artifact_service.py` - Local filesystem-based artifact storage implementation
256
+ - `s3_artifact_service.py` - Amazon S3 compatible storage implementation for artifacts
257
+
258
+ ## Developer API Reference
259
+
260
+ ### filesystem_artifact_service.py
261
+ **Purpose:** Provides local filesystem storage for artifacts with structured directory organization and metadata management.
262
+
263
+ **Import:** `from solace_agent_mesh.agent.adk.artifacts.filesystem_artifact_service import FilesystemArtifactService`
264
+
265
+ **Classes:**
266
+ - `FilesystemArtifactService(base_path: str)` - Filesystem-based artifact service implementation
267
+ - `save_artifact(*, app_name: str, user_id: str, session_id: str, filename: str, artifact: adk_types.Part) -> int` - Saves an artifact and returns version number
268
+ - `load_artifact(*, app_name: str, user_id: str, session_id: str, filename: str, version: int | None = None) -> adk_types.Part | None` - Loads an artifact by version (latest if None)
269
+ - `list_artifact_keys(*, app_name: str, user_id: str, session_id: str) -> list[str]` - Lists all artifact filenames for a scope
270
+ - `delete_artifact(*, app_name: str, user_id: str, session_id: str, filename: str) -> None` - Deletes all versions of an artifact
271
+ - `list_versions(*, app_name: str, user_id: str, session_id: str, filename: str) -> list[int]` - Lists all version numbers for an artifact
272
+ - `base_path: str` - Root directory for artifact storage
273
+
274
+ **Constants/Variables:**
275
+ - `METADATA_FILE_SUFFIX: str` - File suffix for metadata files (".meta")
276
+
277
+ **Usage Examples:**
278
+ ```python
279
+ from solace_agent_mesh.agent.adk.artifacts.filesystem_artifact_service import FilesystemArtifactService
280
+ from google.genai import types as adk_types
281
+
282
+ # Initialize the service
283
+ artifact_service = FilesystemArtifactService(base_path="/path/to/artifacts")
284
+
285
+ # Save an artifact
286
+ artifact_data = b"Hello, World!"
287
+ artifact_part = adk_types.Part.from_bytes(data=artifact_data, mime_type="text/plain")
288
+ version = await artifact_service.save_artifact(
289
+ app_name="my_app",
290
+ user_id="user123",
291
+ session_id="session456",
292
+ filename="greeting.txt",
293
+ artifact=artifact_part
294
+ )
295
+
296
+ # Load the latest version
297
+ loaded_artifact = await artifact_service.load_artifact(
298
+ app_name="my_app",
299
+ user_id="user123",
300
+ session_id="session456",
301
+ filename="greeting.txt"
302
+ )
303
+
304
+ # Load a specific version
305
+ specific_version = await artifact_service.load_artifact(
306
+ app_name="my_app",
307
+ user_id="user123",
308
+ session_id="session456",
309
+ filename="greeting.txt",
310
+ version=1
311
+ )
312
+
313
+ # List all artifacts
314
+ artifact_keys = await artifact_service.list_artifact_keys(
315
+ app_name="my_app",
316
+ user_id="user123",
317
+ session_id="session456"
318
+ )
319
+
320
+ # List versions of an artifact
321
+ versions = await artifact_service.list_versions(
322
+ app_name="my_app",
323
+ user_id="user123",
324
+ session_id="session456",
325
+ filename="greeting.txt"
326
+ )
327
+
328
+ # Delete an artifact
329
+ await artifact_service.delete_artifact(
330
+ app_name="my_app",
331
+ user_id="user123",
332
+ session_id="session456",
333
+ filename="greeting.txt"
334
+ )
335
+ ```
336
+
337
+ ### s3_artifact_service.py
338
+ **Purpose:** Provides S3-compatible storage for artifacts with structured key organization and AWS integration.
339
+
340
+ **Import:** `from solace_agent_mesh.agent.adk.artifacts.s3_artifact_service import S3ArtifactService`
341
+
342
+ **Classes:**
343
+ - `S3ArtifactService(bucket_name: str, s3_client: BaseClient | None = None, **kwargs)` - S3-based artifact service implementation
344
+ - `save_artifact(*, app_name: str, user_id: str, session_id: str, filename: str, artifact: adk_types.Part) -> int` - Saves an artifact to S3 and returns version number
345
+ - `load_artifact(*, app_name: str, user_id: str, session_id: str, filename: str, version: int | None = None) -> adk_types.Part | None` - Loads an artifact from S3 by version (latest if None)
346
+ - `list_artifact_keys(*, app_name: str, user_id: str, session_id: str) -> list[str]` - Lists all artifact filenames for a scope
347
+ - `delete_artifact(*, app_name: str, user_id: str, session_id: str, filename: str) -> None` - Deletes all versions of an artifact from S3
348
+ - `list_versions(*, app_name: str, user_id: str, session_id: str, filename: str) -> list[int]` - Lists all version numbers for an artifact
349
+ - `bucket_name: str` - S3 bucket name for storage
350
+ - `s3: BaseClient` - Boto3 S3 client instance
351
+
352
+ **Usage Examples:**
353
+ ```python
354
+ from solace_agent_mesh.agent.adk.artifacts.s3_artifact_service import S3ArtifactService
355
+ from google.genai import types as adk_types
356
+ import boto3
357
+
358
+ # Initialize with default credentials
359
+ artifact_service = S3ArtifactService(bucket_name="my-artifacts-bucket")
360
+
361
+ # Initialize with custom S3 client
362
+ s3_client = boto3.client(
363
+ 's3',
364
+ endpoint_url='https://minio.example.com',
365
+ aws_access_key_id='access_key',
366
+ aws_secret_access_key='secret_key'
367
+ )
368
+ artifact_service = S3ArtifactService(
369
+ bucket_name="my-artifacts-bucket",
370
+ s3_client=s3_client
371
+ )
372
+
373
+ # Save an artifact
374
+ artifact_data = b"Hello, S3!"
375
+ artifact_part = adk_types.Part.from_bytes(data=artifact_data, mime_type="text/plain")
376
+ version = await artifact_service.save_artifact(
377
+ app_name="my_app",
378
+ user_id="user123",
379
+ session_id="session456",
380
+ filename="greeting.txt",
381
+ artifact=artifact_part
382
+ )
383
+
384
+ # Load the latest version
385
+ loaded_artifact = await artifact_service.load_artifact(
386
+ app_name="my_app",
387
+ user_id="user123",
388
+ session_id="session456",
389
+ filename="greeting.txt"
390
+ )
391
+
392
+ # Save user-scoped artifact (persists across sessions)
393
+ user_artifact = adk_types.Part.from_bytes(data=b"User data", mime_type="text/plain")
394
+ await artifact_service.save_artifact(
395
+ app_name="my_app",
396
+ user_id="user123",
397
+ session_id="session456",
398
+ filename="user:profile.json", # user: prefix for user-scoped storage
399
+ artifact=user_artifact
400
+ )
401
+
402
+ # List all artifacts (includes both session and user-scoped)
403
+ artifact_keys = await artifact_service.list_artifact_keys(
404
+ app_name="my_app",
405
+ user_id="user123",
406
+ session_id="session456"
407
+ )
408
+
409
+ # Delete an artifact
410
+ await artifact_service.delete_artifact(
411
+ app_name="my_app",
412
+ user_id="user123",
413
+ session_id="session456",
414
+ filename="greeting.txt"
415
+ )
416
+ ```
417
+
418
+ ================================================================================
419
+
420
+ ## Section 3: solace_agent_mesh/agent/adk/models/models_llm.txt
421
+
422
+ **Source file:** `solace_agent_mesh/agent/adk/models/models_llm.txt`
423
+
424
+ # DEVELOPER GUIDE for models directory
425
+
426
+ ## Quick Summary
427
+ This directory contains concrete implementations of the `BaseLlm` interface, providing wrappers for various Large Language Model APIs. These classes translate the ADK's standard `LlmRequest` into provider-specific formats and parse responses back into standard `LlmResponse` objects.
428
+
429
+ ## Files Overview
430
+ - `lite_llm.py` - LLM client using the `litellm` library to support hundreds of models from different providers
431
+
432
+ ## Developer API Reference
433
+
434
+ ### lite_llm.py
435
+ **Purpose:** Provides the `LiteLlm` class, a `BaseLlm` implementation that interfaces with hundreds of LLM models through the `litellm` library. Supports models from OpenAI, Anthropic, Vertex AI, and many other providers by simply changing the model string.
436
+
437
+ **Import:** `from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm`
438
+
439
+ **Classes:**
440
+ - `LiteLlm(model: str, **kwargs)` - Wrapper around `litellm` supporting any model it recognizes
441
+ - `generate_content_async(llm_request: LlmRequest, stream: bool = False) -> AsyncGenerator[LlmResponse, None]` - Generates content asynchronously with optional streaming
442
+ - `supported_models() -> list[str]` - Returns list of supported models (empty for LiteLlm due to dynamic model support)
443
+ - `model: str` - The name of the LiteLlm model
444
+ - `llm_client: LiteLLMClient` - The LLM client instance used for API calls
445
+
446
+ - `LiteLLMClient()` - Internal client providing completion methods for better testability
447
+ - `acompletion(model, messages, tools, **kwargs) -> Union[ModelResponse, CustomStreamWrapper]` - Asynchronous completion call
448
+ - `completion(model, messages, tools, stream=False, **kwargs) -> Union[ModelResponse, CustomStreamWrapper]` - Synchronous completion call
449
+
450
+ - `FunctionChunk(BaseModel)` - Represents a function call chunk in streaming responses
451
+ - `id: Optional[str]` - Function call ID
452
+ - `name: Optional[str]` - Function name
453
+ - `args: Optional[str]` - Function arguments as JSON string
454
+ - `index: Optional[int]` - Index of the function call
455
+
456
+ - `TextChunk(BaseModel)` - Represents a text chunk in streaming responses
457
+ - `text: str` - The text content
458
+
459
+ - `UsageMetadataChunk(BaseModel)` - Represents token usage information
460
+ - `prompt_tokens: int` - Number of tokens in the prompt
461
+ - `completion_tokens: int` - Number of tokens in the completion
462
+ - `total_tokens: int` - Total number of tokens used
463
+
464
+ **Functions:**
465
+ - `_content_to_message_param(content: types.Content) -> Union[Message, list[Message]]` - Converts ADK Content to litellm Message format
466
+ - `_get_content(parts: Iterable[types.Part]) -> Union[OpenAIMessageContent, str]` - Converts parts to litellm content format
467
+ - `_function_declaration_to_tool_param(function_declaration: types.FunctionDeclaration) -> dict` - Converts function declarations to OpenAPI spec format
468
+ - `_model_response_to_generate_content_response(response: ModelResponse) -> LlmResponse` - Converts litellm response to LlmResponse
469
+
470
+ **Usage Examples:**
471
+ ```python
472
+ import asyncio
473
+ import os
474
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
475
+ from solace_agent_mesh.agent.adk.models.llm_request import LlmRequest, LlmConfig
476
+ from google.genai.types import Content, Part
477
+
478
+ # Set environment variables for your chosen provider
479
+ # For OpenAI:
480
+ # os.environ["OPENAI_API_KEY"] = "your-api-key"
481
+ # For Vertex AI:
482
+ # os.environ["VERTEXAI_PROJECT"] = "your-project-id"
483
+ # os.environ["VERTEXAI_LOCATION"] = "your-location"
484
+
485
+ async def main():
486
+ # Initialize LiteLlm with a specific model
487
+ llm = LiteLlm(
488
+ model="gpt-4-turbo",
489
+ temperature=0.7,
490
+ max_completion_tokens=150
491
+ )
492
+
493
+ # Create a request
494
+ request = LlmRequest(
495
+ contents=[
496
+ Content(
497
+ role="user",
498
+ parts=[Part.from_text("Explain quantum computing in simple terms")]
499
+ )
500
+ ],
501
+ config=LlmConfig(
502
+ temperature=0.5,
503
+ max_output_tokens=200
504
+ )
505
+ )
506
+
507
+ # Non-streaming generation
508
+ print("=== Non-streaming ===")
509
+ async for response in llm.generate_content_async(request, stream=False):
510
+ print(f"Response: {response.text}")
511
+ if response.usage_metadata:
512
+ print(f"Tokens used: {response.usage_metadata.total_token_count}")
513
+
514
+ # Streaming generation
515
+ print("\n=== Streaming ===")
516
+ async for response in llm.generate_content_async(request, stream=True):
517
+ if response.text:
518
+ print(response.text, end="", flush=True)
519
+ if response.usage_metadata:
520
+ print(f"\nTotal tokens: {response.usage_metadata.total_token_count}")
521
+
522
+ # Example with function calling
523
+ async def function_calling_example():
524
+ from google.genai.types import FunctionDeclaration, Schema, Type, Tool
525
+
526
+ # Define a function for the LLM to call
527
+ get_weather_func = FunctionDeclaration(
528
+ name="get_weather",
529
+ description="Get current weather for a location",
530
+ parameters=Schema(
531
+ type=Type.OBJECT,
532
+ properties={
533
+ "location": Schema(type=Type.STRING, description="City name"),
534
+ "unit": Schema(type=Type.STRING, description="Temperature unit")
535
+ },
536
+ required=["location"]
537
+ )
538
+ )
539
+
540
+ llm = LiteLlm(model="gpt-4-turbo")
541
+
542
+ request = LlmRequest(
543
+ contents=[
544
+ Content(
545
+ role="user",
546
+ parts=[Part.from_text("What's the weather like in Tokyo?")]
547
+ )
548
+ ],
549
+ config=LlmConfig(
550
+ tools=[Tool(function_declarations=[get_weather_func])]
551
+ )
552
+ )
553
+
554
+ async for response in llm.generate_content_async(request):
555
+ if response.function_calls:
556
+ for func_call in response.function_calls:
557
+ print(f"Function called: {func_call.name}")
558
+ print(f"Arguments: {func_call.args}")
559
+
560
+ if __name__ == "__main__":
561
+ asyncio.run(main())
562
+ # asyncio.run(function_calling_example())
563
+ ```
564
+
565
+ ================================================================================
566
+
567
+ ## Section 4: solace_agent_mesh/agent/agent_llm.txt
568
+
569
+ **Source file:** `solace_agent_mesh/agent/agent_llm.txt`
570
+
571
+ # DEVELOPER GUIDE for agent directory
572
+
573
+ ## Quick Summary
574
+ The `agent` directory provides a comprehensive framework for hosting Google ADK (Agent Development Kit) agents within the Solace AI Connector ecosystem. It bridges ADK agents with the A2A (Agent-to-Agent) protocol over Solace messaging, enabling distributed agent communication, task delegation, and rich tool functionality.
575
+
576
+ The architecture is modular, consisting of several key components:
577
+ - **`sac/` (Solace AI Connector):** The main entry point, providing the `SamAgentApp` and `SamAgentComponent` to host the agent and manage its lifecycle and communication over the Solace event mesh.
578
+ - **`adk/` (Agent Development Kit):** The core integration layer with Google's ADK. It defines the custom `AppLlmAgent`, manages asynchronous task execution, and provides a rich set of callbacks to augment agent behavior.
579
+ - **`tools/`:** A comprehensive and extensible library of tools available to the agent, covering data analysis, artifact management, web requests, multimedia processing, and inter-agent communication.
580
+ - **`protocol/`:** The underlying implementation of the A2A (Agent-to-Agent) communication protocol, handling message routing and event processing.
581
+ - **`utils/`:** A collection of helper modules for common tasks like artifact management, configuration parsing, and context handling.
582
+ - **`testing/`:** Utilities to aid in debugging and testing custom agent implementations.
583
+
584
+ These components work together to create a robust environment where an ADK agent can be configured with specific instructions and tools, communicate with other agents, and execute complex tasks in a distributed, event-driven manner.
585
+
586
+ ## Files and Subdirectories Overview
587
+ - **Direct files:**
588
+ - `__init__.py`: Standard Python package initializer that marks the `agent` directory as a Python package
589
+ - `agent_llm.txt`: Documentation file containing comprehensive developer guide content
590
+ - **Subdirectories:**
591
+ - `adk/`: Provides the core integration layer with Google's ADK, including custom agents, services, and callbacks
592
+ - `protocol/`: Implements the A2A protocol event handlers for message routing and agent communication
593
+ - `sac/`: Contains the Solace AI Connector app and component implementations for hosting ADK agents
594
+ - `testing/`: Provides utilities for testing the A2A framework and debugging agent behavior
595
+ - `tools/`: A comprehensive, registry-based tool library for AI agents
596
+ - `utils/`: Contains helper utilities for configuration, context handling, and artifact management
597
+
598
+ ## Developer API Reference
599
+
600
+ ### Direct Files
601
+
602
+ #### __init__.py
603
+ **Purpose:** Standard Python package initializer. It allows the `agent` directory to be treated as a package.
604
+ **Import:** `import solace_agent_mesh.agent`
605
+
606
+ **Classes/Functions/Constants:** [None - empty file]
607
+
608
+ #### agent_llm.txt
609
+ **Purpose:** Documentation file containing comprehensive developer guide content
610
+ **Import:** Not applicable - this is a documentation file, not a code module
611
+
612
+ **Classes/Functions/Constants:** [None - documentation file]
613
+
614
+ ### Subdirectory APIs
615
+
616
+ #### adk/
617
+ **Purpose:** Provides the core integration layer between the Solace AI Connector and Google's ADK
618
+ **Key Exports:** `AppLlmAgent`, `initialize_adk_agent`, `initialize_adk_runner`, `load_adk_tools`, `FilesystemArtifactService`, `LiteLlm`
619
+ **Import Examples:**
620
+ ```python
621
+ from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
622
+ from solace_agent_mesh.agent.adk.app_llm_agent import AppLlmAgent
623
+ from solace_agent_mesh.agent.adk.filesystem_artifact_service import FilesystemArtifactService
624
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
625
+ from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service
626
+ ```
627
+
628
+ #### protocol/
629
+ **Purpose:** Implements the core logic for Agent-to-Agent (A2A) communication protocol
630
+ **Key Exports:** `process_event`, `handle_a2a_request`, `handle_agent_card_message`, `publish_agent_card`
631
+ **Import Examples:**
632
+ ```python
633
+ from solace_agent_mesh.agent.protocol.event_handlers import process_event, publish_agent_card
634
+ ```
635
+
636
+ #### sac/
637
+ **Purpose:** Provides the Solace AI Connector app and component implementations for hosting ADK agents
638
+ **Key Exports:** `SamAgentApp`, `SamAgentComponent`, `TaskExecutionContext`
639
+ **Import Examples:**
640
+ ```python
641
+ from solace_agent_mesh.agent.sac.app import SamAgentApp
642
+ from solace_agent_mesh.agent.sac.component import SamAgentComponent
643
+ from solace_agent_mesh.agent.sac.task_execution_context import TaskExecutionContext
644
+ ```
645
+
646
+ #### testing/
647
+ **Purpose:** Provides utilities for testing the A2A framework and debugging agent behavior
648
+ **Key Exports:** `pretty_print_event_history`
649
+ **Import Examples:**
650
+ ```python
651
+ from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history
652
+ ```
653
+
654
+ #### tools/
655
+ **Purpose:** A comprehensive, registry-based tool library for AI agents
656
+ **Key Exports:** `tool_registry`, `BuiltinTool`, `PeerAgentTool`, and various tool functions
657
+ **Import Examples:**
658
+ ```python
659
+ from solace_agent_mesh.agent.tools.registry import tool_registry
660
+ from solace_agent_mesh.agent.tools.peer_agent_tool import PeerAgentTool
661
+ from solace_agent_mesh.agent.tools.audio_tools import text_to_speech
662
+ from solace_agent_mesh.agent.tools.builtin_artifact_tools import list_artifacts, load_artifact
663
+ ```
664
+
665
+ #### utils/
666
+ **Purpose:** Contains helper utilities for configuration, context handling, and artifact management
667
+ **Key Exports:** `save_artifact_with_metadata`, `load_artifact_content_or_metadata`, `resolve_instruction_provider`
668
+ **Import Examples:**
669
+ ```python
670
+ from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata, load_artifact_content_or_metadata
671
+ from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider
672
+ from solace_agent_mesh.agent.utils.context_helpers import get_session_from_callback_context
673
+ ```
674
+
675
+ ## Complete Usage Guide
676
+
677
+ ### 1. Basic Agent Setup and Configuration
678
+
679
+ ```python
680
+ # Import the main SAC components
681
+ from solace_agent_mesh.agent.sac.app import SamAgentApp
682
+ from solace_agent_mesh.agent.sac.component import SamAgentComponent
683
+
684
+ # The agent is typically configured via YAML and instantiated by the SAC framework
685
+ # Example agent-config.yaml:
686
+ """
687
+ app:
688
+ class_name: solace_agent_mesh.agent.sac.app.SamAgentApp
689
+ app_config:
690
+ namespace: "my-org/production"
691
+ agent_name: "customer-support-agent"
692
+ model: "gemini-1.5-pro-latest"
693
+ tools:
694
+ - tool_type: "builtin"
695
+ tool_name: "text_to_speech"
696
+ - tool_type: "builtin"
697
+ tool_name: "list_artifacts"
698
+ agent_card:
699
+ description: "An agent that can answer questions about customer accounts."
700
+ session_service:
701
+ type: "memory"
702
+ artifact_service:
703
+ type: "filesystem"
704
+ base_path: "/tmp/artifacts"
705
+ """
706
+ ```
707
+
708
+ ### 2. Working with ADK Components
709
+
710
+ ```python
711
+ from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
712
+ from solace_agent_mesh.agent.adk.services import initialize_session_service, initialize_artifact_service
713
+ from solace_agent_mesh.agent.adk.models.lite_llm import LiteLlm
714
+
715
+ async def setup_adk_agent(component):
716
+ # Initialize services
717
+ session_service = initialize_session_service(component)
718
+ artifact_service = initialize_artifact_service(component)
719
+
720
+ # Load tools
721
+ loaded_tools, builtin_tools = await load_adk_tools(component)
722
+
723
+ # Initialize agent with LLM
724
+ agent = initialize_adk_agent(component, loaded_tools, builtin_tools)
725
+
726
+ # Initialize runner
727
+ runner = initialize_adk_runner(component)
728
+
729
+ return agent, runner
730
+ ```
731
+
732
+ ### 3. Custom Tool Development
733
+
734
+ ```python
735
+ from solace_agent_mesh.agent.tools.registry import tool_registry
736
+ from solace_agent_mesh.agent.tools.tool_definition import BuiltinTool
737
+ from google.adk.tools import ToolContext
738
+
739
+ # Define a custom tool function
740
+ async def my_custom_tool(
741
+ query: str,
742
+ tool_context: ToolContext = None,
743
+ tool_config: dict = None
744
+ ) -> dict:
745
+ """A custom tool that processes queries."""
746
+ # Access the host component
747
+ host_component = tool_context._invocation_context.agent.host_component
748
+
749
+ # Use agent state
750
+ db_connection = host_component.get_agent_specific_state('db_connection')
751
+
752
+ # Process the query
753
+ result = await process_query(query, db_connection)
754
+
755
+ return {"result": result, "status": "success"}
756
+
757
+ # Register the tool
758
+ custom_tool = BuiltinTool(
759
+ name="my_custom_tool",
760
+ description="Processes custom queries",
761
+ function=my_custom_tool,
762
+ category="custom"
763
+ )
764
+ tool_registry.register(custom_tool)
765
+ ```
766
+
767
+ ### 4. Artifact Management
768
+
769
+ ```python
770
+ from solace_agent_mesh.agent.utils.artifact_helpers import (
771
+ save_artifact_with_metadata,
772
+ load_artifact_content_or_metadata,
773
+ get_artifact_info_list
774
+ )
775
+ from datetime import datetime, timezone
776
+
777
+ async def artifact_operations(component, artifact_service):
778
+ # Save an artifact with metadata
779
+ content = b"Hello, world!"
780
+ result = await save_artifact_with_metadata(
781
+ artifact_service=artifact_service,
782
+ app_name=component.get_config()["app_name"],
783
+ user_id="user123",
784
+ session_id="session456",
785
+ filename="greeting.txt",
786
+ content_bytes=content,
787
+ mime_type="text/plain",
788
+ metadata_dict={"source": "custom_tool", "description": "A greeting"},
789
+ timestamp=datetime.now(timezone.utc)
790
+ )
791
+
792
+ # Load the artifact
793
+ loaded = await load_artifact_content_or_metadata(
794
+ artifact_service=artifact_service,
795
+ app_name=component.get_config()["app_name"],
796
+ user_id="user123",
797
+ session_id="session456",
798
+ filename="greeting.txt",
799
+ version="latest"
800
+ )
801
+
802
+ # List all artifacts
803
+ artifacts = await get_artifact_info_list(
804
+ artifact_service=artifact_service,
805
+ app_name=component.get_config()["app_name"],
806
+ user_id="user123",
807
+ session_id="session456"
808
+ )
809
+
810
+ return artifacts
811
+ ```
812
+
813
+ ### 5. Inter-Agent Communication
814
+
815
+ ```python
816
+ from solace_agent_mesh.agent.tools.peer_agent_tool import PeerAgentTool
817
+
818
+ # Create a peer agent tool (typically done automatically by the framework)
819
+ peer_tool = PeerAgentTool("data_analyst_agent", host_component)
820
+
821
+ # The LLM can then use this tool to delegate tasks:
822
+ # "Please use the data_analyst_agent to analyze the sales data in report.csv"
823
+
824
+ # The framework handles the A2A protocol communication automatically
825
+ ```
826
+
827
+ ### 6. Audio and Multimedia Tools
828
+
829
+ ```python
830
+ from solace_agent_mesh.agent.tools.audio_tools import text_to_speech, multi_speaker_text_to_speech
831
+ from solace_agent_mesh.agent.tools.image_tools import create_image_from_description, describe_image
832
+
833
+ async def multimedia_example(tool_context):
834
+ # Generate speech from text
835
+ tts_result = await text_to_speech(
836
+ text="Welcome to our service!",
837
+ output_filename="welcome.mp3",
838
+ gender="female",
839
+ tone="friendly",
840
+ tool_context=tool_context
841
+ )
842
+
843
+ # Create a multi-speaker conversation
844
+ conversation_result = await multi_speaker_text_to_speech(
845
+ conversation_text="Alice: Hello there!\nBob: Hi Alice, how are you?",
846
+ speaker_configs=[
847
+ {"name": "Alice", "gender": "female", "tone": "bright"},
848
+ {"name": "Bob", "gender": "male", "tone": "warm"}
849
+ ],
850
+ tool_context=tool_context
851
+ )
852
+
853
+ # Generate an image
854
+ image_result = await create_image_from_description(
855
+ image_description="A futuristic cityscape at sunset",
856
+ output_filename="cityscape.png",
857
+ tool_context=tool_context
858
+ )
859
+
860
+ return tts_result, conversation_result, image_result
861
+ ```
862
+
863
+ ### 7. Testing and Debugging
864
+
865
+ ```python
866
+ from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history
867
+ from solace_agent_mesh.agent.adk.invocation_monitor import InvocationMonitor
868
+
869
+ # Debug event history in tests
870
+ def test_agent_behavior():
871
+ event_history = [
872
+ {"result": {"status": {"state": "EXECUTING"}}},
873
+ {"result": {"status": {"state": "COMPLETED"}}}
874
+ ]
875
+
876
+ # Print formatted event history for debugging
877
+ pretty_print_event_history(event_history)
878
+
879
+ # Monitor agent invocations
880
+ monitor = InvocationMonitor()
881
+ monitor.log_message_event("incoming", "agent/request", {"task": "analyze data"})
882
+ ```
883
+
884
+ ### 8. Configuration and Context Handling
885
+
886
+ ```python
887
+ from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider
888
+ from solace_agent_mesh.agent.utils.context_helpers import get_session_from_callback_context
889
+
890
+ # Resolve dynamic instructions
891
+ def setup_agent_instructions(component):
892
+ # Static instruction
893
+ static_instruction = resolve_instruction_provider(
894
+ component,
895
+ "You are a helpful customer service agent."
896
+ )
897
+
898
+ # Dynamic instruction function
899
+ def dynamic_instruction(context):
900
+ return f"You are assisting user {context.user_id} in session {context.session_id}"
901
+
902
+ dynamic_provider = resolve_instruction_provider(component, dynamic_instruction)
903
+
904
+ return static_instruction, dynamic_provider
905
+
906
+ # Safe context extraction in tools
907
+ def my_tool_with_context(tool_context):
908
+ session = get_session_from_callback_context(tool_context)
909
+ original_session_id = get_original_session_id(tool_context._invocation_context)
910
+
911
+ return {"session_id": original_session_id, "session_data": session}
912
+ ```
913
+
914
+ ### 9. Complete Agent Implementation Example
915
+
916
+ ```python
917
+ from solace_agent_mesh.agent.sac.app import SamAgentApp
918
+ from solace_agent_mesh.agent.sac.component import SamAgentComponent
919
+ from solace_agent_mesh.agent.adk.setup import load_adk_tools, initialize_adk_agent, initialize_adk_runner
920
+ from solace_agent_mesh.agent.tools.registry import tool_registry
921
+ from solace_agent_mesh.agent.tools.tool_definition import BuiltinTool
922
+
923
+ # Custom initialization function
924
+ def initialize_my_agent(host_component: SamAgentComponent, config: dict):
925
+ """Custom initialization function for the agent."""
926
+ # Store custom state
927
+ host_component.set_agent_specific_state('custom_data', config.get('custom_data'))
928
+
929
+ # Set dynamic system instruction
930
+ def dynamic_instruction(context):
931
+ return f"You are a specialized agent for user {context.user_id}"
932
+
933
+ host_component.set_agent_system_instruction_callback(dynamic_instruction)
934
+
935
+ # Custom tool
936
+ async def my_business_tool(
937
+ query: str,
938
+ tool_context = None,
939
+ tool_config: dict = None
940
+ ) -> dict:
941
+ """Custom business logic tool."""
942
+ host_component = tool_context._invocation_context.agent.host_component
943
+ custom_data = host_component.get_agent_specific_state('custom_data')
944
+
945
+ # Process business logic
946
+ result =
947
+
948
+ ================================================================================
949
+
950
+ ## Section 5: solace_agent_mesh/agent/protocol/protocol_llm.txt
951
+
952
+ **Source file:** `solace_agent_mesh/agent/protocol/protocol_llm.txt`
953
+
954
+ # DEVELOPER GUIDE: protocol
955
+
956
+ ## Quick Summary
957
+ The `protocol` directory implements the core logic for Agent-to-Agent (A2A) communication. It handles receiving and processing requests, responses, and discovery messages (Agent Cards) over the Solace event mesh. It acts as the bridge between the A2A protocol and the underlying Google ADK execution environment.
958
+
959
+ ## Files Overview
960
+ - `__init__.py` - Empty package initialization file
961
+ - `event_handlers.py` - Contains the primary logic for handling all A2A protocol events, including routing incoming messages, managing task execution, and handling agent discovery
962
+
963
+ ## Developer API Reference
964
+
965
+ ### __init__.py
966
+ **Purpose:** Standard Python package initialization file
967
+ **Import:** `from solace_agent_mesh.agent.protocol import *`
968
+
969
+ This is an empty package initialization file and has no public interfaces.
970
+
971
+ ### event_handlers.py
972
+ **Purpose:** Central hub for processing all events related to the A2A protocol. Routes events to appropriate handlers and manages task lifecycle.
973
+ **Import:** `from solace_agent_mesh.agent.protocol.event_handlers import process_event, handle_a2a_request, handle_agent_card_message, handle_a2a_response, publish_agent_card, handle_sam_event, cleanup_agent_session`
974
+
975
+ **Functions:**
976
+ - `process_event(component, event: Event) -> None` - Main event router that processes incoming events and delegates to specific handlers based on event type and topic
977
+ - `handle_a2a_request(component, message: SolaceMessage) -> None` - Handles incoming A2A request messages, starts ADK runner for SendTask requests, and processes CancelTask requests
978
+ - `handle_agent_card_message(component, message: SolaceMessage) -> None` - Processes incoming Agent Card discovery messages and updates peer agent registry
979
+ - `handle_a2a_response(component, message: SolaceMessage) -> None` - Handles responses and status updates from peer agents, manages parallel task completion
980
+ - `publish_agent_card(component) -> None` - Publishes the agent's capabilities and information to the discovery topic
981
+ - `handle_sam_event(component, message: SolaceMessage, topic: str) -> None` - Handles incoming SAM system events like session deletion
982
+ - `cleanup_agent_session(component, session_id: str, user_id: str) -> None` - Cleans up agent-side session data when sessions are deleted
983
+
984
+ **Internal Helper Functions:**
985
+ - `_register_peer_artifacts_in_parent_context(parent_task_context: "TaskExecutionContext", peer_task_object: Task, log_identifier: str) -> None` - Registers artifacts produced by peer agents in the parent task context
986
+ - `_publish_peer_tool_result_notification(component: "SamAgentComponent", correlation_data: Dict[str, Any], payload_to_queue: Any, log_identifier: str) -> None` - Publishes a ToolResultData status update for a completed peer tool call
987
+
988
+ **Usage Examples:**
989
+ ```python
990
+ # Main event processing (typically called by the SAC framework)
991
+ from solace_agent_mesh.agent.protocol.event_handlers import process_event
992
+ from solace_ai_connector.common.event import Event, EventType
993
+
994
+ # Process an incoming event
995
+ await process_event(component, event)
996
+
997
+ # Publish agent discovery card
998
+ from solace_agent_mesh.agent.protocol.event_handlers import publish_agent_card
999
+
1000
+ publish_agent_card(component)
1001
+
1002
+ # Handle specific message types (usually called internally by process_event)
1003
+ from solace_agent_mesh.agent.protocol.event_handlers import handle_a2a_request
1004
+
1005
+ await handle_a2a_request(component, solace_message)
1006
+
1007
+ # Handle SAM system events
1008
+ from solace_agent_mesh.agent.protocol.event_handlers import handle_sam_event
1009
+
1010
+ handle_sam_event(component, message, topic)
1011
+
1012
+ # Clean up session data
1013
+ from solace_agent_mesh.agent.protocol.event_handlers import cleanup_agent_session
1014
+
1015
+ await cleanup_agent_session(component, "session_123", "user_456")
1016
+ ```
1017
+
1018
+ **Key Event Flow:**
1019
+ 1. `process_event()` receives all events and routes based on type (MESSAGE, TIMER, CACHE_EXPIRY)
1020
+ 2. For MESSAGE events, routes to specific handlers based on topic patterns:
1021
+ - Agent request topics → `handle_a2a_request()`
1022
+ - Discovery topics → `handle_agent_card_message()`
1023
+ - Response/status topics → `handle_a2a_response()`
1024
+ - SAM events topics → `handle_sam_event()`
1025
+ 3. For TIMER events, handles periodic agent card publishing
1026
+ 4. For CACHE_EXPIRY events, delegates to component's cache handling
1027
+
1028
+ **Dependencies:**
1029
+ - Requires `SamAgentComponent` instance with proper configuration
1030
+ - Uses A2A protocol types from `a2a.types`
1031
+ - Integrates with Google ADK for task execution
1032
+ - Manages task contexts through `TaskExecutionContext`
1033
+
1034
+ ================================================================================
1035
+
1036
+ ## Section 6: solace_agent_mesh/agent/sac/sac_llm.txt
1037
+
1038
+ **Source file:** `solace_agent_mesh/agent/sac/sac_llm.txt`
1039
+
1040
+ # DEVELOPER GUIDE for the directory: sac
1041
+
1042
+ ## Quick Summary
1043
+ The `sac` (Solace AI Connector) directory provides the core implementation for hosting a Google ADK (Agent Development Kit) agent within the Solace AI Connector framework. It acts as a bridge, enabling ADK agents to communicate using the A2A (Agent-to-Agent) protocol over Solace messaging. This allows for the creation of distributed, collaborative agent systems where agents can delegate tasks, share information, and work together to solve complex problems.
1044
+
1045
+ ## Files Overview
1046
+ - `__init__.py` - Empty package marker file
1047
+ - `app.py` - Custom SAC App class that automatically configures Solace subscriptions and broker settings for A2A communication
1048
+ - `component.py` - Main SAC Component that hosts the ADK agent, manages its lifecycle, and handles all A2A protocol messaging
1049
+ - `patch_adk.py` - Runtime patches for the Google ADK library to enhance or correct its behavior
1050
+ - `task_execution_context.py` - State management class that encapsulates all runtime information for a single, in-flight A2A task
1051
+
1052
+ ## Developer API Reference
1053
+
1054
+ ### app.py
1055
+ **Purpose:** Provides a custom SAC App class that simplifies the configuration of an A2A agent
1056
+ **Import:** `from solace_agent_mesh.agent.sac.app import SamAgentApp`
1057
+
1058
+ **Classes:**
1059
+ - `SamAgentApp(app_info: Dict[str, Any], **kwargs)` - Custom App class for SAM Agent Host with namespace prefixing and automatic subscription generation
1060
+ - `app_schema: Dict` - Class attribute defining comprehensive configuration schema for agent host validation
1061
+
1062
+ **Constants/Variables:**
1063
+ - `info: Dict[str, str]` - Metadata dictionary about the SamAgentApp class for SAC framework discovery
1064
+
1065
+ **Usage Examples:**
1066
+ ```python
1067
+ # SamAgentApp is typically instantiated by the SAC framework from YAML config
1068
+ # Example agent-config.yaml:
1069
+ # app:
1070
+ # class_name: solace_agent_mesh.agent.sac.app.SamAgentApp
1071
+ # app_config:
1072
+ # namespace: "my-org/production"
1073
+ # agent_name: "customer-support-agent"
1074
+ # model: "gemini-1.5-pro-latest"
1075
+ # tools:
1076
+ # - tool_type: "builtin"
1077
+ # tool_name: "file_search"
1078
+ # agent_card:
1079
+ # description: "An agent that can answer questions about customer accounts."
1080
+ # agent_card_publishing:
1081
+ # interval_seconds: 60
1082
+ # session_service:
1083
+ # type: "memory"
1084
+ ```
1085
+
1086
+ ### component.py
1087
+ **Purpose:** Core component that hosts a Google ADK agent and bridges communication to A2A protocol
1088
+ **Import:** `from solace_agent_mesh.agent.sac.component import SamAgentComponent`
1089
+
1090
+ **Classes:**
1091
+ - `SamAgentComponent(**kwargs)` - Solace AI Connector component that hosts a Google ADK agent
1092
+ - `process_event(event: Event) -> None` - Main entry point for all SAC framework events
1093
+ - `handle_timer_event(timer_data: Dict[str, Any]) -> None` - Handles scheduled timer events for agent card publishing
1094
+ - `handle_cache_expiry_event(cache_data: Dict[str, Any]) -> None` - Handles cache expiry events for peer agent timeouts
1095
+ - `finalize_task_success(a2a_context: Dict) -> None` - Async method to finalize successful task completion
1096
+ - `finalize_task_canceled(a2a_context: Dict) -> None` - Finalizes task as CANCELED
1097
+ - `finalize_task_error(exception: Exception, a2a_context: Dict) -> None` - Async method to finalize failed tasks
1098
+ - `cleanup() -> None` - Cleans up resources on component shutdown
1099
+ - `set_agent_specific_state(key: str, value: Any) -> None` - Sets key-value pair in agent state dictionary
1100
+ - `get_agent_specific_state(key: str, default: Optional[Any] = None) -> Any` - Retrieves value from agent state
1101
+ - `get_async_loop() -> Optional[asyncio.AbstractEventLoop]` - Returns dedicated asyncio event loop
1102
+ - `set_agent_system_instruction_string(instruction_string: str) -> None` - Sets static system prompt injection
1103
+ - `set_agent_system_instruction_callback(callback_function: Callable) -> None` - Sets dynamic system prompt callback
1104
+ - `get_gateway_id() -> str` - Returns unique identifier for agent host instance
1105
+ - `submit_a2a_task(target_agent_name: str, a2a_message: A2AMessage, user_id: str, user_config: Dict[str, Any], sub_task_id: str) -> str` - Submits task to peer agent
1106
+ - `get_agent_context() -> Dict[str, Any]` - Returns agent context for middleware interactions
1107
+
1108
+ **Constants/Variables:**
1109
+ - `info: Dict` - Metadata dictionary for SAC framework
1110
+ - `CORRELATION_DATA_PREFIX: str` - Prefix for cache keys when tracking peer requests
1111
+ - `HOST_COMPONENT_VERSION: str` - Version string of the host component
1112
+
1113
+ **Usage Examples:**
1114
+ ```python
1115
+ # Custom initialization function example
1116
+ from solace_agent_mesh.agent.sac.component import SamAgentComponent
1117
+
1118
+ def initialize_my_agent(host_component: SamAgentComponent, config: dict):
1119
+ """Custom initialization function for the agent."""
1120
+ # Store database connection in agent state
1121
+ db_connection = create_database_connection(config.get('db_url'))
1122
+ host_component.set_agent_specific_state('db_connection', db_connection)
1123
+
1124
+ # Set custom system instruction
1125
+ host_component.set_agent_system_instruction_string(
1126
+ "You are a specialized customer service agent with access to our database."
1127
+ )
1128
+
1129
+ # Tool accessing agent state
1130
+ def my_custom_tool(host_component: SamAgentComponent, query: str) -> str:
1131
+ """Tool that uses stored database connection."""
1132
+ db_connection = host_component.get_agent_specific_state('db_connection')
1133
+ if db_connection:
1134
+ return db_connection.execute_query(query)
1135
+ return "Database not available"
1136
+
1137
+ # Scheduling async work from synchronous code
1138
+ def schedule_background_task(host_component: SamAgentComponent):
1139
+ """Schedule async work on the component's event loop."""
1140
+ loop = host_component.get_async_loop()
1141
+ if loop:
1142
+ asyncio.run_coroutine_threadsafe(my_async_task(), loop)
1143
+ ```
1144
+
1145
+ ### patch_adk.py
1146
+ **Purpose:** Contains runtime patches for the Google ADK library to enhance behavior
1147
+ **Import:** `from solace_agent_mesh.agent.sac.patch_adk import patch_adk`
1148
+
1149
+ **Functions:**
1150
+ - `patch_adk() -> None` - Applies all necessary patches to the ADK library
1151
+
1152
+ **Usage Examples:**
1153
+ ```python
1154
+ from solace_agent_mesh.agent.sac.patch_adk import patch_adk
1155
+
1156
+ # Apply patches before using ADK
1157
+ patch_adk()
1158
+ ```
1159
+
1160
+ ### task_execution_context.py
1161
+ **Purpose:** State management class for single, in-flight agent tasks
1162
+ **Import:** `from solace_agent_mesh.agent.sac.task_execution_context import TaskExecutionContext`
1163
+
1164
+ **Classes:**
1165
+ - `TaskExecutionContext(task_id: str, a2a_context: Dict[str, Any])` - Encapsulates runtime state for a single agent task
1166
+ - `cancel() -> None` - Signals that the task should be cancelled
1167
+ - `is_cancelled() -> bool` - Checks if cancellation event has been set
1168
+ - `append_to_streaming_buffer(text: str) -> None` - Appends text to streaming buffer
1169
+ - `flush_streaming_buffer() -> str` - Returns and clears streaming buffer content
1170
+ - `get_streaming_buffer_content() -> str` - Returns buffer content without clearing
1171
+ - `append_to_run_based_buffer(text: str) -> None` - Appends text to run-based response buffer
1172
+ - `register_peer_sub_task(sub_task_id: str, correlation_data: Dict[str, Any]) -> None` - Adds peer sub-task tracking
1173
+ - `claim_sub_task_completion(sub_task_id: str) -> Optional[Dict[str, Any]]` - Atomically retrieves and removes sub-task data
1174
+ - `register_parallel_call_sent(invocation_id: str) -> None` - Registers new parallel tool call
1175
+ - `handle_peer_timeout(sub_task_id: str, correlation_data: Dict, timeout_sec: int, invocation_id: str) -> bool` - Handles peer timeout
1176
+ - `record_parallel_result(result: Dict, invocation_id: str) -> bool` - Records parallel tool call result
1177
+ - `clear_parallel_invocation_state(invocation_id: str) -> None` - Removes completed invocation state
1178
+ - `register_produced_artifact(filename: str, version: int) -> None` - Tracks newly created artifacts
1179
+ - `add_artifact_signal(signal: Dict[str, Any]) -> None` - Adds artifact return signal
1180
+ - `get_and_clear_artifact_signals() -> List[Dict[str, Any]]` - Retrieves and clears artifact signals
1181
+ - `set_event_loop(loop: asyncio.AbstractEventLoop) -> None` - Stores event loop reference
1182
+ - `get_event_loop() -> Optional[asyncio.AbstractEventLoop]` - Retrieves stored event loop
1183
+ - `record_token_usage(input_tokens: int, output_tokens: int, model: str, source: str = "agent", tool_name: Optional[str] = None, cached_input_tokens: int = 0) -> None` - Records token usage for LLM calls
1184
+ - `get_token_usage_summary() -> Dict[str, Any]` - Returns summary of all token usage for the task
1185
+
1186
+ **Usage Examples:**
1187
+ ```python
1188
+ from solace_agent_mesh.agent.sac.task_execution_context import TaskExecutionContext
1189
+
1190
+ # Create task context
1191
+ a2a_context = {
1192
+ "logical_task_id": "task-123",
1193
+ "user_id": "user-456",
1194
+ "session_id": "session-789"
1195
+ }
1196
+ task_context = TaskExecutionContext("task-123", a2a_context)
1197
+
1198
+ # Use streaming buffer
1199
+ task_context.append_to_streaming_buffer("Hello ")
1200
+ task_context.append_to_streaming_buffer("world!")
1201
+ content = task_context.flush_streaming_buffer() # Returns "Hello world!"
1202
+
1203
+ # Track peer sub-tasks
1204
+ correlation_data = {
1205
+ "peer_agent_name": "math-agent",
1206
+ "adk_function_call_id": "call-123"
1207
+ }
1208
+ task_context.register_peer_sub_task("sub-task-456", correlation_data)
1209
+
1210
+ # Handle completion
1211
+ completed_data = task_context.claim_sub_task_completion("sub-task-456")
1212
+ if completed_data:
1213
+ print(f"Sub-task completed: {completed_data}")
1214
+
1215
+ # Track token usage
1216
+ task_context.record_token_usage(
1217
+ input_tokens=100,
1218
+ output_tokens=50,
1219
+ model="gemini-1.5-pro",
1220
+ source="agent"
1221
+ )
1222
+
1223
+ # Get usage summary
1224
+ usage = task_context.get_token_usage_summary()
1225
+ print(f"Total tokens used: {usage['total_tokens']}")
1226
+ ```
1227
+
1228
+ ================================================================================
1229
+
1230
+ ## Section 7: solace_agent_mesh/agent/testing/testing_llm.txt
1231
+
1232
+ **Source file:** `solace_agent_mesh/agent/testing/testing_llm.txt`
1233
+
1234
+ ## Quick Summary
1235
+ The `testing` directory provides utilities for testing the A2A (Agent-to-Agent) framework, with a focus on debugging tools that help developers understand test failures by providing readable representations of agent event histories.
1236
+
1237
+ ## Files Overview
1238
+ - `__init__.py` - Package initialization file marking the directory as a Python module
1239
+ - `debug_utils.py` - Debugging utilities including pretty-printing for A2A event history
1240
+ - `testing_llm.txt` - Documentation file (not a code module)
1241
+
1242
+ ## Developer API Reference
1243
+
1244
+ ### debug_utils.py
1245
+ **Purpose:** Provides debugging utilities for the declarative test framework, including a pretty-printer for A2A event history
1246
+ **Import:** `from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history`
1247
+
1248
+ **Functions:**
1249
+ - `pretty_print_event_history(event_history: List[Dict[str, Any]], max_string_length: int = 200) -> None` - Formats and prints a list of A2A event payloads for debugging, intelligently parsing different event types and truncating long strings for readability
1250
+
1251
+ **Usage Examples:**
1252
+ ```python
1253
+ # Import the debugging utility
1254
+ from solace_agent_mesh.agent.testing.debug_utils import pretty_print_event_history
1255
+ from typing import List, Dict, Any
1256
+
1257
+ # Example: Debug a failed test by printing event history
1258
+ event_history: List[Dict[str, Any]] = [
1259
+ {
1260
+ "result": {
1261
+ "status": {
1262
+ "state": "EXECUTING",
1263
+ "message": {
1264
+ "parts": [
1265
+ {"type": "text", "text": "Processing your request..."}
1266
+ ]
1267
+ }
1268
+ },
1269
+ "final": False
1270
+ }
1271
+ },
1272
+ {
1273
+ "error": {
1274
+ "code": "TIMEOUT_ERROR",
1275
+ "message": "Request timed out after 30 seconds"
1276
+ }
1277
+ }
1278
+ ]
1279
+
1280
+ # Print formatted event history for debugging
1281
+ pretty_print_event_history(event_history)
1282
+
1283
+ # Print with custom string truncation length
1284
+ pretty_print_event_history(event_history, max_string_length=100)
1285
+
1286
+ # Handle empty event history (when test fails before any events)
1287
+ pretty_print_event_history([])
1288
+ ```
1289
+
1290
+ ================================================================================
1291
+
1292
+ ## Section 8: solace_agent_mesh/agent/tools/tools_llm.txt
1293
+
1294
+ **Source file:** `solace_agent_mesh/agent/tools/tools_llm.txt`
1295
+
1296
+ # DEVELOPER GUIDE: tools
1297
+
1298
+ ## Quick Summary
1299
+ The `tools` directory contains the complete tool system for the Solace Agent Mesh, providing built-in tools for artifact management, data analysis, audio/image processing, web interactions, and dynamic tool creation. It includes a registry system for tool discovery and management, with support for declarative YAML-based configurations and multiple tool types including built-in, custom Python, and MCP tools.
1300
+
1301
+ ## Files Overview
1302
+ - `__init__.py` - Ensures all built-in tool modules are imported for declarative registration
1303
+ - `audio_tools.py` - Audio processing tools including TTS, transcription, and audio manipulation
1304
+ - `builtin_artifact_tools.py` - Core artifact management tools for CRUD operations and content processing
1305
+ - `builtin_data_analysis_tools.py` - Data analysis tools for creating charts from Plotly configurations
1306
+ - `dynamic_tool.py` - Base classes for creating dynamic, programmatically-defined tools
1307
+ - `general_agent_tools.py` - General-purpose tools for file conversion and diagram generation
1308
+ - `image_tools.py` - Image generation, editing, and multimodal content analysis tools
1309
+ - `peer_agent_tool.py` - Tool for delegating tasks to peer agents over Solace messaging
1310
+ - `registry.py` - Singleton registry for tool discovery and management
1311
+ - `test_tools.py` - Testing utilities for timeouts and error handling
1312
+ - `tool_config_types.py` - Pydantic models for YAML-based tool configurations
1313
+ - `tool_definition.py` - Base tool definition classes and structures
1314
+ - `web_tools.py` - Web scraping and content extraction tools
1315
+
1316
+ ## Developer API Reference
1317
+
1318
+ ### __init__.py
1319
+ **Purpose:** Triggers tool registration by importing all tool modules
1320
+ **Import:** `from solace_agent_mesh.agent.tools import *`
1321
+
1322
+ No public classes or functions - this is an initialization module.
1323
+
1324
+ ### audio_tools.py
1325
+ **Purpose:** Provides comprehensive audio processing capabilities
1326
+ **Import:** `from solace_agent_mesh.agent.tools.audio_tools import select_voice, text_to_speech, multi_speaker_text_to_speech, concatenate_audio, transcribe_audio`
1327
+
1328
+ **Functions:**
1329
+ - `select_voice(gender: Optional[str] = None, tone: Optional[str] = None, exclude_voices: Optional[List[str]] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Selects a suitable voice based on gender and tone criteria
1330
+ - `text_to_speech(text: str, output_filename: Optional[str] = None, voice_name: Optional[str] = None, gender: Optional[str] = None, tone: Optional[str] = None, language: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Converts text to speech using Gemini TTS API
1331
+ - `multi_speaker_text_to_speech(conversation_text: str, output_filename: Optional[str] = None, speaker_configs: Optional[List[Dict[str, str]]] = None, language: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Creates multi-speaker audio from conversation text
1332
+ - `concatenate_audio(clips_to_join: List[Dict[str, Any]], output_filename: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Combines multiple audio clips with custom pause durations
1333
+ - `transcribe_audio(audio_filename: str, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Transcribes audio using OpenAI-compatible API
1334
+
1335
+ **Constants/Variables:**
1336
+ - `VOICE_TONE_MAPPING: Dict[str, List[str]]` - Maps tone preferences to available voices
1337
+ - `GENDER_TO_VOICE_MAPPING: Dict[str, List[str]]` - Maps gender preferences to available voices
1338
+ - `ALL_AVAILABLE_VOICES: List[str]` - Complete list of available voice names
1339
+ - `SUPPORTED_LANGUAGES: Dict[str, str]` - Maps language names to BCP-47 codes
1340
+
1341
+ **Usage Examples:**
1342
+ ```python
1343
+ # Basic text-to-speech
1344
+ result = await text_to_speech(
1345
+ text="Hello, world!",
1346
+ voice_name="Kore",
1347
+ tool_context=context
1348
+ )
1349
+
1350
+ # Multi-speaker conversation
1351
+ conversation = "Speaker1: Hello there!\nSpeaker2: Hi, how are you?"
1352
+ result = await multi_speaker_text_to_speech(
1353
+ conversation_text=conversation,
1354
+ speaker_configs=[
1355
+ {"name": "Speaker1", "gender": "female", "tone": "friendly"},
1356
+ {"name": "Speaker2", "gender": "male", "tone": "casual"}
1357
+ ],
1358
+ tool_context=context
1359
+ )
1360
+ ```
1361
+
1362
+ ### builtin_artifact_tools.py
1363
+ **Purpose:** Core artifact management and content processing tools
1364
+ **Import:** `from solace_agent_mesh.agent.tools.builtin_artifact_tools import list_artifacts, load_artifact, signal_artifact_for_return, apply_embed_and_create_artifact, extract_content_from_artifact, append_to_artifact, delete_artifact`
1365
+
1366
+ **Functions:**
1367
+ - `list_artifacts(tool_context: ToolContext = None) -> Dict[str, Any]` - Lists all available artifacts with metadata summaries
1368
+ - `load_artifact(filename: str, version: int, load_metadata_only: bool = False, max_content_length: Optional[int] = None, tool_context: ToolContext = None) -> Dict[str, Any]` - Loads artifact content or metadata
1369
+ - `signal_artifact_for_return(filename: str, version: int, tool_context: ToolContext = None) -> Dict[str, Any]` - Signals artifact to be returned to caller
1370
+ - `apply_embed_and_create_artifact(output_filename: str, embed_directive: str, output_metadata: Optional[Dict[str, Any]] = None, tool_context: ToolContext = None) -> Dict[str, Any]` - Resolves embed directives and creates new artifacts
1371
+ - `extract_content_from_artifact(filename: str, extraction_goal: str, version: Optional[str] = "latest", output_filename_base: Optional[str] = None, tool_context: ToolContext = None) -> Dict[str, Any]` - Uses LLM to extract/transform artifact content
1372
+ - `append_to_artifact(filename: str, content_chunk: str, mime_type: str, tool_context: ToolContext = None) -> Dict[str, Any]` - Appends content to existing artifacts
1373
+ - `delete_artifact(filename: str, version: Optional[int] = None, tool_context: ToolContext = None) -> Dict[str, Any]` - Deletes artifact versions
1374
+
1375
+ **Usage Examples:**
1376
+ ```python
1377
+ # List all artifacts
1378
+ artifacts = await list_artifacts(tool_context=context)
1379
+
1380
+ # Load specific artifact version
1381
+ content = await load_artifact(
1382
+ filename="data.csv",
1383
+ version=1,
1384
+ tool_context=context
1385
+ )
1386
+
1387
+ # Extract content using LLM
1388
+ result = await extract_content_from_artifact(
1389
+ filename="report.pdf",
1390
+ extraction_goal="Extract all financial figures and create a summary table",
1391
+ tool_context=context
1392
+ )
1393
+ ```
1394
+
1395
+ ### builtin_data_analysis_tools.py
1396
+ **Purpose:** Data analysis and visualization tools
1397
+ **Import:** `from solace_agent_mesh.agent.tools.builtin_data_analysis_tools import create_chart_from_plotly_config`
1398
+
1399
+ **Functions:**
1400
+ - `create_chart_from_plotly_config(config_content: str, config_format: Literal["json", "yaml"], output_filename: str, output_format: Optional[str] = "png", tool_context: ToolContext = None) -> Dict[str, Any]` - Generates static chart images from Plotly configurations
1401
+
1402
+ **Usage Examples:**
1403
+ ```python
1404
+ # Create chart from JSON config
1405
+ plotly_config = '{"data": [{"x": [1,2,3], "y": [4,5,6], "type": "scatter"}]}'
1406
+ result = await create_chart_from_plotly_config(
1407
+ config_content=plotly_config,
1408
+ config_format="json",
1409
+ output_filename="my_chart.png",
1410
+ tool_context=context
1411
+ )
1412
+ ```
1413
+
1414
+ ### dynamic_tool.py
1415
+ **Purpose:** Base classes for creating dynamic, programmatically-defined tools
1416
+ **Import:** `from solace_agent_mesh.agent.tools.dynamic_tool import DynamicTool, DynamicToolProvider`
1417
+
1418
+ **Classes:**
1419
+ - `DynamicTool(tool_config: Optional[Union[dict, BaseModel]] = None)` - Base class for dynamic tools with programmatic definitions
1420
+ - `tool_name: str` - Property returning the function name for LLM calls
1421
+ - `tool_description: str` - Property returning tool description
1422
+ - `parameters_schema: adk_types.Schema` - Property returning parameter schema
1423
+ - `raw_string_args: List[str]` - Property listing args that skip embed resolution
1424
+ - `resolution_type: Literal["early", "all"]` - Property determining embed resolution scope
1425
+ - `run_async(*, args: Dict[str, Any], tool_context: ToolContext) -> Dict[str, Any]` - Executes the tool with embed resolution
1426
+ - `_run_async_impl(args: dict, tool_context: ToolContext, credential: Optional[str] = None) -> dict` - Abstract method for tool implementation
1427
+
1428
+ - `DynamicToolProvider()` - Base class for tool providers that generate multiple tools
1429
+ - `register_tool(func: Callable) -> Callable` - Class method decorator for registering functions as tools
1430
+ - `create_tools(tool_config: Optional[Union[dict, BaseModel]] = None) -> List[DynamicTool]` - Abstract method for creating custom tools
1431
+ - `get_all_tools_for_framework(tool_config: Optional[Union[dict, BaseModel]] = None) -> List[DynamicTool]` - Framework method combining decorated and custom tools
1432
+
1433
+ **Usage Examples:**
1434
+ ```python
1435
+ # Create a custom dynamic tool
1436
+ class MyCustomTool(DynamicTool):
1437
+ @property
1438
+ def tool_name(self) -> str:
1439
+ return "my_custom_tool"
1440
+
1441
+ @property
1442
+ def tool_description(self) -> str:
1443
+ return "Does something custom"
1444
+
1445
+ @property
1446
+ def parameters_schema(self) -> adk_types.Schema:
1447
+ return adk_types.Schema(
1448
+ type=adk_types.Type.OBJECT,
1449
+ properties={
1450
+ "input": adk_types.Schema(type=adk_types.Type.STRING)
1451
+ },
1452
+ required=["input"]
1453
+ )
1454
+
1455
+ async def _run_async_impl(self, args: dict, tool_context: ToolContext, credential: Optional[str] = None) -> dict:
1456
+ return {"result": f"Processed: {args['input']}"}
1457
+
1458
+ # Create a tool provider with decorated methods
1459
+ class MyToolProvider(DynamicToolProvider):
1460
+ @DynamicToolProvider.register_tool
1461
+ async def my_decorated_tool(self, param1: str, tool_context: ToolContext) -> dict:
1462
+ """This tool does something useful."""
1463
+ return {"status": "success", "input": param1}
1464
+
1465
+ def create_tools(self, tool_config: Optional[Union[dict, BaseModel]] = None) -> List[DynamicTool]:
1466
+ return [MyCustomTool(tool_config)]
1467
+ ```
1468
+
1469
+ ### general_agent_tools.py
1470
+ **Purpose:** General-purpose utility tools for file conversion and diagram generation
1471
+ **Import:** `from solace_agent_mesh.agent.tools.general_agent_tools import convert_file_to_markdown, mermaid_diagram_generator`
1472
+
1473
+ **Functions:**
1474
+ - `convert_file_to_markdown(input_filename: str, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Converts files to Markdown using MarkItDown library
1475
+ - `mermaid_diagram_generator(mermaid_syntax: str, output_filename: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Generates PNG images from Mermaid diagram syntax
1476
+
1477
+ **Usage Examples:**
1478
+ ```python
1479
+ # Convert PDF to Markdown
1480
+ result = await convert_file_to_markdown(
1481
+ input_filename="document.pdf",
1482
+ tool_context=context
1483
+ )
1484
+
1485
+ # Generate Mermaid diagram
1486
+ mermaid_code = """
1487
+ graph TD
1488
+ A[Start] --> B[Process]
1489
+ B --> C[End]
1490
+ """
1491
+ result = await mermaid_diagram_generator(
1492
+ mermaid_syntax=mermaid_code,
1493
+ output_filename="flowchart.png",
1494
+ tool_context=context
1495
+ )
1496
+ ```
1497
+
1498
+ ### image_tools.py
1499
+ **Purpose:** Image generation, editing, and multimodal content analysis
1500
+ **Import:** `from solace_agent_mesh.agent.tools.image_tools import create_image_from_description, describe_image, describe_audio, edit_image_with_gemini`
1501
+
1502
+ **Functions:**
1503
+ - `create_image_from_description(image_description: str, output_filename: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Generates images from text descriptions
1504
+ - `describe_image(image_filename: str, prompt: str = "What is in this image?", tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Describes images using vision APIs
1505
+ - `describe_audio(audio_filename: str, prompt: str = "What is in this recording?", tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Describes audio using multimodal APIs
1506
+ - `edit_image_with_gemini(image_filename: str, edit_prompt: str, output_filename: Optional[str] = None, tool_context: ToolContext = None, tool_config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]` - Edits images using Gemini 2.0 Flash
1507
+
1508
+ **Usage Examples:**
1509
+ ```python
1510
+ # Generate image from description
1511
+ result = await create_image_from_description(
1512
+ image_description="A sunset over mountains with a lake in the foreground",
1513
+ output_filename="sunset.png",
1514
+ tool_context=context
1515
+ )
1516
+
1517
+ # Describe an existing image
1518
+ result = await describe_image(
1519
+ image_filename="photo.jpg",
1520
+ prompt="What objects are visible in this image?",
1521
+ tool_context=context
1522
+ )
1523
+
1524
+ # Edit an image
1525
+ result = await edit_image_with_gemini(
1526
+ image_filename="original.jpg",
1527
+ edit_prompt="Add a rainbow in the sky",
1528
+ tool_context=context
1529
+ )
1530
+ ```
1531
+
1532
+ ### peer_agent_tool.py
1533
+ **Purpose:** Enables task delegation to peer agents over Solace messaging
1534
+ **Import:** `from solace_agent_mesh.agent.tools.peer_agent_tool import PeerAgentTool`
1535
+
1536
+ **Classes:**
1537
+ - `PeerAgentTool(target_agent_name: str, host_component)` - Tool for delegating tasks to peer agents
1538
+ - `target_agent_name: str` - Name of the peer agent
1539
+ - `host_component` - Reference to the SamAgentComponent
1540
+ - `is_long_running: bool` - Always True for async delegation
1541
+ - `run_async(*, args: Dict[str, Any], tool_context: ToolContext) -> Any` - Delegates task to peer agent
1542
+
1543
+ **Usage Examples:**
1544
+ ```python
1545
+ # Create peer agent tool (typically done by framework)
1546
+ peer_tool = PeerAgentTool("data_analyst_agent", host_component)
1547
+
1548
+ # Tool is called by LLM with these parameters:
1549
+ # {
1550
+ # "task_description": "Analyze the sales data and create a summary report",
1551
+ # "user_query": "What were our top performing products last quarter?",
1552
+ # "artifacts": [{"filename": "sales_data.csv", "version": "latest"}]
1553
+ # }
1554
+ ```
1555
+
1556
+ ### registry.py
1557
+
1558
+ ================================================================================
1559
+
1560
+ ## Section 9: solace_agent_mesh/agent/utils/utils_llm.txt
1561
+
1562
+ **Source file:** `solace_agent_mesh/agent/utils/utils_llm.txt`
1563
+
1564
+ ## Quick Summary
1565
+ The `utils` directory provides a collection of helper modules designed to support the core functionality of the agent. These utilities encapsulate common, reusable logic for tasks such as artifact management (saving, loading, schema inference), configuration parsing, and safe interaction with the ADK's invocation context.
1566
+
1567
+ ## Files Overview
1568
+ - `__init__.py` - Empty package marker file
1569
+ - `artifact_helpers.py` - Comprehensive artifact management functions including save/load operations, metadata handling, and schema inference
1570
+ - `config_parser.py` - Configuration parsing utilities for resolving instruction providers
1571
+ - `context_helpers.py` - Safe utilities for extracting data from ADK callback and invocation contexts
1572
+
1573
+ ## Developer API Reference
1574
+
1575
+ ### artifact_helpers.py
1576
+ **Purpose:** Comprehensive artifact management with automatic metadata generation, schema inference, and async operations
1577
+ **Import:** `from solace_agent_mesh.agent.utils.artifact_helpers import save_artifact_with_metadata, load_artifact_content_or_metadata, get_artifact_info_list, is_filename_safe, ensure_correct_extension`
1578
+
1579
+ **Functions:**
1580
+ - `is_filename_safe(filename: str) -> bool` - Validates filename safety (no path traversal, separators, or reserved names)
1581
+ - `ensure_correct_extension(filename_from_llm: str, desired_extension: str) -> str` - Ensures filename has correct extension
1582
+ - `format_artifact_uri(app_name: str, user_id: str, session_id: str, filename: str, version: Union[int, str]) -> str` - Formats components into standard artifact:// URI
1583
+ - `parse_artifact_uri(uri: str) -> Dict[str, Any]` - Parses artifact:// URI into constituent parts
1584
+ - `save_artifact_with_metadata(artifact_service: BaseArtifactService, app_name: str, user_id: str, session_id: str, filename: str, content_bytes: bytes, mime_type: str, metadata_dict: Dict[str, Any], timestamp: datetime, explicit_schema: Optional[Dict] = None, schema_inference_depth: int = 2, schema_max_keys: int = 20, tool_context: Optional["ToolContext"] = None) -> Dict[str, Any]` - Saves artifact with auto-generated metadata and schema inference
1585
+ - `load_artifact_content_or_metadata(artifact_service: BaseArtifactService, app_name: str, user_id: str, session_id: str, filename: str, version: Union[int, str], load_metadata_only: bool = False, return_raw_bytes: bool = False, max_content_length: Optional[int] = None, component: Optional[Any] = None, log_identifier_prefix: str = "[ArtifactHelper:load]", encoding: str = "utf-8", error_handling: str = "strict") -> Dict[str, Any]` - Loads artifact content or metadata with flexible options
1586
+ - `get_artifact_info_list(artifact_service: BaseArtifactService, app_name: str, user_id: str, session_id: str) -> List[ArtifactInfo]` - Retrieves detailed info for all artifacts
1587
+ - `get_latest_artifact_version(artifact_service: BaseArtifactService, app_name: str, user_id: str, session_id: str, filename: str) -> Optional[int]` - Gets latest version number for an artifact
1588
+ - `format_metadata_for_llm(metadata: Dict[str, Any]) -> str` - Formats metadata into LLM-friendly text
1589
+ - `decode_and_get_bytes(content_str: str, mime_type: str, log_identifier: str) -> Tuple[bytes, str]` - Decodes content based on MIME type (base64 for binary, UTF-8 for text)
1590
+ - `generate_artifact_metadata_summary(component: "SamAgentComponent", artifact_identifiers: List[Dict[str, Any]], user_id: str, session_id: str, app_name: str, header_text: Optional[str] = None) -> str` - Generates YAML summary of multiple artifacts' metadata
1591
+
1592
+ **Constants/Variables:**
1593
+ - `METADATA_SUFFIX: str` - Suffix for metadata files (".metadata.json")
1594
+ - `DEFAULT_SCHEMA_MAX_KEYS: int` - Default max keys for schema inference (20)
1595
+
1596
+ **Usage Examples:**
1597
+ ```python
1598
+ import asyncio
1599
+ from datetime import datetime, timezone
1600
+ from solace_agent_mesh.agent.utils.artifact_helpers import (
1601
+ save_artifact_with_metadata,
1602
+ load_artifact_content_or_metadata,
1603
+ get_artifact_info_list,
1604
+ ensure_correct_extension,
1605
+ format_artifact_uri,
1606
+ parse_artifact_uri
1607
+ )
1608
+
1609
+ async def artifact_example():
1610
+ # Ensure safe filename
1611
+ safe_name = ensure_correct_extension("report", "csv") # -> "report.csv"
1612
+
1613
+ # Save artifact with metadata
1614
+ csv_data = b"name,age\nAlice,30\nBob,25"
1615
+ result = await save_artifact_with_metadata(
1616
+ artifact_service=service,
1617
+ app_name="my_app",
1618
+ user_id="user123",
1619
+ session_id="session456",
1620
+ filename=safe_name,
1621
+ content_bytes=csv_data,
1622
+ mime_type="text/csv",
1623
+ metadata_dict={"source": "user_upload", "description": "Employee data"},
1624
+ timestamp=datetime.now(timezone.utc)
1625
+ )
1626
+
1627
+ # Load artifact content
1628
+ loaded = await load_artifact_content_or_metadata(
1629
+ artifact_service=service,
1630
+ app_name="my_app",
1631
+ user_id="user123",
1632
+ session_id="session456",
1633
+ filename=safe_name,
1634
+ version="latest"
1635
+ )
1636
+
1637
+ # Work with artifact URIs
1638
+ uri = format_artifact_uri("my_app", "user123", "session456", "report.csv", 1)
1639
+ # Returns: "artifact://my_app/user123/session456/report.csv?version=1"
1640
+
1641
+ parsed = parse_artifact_uri(uri)
1642
+ # Returns: {"app_name": "my_app", "user_id": "user123", ...}
1643
+
1644
+ # List all artifacts
1645
+ artifacts = await get_artifact_info_list(
1646
+ artifact_service=service,
1647
+ app_name="my_app",
1648
+ user_id="user123",
1649
+ session_id="session456"
1650
+ )
1651
+ ```
1652
+
1653
+ ### config_parser.py
1654
+ **Purpose:** Resolves configuration values that can be static strings or dynamic callable providers
1655
+ **Import:** `from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider, InstructionProvider`
1656
+
1657
+ **Functions:**
1658
+ - `resolve_instruction_provider(component, config_value: Any) -> Union[str, InstructionProvider]` - Resolves instruction config from string or invoke block
1659
+
1660
+ **Usage Examples:**
1661
+ ```python
1662
+ from solace_agent_mesh.agent.utils.config_parser import resolve_instruction_provider
1663
+
1664
+ # Static string instruction
1665
+ instruction = resolve_instruction_provider(component, "You are a helpful assistant.")
1666
+ # Returns: "You are a helpful assistant."
1667
+
1668
+ # Dynamic instruction provider (from YAML invoke block)
1669
+ def dynamic_instruction(context):
1670
+ return f"Assistant for {context.user_id}"
1671
+
1672
+ instruction_func = resolve_instruction_provider(component, dynamic_instruction)
1673
+ # Returns: the callable function
1674
+ ```
1675
+
1676
+ ### context_helpers.py
1677
+ **Purpose:** Safe utilities for extracting information from ADK contexts
1678
+ **Import:** `from solace_agent_mesh.agent.utils.context_helpers import get_session_from_callback_context, get_original_session_id`
1679
+
1680
+ **Functions:**
1681
+ - `get_session_from_callback_context(callback_context: CallbackContext) -> Session` - Safely extracts Session object from CallbackContext
1682
+ - `get_original_session_id(invocation_context: Any) -> str` - Extracts base session ID, removing any colon-separated suffixes
1683
+
1684
+ **Usage Examples:**
1685
+ ```python
1686
+ from solace_agent_mesh.agent.utils.context_helpers import (
1687
+ get_session_from_callback_context,
1688
+ get_original_session_id
1689
+ )
1690
+
1691
+ # In a tool function with callback_context
1692
+ def my_tool(callback_context):
1693
+ # Get full session object
1694
+ session = get_session_from_callback_context(callback_context)
1695
+
1696
+ # Get original session ID (strips suffixes after colon)
1697
+ original_id = get_original_session_id(tool_context._invocation_context)
1698
+ # "session123:tool456" -> "session123"
1699
+ ```
1700
+
1701
+ ================================================================================
1702
+