solace-agent-mesh 1.4.12__py3-none-any.whl → 1.5.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 +3 -4
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +1 -1
- solace_agent_mesh/agent/adk/callbacks.py +56 -5
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +3 -1
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +2 -1
- solace_agent_mesh/agent/adk/mcp_content_processor.py +2 -1
- solace_agent_mesh/agent/adk/models/lite_llm.py +1 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +1 -2
- solace_agent_mesh/agent/adk/runner.py +3 -1
- solace_agent_mesh/agent/adk/services.py +4 -1
- solace_agent_mesh/agent/adk/setup.py +3 -1
- solace_agent_mesh/agent/adk/tool_wrapper.py +2 -2
- solace_agent_mesh/agent/agent_llm.txt +1 -1
- solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +4 -14
- solace_agent_mesh/agent/protocol/protocol_llm.txt +15 -2
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
- solace_agent_mesh/agent/sac/app.py +3 -1
- solace_agent_mesh/agent/sac/component.py +55 -22
- solace_agent_mesh/agent/sac/sac_llm.txt +15 -1
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +73 -0
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
- solace_agent_mesh/agent/tools/audio_tools.py +2 -1
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +3 -1
- solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +3 -1
- solace_agent_mesh/agent/tools/dynamic_tool.py +2 -1
- solace_agent_mesh/agent/tools/general_agent_tools.py +2 -1
- solace_agent_mesh/agent/tools/image_tools.py +2 -1
- solace_agent_mesh/agent/tools/peer_agent_tool.py +2 -1
- solace_agent_mesh/agent/tools/registry.py +3 -1
- solace_agent_mesh/agent/tools/test_tools.py +2 -1
- solace_agent_mesh/agent/tools/tools_llm.txt +148 -154
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +274 -0
- solace_agent_mesh/agent/tools/web_tools.py +2 -1
- solace_agent_mesh/agent/utils/artifact_helpers.py +3 -1
- solace_agent_mesh/agent/utils/config_parser.py +3 -1
- solace_agent_mesh/agent/utils/utils_llm.txt +1 -1
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/{b7006a3a.73a79653.js → 032c2d61.f3d37824.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.932dd2db.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{2334.622a6395.js → 2334.1cf50a20.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/240a0364.7eac6021.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{3624.b524e433.js → 3624.0eaa1fd0.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/3a6c6137.f5940cfa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.76654dd9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2be20244.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/509e993c.4c7a1a6d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2cbb060a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.e49689dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.a8b1ef8b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6a520c9d.ba015d81.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.39d5851d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.804d6567.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/77cf947d.64c9bd6c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8024126c.56e59919.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.07034dd9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.139a1a1f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js → 8591.5d015485.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/{8731.49e930c2.js → 8731.6c1dbf0c.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.b5ddb7a1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9bb13469.dd1c9b54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.dd810042.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.3e6dd091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad71b5ed.60668e9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.9d369087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db924877.cbc66f02.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.0aa9630a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.d590bc9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.139b4b9c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.2b916f9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.582a78ca.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.cf6d6522.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5766a13d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.9c0297a6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.bd3c34f3.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.18dc45dd.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +143 -0
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/artifact-management/index.html +7 -7
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/audio-tools/index.html +7 -7
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/data-analysis-tools/index.html +8 -8
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/embeds/index.html +6 -6
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → components}/builtin-tools/index.html +11 -11
- solace_agent_mesh/assets/docs/docs/documentation/{concepts → components}/cli/index.html +25 -25
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +91 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +104 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +57 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +59 -0
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-agents/index.html +113 -152
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/create-gateways/index.html +9 -9
- solace_agent_mesh/assets/docs/docs/documentation/{user-guide → developing}/creating-python-tools/index.html +12 -12
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +32 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/bedrock-agents/index.html +25 -25
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/custom-agent/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/event-mesh-gateway/index.html +11 -11
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mcp-integration/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/mongodb-integration/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rag-integration/index.html +13 -13
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/rest-gateway/index.html +10 -10
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/{tutorials → developing/tutorials}/sql-database/index.html +14 -14
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +33 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +83 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +222 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +161 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +53 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +35 -100
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
- solace_agent_mesh/assets/docs/docs/documentation/{getting-started → installing-and-configuring}/configurations/index.html +56 -50
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +76 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +63 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
- solace_agent_mesh/assets/docs/docs/documentation/{Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html → migrations/a2a-upgrade/a2a-technical-migration-map/index.html} +10 -11
- solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1760121512891.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1760121512891.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-j1LW-wlq.js → authCallback-DwrxZE0E.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-B9p_nFNA.js → client-DarGQzyw.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-2nd1gbaH.js +339 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-DoKXctCM.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-CS5YMf8a.js → vendor-BKIeiHj_.js} +80 -70
- 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 +1 -1
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
- solace_agent_mesh/common/a2a/artifact.py +2 -1
- solace_agent_mesh/common/a2a/protocol.py +3 -2
- solace_agent_mesh/common/a2a/translation.py +3 -1
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +1 -1
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +23 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +93 -15
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +23 -0
- solace_agent_mesh/common/common_llm.txt +24 -39
- solace_agent_mesh/common/common_llm_detail.txt +2562 -0
- solace_agent_mesh/common/data_parts.py +9 -1
- solace_agent_mesh/common/middleware/config_resolver.py +3 -1
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
- solace_agent_mesh/common/middleware/registry.py +3 -1
- solace_agent_mesh/common/sac/sac_llm.txt +1 -1
- solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
- solace_agent_mesh/common/sac/sam_component_base.py +2 -1
- solace_agent_mesh/common/sam_events/event_service.py +3 -2
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
- solace_agent_mesh/common/services/employee_service.py +3 -1
- solace_agent_mesh/common/services/identity_service.py +2 -1
- solace_agent_mesh/common/services/providers/local_file_identity_service.py +2 -1
- solace_agent_mesh/common/services/services_llm.txt +57 -6
- solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
- solace_agent_mesh/common/utils/artifact_utils.py +3 -1
- solace_agent_mesh/common/utils/asyncio_macos_fix.py +3 -1
- solace_agent_mesh/common/utils/embeds/converter.py +3 -1
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +1 -1
- solace_agent_mesh/common/utils/embeds/evaluators.py +2 -1
- solace_agent_mesh/common/utils/embeds/modifiers.py +3 -2
- solace_agent_mesh/common/utils/embeds/resolver.py +2 -1
- solace_agent_mesh/common/utils/initializer.py +3 -1
- solace_agent_mesh/common/utils/message_utils.py +2 -1
- solace_agent_mesh/common/utils/push_notification_auth.py +3 -2
- solace_agent_mesh/common/utils/utils_llm.txt +75 -87
- solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
- solace_agent_mesh/core_a2a/service.py +2 -2
- solace_agent_mesh/gateway/base/app.py +3 -2
- solace_agent_mesh/gateway/base/base_llm.txt +1 -1
- solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
- solace_agent_mesh/gateway/base/component.py +3 -1
- solace_agent_mesh/gateway/base/task_context.py +2 -1
- solace_agent_mesh/gateway/gateway_llm.txt +242 -235
- solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +295 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +10 -1
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +155 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +1 -1
- solace_agent_mesh/gateway/http_sse/app.py +150 -3
- solace_agent_mesh/gateway/http_sse/component.py +372 -61
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +46 -6
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +4 -2
- solace_agent_mesh/gateway/http_sse/dependencies.py +119 -27
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +172 -172
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
- solace_agent_mesh/gateway/http_sse/main.py +149 -42
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +3 -12
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +103 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +263 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -16
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +73 -18
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +9 -5
- solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
- solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +266 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +3 -3
- solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +32 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +340 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +4 -53
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +173 -0
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/auth.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/config.py +29 -6
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +346 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +83 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +2 -10
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +5 -3
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +107 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +1 -15
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +37 -0
- solace_agent_mesh/gateway/http_sse/routers/people.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +255 -204
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +223 -41
- solace_agent_mesh/gateway/http_sse/routers/sse.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +170 -43
- solace_agent_mesh/gateway/http_sse/routers/users.py +3 -1
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +2 -1
- solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +3 -1
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +273 -0
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +242 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +2 -82
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +177 -13
- solace_agent_mesh/gateway/http_sse/services/session_service.py +154 -85
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +318 -0
- solace_agent_mesh/gateway/http_sse/services/task_service.py +3 -2
- solace_agent_mesh/gateway/http_sse/session_manager.py +2 -1
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +25 -14
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +285 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +7 -0
- solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +2 -1
- solace_agent_mesh/gateway/http_sse/sse_manager.py +2 -2
- solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +32 -0
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +1 -1
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -0
- solace_agent_mesh/templates/gateway_app_template.py +4 -2
- solace_agent_mesh/templates/gateway_component_template.py +3 -1
- solace_agent_mesh/templates/logging_config_template.ini +22 -45
- solace_agent_mesh/templates/plugin_tools_template.py +2 -2
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/METADATA +2 -2
- solace_agent_mesh-1.5.1.dist-info/RECORD +504 -0
- solace_agent_mesh/agent/adk/invocation_monitor.py +0 -295
- solace_agent_mesh/assets/docs/assets/images/sac-flows-80d5b603c6aafd33e87945680ce0abf3.png +0 -0
- solace_agent_mesh/assets/docs/assets/images/sac_parts_of_a_component-cb3d0424b1d0c17734c5435cca6b4082.png +0 -0
- solace_agent_mesh/assets/docs/assets/js/04989206.a248f00c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/0e682baa.d54b8668.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1023fc19.8a8a9309.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1523c6b4.2645ef68.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/166ab619.e27886d9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.e056b7e0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/21ceee5f.3bf39250.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/2a9cab12.2afaee76.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/332e10b5.f7629851.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3d406171.5560fdf9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.508ae8db.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/442a8107.b5c2532a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/453a82a6.3c6bb61d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/483cef9a.4736f2d8.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/4c2787c2.c1290a40.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55f47984.bcd00a86.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5b4258a4.fdfd2325.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/664b740a.ba305a89.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/75384d09.c19e8b51.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/768e31b0.9abcdc48.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/85387663.be2bc838.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/945fb41e.16e00776.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9a09e75d.92de8cf5.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9eff14a2.d62aad71.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a12a4955.25fbed32.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/a3a92b25.af35e313.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.4ddf32f2.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ae0e903d.5fe5203f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ae4415af.16cc58d3.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/bac0be12.17de4316.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c2c06897.87cb1f47.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c835a94d.ce21f0bf.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cc969b05.feef7dcc.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cd3d4052.a19e7d78.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ced92a13.fb92e7ca.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cee5d587.47904f5e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/d6a81ee7.829198f1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.ed8dd236.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f897a61a.126663fe.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/fbfa3e75.e144b16c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.f67fc9f4.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.40527046.js +0 -1
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +0 -46
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/rbac-setup-guilde/index.html +0 -201
- solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +0 -25
- solace_agent_mesh/assets/docs/docs/documentation/Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html +0 -105
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +0 -144
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +0 -91
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +0 -91
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +0 -55
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +0 -111
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +0 -77
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +0 -48
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +0 -54
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +0 -45
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/litellm_models/index.html +0 -49
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +0 -76
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +0 -73
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +0 -72
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +0 -54
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +0 -69
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +0 -59
- solace_agent_mesh/assets/docs/lunr-index-1759936913198.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1759936913198.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ChRwcV89.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-DnnE01OM.js +0 -339
- solace_agent_mesh/gateway/http_sse/repository/entities/message.py +0 -41
- solace_agent_mesh/gateway/http_sse/repository/message_repository.py +0 -84
- solace_agent_mesh/gateway/http_sse/repository/models/message_model.py +0 -45
- solace_agent_mesh-1.4.12.dist-info/RECORD +0 -448
- /solace_agent_mesh/assets/docs/assets/js/{8591.d7c16be6.js.LICENSE.txt → 8591.5d015485.js.LICENSE.txt} +0 -0
- /solace_agent_mesh/assets/docs/assets/js/{main.f67fc9f4.js.LICENSE.txt → main.bd3c34f3.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.4.12.dist-info → solace_agent_mesh-1.5.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
API Router for submitting and managing tasks to agents.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import logging
|
|
6
|
+
import yaml
|
|
7
|
+
from datetime import datetime
|
|
5
8
|
from fastapi import (
|
|
6
9
|
APIRouter,
|
|
7
10
|
Depends,
|
|
8
11
|
HTTPException,
|
|
9
12
|
Request as FastAPIRequest,
|
|
13
|
+
Response,
|
|
10
14
|
status,
|
|
11
15
|
)
|
|
12
|
-
from
|
|
16
|
+
from fastapi.exceptions import RequestValidationError
|
|
17
|
+
from typing import List, Optional, Union
|
|
13
18
|
|
|
14
|
-
from solace_ai_connector.common.log import log
|
|
15
19
|
|
|
16
20
|
from ....gateway.http_sse.session_manager import SessionManager
|
|
17
21
|
from ....gateway.http_sse.services.task_service import TaskService
|
|
18
22
|
from ....gateway.http_sse.services.session_service import SessionService
|
|
23
|
+
from ....gateway.http_sse.repository.interfaces import ITaskRepository
|
|
24
|
+
from ....gateway.http_sse.repository.entities import Task
|
|
25
|
+
from ....gateway.http_sse.shared.types import PaginationParams, UserId
|
|
26
|
+
from ..utils.stim_utils import create_stim_from_task_data
|
|
19
27
|
|
|
20
28
|
from a2a.types import (
|
|
21
29
|
CancelTaskRequest,
|
|
@@ -31,7 +39,12 @@ from ....gateway.http_sse.dependencies import (
|
|
|
31
39
|
get_sac_component,
|
|
32
40
|
get_task_service,
|
|
33
41
|
get_session_business_service,
|
|
42
|
+
get_task_repository,
|
|
43
|
+
get_user_id,
|
|
44
|
+
get_user_config,
|
|
45
|
+
get_session_business_service,
|
|
34
46
|
)
|
|
47
|
+
from ....gateway.http_sse.services.session_service import SessionService
|
|
35
48
|
|
|
36
49
|
from typing import TYPE_CHECKING
|
|
37
50
|
|
|
@@ -40,6 +53,7 @@ if TYPE_CHECKING:
|
|
|
40
53
|
|
|
41
54
|
router = APIRouter()
|
|
42
55
|
|
|
56
|
+
log = logging.getLogger(__name__)
|
|
43
57
|
|
|
44
58
|
async def _submit_task(
|
|
45
59
|
request: FastAPIRequest,
|
|
@@ -58,7 +72,7 @@ async def _submit_task(
|
|
|
58
72
|
|
|
59
73
|
if not agent_name:
|
|
60
74
|
raise HTTPException(
|
|
61
|
-
status_code=status.
|
|
75
|
+
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
62
76
|
detail="Missing 'agent_name' in request payload message metadata.",
|
|
63
77
|
)
|
|
64
78
|
|
|
@@ -120,10 +134,14 @@ async def _submit_task(
|
|
|
120
134
|
session_id=session_id,
|
|
121
135
|
)
|
|
122
136
|
db.commit()
|
|
123
|
-
log.info(
|
|
137
|
+
log.info(
|
|
138
|
+
"%sCreated session in database: %s", log_prefix, session_id
|
|
139
|
+
)
|
|
124
140
|
except Exception as e:
|
|
125
141
|
db.rollback()
|
|
126
|
-
log.warning(
|
|
142
|
+
log.warning(
|
|
143
|
+
"%sFailed to create session in database: %s", log_prefix, e
|
|
144
|
+
)
|
|
127
145
|
finally:
|
|
128
146
|
db.close()
|
|
129
147
|
|
|
@@ -131,43 +149,6 @@ async def _submit_task(
|
|
|
131
149
|
"%sUsing ClientID: %s, SessionID: %s", log_prefix, client_id, session_id
|
|
132
150
|
)
|
|
133
151
|
|
|
134
|
-
# Store message in persistence layer if available
|
|
135
|
-
if is_streaming and SessionLocal is not None and session_service is not None:
|
|
136
|
-
db = SessionLocal()
|
|
137
|
-
try:
|
|
138
|
-
from ....gateway.http_sse.shared.enums import SenderType
|
|
139
|
-
|
|
140
|
-
message_text = ""
|
|
141
|
-
if payload.params and payload.params.message:
|
|
142
|
-
parts = a2a.get_parts_from_message(payload.params.message)
|
|
143
|
-
for part in parts:
|
|
144
|
-
if hasattr(part, "text"):
|
|
145
|
-
message_text = part.text
|
|
146
|
-
break
|
|
147
|
-
|
|
148
|
-
session_service.add_message_to_session(
|
|
149
|
-
db=db,
|
|
150
|
-
session_id=session_id,
|
|
151
|
-
user_id=user_id,
|
|
152
|
-
message=message_text or "Task submitted",
|
|
153
|
-
sender_type=SenderType.USER,
|
|
154
|
-
sender_name=user_id or "user",
|
|
155
|
-
agent_id=agent_name,
|
|
156
|
-
)
|
|
157
|
-
db.commit()
|
|
158
|
-
except Exception as e:
|
|
159
|
-
db.rollback()
|
|
160
|
-
log.error(
|
|
161
|
-
"%sFailed to store message in session service: %s", log_prefix, e
|
|
162
|
-
)
|
|
163
|
-
finally:
|
|
164
|
-
db.close()
|
|
165
|
-
else:
|
|
166
|
-
log.debug(
|
|
167
|
-
"%sNo persistence available or non-streaming - skipping message storage",
|
|
168
|
-
log_prefix,
|
|
169
|
-
)
|
|
170
|
-
|
|
171
152
|
# Use the helper to get the unwrapped parts from the incoming message.
|
|
172
153
|
a2a_parts = a2a.get_parts_from_message(payload.params.message)
|
|
173
154
|
|
|
@@ -222,6 +203,146 @@ async def _submit_task(
|
|
|
222
203
|
)
|
|
223
204
|
|
|
224
205
|
|
|
206
|
+
@router.get("/tasks", response_model=List[Task], tags=["Tasks"])
|
|
207
|
+
async def search_tasks(
|
|
208
|
+
request: FastAPIRequest,
|
|
209
|
+
start_date: Optional[str] = None,
|
|
210
|
+
end_date: Optional[str] = None,
|
|
211
|
+
search: Optional[str] = None,
|
|
212
|
+
page: int = 1,
|
|
213
|
+
page_size: int = 20,
|
|
214
|
+
query_user_id: Optional[str] = None,
|
|
215
|
+
user_id: UserId = Depends(get_user_id),
|
|
216
|
+
user_config: dict = Depends(get_user_config),
|
|
217
|
+
repo: ITaskRepository = Depends(get_task_repository),
|
|
218
|
+
):
|
|
219
|
+
"""
|
|
220
|
+
Lists and searches for historical tasks.
|
|
221
|
+
- Regular users can only search their own tasks.
|
|
222
|
+
- Users with the 'tasks:read:all' scope can search for any user's tasks by providing `query_user_id`.
|
|
223
|
+
"""
|
|
224
|
+
log_prefix = f"[GET /api/v1/tasks] "
|
|
225
|
+
log.info("%sRequest from user %s", log_prefix, user_id)
|
|
226
|
+
|
|
227
|
+
target_user_id = user_id
|
|
228
|
+
can_query_all = user_config.get("scopes", {}).get("tasks:read:all", False)
|
|
229
|
+
|
|
230
|
+
if query_user_id:
|
|
231
|
+
if can_query_all:
|
|
232
|
+
target_user_id = query_user_id
|
|
233
|
+
log.info(
|
|
234
|
+
"%sAdmin user %s is querying for user %s",
|
|
235
|
+
log_prefix,
|
|
236
|
+
user_id,
|
|
237
|
+
target_user_id,
|
|
238
|
+
)
|
|
239
|
+
else:
|
|
240
|
+
raise HTTPException(
|
|
241
|
+
status_code=status.HTTP_403_FORBIDDEN,
|
|
242
|
+
detail="You do not have permission to query for other users' tasks.",
|
|
243
|
+
)
|
|
244
|
+
elif can_query_all:
|
|
245
|
+
target_user_id = "*"
|
|
246
|
+
log.info("%sAdmin user %s is querying for all users.", log_prefix, user_id)
|
|
247
|
+
|
|
248
|
+
start_time_ms = None
|
|
249
|
+
if start_date:
|
|
250
|
+
try:
|
|
251
|
+
start_time_ms = int(datetime.fromisoformat(start_date).timestamp() * 1000)
|
|
252
|
+
except ValueError:
|
|
253
|
+
raise HTTPException(
|
|
254
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
255
|
+
detail="Invalid start_date format. Use ISO 8601 format.",
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
end_time_ms = None
|
|
259
|
+
if end_date:
|
|
260
|
+
try:
|
|
261
|
+
end_time_ms = int(datetime.fromisoformat(end_date).timestamp() * 1000)
|
|
262
|
+
except ValueError:
|
|
263
|
+
raise HTTPException(
|
|
264
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
265
|
+
detail="Invalid end_date format. Use ISO 8601 format.",
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
pagination = PaginationParams(page=page, page_size=page_size)
|
|
269
|
+
|
|
270
|
+
try:
|
|
271
|
+
tasks = repo.search(
|
|
272
|
+
user_id=target_user_id,
|
|
273
|
+
start_date=start_time_ms,
|
|
274
|
+
end_date=end_time_ms,
|
|
275
|
+
search_query=search,
|
|
276
|
+
pagination=pagination,
|
|
277
|
+
)
|
|
278
|
+
return tasks
|
|
279
|
+
except Exception as e:
|
|
280
|
+
log.exception("%sError searching for tasks: %s", log_prefix, e)
|
|
281
|
+
raise HTTPException(
|
|
282
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
283
|
+
detail="An error occurred while searching for tasks.",
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@router.get("/tasks/{task_id}", tags=["Tasks"])
|
|
288
|
+
async def get_task_as_stim_file(
|
|
289
|
+
task_id: str,
|
|
290
|
+
request: FastAPIRequest,
|
|
291
|
+
user_id: UserId = Depends(get_user_id),
|
|
292
|
+
user_config: dict = Depends(get_user_config),
|
|
293
|
+
repo: ITaskRepository = Depends(get_task_repository),
|
|
294
|
+
):
|
|
295
|
+
"""
|
|
296
|
+
Retrieves the complete event history for a single task and returns it as a `.stim` file.
|
|
297
|
+
"""
|
|
298
|
+
log_prefix = f"[GET /api/v1/tasks/{task_id}] "
|
|
299
|
+
log.info("%sRequest from user %s", log_prefix, user_id)
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
result = repo.find_by_id_with_events(task_id)
|
|
303
|
+
if not result:
|
|
304
|
+
raise HTTPException(
|
|
305
|
+
status_code=status.HTTP_404_NOT_FOUND,
|
|
306
|
+
detail=f"Task with ID '{task_id}' not found.",
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
task, events = result
|
|
310
|
+
|
|
311
|
+
can_read_all = user_config.get("scopes", {}).get("tasks:read:all", False)
|
|
312
|
+
if task.user_id != user_id and not can_read_all:
|
|
313
|
+
raise HTTPException(
|
|
314
|
+
status_code=status.HTTP_403_FORBIDDEN,
|
|
315
|
+
detail="You do not have permission to view this task.",
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
# Format into .stim structure
|
|
319
|
+
stim_data = create_stim_from_task_data(task, events)
|
|
320
|
+
|
|
321
|
+
yaml_content = yaml.dump(
|
|
322
|
+
stim_data,
|
|
323
|
+
sort_keys=False,
|
|
324
|
+
allow_unicode=True,
|
|
325
|
+
indent=2,
|
|
326
|
+
default_flow_style=False,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
return Response(
|
|
330
|
+
content=yaml_content,
|
|
331
|
+
media_type="application/x-yaml",
|
|
332
|
+
headers={"Content-Disposition": f'attachment; filename="{task_id}.stim"'},
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
except HTTPException:
|
|
336
|
+
# Re-raise HTTPExceptions (404, 403, etc.) without modification
|
|
337
|
+
raise
|
|
338
|
+
except Exception as e:
|
|
339
|
+
log.exception("%sError retrieving task: %s", log_prefix, e)
|
|
340
|
+
raise HTTPException(
|
|
341
|
+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
342
|
+
detail="An error occurred while retrieving the task.",
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
|
|
225
346
|
@router.post("/message:send", response_model=SendMessageSuccessResponse)
|
|
226
347
|
async def send_task_to_agent(
|
|
227
348
|
request: FastAPIRequest,
|
|
@@ -278,6 +399,7 @@ async def cancel_agent_task(
|
|
|
278
399
|
"""
|
|
279
400
|
Sends a cancellation request for a specific task to the specified agent.
|
|
280
401
|
Returns 202 Accepted, as cancellation is asynchronous.
|
|
402
|
+
Returns 404 if the task context is not found.
|
|
281
403
|
"""
|
|
282
404
|
log_prefix = f"[POST /api/v1/tasks/{taskId}:cancel] "
|
|
283
405
|
log.info("%sReceived cancellation request.", log_prefix)
|
|
@@ -290,6 +412,11 @@ async def cancel_agent_task(
|
|
|
290
412
|
|
|
291
413
|
context = component.task_context_manager.get_context(taskId)
|
|
292
414
|
if not context:
|
|
415
|
+
log.warning(
|
|
416
|
+
"%sNo active task context found for task ID: %s",
|
|
417
|
+
log_prefix,
|
|
418
|
+
taskId,
|
|
419
|
+
)
|
|
293
420
|
raise HTTPException(
|
|
294
421
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
295
422
|
detail=f"No active task context found for task ID: {taskId}",
|
|
@@ -328,4 +455,4 @@ async def cancel_agent_task(
|
|
|
328
455
|
raise HTTPException(
|
|
329
456
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
330
457
|
detail=error_resp.model_dump(exclude_none=True),
|
|
331
|
-
)
|
|
458
|
+
)
|
|
@@ -3,13 +3,15 @@ Router for user-related endpoints.
|
|
|
3
3
|
Maintains backward compatibility with original API format.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
import logging
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
8
9
|
from fastapi import APIRouter, Depends
|
|
9
|
-
from solace_ai_connector.common.log import log
|
|
10
10
|
|
|
11
11
|
from ..shared.auth_utils import get_current_user
|
|
12
12
|
|
|
13
|
+
log = logging.getLogger(__name__)
|
|
14
|
+
|
|
13
15
|
router = APIRouter()
|
|
14
16
|
|
|
15
17
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
API Router for managing A2A message visualization streams.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import logging
|
|
5
6
|
import asyncio
|
|
6
7
|
import uuid
|
|
7
8
|
from fastapi import (
|
|
@@ -15,7 +16,6 @@ from fastapi import (
|
|
|
15
16
|
from pydantic import BaseModel, Field
|
|
16
17
|
from typing import List, Optional, Dict, Any, Set
|
|
17
18
|
|
|
18
|
-
from solace_ai_connector.common.log import log
|
|
19
19
|
|
|
20
20
|
from ....gateway.http_sse.dependencies import (
|
|
21
21
|
get_sac_component,
|
|
@@ -30,6 +30,7 @@ from typing import TYPE_CHECKING
|
|
|
30
30
|
if TYPE_CHECKING:
|
|
31
31
|
from ....gateway.http_sse.component import WebUIBackendComponent
|
|
32
32
|
|
|
33
|
+
log = logging.getLogger(__name__)
|
|
33
34
|
|
|
34
35
|
router = APIRouter()
|
|
35
36
|
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Service for managing automatic cleanup of old data based on retention policies.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import time
|
|
7
|
+
from typing import Any, Callable, Dict
|
|
8
|
+
|
|
9
|
+
from sqlalchemy.orm import Session as DBSession
|
|
10
|
+
|
|
11
|
+
from ..repository.feedback_repository import FeedbackRepository
|
|
12
|
+
from ..repository.task_repository import TaskRepository
|
|
13
|
+
from ..shared import now_epoch_ms
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
class DataRetentionService:
|
|
18
|
+
"""
|
|
19
|
+
Service for automatically cleaning up old tasks, task events, and feedback
|
|
20
|
+
based on configurable retention policies.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Validation constants
|
|
24
|
+
MIN_RETENTION_DAYS = 1
|
|
25
|
+
MIN_CLEANUP_INTERVAL_HOURS = 1
|
|
26
|
+
MIN_BATCH_SIZE = 1
|
|
27
|
+
MAX_BATCH_SIZE = 10000
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self, session_factory: Callable[[], DBSession] | None, config: Dict[str, Any]
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initialize the DataRetentionService.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
session_factory: Factory function to create database sessions
|
|
37
|
+
config: Configuration dictionary with retention settings
|
|
38
|
+
"""
|
|
39
|
+
self.session_factory = session_factory
|
|
40
|
+
self.config = config
|
|
41
|
+
self.log_identifier = "[DataRetentionService]"
|
|
42
|
+
|
|
43
|
+
# Validate and store configuration
|
|
44
|
+
self._validate_config()
|
|
45
|
+
|
|
46
|
+
log.info(
|
|
47
|
+
"%s Initialized with task_retention=%d days, feedback_retention=%d days, "
|
|
48
|
+
"cleanup_interval=%d hours, batch_size=%d",
|
|
49
|
+
self.log_identifier,
|
|
50
|
+
self.config.get("task_retention_days"),
|
|
51
|
+
self.config.get("feedback_retention_days"),
|
|
52
|
+
self.config.get("cleanup_interval_hours"),
|
|
53
|
+
self.config.get("batch_size"),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def _validate_config(self) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Validates configuration values and applies safe defaults if needed.
|
|
59
|
+
Logs warnings for invalid values.
|
|
60
|
+
"""
|
|
61
|
+
# Validate task retention days
|
|
62
|
+
task_retention = self.config.get("task_retention_days", 90)
|
|
63
|
+
if task_retention < self.MIN_RETENTION_DAYS:
|
|
64
|
+
log.warning(
|
|
65
|
+
"%s task_retention_days (%d) is below minimum (%d days). Using minimum.",
|
|
66
|
+
self.log_identifier,
|
|
67
|
+
task_retention,
|
|
68
|
+
self.MIN_RETENTION_DAYS,
|
|
69
|
+
)
|
|
70
|
+
self.config["task_retention_days"] = self.MIN_RETENTION_DAYS
|
|
71
|
+
else:
|
|
72
|
+
self.config["task_retention_days"] = task_retention
|
|
73
|
+
|
|
74
|
+
# Validate feedback retention days
|
|
75
|
+
feedback_retention = self.config.get("feedback_retention_days", 90)
|
|
76
|
+
if feedback_retention < self.MIN_RETENTION_DAYS:
|
|
77
|
+
log.warning(
|
|
78
|
+
"%s feedback_retention_days (%d) is below minimum (%d days). Using minimum.",
|
|
79
|
+
self.log_identifier,
|
|
80
|
+
feedback_retention,
|
|
81
|
+
self.MIN_RETENTION_DAYS,
|
|
82
|
+
)
|
|
83
|
+
self.config["feedback_retention_days"] = self.MIN_RETENTION_DAYS
|
|
84
|
+
else:
|
|
85
|
+
self.config["feedback_retention_days"] = feedback_retention
|
|
86
|
+
|
|
87
|
+
# Validate cleanup interval
|
|
88
|
+
cleanup_interval = self.config.get("cleanup_interval_hours", 24)
|
|
89
|
+
if cleanup_interval < self.MIN_CLEANUP_INTERVAL_HOURS:
|
|
90
|
+
log.warning(
|
|
91
|
+
"%s cleanup_interval_hours (%d) is below minimum (%d hours). Using minimum.",
|
|
92
|
+
self.log_identifier,
|
|
93
|
+
cleanup_interval,
|
|
94
|
+
self.MIN_CLEANUP_INTERVAL_HOURS,
|
|
95
|
+
)
|
|
96
|
+
self.config["cleanup_interval_hours"] = self.MIN_CLEANUP_INTERVAL_HOURS
|
|
97
|
+
else:
|
|
98
|
+
self.config["cleanup_interval_hours"] = cleanup_interval
|
|
99
|
+
|
|
100
|
+
# Validate batch size
|
|
101
|
+
batch_size = self.config.get("batch_size", 1000)
|
|
102
|
+
if batch_size < self.MIN_BATCH_SIZE:
|
|
103
|
+
log.warning(
|
|
104
|
+
"%s batch_size (%d) is below minimum (%d). Using minimum.",
|
|
105
|
+
self.log_identifier,
|
|
106
|
+
batch_size,
|
|
107
|
+
self.MIN_BATCH_SIZE,
|
|
108
|
+
)
|
|
109
|
+
self.config["batch_size"] = self.MIN_BATCH_SIZE
|
|
110
|
+
elif batch_size > self.MAX_BATCH_SIZE:
|
|
111
|
+
log.warning(
|
|
112
|
+
"%s batch_size (%d) exceeds maximum (%d). Using maximum.",
|
|
113
|
+
self.log_identifier,
|
|
114
|
+
batch_size,
|
|
115
|
+
self.MAX_BATCH_SIZE,
|
|
116
|
+
)
|
|
117
|
+
self.config["batch_size"] = self.MAX_BATCH_SIZE
|
|
118
|
+
else:
|
|
119
|
+
self.config["batch_size"] = batch_size
|
|
120
|
+
|
|
121
|
+
def cleanup_old_data(self) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Main orchestration method for cleaning up old data.
|
|
124
|
+
Calls cleanup methods for tasks and feedback.
|
|
125
|
+
"""
|
|
126
|
+
if not self.config.get("enabled", True):
|
|
127
|
+
log.warning(
|
|
128
|
+
"%s Data retention cleanup is disabled via configuration.",
|
|
129
|
+
self.log_identifier,
|
|
130
|
+
)
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
if not self.session_factory:
|
|
134
|
+
log.warning(
|
|
135
|
+
"%s No database session factory available. Skipping cleanup.",
|
|
136
|
+
self.log_identifier,
|
|
137
|
+
)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
log.info("%s Starting data retention cleanup...", self.log_identifier)
|
|
141
|
+
start_time = time.time()
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
# Cleanup old tasks
|
|
145
|
+
task_retention_days = self.config.get("task_retention_days")
|
|
146
|
+
tasks_deleted = self._cleanup_old_tasks(task_retention_days)
|
|
147
|
+
|
|
148
|
+
# Cleanup old feedback
|
|
149
|
+
feedback_retention_days = self.config.get("feedback_retention_days")
|
|
150
|
+
feedback_deleted = self._cleanup_old_feedback(feedback_retention_days)
|
|
151
|
+
|
|
152
|
+
elapsed_time = time.time() - start_time
|
|
153
|
+
log.info(
|
|
154
|
+
"%s Cleanup completed. Tasks deleted: %d, Feedback deleted: %d, Time taken: %.2f seconds",
|
|
155
|
+
self.log_identifier,
|
|
156
|
+
tasks_deleted,
|
|
157
|
+
feedback_deleted,
|
|
158
|
+
elapsed_time,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
except Exception as e:
|
|
162
|
+
log.error(
|
|
163
|
+
"%s Error during data retention cleanup: %s",
|
|
164
|
+
self.log_identifier,
|
|
165
|
+
e,
|
|
166
|
+
exc_info=True,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def _cleanup_old_tasks(self, retention_days: int) -> int:
|
|
170
|
+
"""
|
|
171
|
+
Deletes tasks (and their events via cascade) older than the retention period.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
retention_days: Number of days to retain tasks
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Total number of tasks deleted
|
|
178
|
+
"""
|
|
179
|
+
log.info(
|
|
180
|
+
"%s Cleaning up tasks older than %d days...",
|
|
181
|
+
self.log_identifier,
|
|
182
|
+
retention_days,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# Calculate cutoff time in milliseconds
|
|
186
|
+
cutoff_time_ms = now_epoch_ms() - (retention_days * 24 * 60 * 60 * 1000)
|
|
187
|
+
batch_size = self.config.get("batch_size")
|
|
188
|
+
|
|
189
|
+
db = self.session_factory()
|
|
190
|
+
try:
|
|
191
|
+
repo = TaskRepository(db)
|
|
192
|
+
total_deleted = repo.delete_tasks_older_than(cutoff_time_ms, batch_size)
|
|
193
|
+
|
|
194
|
+
if total_deleted == 0:
|
|
195
|
+
log.info(
|
|
196
|
+
"%s No tasks found older than %d days.",
|
|
197
|
+
self.log_identifier,
|
|
198
|
+
retention_days,
|
|
199
|
+
)
|
|
200
|
+
else:
|
|
201
|
+
log.info(
|
|
202
|
+
"%s Deleted %d tasks older than %d days.",
|
|
203
|
+
self.log_identifier,
|
|
204
|
+
total_deleted,
|
|
205
|
+
retention_days,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return total_deleted
|
|
209
|
+
|
|
210
|
+
except Exception as e:
|
|
211
|
+
log.error(
|
|
212
|
+
"%s Error cleaning up old tasks: %s",
|
|
213
|
+
self.log_identifier,
|
|
214
|
+
e,
|
|
215
|
+
exc_info=True,
|
|
216
|
+
)
|
|
217
|
+
db.rollback()
|
|
218
|
+
return 0
|
|
219
|
+
finally:
|
|
220
|
+
db.close()
|
|
221
|
+
|
|
222
|
+
def _cleanup_old_feedback(self, retention_days: int) -> int:
|
|
223
|
+
"""
|
|
224
|
+
Deletes feedback records older than the retention period.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
retention_days: Number of days to retain feedback
|
|
228
|
+
|
|
229
|
+
Returns:
|
|
230
|
+
Total number of feedback records deleted
|
|
231
|
+
"""
|
|
232
|
+
log.info(
|
|
233
|
+
"%s Cleaning up feedback older than %d days...",
|
|
234
|
+
self.log_identifier,
|
|
235
|
+
retention_days,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
# Calculate cutoff time in milliseconds
|
|
239
|
+
cutoff_time_ms = now_epoch_ms() - (retention_days * 24 * 60 * 60 * 1000)
|
|
240
|
+
batch_size = self.config.get("batch_size")
|
|
241
|
+
|
|
242
|
+
db = self.session_factory()
|
|
243
|
+
try:
|
|
244
|
+
repo = FeedbackRepository(db)
|
|
245
|
+
total_deleted = repo.delete_feedback_older_than(cutoff_time_ms, batch_size)
|
|
246
|
+
|
|
247
|
+
if total_deleted == 0:
|
|
248
|
+
log.info(
|
|
249
|
+
"%s No feedback found older than %d days.",
|
|
250
|
+
self.log_identifier,
|
|
251
|
+
retention_days,
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
log.info(
|
|
255
|
+
"%s Deleted %d feedback records older than %d days.",
|
|
256
|
+
self.log_identifier,
|
|
257
|
+
total_deleted,
|
|
258
|
+
retention_days,
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
return total_deleted
|
|
262
|
+
|
|
263
|
+
except Exception as e:
|
|
264
|
+
log.error(
|
|
265
|
+
"%s Error cleaning up old feedback: %s",
|
|
266
|
+
self.log_identifier,
|
|
267
|
+
e,
|
|
268
|
+
exc_info=True,
|
|
269
|
+
)
|
|
270
|
+
db.rollback()
|
|
271
|
+
return 0
|
|
272
|
+
finally:
|
|
273
|
+
db.close()
|