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
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
Session repository implementation using SQLAlchemy.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from sqlalchemy
|
|
5
|
+
from sqlalchemy import or_, func
|
|
6
|
+
from sqlalchemy.orm import Session as DBSession, joinedload
|
|
6
7
|
|
|
7
8
|
from ..shared.base_repository import PaginatedRepository
|
|
8
9
|
from ..shared.pagination import PaginationParams
|
|
9
10
|
from ..shared.types import SessionId, UserId
|
|
11
|
+
from ..shared import now_epoch_ms
|
|
10
12
|
from .entities import Session
|
|
11
13
|
from .interfaces import ISessionRepository
|
|
12
14
|
from .models import CreateSessionModel, SessionModel, UpdateSessionModel
|
|
15
|
+
from .models.chat_task_model import ChatTaskModel
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepository):
|
|
@@ -24,10 +27,20 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
24
27
|
return "session"
|
|
25
28
|
|
|
26
29
|
def find_by_user(
|
|
27
|
-
self, session: DBSession, user_id: UserId, pagination: PaginationParams | None = None
|
|
30
|
+
self, session: DBSession, user_id: UserId, pagination: PaginationParams | None = None, project_id: str | None = None
|
|
28
31
|
) -> list[Session]:
|
|
29
|
-
"""Find all sessions for a specific user."""
|
|
30
|
-
query = session.query(SessionModel).filter(
|
|
32
|
+
"""Find all sessions for a specific user with optional project filtering."""
|
|
33
|
+
query = session.query(SessionModel).filter(
|
|
34
|
+
SessionModel.user_id == user_id,
|
|
35
|
+
SessionModel.deleted_at.is_(None) # Exclude soft-deleted sessions
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Optional project filtering for project-specific views
|
|
39
|
+
if project_id is not None:
|
|
40
|
+
query = query.filter(SessionModel.project_id == project_id)
|
|
41
|
+
|
|
42
|
+
# Eager load project relationship
|
|
43
|
+
query = query.options(joinedload(SessionModel.project))
|
|
31
44
|
query = query.order_by(SessionModel.updated_time.desc())
|
|
32
45
|
|
|
33
46
|
if pagination:
|
|
@@ -36,12 +49,19 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
36
49
|
models = query.all()
|
|
37
50
|
return [Session.model_validate(model) for model in models]
|
|
38
51
|
|
|
39
|
-
def count_by_user(self, session: DBSession, user_id: UserId) -> int:
|
|
40
|
-
"""Count total sessions for a specific user."""
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
def count_by_user(self, session: DBSession, user_id: UserId, project_id: str | None = None) -> int:
|
|
53
|
+
"""Count total sessions for a specific user with optional project filtering."""
|
|
54
|
+
query = session.query(SessionModel).filter(
|
|
55
|
+
SessionModel.user_id == user_id,
|
|
56
|
+
SessionModel.deleted_at.is_(None) # Exclude soft-deleted sessions
|
|
43
57
|
)
|
|
44
58
|
|
|
59
|
+
# Optional project filtering for project-specific views
|
|
60
|
+
if project_id is not None:
|
|
61
|
+
query = query.filter(SessionModel.project_id == project_id)
|
|
62
|
+
|
|
63
|
+
return query.count()
|
|
64
|
+
|
|
45
65
|
def find_user_session(
|
|
46
66
|
self, session: DBSession, session_id: SessionId, user_id: UserId
|
|
47
67
|
) -> Session | None:
|
|
@@ -51,6 +71,7 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
51
71
|
.filter(
|
|
52
72
|
SessionModel.id == session_id,
|
|
53
73
|
SessionModel.user_id == user_id,
|
|
74
|
+
SessionModel.deleted_at.is_(None) # Exclude soft-deleted sessions
|
|
54
75
|
)
|
|
55
76
|
.first()
|
|
56
77
|
)
|
|
@@ -66,6 +87,7 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
66
87
|
update_model = UpdateSessionModel(
|
|
67
88
|
name=session.name,
|
|
68
89
|
agent_id=session.agent_id,
|
|
90
|
+
project_id=session.project_id,
|
|
69
91
|
updated_time=session.updated_time,
|
|
70
92
|
)
|
|
71
93
|
return self.update(
|
|
@@ -77,6 +99,7 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
77
99
|
name=session.name,
|
|
78
100
|
user_id=session.user_id,
|
|
79
101
|
agent_id=session.agent_id,
|
|
102
|
+
project_id=session.project_id,
|
|
80
103
|
created_time=session.created_time,
|
|
81
104
|
updated_time=session.updated_time,
|
|
82
105
|
)
|
|
@@ -100,3 +123,241 @@ class SessionRepository(PaginatedRepository[SessionModel, Session], ISessionRepo
|
|
|
100
123
|
# Use BaseRepository delete method
|
|
101
124
|
super().delete(db_session, session_id)
|
|
102
125
|
return True
|
|
126
|
+
|
|
127
|
+
def soft_delete(self, db_session: DBSession, session_id: SessionId, user_id: UserId) -> bool:
|
|
128
|
+
"""Soft delete a session belonging to a user."""
|
|
129
|
+
session_model = (
|
|
130
|
+
db_session.query(SessionModel)
|
|
131
|
+
.filter(
|
|
132
|
+
SessionModel.id == session_id,
|
|
133
|
+
SessionModel.user_id == user_id,
|
|
134
|
+
SessionModel.deleted_at.is_(None)
|
|
135
|
+
)
|
|
136
|
+
.first()
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if not session_model:
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
# Perform soft delete
|
|
143
|
+
session_model.deleted_at = now_epoch_ms()
|
|
144
|
+
session_model.deleted_by = user_id
|
|
145
|
+
session_model.updated_time = now_epoch_ms()
|
|
146
|
+
|
|
147
|
+
db_session.flush()
|
|
148
|
+
return True
|
|
149
|
+
|
|
150
|
+
def soft_delete_by_project(self, db_session: DBSession, project_id: str, user_id: UserId) -> int:
|
|
151
|
+
"""
|
|
152
|
+
Soft delete all sessions belonging to a specific project.
|
|
153
|
+
Used when cascading project deletion.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
db_session: Database session
|
|
157
|
+
project_id: The project ID
|
|
158
|
+
user_id: The user ID (for deleted_by tracking)
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
int: Number of sessions soft deleted
|
|
162
|
+
"""
|
|
163
|
+
now = now_epoch_ms()
|
|
164
|
+
|
|
165
|
+
# Find all non-deleted sessions for this project
|
|
166
|
+
sessions_to_delete = (
|
|
167
|
+
db_session.query(SessionModel)
|
|
168
|
+
.filter(
|
|
169
|
+
SessionModel.project_id == project_id,
|
|
170
|
+
SessionModel.user_id == user_id,
|
|
171
|
+
SessionModel.deleted_at.is_(None)
|
|
172
|
+
)
|
|
173
|
+
.all()
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Soft delete each session
|
|
177
|
+
for session_model in sessions_to_delete:
|
|
178
|
+
session_model.deleted_at = now
|
|
179
|
+
session_model.deleted_by = user_id
|
|
180
|
+
session_model.updated_time = now
|
|
181
|
+
|
|
182
|
+
db_session.flush()
|
|
183
|
+
return len(sessions_to_delete)
|
|
184
|
+
|
|
185
|
+
def move_to_project(
|
|
186
|
+
self, db_session: DBSession, session_id: SessionId, user_id: UserId, new_project_id: str | None
|
|
187
|
+
) -> Session | None:
|
|
188
|
+
"""Move a session to a different project."""
|
|
189
|
+
session_model = (
|
|
190
|
+
db_session.query(SessionModel)
|
|
191
|
+
.filter(
|
|
192
|
+
SessionModel.id == session_id,
|
|
193
|
+
SessionModel.user_id == user_id,
|
|
194
|
+
SessionModel.deleted_at.is_(None)
|
|
195
|
+
)
|
|
196
|
+
.first()
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
if not session_model:
|
|
200
|
+
return None
|
|
201
|
+
|
|
202
|
+
# Update project_id
|
|
203
|
+
session_model.project_id = new_project_id
|
|
204
|
+
session_model.updated_time = now_epoch_ms()
|
|
205
|
+
|
|
206
|
+
db_session.flush()
|
|
207
|
+
db_session.refresh(session_model)
|
|
208
|
+
|
|
209
|
+
return Session.model_validate(session_model)
|
|
210
|
+
|
|
211
|
+
def search(
|
|
212
|
+
self,
|
|
213
|
+
db_session: DBSession,
|
|
214
|
+
user_id: UserId,
|
|
215
|
+
query: str,
|
|
216
|
+
pagination: PaginationParams | None = None,
|
|
217
|
+
project_id: str | None = None
|
|
218
|
+
) -> list[Session]:
|
|
219
|
+
"""
|
|
220
|
+
Search sessions by name or content.
|
|
221
|
+
|
|
222
|
+
Uses PostgreSQL full-text search when available (for queries >= 3 chars),
|
|
223
|
+
falls back to ILIKE for SQLite or short queries.
|
|
224
|
+
"""
|
|
225
|
+
# Base query - only non-deleted sessions for the user
|
|
226
|
+
base_query = db_session.query(SessionModel).filter(
|
|
227
|
+
SessionModel.user_id == user_id,
|
|
228
|
+
SessionModel.deleted_at.is_(None)
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Optional project filtering
|
|
232
|
+
if project_id is not None:
|
|
233
|
+
base_query = base_query.filter(SessionModel.project_id == project_id)
|
|
234
|
+
|
|
235
|
+
# Detect database dialect
|
|
236
|
+
dialect_name = db_session.bind.dialect.name
|
|
237
|
+
use_fts = dialect_name == 'postgresql' and len(query.strip()) >= 3
|
|
238
|
+
|
|
239
|
+
if use_fts:
|
|
240
|
+
# PostgreSQL full-text search for better performance
|
|
241
|
+
matching_chat_tasks = (
|
|
242
|
+
db_session.query(ChatTaskModel.session_id)
|
|
243
|
+
.filter(
|
|
244
|
+
or_(
|
|
245
|
+
func.to_tsvector('english', func.coalesce(ChatTaskModel.user_message, ''))
|
|
246
|
+
.op('@@')(func.plainto_tsquery('english', query)),
|
|
247
|
+
func.to_tsvector('english', ChatTaskModel.message_bubbles)
|
|
248
|
+
.op('@@')(func.plainto_tsquery('english', query))
|
|
249
|
+
)
|
|
250
|
+
)
|
|
251
|
+
.distinct()
|
|
252
|
+
.subquery()
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
search_query = base_query.filter(
|
|
256
|
+
or_(
|
|
257
|
+
func.to_tsvector('english', func.coalesce(SessionModel.name, ''))
|
|
258
|
+
.op('@@')(func.plainto_tsquery('english', query)),
|
|
259
|
+
SessionModel.id.in_(matching_chat_tasks)
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
else:
|
|
263
|
+
# ILIKE search for SQLite or short queries
|
|
264
|
+
search_pattern = f"%{query}%"
|
|
265
|
+
matching_chat_tasks = (
|
|
266
|
+
db_session.query(ChatTaskModel.session_id)
|
|
267
|
+
.filter(
|
|
268
|
+
or_(
|
|
269
|
+
ChatTaskModel.user_message.ilike(search_pattern),
|
|
270
|
+
ChatTaskModel.message_bubbles.ilike(search_pattern)
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
.distinct()
|
|
274
|
+
.subquery()
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
search_query = base_query.filter(
|
|
278
|
+
or_(
|
|
279
|
+
SessionModel.name.ilike(search_pattern),
|
|
280
|
+
SessionModel.id.in_(matching_chat_tasks)
|
|
281
|
+
)
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
# Eager load project relationship
|
|
285
|
+
search_query = search_query.options(joinedload(SessionModel.project))
|
|
286
|
+
search_query = search_query.order_by(SessionModel.updated_time.desc())
|
|
287
|
+
|
|
288
|
+
if pagination:
|
|
289
|
+
search_query = search_query.offset(pagination.offset).limit(pagination.page_size)
|
|
290
|
+
|
|
291
|
+
models = search_query.all()
|
|
292
|
+
return [Session.model_validate(model) for model in models]
|
|
293
|
+
|
|
294
|
+
def count_search_results(
|
|
295
|
+
self,
|
|
296
|
+
db_session: DBSession,
|
|
297
|
+
user_id: UserId,
|
|
298
|
+
query: str,
|
|
299
|
+
project_id: str | None = None
|
|
300
|
+
) -> int:
|
|
301
|
+
"""
|
|
302
|
+
Count search results for pagination.
|
|
303
|
+
|
|
304
|
+
Uses same database-agnostic logic as search() method for consistency.
|
|
305
|
+
"""
|
|
306
|
+
# Base query - only non-deleted sessions for the user
|
|
307
|
+
base_query = db_session.query(SessionModel).filter(
|
|
308
|
+
SessionModel.user_id == user_id,
|
|
309
|
+
SessionModel.deleted_at.is_(None)
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
if project_id is not None:
|
|
313
|
+
base_query = base_query.filter(SessionModel.project_id == project_id)
|
|
314
|
+
|
|
315
|
+
dialect_name = db_session.bind.dialect.name
|
|
316
|
+
use_fts = dialect_name == 'postgresql' and len(query.strip()) >= 3
|
|
317
|
+
|
|
318
|
+
if use_fts:
|
|
319
|
+
# PostgreSQL full-text search
|
|
320
|
+
matching_chat_tasks = (
|
|
321
|
+
db_session.query(ChatTaskModel.session_id)
|
|
322
|
+
.filter(
|
|
323
|
+
or_(
|
|
324
|
+
func.to_tsvector('english', func.coalesce(ChatTaskModel.user_message, ''))
|
|
325
|
+
.op('@@')(func.plainto_tsquery('english', query)),
|
|
326
|
+
func.to_tsvector('english', ChatTaskModel.message_bubbles)
|
|
327
|
+
.op('@@')(func.plainto_tsquery('english', query))
|
|
328
|
+
)
|
|
329
|
+
)
|
|
330
|
+
.distinct()
|
|
331
|
+
.subquery()
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
search_query = base_query.filter(
|
|
335
|
+
or_(
|
|
336
|
+
func.to_tsvector('english', func.coalesce(SessionModel.name, ''))
|
|
337
|
+
.op('@@')(func.plainto_tsquery('english', query)),
|
|
338
|
+
SessionModel.id.in_(matching_chat_tasks)
|
|
339
|
+
)
|
|
340
|
+
)
|
|
341
|
+
else:
|
|
342
|
+
# ILIKE search for SQLite or short queries
|
|
343
|
+
search_pattern = f"%{query}%"
|
|
344
|
+
matching_chat_tasks = (
|
|
345
|
+
db_session.query(ChatTaskModel.session_id)
|
|
346
|
+
.filter(
|
|
347
|
+
or_(
|
|
348
|
+
ChatTaskModel.user_message.ilike(search_pattern),
|
|
349
|
+
ChatTaskModel.message_bubbles.ilike(search_pattern)
|
|
350
|
+
)
|
|
351
|
+
)
|
|
352
|
+
.distinct()
|
|
353
|
+
.subquery()
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
search_query = base_query.filter(
|
|
357
|
+
or_(
|
|
358
|
+
SessionModel.name.ilike(search_pattern),
|
|
359
|
+
SessionModel.id.in_(matching_chat_tasks)
|
|
360
|
+
)
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
return search_query.count()
|