solace-agent-mesh 1.0.8__py3-none-any.whl → 1.1.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 (162) hide show
  1. solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
  2. solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
  3. solace_agent_mesh/agent/adk/callbacks.py +165 -104
  4. solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
  5. solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
  6. solace_agent_mesh/agent/adk/runner.py +7 -5
  7. solace_agent_mesh/agent/adk/setup.py +11 -0
  8. solace_agent_mesh/agent/adk/stream_parser.py +8 -1
  9. solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
  10. solace_agent_mesh/agent/agent_llm.txt +355 -18
  11. solace_agent_mesh/agent/protocol/event_handlers.py +433 -296
  12. solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
  13. solace_agent_mesh/agent/sac/app.py +1 -1
  14. solace_agent_mesh/agent/sac/component.py +212 -517
  15. solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
  16. solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
  17. solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
  18. solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
  19. solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
  20. solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
  21. solace_agent_mesh/assets/docs/404.html +3 -3
  22. solace_agent_mesh/assets/docs/assets/js/{3d406171.7d02a73b.js → 3d406171.0b9eeed1.js} +1 -1
  23. solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
  24. solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
  25. solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
  26. solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
  27. solace_agent_mesh/assets/docs/assets/js/main.a75ecc0d.js +2 -0
  28. solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
  29. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
  37. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  38. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +105 -0
  44. solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +8 -8
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
  49. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
  51. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
  52. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
  60. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  61. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  62. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  63. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  64. solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +1 -0
  65. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  66. solace_agent_mesh/assets/docs/search-doc-1756992446316.json +1 -0
  67. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  68. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  69. solace_agent_mesh/cli/__init__.py +1 -1
  70. solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +12 -3
  71. solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +10 -14
  72. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +2 -15
  73. solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +6 -2
  74. solace_agent_mesh/cli/utils.py +15 -0
  75. solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-DvlO62me.js → authCallback-BmF2l6vg.js} +1 -1
  76. solace_agent_mesh/client/webui/frontend/static/assets/{client-bp6u3qVZ.js → client-D881Dttc.js} +4 -4
  77. solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +699 -0
  78. solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +1 -0
  79. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +2 -2
  80. solace_agent_mesh/client/webui/frontend/static/index.html +3 -3
  81. solace_agent_mesh/common/a2a/__init__.py +213 -0
  82. solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
  83. solace_agent_mesh/common/a2a/artifact.py +328 -0
  84. solace_agent_mesh/common/a2a/events.py +183 -0
  85. solace_agent_mesh/common/a2a/message.py +307 -0
  86. solace_agent_mesh/common/a2a/protocol.py +513 -0
  87. solace_agent_mesh/common/a2a/task.py +127 -0
  88. solace_agent_mesh/common/a2a/translation.py +653 -0
  89. solace_agent_mesh/common/a2a/types.py +54 -0
  90. solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
  91. solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
  92. solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
  93. solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
  94. solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
  95. solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
  96. solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
  97. solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
  98. solace_agent_mesh/common/agent_registry.py +1 -1
  99. solace_agent_mesh/common/common_llm.txt +192 -70
  100. solace_agent_mesh/common/data_parts.py +99 -0
  101. solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
  102. solace_agent_mesh/common/sac/__init__.py +0 -0
  103. solace_agent_mesh/common/sac/sac_llm.txt +71 -0
  104. solace_agent_mesh/common/sac/sam_component_base.py +252 -0
  105. solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
  106. solace_agent_mesh/common/services/services_llm.txt +206 -26
  107. solace_agent_mesh/common/utils/artifact_utils.py +29 -0
  108. solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
  109. solace_agent_mesh/common/utils/utils_llm.txt +323 -42
  110. solace_agent_mesh/config_portal/backend/common.py +1 -1
  111. solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-MqsrTd6g.js → _index-Bym6YkMd.js} +74 -24
  112. solace_agent_mesh/config_portal/frontend/static/client/assets/{components-B7lKcHVY.js → components-Rk0n-9cK.js} +1 -1
  113. solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-CEumGClk.js → entry.client-mvZjNKiz.js} +1 -1
  114. solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DSo1AH_7.js → index-DzNKzXrc.js} +1 -1
  115. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-d845808d.js +1 -0
  116. solace_agent_mesh/config_portal/frontend/static/client/assets/{root-C4XmHinv.js → root-BWvk5-gF.js} +1 -1
  117. solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
  118. solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
  119. solace_agent_mesh/core_a2a/service.py +20 -44
  120. solace_agent_mesh/gateway/base/app.py +27 -1
  121. solace_agent_mesh/gateway/base/base_llm.txt +177 -72
  122. solace_agent_mesh/gateway/base/component.py +294 -523
  123. solace_agent_mesh/gateway/gateway_llm.txt +299 -58
  124. solace_agent_mesh/gateway/http_sse/component.py +156 -183
  125. solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
  126. solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
  127. solace_agent_mesh/gateway/http_sse/main.py +8 -10
  128. solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
  129. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +18 -4
  130. solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
  131. solace_agent_mesh/gateway/http_sse/routers/sessions.py +12 -7
  132. solace_agent_mesh/gateway/http_sse/routers/tasks.py +116 -169
  133. solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
  134. solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
  135. solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
  136. solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
  137. solace_agent_mesh/templates/gateway_component_template.py +149 -98
  138. {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/METADATA +5 -4
  139. {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/RECORD +143 -126
  140. solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
  141. solace_agent_mesh/assets/docs/assets/js/main.6dba4a66.js +0 -2
  142. solace_agent_mesh/assets/docs/assets/js/runtime~main.6415ad00.js +0 -1
  143. solace_agent_mesh/assets/docs/lunr-index-1756153049706.json +0 -1
  144. solace_agent_mesh/assets/docs/search-doc-1756153049706.json +0 -1
  145. solace_agent_mesh/client/webui/frontend/static/assets/main-BCpII1-0.css +0 -1
  146. solace_agent_mesh/client/webui/frontend/static/assets/main-BucUdn9m.js +0 -673
  147. solace_agent_mesh/common/a2a_protocol.py +0 -564
  148. solace_agent_mesh/common/client/__init__.py +0 -4
  149. solace_agent_mesh/common/client/card_resolver.py +0 -21
  150. solace_agent_mesh/common/client/client.py +0 -85
  151. solace_agent_mesh/common/client/client_llm.txt +0 -133
  152. solace_agent_mesh/common/server/__init__.py +0 -4
  153. solace_agent_mesh/common/server/server.py +0 -122
  154. solace_agent_mesh/common/server/server_llm.txt +0 -169
  155. solace_agent_mesh/common/server/task_manager.py +0 -291
  156. solace_agent_mesh/common/server/utils.py +0 -28
  157. solace_agent_mesh/common/types.py +0 -411
  158. solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-28271392.js +0 -1
  159. /solace_agent_mesh/assets/docs/assets/js/{main.6dba4a66.js.LICENSE.txt → main.a75ecc0d.js.LICENSE.txt} +0 -0
  160. {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/WHEEL +0 -0
  161. {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/entry_points.txt +0 -0
  162. {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/licenses/LICENSE +0 -0
@@ -2,112 +2,79 @@
2
2
  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.
3
3
 
4
4
  ## Files Overview
5
- - `__init__.py`: Marks the directory as a Python package.
6
- - `local_file_identity_service.py`: An identity service implementation that reads user data from a local JSON file.
5
+ - `__init__.py` - Package initialization file marking the directory as a Python package
6
+ - `local_file_identity_service.py` - File-based identity service implementation that reads user data from local JSON files
7
7
 
8
8
  ## Developer API Reference
9
9
 
10
10
  ### __init__.py
11
- **Purpose:** Initializes the `providers` package.
12
- **Import:** `from solace_ai_connector.common.services import providers`
11
+ **Purpose:** Initializes the providers package
12
+ **Import:** `from solace_agent_mesh.common.services import providers`
13
13
 
14
- This file contains no public classes or functions.
15
-
16
- ---
14
+ This file contains no public classes or functions - it serves only as package documentation.
17
15
 
18
16
  ### local_file_identity_service.py
19
- **Purpose:** Provides a simple, file-based identity service that reads user profiles from a local JSON file. It's ideal for development, testing, or small-scale deployments where a full-fledged identity provider is not available.
20
- **Import:** `from solace_ai_connector.common.services.providers.local_file_identity_service import LocalFileIdentityService`
17
+ **Purpose:** Provides a file-based identity service that reads user profiles from a local JSON file, ideal for development, testing, or small-scale deployments
18
+ **Import:** `from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService`
21
19
 
22
20
  **Classes:**
23
- - `LocalFileIdentityService(config: Dict[str, Any])` - An identity service that sources user data from a local JSON file. The `config` dictionary must contain a `file_path` key.
24
- - `async get_user_profile(auth_claims: Dict[str, Any]) -> Optional[Dict[str, Any]]` - Looks up a user profile from the in-memory index. The lookup is performed using the `lookup_key` (configured during initialization) present in the `auth_claims` dictionary.
25
- - `async search_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Performs a simple, case-insensitive search across user names and emails. Returns a list of matching user profiles.
26
- - `file_path: str` - The path to the JSON file containing the user data.
27
- - `lookup_key: str` - The key within the user profile objects and `auth_claims` used to identify a user. Defaults to `"id"`.
28
- - `all_users: List[Dict[str, Any]]` - The complete list of all user profiles loaded from the file.
29
- - `user_index: Dict[str, Dict[str, Any]]` - An in-memory dictionary mapping the `lookup_key` value to the corresponding user profile for fast lookups.
21
+ - `LocalFileIdentityService(config: Dict[str, Any])` - Identity service that sources user data from a local JSON file
22
+ - `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
23
+ - `async search_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Performs case-insensitive search on user names and emails
24
+ - `file_path: str` - Path to the JSON file containing user data
25
+ - `lookup_key: str` - Key used to identify users (defaults to "id")
26
+ - `all_users: List[Dict[str, Any]]` - Complete list of user profiles loaded from file
27
+ - `user_index: Dict[str, Dict[str, Any]]` - In-memory index mapping lookup keys to user profiles
30
28
 
31
29
  **Usage Examples:**
32
30
  ```python
33
31
  import asyncio
34
32
  import json
35
- import os
36
- from typing import Dict, Any, Optional, List
37
-
38
- # Assume this is the identity service class from the file
39
- from solace_ai_connector.common.services.providers.local_file_identity_service import LocalFileIdentityService
33
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
40
34
 
41
- # --- Setup: Create a dummy users.json for the example ---
35
+ # Create sample users.json file
42
36
  users_data = [
43
- {
44
- "id": "jdoe",
45
- "email": "jane.doe@example.com",
46
- "name": "Jane Doe",
47
- "title": "Senior Engineer",
48
- "manager_id": "ssmith"
49
- },
50
- {
51
- "id": "ssmith",
52
- "email": "sam.smith@example.com",
53
- "name": "Sam Smith",
54
- "title": "Engineering Manager",
55
- "manager_id": None
56
- }
37
+ {
38
+ "id": "jdoe",
39
+ "email": "jane.doe@example.com",
40
+ "name": "Jane Doe",
41
+ "title": "Senior Engineer",
42
+ "manager_id": "ssmith"
43
+ },
44
+ {
45
+ "id": "ssmith",
46
+ "email": "sam.smith@example.com",
47
+ "name": "Sam Smith",
48
+ "title": "Engineering Manager"
49
+ }
57
50
  ]
58
- file_path = "users.json"
59
- with open(file_path, "w") as f:
60
- json.dump(users_data, f)
61
- # --- End Setup ---
62
51
 
52
+ with open("users.json", "w") as f:
53
+ json.dump(users_data, f)
63
54
 
64
55
  async def main():
65
- # 1. Configure the service
66
- # The 'file_path' is required. 'lookup_key' is optional (defaults to 'id').
56
+ # Initialize the service
67
57
  config = {
68
- "file_path": file_path,
69
- "lookup_key": "id"
58
+ "file_path": "users.json",
59
+ "lookup_key": "id" # Optional, defaults to "id"
70
60
  }
71
-
72
- # 2. Initialize the service
61
+
73
62
  identity_service = LocalFileIdentityService(config)
74
- print(f"Service initialized. Loaded {len(identity_service.all_users)} users.")
75
-
76
- # 3. Get a specific user profile
77
- print("\n--- Getting user profile for id 'jdoe' ---")
63
+
64
+ # Get user profile by ID
78
65
  auth_claims = {"id": "jdoe"}
79
66
  profile = await identity_service.get_user_profile(auth_claims)
80
- if profile:
81
- print(f"Found profile: {profile}")
82
- else:
83
- print("Profile not found.")
84
-
85
- # 4. Search for users by name
86
- print("\n--- Searching for users with 'sam' in their name ---")
87
- search_results = await identity_service.search_users(query="sam", limit=5)
88
- print(f"Found {len(search_results)} user(s): {search_results}")
89
-
90
- # 5. Handle a case where the user is not found
91
- print("\n--- Getting user profile for non-existent id 'nobody' ---")
92
- not_found_profile = await identity_service.get_user_profile({"id": "nobody"})
93
- print(f"Profile for 'nobody': {not_found_profile}")
94
-
95
-
96
- if __name__ == "__main__":
97
- asyncio.run(main())
98
- # Clean up the dummy file
99
- os.remove(file_path)
100
-
101
- # Expected output:
102
- #
103
- # Service initialized. Loaded 2 users.
104
- #
105
- # --- Getting user profile for id 'jdoe' ---
106
- # Found profile: {'id': 'jdoe', 'email': 'jane.doe@example.com', 'name': 'Jane Doe', 'title': 'Senior Engineer', 'manager_id': 'ssmith'}
107
- #
108
- # --- Searching for users with 'sam' in their name ---
109
- # Found 1 user(s): [{'id': 'ssmith', 'name': 'Sam Smith', 'email': 'sam.smith@example.com', 'title': 'Engineering Manager'}]
110
- #
111
- # --- Getting user profile for non-existent id 'nobody' ---
112
- # Profile for 'nobody': None
113
- ```
67
+ print(f"User profile: {profile}")
68
+
69
+ # Search for users
70
+ results = await identity_service.search_users("jane", limit=5)
71
+ print(f"Search results: {results}")
72
+
73
+ # Handle missing user
74
+ missing = await identity_service.get_user_profile({"id": "nonexistent"})
75
+ print(f"Missing user: {missing}") # Returns None
76
+
77
+ asyncio.run(main())
78
+ ```
79
+
80
+ # content_hash: 3661ffe07466b1391797c2feb90e2c97544b1a9c6c8cd15fc448cf95f4be6015
@@ -1,3 +1,5 @@
1
+ # DEVELOPER GUIDE: services
2
+
1
3
  ## Quick Summary
2
4
  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.
3
5
 
@@ -5,11 +7,11 @@ The core architecture revolves around factory functions (`create_identity_servic
5
7
 
6
8
  ## Files and Subdirectories Overview
7
9
  - **Direct files:**
8
- - `__init__.py`: Marks the directory as a Python package.
9
- - `employee_service.py`: Defines the abstract contract and factory for employee data services.
10
- - `identity_service.py`: Defines the abstract contract and factory for user identity services.
10
+ - `__init__.py`: Marks the directory as a Python package with shared, reusable services
11
+ - `employee_service.py`: Defines the abstract contract and factory for employee data services
12
+ - `identity_service.py`: Defines the abstract contract and factory for user identity services
11
13
  - **Subdirectories:**
12
- - `providers/`: Contains concrete implementations of the service contracts, such as a file-based identity provider.
14
+ - `providers/`: Contains concrete implementations of the service contracts, including a file-based identity provider
13
15
 
14
16
  ## Developer API Reference
15
17
 
@@ -17,7 +19,7 @@ The core architecture revolves around factory functions (`create_identity_servic
17
19
 
18
20
  #### employee_service.py
19
21
  **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.
20
- **Import:** `from solace_ai_connector.common.services import BaseEmployeeService, create_employee_service`
22
+ **Import:** `from solace_agent_mesh.common.services.employee_service import BaseEmployeeService, create_employee_service`
21
23
 
22
24
  **Classes/Functions/Constants:**
23
25
  - **`class BaseEmployeeService(ABC)`**: The abstract base class for employee service providers.
@@ -30,7 +32,7 @@ The core architecture revolves around factory functions (`create_identity_servic
30
32
 
31
33
  #### identity_service.py
32
34
  **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.
33
- **Import:** `from solace_ai_connector.common.services import BaseIdentityService, create_identity_service`
35
+ **Import:** `from solace_agent_mesh.common.services.identity_service import BaseIdentityService, create_identity_service`
34
36
 
35
37
  **Classes/Functions/Constants:**
36
38
  - **`class BaseIdentityService(ABC)`**: The abstract base class for identity service providers.
@@ -48,26 +50,23 @@ The core architecture revolves around factory functions (`create_identity_servic
48
50
  ```python
49
51
  # Typically, you would use the factory function.
50
52
  # But for direct instantiation (e.g., in tests), you can do this:
51
- from solace_ai_connector.common.services.providers import LocalFileIdentityService
53
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
52
54
  ```
53
55
 
54
56
  ## Complete Usage Guide
55
- The following examples demonstrate how to use the services framework, from basic instantiation using factories to creating custom providers.
56
57
 
57
- ### 1. How to Use the Service Factories (Recommended)
58
- The factories are the primary way to create and use services. They abstract away the specific implementation details.
58
+ ### 1. Using Service Factories (Recommended Approach)
59
+ The factories are the primary way to create and use services. They abstract away the specific implementation details and handle plugin loading.
59
60
 
60
- **Example: Creating a File-Based Identity Service and a Plugin-Based Employee Service**
61
+ **Example: Creating Identity and Employee Services**
61
62
 
62
63
  ```python
63
64
  import asyncio
64
- from solace_ai_connector.common.services import create_identity_service, create_employee_service
65
-
66
- # Assume you have a users.json file for the identity service
67
- # and a plugin installed for the employee service.
65
+ from solace_agent_mesh.common.services.identity_service import create_identity_service
66
+ from solace_agent_mesh.common.services.employee_service import create_employee_service
68
67
 
69
68
  async def main():
70
- # --- Identity Service Example (using a built-in provider) ---
69
+ # --- Identity Service Example (using built-in provider) ---
71
70
  identity_config = {
72
71
  "type": "local_file",
73
72
  "file_path": "path/to/your/users.json",
@@ -87,8 +86,8 @@ async def main():
87
86
  search_results = await identity_service.search_users("Jane")
88
87
  print(f"Search Results: {search_results}")
89
88
 
90
- # --- Employee Service Example (using an external plugin) ---
91
- # The 'type' must match the name of a registered plugin entry point.
89
+ # --- Employee Service Example (using external plugin) ---
90
+ # The 'type' must match the name of a registered plugin entry point
92
91
  employee_config = {
93
92
  "type": "bamboohr_plugin",
94
93
  "api_key": "your-secret-api-key",
@@ -107,26 +106,207 @@ async def main():
107
106
  time_off = await employee_service.get_time_off_data("jane.doe@example.com")
108
107
  print(f"Time Off Data: {time_off}")
109
108
 
110
- # To run this example:
111
- # asyncio.run(main())
109
+ # Get employee directory as DataFrame
110
+ df = await employee_service.get_employee_dataframe()
111
+ print(f"Employee Directory Shape: {df.shape}")
112
+
113
+ # Run the example
114
+ asyncio.run(main())
112
115
  ```
113
116
 
114
- ### 2. How to Use Functionality from Subdirectories
117
+ ### 2. Direct Provider Instantiation
115
118
  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.
116
119
 
117
- **Example: Direct Instantiation of `LocalFileIdentityService`**
120
+ **Example: Direct Use of LocalFileIdentityService**
118
121
 
119
122
  ```python
120
123
  import asyncio
121
- from solace_ai_connector.common.services.providers import LocalFileIdentityService
124
+ import json
125
+ from solace_agent_mesh.common.services.providers.local_file_identity_service import LocalFileIdentityService
122
126
 
123
127
  async def main():
128
+ # First, create a sample users.json file
129
+ users_data = [
130
+ {
131
+ "id": "jdoe",
132
+ "email": "jane.doe@example.com",
133
+ "name": "Jane Doe",
134
+ "title": "Senior Engineer",
135
+ "manager_id": "ssmith"
136
+ },
137
+ {
138
+ "id": "ssmith",
139
+ "email": "sam.smith@example.com",
140
+ "name": "Sam Smith",
141
+ "title": "Engineering Manager"
142
+ }
143
+ ]
144
+
145
+ with open("users.json", "w") as f:
146
+ json.dump(users_data, f)
147
+
124
148
  # Configuration does not need a 'type' key for direct instantiation
125
149
  config = {
126
- "file_path": "path/to/your/users.json",
127
- "lookup_key": "id"
150
+ "file_path": "users.json",
151
+ "lookup_key": "id",
152
+ "cache_ttl_seconds": 1800
128
153
  }
129
154
 
130
155
  # Instantiate the class directly
131
156
  local_service = LocalFileIdentityService(config)
132
- print("LocalFileIdentityService
157
+ print("LocalFileIdentityService created directly")
158
+
159
+ # Get user profile by ID
160
+ auth_claims = {"id": "jdoe"}
161
+ profile = await local_service.get_user_profile(auth_claims)
162
+ print(f"User profile: {profile}")
163
+
164
+ # Search for users
165
+ results = await local_service.search_users("jane", limit=5)
166
+ print(f"Search results: {results}")
167
+
168
+ asyncio.run(main())
169
+ ```
170
+
171
+ ### 3. Creating Custom Service Providers
172
+ To create your own service provider, inherit from the appropriate base class and implement all abstract methods.
173
+
174
+ **Example: Custom Employee Service Provider**
175
+
176
+ ```python
177
+ import pandas as pd
178
+ from typing import Any, Dict, List, Optional
179
+ from solace_agent_mesh.common.services.employee_service import BaseEmployeeService
180
+
181
+ class CustomEmployeeService(BaseEmployeeService):
182
+ """Custom employee service that connects to your HR system."""
183
+
184
+ def __init__(self, config: Dict[str, Any]):
185
+ super().__init__(config)
186
+ self.api_endpoint = config.get("api_endpoint")
187
+ self.api_key = config.get("api_key")
188
+
189
+ async def get_employee_dataframe(self) -> pd.DataFrame:
190
+ """Fetch all employees and return as DataFrame."""
191
+ # Your implementation here
192
+ # This should return a DataFrame with canonical schema columns:
193
+ # id, displayName, workEmail, jobTitle, department, location, supervisorId, hireDate, mobilePhone
194
+ employees_data = [
195
+ {
196
+ "id": "jdoe@company.com",
197
+ "displayName": "Jane Doe",
198
+ "workEmail": "jdoe@company.com",
199
+ "jobTitle": "Software Engineer",
200
+ "department": "Engineering",
201
+ "location": "San Francisco",
202
+ "supervisorId": "manager@company.com",
203
+ "hireDate": "2023-01-15",
204
+ "mobilePhone": "+1-555-0123"
205
+ }
206
+ ]
207
+ return pd.DataFrame(employees_data)
208
+
209
+ async def get_employee_profile(self, employee_id: str) -> Optional[Dict[str, Any]]:
210
+ """Get single employee profile."""
211
+ # Your implementation here
212
+ return {
213
+ "id": employee_id,
214
+ "displayName": "Jane Doe",
215
+ "workEmail": employee_id,
216
+ "jobTitle": "Software Engineer"
217
+ }
218
+
219
+ async def get_time_off_data(self, employee_id: str) -> List[Dict[str, Any]]:
220
+ """Get employee time off data."""
221
+ # Your implementation here
222
+ return [
223
+ {
224
+ 'start': '2025-07-04',
225
+ 'end': '2025-07-04',
226
+ 'type': 'Holiday',
227
+ 'amount': 'full_day'
228
+ }
229
+ ]
230
+
231
+ async def get_employee_profile_picture(self, employee_id: str) -> Optional[str]:
232
+ """Get employee profile picture as data URI."""
233
+ # Your implementation here
234
+ return None # or return "data:image/jpeg;base64,..."
235
+
236
+ # Usage
237
+ async def use_custom_service():
238
+ config = {
239
+ "api_endpoint": "https://your-hr-api.com",
240
+ "api_key": "your-api-key",
241
+ "cache_ttl_seconds": 3600
242
+ }
243
+
244
+ service = CustomEmployeeService(config)
245
+ profile = await service.get_employee_profile("jdoe@company.com")
246
+ print(f"Custom service profile: {profile}")
247
+ ```
248
+
249
+ ### 4. Working with Both Services Together
250
+ Often you'll want to use both identity and employee services together for comprehensive user information.
251
+
252
+ **Example: Combined Service Usage**
253
+
254
+ ```python
255
+ import asyncio
256
+ from solace_agent_mesh.common.services.identity_service import create_identity_service
257
+ from solace_agent_mesh.common.services.employee_service import create_employee_service
258
+
259
+ async def get_complete_user_info(user_email: str):
260
+ """Get comprehensive user information from both services."""
261
+
262
+ # Configure services
263
+ identity_config = {
264
+ "type": "local_file",
265
+ "file_path": "users.json",
266
+ "lookup_key": "email"
267
+ }
268
+
269
+ employee_config = {
270
+ "type": "your_hr_plugin",
271
+ "api_key": "your-key"
272
+ }
273
+
274
+ # Create services
275
+ identity_service = create_identity_service(identity_config)
276
+ employee_service = create_employee_service(employee_config)
277
+
278
+ # Gather information
279
+ user_info = {}
280
+
281
+ if identity_service:
282
+ auth_claims = {"email": user_email}
283
+ identity_profile = await identity_service.get_user_profile(auth_claims)
284
+ if identity_profile:
285
+ user_info.update(identity_profile)
286
+
287
+ if employee_service:
288
+ employee_profile = await employee_service.get_employee_profile(user_email)
289
+ if employee_profile:
290
+ user_info.update(employee_profile)
291
+
292
+ # Get additional employee data
293
+ time_off = await employee_service.get_time_off_data(user_email)
294
+ user_info["time_off"] = time_off
295
+
296
+ profile_pic = await employee_service.get_employee_profile_picture(user_email)
297
+ if profile_pic:
298
+ user_info["profile_picture"] = profile_pic
299
+
300
+ return user_info
301
+
302
+ # Usage
303
+ async def main():
304
+ complete_info = await get_complete_user_info("jane.doe@example.com")
305
+ print(f"Complete user information: {complete_info}")
306
+
307
+ asyncio.run(main())
308
+ ```
309
+
310
+ 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.
311
+
312
+ # content_hash: 63457e2c72256810f713e62325c1601a675951fe47c1121a647c404690179206
@@ -0,0 +1,29 @@
1
+ """
2
+ Common utility functions for working with ADK artifacts.
3
+ """
4
+
5
+ from typing import Optional
6
+ from google.adk.artifacts import BaseArtifactService
7
+ from solace_ai_connector.common.log import log
8
+
9
+
10
+ async def get_latest_artifact_version(
11
+ artifact_service: BaseArtifactService,
12
+ app_name: str,
13
+ user_id: str,
14
+ session_id: str,
15
+ filename: str,
16
+ ) -> Optional[int]:
17
+ """Resolves the latest version number for a given artifact."""
18
+ try:
19
+ versions = await artifact_service.list_artifact_versions(
20
+ app_name=app_name,
21
+ user_id=user_id,
22
+ session_id=session_id,
23
+ filename=filename,
24
+ )
25
+ if versions:
26
+ return max(versions)
27
+ except Exception as e:
28
+ log.error(f"Error listing versions for artifact '{filename}': {e}")
29
+ return None