solace-agent-mesh 1.6.1__py3-none-any.whl → 1.6.3__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/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +1 -1
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +135 -31
- solace_agent_mesh/agent/adk/models/lite_llm.py +5 -0
- solace_agent_mesh/agent/adk/runner.py +10 -12
- solace_agent_mesh/agent/adk/services.py +53 -17
- solace_agent_mesh/agent/adk/setup.py +66 -38
- solace_agent_mesh/agent/protocol/event_handlers.py +243 -122
- solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
- solace_agent_mesh/agent/proxies/base/app.py +3 -2
- solace_agent_mesh/agent/sac/app.py +43 -2
- solace_agent_mesh/agent/sac/component.py +200 -72
- solace_agent_mesh/agent/sac/task_execution_context.py +35 -4
- solace_agent_mesh/agent/tools/tool_config_types.py +3 -0
- solace_agent_mesh/agent/utils/artifact_helpers.py +1 -1
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.3b883666.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.ed05b14d.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.a8a75e0b.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +4 -25
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +76 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +5 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +23 -28
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/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/try-agent-mesh/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +3 -6
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1761744323675.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1761744323675.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/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-D4_RMYRh.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-CaY59VuC.js → client-UZ3qU6Bq.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +342 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BEmvJSYz.js → vendor-DSqhjwq_.js} +1 -1
- 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/events.py +2 -1
- solace_agent_mesh/common/sac/sam_component_base.py +24 -18
- solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
- solace_agent_mesh/gateway/base/component.py +12 -8
- solace_agent_mesh/gateway/http_sse/app.py +26 -0
- solace_agent_mesh/gateway/http_sse/component.py +158 -79
- solace_agent_mesh/gateway/http_sse/dependencies.py +83 -59
- solace_agent_mesh/gateway/http_sse/main.py +35 -11
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/auth.py +103 -6
- solace_agent_mesh/gateway/http_sse/routers/config.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/sse.py +15 -5
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +90 -8
- solace_agent_mesh/gateway/http_sse/services/session_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +16 -1
- solace_agent_mesh/gateway/http_sse/sse_manager.py +15 -6
- solace_agent_mesh/templates/logging_config_template.ini +2 -2
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/METADATA +2 -2
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/RECORD +112 -110
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.b12eac43.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761248203150.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +0 -1
- /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.ed05b14d.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.6.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,7 +5,6 @@ managed by the WebUIBackendComponent.
|
|
|
5
5
|
|
|
6
6
|
import logging
|
|
7
7
|
from collections.abc import Callable, Generator
|
|
8
|
-
from contextlib import contextmanager
|
|
9
8
|
from typing import TYPE_CHECKING, Any
|
|
10
9
|
|
|
11
10
|
from fastapi import Depends, HTTPException, Request, status
|
|
@@ -18,11 +17,11 @@ from ...common.services.identity_service import BaseIdentityService
|
|
|
18
17
|
from ...core_a2a.service import CoreA2AService
|
|
19
18
|
from ...gateway.base.task_context import TaskContextManager
|
|
20
19
|
from ...gateway.http_sse.services.agent_card_service import AgentCardService
|
|
21
|
-
from ...gateway.http_sse.services.
|
|
22
|
-
from ...gateway.http_sse.services.task_service import TaskService
|
|
20
|
+
from ...gateway.http_sse.services.data_retention_service import DataRetentionService
|
|
23
21
|
from ...gateway.http_sse.services.feedback_service import FeedbackService
|
|
22
|
+
from ...gateway.http_sse.services.people_service import PeopleService
|
|
24
23
|
from ...gateway.http_sse.services.task_logger_service import TaskLoggerService
|
|
25
|
-
from ...gateway.http_sse.services.
|
|
24
|
+
from ...gateway.http_sse.services.task_service import TaskService
|
|
26
25
|
from ...gateway.http_sse.session_manager import SessionManager
|
|
27
26
|
from ...gateway.http_sse.sse_manager import SSEManager
|
|
28
27
|
from .repository import SessionRepository
|
|
@@ -54,32 +53,57 @@ def set_component_instance(component: "WebUIBackendComponent"):
|
|
|
54
53
|
global sac_component_instance
|
|
55
54
|
if sac_component_instance is None:
|
|
56
55
|
sac_component_instance = component
|
|
57
|
-
log.info("
|
|
56
|
+
log.info("SAC Component instance provided.")
|
|
58
57
|
else:
|
|
59
|
-
log.warning("
|
|
58
|
+
log.warning("SAC Component instance already set.")
|
|
60
59
|
|
|
61
60
|
|
|
62
61
|
def init_database(database_url: str):
|
|
63
|
-
"""Initialize database with
|
|
62
|
+
"""Initialize database with appropriate configuration based on database dialect."""
|
|
64
63
|
global SessionLocal
|
|
65
64
|
if SessionLocal is None:
|
|
66
|
-
|
|
65
|
+
from sqlalchemy import event, pool
|
|
66
|
+
from sqlalchemy.engine.url import make_url
|
|
67
|
+
|
|
68
|
+
url = make_url(database_url)
|
|
69
|
+
dialect_name = url.get_dialect().name
|
|
70
|
+
|
|
71
|
+
engine_kwargs = {}
|
|
72
|
+
|
|
73
|
+
if dialect_name == "sqlite":
|
|
74
|
+
engine_kwargs = {
|
|
75
|
+
"poolclass": pool.StaticPool,
|
|
76
|
+
"connect_args": {"check_same_thread": False}
|
|
77
|
+
}
|
|
78
|
+
log.info("Configuring SQLite database (single-connection mode)")
|
|
79
|
+
|
|
80
|
+
elif dialect_name in ("postgresql", "mysql"):
|
|
81
|
+
engine_kwargs = {
|
|
82
|
+
"pool_size": 10,
|
|
83
|
+
"max_overflow": 20,
|
|
84
|
+
"pool_timeout": 30,
|
|
85
|
+
"pool_recycle": 1800,
|
|
86
|
+
"pool_pre_ping": True,
|
|
87
|
+
}
|
|
88
|
+
log.info(f"Configuring {dialect_name} database with connection pooling")
|
|
89
|
+
|
|
90
|
+
else:
|
|
91
|
+
log.warning(f"Using default configuration for dialect: {dialect_name}")
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
from sqlalchemy import event
|
|
93
|
+
engine = create_engine(database_url, **engine_kwargs)
|
|
70
94
|
|
|
71
95
|
@event.listens_for(engine, "connect")
|
|
72
96
|
def set_sqlite_pragma(dbapi_conn, connection_record):
|
|
73
|
-
|
|
74
|
-
if database_url.startswith("sqlite"):
|
|
97
|
+
if dialect_name == "sqlite":
|
|
75
98
|
cursor = dbapi_conn.cursor()
|
|
76
99
|
cursor.execute("PRAGMA foreign_keys=ON")
|
|
77
100
|
cursor.close()
|
|
78
101
|
|
|
79
102
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
80
|
-
log.
|
|
103
|
+
log.debug(f"Database initialized: {url}")
|
|
104
|
+
log.info("Database initialized successfully")
|
|
81
105
|
else:
|
|
82
|
-
log.warning("
|
|
106
|
+
log.warning("Database already initialized.")
|
|
83
107
|
|
|
84
108
|
|
|
85
109
|
def set_api_config(config: dict[str, Any]):
|
|
@@ -87,16 +111,16 @@ def set_api_config(config: dict[str, Any]):
|
|
|
87
111
|
global api_config
|
|
88
112
|
if api_config is None:
|
|
89
113
|
api_config = config
|
|
90
|
-
log.
|
|
114
|
+
log.debug("API configuration provided.")
|
|
91
115
|
else:
|
|
92
|
-
log.warning("
|
|
116
|
+
log.warning("API configuration already set.")
|
|
93
117
|
|
|
94
118
|
|
|
95
119
|
def get_sac_component() -> "WebUIBackendComponent":
|
|
96
120
|
"""FastAPI dependency to get the SAC component instance."""
|
|
97
121
|
if sac_component_instance is None:
|
|
98
122
|
log.critical(
|
|
99
|
-
"
|
|
123
|
+
"SAC Component instance accessed before it was set!"
|
|
100
124
|
)
|
|
101
125
|
raise HTTPException(
|
|
102
126
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
@@ -108,7 +132,7 @@ def get_sac_component() -> "WebUIBackendComponent":
|
|
|
108
132
|
def get_api_config() -> dict[str, Any]:
|
|
109
133
|
"""FastAPI dependency to get the API configuration."""
|
|
110
134
|
if api_config is None:
|
|
111
|
-
log.critical("
|
|
135
|
+
log.critical("API configuration accessed before it was set!")
|
|
112
136
|
raise HTTPException(
|
|
113
137
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
114
138
|
detail="API configuration not yet initialized.",
|
|
@@ -120,7 +144,7 @@ def get_agent_registry(
|
|
|
120
144
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
121
145
|
) -> AgentRegistry:
|
|
122
146
|
"""FastAPI dependency to get the AgentRegistry."""
|
|
123
|
-
log.debug("
|
|
147
|
+
log.debug("get_agent_registry called")
|
|
124
148
|
return component.get_agent_registry()
|
|
125
149
|
|
|
126
150
|
|
|
@@ -128,7 +152,7 @@ def get_sse_manager(
|
|
|
128
152
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
129
153
|
) -> SSEManager:
|
|
130
154
|
"""FastAPI dependency to get the SSEManager."""
|
|
131
|
-
log.debug("
|
|
155
|
+
log.debug("get_sse_manager called")
|
|
132
156
|
return component.get_sse_manager()
|
|
133
157
|
|
|
134
158
|
|
|
@@ -136,7 +160,7 @@ def get_session_manager(
|
|
|
136
160
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
137
161
|
) -> SessionManager:
|
|
138
162
|
"""FastAPI dependency to get the SessionManager."""
|
|
139
|
-
log.debug("
|
|
163
|
+
log.debug("get_session_manager called")
|
|
140
164
|
return component.get_session_manager()
|
|
141
165
|
|
|
142
166
|
|
|
@@ -144,7 +168,7 @@ def get_user_id_callable(
|
|
|
144
168
|
session_manager: SessionManager = Depends(get_session_manager),
|
|
145
169
|
) -> Callable:
|
|
146
170
|
"""Dependency that provides the callable for getting user_id (client_id)."""
|
|
147
|
-
log.debug("
|
|
171
|
+
log.debug("Providing user_id callable")
|
|
148
172
|
return session_manager.dep_get_client_id()
|
|
149
173
|
|
|
150
174
|
|
|
@@ -152,7 +176,7 @@ def ensure_session_id_callable(
|
|
|
152
176
|
session_manager: SessionManager = Depends(get_session_manager),
|
|
153
177
|
) -> Callable:
|
|
154
178
|
"""Dependency that provides the callable for ensuring session_id."""
|
|
155
|
-
log.debug("
|
|
179
|
+
log.debug("Providing ensure_session_id callable")
|
|
156
180
|
return session_manager.dep_ensure_session_id()
|
|
157
181
|
|
|
158
182
|
|
|
@@ -165,17 +189,17 @@ def get_user_id(
|
|
|
165
189
|
When FRONTEND_USE_AUTHORIZATION is true: Fully relies on OAuth - user must be authenticated by AuthMiddleware.
|
|
166
190
|
When FRONTEND_USE_AUTHORIZATION is false: Uses development fallback user.
|
|
167
191
|
"""
|
|
168
|
-
log.debug("
|
|
192
|
+
log.debug("Resolving user_id string")
|
|
169
193
|
|
|
170
194
|
# AuthMiddleware should always set user state for both auth enabled/disabled cases
|
|
171
195
|
if hasattr(request.state, "user") and request.state.user:
|
|
172
196
|
user_id = request.state.user.get("id")
|
|
173
197
|
if user_id:
|
|
174
|
-
log.debug(f"
|
|
198
|
+
log.debug(f"Using user ID from AuthMiddleware: {user_id}")
|
|
175
199
|
return user_id
|
|
176
200
|
else:
|
|
177
201
|
log.error(
|
|
178
|
-
"
|
|
202
|
+
"request.state.user exists but has no 'id' field: %s. This indicates a bug in AuthMiddleware.",
|
|
179
203
|
request.state.user,
|
|
180
204
|
)
|
|
181
205
|
|
|
@@ -185,7 +209,7 @@ def get_user_id(
|
|
|
185
209
|
if use_authorization:
|
|
186
210
|
# When OAuth is enabled, we should never reach here - AuthMiddleware should have handled authentication
|
|
187
211
|
log.error(
|
|
188
|
-
"
|
|
212
|
+
"OAuth is enabled but no authenticated user found. This indicates an authentication failure or middleware bug."
|
|
189
213
|
)
|
|
190
214
|
raise HTTPException(
|
|
191
215
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
@@ -195,7 +219,7 @@ def get_user_id(
|
|
|
195
219
|
# When auth is disabled, use development fallback user
|
|
196
220
|
fallback_id = "sam_dev_user"
|
|
197
221
|
log.info(
|
|
198
|
-
"
|
|
222
|
+
"Authorization disabled and no user in request state, using fallback user: %s",
|
|
199
223
|
fallback_id,
|
|
200
224
|
)
|
|
201
225
|
return fallback_id
|
|
@@ -206,7 +230,7 @@ def ensure_session_id(
|
|
|
206
230
|
session_manager: SessionManager = Depends(get_session_manager),
|
|
207
231
|
) -> str:
|
|
208
232
|
"""FastAPI dependency that directly returns the ensured session_id string."""
|
|
209
|
-
log.debug("
|
|
233
|
+
log.debug("Resolving ensured session_id string")
|
|
210
234
|
return session_manager.ensure_a2a_session(request)
|
|
211
235
|
|
|
212
236
|
|
|
@@ -214,7 +238,7 @@ def get_identity_service(
|
|
|
214
238
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
215
239
|
) -> BaseIdentityService | None:
|
|
216
240
|
"""FastAPI dependency to get the configured IdentityService instance."""
|
|
217
|
-
log.debug("
|
|
241
|
+
log.debug("get_identity_service called")
|
|
218
242
|
return component.identity_service
|
|
219
243
|
|
|
220
244
|
|
|
@@ -239,13 +263,13 @@ def get_people_service(
|
|
|
239
263
|
identity_service: BaseIdentityService | None = Depends(get_identity_service),
|
|
240
264
|
) -> PeopleService:
|
|
241
265
|
"""FastAPI dependency to get an instance of PeopleService."""
|
|
242
|
-
log.debug("
|
|
266
|
+
log.debug("get_people_service called")
|
|
243
267
|
return PeopleService(identity_service=identity_service)
|
|
244
268
|
|
|
245
269
|
|
|
246
270
|
def get_task_repository() -> ITaskRepository:
|
|
247
271
|
"""FastAPI dependency to get an instance of TaskRepository."""
|
|
248
|
-
log.debug("
|
|
272
|
+
log.debug("get_task_repository called")
|
|
249
273
|
return TaskRepository()
|
|
250
274
|
|
|
251
275
|
|
|
@@ -254,7 +278,7 @@ def get_feedback_service(
|
|
|
254
278
|
task_repo: ITaskRepository = Depends(get_task_repository),
|
|
255
279
|
) -> FeedbackService:
|
|
256
280
|
"""FastAPI dependency to get an instance of FeedbackService."""
|
|
257
|
-
log.debug("
|
|
281
|
+
log.debug("get_feedback_service called")
|
|
258
282
|
# The session factory is needed for the existing DB save logic.
|
|
259
283
|
session_factory = SessionLocal if component.database_url else None
|
|
260
284
|
return FeedbackService(
|
|
@@ -277,11 +301,11 @@ def get_data_retention_service(
|
|
|
277
301
|
data retention statistics or manual cleanup triggers. The service itself
|
|
278
302
|
runs automatically via timer in the component.
|
|
279
303
|
"""
|
|
280
|
-
log.debug("
|
|
304
|
+
log.debug("get_data_retention_service called")
|
|
281
305
|
|
|
282
306
|
if not component.database_url:
|
|
283
307
|
log.debug(
|
|
284
|
-
"
|
|
308
|
+
"Database not configured, returning None for data retention service"
|
|
285
309
|
)
|
|
286
310
|
return None
|
|
287
311
|
|
|
@@ -289,7 +313,7 @@ def get_data_retention_service(
|
|
|
289
313
|
not hasattr(component, "data_retention_service")
|
|
290
314
|
or component.data_retention_service is None
|
|
291
315
|
):
|
|
292
|
-
log.warning("
|
|
316
|
+
log.warning("DataRetentionService not initialized on component")
|
|
293
317
|
return None
|
|
294
318
|
|
|
295
319
|
return component.data_retention_service
|
|
@@ -299,10 +323,10 @@ def get_task_logger_service(
|
|
|
299
323
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
300
324
|
) -> TaskLoggerService:
|
|
301
325
|
"""FastAPI dependency to get an instance of TaskLoggerService."""
|
|
302
|
-
log.debug("
|
|
326
|
+
log.debug("get_task_logger_service called")
|
|
303
327
|
task_logger_service = component.get_task_logger_service()
|
|
304
328
|
if task_logger_service is None:
|
|
305
|
-
log.error("
|
|
329
|
+
log.error("TaskLoggerService is not available.")
|
|
306
330
|
raise HTTPException(
|
|
307
331
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
308
332
|
detail="Task logging service is not configured or available.",
|
|
@@ -317,7 +341,7 @@ def get_publish_a2a_func(
|
|
|
317
341
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
318
342
|
) -> PublishFunc:
|
|
319
343
|
"""FastAPI dependency to get the component's publish_a2a method."""
|
|
320
|
-
log.debug("
|
|
344
|
+
log.debug("get_publish_a2a_func called")
|
|
321
345
|
return component.publish_a2a
|
|
322
346
|
|
|
323
347
|
|
|
@@ -325,7 +349,7 @@ def get_namespace(
|
|
|
325
349
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
326
350
|
) -> str:
|
|
327
351
|
"""FastAPI dependency to get the namespace."""
|
|
328
|
-
log.debug("
|
|
352
|
+
log.debug("get_namespace called")
|
|
329
353
|
return component.get_namespace()
|
|
330
354
|
|
|
331
355
|
|
|
@@ -333,7 +357,7 @@ def get_gateway_id(
|
|
|
333
357
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
334
358
|
) -> str:
|
|
335
359
|
"""FastAPI dependency to get the Gateway ID."""
|
|
336
|
-
log.debug("
|
|
360
|
+
log.debug("get_gateway_id called")
|
|
337
361
|
return component.get_gateway_id()
|
|
338
362
|
|
|
339
363
|
|
|
@@ -341,7 +365,7 @@ def get_config_resolver(
|
|
|
341
365
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
342
366
|
) -> ConfigResolver:
|
|
343
367
|
"""FastAPI dependency to get the ConfigResolver."""
|
|
344
|
-
log.debug("
|
|
368
|
+
log.debug("get_config_resolver called")
|
|
345
369
|
return component.get_config_resolver()
|
|
346
370
|
|
|
347
371
|
|
|
@@ -351,7 +375,7 @@ def get_app_config(
|
|
|
351
375
|
"""
|
|
352
376
|
FastAPI dependency to safely get the application configuration dictionary.
|
|
353
377
|
"""
|
|
354
|
-
log.debug("
|
|
378
|
+
log.debug("get_app_config called")
|
|
355
379
|
return component.component_config.get("app_config", {})
|
|
356
380
|
|
|
357
381
|
|
|
@@ -365,7 +389,7 @@ async def get_user_config(
|
|
|
365
389
|
"""
|
|
366
390
|
FastAPI dependency to get the user-specific configuration.
|
|
367
391
|
"""
|
|
368
|
-
log.debug(f"
|
|
392
|
+
log.debug(f"get_user_config called for user_id: {user_id}")
|
|
369
393
|
gateway_context = {
|
|
370
394
|
"gateway_id": component.gateway_id,
|
|
371
395
|
"gateway_app_config": app_config,
|
|
@@ -408,7 +432,7 @@ class ValidatedUserConfig:
|
|
|
408
432
|
user_id = user_config.get("user_profile", {}).get("id")
|
|
409
433
|
|
|
410
434
|
log.debug(
|
|
411
|
-
f"
|
|
435
|
+
f"ValidatedUserConfig called for user_id: {user_id} with required scopes: {self.required_scopes}"
|
|
412
436
|
)
|
|
413
437
|
|
|
414
438
|
# Validate scopes
|
|
@@ -418,7 +442,7 @@ class ValidatedUserConfig:
|
|
|
418
442
|
{},
|
|
419
443
|
):
|
|
420
444
|
log.warning(
|
|
421
|
-
f"
|
|
445
|
+
f"Authorization denied for user '{user_id}'. Required scopes: {self.required_scopes}"
|
|
422
446
|
)
|
|
423
447
|
raise HTTPException(
|
|
424
448
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
@@ -432,7 +456,7 @@ def get_shared_artifact_service(
|
|
|
432
456
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
433
457
|
) -> BaseArtifactService | None:
|
|
434
458
|
"""FastAPI dependency to get the shared ArtifactService."""
|
|
435
|
-
log.debug("
|
|
459
|
+
log.debug("get_shared_artifact_service called")
|
|
436
460
|
return component.get_shared_artifact_service()
|
|
437
461
|
|
|
438
462
|
|
|
@@ -440,7 +464,7 @@ def get_embed_config(
|
|
|
440
464
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
441
465
|
) -> dict[str, Any]:
|
|
442
466
|
"""FastAPI dependency to get embed-related configuration."""
|
|
443
|
-
log.debug("
|
|
467
|
+
log.debug("get_embed_config called")
|
|
444
468
|
return component.get_embed_config()
|
|
445
469
|
|
|
446
470
|
|
|
@@ -448,10 +472,10 @@ def get_core_a2a_service(
|
|
|
448
472
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
449
473
|
) -> CoreA2AService:
|
|
450
474
|
"""FastAPI dependency to get the CoreA2AService."""
|
|
451
|
-
log.debug("
|
|
475
|
+
log.debug("get_core_a2a_service called")
|
|
452
476
|
core_service = component.get_core_a2a_service()
|
|
453
477
|
if core_service is None:
|
|
454
|
-
log.critical("
|
|
478
|
+
log.critical("CoreA2AService accessed before initialization!")
|
|
455
479
|
raise HTTPException(status_code=503, detail="Core service not ready.")
|
|
456
480
|
return core_service
|
|
457
481
|
|
|
@@ -460,10 +484,10 @@ def get_task_context_manager_from_component(
|
|
|
460
484
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
461
485
|
) -> TaskContextManager:
|
|
462
486
|
"""FastAPI dependency to get the TaskContextManager from the component."""
|
|
463
|
-
log.debug("
|
|
487
|
+
log.debug("get_task_context_manager_from_component called")
|
|
464
488
|
if component.task_context_manager is None:
|
|
465
489
|
log.critical(
|
|
466
|
-
"
|
|
490
|
+
"TaskContextManager accessed before initialization!"
|
|
467
491
|
)
|
|
468
492
|
raise HTTPException(status_code=503, detail="Task context manager not ready.")
|
|
469
493
|
return component.task_context_manager
|
|
@@ -473,7 +497,7 @@ def get_agent_card_service(
|
|
|
473
497
|
registry: AgentRegistry = Depends(get_agent_registry),
|
|
474
498
|
) -> AgentCardService:
|
|
475
499
|
"""FastAPI dependency to get an instance of AgentCardService."""
|
|
476
|
-
log.debug("
|
|
500
|
+
log.debug("get_agent_card_service called")
|
|
477
501
|
return AgentCardService(agent_registry=registry)
|
|
478
502
|
|
|
479
503
|
|
|
@@ -489,7 +513,7 @@ def get_task_service(
|
|
|
489
513
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
490
514
|
) -> TaskService:
|
|
491
515
|
"""FastAPI dependency to get an instance of TaskService."""
|
|
492
|
-
log.debug("
|
|
516
|
+
log.debug("get_task_service called")
|
|
493
517
|
app_name = component.get_config("name", "WebUIBackendApp")
|
|
494
518
|
return TaskService(
|
|
495
519
|
core_a2a_service=core_a2a_service,
|
|
@@ -506,7 +530,7 @@ def get_task_service(
|
|
|
506
530
|
def get_session_business_service(
|
|
507
531
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
508
532
|
) -> SessionService:
|
|
509
|
-
log.debug("
|
|
533
|
+
log.debug("get_session_business_service called")
|
|
510
534
|
|
|
511
535
|
# Note: Session and message repositories will be created per request
|
|
512
536
|
# when the SessionService methods receive the db parameter
|
|
@@ -516,7 +540,7 @@ def get_session_business_service(
|
|
|
516
540
|
def get_session_validator(
|
|
517
541
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
518
542
|
) -> Callable[[str, str], bool]:
|
|
519
|
-
log.debug("
|
|
543
|
+
log.debug("get_session_validator called")
|
|
520
544
|
|
|
521
545
|
if SessionLocal:
|
|
522
546
|
log.debug("Using database-backed session validation")
|
|
@@ -532,7 +556,7 @@ def get_session_validator(
|
|
|
532
556
|
return session_domain is not None
|
|
533
557
|
finally:
|
|
534
558
|
db.close()
|
|
535
|
-
except:
|
|
559
|
+
except Exception:
|
|
536
560
|
return False
|
|
537
561
|
|
|
538
562
|
return validate_with_database
|
|
@@ -550,7 +574,7 @@ def get_session_validator(
|
|
|
550
574
|
def get_db_optional() -> Generator[Session | None, None, None]:
|
|
551
575
|
"""Optional database dependency that returns None if database is not configured."""
|
|
552
576
|
if SessionLocal is None:
|
|
553
|
-
log.debug("
|
|
577
|
+
log.debug("Database not configured, returning None")
|
|
554
578
|
yield None
|
|
555
579
|
else:
|
|
556
580
|
db = SessionLocal()
|
|
@@ -570,7 +594,7 @@ def get_session_business_service_optional(
|
|
|
570
594
|
"""Optional session service dependency that returns None if database is not configured."""
|
|
571
595
|
if SessionLocal is None:
|
|
572
596
|
log.debug(
|
|
573
|
-
"
|
|
597
|
+
"Database not configured, returning None for session service"
|
|
574
598
|
)
|
|
575
599
|
return None
|
|
576
600
|
return SessionService(component=component)
|
|
@@ -209,6 +209,7 @@ def _create_auth_middleware(component):
|
|
|
209
209
|
skip_paths = [
|
|
210
210
|
"/api/v1/config",
|
|
211
211
|
"/api/v1/auth/callback",
|
|
212
|
+
"/api/v1/auth/tool/callback",
|
|
212
213
|
"/api/v1/auth/login",
|
|
213
214
|
"/api/v1/auth/refresh",
|
|
214
215
|
"/api/v1/csrf-token",
|
|
@@ -452,17 +453,32 @@ def _run_enterprise_migrations(
|
|
|
452
453
|
raise RuntimeError(f"Enterprise database migration failed: {e}") from e
|
|
453
454
|
|
|
454
455
|
|
|
455
|
-
def _setup_database(
|
|
456
|
+
def _setup_database(
|
|
457
|
+
component: "WebUIBackendComponent",
|
|
458
|
+
database_url: str,
|
|
459
|
+
platform_database_url: str = None
|
|
460
|
+
) -> None:
|
|
456
461
|
"""
|
|
457
|
-
Initialize database
|
|
458
|
-
|
|
462
|
+
Initialize database connections and run all required migrations.
|
|
463
|
+
Sets up both runtime and platform database schemas.
|
|
464
|
+
|
|
465
|
+
Args:
|
|
466
|
+
component: WebUIBackendComponent instance
|
|
467
|
+
database_url: Runtime database URL (sessions, tasks, chat) - REQUIRED
|
|
468
|
+
platform_database_url: Platform database URL (agents, connectors, deployments).
|
|
469
|
+
If None, platform features will be unavailable.
|
|
459
470
|
"""
|
|
460
471
|
dependencies.init_database(database_url)
|
|
461
472
|
log.info("Persistence enabled - sessions will be stored in database")
|
|
462
473
|
log.info("Running database migrations...")
|
|
463
474
|
|
|
464
475
|
_run_community_migrations(database_url)
|
|
465
|
-
|
|
476
|
+
|
|
477
|
+
if platform_database_url:
|
|
478
|
+
log.info("Platform database configured - running migrations")
|
|
479
|
+
_run_enterprise_migrations(component, platform_database_url)
|
|
480
|
+
else:
|
|
481
|
+
log.info("No platform database configured - skipping platform migrations")
|
|
466
482
|
|
|
467
483
|
|
|
468
484
|
def _get_app_config(component: "WebUIBackendComponent") -> dict:
|
|
@@ -497,12 +513,20 @@ def _create_api_config(app_config: dict, database_url: str) -> dict:
|
|
|
497
513
|
}
|
|
498
514
|
|
|
499
515
|
|
|
500
|
-
def setup_dependencies(
|
|
516
|
+
def setup_dependencies(
|
|
517
|
+
component: "WebUIBackendComponent",
|
|
518
|
+
database_url: str = None,
|
|
519
|
+
platform_database_url: str = None
|
|
520
|
+
):
|
|
501
521
|
"""
|
|
502
|
-
|
|
503
|
-
backward compatibility with existing API contracts.
|
|
522
|
+
Initialize dependencies for both runtime and platform databases.
|
|
504
523
|
|
|
505
|
-
|
|
524
|
+
Args:
|
|
525
|
+
component: WebUIBackendComponent instance
|
|
526
|
+
database_url: Runtime database URL (sessions, tasks, chat).
|
|
527
|
+
If None, runs in compatibility mode with in-memory sessions.
|
|
528
|
+
platform_database_url: Platform database URL (agents, connectors, deployments).
|
|
529
|
+
If None, platform features will be unavailable (returns 501).
|
|
506
530
|
|
|
507
531
|
This function is idempotent and safe to call multiple times.
|
|
508
532
|
"""
|
|
@@ -515,7 +539,7 @@ def setup_dependencies(component: "WebUIBackendComponent", database_url: str = N
|
|
|
515
539
|
dependencies.set_component_instance(component)
|
|
516
540
|
|
|
517
541
|
if database_url:
|
|
518
|
-
_setup_database(component, database_url)
|
|
542
|
+
_setup_database(component, database_url, platform_database_url)
|
|
519
543
|
else:
|
|
520
544
|
log.warning(
|
|
521
545
|
"No database URL provided - using in-memory session storage (data not persisted across restarts)"
|
|
@@ -526,14 +550,14 @@ def setup_dependencies(component: "WebUIBackendComponent", database_url: str = N
|
|
|
526
550
|
api_config_dict = _create_api_config(app_config, database_url)
|
|
527
551
|
|
|
528
552
|
dependencies.set_api_config(api_config_dict)
|
|
529
|
-
log.
|
|
553
|
+
log.debug("API configuration extracted and stored.")
|
|
530
554
|
|
|
531
555
|
_setup_middleware(component)
|
|
532
556
|
_setup_routers()
|
|
533
557
|
_setup_static_files()
|
|
534
558
|
|
|
535
559
|
_dependencies_initialized = True
|
|
536
|
-
log.
|
|
560
|
+
log.debug("[setup_dependencies] Dependencies initialization complete")
|
|
537
561
|
|
|
538
562
|
|
|
539
563
|
def _setup_middleware(component: "WebUIBackendComponent") -> None:
|
|
@@ -33,7 +33,7 @@ async def get_discovered_agent_cards(
|
|
|
33
33
|
if agent_registry.get_agent(name)
|
|
34
34
|
]
|
|
35
35
|
|
|
36
|
-
log.
|
|
36
|
+
log.debug("%sReturning %d discovered agent cards.", log_prefix, len(agents))
|
|
37
37
|
return agents
|
|
38
38
|
except Exception as e:
|
|
39
39
|
log.exception("%sError retrieving discovered agent cards: %s", log_prefix, e)
|