solace-agent-mesh 1.6.3__py3-none-any.whl → 1.7.1__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 +12 -18
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +138 -20
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +2 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +38 -5
- solace_agent_mesh/agent/adk/models/models_llm.txt +82 -35
- solace_agent_mesh/agent/adk/runner.py +9 -0
- solace_agent_mesh/agent/adk/stream_parser.py +6 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/agent_llm.txt +61 -70
- solace_agent_mesh/agent/protocol/event_handlers.py +29 -1
- solace_agent_mesh/agent/protocol/protocol_llm.txt +1 -1
- solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
- solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
- solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
- solace_agent_mesh/agent/sac/app.py +22 -0
- solace_agent_mesh/agent/sac/component.py +76 -40
- solace_agent_mesh/agent/sac/sac_llm.txt +1 -1
- solace_agent_mesh/agent/sac/task_execution_context.py +21 -0
- solace_agent_mesh/agent/testing/testing_llm.txt +2 -1
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +13 -148
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +93 -80
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +3 -2
- solace_agent_mesh/agent/utils/artifact_helpers.py +4 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +16 -2
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.e4870a49.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.09ed9234.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{ab9708a8.3e6dd091.js → ab9708a8.245ae0ef.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{e6f9706b.e74a984d.js → e6f9706b.045d0fa1.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +18 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +196 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +6 -7
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +160 -169
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +59 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +10 -6
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +27 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +5 -4
- 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/artifact-storage/index.html +290 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +9 -9
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
- 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-1762283454666.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.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/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-D4_RMYRh.js → authCallback-tcIFZLis.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-UZ3qU6Bq.js → client-CRYdKo2Q.js} +3 -3
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +353 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CINwxvwV.js +470 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/a2a_llm.txt +13 -20
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +1 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +49 -11
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +23 -6
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +26 -9
- solace_agent_mesh/common/common_llm.txt +13 -34
- solace_agent_mesh/common/data_parts.py +20 -4
- solace_agent_mesh/common/middleware/middleware_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +1 -1
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/services/providers/providers_llm.txt +3 -2
- solace_agent_mesh/common/services/services_llm.txt +9 -4
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/embeds/modifiers.py +2 -1
- solace_agent_mesh/common/utils/embeds/resolver.py +58 -6
- solace_agent_mesh/common/utils/embeds/types.py +8 -0
- solace_agent_mesh/common/utils/utils_llm.txt +5 -6
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +1 -1
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +143 -0
- solace_agent_mesh/gateway/adapter/types.py +221 -0
- solace_agent_mesh/gateway/base/app.py +29 -2
- solace_agent_mesh/gateway/base/base_llm.txt +10 -8
- solace_agent_mesh/gateway/base/component.py +573 -142
- solace_agent_mesh/gateway/gateway_llm.txt +55 -59
- solace_agent_mesh/gateway/generic/__init__.py +1 -0
- solace_agent_mesh/gateway/generic/app.py +50 -0
- solace_agent_mesh/gateway/generic/component.py +650 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +99 -49
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +92 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +150 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +26 -20
- solace_agent_mesh/gateway/http_sse/app.py +0 -14
- solace_agent_mesh/gateway/http_sse/component.py +17 -56
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +1 -1
- solace_agent_mesh/gateway/http_sse/dependencies.py +21 -3
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +8 -8
- solace_agent_mesh/gateway/http_sse/main.py +23 -5
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +56 -98
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +23 -1
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +112 -4
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -1
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +51 -60
- solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +7 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +125 -157
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +269 -8
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +143 -51
- solace_agent_mesh/gateway/http_sse/routers/config.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +198 -94
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +68 -18
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +13 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +51 -35
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +2 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +542 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +9 -11
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +154 -3
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +296 -4
- solace_agent_mesh/gateway/http_sse/services/project_service.py +403 -0
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +16 -10
- solace_agent_mesh/gateway/http_sse/services/session_service.py +178 -6
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +2 -3
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +48 -14
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/METADATA +3 -5
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/RECORD +218 -175
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.7c4594c9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.ddbdfbe2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.3b883666.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.d08a9466.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.6b9493d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.4f395c6b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.720d2ef2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.ed05b14d.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.a8a75e0b.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1761744323675.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1761744323675.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main--3yJYl7S.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DojKHS49.js +0 -342
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-DSqhjwq_.js +0 -405
- /solace_agent_mesh/assets/docs/assets/js/{main.ed05b14d.js.LICENSE.txt → main.f213fe0c.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.3.dist-info → solace_agent_mesh-1.7.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,7 +4,7 @@ FastAPI router for managing session-specific artifacts via REST endpoints.
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
from collections.abc import Callable
|
|
7
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
8
8
|
|
|
9
9
|
from fastapi import (
|
|
10
10
|
APIRouter,
|
|
@@ -13,6 +13,7 @@ from fastapi import (
|
|
|
13
13
|
Form,
|
|
14
14
|
HTTPException,
|
|
15
15
|
Path,
|
|
16
|
+
Query,
|
|
16
17
|
UploadFile,
|
|
17
18
|
status,
|
|
18
19
|
Request as FastAPIRequest,
|
|
@@ -39,8 +40,10 @@ from ....common.utils.embeds import (
|
|
|
39
40
|
evaluate_embed,
|
|
40
41
|
resolve_embeds_recursively_in_string,
|
|
41
42
|
)
|
|
43
|
+
from ....common.utils.embeds.types import ResolutionMode
|
|
42
44
|
from ....common.utils.mime_helpers import is_text_based_mime_type
|
|
43
45
|
from ..dependencies import (
|
|
46
|
+
get_project_service_optional,
|
|
44
47
|
ValidatedUserConfig,
|
|
45
48
|
get_sac_component,
|
|
46
49
|
get_session_validator,
|
|
@@ -50,6 +53,7 @@ from ..dependencies import (
|
|
|
50
53
|
get_session_business_service_optional,
|
|
51
54
|
get_db_optional,
|
|
52
55
|
)
|
|
56
|
+
from ..services.project_service import ProjectService
|
|
53
57
|
|
|
54
58
|
|
|
55
59
|
from ..session_manager import SessionManager
|
|
@@ -85,6 +89,80 @@ class ArtifactUploadResponse(BaseModel):
|
|
|
85
89
|
router = APIRouter()
|
|
86
90
|
|
|
87
91
|
|
|
92
|
+
def _resolve_storage_context(
|
|
93
|
+
session_id: str,
|
|
94
|
+
project_id: str | None,
|
|
95
|
+
user_id: str,
|
|
96
|
+
validate_session: Callable[[str, str], bool],
|
|
97
|
+
project_service: ProjectService | None,
|
|
98
|
+
log_prefix: str
|
|
99
|
+
) -> tuple[str, str, str]:
|
|
100
|
+
"""
|
|
101
|
+
Resolve storage context from session or project parameters.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
tuple: (storage_user_id, storage_session_id, context_type)
|
|
105
|
+
|
|
106
|
+
Raises:
|
|
107
|
+
HTTPException: If no valid context found
|
|
108
|
+
"""
|
|
109
|
+
# Priority 1: Session context
|
|
110
|
+
if session_id and session_id.strip() and session_id not in ["null", "undefined"]:
|
|
111
|
+
if not validate_session(session_id, user_id):
|
|
112
|
+
log.warning("%s Session validation failed", log_prefix)
|
|
113
|
+
raise HTTPException(
|
|
114
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
115
|
+
detail="Session not found or access denied.",
|
|
116
|
+
)
|
|
117
|
+
return user_id, session_id, "session"
|
|
118
|
+
|
|
119
|
+
# Priority 2: Project context (only if persistence is enabled)
|
|
120
|
+
elif project_id and project_id.strip() and project_id not in ["null", "undefined"]:
|
|
121
|
+
if project_service is None:
|
|
122
|
+
log.warning("%s Project context requested but persistence not enabled", log_prefix)
|
|
123
|
+
raise HTTPException(
|
|
124
|
+
status_code=status.HTTP_501_NOT_IMPLEMENTED,
|
|
125
|
+
detail="Project context requires database configuration.",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
from ....gateway.http_sse.dependencies import SessionLocal
|
|
129
|
+
|
|
130
|
+
if SessionLocal is None:
|
|
131
|
+
log.warning("%s Project context requested but database not configured", log_prefix)
|
|
132
|
+
raise HTTPException(
|
|
133
|
+
status_code=status.HTTP_501_NOT_IMPLEMENTED,
|
|
134
|
+
detail="Project context requires database configuration.",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
db = SessionLocal()
|
|
138
|
+
try:
|
|
139
|
+
project = project_service.get_project(db, project_id, user_id)
|
|
140
|
+
if not project:
|
|
141
|
+
log.warning("%s Project not found or access denied", log_prefix)
|
|
142
|
+
raise HTTPException(
|
|
143
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
144
|
+
detail="Project not found or access denied.",
|
|
145
|
+
)
|
|
146
|
+
return project.user_id, f"project-{project_id}", "project"
|
|
147
|
+
except HTTPException:
|
|
148
|
+
raise
|
|
149
|
+
except Exception as e:
|
|
150
|
+
log.error("%s Error resolving project context: %s", log_prefix, e)
|
|
151
|
+
raise HTTPException(
|
|
152
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
153
|
+
detail="Failed to resolve project context"
|
|
154
|
+
)
|
|
155
|
+
finally:
|
|
156
|
+
db.close()
|
|
157
|
+
|
|
158
|
+
# No valid context
|
|
159
|
+
log.warning("%s No valid context found", log_prefix)
|
|
160
|
+
raise HTTPException(
|
|
161
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
162
|
+
detail="No valid context provided.",
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
88
166
|
@router.post(
|
|
89
167
|
"/upload",
|
|
90
168
|
status_code=status.HTTP_201_CREATED,
|
|
@@ -310,33 +388,32 @@ async def upload_artifact_with_session(
|
|
|
310
388
|
)
|
|
311
389
|
async def list_artifact_versions(
|
|
312
390
|
session_id: str = Path(
|
|
313
|
-
..., title="Session ID", description="The session ID to get artifacts from"
|
|
391
|
+
..., title="Session ID", description="The session ID to get artifacts from (or 'null' for project context)"
|
|
314
392
|
),
|
|
315
393
|
filename: str = Path(..., title="Filename", description="The name of the artifact"),
|
|
394
|
+
project_id: Optional[str] = Query(None, description="Project ID for project context"),
|
|
316
395
|
artifact_service: BaseArtifactService = Depends(get_shared_artifact_service),
|
|
317
396
|
user_id: str = Depends(get_user_id),
|
|
318
397
|
validate_session: Callable[[str, str], bool] = Depends(get_session_validator),
|
|
319
398
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
399
|
+
project_service: ProjectService | None = Depends(get_project_service_optional),
|
|
320
400
|
user_config: dict = Depends(ValidatedUserConfig(["tool:artifact:list"])),
|
|
321
401
|
):
|
|
322
402
|
"""
|
|
323
403
|
Lists the available integer versions for a given artifact filename
|
|
324
|
-
associated with the
|
|
404
|
+
associated with the specified context (session or project).
|
|
325
405
|
"""
|
|
326
406
|
|
|
327
407
|
log_prefix = f"[ArtifactRouter:ListVersions:{filename}] User={user_id}, Session={session_id} -"
|
|
328
408
|
log.info("%s Request received.", log_prefix)
|
|
329
409
|
|
|
330
|
-
#
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
335
|
-
detail="Session not found or access denied.",
|
|
336
|
-
)
|
|
410
|
+
# Resolve storage context
|
|
411
|
+
storage_user_id, storage_session_id, context_type = _resolve_storage_context(
|
|
412
|
+
session_id, project_id, user_id, validate_session, project_service, log_prefix
|
|
413
|
+
)
|
|
337
414
|
|
|
338
415
|
if artifact_service is None:
|
|
339
|
-
log.error("%s Artifact service
|
|
416
|
+
log.error("%s Artifact service not available.", log_prefix)
|
|
340
417
|
raise HTTPException(
|
|
341
418
|
status_code=status.HTTP_501_NOT_IMPLEMENTED,
|
|
342
419
|
detail="Artifact service is not configured.",
|
|
@@ -356,10 +433,13 @@ async def list_artifact_versions(
|
|
|
356
433
|
try:
|
|
357
434
|
app_name = component.get_config("name", "A2A_WebUI_App")
|
|
358
435
|
|
|
436
|
+
log.info("%s Using %s context: storage_user_id=%s, storage_session_id=%s",
|
|
437
|
+
log_prefix, context_type, storage_user_id, storage_session_id)
|
|
438
|
+
|
|
359
439
|
versions = await artifact_service.list_versions(
|
|
360
440
|
app_name=app_name,
|
|
361
|
-
user_id=
|
|
362
|
-
session_id=
|
|
441
|
+
user_id=storage_user_id,
|
|
442
|
+
session_id=storage_session_id,
|
|
363
443
|
filename=filename,
|
|
364
444
|
)
|
|
365
445
|
log.info("%s Found versions: %s", log_prefix, versions)
|
|
@@ -368,7 +448,7 @@ async def list_artifact_versions(
|
|
|
368
448
|
log.warning("%s Artifact not found.", log_prefix)
|
|
369
449
|
raise HTTPException(
|
|
370
450
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
371
|
-
detail=f"Artifact '{filename}' not found
|
|
451
|
+
detail=f"Artifact '{filename}' not found.",
|
|
372
452
|
)
|
|
373
453
|
except Exception as e:
|
|
374
454
|
log.exception("%s Error listing artifact versions: %s", log_prefix, e)
|
|
@@ -392,35 +472,33 @@ async def list_artifact_versions(
|
|
|
392
472
|
)
|
|
393
473
|
async def list_artifacts(
|
|
394
474
|
session_id: str = Path(
|
|
395
|
-
..., title="Session ID", description="The session ID to list artifacts for"
|
|
475
|
+
..., title="Session ID", description="The session ID to list artifacts for (or 'null' for project context)"
|
|
396
476
|
),
|
|
477
|
+
project_id: Optional[str] = Query(None, description="Project ID for project context"),
|
|
397
478
|
artifact_service: BaseArtifactService = Depends(get_shared_artifact_service),
|
|
398
479
|
user_id: str = Depends(get_user_id),
|
|
399
480
|
validate_session: Callable[[str, str], bool] = Depends(get_session_validator),
|
|
400
481
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
482
|
+
project_service: ProjectService | None = Depends(get_project_service_optional),
|
|
401
483
|
user_config: dict = Depends(ValidatedUserConfig(["tool:artifact:list"])),
|
|
402
484
|
):
|
|
403
485
|
"""
|
|
404
486
|
Lists detailed information (filename, size, type, modified date, uri)
|
|
405
|
-
for all artifacts associated with the specified
|
|
406
|
-
by calling the artifact helper function.
|
|
487
|
+
for all artifacts associated with the specified context (session or project).
|
|
407
488
|
"""
|
|
408
489
|
|
|
409
490
|
log_prefix = f"[ArtifactRouter:ListInfo] User={user_id}, Session={session_id} -"
|
|
410
491
|
log.info("%s Request received.", log_prefix)
|
|
411
492
|
|
|
412
|
-
#
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
log_prefix
|
|
417
|
-
session_id,
|
|
418
|
-
user_id,
|
|
419
|
-
)
|
|
420
|
-
raise HTTPException(
|
|
421
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
422
|
-
detail="Session not found or access denied.",
|
|
493
|
+
# Resolve storage context (projects vs sessions). This allows for project artiacts
|
|
494
|
+
# to be listed before a session is created.
|
|
495
|
+
try:
|
|
496
|
+
storage_user_id, storage_session_id, context_type = _resolve_storage_context(
|
|
497
|
+
session_id, project_id, user_id, validate_session, project_service, log_prefix
|
|
423
498
|
)
|
|
499
|
+
except HTTPException:
|
|
500
|
+
log.info("%s No valid context found, returning empty list", log_prefix)
|
|
501
|
+
return []
|
|
424
502
|
|
|
425
503
|
if artifact_service is None:
|
|
426
504
|
log.error("%s Artifact service is not configured or available.", log_prefix)
|
|
@@ -432,22 +510,21 @@ async def list_artifacts(
|
|
|
432
510
|
try:
|
|
433
511
|
app_name = component.get_config("name", "A2A_WebUI_App")
|
|
434
512
|
|
|
513
|
+
log.info("%s Using %s context: storage_user_id=%s, storage_session_id=%s",
|
|
514
|
+
log_prefix, context_type, storage_user_id, storage_session_id)
|
|
515
|
+
|
|
435
516
|
artifact_info_list = await get_artifact_info_list(
|
|
436
517
|
artifact_service=artifact_service,
|
|
437
518
|
app_name=app_name,
|
|
438
|
-
user_id=
|
|
439
|
-
session_id=
|
|
519
|
+
user_id=storage_user_id,
|
|
520
|
+
session_id=storage_session_id,
|
|
440
521
|
)
|
|
441
522
|
|
|
442
|
-
log.info(
|
|
443
|
-
"%s Returning %d artifact details.", log_prefix, len(artifact_info_list)
|
|
444
|
-
)
|
|
523
|
+
log.info("%s Returning %d artifact details.", log_prefix, len(artifact_info_list))
|
|
445
524
|
return artifact_info_list
|
|
446
525
|
|
|
447
526
|
except Exception as e:
|
|
448
|
-
log.exception(
|
|
449
|
-
"%s Error retrieving artifact details via helper: %s", log_prefix, e
|
|
450
|
-
)
|
|
527
|
+
log.exception("%s Error retrieving artifact details: %s", log_prefix, e)
|
|
451
528
|
raise HTTPException(
|
|
452
529
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
453
530
|
detail=f"Failed to retrieve artifact details: {str(e)}",
|
|
@@ -461,24 +538,31 @@ async def list_artifacts(
|
|
|
461
538
|
)
|
|
462
539
|
async def get_latest_artifact(
|
|
463
540
|
session_id: str = Path(
|
|
464
|
-
..., title="Session ID", description="The session ID to get artifacts from"
|
|
541
|
+
..., title="Session ID", description="The session ID to get artifacts from (or 'null' for project context)"
|
|
465
542
|
),
|
|
466
543
|
filename: str = Path(..., title="Filename", description="The name of the artifact"),
|
|
544
|
+
project_id: Optional[str] = Query(None, description="Project ID for project context"),
|
|
467
545
|
artifact_service: BaseArtifactService = Depends(get_shared_artifact_service),
|
|
468
546
|
user_id: str = Depends(get_user_id),
|
|
469
547
|
validate_session: Callable[[str, str], bool] = Depends(get_session_validator),
|
|
470
548
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
549
|
+
project_service: ProjectService | None = Depends(get_project_service_optional),
|
|
471
550
|
user_config: dict = Depends(ValidatedUserConfig(["tool:artifact:load"])),
|
|
472
551
|
):
|
|
473
552
|
"""
|
|
474
553
|
Retrieves the content of the latest version of the specified artifact
|
|
475
|
-
associated with the
|
|
554
|
+
associated with the specified context (session or project).
|
|
476
555
|
"""
|
|
477
556
|
log_prefix = (
|
|
478
557
|
f"[ArtifactRouter:GetLatest:{filename}] User={user_id}, Session={session_id} -"
|
|
479
558
|
)
|
|
480
559
|
log.info("%s Request received.", log_prefix)
|
|
481
560
|
|
|
561
|
+
# Resolve storage context
|
|
562
|
+
storage_user_id, storage_session_id, context_type = _resolve_storage_context(
|
|
563
|
+
session_id, project_id, user_id, validate_session, project_service, log_prefix
|
|
564
|
+
)
|
|
565
|
+
|
|
482
566
|
if artifact_service is None:
|
|
483
567
|
log.error("%s Artifact service is not configured or available.", log_prefix)
|
|
484
568
|
raise HTTPException(
|
|
@@ -488,10 +572,14 @@ async def get_latest_artifact(
|
|
|
488
572
|
|
|
489
573
|
try:
|
|
490
574
|
app_name = component.get_config("name", "A2A_WebUI_App")
|
|
575
|
+
|
|
576
|
+
log.info("%s Using %s context: storage_user_id=%s, storage_session_id=%s",
|
|
577
|
+
log_prefix, context_type, storage_user_id, storage_session_id)
|
|
578
|
+
|
|
491
579
|
artifact_part = await artifact_service.load_artifact(
|
|
492
580
|
app_name=app_name,
|
|
493
|
-
user_id=
|
|
494
|
-
session_id=
|
|
581
|
+
user_id=storage_user_id,
|
|
582
|
+
session_id=storage_session_id,
|
|
495
583
|
filename=filename,
|
|
496
584
|
)
|
|
497
585
|
|
|
@@ -537,6 +625,7 @@ async def get_latest_artifact(
|
|
|
537
625
|
context=context_for_resolver,
|
|
538
626
|
resolver_func=evaluate_embed,
|
|
539
627
|
types_to_resolve=LATE_EMBED_TYPES,
|
|
628
|
+
resolution_mode=ResolutionMode.RECURSIVE_ARTIFACT_CONTENT,
|
|
540
629
|
log_identifier=f"{log_prefix}[RecursiveResolve]",
|
|
541
630
|
config=config_for_resolver,
|
|
542
631
|
max_depth=component.gateway_recursive_embed_depth,
|
|
@@ -596,7 +685,7 @@ async def get_latest_artifact(
|
|
|
596
685
|
)
|
|
597
686
|
async def get_specific_artifact_version(
|
|
598
687
|
session_id: str = Path(
|
|
599
|
-
..., title="Session ID", description="The session ID to get artifacts from"
|
|
688
|
+
..., title="Session ID", description="The session ID to get artifacts from (or 'null' for project context)"
|
|
600
689
|
),
|
|
601
690
|
filename: str = Path(..., title="Filename", description="The name of the artifact"),
|
|
602
691
|
version: int | str = Path(
|
|
@@ -604,26 +693,25 @@ async def get_specific_artifact_version(
|
|
|
604
693
|
title="Version",
|
|
605
694
|
description="The specific version number to retrieve, or 'latest'",
|
|
606
695
|
),
|
|
696
|
+
project_id: Optional[str] = Query(None, description="Project ID for project context"),
|
|
607
697
|
artifact_service: BaseArtifactService = Depends(get_shared_artifact_service),
|
|
608
698
|
user_id: str = Depends(get_user_id),
|
|
609
699
|
validate_session: Callable[[str, str], bool] = Depends(get_session_validator),
|
|
610
700
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
701
|
+
project_service: ProjectService | None = Depends(get_project_service_optional),
|
|
611
702
|
user_config: dict = Depends(ValidatedUserConfig(["tool:artifact:load"])),
|
|
612
703
|
):
|
|
613
704
|
"""
|
|
614
705
|
Retrieves the content of a specific version of the specified artifact
|
|
615
|
-
associated with the
|
|
706
|
+
associated with the specified context (session or project).
|
|
616
707
|
"""
|
|
617
708
|
log_prefix = f"[ArtifactRouter:GetVersion:{filename} v{version}] User={user_id}, Session={session_id} -"
|
|
618
709
|
log.info("%s Request received.", log_prefix)
|
|
619
710
|
|
|
620
|
-
#
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
status_code=status.HTTP_404_NOT_FOUND,
|
|
625
|
-
detail="Session not found or access denied.",
|
|
626
|
-
)
|
|
711
|
+
# Resolve storage context
|
|
712
|
+
storage_user_id, storage_session_id, context_type = _resolve_storage_context(
|
|
713
|
+
session_id, project_id, user_id, validate_session, project_service, log_prefix
|
|
714
|
+
)
|
|
627
715
|
|
|
628
716
|
if artifact_service is None:
|
|
629
717
|
log.error("%s Artifact service is not configured or available.", log_prefix)
|
|
@@ -635,11 +723,14 @@ async def get_specific_artifact_version(
|
|
|
635
723
|
try:
|
|
636
724
|
app_name = component.get_config("name", "A2A_WebUI_App")
|
|
637
725
|
|
|
726
|
+
log.info("%s Using %s context: storage_user_id=%s, storage_session_id=%s",
|
|
727
|
+
log_prefix, context_type, storage_user_id, storage_session_id)
|
|
728
|
+
|
|
638
729
|
load_result = await load_artifact_content_or_metadata(
|
|
639
730
|
artifact_service=artifact_service,
|
|
640
731
|
app_name=app_name,
|
|
641
|
-
user_id=
|
|
642
|
-
session_id=
|
|
732
|
+
user_id=storage_user_id,
|
|
733
|
+
session_id=storage_session_id,
|
|
643
734
|
filename=filename,
|
|
644
735
|
version=version,
|
|
645
736
|
load_metadata_only=False,
|
|
@@ -715,6 +806,7 @@ async def get_specific_artifact_version(
|
|
|
715
806
|
context=context_for_resolver,
|
|
716
807
|
resolver_func=evaluate_embed,
|
|
717
808
|
types_to_resolve=LATE_EMBED_TYPES,
|
|
809
|
+
resolution_mode=ResolutionMode.RECURSIVE_ARTIFACT_CONTENT,
|
|
718
810
|
log_identifier=f"{log_prefix}[RecursiveResolve]",
|
|
719
811
|
config=config_for_resolver,
|
|
720
812
|
max_depth=component.gateway_recursive_embed_depth,
|
|
@@ -7,6 +7,7 @@ from fastapi import APIRouter, Depends, HTTPException, status
|
|
|
7
7
|
from typing import Dict, Any
|
|
8
8
|
|
|
9
9
|
from ....gateway.http_sse.dependencies import get_sac_component, get_api_config
|
|
10
|
+
from ..routers.dto.requests.project_requests import CreateProjectRequest, UpdateProjectRequest
|
|
10
11
|
from typing import TYPE_CHECKING
|
|
11
12
|
|
|
12
13
|
if TYPE_CHECKING:
|
|
@@ -17,6 +18,64 @@ log = logging.getLogger(__name__)
|
|
|
17
18
|
router = APIRouter()
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
def _get_validation_limits() -> Dict[str, Any]:
|
|
22
|
+
"""
|
|
23
|
+
Extract validation limits from Pydantic models to expose to frontend.
|
|
24
|
+
This ensures frontend and backend validation limits stay in sync.
|
|
25
|
+
"""
|
|
26
|
+
# Extract limits from CreateProjectRequest model
|
|
27
|
+
create_fields = CreateProjectRequest.model_fields
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
"projectNameMax": create_fields["name"].metadata[1].max_length if create_fields["name"].metadata else 255,
|
|
31
|
+
"projectDescriptionMax": create_fields["description"].metadata[0].max_length if create_fields["description"].metadata else 1000,
|
|
32
|
+
"projectInstructionsMax": create_fields["system_prompt"].metadata[0].max_length if create_fields["system_prompt"].metadata else 4000,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _determine_projects_enabled(
|
|
37
|
+
component: "WebUIBackendComponent",
|
|
38
|
+
api_config: Dict[str, Any],
|
|
39
|
+
log_prefix: str
|
|
40
|
+
) -> bool:
|
|
41
|
+
"""
|
|
42
|
+
Determines if projects feature should be enabled.
|
|
43
|
+
|
|
44
|
+
Logic:
|
|
45
|
+
1. Check if persistence is enabled (required for projects)
|
|
46
|
+
2. Check explicit projects.enabled config
|
|
47
|
+
3. Check frontend_feature_enablement.projects override
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
bool: True if projects should be enabled
|
|
51
|
+
"""
|
|
52
|
+
# Projects require persistence
|
|
53
|
+
persistence_enabled = api_config.get("persistence_enabled", False)
|
|
54
|
+
if not persistence_enabled:
|
|
55
|
+
log.debug("%s Projects disabled: persistence is not enabled", log_prefix)
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
# Check explicit projects config
|
|
59
|
+
projects_config = component.get_config("projects", {})
|
|
60
|
+
if isinstance(projects_config, dict):
|
|
61
|
+
projects_explicitly_enabled = projects_config.get("enabled", True)
|
|
62
|
+
if not projects_explicitly_enabled:
|
|
63
|
+
log.debug("%s Projects disabled: explicitly disabled in config", log_prefix)
|
|
64
|
+
return False
|
|
65
|
+
|
|
66
|
+
# Check frontend_feature_enablement override
|
|
67
|
+
feature_flags = component.get_config("frontend_feature_enablement", {})
|
|
68
|
+
if "projects" in feature_flags:
|
|
69
|
+
projects_flag = feature_flags.get("projects", True)
|
|
70
|
+
if not projects_flag:
|
|
71
|
+
log.debug("%s Projects disabled: disabled in frontend_feature_enablement", log_prefix)
|
|
72
|
+
return False
|
|
73
|
+
|
|
74
|
+
# All checks passed
|
|
75
|
+
log.debug("%s Projects enabled: persistence enabled and no explicit disable", log_prefix)
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
|
|
20
79
|
@router.get("/config", response_model=Dict[str, Any])
|
|
21
80
|
async def get_app_config(
|
|
22
81
|
component: "WebUIBackendComponent" = Depends(get_sac_component),
|
|
@@ -51,6 +110,15 @@ async def get_app_config(
|
|
|
51
110
|
session_type
|
|
52
111
|
)
|
|
53
112
|
feedback_enabled = False
|
|
113
|
+
|
|
114
|
+
# Determine if projects should be enabled
|
|
115
|
+
# Projects require SQL session storage for persistence
|
|
116
|
+
projects_enabled = _determine_projects_enabled(component, api_config, log_prefix)
|
|
117
|
+
feature_enablement["projects"] = projects_enabled
|
|
118
|
+
if projects_enabled:
|
|
119
|
+
log.debug("%s Projects feature flag is enabled.", log_prefix)
|
|
120
|
+
else:
|
|
121
|
+
log.debug("%s Projects feature flag is disabled.", log_prefix)
|
|
54
122
|
|
|
55
123
|
config_data = {
|
|
56
124
|
"frontend_server_url": "",
|
|
@@ -68,6 +136,7 @@ async def get_app_config(
|
|
|
68
136
|
"frontend_bot_name": component.get_config("frontend_bot_name", "A2A Agent"),
|
|
69
137
|
"frontend_feature_enablement": feature_enablement,
|
|
70
138
|
"persistence_enabled": api_config.get("persistence_enabled", False),
|
|
139
|
+
"validation_limits": _get_validation_limits(),
|
|
71
140
|
}
|
|
72
141
|
log.debug("%sReturning frontend configuration.", log_prefix)
|
|
73
142
|
return config_data
|