solace-agent-mesh 1.0.9__py3-none-any.whl → 1.3.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 +25 -17
- solace_agent_mesh/agent/adk/services.py +3 -3
- 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 +460 -317
- solace_agent_mesh/agent/protocol/protocol_llm.txt +54 -7
- solace_agent_mesh/agent/sac/app.py +2 -2
- solace_agent_mesh/agent/sac/component.py +211 -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/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.08d30374.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 +4 -4
- 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-1757433031159.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1757433031159.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/agent_cmd.py +125 -48
- solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
- solace_agent_mesh/cli/commands/run_cmd.py +5 -3
- solace_agent_mesh/cli/utils.py +68 -12
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-vY5eu2lI.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-BeBkzgWW.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bjys1KQs.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CE0AeXyK.js +395 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -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/embeds/resolver.py +1 -0
- solace_agent_mesh/common/utils/utils_llm.txt +323 -42
- solace_agent_mesh/config_portal/backend/common.py +2 -2
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +10 -8
- solace_agent_mesh/core_a2a/service.py +20 -44
- solace_agent_mesh/evaluation/message_organizer.py +35 -56
- solace_agent_mesh/evaluation/run.py +26 -5
- solace_agent_mesh/evaluation/subscriber.py +35 -10
- solace_agent_mesh/evaluation/summary_builder.py +27 -34
- 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/ARCHITECTURE_GUIDE.md +676 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
- solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
- solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
- solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
- solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
- solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
- solace_agent_mesh/gateway/http_sse/app.py +31 -1
- solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
- solace_agent_mesh/gateway/http_sse/component.py +371 -236
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +29 -29
- solace_agent_mesh/gateway/http_sse/dependencies.py +142 -39
- solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +272 -36
- solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
- solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
- solace_agent_mesh/gateway/http_sse/main.py +293 -91
- solace_agent_mesh/gateway/http_sse/routers/agents.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +137 -56
- solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +231 -5
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +199 -171
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
- 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/gateway/http_sse/session_manager.py +64 -30
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
- solace_agent_mesh/templates/gateway_component_template.py +149 -98
- solace_agent_mesh/templates/shared_config.yaml +4 -5
- solace_agent_mesh/templates/webui.yaml +8 -10
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/METADATA +9 -6
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/RECORD +197 -141
- solace_agent_mesh/assets/docs/assets/js/f284c35a.731836ad.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.3d0e7879.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.05d19492.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1757091012487.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1757091012487.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
- solace_agent_mesh/client/webui/frontend/static/assets/main-D0FnP_W4.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-Do32sFPX.js +0 -708
- 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/_index-Bym6YkMd.js +0 -98
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -80
- solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
- /solace_agent_mesh/assets/docs/assets/js/{main.3d0e7879.js.LICENSE.txt → main.08d30374.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.0.9.dist-info → solace_agent_mesh-1.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,179 +1,133 @@
|
|
|
1
|
-
|
|
1
|
+
# DEVELOPER GUIDE: services
|
|
2
2
|
|
|
3
3
|
## Quick Summary
|
|
4
|
-
The `services` directory contains the business logic layer for the HTTP SSE Gateway. It
|
|
4
|
+
The `services` directory contains the business logic layer for the HTTP SSE Gateway. It provides high-level services for agent management (discovering and retrieving A2A agents), user identity operations (searching for users), and task management (cancelling A2A tasks). These services abstract the complexities of interacting with agent registries, identity providers, and A2A messaging protocols.
|
|
5
5
|
|
|
6
6
|
## Files Overview
|
|
7
|
-
- `__init__.py` -
|
|
8
|
-
- `agent_service.py` - Service for retrieving information about discovered A2A agents
|
|
9
|
-
- `people_service.py` - Service for searching
|
|
10
|
-
- `task_service.py` - Service for handling
|
|
7
|
+
- `__init__.py` - Package initialization file marking the directory as a Python package
|
|
8
|
+
- `agent_service.py` - Service for retrieving information about discovered A2A agents from the registry
|
|
9
|
+
- `people_service.py` - Service for searching users via configured identity services
|
|
10
|
+
- `task_service.py` - Service for handling A2A task cancellation operations
|
|
11
11
|
|
|
12
12
|
## Developer API Reference
|
|
13
13
|
|
|
14
14
|
### __init__.py
|
|
15
|
-
**Purpose:**
|
|
16
|
-
**Import:** N/A - No public interfaces
|
|
17
|
-
|
|
18
|
-
---
|
|
15
|
+
**Purpose:** Marks the services directory as a Python package
|
|
16
|
+
**Import:** N/A - No public interfaces
|
|
19
17
|
|
|
20
18
|
### agent_service.py
|
|
21
|
-
**Purpose:** Provides
|
|
22
|
-
**Import:** `from
|
|
19
|
+
**Purpose:** Provides methods for accessing information about discovered A2A agents from the shared AgentRegistry
|
|
20
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.services.agent_service import AgentService`
|
|
23
21
|
|
|
24
22
|
**Classes:**
|
|
25
|
-
- `AgentService(agent_registry: AgentRegistry)` -
|
|
26
|
-
- `get_all_agents() -> List[AgentCard]` - Retrieves all currently discovered and registered agent cards
|
|
27
|
-
- `get_agent_by_name(agent_name: str) -> Optional[AgentCard]` - Retrieves a specific agent card by
|
|
23
|
+
- `AgentService(agent_registry: AgentRegistry)` - Service for accessing discovered A2A agent information
|
|
24
|
+
- `get_all_agents() -> List[AgentCard]` - Retrieves all currently discovered and registered agent cards
|
|
25
|
+
- `get_agent_by_name(agent_name: str) -> Optional[AgentCard]` - Retrieves a specific agent card by name, returns None if not found
|
|
28
26
|
|
|
29
27
|
**Usage Examples:**
|
|
30
28
|
```python
|
|
31
|
-
from
|
|
32
|
-
from
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
# In a real application, AgentRegistry would be a shared instance.
|
|
37
|
-
# For this example, we'll create a new one and populate it.
|
|
38
|
-
agent_registry = AgentRegistry()
|
|
39
|
-
my_agent_card = AgentCard(name="data-analyzer", description="Analyzes data files.")
|
|
40
|
-
agent_registry.register_agent(my_agent_card)
|
|
41
|
-
|
|
42
|
-
# 1. Initialize the service with the agent registry
|
|
29
|
+
from solace_agent_mesh.gateway.http_sse.services.agent_service import AgentService
|
|
30
|
+
from solace_agent_mesh.common.agent_registry import AgentRegistry
|
|
31
|
+
|
|
32
|
+
# Initialize with shared agent registry
|
|
33
|
+
agent_registry = AgentRegistry() # Usually injected as shared instance
|
|
43
34
|
agent_service = AgentService(agent_registry=agent_registry)
|
|
44
35
|
|
|
45
|
-
#
|
|
36
|
+
# Get all available agents
|
|
46
37
|
all_agents = agent_service.get_all_agents()
|
|
47
|
-
print(f"Found {len(all_agents)}
|
|
48
|
-
for agent in all_agents:
|
|
49
|
-
print(f"- Agent: {agent.name}, Description: {agent.description}")
|
|
50
|
-
|
|
51
|
-
# 3. Get a specific agent by name
|
|
52
|
-
found_agent = agent_service.get_agent_by_name("data-analyzer")
|
|
53
|
-
if found_agent:
|
|
54
|
-
print(f"\nSuccessfully retrieved agent: {found_agent.name}")
|
|
55
|
-
else:
|
|
56
|
-
print("\nCould not find agent 'data-analyzer'.")
|
|
38
|
+
print(f"Found {len(all_agents)} agents")
|
|
57
39
|
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
40
|
+
# Get specific agent by name
|
|
41
|
+
agent = agent_service.get_agent_by_name("data-processor")
|
|
42
|
+
if agent:
|
|
43
|
+
print(f"Found agent: {agent.name}")
|
|
44
|
+
else:
|
|
45
|
+
print("Agent not found")
|
|
61
46
|
```
|
|
62
47
|
|
|
63
|
-
---
|
|
64
|
-
|
|
65
48
|
### people_service.py
|
|
66
|
-
**Purpose:**
|
|
67
|
-
**Import:** `from
|
|
49
|
+
**Purpose:** Provides user search functionality via configured identity services
|
|
50
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.services.people_service import PeopleService`
|
|
68
51
|
|
|
69
52
|
**Classes:**
|
|
70
|
-
- `PeopleService(identity_service: Optional[BaseIdentityService])` -
|
|
71
|
-
- `search_for_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Asynchronously searches for users
|
|
53
|
+
- `PeopleService(identity_service: Optional[BaseIdentityService])` - Service for searching and retrieving user information
|
|
54
|
+
- `search_for_users(query: str, limit: int = 10) -> List[Dict[str, Any]]` - Asynchronously searches for users, returns empty list if no identity service configured or query too short
|
|
72
55
|
|
|
73
56
|
**Usage Examples:**
|
|
74
57
|
```python
|
|
75
58
|
import asyncio
|
|
76
|
-
from
|
|
77
|
-
from
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{"id": "jdoe", "name": "John Doe", "email": "j.doe@example.com"},
|
|
86
|
-
{"id": "jsmith", "name": "Jane Smith", "email": "j.smith@example.com"},
|
|
87
|
-
]
|
|
88
|
-
return [user for user in all_users if query.lower() in user["name"].lower()][:limit]
|
|
89
|
-
|
|
90
|
-
async def main():
|
|
91
|
-
# 1. Initialize with a configured identity service
|
|
92
|
-
identity_service = MockIdentityService()
|
|
93
|
-
people_service = PeopleService(identity_service=identity_service)
|
|
94
|
-
|
|
95
|
-
# 2. Search for users
|
|
59
|
+
from solace_agent_mesh.gateway.http_sse.services.people_service import PeopleService
|
|
60
|
+
from solace_agent_mesh.common.services.identity_service import BaseIdentityService
|
|
61
|
+
|
|
62
|
+
# Initialize with identity service
|
|
63
|
+
identity_service = SomeIdentityService() # Your identity service implementation
|
|
64
|
+
people_service = PeopleService(identity_service=identity_service)
|
|
65
|
+
|
|
66
|
+
async def search_users():
|
|
67
|
+
# Search for users
|
|
96
68
|
users = await people_service.search_for_users("john", limit=5)
|
|
97
|
-
|
|
69
|
+
for user in users:
|
|
70
|
+
print(f"User: {user.get('name')} - {user.get('email')}")
|
|
98
71
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
# 4. Search will return an empty list
|
|
103
|
-
empty_results = await people_service_no_id.search_for_users("jane")
|
|
104
|
-
print(f"Results with no identity service: {empty_results}")
|
|
72
|
+
# Initialize without identity service (graceful degradation)
|
|
73
|
+
people_service_no_id = PeopleService(identity_service=None)
|
|
74
|
+
# search_for_users will return empty list
|
|
105
75
|
|
|
106
|
-
|
|
107
|
-
asyncio.run(main())
|
|
76
|
+
asyncio.run(search_users())
|
|
108
77
|
```
|
|
109
78
|
|
|
110
|
-
---
|
|
111
|
-
|
|
112
79
|
### task_service.py
|
|
113
|
-
**Purpose:** Handles
|
|
114
|
-
**Import:** `from
|
|
115
|
-
|
|
116
|
-
**Classes:**
|
|
117
|
-
- `TaskService(core_a2a_service: CoreA2AService, publish_func: PublishFunc, namespace: str, gateway_id: str, sse_manager: SSEManager, task_context_map: Dict[str, Dict], task_context_lock: threading.Lock, app_name: str)` - A service for managing A2A task operations.
|
|
118
|
-
- `cancel_task(agent_name: str, task_id: str, client_id: str, user_id: str = "web_user") -> None` - Asynchronously constructs and publishes an A2A `CancelTaskRequest` message for a specific task.
|
|
80
|
+
**Purpose:** Handles A2A task operations, specifically task cancellation using CoreA2AService and message publishing
|
|
81
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.services.task_service import TaskService, PublishFunc`
|
|
119
82
|
|
|
120
83
|
**Type Aliases:**
|
|
121
|
-
- `PublishFunc: Callable[[str, Dict, Optional[Dict]], None]` -
|
|
84
|
+
- `PublishFunc: Callable[[str, Dict, Optional[Dict]], None]` - Function type for publishing messages (topic, payload, user_properties)
|
|
85
|
+
|
|
86
|
+
**Classes:**
|
|
87
|
+
- `TaskService(core_a2a_service: CoreA2AService, publish_func: PublishFunc, namespace: str, gateway_id: str, sse_manager: SSEManager, task_context_map: Dict[str, Dict], task_context_lock: threading.Lock, app_name: str)` - Service for managing A2A task operations
|
|
88
|
+
- `cancel_task(agent_name: str, task_id: str, client_id: str, user_id: str = "web_user") -> None` - Asynchronously cancels a task by publishing A2A CancelTaskRequest message
|
|
122
89
|
|
|
123
90
|
**Usage Examples:**
|
|
124
91
|
```python
|
|
125
92
|
import asyncio
|
|
126
93
|
import threading
|
|
127
|
-
from
|
|
128
|
-
|
|
129
|
-
from
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
#
|
|
156
|
-
task_service = TaskService(
|
|
157
|
-
core_a2a_service=core_a2a_service,
|
|
158
|
-
publish_func=my_publish_func,
|
|
159
|
-
namespace="my-namespace",
|
|
160
|
-
gateway_id="gateway-01",
|
|
161
|
-
sse_manager=sse_manager,
|
|
162
|
-
task_context_map=task_context_map,
|
|
163
|
-
task_context_lock=task_context_lock,
|
|
164
|
-
app_name="my-app"
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
# 3. Call the cancel_task method
|
|
168
|
-
print("Requesting task cancellation...")
|
|
94
|
+
from solace_agent_mesh.gateway.http_sse.services.task_service import TaskService, PublishFunc
|
|
95
|
+
from solace_agent_mesh.core_a2a.service import CoreA2AService
|
|
96
|
+
from solace_agent_mesh.gateway.http_sse.sse_manager import SSEManager
|
|
97
|
+
|
|
98
|
+
# Define publish function
|
|
99
|
+
def my_publish_func(topic: str, payload: dict, user_properties: dict = None):
|
|
100
|
+
print(f"Publishing to {topic}: {payload}")
|
|
101
|
+
# Your actual message publishing logic here
|
|
102
|
+
|
|
103
|
+
# Initialize dependencies
|
|
104
|
+
core_a2a_service = CoreA2AService() # Your core A2A service
|
|
105
|
+
sse_manager = SSEManager()
|
|
106
|
+
task_context_map = {}
|
|
107
|
+
task_context_lock = threading.Lock()
|
|
108
|
+
|
|
109
|
+
# Create task service
|
|
110
|
+
task_service = TaskService(
|
|
111
|
+
core_a2a_service=core_a2a_service,
|
|
112
|
+
publish_func=my_publish_func,
|
|
113
|
+
namespace="my-namespace",
|
|
114
|
+
gateway_id="gateway-01",
|
|
115
|
+
sse_manager=sse_manager,
|
|
116
|
+
task_context_map=task_context_map,
|
|
117
|
+
task_context_lock=task_context_lock,
|
|
118
|
+
app_name="my-app"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
async def cancel_task_example():
|
|
122
|
+
# Cancel a task
|
|
169
123
|
await task_service.cancel_task(
|
|
170
|
-
agent_name="
|
|
171
|
-
task_id="task-
|
|
172
|
-
client_id="client-
|
|
173
|
-
user_id="
|
|
124
|
+
agent_name="data-processor",
|
|
125
|
+
task_id="task-123",
|
|
126
|
+
client_id="client-456",
|
|
127
|
+
user_id="user@example.com"
|
|
174
128
|
)
|
|
175
|
-
print("Task cancellation request sent.")
|
|
176
129
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
130
|
+
asyncio.run(cancel_task_example())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
# content_hash: 83ddf6b403dc50598ed550e4b3a5445f832b3956dad75f7a3fbbb7e6e5c6c115
|
|
@@ -8,10 +8,7 @@ from typing import Callable, Dict, Optional
|
|
|
8
8
|
|
|
9
9
|
from solace_ai_connector.common.log import log
|
|
10
10
|
|
|
11
|
-
from ....common
|
|
12
|
-
InternalError,
|
|
13
|
-
)
|
|
14
|
-
|
|
11
|
+
from ....common import a2a
|
|
15
12
|
from ....gateway.http_sse.sse_manager import SSEManager
|
|
16
13
|
from ....core_a2a.service import CoreA2AService
|
|
17
14
|
|
|
@@ -116,6 +113,6 @@ class TaskService:
|
|
|
116
113
|
|
|
117
114
|
except Exception as e:
|
|
118
115
|
log.exception("%sFailed to publish cancellation request: %s", log_prefix, e)
|
|
119
|
-
raise
|
|
116
|
+
raise a2a.create_internal_error(
|
|
120
117
|
message="Failed to publish cancellation request: %s" % e
|
|
121
118
|
) from e
|
|
@@ -3,10 +3,13 @@ Manages web user sessions and mapping to A2A Client IDs.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import uuid
|
|
6
|
-
from
|
|
7
|
-
from typing import
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
from solace_ai_connector.common.log import log
|
|
10
|
+
from starlette.requests import Request
|
|
11
|
+
|
|
12
|
+
from .infrastructure.persistence_service import PersistenceService
|
|
10
13
|
|
|
11
14
|
SESSION_KEY_CLIENT_ID = "a2a_client_id"
|
|
12
15
|
SESSION_KEY_SESSION_ID = "a2a_session_id"
|
|
@@ -21,12 +24,18 @@ class SessionManager:
|
|
|
21
24
|
Generates and stores unique A2A Client IDs and manages the current A2A Session ID per web session.
|
|
22
25
|
"""
|
|
23
26
|
|
|
24
|
-
def __init__(
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
secret_key: str,
|
|
30
|
+
app_config: dict[str, Any],
|
|
31
|
+
persistence_service: "PersistenceService",
|
|
32
|
+
):
|
|
25
33
|
if not secret_key:
|
|
26
34
|
raise ValueError("Session secret key cannot be empty.")
|
|
27
35
|
self.secret_key = secret_key
|
|
28
36
|
self.force_user_identity = app_config.get("force_user_identity")
|
|
29
|
-
self.
|
|
37
|
+
self.use_authorization = app_config.get("frontend_use_authorization", False)
|
|
38
|
+
self.persistence_service = persistence_service
|
|
30
39
|
self._temp_code_cache = {}
|
|
31
40
|
log.info("[SessionManager] Initialized.")
|
|
32
41
|
if self.force_user_identity:
|
|
@@ -34,10 +43,11 @@ class SessionManager:
|
|
|
34
43
|
f"[SessionManager] Forcing user identity to: {self.force_user_identity}"
|
|
35
44
|
)
|
|
36
45
|
|
|
37
|
-
def _get_or_create_client_id(self, request: Request) -> str:
|
|
46
|
+
def _get_or_create_client_id(self, request: Request) -> str | None:
|
|
38
47
|
"""
|
|
39
48
|
Retrieves the A2A Client ID. It prioritizes the authenticated user from
|
|
40
49
|
`request.state.user` and falls back to session-based or generated IDs.
|
|
50
|
+
If authorization is enabled, it returns None if no user can be identified.
|
|
41
51
|
"""
|
|
42
52
|
if self.force_user_identity:
|
|
43
53
|
return self.force_user_identity
|
|
@@ -64,35 +74,35 @@ class SessionManager:
|
|
|
64
74
|
return user_id
|
|
65
75
|
|
|
66
76
|
client_id = request.session.get(SESSION_KEY_CLIENT_ID)
|
|
67
|
-
if
|
|
68
|
-
if self.default_user_identity:
|
|
69
|
-
log.info(
|
|
70
|
-
"[SessionManager] Using default_user_identity as A2A Client ID: %s",
|
|
71
|
-
self.default_user_identity,
|
|
72
|
-
)
|
|
73
|
-
client_id = self.default_user_identity
|
|
74
|
-
else:
|
|
75
|
-
client_id = f"web-client-{uuid.uuid4().hex}"
|
|
76
|
-
log.info(
|
|
77
|
-
"[SessionManager] Created new A2A Client ID: %s for web session.",
|
|
78
|
-
client_id,
|
|
79
|
-
)
|
|
80
|
-
request.session[SESSION_KEY_CLIENT_ID] = client_id
|
|
81
|
-
else:
|
|
77
|
+
if client_id:
|
|
82
78
|
log.debug(
|
|
83
79
|
"[SessionManager] Using existing A2A Client ID: %s for web session.",
|
|
84
80
|
client_id,
|
|
85
81
|
)
|
|
86
|
-
|
|
82
|
+
return client_id
|
|
83
|
+
|
|
84
|
+
if not self.use_authorization:
|
|
85
|
+
client_id = "sam_dev_user"
|
|
86
|
+
log.info(
|
|
87
|
+
"[SessionManager] No authenticated user and auth is disabled, using client ID: %s for web session.",
|
|
88
|
+
client_id,
|
|
89
|
+
)
|
|
90
|
+
request.session[SESSION_KEY_CLIENT_ID] = client_id
|
|
91
|
+
return client_id
|
|
92
|
+
|
|
93
|
+
log.warning(
|
|
94
|
+
"[SessionManager] Could not determine client ID and authorization is enabled."
|
|
95
|
+
)
|
|
96
|
+
return None
|
|
87
97
|
|
|
88
|
-
def get_a2a_client_id(self, request: Request) -> str:
|
|
98
|
+
def get_a2a_client_id(self, request: Request) -> str | None:
|
|
89
99
|
"""
|
|
90
100
|
FastAPI dependency callable to get the A2A Client ID for the current request.
|
|
91
|
-
Ensures a client ID exists in the session.
|
|
101
|
+
Ensures a client ID exists in the session if auth is disabled.
|
|
92
102
|
"""
|
|
93
103
|
return self._get_or_create_client_id(request)
|
|
94
104
|
|
|
95
|
-
def get_a2a_session_id(self, request: Request) ->
|
|
105
|
+
def get_a2a_session_id(self, request: Request) -> str | None:
|
|
96
106
|
"""
|
|
97
107
|
FastAPI dependency callable to get the current A2A Session ID for the current request.
|
|
98
108
|
Returns None if no session has been started for the current agent in this web session.
|
|
@@ -107,6 +117,11 @@ class SessionManager:
|
|
|
107
117
|
This should be called when the user explicitly starts a new chat or switches agents.
|
|
108
118
|
"""
|
|
109
119
|
client_id = self._get_or_create_client_id(request)
|
|
120
|
+
if not client_id:
|
|
121
|
+
# This case should ideally be prevented by middleware raising 401
|
|
122
|
+
raise RuntimeError(
|
|
123
|
+
"Cannot start a new A2A session without a client ID when authorization is enabled."
|
|
124
|
+
)
|
|
110
125
|
new_session_id = f"web-session-{uuid.uuid4().hex}"
|
|
111
126
|
request.session[SESSION_KEY_SESSION_ID] = new_session_id
|
|
112
127
|
log.info(
|
|
@@ -116,6 +131,25 @@ class SessionManager:
|
|
|
116
131
|
)
|
|
117
132
|
return new_session_id
|
|
118
133
|
|
|
134
|
+
def create_new_session_id(self, request: Request) -> str:
|
|
135
|
+
"""
|
|
136
|
+
Generates a new A2A Session ID without storing it in cookies.
|
|
137
|
+
This should be used when the frontend manages session state.
|
|
138
|
+
"""
|
|
139
|
+
client_id = self._get_or_create_client_id(request)
|
|
140
|
+
if not client_id:
|
|
141
|
+
# This case should ideally be prevented by middleware raising 401
|
|
142
|
+
raise RuntimeError(
|
|
143
|
+
"Cannot start a new A2A session without a client ID when authorization is enabled."
|
|
144
|
+
)
|
|
145
|
+
new_session_id = f"web-session-{uuid.uuid4().hex}"
|
|
146
|
+
log.info(
|
|
147
|
+
"[SessionManager] Generated new A2A Session ID: %s for Client ID: %s (not stored in cookies)",
|
|
148
|
+
new_session_id,
|
|
149
|
+
client_id,
|
|
150
|
+
)
|
|
151
|
+
return new_session_id
|
|
152
|
+
|
|
119
153
|
def ensure_a2a_session(self, request: Request) -> str:
|
|
120
154
|
"""
|
|
121
155
|
Ensures an A2A session ID exists, creating one if necessary.
|
|
@@ -131,7 +165,7 @@ class SessionManager:
|
|
|
131
165
|
return session_id
|
|
132
166
|
|
|
133
167
|
def store_auth_tokens(
|
|
134
|
-
self, request: Request, access_token: str, refresh_token:
|
|
168
|
+
self, request: Request, access_token: str, refresh_token: str | None = None
|
|
135
169
|
):
|
|
136
170
|
"""
|
|
137
171
|
Stores authentication tokens directly in the user's session.
|
|
@@ -141,13 +175,13 @@ class SessionManager:
|
|
|
141
175
|
request.session[SESSION_KEY_REFRESH_TOKEN] = refresh_token
|
|
142
176
|
log.info("[SessionManager] Stored auth tokens directly in session.")
|
|
143
177
|
|
|
144
|
-
def get_access_token(self, request: Request) ->
|
|
178
|
+
def get_access_token(self, request: Request) -> str | None:
|
|
145
179
|
"""
|
|
146
180
|
Retrieves the access token from the web session.
|
|
147
181
|
"""
|
|
148
182
|
return request.session.get(SESSION_KEY_ACCESS_TOKEN)
|
|
149
183
|
|
|
150
|
-
def get_refresh_token(self, request: Request) ->
|
|
184
|
+
def get_refresh_token(self, request: Request) -> str | None:
|
|
151
185
|
"""
|
|
152
186
|
Retrieves the refresh token from the web session.
|
|
153
187
|
"""
|
|
@@ -168,17 +202,17 @@ class SessionManager:
|
|
|
168
202
|
request.session[SESSION_KEY_USER_ID] = user_id
|
|
169
203
|
log.info("[SessionManager] Stored user ID in session: %s", user_id)
|
|
170
204
|
|
|
171
|
-
def get_user_id(self, request: Request) ->
|
|
205
|
+
def get_user_id(self, request: Request) -> str | None:
|
|
172
206
|
"""
|
|
173
207
|
Retrieves the user ID from the web session.
|
|
174
208
|
"""
|
|
175
209
|
return request.session.get(SESSION_KEY_USER_ID)
|
|
176
210
|
|
|
177
|
-
def dep_get_client_id(self) -> Callable[[Request], str]:
|
|
211
|
+
def dep_get_client_id(self) -> Callable[[Request], str | None]:
|
|
178
212
|
"""Returns a callable suitable for FastAPI Depends to get the client ID."""
|
|
179
213
|
return self.get_a2a_client_id
|
|
180
214
|
|
|
181
|
-
def dep_get_session_id(self) -> Callable[[Request],
|
|
215
|
+
def dep_get_session_id(self) -> Callable[[Request], str | None]:
|
|
182
216
|
"""Returns a callable suitable for FastAPI Depends to get the current session ID."""
|
|
183
217
|
return self.get_a2a_session_id
|
|
184
218
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Authentication utilities for the FastAPI application.
|
|
3
|
+
|
|
4
|
+
This module provides common authentication functions used across controllers.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from fastapi import Depends, Request as FastAPIRequest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def get_current_user(request: FastAPIRequest) -> dict:
|
|
11
|
+
"""
|
|
12
|
+
Extracts the current user from the request state.
|
|
13
|
+
|
|
14
|
+
This function is used as a FastAPI dependency to get the authenticated user
|
|
15
|
+
information that was set by the AuthMiddleware.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
request: The FastAPI request object with user state
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
dict: User information dictionary containing id, name, email, etc.
|
|
22
|
+
"""
|
|
23
|
+
return getattr(request.state, "user", {
|
|
24
|
+
"id": "anonymous",
|
|
25
|
+
"name": "Anonymous User",
|
|
26
|
+
"email": "anonymous@localhost",
|
|
27
|
+
"authenticated": False,
|
|
28
|
+
"auth_method": "none"
|
|
29
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Enumerations used throughout the application.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SenderType(str, Enum):
|
|
9
|
+
"""Types of message senders."""
|
|
10
|
+
USER = "user"
|
|
11
|
+
AGENT = "agent"
|
|
12
|
+
SYSTEM = "system"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TaskStatus(str, Enum):
|
|
16
|
+
"""Task execution status."""
|
|
17
|
+
PENDING = "pending"
|
|
18
|
+
RUNNING = "running"
|
|
19
|
+
COMPLETED = "completed"
|
|
20
|
+
FAILED = "failed"
|
|
21
|
+
CANCELLED = "cancelled"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class SessionStatus(str, Enum):
|
|
25
|
+
"""Session status."""
|
|
26
|
+
ACTIVE = "active"
|
|
27
|
+
INACTIVE = "inactive"
|
|
28
|
+
ARCHIVED = "archived"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MessageType(str, Enum):
|
|
32
|
+
"""Types of messages."""
|
|
33
|
+
TEXT = "text"
|
|
34
|
+
FILE = "file"
|
|
35
|
+
IMAGE = "image"
|
|
36
|
+
DOCUMENT = "document"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ValidationErrorType(str, Enum):
|
|
40
|
+
"""Types of validation errors."""
|
|
41
|
+
REQUIRED_FIELD = "required_field"
|
|
42
|
+
INVALID_FORMAT = "invalid_format"
|
|
43
|
+
OUT_OF_RANGE = "out_of_range"
|
|
44
|
+
DUPLICATE_VALUE = "duplicate_value"
|
|
45
|
+
BUSINESS_RULE = "business_rule"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Custom types and type aliases used throughout the application.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any, List, Optional, Union
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
# Basic type aliases
|
|
10
|
+
UserId = str
|
|
11
|
+
SessionId = str
|
|
12
|
+
MessageId = str
|
|
13
|
+
TaskId = str
|
|
14
|
+
AgentId = str
|
|
15
|
+
|
|
16
|
+
# Dictionary types
|
|
17
|
+
JsonDict = Dict[str, Any]
|
|
18
|
+
Headers = Dict[str, str]
|
|
19
|
+
QueryParams = Dict[str, Union[str, List[str]]]
|
|
20
|
+
|
|
21
|
+
# Common data structures
|
|
22
|
+
class Timestamp(BaseModel):
|
|
23
|
+
"""Standardized timestamp representation."""
|
|
24
|
+
created_at: datetime
|
|
25
|
+
updated_at: Optional[datetime] = None
|
|
26
|
+
|
|
27
|
+
class PaginationInfo(BaseModel):
|
|
28
|
+
"""Pagination information for list responses."""
|
|
29
|
+
page: int
|
|
30
|
+
page_size: int
|
|
31
|
+
total_items: int
|
|
32
|
+
total_pages: int
|
|
33
|
+
has_next: bool
|
|
34
|
+
has_previous: bool
|
|
35
|
+
|
|
36
|
+
class SortInfo(BaseModel):
|
|
37
|
+
"""Sorting information for list requests."""
|
|
38
|
+
field: str
|
|
39
|
+
direction: str = "asc" # asc or desc
|
|
40
|
+
|
|
41
|
+
class FilterInfo(BaseModel):
|
|
42
|
+
"""Filtering information for list requests."""
|
|
43
|
+
field: str
|
|
44
|
+
operator: str # eq, ne, gt, lt, gte, lte, contains, in
|
|
45
|
+
value: Any
|