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.
- solace_agent_mesh/agent/adk/adk_llm.txt +182 -42
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
- solace_agent_mesh/agent/adk/callbacks.py +165 -104
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +0 -18
- solace_agent_mesh/agent/adk/models/models_llm.txt +104 -55
- solace_agent_mesh/agent/adk/runner.py +7 -5
- solace_agent_mesh/agent/adk/setup.py +11 -0
- solace_agent_mesh/agent/adk/stream_parser.py +8 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +10 -3
- solace_agent_mesh/agent/agent_llm.txt +355 -18
- solace_agent_mesh/agent/protocol/event_handlers.py +433 -296
- solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
- solace_agent_mesh/agent/sac/app.py +1 -1
- solace_agent_mesh/agent/sac/component.py +212 -517
- solace_agent_mesh/agent/sac/sac_llm.txt +133 -63
- solace_agent_mesh/agent/testing/testing_llm.txt +25 -58
- solace_agent_mesh/agent/tools/peer_agent_tool.py +15 -11
- solace_agent_mesh/agent/tools/tools_llm.txt +234 -69
- solace_agent_mesh/agent/utils/artifact_helpers.py +35 -1
- solace_agent_mesh/agent/utils/utils_llm.txt +90 -105
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/{3d406171.7d02a73b.js → 3d406171.0b9eeed1.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{75384d09.ccd480c4.js → 75384d09.bf78fbdb.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.a75ecc0d.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
- 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
- solace_agent_mesh/assets/docs/docs/documentation/migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html +53 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1756992446316.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +12 -3
- solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +10 -14
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +2 -15
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +6 -2
- solace_agent_mesh/cli/utils.py +15 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-DvlO62me.js → authCallback-BmF2l6vg.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-bp6u3qVZ.js → client-D881Dttc.js} +4 -4
- solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +699 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +2 -2
- solace_agent_mesh/client/webui/frontend/static/index.html +3 -3
- solace_agent_mesh/common/a2a/__init__.py +213 -0
- solace_agent_mesh/common/a2a/a2a_llm.txt +182 -0
- solace_agent_mesh/common/a2a/artifact.py +328 -0
- solace_agent_mesh/common/a2a/events.py +183 -0
- solace_agent_mesh/common/a2a/message.py +307 -0
- solace_agent_mesh/common/a2a/protocol.py +513 -0
- solace_agent_mesh/common/a2a/task.py +127 -0
- solace_agent_mesh/common/a2a/translation.py +653 -0
- solace_agent_mesh/common/a2a/types.py +54 -0
- solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +407 -0
- solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +31 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +235 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +25 -0
- solace_agent_mesh/common/agent_registry.py +1 -1
- solace_agent_mesh/common/common_llm.txt +192 -70
- solace_agent_mesh/common/data_parts.py +99 -0
- solace_agent_mesh/common/middleware/middleware_llm.txt +17 -17
- solace_agent_mesh/common/sac/__init__.py +0 -0
- solace_agent_mesh/common/sac/sac_llm.txt +71 -0
- solace_agent_mesh/common/sac/sam_component_base.py +252 -0
- solace_agent_mesh/common/services/providers/providers_llm.txt +51 -84
- solace_agent_mesh/common/services/services_llm.txt +206 -26
- solace_agent_mesh/common/utils/artifact_utils.py +29 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +176 -80
- solace_agent_mesh/common/utils/utils_llm.txt +323 -42
- solace_agent_mesh/config_portal/backend/common.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/{_index-MqsrTd6g.js → _index-Bym6YkMd.js} +74 -24
- solace_agent_mesh/config_portal/frontend/static/client/assets/{components-B7lKcHVY.js → components-Rk0n-9cK.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-CEumGClk.js → entry.client-mvZjNKiz.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DSo1AH_7.js → index-DzNKzXrc.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-d845808d.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{root-C4XmHinv.js → root-BWvk5-gF.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
- solace_agent_mesh/core_a2a/service.py +20 -44
- solace_agent_mesh/gateway/base/app.py +27 -1
- solace_agent_mesh/gateway/base/base_llm.txt +177 -72
- solace_agent_mesh/gateway/base/component.py +294 -523
- solace_agent_mesh/gateway/gateway_llm.txt +299 -58
- solace_agent_mesh/gateway/http_sse/component.py +156 -183
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
- solace_agent_mesh/gateway/http_sse/main.py +8 -10
- solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +18 -4
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +12 -7
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +116 -169
- solace_agent_mesh/gateway/http_sse/services/agent_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +89 -135
- solace_agent_mesh/gateway/http_sse/services/task_service.py +2 -5
- solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
- solace_agent_mesh/templates/gateway_component_template.py +149 -98
- {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/METADATA +5 -4
- {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/RECORD +143 -126
- solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.6dba4a66.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.6415ad00.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1756153049706.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1756153049706.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-BCpII1-0.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-BucUdn9m.js +0 -673
- solace_agent_mesh/common/a2a_protocol.py +0 -564
- solace_agent_mesh/common/client/__init__.py +0 -4
- solace_agent_mesh/common/client/card_resolver.py +0 -21
- solace_agent_mesh/common/client/client.py +0 -85
- solace_agent_mesh/common/client/client_llm.txt +0 -133
- solace_agent_mesh/common/server/__init__.py +0 -4
- solace_agent_mesh/common/server/server.py +0 -122
- solace_agent_mesh/common/server/server_llm.txt +0 -169
- solace_agent_mesh/common/server/task_manager.py +0 -291
- solace_agent_mesh/common/server/utils.py +0 -28
- solace_agent_mesh/common/types.py +0 -411
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-28271392.js +0 -1
- /solace_agent_mesh/assets/docs/assets/js/{main.6dba4a66.js.LICENSE.txt → main.a75ecc0d.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.8.dist-info → solace_agent_mesh-1.1.0.dist-info}/entry_points.txt +0 -0
- {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
|
|
6
|
-
- `local_file_identity_service.py
|
|
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
|
|
12
|
-
**Import:** `from
|
|
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
|
|
20
|
-
**Import:** `from
|
|
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])` -
|
|
24
|
-
- `async get_user_profile(auth_claims: Dict[str, Any]) -> Optional[Dict[str, Any]]` - Looks up a user profile
|
|
25
|
-
- `async search_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Performs
|
|
26
|
-
- `file_path: str` -
|
|
27
|
-
- `lookup_key: str` -
|
|
28
|
-
- `all_users: List[Dict[str, Any]]` -
|
|
29
|
-
- `user_index: Dict[str, Dict[str, Any]]` -
|
|
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
|
|
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
|
-
#
|
|
35
|
+
# Create sample users.json file
|
|
42
36
|
users_data = [
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
#
|
|
66
|
-
# The 'file_path' is required. 'lookup_key' is optional (defaults to 'id').
|
|
56
|
+
# Initialize the service
|
|
67
57
|
config = {
|
|
68
|
-
"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
|
-
|
|
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
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
print(f"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
61
|
+
**Example: Creating Identity and Employee Services**
|
|
61
62
|
|
|
62
63
|
```python
|
|
63
64
|
import asyncio
|
|
64
|
-
from
|
|
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
|
|
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
|
|
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
|
-
#
|
|
111
|
-
|
|
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.
|
|
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
|
|
120
|
+
**Example: Direct Use of LocalFileIdentityService**
|
|
118
121
|
|
|
119
122
|
```python
|
|
120
123
|
import asyncio
|
|
121
|
-
|
|
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": "
|
|
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
|