solace-agent-mesh 1.6.1__py3-none-any.whl → 1.13.2__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/alembic/README +74 -0
- solace_agent_mesh/agent/adk/alembic/env.py +77 -0
- solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
- solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
- solace_agent_mesh/agent/adk/alembic.ini +112 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +165 -1
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
- solace_agent_mesh/agent/adk/callbacks.py +852 -109
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +234 -36
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +52 -5
- solace_agent_mesh/agent/adk/mcp_content_processor.py +1 -1
- solace_agent_mesh/agent/adk/models/lite_llm.py +77 -21
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
- solace_agent_mesh/agent/adk/runner.py +85 -20
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +94 -18
- solace_agent_mesh/agent/adk/setup.py +281 -65
- solace_agent_mesh/agent/adk/stream_parser.py +231 -37
- solace_agent_mesh/agent/adk/tool_wrapper.py +3 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +472 -137
- solace_agent_mesh/agent/proxies/a2a/app.py +3 -2
- solace_agent_mesh/agent/proxies/a2a/component.py +572 -75
- solace_agent_mesh/agent/proxies/a2a/config.py +80 -4
- solace_agent_mesh/agent/proxies/base/app.py +3 -2
- solace_agent_mesh/agent/proxies/base/component.py +188 -22
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
- solace_agent_mesh/agent/sac/app.py +91 -3
- solace_agent_mesh/agent/sac/component.py +591 -157
- solace_agent_mesh/agent/sac/patch_adk.py +8 -16
- solace_agent_mesh/agent/sac/task_execution_context.py +146 -4
- solace_agent_mesh/agent/tools/__init__.py +3 -0
- solace_agent_mesh/agent/tools/audio_tools.py +3 -3
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +710 -171
- solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +82 -15
- solace_agent_mesh/agent/tools/time_tools.py +126 -0
- solace_agent_mesh/agent/tools/tool_config_types.py +57 -2
- solace_agent_mesh/agent/tools/web_search_tools.py +279 -0
- solace_agent_mesh/agent/tools/web_tools.py +125 -17
- solace_agent_mesh/agent/utils/artifact_helpers.py +248 -6
- solace_agent_mesh/agent/utils/context_helpers.py +17 -0
- solace_agent_mesh/assets/docs/404.html +6 -6
- solace_agent_mesh/assets/docs/assets/css/{styles.906a1503.css → styles.8162edfb.css} +1 -1
- solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.e612dfb4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/{17896441.a5e82f9b.js.LICENSE.txt → 2279.550aa580.js.LICENSE.txt} +6 -0
- solace_agent_mesh/assets/docs/assets/js/240a0364.83e37aa8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.2f0db237.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.7e61915d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.7f7ab1c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.e53c9b78.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/41adc471.0e95b87c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/49eed117.493d6f99.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{509e993c.4c7a1a6d.js → 509e993c.a1fbf45a.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5b8d9c11.d4eb37b8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.1ee87753.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/729898df.7249e9fd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7e294c01.7c5f6906.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.e3467286.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.7ed65d45.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.4523ae20.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7d42657.a956689d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e563275.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.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.06d23db6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.deb2b62e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.acc800d3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.c147a429.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ee0c2fe7.94d0a351.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.cc97854c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.d634009f.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.27bb82a7.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +68 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +50 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +55 -55
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +82 -68
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/image-tools/index.html +81 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +67 -50
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/research-tools/index.html +136 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +178 -144
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +43 -42
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +20 -18
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +23 -23
- solace_agent_mesh/assets/docs/docs/documentation/components/platform-service/index.html +33 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +45 -45
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +208 -125
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +28 -49
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -30
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes/kubernetes-deployment-guide/index.html +197 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -16
- solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +38 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +162 -171
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +67 -49
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +17 -17
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +22 -22
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +27 -27
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +135 -135
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +66 -66
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +50 -38
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +86 -86
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +51 -51
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +24 -24
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +23 -19
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +40 -37
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +112 -87
- 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 +87 -64
- 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 +44 -44
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +39 -37
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +30 -30
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +18 -18
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/vibe_coding/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +311 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +39 -42
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +27 -25
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +69 -69
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +72 -72
- 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 +42 -42
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +20 -20
- solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
- solace_agent_mesh/assets/docs/lunr-index-1768329217460.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1768329217460.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/__init__.py +3 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +6 -1
- solace_agent_mesh/cli/commands/add_cmd/proxy_cmd.py +100 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +4 -1
- solace_agent_mesh/cli/commands/eval_cmd.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +15 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +1 -1
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +30 -3
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +3 -4
- solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +16 -3
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +2 -1
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +1 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +3 -3
- solace_agent_mesh/cli/commands/run_cmd.py +64 -49
- solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
- solace_agent_mesh/cli/main.py +15 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-BTf6dqwp.js → authCallback-KnKMP_vb.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/client-DpBL2stg.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Cd498TV2.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-rSf8Vu29.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-CGk8Suyh.js +565 -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/client/webui/frontend/static/mockServiceWorker.js +336 -0
- solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
- solace_agent_mesh/common/a2a/events.py +2 -1
- solace_agent_mesh/common/a2a/protocol.py +5 -0
- solace_agent_mesh/common/a2a/types.py +2 -1
- 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/agent_registry.py +38 -11
- solace_agent_mesh/common/data_parts.py +144 -4
- solace_agent_mesh/common/error_handlers.py +83 -0
- solace_agent_mesh/common/exceptions.py +24 -0
- solace_agent_mesh/common/oauth/__init__.py +17 -0
- solace_agent_mesh/common/oauth/oauth_client.py +408 -0
- solace_agent_mesh/common/oauth/utils.py +50 -0
- solace_agent_mesh/common/rag_dto.py +156 -0
- solace_agent_mesh/common/sac/sam_component_base.py +97 -19
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/common/services/employee_service.py +1 -1
- solace_agent_mesh/common/utils/embeds/constants.py +1 -0
- solace_agent_mesh/common/utils/embeds/converter.py +1 -8
- solace_agent_mesh/common/utils/embeds/modifiers.py +4 -28
- solace_agent_mesh/common/utils/embeds/resolver.py +152 -31
- solace_agent_mesh/common/utils/embeds/types.py +9 -0
- solace_agent_mesh/common/utils/log_formatters.py +20 -0
- solace_agent_mesh/common/utils/mime_helpers.py +12 -5
- solace_agent_mesh/common/utils/pydantic_utils.py +90 -3
- solace_agent_mesh/common/utils/rbac_utils.py +69 -0
- solace_agent_mesh/common/utils/templates/__init__.py +8 -0
- solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
- solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
- solace_agent_mesh/config_portal/backend/common.py +12 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-CljP4_mv.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{components-Rk0n-9cK.js → components-CaC6hG8d.js} +22 -22
- solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-mvZjNKiz.js → entry.client-H_TM0YBt.js} +3 -3
- solace_agent_mesh/config_portal/frontend/static/client/assets/{index-DzNKzXrc.js → index-CnFykb2v.js} +16 -16
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-f8439d40.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BIMqslJB.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-mJmTIdIk.js +10 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
- solace_agent_mesh/core_a2a/service.py +3 -2
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +170 -0
- solace_agent_mesh/gateway/adapter/types.py +230 -0
- solace_agent_mesh/gateway/base/app.py +39 -2
- solace_agent_mesh/gateway/base/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +1027 -151
- 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 +894 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
- 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 +109 -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/20251108_create_prompt_tables_with_sharing.py +154 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +0 -36
- solace_agent_mesh/gateway/http_sse/app.py +40 -11
- solace_agent_mesh/gateway/http_sse/component.py +285 -160
- solace_agent_mesh/gateway/http_sse/dependencies.py +149 -114
- solace_agent_mesh/gateway/http_sse/main.py +68 -450
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +19 -1
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
- 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 +26 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +114 -6
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +13 -0
- 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/prompt_model.py +159 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +8 -2
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -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/session_repository.py +177 -11
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +86 -2
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +38 -7
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +256 -58
- solace_agent_mesh/gateway/http_sse/routers/auth.py +168 -134
- solace_agent_mesh/gateway/http_sse/routers/config.py +302 -8
- solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +14 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +5 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +133 -2
- solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +768 -0
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +167 -7
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +131 -8
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +670 -18
- solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +92 -9
- solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
- solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +1 -1
- solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +361 -12
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
- solace_agent_mesh/gateway/http_sse/session_manager.py +15 -15
- solace_agent_mesh/gateway/http_sse/sse_manager.py +286 -166
- solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +41 -1
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/platform/__init__.py +29 -0
- solace_agent_mesh/services/platform/alembic/env.py +85 -0
- solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
- solace_agent_mesh/services/platform/alembic.ini +109 -0
- solace_agent_mesh/services/platform/api/__init__.py +3 -0
- solace_agent_mesh/services/platform/api/dependencies.py +154 -0
- solace_agent_mesh/services/platform/api/main.py +314 -0
- solace_agent_mesh/services/platform/api/middleware.py +51 -0
- solace_agent_mesh/services/platform/api/routers/__init__.py +33 -0
- solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
- solace_agent_mesh/services/platform/app.py +215 -0
- solace_agent_mesh/services/platform/component.py +777 -0
- solace_agent_mesh/shared/__init__.py +14 -0
- solace_agent_mesh/shared/api/__init__.py +42 -0
- solace_agent_mesh/shared/auth/__init__.py +26 -0
- solace_agent_mesh/shared/auth/dependencies.py +204 -0
- solace_agent_mesh/shared/auth/middleware.py +347 -0
- solace_agent_mesh/shared/database/__init__.py +20 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/base_repository.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_exceptions.py +1 -1
- solace_agent_mesh/{gateway/http_sse/shared → shared/database}/database_helpers.py +1 -1
- solace_agent_mesh/shared/exceptions/__init__.py +36 -0
- solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exception_handlers.py +19 -5
- solace_agent_mesh/shared/utils/__init__.py +21 -0
- solace_agent_mesh/templates/logging_config_template.yaml +48 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +12 -1
- solace_agent_mesh/templates/platform.yaml +49 -0
- solace_agent_mesh/templates/plugin_readme_template.md +3 -25
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- solace_agent_mesh/templates/proxy_template.yaml +62 -0
- solace_agent_mesh/templates/webui.yaml +148 -6
- solace_agent_mesh/tools/web_search/__init__.py +18 -0
- solace_agent_mesh/tools/web_search/base.py +84 -0
- solace_agent_mesh/tools/web_search/google_search.py +247 -0
- solace_agent_mesh/tools/web_search/models.py +99 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +31 -12
- solace_agent_mesh-1.13.2.dist-info/RECORD +591 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
- solace_agent_mesh/agent/adk/adk_llm.txt +0 -232
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +0 -566
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +0 -171
- solace_agent_mesh/agent/adk/models/models_llm.txt +0 -142
- solace_agent_mesh/agent/agent_llm.txt +0 -378
- solace_agent_mesh/agent/agent_llm_detail.txt +0 -1702
- solace_agent_mesh/agent/protocol/protocol_llm.txt +0 -81
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +0 -92
- solace_agent_mesh/agent/sac/sac_llm.txt +0 -189
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +0 -200
- solace_agent_mesh/agent/testing/testing_llm.txt +0 -57
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
- solace_agent_mesh/agent/tools/tools_llm.txt +0 -263
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -274
- solace_agent_mesh/agent/utils/utils_llm.txt +0 -138
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.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/55b7b518.f2b1d1ba.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.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/6d84eae0.4a5fbf39.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.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/e6f9706b.e74a984d.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/ff4d71f2.15b02f97.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/cli/commands/add_cmd/add_cmd_llm.txt +0 -250
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +0 -365
- solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +0 -305
- solace_agent_mesh/client/webui/frontend/static/assets/client-CaY59VuC.js +0 -25
- 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/client/webui/frontend/static/assets/vendor-BEmvJSYz.js +0 -405
- solace_agent_mesh/common/a2a/a2a_llm.txt +0 -182
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -407
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -313
- solace_agent_mesh/common/common_llm.txt +0 -251
- solace_agent_mesh/common/common_llm_detail.txt +0 -2562
- solace_agent_mesh/common/middleware/middleware_llm.txt +0 -174
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +0 -185
- solace_agent_mesh/common/sac/sac_llm.txt +0 -71
- solace_agent_mesh/common/sac/sac_llm_detail.txt +0 -82
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +0 -104
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +0 -115
- solace_agent_mesh/common/services/providers/providers_llm.txt +0 -80
- solace_agent_mesh/common/services/services_llm.txt +0 -363
- solace_agent_mesh/common/services/services_llm_detail.txt +0 -459
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +0 -220
- solace_agent_mesh/common/utils/utils_llm.txt +0 -336
- solace_agent_mesh/common/utils/utils_llm_detail.txt +0 -572
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +0 -98
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-61038fc6.js +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-BWvk5-gF.js +0 -10
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +0 -1
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +0 -90
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +0 -101
- solace_agent_mesh/gateway/base/base_llm.txt +0 -224
- solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
- solace_agent_mesh/gateway/gateway_llm.txt +0 -373
- solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -295
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -155
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +0 -105
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +0 -299
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +0 -3278
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +0 -263
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -266
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -340
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -346
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -83
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -107
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -314
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -297
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -285
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +0 -47
- solace_agent_mesh/llm.txt +0 -228
- solace_agent_mesh/llm_detail.txt +0 -2835
- solace_agent_mesh/solace_agent_mesh_llm.txt +0 -362
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +0 -8599
- solace_agent_mesh/templates/logging_config_template.ini +0 -45
- solace_agent_mesh/templates/templates_llm.txt +0 -147
- solace_agent_mesh-1.6.1.dist-info/RECORD +0 -525
- /solace_agent_mesh/assets/docs/assets/js/{main.b12eac43.js.LICENSE.txt → main.d634009f.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/auth_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/pagination.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/api}/response_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/error_dto.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/exceptions}/exceptions.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/enums.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/timestamp_utils.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/types.py +0 -0
- /solace_agent_mesh/{gateway/http_sse/shared → shared/utils}/utils.py +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.6.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -6,8 +6,8 @@ from typing import List, Optional
|
|
|
6
6
|
|
|
7
7
|
from sqlalchemy.orm import Session as DBSession
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
|
|
10
|
+
from solace_agent_mesh.shared.utils.types import SessionId, UserId
|
|
11
11
|
from .entities import ChatTask
|
|
12
12
|
from .interfaces import IChatTaskRepository
|
|
13
13
|
from .models import ChatTaskModel
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project domain entity.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Project(BaseModel):
|
|
12
|
+
"""Project domain entity with business logic."""
|
|
13
|
+
|
|
14
|
+
id: str
|
|
15
|
+
name: str = Field(..., min_length=1, max_length=255)
|
|
16
|
+
user_id: str
|
|
17
|
+
description: Optional[str] = Field(None, max_length=1000)
|
|
18
|
+
system_prompt: Optional[str] = Field(None, max_length=4000)
|
|
19
|
+
default_agent_id: Optional[str] = None
|
|
20
|
+
created_at: int
|
|
21
|
+
updated_at: Optional[int] = None
|
|
22
|
+
deleted_at: Optional[int] = None
|
|
23
|
+
deleted_by: Optional[str] = None
|
|
24
|
+
|
|
25
|
+
def update_name(self, new_name: str) -> None:
|
|
26
|
+
"""Update project name with validation."""
|
|
27
|
+
if not new_name or len(new_name.strip()) == 0:
|
|
28
|
+
raise ValueError("Project name cannot be empty")
|
|
29
|
+
if len(new_name) > 255:
|
|
30
|
+
raise ValueError("Project name cannot exceed 255 characters")
|
|
31
|
+
|
|
32
|
+
self.name = new_name.strip()
|
|
33
|
+
self.updated_at = now_epoch_ms()
|
|
34
|
+
|
|
35
|
+
def update_description(self, new_description: Optional[str]) -> None:
|
|
36
|
+
"""Update project description with validation."""
|
|
37
|
+
if new_description is not None:
|
|
38
|
+
if len(new_description) > 1000:
|
|
39
|
+
raise ValueError("Project description cannot exceed 1000 characters")
|
|
40
|
+
self.description = new_description.strip() if new_description else None
|
|
41
|
+
else:
|
|
42
|
+
self.description = None
|
|
43
|
+
|
|
44
|
+
self.updated_at = now_epoch_ms()
|
|
45
|
+
|
|
46
|
+
def update_default_agent(self, agent_id: Optional[str]) -> None:
|
|
47
|
+
"""Update project default agent."""
|
|
48
|
+
self.default_agent_id = agent_id
|
|
49
|
+
self.updated_at = now_epoch_ms()
|
|
50
|
+
|
|
51
|
+
def soft_delete(self, user_id: str) -> None:
|
|
52
|
+
"""Soft delete the project."""
|
|
53
|
+
if not self.can_be_deleted_by_user(user_id):
|
|
54
|
+
raise ValueError("User does not have permission to delete this project")
|
|
55
|
+
|
|
56
|
+
self.deleted_at = now_epoch_ms()
|
|
57
|
+
self.deleted_by = user_id
|
|
58
|
+
self.updated_at = now_epoch_ms()
|
|
59
|
+
|
|
60
|
+
def is_deleted(self) -> bool:
|
|
61
|
+
"""Check if project is soft deleted."""
|
|
62
|
+
return self.deleted_at is not None
|
|
63
|
+
|
|
64
|
+
def can_be_accessed_by_user(self, user_id: str) -> bool:
|
|
65
|
+
"""Check if project can be accessed by the given user."""
|
|
66
|
+
# User projects are only accessible by their owner and not deleted
|
|
67
|
+
return self.user_id == user_id and not self.is_deleted()
|
|
68
|
+
|
|
69
|
+
def can_be_edited_by_user(self, user_id: str) -> bool:
|
|
70
|
+
"""Check if project can be edited by the given user."""
|
|
71
|
+
# Users can only edit their own projects that are not deleted
|
|
72
|
+
return self.user_id == user_id and not self.is_deleted()
|
|
73
|
+
|
|
74
|
+
def can_be_deleted_by_user(self, user_id: str) -> bool:
|
|
75
|
+
"""Check if project can be deleted by the given user."""
|
|
76
|
+
# Users can only delete their own projects that are not already deleted
|
|
77
|
+
return self.user_id == user_id and not self.is_deleted()
|
|
78
|
+
|
|
79
|
+
def mark_as_updated(self) -> None:
|
|
80
|
+
"""Mark project as updated."""
|
|
81
|
+
self.updated_at = now_epoch_ms()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project user access domain entity.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
from pydantic import BaseModel, Field
|
|
7
|
+
|
|
8
|
+
from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProjectUser(BaseModel):
|
|
12
|
+
"""
|
|
13
|
+
Project user access domain entity.
|
|
14
|
+
|
|
15
|
+
Represents a user's access to a project with a specific role.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
id: str
|
|
19
|
+
project_id: str
|
|
20
|
+
user_id: str
|
|
21
|
+
role: str = Field(..., pattern="^(owner|editor|viewer)$")
|
|
22
|
+
added_at: int
|
|
23
|
+
added_by_user_id: str
|
|
24
|
+
|
|
25
|
+
def can_edit_project(self) -> bool:
|
|
26
|
+
"""Check if this user can edit the project based on their role."""
|
|
27
|
+
return self.role in ["owner", "editor"]
|
|
28
|
+
|
|
29
|
+
def can_manage_users(self) -> bool:
|
|
30
|
+
"""Check if this user can manage other users' access to the project."""
|
|
31
|
+
return self.role == "owner"
|
|
32
|
+
|
|
33
|
+
def can_view_project(self) -> bool:
|
|
34
|
+
"""Check if this user can view the project."""
|
|
35
|
+
return self.role in ["owner", "editor", "viewer"]
|
|
36
|
+
|
|
37
|
+
def update_role(self, new_role: str) -> None:
|
|
38
|
+
"""Update the user's role with validation."""
|
|
39
|
+
valid_roles = ["owner", "editor", "viewer"]
|
|
40
|
+
if new_role not in valid_roles:
|
|
41
|
+
raise ValueError(f"Invalid role. Must be one of: {', '.join(valid_roles)}")
|
|
42
|
+
|
|
43
|
+
self.role = new_role
|
|
44
|
+
|
|
45
|
+
class Config:
|
|
46
|
+
"""Pydantic configuration."""
|
|
47
|
+
frozen = False
|
|
@@ -4,8 +4,8 @@ Session domain entity.
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel, ConfigDict
|
|
6
6
|
|
|
7
|
-
from
|
|
8
|
-
from
|
|
7
|
+
from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
|
|
8
|
+
from solace_agent_mesh.shared.utils.types import AgentId, SessionId, UserId
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Session(BaseModel):
|
|
@@ -17,8 +17,13 @@ class Session(BaseModel):
|
|
|
17
17
|
user_id: UserId
|
|
18
18
|
name: str | None = None
|
|
19
19
|
agent_id: AgentId | None = None
|
|
20
|
+
project_id: str | None = None
|
|
21
|
+
project_name: str | None = None
|
|
22
|
+
has_running_background_task: bool = False # Enriched field, not stored in DB
|
|
20
23
|
created_time: int
|
|
21
24
|
updated_time: int | None = None
|
|
25
|
+
deleted_at: int | None = None
|
|
26
|
+
deleted_by: str | None = None
|
|
22
27
|
|
|
23
28
|
def update_name(self, new_name: str) -> None:
|
|
24
29
|
"""Update session name with validation."""
|
|
@@ -34,10 +39,28 @@ class Session(BaseModel):
|
|
|
34
39
|
"""Mark session as having recent activity."""
|
|
35
40
|
self.updated_time = now_epoch_ms()
|
|
36
41
|
|
|
42
|
+
def soft_delete(self, user_id: UserId) -> None:
|
|
43
|
+
"""Soft delete the session."""
|
|
44
|
+
if not self.can_be_deleted_by_user(user_id):
|
|
45
|
+
raise ValueError("User does not have permission to delete this session")
|
|
46
|
+
|
|
47
|
+
self.deleted_at = now_epoch_ms()
|
|
48
|
+
self.deleted_by = user_id
|
|
49
|
+
self.updated_time = now_epoch_ms()
|
|
50
|
+
|
|
51
|
+
def is_deleted(self) -> bool:
|
|
52
|
+
"""Check if session is soft deleted."""
|
|
53
|
+
return self.deleted_at is not None
|
|
54
|
+
|
|
55
|
+
def move_to_project(self, new_project_id: str | None) -> None:
|
|
56
|
+
"""Move session to a different project."""
|
|
57
|
+
self.project_id = new_project_id
|
|
58
|
+
self.updated_time = now_epoch_ms()
|
|
59
|
+
|
|
37
60
|
def can_be_deleted_by_user(self, user_id: UserId) -> bool:
|
|
38
61
|
"""Check if user can delete this session."""
|
|
39
62
|
return self.user_id == user_id
|
|
40
63
|
|
|
41
64
|
def can_be_accessed_by_user(self, user_id: UserId) -> bool:
|
|
42
65
|
"""Check if user can access this session."""
|
|
43
|
-
return self.user_id == user_id
|
|
66
|
+
return self.user_id == user_id and not self.is_deleted()
|
|
@@ -10,6 +10,7 @@ class Task(BaseModel):
|
|
|
10
10
|
|
|
11
11
|
id: str
|
|
12
12
|
user_id: str
|
|
13
|
+
parent_task_id: str | None = None
|
|
13
14
|
start_time: int
|
|
14
15
|
end_time: int | None = None
|
|
15
16
|
status: str | None = None
|
|
@@ -20,6 +21,12 @@ class Task(BaseModel):
|
|
|
20
21
|
total_output_tokens: int | None = None
|
|
21
22
|
total_cached_input_tokens: int | None = None
|
|
22
23
|
token_usage_details: dict | None = None
|
|
24
|
+
|
|
25
|
+
# Background task execution fields
|
|
26
|
+
execution_mode: str | None = "foreground"
|
|
27
|
+
last_activity_time: int | None = None
|
|
28
|
+
background_execution_enabled: bool | None = False
|
|
29
|
+
max_execution_time_ms: int | None = None
|
|
23
30
|
|
|
24
31
|
class Config:
|
|
25
32
|
from_attributes = True
|
|
@@ -4,6 +4,8 @@ Feedback repository implementation using SQLAlchemy.
|
|
|
4
4
|
|
|
5
5
|
from sqlalchemy.orm import Session as DBSession
|
|
6
6
|
|
|
7
|
+
from solace_agent_mesh.shared.api.pagination import PaginationParams
|
|
8
|
+
from solace_agent_mesh.shared.utils.types import UserId
|
|
7
9
|
from .entities import Feedback
|
|
8
10
|
from .interfaces import IFeedbackRepository
|
|
9
11
|
from .models import FeedbackModel
|
|
@@ -28,6 +30,51 @@ class FeedbackRepository(IFeedbackRepository):
|
|
|
28
30
|
session.refresh(model)
|
|
29
31
|
return self._model_to_entity(model)
|
|
30
32
|
|
|
33
|
+
def search(
|
|
34
|
+
self,
|
|
35
|
+
session: DBSession,
|
|
36
|
+
user_id: UserId,
|
|
37
|
+
start_date: int | None = None,
|
|
38
|
+
end_date: int | None = None,
|
|
39
|
+
task_id: str | None = None,
|
|
40
|
+
session_id: str | None = None,
|
|
41
|
+
rating: str | None = None,
|
|
42
|
+
pagination: PaginationParams | None = None,
|
|
43
|
+
) -> list[Feedback]:
|
|
44
|
+
"""
|
|
45
|
+
Search feedback with flexible filtering.
|
|
46
|
+
All filters are optional and can be combined.
|
|
47
|
+
"""
|
|
48
|
+
query = session.query(FeedbackModel)
|
|
49
|
+
|
|
50
|
+
# User filter (unless admin querying all users)
|
|
51
|
+
if user_id != "*":
|
|
52
|
+
query = query.filter(FeedbackModel.user_id == user_id)
|
|
53
|
+
|
|
54
|
+
# Time-based filters
|
|
55
|
+
if start_date:
|
|
56
|
+
query = query.filter(FeedbackModel.created_time >= start_date)
|
|
57
|
+
if end_date:
|
|
58
|
+
query = query.filter(FeedbackModel.created_time <= end_date)
|
|
59
|
+
|
|
60
|
+
# Resource-based filters
|
|
61
|
+
if task_id:
|
|
62
|
+
query = query.filter(FeedbackModel.task_id == task_id)
|
|
63
|
+
if session_id:
|
|
64
|
+
query = query.filter(FeedbackModel.session_id == session_id)
|
|
65
|
+
if rating:
|
|
66
|
+
query = query.filter(FeedbackModel.rating == rating)
|
|
67
|
+
|
|
68
|
+
# Order by most recent first
|
|
69
|
+
query = query.order_by(FeedbackModel.created_time.desc())
|
|
70
|
+
|
|
71
|
+
# Apply pagination
|
|
72
|
+
if pagination:
|
|
73
|
+
query = query.offset(pagination.offset).limit(pagination.page_size)
|
|
74
|
+
|
|
75
|
+
models = query.all()
|
|
76
|
+
return [self._model_to_entity(model) for model in models]
|
|
77
|
+
|
|
31
78
|
def delete_feedback_older_than(self, session: DBSession, cutoff_time_ms: int, batch_size: int) -> int:
|
|
32
79
|
"""
|
|
33
80
|
Delete feedback records older than the cutoff time.
|
|
@@ -6,9 +6,11 @@ from abc import ABC, abstractmethod
|
|
|
6
6
|
from typing import TYPE_CHECKING, Optional
|
|
7
7
|
from sqlalchemy.orm import Session as DBSession
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from
|
|
9
|
+
from solace_agent_mesh.shared.api.pagination import PaginationParams
|
|
10
|
+
from solace_agent_mesh.shared.utils.types import SessionId, UserId
|
|
11
11
|
from .entities import Feedback, Session, Task, TaskEvent
|
|
12
|
+
from .entities.project import Project
|
|
13
|
+
from ..routers.dto.requests.project_requests import ProjectFilter
|
|
12
14
|
|
|
13
15
|
if TYPE_CHECKING:
|
|
14
16
|
from .entities import ChatTask
|
|
@@ -19,14 +21,14 @@ class ISessionRepository(ABC):
|
|
|
19
21
|
|
|
20
22
|
@abstractmethod
|
|
21
23
|
def find_by_user(
|
|
22
|
-
self, session: DBSession, user_id: UserId, pagination: PaginationParams | None = None
|
|
24
|
+
self, session: DBSession, user_id: UserId, pagination: PaginationParams | None = None, project_id: str | None = None
|
|
23
25
|
) -> list[Session]:
|
|
24
|
-
"""Find all sessions for a specific user."""
|
|
26
|
+
"""Find all sessions for a specific user, optionally filtered by project."""
|
|
25
27
|
pass
|
|
26
28
|
|
|
27
29
|
@abstractmethod
|
|
28
|
-
def count_by_user(self, session: DBSession, user_id: UserId) -> int:
|
|
29
|
-
"""Count total sessions for a specific user."""
|
|
30
|
+
def count_by_user(self, session: DBSession, user_id: UserId, project_id: str | None = None) -> int:
|
|
31
|
+
"""Count total sessions for a specific user, optionally filtered by project."""
|
|
30
32
|
pass
|
|
31
33
|
|
|
32
34
|
@abstractmethod
|
|
@@ -46,6 +48,41 @@ class ISessionRepository(ABC):
|
|
|
46
48
|
"""Delete a session belonging to a user."""
|
|
47
49
|
pass
|
|
48
50
|
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def soft_delete(self, session: DBSession, session_id: SessionId, user_id: UserId) -> bool:
|
|
53
|
+
"""Soft delete a session belonging to a user."""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
@abstractmethod
|
|
57
|
+
def move_to_project(
|
|
58
|
+
self, session: DBSession, session_id: SessionId, user_id: UserId, new_project_id: str | None
|
|
59
|
+
) -> Session | None:
|
|
60
|
+
"""Move a session to a different project."""
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
@abstractmethod
|
|
64
|
+
def search(
|
|
65
|
+
self,
|
|
66
|
+
session: DBSession,
|
|
67
|
+
user_id: UserId,
|
|
68
|
+
query: str,
|
|
69
|
+
pagination: PaginationParams | None = None,
|
|
70
|
+
project_id: str | None = None
|
|
71
|
+
) -> list[Session]:
|
|
72
|
+
"""Search sessions by name or content."""
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
@abstractmethod
|
|
76
|
+
def count_search_results(
|
|
77
|
+
self,
|
|
78
|
+
session: DBSession,
|
|
79
|
+
user_id: UserId,
|
|
80
|
+
query: str,
|
|
81
|
+
project_id: str | None = None
|
|
82
|
+
) -> int:
|
|
83
|
+
"""Count search results for pagination."""
|
|
84
|
+
pass
|
|
85
|
+
|
|
49
86
|
|
|
50
87
|
class ITaskRepository(ABC):
|
|
51
88
|
"""Interface for task data access operations."""
|
|
@@ -99,6 +136,37 @@ class IFeedbackRepository(ABC):
|
|
|
99
136
|
"""Save feedback."""
|
|
100
137
|
pass
|
|
101
138
|
|
|
139
|
+
@abstractmethod
|
|
140
|
+
def search(
|
|
141
|
+
self,
|
|
142
|
+
session: DBSession,
|
|
143
|
+
user_id: UserId,
|
|
144
|
+
start_date: int | None = None,
|
|
145
|
+
end_date: int | None = None,
|
|
146
|
+
task_id: str | None = None,
|
|
147
|
+
session_id: str | None = None,
|
|
148
|
+
rating: str | None = None,
|
|
149
|
+
pagination: PaginationParams | None = None,
|
|
150
|
+
) -> list[Feedback]:
|
|
151
|
+
"""
|
|
152
|
+
Search feedback with flexible filtering.
|
|
153
|
+
All filters are optional and can be combined.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
session: Database session
|
|
157
|
+
user_id: User ID to filter by, or "*" for all users (admin)
|
|
158
|
+
start_date: Start of date range in epoch milliseconds
|
|
159
|
+
end_date: End of date range in epoch milliseconds
|
|
160
|
+
task_id: Filter by specific task ID
|
|
161
|
+
session_id: Filter by specific session ID
|
|
162
|
+
rating: Filter by rating type ("up" or "down")
|
|
163
|
+
pagination: Pagination parameters
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
List of feedback entries matching the filters
|
|
167
|
+
"""
|
|
168
|
+
pass
|
|
169
|
+
|
|
102
170
|
@abstractmethod
|
|
103
171
|
def delete_feedback_older_than(self, session: DBSession, cutoff_time_ms: int, batch_size: int) -> int:
|
|
104
172
|
"""Delete feedback older than cutoff time using batch deletion."""
|
|
@@ -129,3 +197,43 @@ class IChatTaskRepository(ABC):
|
|
|
129
197
|
def delete_by_session(self, session: DBSession, session_id: SessionId) -> bool:
|
|
130
198
|
"""Delete all tasks for a session."""
|
|
131
199
|
pass
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class IProjectRepository(ABC):
|
|
203
|
+
"""Interface for project repository operations."""
|
|
204
|
+
|
|
205
|
+
@abstractmethod
|
|
206
|
+
def create_project(self, name: str, user_id: str, description: Optional[str] = None,
|
|
207
|
+
system_prompt: Optional[str] = None) -> Project:
|
|
208
|
+
"""Create a new user project."""
|
|
209
|
+
pass
|
|
210
|
+
|
|
211
|
+
@abstractmethod
|
|
212
|
+
def get_user_projects(self, user_id: str) -> list[Project]:
|
|
213
|
+
"""Get all projects owned by a specific user."""
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
@abstractmethod
|
|
217
|
+
def get_filtered_projects(self, project_filter: ProjectFilter) -> list[Project]:
|
|
218
|
+
"""Get projects based on filter criteria."""
|
|
219
|
+
pass
|
|
220
|
+
|
|
221
|
+
@abstractmethod
|
|
222
|
+
def get_by_id(self, project_id: str, user_id: str) -> Optional[Project]:
|
|
223
|
+
"""Get a project by its ID, ensuring user access."""
|
|
224
|
+
pass
|
|
225
|
+
|
|
226
|
+
@abstractmethod
|
|
227
|
+
def update(self, project_id: str, user_id: str, update_data: dict) -> Optional[Project]:
|
|
228
|
+
"""Update a project with the given data, ensuring user access."""
|
|
229
|
+
pass
|
|
230
|
+
|
|
231
|
+
@abstractmethod
|
|
232
|
+
def delete(self, project_id: str, user_id: str) -> bool:
|
|
233
|
+
"""Delete a project by its ID, ensuring user access."""
|
|
234
|
+
pass
|
|
235
|
+
|
|
236
|
+
@abstractmethod
|
|
237
|
+
def soft_delete(self, project_id: str, user_id: str) -> bool:
|
|
238
|
+
"""Soft delete a project by its ID, ensuring user access."""
|
|
239
|
+
pass
|
|
@@ -5,17 +5,30 @@ SQLAlchemy models and Pydantic models for database persistence.
|
|
|
5
5
|
from .base import Base
|
|
6
6
|
from .chat_task_model import ChatTaskModel
|
|
7
7
|
from .feedback_model import FeedbackModel
|
|
8
|
+
from .project_model import ProjectModel, CreateProjectModel, UpdateProjectModel
|
|
9
|
+
from .project_user_model import ProjectUserModel, CreateProjectUserModel, UpdateProjectUserModel
|
|
8
10
|
from .session_model import SessionModel, CreateSessionModel, UpdateSessionModel
|
|
9
11
|
from .task_event_model import TaskEventModel
|
|
10
12
|
from .task_model import TaskModel
|
|
13
|
+
from .prompt_model import PromptGroupModel, PromptModel, PromptGroupUserModel
|
|
11
14
|
|
|
12
15
|
__all__ = [
|
|
13
16
|
"Base",
|
|
14
17
|
"ChatTaskModel",
|
|
18
|
+
"FeedbackModel",
|
|
19
|
+
"ProjectModel",
|
|
20
|
+
"ProjectUserModel",
|
|
15
21
|
"SessionModel",
|
|
22
|
+
"CreateProjectModel",
|
|
23
|
+
"UpdateProjectModel",
|
|
24
|
+
"CreateProjectUserModel",
|
|
25
|
+
"UpdateProjectUserModel",
|
|
16
26
|
"CreateSessionModel",
|
|
17
27
|
"UpdateSessionModel",
|
|
18
28
|
"TaskEventModel",
|
|
19
29
|
"TaskModel",
|
|
20
30
|
"FeedbackModel",
|
|
31
|
+
"PromptGroupModel",
|
|
32
|
+
"PromptModel",
|
|
33
|
+
"PromptGroupUserModel",
|
|
21
34
|
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SQLAlchemy model for project data.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from sqlalchemy import Column, String, Boolean, BigInteger, Text
|
|
6
|
+
from sqlalchemy.orm import relationship
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from .base import Base
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProjectModel(Base):
|
|
13
|
+
"""SQLAlchemy model for projects."""
|
|
14
|
+
|
|
15
|
+
__tablename__ = "projects"
|
|
16
|
+
|
|
17
|
+
id = Column(String, primary_key=True)
|
|
18
|
+
name = Column(String, nullable=False)
|
|
19
|
+
user_id = Column(String, nullable=False)
|
|
20
|
+
description = Column(Text, nullable=True)
|
|
21
|
+
system_prompt = Column(Text, nullable=True)
|
|
22
|
+
default_agent_id = Column(String, nullable=True)
|
|
23
|
+
created_at = Column(BigInteger, nullable=False)
|
|
24
|
+
updated_at = Column(BigInteger, nullable=True)
|
|
25
|
+
deleted_at = Column(BigInteger, nullable=True)
|
|
26
|
+
deleted_by = Column(String, nullable=True)
|
|
27
|
+
|
|
28
|
+
# Relationships
|
|
29
|
+
sessions = relationship("SessionModel", back_populates="project")
|
|
30
|
+
project_users = relationship("ProjectUserModel", back_populates="project", cascade="all, delete-orphan")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CreateProjectModel(BaseModel):
|
|
34
|
+
"""Pydantic model for creating a project."""
|
|
35
|
+
id: str
|
|
36
|
+
name: str
|
|
37
|
+
user_id: str | None = None
|
|
38
|
+
description: str | None = None
|
|
39
|
+
system_prompt: str | None = None
|
|
40
|
+
default_agent_id: str | None = None
|
|
41
|
+
created_at: int
|
|
42
|
+
updated_at: int | None = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class UpdateProjectModel(BaseModel):
|
|
46
|
+
"""Pydantic model for updating a project."""
|
|
47
|
+
name: str | None = None
|
|
48
|
+
description: str | None = None
|
|
49
|
+
system_prompt: str | None = None
|
|
50
|
+
default_agent_id: str | None = None
|
|
51
|
+
updated_at: int
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SQLAlchemy model for project user access (junction table).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from enum import Enum
|
|
6
|
+
from sqlalchemy import Column, String, BigInteger, ForeignKey, UniqueConstraint, Enum as SQLEnum
|
|
7
|
+
from sqlalchemy.orm import relationship
|
|
8
|
+
from pydantic import BaseModel, field_validator
|
|
9
|
+
from typing import Literal
|
|
10
|
+
|
|
11
|
+
from .base import Base
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ProjectRole(str, Enum):
|
|
15
|
+
"""Valid roles for project users."""
|
|
16
|
+
OWNER = "owner"
|
|
17
|
+
EDITOR = "editor"
|
|
18
|
+
VIEWER = "viewer"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ProjectUserModel(Base):
|
|
22
|
+
"""
|
|
23
|
+
SQLAlchemy model for project user access.
|
|
24
|
+
|
|
25
|
+
This junction table tracks which users have access to which projects,
|
|
26
|
+
enabling multi-user collaboration on projects.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
__tablename__ = "project_users"
|
|
30
|
+
|
|
31
|
+
id = Column(String, primary_key=True)
|
|
32
|
+
project_id = Column(String, ForeignKey("projects.id", ondelete="CASCADE"), nullable=False)
|
|
33
|
+
user_id = Column(String, nullable=False)
|
|
34
|
+
role = Column(SQLEnum(ProjectRole), nullable=False, default=ProjectRole.VIEWER)
|
|
35
|
+
added_at = Column(BigInteger, nullable=False) # Epoch timestamp in milliseconds
|
|
36
|
+
added_by_user_id = Column(String, nullable=False) # User who granted access
|
|
37
|
+
|
|
38
|
+
# Ensure a user can only be added once per project
|
|
39
|
+
__table_args__ = (
|
|
40
|
+
UniqueConstraint('project_id', 'user_id', name='uq_project_user'),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
# Relationships
|
|
44
|
+
project = relationship("ProjectModel", back_populates="project_users")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class CreateProjectUserModel(BaseModel):
|
|
48
|
+
"""Pydantic model for creating a project user access record."""
|
|
49
|
+
id: str
|
|
50
|
+
project_id: str
|
|
51
|
+
user_id: str
|
|
52
|
+
role: Literal["owner", "editor", "viewer"] = "viewer"
|
|
53
|
+
added_at: int
|
|
54
|
+
added_by_user_id: str
|
|
55
|
+
|
|
56
|
+
@field_validator('role')
|
|
57
|
+
@classmethod
|
|
58
|
+
def validate_role(cls, v: str) -> str:
|
|
59
|
+
"""Validate that role is one of the allowed values."""
|
|
60
|
+
if v not in [role.value for role in ProjectRole]:
|
|
61
|
+
raise ValueError(f"Role must be one of: {', '.join([role.value for role in ProjectRole])}")
|
|
62
|
+
return v
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class UpdateProjectUserModel(BaseModel):
|
|
66
|
+
"""Pydantic model for updating a project user access record."""
|
|
67
|
+
role: Literal["owner", "editor", "viewer"] | None = None
|
|
68
|
+
|
|
69
|
+
@field_validator('role')
|
|
70
|
+
@classmethod
|
|
71
|
+
def validate_role(cls, v: str | None) -> str | None:
|
|
72
|
+
"""Validate that role is one of the allowed values."""
|
|
73
|
+
if v is not None and v not in [role.value for role in ProjectRole]:
|
|
74
|
+
raise ValueError(f"Role must be one of: {', '.join([role.value for role in ProjectRole])}")
|
|
75
|
+
return v
|