solace-agent-mesh 1.7.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/artifacts/filesystem_artifact_service.py +164 -0
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +163 -0
- solace_agent_mesh/agent/adk/callbacks.py +752 -127
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +99 -7
- 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 +34 -16
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +24 -137
- solace_agent_mesh/agent/adk/runner.py +66 -8
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +41 -1
- solace_agent_mesh/agent/adk/setup.py +220 -32
- solace_agent_mesh/agent/adk/stream_parser.py +229 -40
- solace_agent_mesh/agent/protocol/event_handlers.py +219 -33
- 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/component.py +188 -22
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +3 -1
- solace_agent_mesh/agent/sac/app.py +37 -12
- solace_agent_mesh/agent/sac/component.py +322 -52
- solace_agent_mesh/agent/sac/patch_adk.py +8 -16
- solace_agent_mesh/agent/sac/task_execution_context.py +90 -0
- 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 +698 -24
- solace_agent_mesh/agent/tools/deep_research_tools.py +2161 -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 +54 -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 +243 -5
- 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/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/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.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/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/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/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/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 +75 -75
- 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 +98 -112
- 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 -28
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +29 -29
- 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 +67 -53
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +17 -17
- 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 +87 -87
- 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 +50 -23
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +29 -24
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +21 -21
- 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 +96 -66
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +181 -181
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +75 -75
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +27 -27
- 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 -38
- 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 +135 -114
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +37 -37
- 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 +112 -112
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +28 -28
- 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/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-tcIFZLis.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-CINwxvwV.js → vendor-CGk8Suyh.js} +189 -94
- 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/types.py +1 -1
- solace_agent_mesh/common/agent_registry.py +38 -11
- solace_agent_mesh/common/data_parts.py +124 -0
- 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 +73 -1
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/common/utils/embeds/converter.py +1 -8
- solace_agent_mesh/common/utils/embeds/modifiers.py +2 -27
- solace_agent_mesh/common/utils/embeds/resolver.py +94 -25
- solace_agent_mesh/common/utils/embeds/types.py +1 -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/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/base.py +28 -1
- solace_agent_mesh/gateway/adapter/types.py +9 -0
- solace_agent_mesh/gateway/base/app.py +10 -0
- solace_agent_mesh/gateway/base/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +451 -10
- solace_agent_mesh/gateway/generic/component.py +274 -30
- solace_agent_mesh/gateway/http_sse/alembic/env.py +0 -7
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +2 -43
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +2 -2
- 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 +23 -6
- solace_agent_mesh/gateway/http_sse/component.py +158 -73
- solace_agent_mesh/gateway/http_sse/dependencies.py +50 -57
- solace_agent_mesh/gateway/http_sse/main.py +58 -482
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +3 -2
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +2 -2
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +5 -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 +1 -1
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +8 -1
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +12 -107
- 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 +113 -7
- solace_agent_mesh/gateway/http_sse/routers/auth.py +69 -132
- solace_agent_mesh/gateway/http_sse/routers/config.py +235 -10
- 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/session_requests.py +1 -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 +1 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/people.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/projects.py +250 -24
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1416 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +14 -5
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +117 -4
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +509 -149
- 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 +2 -1
- 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 +539 -12
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +198 -21
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +354 -4
- solace_agent_mesh/gateway/http_sse/sse_manager.py +280 -169
- 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 +1 -1
- 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.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/METADATA +29 -8
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/RECORD +334 -313
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/WHEEL +1 -1
- solace_agent_mesh/agent/adk/adk_llm.txt +0 -226
- 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 -189
- solace_agent_mesh/agent/agent_llm.txt +0 -369
- 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/proxies/a2a/a2a_llm.txt +0 -190
- solace_agent_mesh/agent/proxies/base/base_llm.txt +0 -148
- solace_agent_mesh/agent/proxies/proxies_llm.txt +0 -283
- 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 -58
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +0 -68
- solace_agent_mesh/agent/tools/tools_llm.txt +0 -276
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +0 -275
- solace_agent_mesh/agent/utils/utils_llm.txt +0 -152
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +0 -149
- solace_agent_mesh/assets/docs/assets/js/05749d90.c70b2be9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.92fea363.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/15e40e79.36003774.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/240a0364.c39f8388.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.e4870a49.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.b63ee53a.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/55b7b518.f2b1d1ba.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.45b32c2b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/66d4869e.830d443f.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.4a5fbf39.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.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.09ed9234.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.245ae0ef.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.eaff365e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.f902fad8.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e04b235d.c9c50c7b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.d11c67a7.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.045d0fa1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5099c51e.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.f213fe0c.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9606d6a.js +0 -1
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +0 -47
- solace_agent_mesh/assets/docs/lunr-index-1762283454666.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1762283454666.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-CRYdKo2Q.js +0 -25
- solace_agent_mesh/client/webui/frontend/static/assets/main-CojeY_1w.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-ILja9MCG.js +0 -353
- solace_agent_mesh/common/a2a/a2a_llm.txt +0 -175
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +0 -193
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +0 -445
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +0 -736
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +0 -330
- solace_agent_mesh/common/common_llm.txt +0 -230
- 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 -81
- solace_agent_mesh/common/services/services_llm.txt +0 -368
- 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 -335
- 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 -226
- solace_agent_mesh/gateway/base/base_llm_detail.txt +0 -235
- solace_agent_mesh/gateway/gateway_llm.txt +0 -369
- solace_agent_mesh/gateway/gateway_llm_detail.txt +0 -3885
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +0 -345
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_fulltext_search_indexes.py +0 -92
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +0 -161
- 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 -221
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +0 -257
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +0 -308
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +0 -450
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +0 -133
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +0 -123
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +0 -312
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +0 -303
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +0 -146
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +0 -319
- 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/assets/docs/assets/js/{main.f213fe0c.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.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.7.1.dist-info → solace_agent_mesh-1.13.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,7 @@ Service for logging A2A tasks and events to the database.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import copy
|
|
6
|
+
import json
|
|
6
7
|
import logging
|
|
7
8
|
import uuid
|
|
8
9
|
from typing import Any, Callable, Dict, Union
|
|
@@ -20,7 +21,7 @@ from sqlalchemy.orm import Session as DBSession
|
|
|
20
21
|
from ....common import a2a
|
|
21
22
|
from ..repository.entities import Task, TaskEvent
|
|
22
23
|
from ..repository.task_repository import TaskRepository
|
|
23
|
-
from
|
|
24
|
+
from solace_agent_mesh.shared.utils.timestamp_utils import now_epoch_ms
|
|
24
25
|
|
|
25
26
|
log = logging.getLogger(__name__)
|
|
26
27
|
|
|
@@ -97,33 +98,83 @@ class TaskLoggerService:
|
|
|
97
98
|
# Check for existing task or create a new one
|
|
98
99
|
task = repo.find_by_id(db, task_id)
|
|
99
100
|
if not task:
|
|
101
|
+
# Extract parent_task_id and background execution metadata
|
|
102
|
+
parent_task_id = None
|
|
103
|
+
background_execution_enabled = False
|
|
104
|
+
max_execution_time_ms = None
|
|
105
|
+
|
|
106
|
+
log.info(
|
|
107
|
+
f"{self.log_identifier} Creating new task {task_id}: direction={direction}, "
|
|
108
|
+
f"parsed_event_type={type(parsed_event).__name__}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if direction == "request" and isinstance(parsed_event, A2ARequest):
|
|
112
|
+
message = a2a.get_message_from_send_request(parsed_event)
|
|
113
|
+
log.info(f"{self.log_identifier} Message extracted: {message is not None}")
|
|
114
|
+
|
|
115
|
+
if message:
|
|
116
|
+
log.info(f"{self.log_identifier} Message metadata: {message.metadata}")
|
|
117
|
+
|
|
118
|
+
if message.metadata:
|
|
119
|
+
parent_task_id = message.metadata.get("parentTaskId")
|
|
120
|
+
background_execution_enabled = message.metadata.get("backgroundExecutionEnabled", False)
|
|
121
|
+
# Default to 1 hour (3600000ms) if background execution is enabled but no timeout specified
|
|
122
|
+
max_execution_time_ms = message.metadata.get("maxExecutionTimeMs")
|
|
123
|
+
if background_execution_enabled and max_execution_time_ms is None:
|
|
124
|
+
max_execution_time_ms = 3600000 # 1 hour default
|
|
125
|
+
else:
|
|
126
|
+
log.warning(
|
|
127
|
+
f"{self.log_identifier} Message has no metadata for task {task_id}"
|
|
128
|
+
)
|
|
129
|
+
else:
|
|
130
|
+
log.warning(
|
|
131
|
+
f"{self.log_identifier} Could not extract message from request for task {task_id}"
|
|
132
|
+
)
|
|
133
|
+
|
|
100
134
|
if direction == "request":
|
|
101
135
|
initial_text = self._extract_initial_text(parsed_event)
|
|
136
|
+
current_time = now_epoch_ms()
|
|
102
137
|
new_task = Task(
|
|
103
138
|
id=task_id,
|
|
104
139
|
user_id=user_id or "unknown",
|
|
105
|
-
|
|
140
|
+
parent_task_id=parent_task_id,
|
|
141
|
+
start_time=current_time,
|
|
106
142
|
initial_request_text=(
|
|
107
143
|
initial_text[:1024] if initial_text else None
|
|
108
144
|
), # Truncate
|
|
145
|
+
execution_mode="background" if background_execution_enabled else "foreground",
|
|
146
|
+
last_activity_time=current_time,
|
|
147
|
+
background_execution_enabled=background_execution_enabled,
|
|
148
|
+
max_execution_time_ms=max_execution_time_ms,
|
|
109
149
|
)
|
|
110
150
|
repo.save_task(db, new_task)
|
|
111
151
|
log.info(
|
|
112
152
|
f"{self.log_identifier} Created new task record for ID: {task_id}"
|
|
153
|
+
+ (f" with parent: {parent_task_id}" if parent_task_id else "")
|
|
154
|
+
+ (f" (background execution enabled)" if background_execution_enabled else "")
|
|
113
155
|
)
|
|
114
156
|
else:
|
|
115
157
|
# We received an event for a task we haven't seen the start of.
|
|
116
158
|
# This can happen if the logger starts mid-conversation. Create a placeholder.
|
|
159
|
+
current_time = now_epoch_ms()
|
|
117
160
|
placeholder_task = Task(
|
|
118
161
|
id=task_id,
|
|
119
162
|
user_id=user_id or "unknown",
|
|
120
|
-
|
|
163
|
+
parent_task_id=parent_task_id,
|
|
164
|
+
start_time=current_time,
|
|
121
165
|
initial_request_text="[Task started before logger was active]",
|
|
166
|
+
execution_mode="foreground",
|
|
167
|
+
last_activity_time=current_time,
|
|
168
|
+
background_execution_enabled=False,
|
|
122
169
|
)
|
|
123
170
|
repo.save_task(db, placeholder_task)
|
|
124
171
|
log.info(
|
|
125
172
|
f"{self.log_identifier} Created placeholder task record for ID: {task_id}"
|
|
126
173
|
)
|
|
174
|
+
else:
|
|
175
|
+
# Update last activity time for existing task
|
|
176
|
+
task.last_activity_time = now_epoch_ms()
|
|
177
|
+
repo.save_task(db, task)
|
|
127
178
|
|
|
128
179
|
# Create and save the event using the sanitized raw payload
|
|
129
180
|
task_event = TaskEvent(
|
|
@@ -142,8 +193,10 @@ class TaskLoggerService:
|
|
|
142
193
|
if final_status:
|
|
143
194
|
task_to_update = repo.find_by_id(db, task_id)
|
|
144
195
|
if task_to_update:
|
|
145
|
-
|
|
196
|
+
current_time = now_epoch_ms()
|
|
197
|
+
task_to_update.end_time = current_time
|
|
146
198
|
task_to_update.status = final_status
|
|
199
|
+
task_to_update.last_activity_time = current_time
|
|
147
200
|
|
|
148
201
|
# Extract and store token usage if present
|
|
149
202
|
if isinstance(parsed_event, A2ATask) and parsed_event.metadata:
|
|
@@ -164,6 +217,21 @@ class TaskLoggerService:
|
|
|
164
217
|
log.info(
|
|
165
218
|
f"{self.log_identifier} Finalized task record for ID: {task_id} with status: {final_status}"
|
|
166
219
|
)
|
|
220
|
+
|
|
221
|
+
# For background tasks, save chat messages when task completes
|
|
222
|
+
# Only save for top-level tasks (no parent_task_id) to avoid duplicates
|
|
223
|
+
# Sub-tasks (delegated by orchestrator) have parent_task_id set and contain system prompts
|
|
224
|
+
if task_to_update.background_execution_enabled and not task_to_update.parent_task_id:
|
|
225
|
+
self._save_chat_messages_for_background_task(db, task_id, task_to_update, repo)
|
|
226
|
+
|
|
227
|
+
# Note: The frontend will detect task completion through:
|
|
228
|
+
# 1. SSE final_response event (if connected to that task)
|
|
229
|
+
# 2. Session list refresh triggered by the ChatProvider
|
|
230
|
+
# 3. Database status check when loading sessions
|
|
231
|
+
log.info(
|
|
232
|
+
f"{self.log_identifier} Background task {task_id} completed and chat messages saved"
|
|
233
|
+
)
|
|
234
|
+
|
|
167
235
|
db.commit()
|
|
168
236
|
except Exception as e:
|
|
169
237
|
log.exception(
|
|
@@ -188,6 +256,9 @@ class TaskLoggerService:
|
|
|
188
256
|
# Ignore discovery messages
|
|
189
257
|
if "/discovery/agentcards" in topic:
|
|
190
258
|
return None
|
|
259
|
+
# Ignore trust manager trust card messages
|
|
260
|
+
if "/trust/" in topic:
|
|
261
|
+
return None
|
|
191
262
|
|
|
192
263
|
try:
|
|
193
264
|
# Check if it's a response (has 'result' or 'error')
|
|
@@ -316,3 +387,282 @@ class TaskLoggerService:
|
|
|
316
387
|
|
|
317
388
|
walk_and_sanitize(new_payload)
|
|
318
389
|
return new_payload
|
|
390
|
+
|
|
391
|
+
def _save_chat_messages_for_background_task(
|
|
392
|
+
self, db: DBSession, task_id: str, task: Task, repo: TaskRepository
|
|
393
|
+
) -> None:
|
|
394
|
+
"""
|
|
395
|
+
Save chat messages for a completed background task by reconstructing them from task events.
|
|
396
|
+
This ensures chat history is available when users return to a session after a background task completes.
|
|
397
|
+
Uses upsert to avoid duplicates.
|
|
398
|
+
"""
|
|
399
|
+
try:
|
|
400
|
+
# Get all events for this task
|
|
401
|
+
task_with_events = repo.find_by_id_with_events(db, task_id)
|
|
402
|
+
if not task_with_events:
|
|
403
|
+
log.warning(
|
|
404
|
+
f"{self.log_identifier} Could not find task {task_id} with events for chat message saving"
|
|
405
|
+
)
|
|
406
|
+
return
|
|
407
|
+
|
|
408
|
+
_, events = task_with_events
|
|
409
|
+
|
|
410
|
+
# Extract session_id and user_id from the task's initial request
|
|
411
|
+
session_id = None
|
|
412
|
+
user_id = task.user_id
|
|
413
|
+
agent_name = None
|
|
414
|
+
user_message_text = task.initial_request_text
|
|
415
|
+
|
|
416
|
+
# Parse events to extract session context and reconstruct messages
|
|
417
|
+
message_bubbles = []
|
|
418
|
+
artifacts = [] # Track artifacts - only from final task response to avoid duplicates
|
|
419
|
+
rag_data = [] # Track RAG metadata from tool results
|
|
420
|
+
|
|
421
|
+
for event in events:
|
|
422
|
+
try:
|
|
423
|
+
payload = event.payload
|
|
424
|
+
|
|
425
|
+
# Extract session_id from the first request event
|
|
426
|
+
if event.direction == "request" and not session_id:
|
|
427
|
+
if "params" in payload and isinstance(payload["params"], dict):
|
|
428
|
+
message = payload["params"].get("message", {})
|
|
429
|
+
if isinstance(message, dict):
|
|
430
|
+
session_id = message.get("contextId")
|
|
431
|
+
# Extract agent name from metadata
|
|
432
|
+
metadata = message.get("metadata", {})
|
|
433
|
+
if isinstance(metadata, dict):
|
|
434
|
+
agent_name = metadata.get("agent_name")
|
|
435
|
+
|
|
436
|
+
# Add user message bubble
|
|
437
|
+
parts = message.get("parts", [])
|
|
438
|
+
|
|
439
|
+
# Filter out the gateway timestamp part (first part if it starts with "Request received by gateway")
|
|
440
|
+
filtered_parts = []
|
|
441
|
+
for i, part in enumerate(parts):
|
|
442
|
+
if part.get("kind") == "text":
|
|
443
|
+
text = part.get("text", "")
|
|
444
|
+
# Skip the first part if it's the gateway timestamp
|
|
445
|
+
if i == 0 and text.startswith("Request received by gateway at:"):
|
|
446
|
+
continue
|
|
447
|
+
filtered_parts.append(part)
|
|
448
|
+
else:
|
|
449
|
+
filtered_parts.append(part)
|
|
450
|
+
|
|
451
|
+
text_parts = [p.get("text", "") for p in filtered_parts if p.get("kind") == "text"]
|
|
452
|
+
combined_text = "".join(text_parts)
|
|
453
|
+
|
|
454
|
+
if combined_text or any(p.get("kind") == "file" for p in filtered_parts):
|
|
455
|
+
message_bubbles.append({
|
|
456
|
+
"id": f"msg-{uuid.uuid4()}",
|
|
457
|
+
"type": "user",
|
|
458
|
+
"text": combined_text,
|
|
459
|
+
"parts": filtered_parts,
|
|
460
|
+
})
|
|
461
|
+
|
|
462
|
+
# Collect RAG metadata from status events (but NOT artifacts to avoid duplicates)
|
|
463
|
+
elif event.direction == "status":
|
|
464
|
+
if "result" in payload:
|
|
465
|
+
result = payload["result"]
|
|
466
|
+
# Only extract RAG metadata, skip artifact collection from status events
|
|
467
|
+
# Artifacts will be collected from the final task response only
|
|
468
|
+
|
|
469
|
+
# Extract RAG metadata from tool_result data parts
|
|
470
|
+
status = result.get("status", {})
|
|
471
|
+
if isinstance(status, dict):
|
|
472
|
+
message = status.get("message", {})
|
|
473
|
+
if isinstance(message, dict):
|
|
474
|
+
parts = message.get("parts", [])
|
|
475
|
+
for part in parts:
|
|
476
|
+
if isinstance(part, dict) and part.get("kind") == "data":
|
|
477
|
+
data = part.get("data", {})
|
|
478
|
+
if isinstance(data, dict) and data.get("type") == "tool_result":
|
|
479
|
+
result_data = data.get("result_data", {})
|
|
480
|
+
if isinstance(result_data, dict) and "rag_metadata" in result_data:
|
|
481
|
+
rag_metadata = result_data["rag_metadata"]
|
|
482
|
+
if isinstance(rag_metadata, dict):
|
|
483
|
+
# Add taskId to the RAG metadata
|
|
484
|
+
rag_metadata["taskId"] = task_id
|
|
485
|
+
rag_data.append(rag_metadata)
|
|
486
|
+
log.info(
|
|
487
|
+
f"{self.log_identifier} Extracted RAG metadata for task {task_id}: "
|
|
488
|
+
f"searchType={rag_metadata.get('searchType')}, "
|
|
489
|
+
f"sources_count={len(rag_metadata.get('sources', []))}"
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
# Extract agent response messages - only from final task response
|
|
493
|
+
elif event.direction == "response":
|
|
494
|
+
if "result" in payload:
|
|
495
|
+
result = payload["result"]
|
|
496
|
+
|
|
497
|
+
# Only process final task response (kind="task")
|
|
498
|
+
if isinstance(result, dict) and result.get("kind") == "task":
|
|
499
|
+
# Extract artifacts from task metadata
|
|
500
|
+
metadata = result.get("metadata", {})
|
|
501
|
+
if isinstance(metadata, dict):
|
|
502
|
+
# Try both 'produced_artifacts' and 'artifact_manifest'
|
|
503
|
+
artifact_list = metadata.get("produced_artifacts") or metadata.get("artifact_manifest", [])
|
|
504
|
+
if isinstance(artifact_list, list):
|
|
505
|
+
for artifact_info in artifact_list:
|
|
506
|
+
if isinstance(artifact_info, dict):
|
|
507
|
+
# Handle both 'name' and 'filename' keys
|
|
508
|
+
artifact_name = artifact_info.get("name") or artifact_info.get("filename")
|
|
509
|
+
# Skip web_content_ artifacts (temporary files from deep research)
|
|
510
|
+
if artifact_name and not artifact_name.startswith("web_content_"):
|
|
511
|
+
artifacts.append({
|
|
512
|
+
"kind": "artifact",
|
|
513
|
+
"status": "completed",
|
|
514
|
+
"name": artifact_name,
|
|
515
|
+
"file": {
|
|
516
|
+
"name": artifact_name,
|
|
517
|
+
"mime_type": artifact_info.get("mime_type"),
|
|
518
|
+
"uri": f"artifact://{session_id}/{artifact_name}" if session_id else f"artifact://unknown/{artifact_name}"
|
|
519
|
+
}
|
|
520
|
+
})
|
|
521
|
+
|
|
522
|
+
# Final task object - extract the complete message
|
|
523
|
+
status = result.get("status", {})
|
|
524
|
+
if isinstance(status, dict):
|
|
525
|
+
message = status.get("message", {})
|
|
526
|
+
if isinstance(message, dict):
|
|
527
|
+
parts = message.get("parts", [])
|
|
528
|
+
|
|
529
|
+
# Extract RAG metadata from tool_result data parts in final response
|
|
530
|
+
for part in parts:
|
|
531
|
+
if isinstance(part, dict) and part.get("kind") == "data":
|
|
532
|
+
data = part.get("data", {})
|
|
533
|
+
if isinstance(data, dict) and data.get("type") == "tool_result":
|
|
534
|
+
result_data = data.get("result_data", {})
|
|
535
|
+
if isinstance(result_data, dict) and "rag_metadata" in result_data:
|
|
536
|
+
rag_metadata = result_data["rag_metadata"]
|
|
537
|
+
if isinstance(rag_metadata, dict):
|
|
538
|
+
# Add taskId to the RAG metadata
|
|
539
|
+
rag_metadata["taskId"] = task_id
|
|
540
|
+
# Avoid duplicates
|
|
541
|
+
if rag_metadata not in rag_data:
|
|
542
|
+
rag_data.append(rag_metadata)
|
|
543
|
+
log.info(
|
|
544
|
+
f"{self.log_identifier} Extracted RAG metadata from final response for task {task_id}: "
|
|
545
|
+
f"searchType={rag_metadata.get('searchType')}, "
|
|
546
|
+
f"sources_count={len(rag_metadata.get('sources', []))}"
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
# Filter out data parts (status updates, tool invocations, etc.)
|
|
550
|
+
content_parts = [p for p in parts if p.get("kind") != "data"]
|
|
551
|
+
|
|
552
|
+
if content_parts or artifacts:
|
|
553
|
+
text_parts = [p.get("text", "") for p in content_parts if p.get("kind") == "text"]
|
|
554
|
+
combined_text = "".join(text_parts).strip()
|
|
555
|
+
|
|
556
|
+
# Check if artifact markers are already in the text
|
|
557
|
+
# (they might be included in the final response text parts)
|
|
558
|
+
import re
|
|
559
|
+
existing_markers = set()
|
|
560
|
+
marker_pattern = r'«artifact_return:([^»]+)»'
|
|
561
|
+
for match in re.finditer(marker_pattern, combined_text):
|
|
562
|
+
# Normalize the artifact name (strip version suffix)
|
|
563
|
+
artifact_ref = match.group(1)
|
|
564
|
+
if ':' in artifact_ref:
|
|
565
|
+
base_name = artifact_ref.rsplit(':', 1)[0]
|
|
566
|
+
try:
|
|
567
|
+
int(artifact_ref.rsplit(':', 1)[1])
|
|
568
|
+
# Add the base name (without version) to existing markers
|
|
569
|
+
# so we don't add a duplicate marker later
|
|
570
|
+
existing_markers.add(base_name)
|
|
571
|
+
except ValueError:
|
|
572
|
+
# Not a version number, treat the whole thing as the artifact name
|
|
573
|
+
existing_markers.add(artifact_ref)
|
|
574
|
+
else:
|
|
575
|
+
existing_markers.add(artifact_ref)
|
|
576
|
+
|
|
577
|
+
# Only add artifact markers if they're not already present
|
|
578
|
+
for artifact in artifacts:
|
|
579
|
+
artifact_name = artifact['name']
|
|
580
|
+
if artifact_name not in existing_markers:
|
|
581
|
+
combined_text += f"«artifact_return:{artifact_name}»"
|
|
582
|
+
log.info(
|
|
583
|
+
f"{self.log_identifier} Adding artifact marker for {artifact_name}"
|
|
584
|
+
)
|
|
585
|
+
else:
|
|
586
|
+
log.info(
|
|
587
|
+
f"{self.log_identifier} Skipping duplicate artifact marker for {artifact_name} (already in text)"
|
|
588
|
+
)
|
|
589
|
+
|
|
590
|
+
message_bubbles.append({
|
|
591
|
+
"id": f"msg-{uuid.uuid4()}",
|
|
592
|
+
"type": "agent",
|
|
593
|
+
"text": combined_text,
|
|
594
|
+
"parts": content_parts, # Only content parts, no artifacts
|
|
595
|
+
})
|
|
596
|
+
|
|
597
|
+
except Exception as e:
|
|
598
|
+
log.warning(
|
|
599
|
+
f"{self.log_identifier} Error parsing event for chat message reconstruction: {e}"
|
|
600
|
+
)
|
|
601
|
+
continue
|
|
602
|
+
|
|
603
|
+
# Only save if we have a session_id and at least one message
|
|
604
|
+
if not session_id:
|
|
605
|
+
log.warning(
|
|
606
|
+
f"{self.log_identifier} Could not extract session_id for task {task_id}, skipping chat message save"
|
|
607
|
+
)
|
|
608
|
+
return
|
|
609
|
+
|
|
610
|
+
if not message_bubbles:
|
|
611
|
+
log.warning(
|
|
612
|
+
f"{self.log_identifier} No message bubbles reconstructed for task {task_id}, skipping chat message save"
|
|
613
|
+
)
|
|
614
|
+
return
|
|
615
|
+
|
|
616
|
+
# Import here to avoid circular dependency
|
|
617
|
+
from ..repository.chat_task_repository import ChatTaskRepository
|
|
618
|
+
from ..repository.entities import ChatTask
|
|
619
|
+
from ..repository.session_repository import SessionRepository
|
|
620
|
+
|
|
621
|
+
# Check if the session exists in this database
|
|
622
|
+
session_repo = SessionRepository()
|
|
623
|
+
if not session_repo.exists(db, session_id):
|
|
624
|
+
log.debug(
|
|
625
|
+
f"{self.log_identifier} Session {session_id} not found in webui_gateway database "
|
|
626
|
+
f"Skipping chat message save for task {task_id}"
|
|
627
|
+
)
|
|
628
|
+
return
|
|
629
|
+
|
|
630
|
+
# Build task metadata including RAG data if present
|
|
631
|
+
task_metadata_dict = {
|
|
632
|
+
"schema_version": 1,
|
|
633
|
+
"status": task.status,
|
|
634
|
+
"agent_name": agent_name,
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
# Include RAG data if we found any
|
|
638
|
+
if rag_data:
|
|
639
|
+
task_metadata_dict["rag_data"] = rag_data
|
|
640
|
+
log.info(
|
|
641
|
+
f"{self.log_identifier} Including {len(rag_data)} RAG data entries in task metadata for {task_id}"
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
# Create and save the chat task
|
|
645
|
+
chat_task = ChatTask(
|
|
646
|
+
id=task_id,
|
|
647
|
+
session_id=session_id,
|
|
648
|
+
user_id=user_id,
|
|
649
|
+
user_message=user_message_text,
|
|
650
|
+
message_bubbles=json.dumps(message_bubbles),
|
|
651
|
+
task_metadata=json.dumps(task_metadata_dict),
|
|
652
|
+
created_time=task.start_time,
|
|
653
|
+
updated_time=task.end_time,
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
chat_task_repo = ChatTaskRepository()
|
|
657
|
+
chat_task_repo.save(db, chat_task)
|
|
658
|
+
|
|
659
|
+
log.info(
|
|
660
|
+
f"{self.log_identifier} Saved chat messages for background task {task_id} "
|
|
661
|
+
f"(session: {session_id}, {len(message_bubbles)} message bubbles)"
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
except Exception as e:
|
|
665
|
+
log.error(
|
|
666
|
+
f"{self.log_identifier} Failed to save chat messages for background task {task_id}: {e}",
|
|
667
|
+
exc_info=True
|
|
668
|
+
)
|