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.
- solace_agent_mesh/agent/adk/adk_llm.txt +3 -4
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +51 -2
- solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
- solace_agent_mesh/agent/agent_llm.txt +1 -1
- solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +2 -13
- solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
- solace_agent_mesh/agent/sac/component.py +51 -21
- solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/483cef9a.bf9398af.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js → main.0c149855.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/{runtime~main.40527046.js → runtime~main.c66557e4.js} +1 -1
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +8 -4
- 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
- solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1760032255022.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1760032255022.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-CZbpmwfA.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C__uuUkB.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/a2a_llm.txt +1 -1
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
- solace_agent_mesh/common/common_llm.txt +24 -39
- solace_agent_mesh/common/common_llm_detail.txt +2562 -0
- solace_agent_mesh/common/data_parts.py +9 -1
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
- solace_agent_mesh/common/services/services_llm.txt +57 -6
- solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/utils_llm.txt +75 -87
- solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
- solace_agent_mesh/gateway/base/app.py +1 -1
- solace_agent_mesh/gateway/base/base_llm.txt +1 -1
- solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
- solace_agent_mesh/gateway/gateway_llm.txt +242 -235
- solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
- solace_agent_mesh/gateway/http_sse/app.py +148 -2
- solace_agent_mesh/gateway/http_sse/component.py +368 -60
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +108 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +1 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +116 -26
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
- solace_agent_mesh/gateway/http_sse/main.py +146 -41
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
- solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
- solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
- solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/config.py +26 -4
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +220 -40
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +168 -42
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +272 -0
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +241 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +0 -80
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
- solace_agent_mesh/gateway/http_sse/services/session_service.py +151 -84
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +317 -0
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
- solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/METADATA +1 -1
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/RECORD +172 -124
- solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
- solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1759936913198.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1759936913198.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
- solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
- solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
- solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
- /solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js.LICENSE.txt → main.0c149855.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.0.dist-info}/entry_points.txt +0 -0
- {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
|
+
|
|
@@ -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.
|
|
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
|
-
###
|
|
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
|
-
###
|
|
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"
|
|
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:
|
|
336
|
+
# content_hash: d80ffe631ca180ea5aacca592313af42838960a949c8664559a957c2492fa86f
|