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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# DEVELOPER GUIDE for the http_sse directory
|
|
2
2
|
|
|
3
3
|
## Quick Summary
|
|
4
4
|
The `http_sse` directory implements a complete HTTP/SSE (Server-Sent Events) gateway for the A2A (Agent-to-Agent) system. Its primary purpose is to serve a web-based user interface and act as a bridge between standard web protocols (HTTP, WebSockets/SSE) and the backend A2A messaging fabric.
|
|
@@ -6,26 +6,26 @@ The `http_sse` directory implements a complete HTTP/SSE (Server-Sent Events) gat
|
|
|
6
6
|
The architecture is centered around the `WebUIBackendComponent`, a custom Solace AI Connector (SAC) component that hosts an embedded FastAPI web server. This component manages shared state and resources, such as the `SSEManager` for real-time updates, the `SessionManager` for user sessions, and the `AgentRegistry` for discovering available agents.
|
|
7
7
|
|
|
8
8
|
Subdirectories organize the functionality:
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
9
|
+
- `routers/` defines the REST API endpoints (e.g., `/tasks`, `/agents`).
|
|
10
|
+
- `services/` contains the business logic that the API endpoints call.
|
|
11
|
+
- `dependencies.py` uses FastAPI's dependency injection system to provide the routers and services with safe access to the shared resources managed by the main component.
|
|
12
|
+
- `components/` contains specialized SAC components, for example, to forward A2A messages for real-time visualization.
|
|
13
13
|
|
|
14
14
|
This design creates a clean separation of concerns, where the web layer (FastAPI) is decoupled from the core messaging and state management layer (SAC Component).
|
|
15
15
|
|
|
16
16
|
## Files and Subdirectories Overview
|
|
17
17
|
- **Direct files:**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
- `__init__.py`: Standard Python package initializer.
|
|
19
|
+
- `app.py`: Defines the main SAC `WebUIBackendApp`, which specifies configuration and launches the component.
|
|
20
|
+
- `component.py`: The core SAC component that hosts the FastAPI server and manages all shared resources and A2A logic.
|
|
21
|
+
- `dependencies.py`: Provides FastAPI dependency injectors for accessing shared resources like services and managers.
|
|
22
|
+
- `main.py`: The main FastAPI application instance, including middleware, router mounting, and exception handling.
|
|
23
|
+
- `session_manager.py`: Manages web user sessions and maps them to unique A2A client and session IDs.
|
|
24
|
+
- `sse_manager.py`: Manages Server-Sent Event (SSE) connections for streaming real-time updates to clients.
|
|
25
25
|
- **Subdirectories:**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
- `components/`: Contains specialized SAC components, such as for forwarding messages to the visualization system.
|
|
27
|
+
- `routers/`: Defines the FastAPI `APIRouter` modules for all REST API endpoints.
|
|
28
|
+
- `services/`: Encapsulates business logic for agents, tasks, and other domain-specific operations.
|
|
29
29
|
|
|
30
30
|
## Developer API Reference
|
|
31
31
|
|
|
@@ -33,31 +33,267 @@ This design creates a clean separation of concerns, where the web layer (FastAPI
|
|
|
33
33
|
|
|
34
34
|
#### app.py
|
|
35
35
|
**Purpose:** This file defines the `WebUIBackendApp`, a custom SAC (Solace AI Connector) App class. It is responsible for defining the configuration schema for the entire HTTP/SSE gateway and programmatically creating the `WebUIBackendComponent`.
|
|
36
|
-
**Import:** `from gateway.http_sse.app import WebUIBackendApp`
|
|
36
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.app import WebUIBackendApp`
|
|
37
37
|
|
|
38
38
|
**Classes/Functions/Constants:**
|
|
39
|
-
-
|
|
40
|
-
-
|
|
39
|
+
- **`WebUIBackendApp(BaseGatewayApp)`**: The main application class. It extends `BaseGatewayApp` and adds a list of WebUI-specific configuration parameters to the application schema.
|
|
40
|
+
- **`SPECIFIC_APP_SCHEMA_PARAMS: List[Dict[str, Any]]`**: A constant list defining the configuration parameters specific to the HTTP/SSE gateway, such as `session_secret_key`, `fastapi_host`, `fastapi_port`, and various frontend-related settings.
|
|
41
41
|
|
|
42
42
|
#### component.py
|
|
43
43
|
**Purpose:** This is the core component of the gateway. It hosts the FastAPI server, manages all shared state (like the SSE and Session managers), handles the lifecycle of the web server, and implements the logic for translating between external HTTP requests and internal A2A messages.
|
|
44
|
-
**Import:** `from gateway.http_sse.component import WebUIBackendComponent`
|
|
44
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.component import WebUIBackendComponent`
|
|
45
45
|
|
|
46
46
|
**Classes/Functions/Constants:**
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
47
|
+
- **`WebUIBackendComponent(BaseGatewayComponent)`**: The main component class. Developers will primarily interact with its instances via the dependency injection system.
|
|
48
|
+
- **Public Accessor Methods (for Dependencies):**
|
|
49
|
+
- `get_sse_manager() -> SSEManager`: Returns the shared `SSEManager` instance.
|
|
50
|
+
- `get_session_manager() -> SessionManager`: Returns the shared `SessionManager` instance.
|
|
51
|
+
- `get_agent_registry() -> AgentRegistry`: Returns the shared `AgentRegistry` instance.
|
|
52
|
+
- `get_core_a2a_service() -> CoreA2AService`: Returns the core service for creating A2A messages.
|
|
53
|
+
- `get_shared_artifact_service() -> Optional[BaseArtifactService]`: Returns the service for artifact storage.
|
|
54
|
+
- `get_namespace() -> str`: Returns the configured A2A namespace.
|
|
55
|
+
- `get_gateway_id() -> str`: Returns the unique ID of this gateway.
|
|
56
|
+
- **Core Logic Methods:**
|
|
57
|
+
- `publish_a2a(topic: str, payload: Dict, user_properties: Optional[Dict] = None)`: Publishes a message onto the A2A messaging fabric. This is the primary method for sending data to agents.
|
|
58
|
+
- **Gateway-Development-Kit (GDK) Hooks:** These methods implement the `BaseGatewayComponent` abstract interface.
|
|
59
|
+
- `_start_listener()`: Starts the FastAPI/Uvicorn server.
|
|
60
|
+
- `_stop_listener()`: Stops the FastAPI/Uvicorn server.
|
|
61
|
+
- `_translate_external_input(...)`: Translates an incoming HTTP request (e.g., form data with files) into a structured A2A message (`List[ContentPart]`).
|
|
62
|
+
- `_send_update_to_external(...)`: Sends an intermediate status update from an agent back to the client via SSE.
|
|
63
|
+
- `_send_final_response_to_external(...)`: Sends the final A2A Task result to the client via SSE.
|
|
64
|
+
- `_send_error_to_external(...)`: Sends an error notification to the client via SSE.
|
|
65
|
+
|
|
66
|
+
#### dependencies.py
|
|
67
|
+
**Purpose:** Defines FastAPI dependency injectors to access shared resources managed by the WebUIBackendComponent.
|
|
68
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.dependencies import *`
|
|
69
|
+
|
|
70
|
+
**Functions:**
|
|
71
|
+
- `get_sac_component() -> WebUIBackendComponent`: Returns the main component instance.
|
|
72
|
+
- `get_agent_registry() -> AgentRegistry`: Returns the shared agent registry.
|
|
73
|
+
- `get_sse_manager() -> SSEManager`: Returns the SSE manager for real-time updates.
|
|
74
|
+
- `get_session_manager() -> SessionManager`: Returns the session manager.
|
|
75
|
+
- `get_user_id(request: Request) -> str`: Returns the current user's identity.
|
|
76
|
+
- `get_publish_a2a_func() -> PublishFunc`: Returns the function for publishing A2A messages.
|
|
77
|
+
- `get_core_a2a_service() -> CoreA2AService`: Returns the core A2A service.
|
|
78
|
+
- `get_shared_artifact_service() -> Optional[BaseArtifactService]`: Returns the artifact service.
|
|
79
|
+
|
|
80
|
+
#### main.py
|
|
81
|
+
**Purpose:** Defines the FastAPI application instance, mounts routers, and configures middleware.
|
|
82
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.main import app, setup_dependencies`
|
|
83
|
+
|
|
84
|
+
**Classes/Functions/Constants:**
|
|
85
|
+
- **`app: FastAPI`**: The main FastAPI application instance.
|
|
86
|
+
- **`setup_dependencies(component: WebUIBackendComponent)`**: Configures middleware, routers, and dependency injection based on the component instance.
|
|
87
|
+
|
|
88
|
+
#### session_manager.py
|
|
89
|
+
**Purpose:** Manages web user sessions and mapping to A2A Client IDs.
|
|
90
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.session_manager import SessionManager`
|
|
91
|
+
|
|
92
|
+
**Classes/Functions/Constants:**
|
|
93
|
+
- **`SessionManager(secret_key: str, app_config: Dict[str, Any])`**: Manages user sessions and A2A identity mapping.
|
|
94
|
+
- `get_a2a_client_id(request: Request) -> str`: Returns the A2A client ID for the current request.
|
|
95
|
+
- `start_new_a2a_session(request: Request) -> str`: Creates a new A2A session ID.
|
|
96
|
+
- `ensure_a2a_session(request: Request) -> str`: Ensures a session ID exists, creating one if necessary.
|
|
97
|
+
- `store_auth_tokens(request: Request, access_token: str, refresh_token: Optional[str])`: Stores authentication tokens.
|
|
98
|
+
- `get_access_token(request: Request) -> Optional[str]`: Retrieves stored access token.
|
|
99
|
+
|
|
100
|
+
#### sse_manager.py
|
|
101
|
+
**Purpose:** Manages Server-Sent Event (SSE) connections for streaming task updates.
|
|
102
|
+
**Import:** `from solace_agent_mesh.gateway.http_sse.sse_manager import SSEManager`
|
|
103
|
+
|
|
104
|
+
**Classes/Functions/Constants:**
|
|
105
|
+
- **`SSEManager(max_queue_size: int = 200)`**: Manages active SSE connections and distributes events.
|
|
106
|
+
- `create_sse_connection(task_id: str) -> asyncio.Queue`: Creates a new SSE connection queue for a task.
|
|
107
|
+
- `send_event(task_id: str, event_data: Dict[str, Any], event_type: str)`: Sends an event to all connections for a task.
|
|
108
|
+
- `close_all_for_task(task_id: str)`: Closes all SSE connections for a specific task.
|
|
109
|
+
- `close_all()`: Closes all active SSE connections.
|
|
110
|
+
|
|
111
|
+
### Subdirectory APIs
|
|
112
|
+
|
|
113
|
+
#### components/
|
|
114
|
+
**Purpose:** Contains specialized SAC components for message forwarding and visualization
|
|
115
|
+
**Key Exports:** `VisualizationForwarderComponent`
|
|
116
|
+
**Import Examples:**
|
|
117
|
+
```python
|
|
118
|
+
from solace_agent_mesh.gateway.http_sse.components import VisualizationForwarderComponent
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### routers/
|
|
122
|
+
**Purpose:** Defines FastAPI APIRouter modules for all REST API endpoints
|
|
123
|
+
**Key Exports:** Router instances for agents, tasks, SSE, artifacts, auth, config, sessions, people, users, visualization
|
|
124
|
+
**Import Examples:**
|
|
125
|
+
```python
|
|
126
|
+
from solace_agent_mesh.gateway.http_sse.routers import agents, tasks, sse, artifacts
|
|
127
|
+
from solace_agent_mesh.gateway.http_sse.routers.tasks import CancelTaskApiPayload
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### services/
|
|
131
|
+
**Purpose:** Encapsulates business logic for domain-specific operations
|
|
132
|
+
**Key Exports:** `AgentService`, `TaskService`, `PeopleService`
|
|
133
|
+
**Import Examples:**
|
|
134
|
+
```python
|
|
135
|
+
from solace_agent_mesh.gateway.http_sse.services.agent_service import AgentService
|
|
136
|
+
from solace_agent_mesh.gateway.http_sse.services.task_service import TaskService
|
|
137
|
+
from solace_agent_mesh.gateway.http_sse.services.people_service import PeopleService
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Complete Usage Guide
|
|
141
|
+
|
|
142
|
+
### 1. Setting Up the Gateway Application
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from solace_agent_mesh.gateway.http_sse.app import WebUIBackendApp
|
|
146
|
+
|
|
147
|
+
# Create the gateway app with configuration
|
|
148
|
+
app_config = {
|
|
149
|
+
"name": "my-webui-gateway",
|
|
150
|
+
"session_secret_key": "your-secret-key-here",
|
|
151
|
+
"fastapi_host": "0.0.0.0",
|
|
152
|
+
"fastapi_port": 8000,
|
|
153
|
+
"namespace": "/my-namespace",
|
|
154
|
+
"gateway_id": "webui-gateway-01",
|
|
155
|
+
"cors_allowed_origins": ["http://localhost:3000"],
|
|
156
|
+
"frontend_welcome_message": "Welcome to my A2A system!",
|
|
157
|
+
"frontend_bot_name": "My Assistant",
|
|
158
|
+
# ... other configuration parameters
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Initialize the app
|
|
162
|
+
webui_app = WebUIBackendApp(app_info=app_config)
|
|
163
|
+
|
|
164
|
+
# Run the app (this starts the FastAPI server)
|
|
165
|
+
webui_app.run()
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 2. Using Dependencies in Custom Routers
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from fastapi import APIRouter, Depends
|
|
172
|
+
from solace_agent_mesh.gateway.http_sse.dependencies import (
|
|
173
|
+
get_agent_registry,
|
|
174
|
+
get_user_id,
|
|
175
|
+
get_publish_a2a_func,
|
|
176
|
+
get_core_a2a_service
|
|
177
|
+
)
|
|
178
|
+
from solace_agent_mesh.common.agent_registry import AgentRegistry
|
|
179
|
+
|
|
180
|
+
router = APIRouter()
|
|
181
|
+
|
|
182
|
+
@router.get("/my-custom-endpoint")
|
|
183
|
+
async def my_custom_endpoint(
|
|
184
|
+
user_id: str = Depends(get_user_id),
|
|
185
|
+
agent_registry: AgentRegistry = Depends(get_agent_registry),
|
|
186
|
+
publish_func = Depends(get_publish_a2a_func)
|
|
187
|
+
):
|
|
188
|
+
# Access discovered agents
|
|
189
|
+
agents = agent_registry.get_all_agents()
|
|
190
|
+
|
|
191
|
+
# Publish a message to the A2A fabric
|
|
192
|
+
publish_func(
|
|
193
|
+
topic=f"/my-namespace/a2a/v1/agent/request/some-agent",
|
|
194
|
+
payload={"method": "custom/request", "params": {"user": user_id}},
|
|
195
|
+
user_properties={"clientId": user_id}
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return {"agents_count": len(agents), "user_id": user_id}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 3. Managing SSE Connections
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from fastapi import APIRouter, Depends
|
|
205
|
+
from fastapi.responses import StreamingResponse
|
|
206
|
+
from solace_agent_mesh.gateway.http_sse.dependencies import get_sse_manager
|
|
207
|
+
from solace_agent_mesh.gateway.http_sse.sse_manager import SSEManager
|
|
208
|
+
import asyncio
|
|
209
|
+
import json
|
|
210
|
+
|
|
211
|
+
router = APIRouter()
|
|
212
|
+
|
|
213
|
+
@router.get("/my-sse-endpoint/{task_id}")
|
|
214
|
+
async def my_sse_endpoint(
|
|
215
|
+
task_id: str,
|
|
216
|
+
sse_manager: SSEManager = Depends(get_sse_manager)
|
|
217
|
+
):
|
|
218
|
+
# Create SSE connection for the task
|
|
219
|
+
connection_queue = await sse_manager.create_sse_connection(task_id)
|
|
220
|
+
|
|
221
|
+
async def event_generator():
|
|
222
|
+
try:
|
|
223
|
+
while True:
|
|
224
|
+
# Wait for events from the queue
|
|
225
|
+
event = await connection_queue.get()
|
|
226
|
+
if event is None: # Close signal
|
|
227
|
+
break
|
|
228
|
+
|
|
229
|
+
# Format as SSE
|
|
230
|
+
yield f"event: {event['event']}\n"
|
|
231
|
+
yield f"data: {event['data']}\n\n"
|
|
232
|
+
|
|
233
|
+
except asyncio.CancelledError:
|
|
234
|
+
pass
|
|
235
|
+
finally:
|
|
236
|
+
# Clean up connection
|
|
237
|
+
await sse_manager.remove_sse_connection(task_id, connection_queue)
|
|
238
|
+
|
|
239
|
+
return StreamingResponse(
|
|
240
|
+
event_generator(),
|
|
241
|
+
media_type="text/event-stream",
|
|
242
|
+
headers={
|
|
243
|
+
"Cache-Control": "no-cache",
|
|
244
|
+
"Connection": "keep-alive",
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# Send events to SSE connections
|
|
249
|
+
async def send_custom_event(sse_manager: SSEManager, task_id: str):
|
|
250
|
+
await sse_manager.send_event(
|
|
251
|
+
task_id=task_id,
|
|
252
|
+
event_data={"message": "Custom event", "timestamp": "2024-01-01T00:00:00Z"},
|
|
253
|
+
event_type="custom_event"
|
|
254
|
+
)
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### 4. Working with Sessions and User Identity
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
from fastapi import APIRouter, Depends, Request
|
|
261
|
+
from solace_agent_mesh.gateway.http_sse.dependencies import (
|
|
262
|
+
get_session_manager,
|
|
263
|
+
get_user_id,
|
|
264
|
+
ensure_session_id
|
|
265
|
+
)
|
|
266
|
+
from solace_agent_mesh.gateway.http_sse.session_manager import SessionManager
|
|
267
|
+
|
|
268
|
+
router = APIRouter()
|
|
269
|
+
|
|
270
|
+
@router.post("/start-conversation")
|
|
271
|
+
async def start_conversation(
|
|
272
|
+
request: Request,
|
|
273
|
+
user_id: str = Depends(get_user_id),
|
|
274
|
+
session_id: str = Depends(ensure_session_id),
|
|
275
|
+
session_manager: SessionManager = Depends(get_session_manager)
|
|
276
|
+
):
|
|
277
|
+
# Start a new A2A session for this conversation
|
|
278
|
+
new_session_id = session_manager.start_new_a2a_session(request)
|
|
279
|
+
|
|
280
|
+
return {
|
|
281
|
+
"user_id": user_id,
|
|
282
|
+
"old_session_id": session_id,
|
|
283
|
+
"new_session_id": new_session_id,
|
|
284
|
+
"message": "New conversation started"
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 5. Using Services for Business Logic
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
from fastapi import APIRouter, Depends
|
|
292
|
+
from solace_agent_mesh.gateway.http_sse.dependencies import (
|
|
293
|
+
get_agent_service,
|
|
294
|
+
get_task_service,
|
|
295
|
+
get_people_service
|
|
296
|
+
)
|
|
297
|
+
from solace_agent_mesh.gateway.http_sse.services.agent_service import AgentService
|
|
298
|
+
|
|
299
|
+
# content_hash: 765fb33c6a30298c67ac7c1525df5787791b2b37e0d69b046e405aec85287feb
|
|
@@ -32,12 +32,11 @@ from ...gateway.http_sse.routers import (
|
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
from ...gateway.http_sse import dependencies
|
|
35
|
-
from
|
|
36
|
-
JSONRPCResponse as A2AJSONRPCResponse,
|
|
35
|
+
from a2a.types import (
|
|
37
36
|
JSONRPCError,
|
|
38
37
|
InternalError,
|
|
39
|
-
InvalidRequestError,
|
|
40
38
|
)
|
|
39
|
+
from ...common import a2a
|
|
41
40
|
|
|
42
41
|
from typing import TYPE_CHECKING
|
|
43
42
|
|
|
@@ -313,7 +312,7 @@ def setup_dependencies(component: "WebUIBackendComponent"):
|
|
|
313
312
|
api_prefix = "/api/v1"
|
|
314
313
|
app.include_router(config.router, prefix=api_prefix, tags=["Config"])
|
|
315
314
|
app.include_router(agents.router, prefix=api_prefix, tags=["Agents"])
|
|
316
|
-
app.include_router(tasks.router, prefix=
|
|
315
|
+
app.include_router(tasks.router, prefix=api_prefix, tags=["Tasks"])
|
|
317
316
|
app.include_router(sse.router, prefix=f"{api_prefix}/sse", tags=["SSE"])
|
|
318
317
|
app.include_router(
|
|
319
318
|
artifacts.router, prefix=f"{api_prefix}/artifacts", tags=["Artifacts"]
|
|
@@ -387,7 +386,7 @@ async def http_exception_handler(request: FastAPIRequest, exc: HTTPException):
|
|
|
387
386
|
error_message = "Resource not found"
|
|
388
387
|
|
|
389
388
|
error_obj = JSONRPCError(code=error_code, message=error_message, data=error_data)
|
|
390
|
-
response =
|
|
389
|
+
response = a2a.create_error_response(error=error_obj, request_id=None)
|
|
391
390
|
return JSONResponse(
|
|
392
391
|
status_code=exc.status_code, content=response.model_dump(exclude_none=True)
|
|
393
392
|
)
|
|
@@ -404,10 +403,9 @@ async def validation_exception_handler(
|
|
|
404
403
|
request.method,
|
|
405
404
|
request.url,
|
|
406
405
|
)
|
|
407
|
-
|
|
408
|
-
message="Invalid request parameters", data=exc.errors()
|
|
406
|
+
response = a2a.create_invalid_request_error_response(
|
|
407
|
+
message="Invalid request parameters", data=exc.errors(), request_id=None
|
|
409
408
|
)
|
|
410
|
-
response = A2AJSONRPCResponse(error=error_obj)
|
|
411
409
|
return JSONResponse(
|
|
412
410
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
413
411
|
content=response.model_dump(exclude_none=True),
|
|
@@ -420,10 +418,10 @@ async def generic_exception_handler(request: FastAPIRequest, exc: Exception):
|
|
|
420
418
|
log.exception(
|
|
421
419
|
"Unhandled Exception: %s, Request: %s %s", exc, request.method, request.url
|
|
422
420
|
)
|
|
423
|
-
error_obj =
|
|
421
|
+
error_obj = a2a.create_internal_error(
|
|
424
422
|
message="An unexpected server error occurred: %s" % type(exc).__name__
|
|
425
423
|
)
|
|
426
|
-
response =
|
|
424
|
+
response = a2a.create_error_response(error=error_obj, request_id=None)
|
|
427
425
|
return JSONResponse(
|
|
428
426
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
429
427
|
content=response.model_dump(exclude_none=True),
|
|
@@ -8,7 +8,7 @@ from typing import List
|
|
|
8
8
|
from solace_ai_connector.common.log import log
|
|
9
9
|
|
|
10
10
|
from ....common.agent_registry import AgentRegistry
|
|
11
|
-
from
|
|
11
|
+
from a2a.types import AgentCard
|
|
12
12
|
from ....gateway.http_sse.dependencies import get_agent_registry
|
|
13
13
|
|
|
14
14
|
router = APIRouter()
|
|
@@ -40,7 +40,7 @@ from ..dependencies import (
|
|
|
40
40
|
from solace_ai_connector.common.log import log
|
|
41
41
|
|
|
42
42
|
from ....common.middleware import ConfigResolver
|
|
43
|
-
from ....common.types import ArtifactInfo
|
|
43
|
+
from ....common.a2a.types import ArtifactInfo
|
|
44
44
|
from ....common.utils.mime_helpers import is_text_based_mime_type
|
|
45
45
|
from ....common.utils.embeds import (
|
|
46
46
|
resolve_embeds_recursively_in_string,
|
|
@@ -56,6 +56,7 @@ from ....agent.utils.artifact_helpers import (
|
|
|
56
56
|
save_artifact_with_metadata,
|
|
57
57
|
load_artifact_content_or_metadata,
|
|
58
58
|
DEFAULT_SCHEMA_MAX_KEYS,
|
|
59
|
+
format_artifact_uri,
|
|
59
60
|
)
|
|
60
61
|
|
|
61
62
|
router = APIRouter()
|
|
@@ -668,7 +669,6 @@ async def upload_artifact(
|
|
|
668
669
|
log_prefix,
|
|
669
670
|
upload_file.filename,
|
|
670
671
|
upload_file.content_type,
|
|
671
|
-
f"Metadata provided: {bool(metadata_json)}",
|
|
672
672
|
)
|
|
673
673
|
|
|
674
674
|
if artifact_service is None:
|
|
@@ -724,7 +724,7 @@ async def upload_artifact(
|
|
|
724
724
|
),
|
|
725
725
|
)
|
|
726
726
|
|
|
727
|
-
if save_result["status"]
|
|
727
|
+
if save_result["status"] == "success":
|
|
728
728
|
log.info(
|
|
729
729
|
"%s Artifact and metadata processing completed. Data version: %s, Metadata version: %s. Message: %s",
|
|
730
730
|
log_prefix,
|
|
@@ -732,14 +732,28 @@ async def upload_artifact(
|
|
|
732
732
|
save_result.get("metadata_version"),
|
|
733
733
|
save_result.get("message"),
|
|
734
734
|
)
|
|
735
|
+
saved_version = save_result.get("data_version")
|
|
736
|
+
artifact_uri = format_artifact_uri(
|
|
737
|
+
app_name=app_name,
|
|
738
|
+
user_id=user_id,
|
|
739
|
+
session_id=session_id,
|
|
740
|
+
filename=filename,
|
|
741
|
+
version=saved_version,
|
|
742
|
+
)
|
|
743
|
+
log.info(
|
|
744
|
+
"%s Successfully saved artifact. Returning URI: %s",
|
|
745
|
+
log_prefix,
|
|
746
|
+
artifact_uri,
|
|
747
|
+
)
|
|
735
748
|
return {
|
|
736
749
|
"filename": filename,
|
|
737
|
-
"data_version":
|
|
750
|
+
"data_version": saved_version,
|
|
738
751
|
"metadata_version": save_result.get("metadata_version"),
|
|
739
752
|
"mime_type": mime_type,
|
|
740
753
|
"size": len(content_bytes),
|
|
741
754
|
"message": save_result.get("message"),
|
|
742
755
|
"status": save_result["status"],
|
|
756
|
+
"uri": artifact_uri,
|
|
743
757
|
}
|
|
744
758
|
else:
|
|
745
759
|
log.error(
|