solace-agent-mesh 1.4.12__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 (181) 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/callbacks.py +51 -2
  5. solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
  6. solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
  7. solace_agent_mesh/agent/agent_llm.txt +1 -1
  8. solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
  9. solace_agent_mesh/agent/protocol/event_handlers.py +2 -13
  10. solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
  11. solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
  12. solace_agent_mesh/agent/sac/component.py +51 -21
  13. solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
  14. solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
  15. solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
  16. solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
  17. solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
  18. solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
  19. solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
  20. solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
  21. solace_agent_mesh/assets/docs/404.html +3 -3
  22. solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +1 -0
  23. solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js → main.0c149855.js} +2 -2
  24. solace_agent_mesh/assets/docs/assets/js/{runtime~main.40527046.js → runtime~main.c66557e4.js} +1 -1
  25. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
  26. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +3 -3
  27. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +8 -4
  28. 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
  29. solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
  35. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
  38. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +3 -3
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
  43. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
  44. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +3 -3
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
  64. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
  65. solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +1 -0
  66. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  67. solace_agent_mesh/assets/docs/search-doc-1760032255022.json +1 -0
  68. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  69. solace_agent_mesh/cli/__init__.py +1 -1
  70. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
  71. solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
  72. solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +1 -0
  73. solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +339 -0
  74. solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
  75. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
  76. solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
  77. solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
  78. solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
  79. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
  80. solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
  81. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
  82. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
  83. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
  84. solace_agent_mesh/common/common_llm.txt +24 -39
  85. solace_agent_mesh/common/common_llm_detail.txt +2562 -0
  86. solace_agent_mesh/common/data_parts.py +9 -1
  87. solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
  88. solace_agent_mesh/common/sac/sac_llm.txt +1 -1
  89. solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
  90. solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
  91. solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
  92. solace_agent_mesh/common/services/services_llm.txt +57 -6
  93. solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
  94. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
  95. solace_agent_mesh/common/utils/utils_llm.txt +75 -87
  96. solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
  97. solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
  98. solace_agent_mesh/gateway/base/app.py +1 -1
  99. solace_agent_mesh/gateway/base/base_llm.txt +1 -1
  100. solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
  101. solace_agent_mesh/gateway/gateway_llm.txt +242 -235
  102. solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
  103. solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
  104. solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
  105. solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
  106. solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
  107. solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
  108. solace_agent_mesh/gateway/http_sse/app.py +148 -2
  109. solace_agent_mesh/gateway/http_sse/component.py +368 -60
  110. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
  111. solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +108 -0
  112. solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +1 -1
  113. solace_agent_mesh/gateway/http_sse/dependencies.py +116 -26
  114. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
  115. solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
  116. solace_agent_mesh/gateway/http_sse/main.py +146 -41
  117. solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
  118. solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
  119. solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
  120. solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
  121. solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
  122. solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
  123. solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
  124. solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
  125. solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
  126. solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
  127. solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
  128. solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
  129. solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
  130. solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
  131. solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
  132. solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
  133. solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
  134. solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
  135. solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
  136. solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
  137. solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
  138. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1 -1
  139. solace_agent_mesh/gateway/http_sse/routers/config.py +26 -4
  140. solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
  141. solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
  142. solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
  143. solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
  144. solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
  145. solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
  146. solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
  147. solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
  148. solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
  149. solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
  150. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
  151. solace_agent_mesh/gateway/http_sse/routers/sessions.py +220 -40
  152. solace_agent_mesh/gateway/http_sse/routers/tasks.py +168 -42
  153. solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +272 -0
  154. solace_agent_mesh/gateway/http_sse/services/feedback_service.py +241 -0
  155. solace_agent_mesh/gateway/http_sse/services/people_service.py +0 -80
  156. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
  157. solace_agent_mesh/gateway/http_sse/services/session_service.py +151 -84
  158. solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +317 -0
  159. solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
  160. solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
  161. solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
  162. solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
  163. solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
  164. solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
  165. solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
  166. solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
  167. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/METADATA +1 -1
  168. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/RECORD +172 -124
  169. solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
  170. solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
  171. solace_agent_mesh/assets/docs/lunr-index-1759936913198.json +0 -1
  172. solace_agent_mesh/assets/docs/search-doc-1759936913198.json +0 -1
  173. solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
  174. solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
  175. solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
  176. solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
  177. solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
  178. /solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js.LICENSE.txt → main.0c149855.js.LICENSE.txt} +0 -0
  179. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/WHEEL +0 -0
  180. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/entry_points.txt +0 -0
  181. {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,459 @@
1
+ # LLM Summary Detail File
2
+
3
+ This file is a concatenation of all individual *llm.txt files found in the 'services' directory tree. Each section below corresponds to a specific directory's summary file.
4
+
5
+ ================================================================================
6
+
7
+ ## Section 1: solace_agent_mesh/common/services/providers/providers_llm.txt
8
+
9
+ **Source file:** `solace_agent_mesh/common/services/providers/providers_llm.txt`
10
+
11
+ ## Quick Summary
12
+ This directory contains concrete implementations (providers) for the abstract services defined in the parent `services` package. These providers offer specific ways to fulfill service contracts, such as sourcing user identity information from a local file.
13
+
14
+ ## Files Overview
15
+ - `__init__.py` - Package initialization file marking the directory as a Python package
16
+ - `local_file_identity_service.py` - File-based identity service implementation that reads user data from local JSON files
17
+
18
+ ## Developer API Reference
19
+
20
+ ### __init__.py
21
+ **Purpose:** Initializes the providers package
22
+ **Import:** `from solace_agent_mesh.common.services import providers`
23
+
24
+ This file contains no public classes or functions - it serves only as package documentation.
25
+
26
+ ### local_file_identity_service.py
27
+ **Purpose:** Provides a file-based identity service that reads user profiles from a local JSON file, ideal for development, testing, or small-scale deployments
28
+ **Import:** `from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService`
29
+
30
+ **Classes:**
31
+ - `LocalFileIdentityService(config: Dict[str, Any])` - Identity service that sources user data from a local JSON file
32
+ - `async get_user_profile(auth_claims: Dict[str, Any]) -> Optional[Dict[str, Any]]` - Looks up a user profile using the lookup key from auth claims
33
+ - `async search_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Performs case-insensitive search on user names and emails
34
+ - `file_path: str` - Path to the JSON file containing user data
35
+ - `lookup_key: str` - Key used to identify users (defaults to "id")
36
+ - `all_users: List[Dict[str, Any]]` - Complete list of user profiles loaded from file
37
+ - `user_index: Dict[str, Dict[str, Any]]` - In-memory index mapping lookup keys to user profiles
38
+
39
+ **Usage Examples:**
40
+ ```python
41
+ import asyncio
42
+ import json
43
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
44
+
45
+ # Create sample users.json file
46
+ users_data = [
47
+ {
48
+ "id": "jdoe",
49
+ "email": "jane.doe@example.com",
50
+ "name": "Jane Doe",
51
+ "title": "Senior Engineer",
52
+ "manager_id": "ssmith"
53
+ },
54
+ {
55
+ "id": "ssmith",
56
+ "email": "sam.smith@example.com",
57
+ "name": "Sam Smith",
58
+ "title": "Engineering Manager"
59
+ }
60
+ ]
61
+
62
+ with open("users.json", "w") as f:
63
+ json.dump(users_data, f)
64
+
65
+ async def main():
66
+ # Initialize the service
67
+ config = {
68
+ "file_path": "users.json",
69
+ "lookup_key": "id" # Optional, defaults to "id"
70
+ }
71
+
72
+ identity_service = LocalFileIdentityService(config)
73
+
74
+ # Get user profile by ID
75
+ auth_claims = {"id": "jdoe"}
76
+ profile = await identity_service.get_user_profile(auth_claims)
77
+ print(f"User profile: {profile}")
78
+
79
+ # Search for users
80
+ results = await identity_service.search_users("jane", limit=5)
81
+ print(f"Search results: {results}")
82
+
83
+ # Handle missing user
84
+ missing = await identity_service.get_user_profile({"id": "nonexistent"})
85
+ print(f"Missing user: {missing}") # Returns None
86
+
87
+ asyncio.run(main())
88
+ ```
89
+
90
+ ================================================================================
91
+
92
+ ## Section 2: solace_agent_mesh/common/services/services_llm.txt
93
+
94
+ **Source file:** `solace_agent_mesh/common/services/services_llm.txt`
95
+
96
+ # DEVELOPER GUIDE: services
97
+
98
+ ## Quick Summary
99
+ The `services` directory provides a modular and extensible framework for integrating external data sources related to identity and employee information into the Solace AI Connector. It is built on a provider pattern, defining abstract base classes (`BaseIdentityService`, `BaseEmployeeService`) that establish a clear contract for what data and functionality a service must provide.
100
+
101
+ The core architecture revolves around factory functions (`create_identity_service`, `create_employee_service`) that instantiate specific service providers based on a configuration dictionary. This allows the application to remain decoupled from the concrete implementations. The `providers/` subdirectory contains concrete implementations, including a built-in file-based identity service, while external providers can be dynamically loaded as plugins through Python's entry points system.
102
+
103
+ ## Files and Subdirectories Overview
104
+ - **Direct files:**
105
+ - `__init__.py`: Marks the directory as a Python package with shared, reusable services
106
+ - `employee_service.py`: Defines the abstract contract and factory for employee data services
107
+ - `identity_service.py`: Defines the abstract contract and factory for user identity services
108
+ - **Subdirectories:**
109
+ - `providers/`: Contains concrete implementations of the service contracts, including a file-based identity provider
110
+
111
+ ## Developer API Reference
112
+
113
+ ### Direct Files
114
+
115
+ #### employee_service.py
116
+ **Purpose:** Defines the abstract base class (`BaseEmployeeService`) that all employee service providers must implement, and a factory function (`create_employee_service`) to instantiate them. It enforces a canonical schema for employee data to ensure consistency across different providers.
117
+ **Import:** `from solace_agent_mesh.common.services.employee_service import BaseEmployeeService, create_employee_service`
118
+
119
+ **Classes/Functions/Constants:**
120
+ - **`class BaseEmployeeService(ABC)`**: The abstract base class for employee service providers.
121
+ - **`__init__(self, config: Dict[str, Any])`**: Initializes the service, setting up configuration and an optional in-memory cache.
122
+ - **`async def get_employee_dataframe(self) -> pd.DataFrame`**: (Abstract) Returns the entire employee directory as a pandas DataFrame.
123
+ - **`async def get_employee_profile(self, employee_id: str) -> Optional[Dict[str, Any]]`**: (Abstract) Fetches the profile for a single employee, conforming to the canonical schema.
124
+ - **`async def get_time_off_data(self, employee_id: str) -> List[Dict[str, Any]]`**: (Abstract) Retrieves a list of time-off entries for an employee.
125
+ - **`async def get_employee_profile_picture(self, employee_id: str) -> Optional[str]`**: (Abstract) Fetches an employee's profile picture as a data URI string.
126
+ - **`def create_employee_service(config: Optional[Dict[str, Any]]) -> Optional[BaseEmployeeService]`**: A factory function that dynamically loads and instantiates an employee service provider based on the `type` specified in the configuration. It primarily uses Python's entry points to find and load external plugins.
127
+
128
+ #### identity_service.py
129
+ **Purpose:** Defines the abstract base class (`BaseIdentityService`) for identity providers and a factory function (`create_identity_service`) to create instances of them. This service is used for user lookups and profile enrichment.
130
+ **Import:** `from solace_agent_mesh.common.services.identity_service import BaseIdentityService, create_identity_service`
131
+
132
+ **Classes/Functions/Constants:**
133
+ - **`class BaseIdentityService(ABC)`**: The abstract base class for identity service providers.
134
+ - **`__init__(self, config: Dict[str, Any])`**: Initializes the service, setting up configuration and an optional in-memory cache.
135
+ - **`async def get_user_profile(self, auth_claims: Dict[str, Any]) -> Optional[Dict[str, Any]]`**: (Abstract) Fetches additional profile details for an authenticated user based on claims.
136
+ - **`async def search_users(self, query: str, limit: int = 10) -> List[Dict[str, Any]]`**: (Abstract) Searches for users based on a query string (e.g., for autocomplete).
137
+ - **`def create_identity_service(config: Optional[Dict[str, Any]]) -> Optional[BaseIdentityService]`**: A factory function that instantiates an identity service provider. It has special handling for the built-in `local_file` provider and uses Python entry points for all other provider types.
138
+
139
+ ### Subdirectory APIs
140
+
141
+ #### providers/
142
+ **Purpose:** Contains concrete implementations of the abstract service classes, providing specific ways to fulfill service contracts such as sourcing user identity information from local files
143
+ **Key Exports:** `LocalFileIdentityService`
144
+ **Import Examples:**
145
+ ```python
146
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
147
+ ```
148
+
149
+ ## Complete Usage Guide
150
+
151
+ ### 1. Using Service Factories (Recommended Approach)
152
+ The factories are the primary way to create and use services. They abstract away the specific implementation details and handle plugin loading.
153
+
154
+ **Example: Creating Identity and Employee Services**
155
+
156
+ ```python
157
+ import asyncio
158
+ from solace_agent_mesh.common.services.identity_service import create_identity_service
159
+ from solace_agent_mesh.common.services.employee_service import create_employee_service
160
+
161
+ async def main():
162
+ # --- Identity Service Example (using built-in provider) ---
163
+ identity_config = {
164
+ "type": "local_file",
165
+ "file_path": "path/to/your/users.json",
166
+ "lookup_key": "email", # Key to use for lookups from auth_claims
167
+ "cache_ttl_seconds": 3600
168
+ }
169
+ identity_service = create_identity_service(identity_config)
170
+
171
+ if identity_service:
172
+ print("Identity Service created.")
173
+ # Fetch a user profile
174
+ auth_claims = {"email": "jane.doe@example.com"}
175
+ user_profile = await identity_service.get_user_profile(auth_claims)
176
+ print(f"User Profile: {user_profile}")
177
+
178
+ # Search for users
179
+ search_results = await identity_service.search_users("Jane")
180
+ print(f"Search Results: {search_results}")
181
+
182
+ # --- Employee Service Example (using external plugin) ---
183
+ # The 'type' must match the name of a registered plugin entry point
184
+ employee_config = {
185
+ "type": "bamboohr_plugin",
186
+ "api_key": "your-secret-api-key",
187
+ "subdomain": "your-company",
188
+ "cache_ttl_seconds": 7200
189
+ }
190
+ employee_service = create_employee_service(employee_config)
191
+
192
+ if employee_service:
193
+ print("\nEmployee Service created.")
194
+ # Get a detailed employee profile
195
+ employee_profile = await employee_service.get_employee_profile("jane.doe@example.com")
196
+ print(f"Employee Profile: {employee_profile}")
197
+
198
+ # Get time off data
199
+ time_off = await employee_service.get_time_off_data("jane.doe@example.com")
200
+ print(f"Time Off Data: {time_off}")
201
+
202
+ # Get employee directory as DataFrame
203
+ df = await employee_service.get_employee_dataframe()
204
+ print(f"Employee Directory Shape: {df.shape}")
205
+
206
+ # Run the example
207
+ asyncio.run(main())
208
+ ```
209
+
210
+ ### 2. Direct Provider Instantiation
211
+ While factories are preferred, you can instantiate providers from the `providers/` directory directly. This is useful for testing or when you know you will always use a specific built-in provider.
212
+
213
+ **Example: Direct Use of LocalFileIdentityService**
214
+
215
+ ```python
216
+ import asyncio
217
+ import json
218
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
219
+
220
+ async def main():
221
+ # First, create a sample users.json file
222
+ users_data = [
223
+ {
224
+ "id": "jdoe",
225
+ "email": "jane.doe@example.com",
226
+ "name": "Jane Doe",
227
+ "title": "Senior Engineer",
228
+ "manager_id": "ssmith"
229
+ },
230
+ {
231
+ "id": "ssmith",
232
+ "email": "sam.smith@example.com",
233
+ "name": "Sam Smith",
234
+ "title": "Engineering Manager"
235
+ }
236
+ ]
237
+
238
+ with open("users.json", "w") as f:
239
+ json.dump(users_data, f)
240
+
241
+ # Configuration does not need a 'type' key for direct instantiation
242
+ config = {
243
+ "file_path": "users.json",
244
+ "lookup_key": "id",
245
+ "cache_ttl_seconds": 1800
246
+ }
247
+
248
+ # Instantiate the class directly
249
+ local_service = LocalFileIdentityService(config)
250
+ print("LocalFileIdentityService created directly")
251
+
252
+ # Get user profile by ID
253
+ auth_claims = {"id": "jdoe"}
254
+ profile = await local_service.get_user_profile(auth_claims)
255
+ print(f"User profile: {profile}")
256
+
257
+ # Search for users
258
+ results = await local_service.search_users("jane", limit=5)
259
+ print(f"Search results: {results}")
260
+
261
+ asyncio.run(main())
262
+ ```
263
+
264
+ ### 3. Creating Custom Service Providers
265
+ To create your own service provider, inherit from the appropriate base class and implement all abstract methods.
266
+
267
+ **Example: Custom Employee Service Provider**
268
+
269
+ ```python
270
+ import pandas as pd
271
+ from typing import Any, Dict, List, Optional
272
+ from solace_agent_mesh.common.services.employee_service import BaseEmployeeService
273
+
274
+ class CustomEmployeeService(BaseEmployeeService):
275
+ """Custom employee service that connects to your HR system."""
276
+
277
+ def __init__(self, config: Dict[str, Any]):
278
+ super().__init__(config)
279
+ self.api_endpoint = config.get("api_endpoint")
280
+ self.api_key = config.get("api_key")
281
+
282
+ async def get_employee_dataframe(self) -> pd.DataFrame:
283
+ """Fetch all employees and return as DataFrame."""
284
+ # Your implementation here
285
+ # This should return a DataFrame with canonical schema columns:
286
+ # id, displayName, workEmail, jobTitle, department, location, supervisorId, hireDate, mobilePhone
287
+ employees_data = [
288
+ {
289
+ "id": "jdoe@company.com",
290
+ "displayName": "Jane Doe",
291
+ "workEmail": "jdoe@company.com",
292
+ "jobTitle": "Software Engineer",
293
+ "department": "Engineering",
294
+ "location": "San Francisco",
295
+ "supervisorId": "manager@company.com",
296
+ "hireDate": "2023-01-15",
297
+ "mobilePhone": "+1-555-0123"
298
+ }
299
+ ]
300
+ return pd.DataFrame(employees_data)
301
+
302
+ async def get_employee_profile(self, employee_id: str) -> Optional[Dict[str, Any]]:
303
+ """Get single employee profile."""
304
+ # Your implementation here
305
+ return {
306
+ "id": employee_id,
307
+ "displayName": "Jane Doe",
308
+ "workEmail": employee_id,
309
+ "jobTitle": "Software Engineer"
310
+ }
311
+
312
+ async def get_time_off_data(self, employee_id: str) -> List[Dict[str, Any]]:
313
+ """Get employee time off data."""
314
+ # Your implementation here
315
+ return [
316
+ {
317
+ 'start': '2025-07-04',
318
+ 'end': '2025-07-04',
319
+ 'type': 'Holiday',
320
+ 'amount': 'full_day'
321
+ }
322
+ ]
323
+
324
+ async def get_employee_profile_picture(self, employee_id: str) -> Optional[str]:
325
+ """Get employee profile picture as data URI."""
326
+ # Your implementation here
327
+ return None # or return "data:image/jpeg;base64,..."
328
+
329
+ # Usage
330
+ async def use_custom_service():
331
+ config = {
332
+ "api_endpoint": "https://your-hr-api.com",
333
+ "api_key": "your-api-key",
334
+ "cache_ttl_seconds": 3600
335
+ }
336
+
337
+ service = CustomEmployeeService(config)
338
+ profile = await service.get_employee_profile("jdoe@company.com")
339
+ print(f"Custom service profile: {profile}")
340
+ ```
341
+
342
+ ### 4. Working with Both Services Together
343
+ Often you'll want to use both identity and employee services together for comprehensive user information.
344
+
345
+ **Example: Combined Service Usage**
346
+
347
+ ```python
348
+ import asyncio
349
+ from solace_agent_mesh.common.services.identity_service import create_identity_service
350
+ from solace_agent_mesh.common.services.employee_service import create_employee_service
351
+
352
+ async def get_complete_user_info(user_email: str):
353
+ """Get comprehensive user information from both services."""
354
+
355
+ # Configure services
356
+ identity_config = {
357
+ "type": "local_file",
358
+ "file_path": "users.json",
359
+ "lookup_key": "email"
360
+ }
361
+
362
+ employee_config = {
363
+ "type": "your_hr_plugin",
364
+ "api_key": "your-key"
365
+ }
366
+
367
+ # Create services
368
+ identity_service = create_identity_service(identity_config)
369
+ employee_service = create_employee_service(employee_config)
370
+
371
+ # Gather information
372
+ user_info = {}
373
+
374
+ if identity_service:
375
+ auth_claims = {"email": user_email}
376
+ identity_profile = await identity_service.get_user_profile(auth_claims)
377
+ if identity_profile:
378
+ user_info.update(identity_profile)
379
+
380
+ if employee_service:
381
+ employee_profile = await employee_service.get_employee_profile(user_email)
382
+ if employee_profile:
383
+ user_info.update(employee_profile)
384
+
385
+ # Get additional employee data
386
+ time_off = await employee_service.get_time_off_data(user_email)
387
+ user_info["time_off"] = time_off
388
+
389
+ profile_pic = await employee_service.get_employee_profile_picture(user_email)
390
+ if profile_pic:
391
+ user_info["profile_picture"] = profile_pic
392
+
393
+ return user_info
394
+
395
+ # Usage
396
+ async def main():
397
+ complete_info = await get_complete_user_info("jane.doe@example.com")
398
+ print(f"Complete user information: {complete_info}")
399
+
400
+ asyncio.run(main())
401
+ ```
402
+
403
+ ### 5. Using the Built-in LocalFileIdentityService
404
+ The `providers/` subdirectory includes a ready-to-use file-based identity service that's perfect for development and testing.
405
+
406
+ **Example: Setting up LocalFileIdentityService with Factory**
407
+
408
+ ```python
409
+ import asyncio
410
+ import json
411
+ from solace_agent_mesh.common.services.identity_service import create_identity_service
412
+
413
+ async def setup_file_based_identity():
414
+ # Create sample users.json file
415
+ users_data = [
416
+ {
417
+ "id": "jdoe",
418
+ "email": "jane.doe@example.com",
419
+ "name": "Jane Doe",
420
+ "title": "Senior Engineer",
421
+ "manager_id": "ssmith"
422
+ },
423
+ {
424
+ "id": "ssmith",
425
+ "email": "sam.smith@example.com",
426
+ "name": "Sam Smith",
427
+ "title": "Engineering Manager"
428
+ }
429
+ ]
430
+
431
+ with open("users.json", "w") as f:
432
+ json.dump(users_data, f)
433
+
434
+ # Use factory to create the service
435
+ config = {
436
+ "type": "local_file", # This triggers the built-in provider
437
+ "file_path": "users.json",
438
+ "lookup_key": "email", # Use email for lookups
439
+ "cache_ttl_seconds": 3600
440
+ }
441
+
442
+ identity_service = create_identity_service(config)
443
+
444
+ # Test the service
445
+ auth_claims = {"email": "jane.doe@example.com"}
446
+ profile = await identity_service.get_user_profile(auth_claims)
447
+ print(f"Profile found: {profile}")
448
+
449
+ # Search functionality
450
+ search_results = await identity_service.search_users("jane")
451
+ print(f"Search results: {search_results}")
452
+
453
+ asyncio.run(setup_file_based_identity())
454
+ ```
455
+
456
+ This comprehensive guide shows how the services framework provides a clean, extensible way to integrate various data sources while maintaining consistent interfaces and supporting both built-in providers and external plugins through the factory pattern and plugin system.
457
+
458
+ ================================================================================
459
+
@@ -217,4 +217,4 @@ result, error, size = await evaluate_embed(
217
217
 
218
218
  ### types.py
219
219
 
220
- # content_hash: cbca48790a6e817c5bf49ddd8212cbbc663e920e9dd4dbece95bcf57d79c1837
220
+ # content_hash: 2f31c6289fe46fe2ebb4c490574d6d030547346221337f730f315f7b3cac572f
@@ -13,6 +13,8 @@ The `utils` directory provides essential utility functions and tools for the Sol
13
13
  - **`message_utils.py`** - Message size calculation and validation utilities
14
14
  - **`mime_helpers.py`** - MIME type classification and file extension utilities
15
15
  - **`push_notification_auth.py`** - JWT-based authentication for push notifications
16
+ - **`pydantic_utils.py`** - Pydantic BaseModel with dict-like access for configuration
17
+ - **`type_utils.py`** - Robust type checking utilities for development environments
16
18
 
17
19
  ### Subdirectories:
18
20
  - **`embeds/`** - Dynamic expression evaluation system using `«...»` syntax for mathematical calculations, datetime formatting, UUID generation, and artifact content processing
@@ -105,6 +107,26 @@ The `utils` directory provides essential utility functions and tools for the Sol
105
107
  - `load_jwks(jwks_url: str) -> None` - Load public keys from JWKS endpoint
106
108
  - `verify_push_notification(request: Request) -> bool` - Verify notification authenticity
107
109
 
110
+ #### pydantic_utils.py
111
+ **Purpose:** Provides a Pydantic BaseModel for SAM configuration with dict-like access
112
+ **Import:** `from solace_agent_mesh.common.utils.pydantic_utils import SamConfigBase`
113
+
114
+ **Classes:**
115
+ - **`SamConfigBase(BaseModel)`** - Pydantic BaseModel with dict-like access
116
+ - `model_validate_and_clean(cls: Type[T], obj: Any) -> T` - Validates dict after removing None values
117
+ - `get(key: str, default: Any = None) -> Any` - Dict-like .get() method
118
+ - `__getitem__(key: str) -> Any` - Dict-like ['key'] access
119
+ - `__setitem__(key: str, value: Any)` - Dict-like ['key'] = value assignment
120
+ - `__contains__(key: str) -> bool` - Dict-like 'in' support
121
+ - `keys()`, `values()`, `items()`, `__iter__()` - Dict-like iteration methods
122
+
123
+ #### type_utils.py
124
+ **Purpose:** Utilities for robust type checking, especially in development environments
125
+ **Import:** `from solace_agent_mesh.common.utils.type_utils import is_subclass_by_name`
126
+
127
+ **Functions:**
128
+ - `is_subclass_by_name(cls_to_check: type, base_class_name: str) -> bool` - Checks if a class is a subclass by looking for the base class name in the MRO
129
+
108
130
  ### Subdirectory APIs
109
131
 
110
132
  #### embeds/
@@ -154,7 +176,55 @@ extension = get_extension_for_mime_type("image/png") # Returns ".png"
154
176
  filename = f"image_{uuid.uuid4()}{extension}"
155
177
  ```
156
178
 
157
- ### 2. Platform Compatibility and System Initialization
179
+ ### 2. Configuration and Type Utilities
180
+
181
+ ```python
182
+ from solace_agent_mesh.common.utils.pydantic_utils import SamConfigBase
183
+ from solace_agent_mesh.common.utils.type_utils import is_subclass_by_name
184
+ from pydantic import Field
185
+ from typing import Optional
186
+
187
+ # Define configuration with Pydantic validation and dict-like access
188
+ class AgentConfig(SamConfigBase):
189
+ name: str
190
+ timeout: int = 30
191
+ debug: bool = False
192
+ api_key: Optional[str] = None
193
+
194
+ # Load config from YAML/dict with None value cleaning
195
+ config_dict = {
196
+ "name": "my_agent",
197
+ "timeout": None, # Will use default value of 30
198
+ "debug": True,
199
+ "api_key": None # Will use default value of None
200
+ }
201
+
202
+ config = AgentConfig.model_validate_and_clean(config_dict)
203
+
204
+ # Use both Pydantic and dict-style access
205
+ print(config.name) # Pydantic style: "my_agent"
206
+ print(config["timeout"]) # Dict style: 30 (default applied)
207
+ print(config.get("debug", False)) # Dict .get(): True
208
+
209
+ # Check if field was explicitly set
210
+ if "api_key" in config:
211
+ print("API key was provided")
212
+ else:
213
+ print("API key not provided, using default")
214
+
215
+ # Robust type checking for development
216
+ class BaseAgent:
217
+ pass
218
+
219
+ class MyAgent(BaseAgent):
220
+ pass
221
+
222
+ # This works even if BaseAgent is loaded from different paths
223
+ if is_subclass_by_name(MyAgent, "BaseAgent"):
224
+ print("MyAgent is a BaseAgent subclass")
225
+ ```
226
+
227
+ ### 3. Platform Compatibility and System Initialization
158
228
 
159
229
  ```python
160
230
  # Early in application startup - import for side effects
@@ -184,7 +254,7 @@ async def run_command(cmd: str):
184
254
  result = await run_command("echo Hello World")
185
255
  ```
186
256
 
187
- ### 3. Structured Logging Setup
257
+ ### 4. Structured Logging Setup
188
258
 
189
259
  ```python
190
260
  import logging
@@ -212,7 +282,7 @@ logger.info("User action completed", extra={
212
282
  # Output will be JSON with timestamp, level, service, code location, etc.
213
283
  ```
214
284
 
215
- ### 4. Secure Push Notification System
285
+ ### 5. Secure Push Notification System
216
286
 
217
287
  ```python
218
288
  from solace_agent_mesh.common.utils.push_notification_auth import (
@@ -261,88 +331,6 @@ async def webhook_handler(request: Request):
261
331
  else:
262
332
  return Response("Unauthorized", status_code=401)
263
333
  except Exception as e:
264
- print(f"Verification failed: {e}")
265
- return Response("Bad Request", status_code=400)
266
-
267
- # JWKS endpoint for sender
268
- @app.route("/.well-known/jwks.json")
269
- async def jwks_endpoint(request: Request):
270
- return sender_auth.handle_jwks_endpoint(request)
271
- ```
272
-
273
- ### 5. Advanced Embed Processing
274
-
275
- ```python
276
- from solace_agent_mesh.common.utils.embeds import (
277
- resolve_embeds_recursively_in_string,
278
- evaluate_embed,
279
- EARLY_EMBED_TYPES,
280
- LATE_EMBED_TYPES
281
- )
282
-
283
- # Set up context for embed resolution
284
- context = {
285
- "artifact_service": my_artifact_service,
286
- "session_context": {
287
- "app_name": "sales_analyzer",
288
- "user_id": "user123",
289
- "session_id": "sess456"
290
- }
291
- }
292
-
293
- # Simple embed resolution for dynamic content
294
- template = """
295
- Sales Report Generated: «datetime:%Y-%m-%d %H:%M:%S»
296
- Total Revenue: $«math:«artifact_content:sales.csv >>> jsonpath:$.total_revenue» * 1.08 | .2f»
297
- Report ID: «uuid:new»
298
- Tax Rate Applied: 8%
299
- """
300
-
301
- # Resolve embeds recursively with safety limits
302
- resolved_content = await resolve_embeds_recursively_in_string(
303
- text=template,
304
- context=context,
305
- resolver_func=evaluate_embed,
306
- types_to_resolve=EARLY_EMBED_TYPES | LATE_EMBED_TYPES,
307
- log_identifier="[SalesReport]",
308
- config={"max_artifact_size": 1024*1024}, # 1MB limit
309
- max_depth=5
310
- )
311
-
312
- # Complex data transformation pipeline
313
- data_analysis = """
314
- Product Analysis:
315
- «artifact_content:products.csv:latest >>> select_cols:name,category,price,sales >>> filter_rows_eq:category:electronics >>> slice_rows:0:10 >>> format:json_pretty»
316
-
317
- Summary Statistics:
318
- «artifact_content:summary.txt >>> head:5»
319
-
320
- Top Performers:
321
- «artifact_content:sales.json >>> jsonpath:$.top_products[*].name >>> format:text»
322
- """
323
-
324
- analysis_result = await resolve_embeds_recursively_in_string(
325
- text=data_analysis,
326
- context=context,
327
- resolver_func=evaluate_embed,
328
- types_to_resolve=LATE_EMBED_TYPES,
329
- log_identifier="[Analysis]",
330
- config={},
331
- max_depth=3
332
- )
333
- ```
334
-
335
- ### 6. Integrated Workflow Example
336
-
337
- ```python
338
- from solace_agent_mesh.common.utils import is_text_based_mime_type
339
- from solace_agent_mesh.common.utils.in_memory_cache import InMemoryCache
340
- from solace_agent_mesh.common.utils.message_utils import validate_message_size
341
- from solace_agent_mesh.common.utils.embeds import resolve_embeds_recursively_in_string, evaluate_embed
342
- from solace_agent_mesh.common.utils.push_notification_auth import PushNotificationSenderAuth
343
- import hashlib
344
-
345
- async def process_and_notify_report(user_id: str, template: str, context: dict, notification_urls: list):
346
- """Complete workflow integrating
334
+ print(f"
347
335
 
348
- # content_hash: 0f48341a035bc4fbdb720885186fe04075f8fbca7ddeee6a151b00b4c667c47a
336
+ # content_hash: d80ffe631ca180ea5aacca592313af42838960a949c8664559a957c2492fa86f