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,18 +3,30 @@ A stateful stream parser for identifying and extracting fenced artifact blocks
|
|
|
3
3
|
from an LLM's text stream.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
import logging
|
|
6
7
|
import re
|
|
7
8
|
from enum import Enum, auto
|
|
8
9
|
from dataclasses import dataclass, field
|
|
9
10
|
from typing import List, Dict, Any
|
|
10
11
|
|
|
12
|
+
from ...common.utils.embeds.constants import (
|
|
13
|
+
EMBED_DELIMITER_OPEN,
|
|
14
|
+
EMBED_DELIMITER_CLOSE,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
log = logging.getLogger(__name__)
|
|
18
|
+
|
|
11
19
|
# --- Constants ---
|
|
12
20
|
# These are duplicated from callbacks for now to keep the parser self-contained.
|
|
13
21
|
# They should eventually live in a shared constants module.
|
|
14
22
|
ARTIFACT_BLOCK_DELIMITER_OPEN = "«««"
|
|
15
23
|
ARTIFACT_BLOCK_DELIMITER_CLOSE = "»»»"
|
|
16
|
-
# The full
|
|
17
|
-
|
|
24
|
+
# The full sequences that must be matched to start a block.
|
|
25
|
+
SAVE_ARTIFACT_START_SEQUENCE = f"{ARTIFACT_BLOCK_DELIMITER_OPEN}save_artifact:"
|
|
26
|
+
TEMPLATE_START_SEQUENCE = f"{ARTIFACT_BLOCK_DELIMITER_OPEN}template:"
|
|
27
|
+
TEMPLATE_LIQUID_START_SEQUENCE = f"{ARTIFACT_BLOCK_DELIMITER_OPEN}template_liquid:"
|
|
28
|
+
# For backward compatibility
|
|
29
|
+
BLOCK_START_SEQUENCE = SAVE_ARTIFACT_START_SEQUENCE
|
|
18
30
|
# Regex to parse parameters from a confirmed start line.
|
|
19
31
|
PARAMS_REGEX = re.compile(r'(\w+)\s*=\s*"(.*?)"')
|
|
20
32
|
|
|
@@ -66,6 +78,21 @@ class BlockInvalidatedEvent(ParserEvent):
|
|
|
66
78
|
rolled_back_text: str
|
|
67
79
|
|
|
68
80
|
|
|
81
|
+
@dataclass
|
|
82
|
+
class TemplateBlockStartedEvent(ParserEvent):
|
|
83
|
+
"""Emitted when a template block's start is confirmed."""
|
|
84
|
+
|
|
85
|
+
params: Dict[str, Any]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class TemplateBlockCompletedEvent(ParserEvent):
|
|
90
|
+
"""Emitted when a template block is successfully closed."""
|
|
91
|
+
|
|
92
|
+
params: Dict[str, Any]
|
|
93
|
+
template_content: str
|
|
94
|
+
|
|
95
|
+
|
|
69
96
|
@dataclass
|
|
70
97
|
class ParserResult:
|
|
71
98
|
"""The result of processing a single text chunk."""
|
|
@@ -93,6 +120,14 @@ class FencedBlockStreamParser:
|
|
|
93
120
|
self._block_params: Dict[str, Any] = {}
|
|
94
121
|
self._progress_update_interval = progress_update_interval_bytes
|
|
95
122
|
self._last_progress_update_size = 0
|
|
123
|
+
self._last_progress_chunk_end = 0 # Character position in buffer where last chunk ended
|
|
124
|
+
# Track block type and nesting for template handling
|
|
125
|
+
self._current_block_type: str = None # "save_artifact" or "template"
|
|
126
|
+
self._nesting_depth = 0 # Track if we're inside a block
|
|
127
|
+
self._previous_state: ParserState = None # Track state before POTENTIAL_BLOCK
|
|
128
|
+
# Safety limit: force emission after this many pending bytes (to handle unclosed embeds)
|
|
129
|
+
# Use minimum of 8KB to handle long templates/embeds
|
|
130
|
+
self._max_pending_bytes = max(progress_update_interval_bytes * 4, 8192) # Min 8KB
|
|
96
131
|
|
|
97
132
|
def _reset_state(self):
|
|
98
133
|
"""Resets the parser to its initial IDLE state."""
|
|
@@ -101,6 +136,36 @@ class FencedBlockStreamParser:
|
|
|
101
136
|
self._artifact_buffer = ""
|
|
102
137
|
self._block_params = {}
|
|
103
138
|
self._last_progress_update_size = 0
|
|
139
|
+
self._last_progress_chunk_end = 0
|
|
140
|
+
self._current_block_type = None
|
|
141
|
+
self._nesting_depth = 0
|
|
142
|
+
self._previous_state = None
|
|
143
|
+
|
|
144
|
+
def _is_safe_to_emit_chunk(self) -> bool:
|
|
145
|
+
"""
|
|
146
|
+
Check if current buffer position is safe for chunking (not inside an embed).
|
|
147
|
+
|
|
148
|
+
Looks at the content since the last chunk emission to see if there's an
|
|
149
|
+
unclosed embed delimiter. If so, waits until the embed is closed before emitting.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
True if safe to emit chunk (no partial embeds), False otherwise.
|
|
153
|
+
"""
|
|
154
|
+
# Check the portion of buffer we're about to emit
|
|
155
|
+
buffer_to_check = self._artifact_buffer[self._last_progress_chunk_end:]
|
|
156
|
+
|
|
157
|
+
# Find last occurrence of opening delimiter
|
|
158
|
+
last_open = buffer_to_check.rfind(EMBED_DELIMITER_OPEN)
|
|
159
|
+
|
|
160
|
+
if last_open == -1:
|
|
161
|
+
# No embed delimiter found in this portion
|
|
162
|
+
return True
|
|
163
|
+
|
|
164
|
+
# Found an opening delimiter - check if it's closed
|
|
165
|
+
last_close = buffer_to_check.rfind(EMBED_DELIMITER_CLOSE, last_open)
|
|
166
|
+
|
|
167
|
+
# Safe only if there's a closing delimiter after the opening one
|
|
168
|
+
return last_close > last_open
|
|
104
169
|
|
|
105
170
|
def process_chunk(self, text_chunk: str) -> ParserResult:
|
|
106
171
|
"""
|
|
@@ -142,14 +207,28 @@ class FencedBlockStreamParser:
|
|
|
142
207
|
events.append(BlockInvalidatedEvent(rolled_back_text=rolled_back_text))
|
|
143
208
|
elif self._state == ParserState.IN_BLOCK:
|
|
144
209
|
# The turn ended while inside a block. This is an error/failure.
|
|
145
|
-
# The orchestrator (callback) will see this and know to fail the artifact.
|
|
146
|
-
# We emit
|
|
210
|
+
# The orchestrator (callback) will see this and know to fail the artifact/template.
|
|
211
|
+
# We emit the appropriate completion event so the orchestrator knows what was buffered.
|
|
147
212
|
# The orchestrator is responsible for interpreting this as a failure.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)
|
|
213
|
+
log.warning(
|
|
214
|
+
"[StreamParser] finalize() found unterminated block! Type: %s, buffer length: %d, nesting_depth: %d",
|
|
215
|
+
self._current_block_type,
|
|
216
|
+
len(self._artifact_buffer),
|
|
217
|
+
self._nesting_depth,
|
|
152
218
|
)
|
|
219
|
+
if self._current_block_type == "template":
|
|
220
|
+
events.append(
|
|
221
|
+
TemplateBlockCompletedEvent(
|
|
222
|
+
params=self._block_params,
|
|
223
|
+
template_content=self._artifact_buffer,
|
|
224
|
+
)
|
|
225
|
+
)
|
|
226
|
+
else:
|
|
227
|
+
events.append(
|
|
228
|
+
BlockCompletedEvent(
|
|
229
|
+
params=self._block_params, content=self._artifact_buffer
|
|
230
|
+
)
|
|
231
|
+
)
|
|
153
232
|
|
|
154
233
|
self._reset_state()
|
|
155
234
|
return ParserResult("".join(user_text_parts), events)
|
|
@@ -157,6 +236,7 @@ class FencedBlockStreamParser:
|
|
|
157
236
|
def _process_idle(self, char: str, user_text_parts: List[str]):
|
|
158
237
|
"""State handler for when the parser is outside any block."""
|
|
159
238
|
if char == BLOCK_START_SEQUENCE[0]:
|
|
239
|
+
self._previous_state = ParserState.IDLE
|
|
160
240
|
self._state = ParserState.POTENTIAL_BLOCK
|
|
161
241
|
self._speculative_buffer += char
|
|
162
242
|
else:
|
|
@@ -168,59 +248,168 @@ class FencedBlockStreamParser:
|
|
|
168
248
|
"""State handler for when a block might be starting."""
|
|
169
249
|
self._speculative_buffer += char
|
|
170
250
|
|
|
171
|
-
#
|
|
172
|
-
|
|
251
|
+
# Check if we match save_artifact or template start sequences
|
|
252
|
+
matched_sequence = None
|
|
253
|
+
matched_type = None
|
|
254
|
+
|
|
255
|
+
if self._speculative_buffer.startswith(SAVE_ARTIFACT_START_SEQUENCE):
|
|
256
|
+
matched_sequence = SAVE_ARTIFACT_START_SEQUENCE
|
|
257
|
+
matched_type = "save_artifact"
|
|
258
|
+
elif self._speculative_buffer.startswith(TEMPLATE_LIQUID_START_SEQUENCE):
|
|
259
|
+
matched_sequence = TEMPLATE_LIQUID_START_SEQUENCE
|
|
260
|
+
matched_type = "template"
|
|
261
|
+
elif self._speculative_buffer.startswith(TEMPLATE_START_SEQUENCE):
|
|
262
|
+
matched_sequence = TEMPLATE_START_SEQUENCE
|
|
263
|
+
matched_type = "template"
|
|
264
|
+
|
|
265
|
+
if matched_sequence:
|
|
173
266
|
if char == "\n":
|
|
174
267
|
# We found the newline, the block is officially started.
|
|
268
|
+
|
|
269
|
+
# If we're already inside a save_artifact block and this is a template,
|
|
270
|
+
# we need to pass it through as literal text (preserve nesting)
|
|
271
|
+
if self._nesting_depth > 0 and matched_type == "template":
|
|
272
|
+
# Preserve template literally inside artifact
|
|
273
|
+
self._artifact_buffer += self._speculative_buffer
|
|
274
|
+
# Increment nesting depth so we know to skip the next »»»
|
|
275
|
+
# (it will close the nested template, not the outer artifact)
|
|
276
|
+
self._nesting_depth += 1
|
|
277
|
+
# Don't reset state! We're still inside the save_artifact block.
|
|
278
|
+
# Just clear the speculative buffer and stay IN_BLOCK to continue
|
|
279
|
+
# buffering the rest of the artifact content.
|
|
280
|
+
self._speculative_buffer = ""
|
|
281
|
+
self._state = ParserState.IN_BLOCK
|
|
282
|
+
return
|
|
283
|
+
|
|
175
284
|
self._state = ParserState.IN_BLOCK
|
|
285
|
+
self._current_block_type = matched_type
|
|
286
|
+
self._nesting_depth += 1
|
|
287
|
+
|
|
176
288
|
# Extract the parameters string between the start sequence and the newline
|
|
177
|
-
params_str = self._speculative_buffer[len(
|
|
289
|
+
params_str = self._speculative_buffer[len(matched_sequence) : -1]
|
|
178
290
|
self._block_params = dict(PARAMS_REGEX.findall(params_str))
|
|
179
|
-
|
|
291
|
+
|
|
292
|
+
if matched_type == "save_artifact":
|
|
293
|
+
events.append(BlockStartedEvent(params=self._block_params))
|
|
294
|
+
elif matched_type == "template":
|
|
295
|
+
events.append(TemplateBlockStartedEvent(params=self._block_params))
|
|
296
|
+
|
|
180
297
|
self._speculative_buffer = "" # Clear buffer, we are done with it.
|
|
181
298
|
# else, we are still buffering the parameters line.
|
|
182
299
|
return
|
|
183
300
|
|
|
184
|
-
# If we are still building up
|
|
185
|
-
if
|
|
301
|
+
# If we are still building up a start sequence (could be either)
|
|
302
|
+
if (SAVE_ARTIFACT_START_SEQUENCE.startswith(self._speculative_buffer) or
|
|
303
|
+
TEMPLATE_LIQUID_START_SEQUENCE.startswith(self._speculative_buffer) or
|
|
304
|
+
TEMPLATE_START_SEQUENCE.startswith(self._speculative_buffer)):
|
|
186
305
|
# It's still a potential match. Continue buffering.
|
|
187
306
|
return
|
|
188
307
|
|
|
189
308
|
# If we've reached here, the sequence is invalid.
|
|
190
309
|
# Rollback: The sequence was invalid.
|
|
191
310
|
rolled_back_text = self._speculative_buffer
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
311
|
+
|
|
312
|
+
# Check if we were IN_BLOCK before transitioning to POTENTIAL_BLOCK
|
|
313
|
+
# If so, add the rolled-back text to the artifact buffer, not user-visible text
|
|
314
|
+
if self._previous_state == ParserState.IN_BLOCK:
|
|
315
|
+
log.debug(
|
|
316
|
+
"[StreamParser] Invalid sequence '%s' detected while IN_BLOCK. Adding to artifact buffer.",
|
|
317
|
+
repr(rolled_back_text),
|
|
318
|
+
)
|
|
319
|
+
self._artifact_buffer += rolled_back_text
|
|
320
|
+
self._speculative_buffer = ""
|
|
321
|
+
self._state = ParserState.IN_BLOCK
|
|
322
|
+
# Don't emit BlockInvalidatedEvent - this is just normal artifact content
|
|
323
|
+
else:
|
|
324
|
+
# We were IDLE, so this is user-facing text
|
|
325
|
+
user_text_parts.append(rolled_back_text)
|
|
326
|
+
events.append(BlockInvalidatedEvent(rolled_back_text=rolled_back_text))
|
|
327
|
+
self._speculative_buffer = ""
|
|
328
|
+
self._state = ParserState.IDLE
|
|
329
|
+
|
|
330
|
+
self._previous_state = None
|
|
195
331
|
|
|
196
332
|
def _process_in_block(self, char: str, events: List[ParserEvent]):
|
|
197
333
|
"""State handler for when the parser is inside a block, buffering content."""
|
|
334
|
+
# Check if this might be the start of a nested block
|
|
335
|
+
if char == BLOCK_START_SEQUENCE[0]:
|
|
336
|
+
# This might be the start of a nested template block
|
|
337
|
+
# Transition to POTENTIAL_BLOCK to check
|
|
338
|
+
self._previous_state = ParserState.IN_BLOCK
|
|
339
|
+
self._state = ParserState.POTENTIAL_BLOCK
|
|
340
|
+
self._speculative_buffer += char
|
|
341
|
+
return
|
|
342
|
+
|
|
198
343
|
self._artifact_buffer += char
|
|
199
344
|
|
|
200
345
|
# Check for the closing delimiter
|
|
201
346
|
if self._artifact_buffer.endswith(ARTIFACT_BLOCK_DELIMITER_CLOSE):
|
|
202
|
-
#
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
current_size - self._last_progress_update_size
|
|
215
|
-
) >= self._progress_update_interval:
|
|
216
|
-
new_chunk = self._artifact_buffer[
|
|
217
|
-
self._last_progress_update_size : current_size
|
|
347
|
+
# Check if this is closing a nested block or the current block
|
|
348
|
+
if self._nesting_depth > 1:
|
|
349
|
+
# This »»» is closing a nested template block, not the outer save_artifact
|
|
350
|
+
# Keep it in the buffer and just decrement nesting
|
|
351
|
+
self._nesting_depth -= 1
|
|
352
|
+
# Don't emit events, don't strip the delimiter, just continue buffering
|
|
353
|
+
else:
|
|
354
|
+
# This is closing the outermost block (nesting_depth == 1)
|
|
355
|
+
# Block is complete.
|
|
356
|
+
final_content = self._artifact_buffer[
|
|
357
|
+
: -len(ARTIFACT_BLOCK_DELIMITER_CLOSE)
|
|
218
358
|
]
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
359
|
+
|
|
360
|
+
# Emit the appropriate completion event based on block type
|
|
361
|
+
if self._current_block_type == "template":
|
|
362
|
+
events.append(
|
|
363
|
+
TemplateBlockCompletedEvent(
|
|
364
|
+
params=self._block_params, template_content=final_content
|
|
365
|
+
)
|
|
224
366
|
)
|
|
225
|
-
|
|
226
|
-
|
|
367
|
+
else:
|
|
368
|
+
# Default to save_artifact behavior
|
|
369
|
+
events.append(
|
|
370
|
+
BlockCompletedEvent(
|
|
371
|
+
params=self._block_params, content=final_content
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
# Decrement nesting depth
|
|
376
|
+
self._nesting_depth = max(0, self._nesting_depth - 1)
|
|
377
|
+
self._reset_state()
|
|
378
|
+
else:
|
|
379
|
+
# Check if we should emit a progress update (only for save_artifact blocks)
|
|
380
|
+
if self._current_block_type == "save_artifact":
|
|
381
|
+
# Calculate current total size in bytes (for threshold check)
|
|
382
|
+
current_size_bytes = len(self._artifact_buffer.encode("utf-8"))
|
|
383
|
+
|
|
384
|
+
# Check if we've accumulated enough new bytes since last update
|
|
385
|
+
bytes_since_last = current_size_bytes - self._last_progress_update_size
|
|
386
|
+
if bytes_since_last >= self._progress_update_interval:
|
|
387
|
+
# Check if it's safe to emit (not inside an embed)
|
|
388
|
+
# OR force emit if we've exceeded safety limit (very long unclosed embed)
|
|
389
|
+
force_emit = bytes_since_last >= self._max_pending_bytes
|
|
390
|
+
|
|
391
|
+
if force_emit:
|
|
392
|
+
log.warning(
|
|
393
|
+
"[StreamParser] Forcing chunk emission due to safety limit (%d bytes pending). "
|
|
394
|
+
"Possible unclosed embed or very long embed.",
|
|
395
|
+
bytes_since_last
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
if self._is_safe_to_emit_chunk() or force_emit:
|
|
399
|
+
# Extract all new content since last progress update
|
|
400
|
+
# Slice by character position (not bytes) to avoid UTF-8 issues
|
|
401
|
+
current_char_position = len(self._artifact_buffer)
|
|
402
|
+
new_chunk = self._artifact_buffer[self._last_progress_chunk_end:]
|
|
403
|
+
|
|
404
|
+
events.append(
|
|
405
|
+
BlockProgressedEvent(
|
|
406
|
+
params=self._block_params,
|
|
407
|
+
buffered_size=current_size_bytes, # Total bytes accumulated so far
|
|
408
|
+
chunk=new_chunk, # All new content since last update
|
|
409
|
+
)
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
# Update tracking: character position for slicing, bytes for threshold
|
|
413
|
+
self._last_progress_chunk_end = current_char_position
|
|
414
|
+
self._last_progress_update_size = current_size_bytes
|
|
415
|
+
# else: wait for embed to close before emitting
|
|
@@ -8,6 +8,8 @@ import json
|
|
|
8
8
|
import logging
|
|
9
9
|
from typing import TYPE_CHECKING, Any, Dict
|
|
10
10
|
|
|
11
|
+
from litellm.exceptions import BadRequestError
|
|
12
|
+
|
|
11
13
|
from a2a.types import (
|
|
12
14
|
A2ARequest,
|
|
13
15
|
AgentCapabilities,
|
|
@@ -25,11 +27,17 @@ from google.adk.agents import RunConfig
|
|
|
25
27
|
from google.adk.agents.run_config import StreamingMode
|
|
26
28
|
from solace_ai_connector.common.event import Event, EventType
|
|
27
29
|
from solace_ai_connector.common.message import Message as SolaceMessage
|
|
30
|
+
from sqlalchemy.exc import OperationalError
|
|
28
31
|
|
|
29
32
|
from ...agent.adk.callbacks import _publish_data_part_status_update
|
|
30
33
|
from ...agent.adk.runner import TaskCancelledError, run_adk_async_task_thread_wrapper
|
|
31
34
|
from ...agent.utils.artifact_helpers import generate_artifact_metadata_summary
|
|
32
35
|
from ...common import a2a
|
|
36
|
+
from ...common.error_handlers import get_error_message
|
|
37
|
+
from ...common.utils.embeds.constants import (
|
|
38
|
+
EMBED_DELIMITER_OPEN,
|
|
39
|
+
EMBED_DELIMITER_CLOSE,
|
|
40
|
+
)
|
|
33
41
|
from ...common.a2a import (
|
|
34
42
|
get_agent_request_topic,
|
|
35
43
|
get_agent_response_subscription_topic,
|
|
@@ -753,6 +761,7 @@ async def handle_a2a_request(component, message: SolaceMessage):
|
|
|
753
761
|
"system_purpose": system_purpose,
|
|
754
762
|
"response_format": response_format,
|
|
755
763
|
"host_agent_name": agent_name,
|
|
764
|
+
"original_message_metadata": task_metadata, # Store original message metadata for tools
|
|
756
765
|
}
|
|
757
766
|
|
|
758
767
|
# Store verified user identity claims in a2a_context (not the raw token)
|
|
@@ -970,6 +979,101 @@ async def handle_a2a_request(component, message: SolaceMessage):
|
|
|
970
979
|
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
971
980
|
return None
|
|
972
981
|
|
|
982
|
+
except BadRequestError as e:
|
|
983
|
+
log.error(
|
|
984
|
+
"%s Bad Request error handling A2A request: %s", component.log_identifier, e
|
|
985
|
+
)
|
|
986
|
+
|
|
987
|
+
# Use centralized error handler
|
|
988
|
+
error_message, is_context_limit = get_error_message(e)
|
|
989
|
+
|
|
990
|
+
if is_context_limit:
|
|
991
|
+
log.error(
|
|
992
|
+
"%s Context limit exceeded for task %s",
|
|
993
|
+
component.log_identifier,
|
|
994
|
+
logical_task_id,
|
|
995
|
+
)
|
|
996
|
+
|
|
997
|
+
error_response = a2a.create_invalid_request_error_response(
|
|
998
|
+
message=error_message,
|
|
999
|
+
request_id=jsonrpc_request_id,
|
|
1000
|
+
data={"taskId": logical_task_id},
|
|
1001
|
+
)
|
|
1002
|
+
target_topic = reply_topic_from_peer or (
|
|
1003
|
+
get_client_response_topic(namespace, client_id) if client_id else None
|
|
1004
|
+
)
|
|
1005
|
+
if target_topic:
|
|
1006
|
+
component.publish_a2a_message(
|
|
1007
|
+
error_response.model_dump(exclude_none=True),
|
|
1008
|
+
target_topic,
|
|
1009
|
+
)
|
|
1010
|
+
|
|
1011
|
+
try:
|
|
1012
|
+
message.call_negative_acknowledgements()
|
|
1013
|
+
log.warning(
|
|
1014
|
+
"%s NACKed original A2A request due to bad request error.",
|
|
1015
|
+
component.log_identifier,
|
|
1016
|
+
)
|
|
1017
|
+
except Exception as nack_e:
|
|
1018
|
+
log.error(
|
|
1019
|
+
"%s Failed to NACK message after bad request error: %s",
|
|
1020
|
+
component.log_identifier,
|
|
1021
|
+
nack_e,
|
|
1022
|
+
)
|
|
1023
|
+
|
|
1024
|
+
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
1025
|
+
return None
|
|
1026
|
+
|
|
1027
|
+
except OperationalError as e:
|
|
1028
|
+
log.error(
|
|
1029
|
+
"%s Database error while processing A2A request: %s",
|
|
1030
|
+
component.log_identifier,
|
|
1031
|
+
e,
|
|
1032
|
+
)
|
|
1033
|
+
|
|
1034
|
+
# Check if it's a schema error
|
|
1035
|
+
error_msg = str(e).lower()
|
|
1036
|
+
if "no such column" in error_msg or "no such table" in error_msg:
|
|
1037
|
+
user_message = (
|
|
1038
|
+
"Database schema update required. "
|
|
1039
|
+
"Please contact your administrator to run database migrations."
|
|
1040
|
+
)
|
|
1041
|
+
else:
|
|
1042
|
+
user_message = (
|
|
1043
|
+
"Database error occurred. Please try again or contact support."
|
|
1044
|
+
)
|
|
1045
|
+
|
|
1046
|
+
error_response = a2a.create_internal_error_response(
|
|
1047
|
+
message=user_message,
|
|
1048
|
+
request_id=jsonrpc_request_id,
|
|
1049
|
+
data={"taskId": logical_task_id} if logical_task_id else None,
|
|
1050
|
+
)
|
|
1051
|
+
|
|
1052
|
+
target_topic = reply_topic_from_peer or (
|
|
1053
|
+
get_client_response_topic(namespace, client_id) if client_id else None
|
|
1054
|
+
)
|
|
1055
|
+
if target_topic:
|
|
1056
|
+
component.publish_a2a_message(
|
|
1057
|
+
error_response.model_dump(exclude_none=True),
|
|
1058
|
+
target_topic,
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
try:
|
|
1062
|
+
message.call_negative_acknowledgements()
|
|
1063
|
+
log.warning(
|
|
1064
|
+
"%s NACKed A2A request due to database error.",
|
|
1065
|
+
component.log_identifier,
|
|
1066
|
+
)
|
|
1067
|
+
except Exception as nack_e:
|
|
1068
|
+
log.error(
|
|
1069
|
+
"%s Failed to NACK message after database error: %s",
|
|
1070
|
+
component.log_identifier,
|
|
1071
|
+
nack_e,
|
|
1072
|
+
)
|
|
1073
|
+
|
|
1074
|
+
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
1075
|
+
return None
|
|
1076
|
+
|
|
973
1077
|
except Exception as e:
|
|
974
1078
|
log.exception(
|
|
975
1079
|
"%s Unexpected error handling A2A request: %s", component.log_identifier, e
|
|
@@ -1296,43 +1400,96 @@ async def handle_a2a_response(component, message: SolaceMessage):
|
|
|
1296
1400
|
peer_agent_name=peer_agent_name,
|
|
1297
1401
|
message=message,
|
|
1298
1402
|
)
|
|
1403
|
+
# Reset the timeout since we received a status update
|
|
1404
|
+
await component.reset_peer_timeout(sub_task_id)
|
|
1299
1405
|
return
|
|
1300
1406
|
|
|
1407
|
+
# Filter out artifact creation progress from peer agents.
|
|
1408
|
+
# These are implementation details that should not leak across
|
|
1409
|
+
# agent boundaries. Artifacts are properly bubbled up in the
|
|
1410
|
+
# final Task response metadata.
|
|
1411
|
+
filtered_data_parts = []
|
|
1412
|
+
has_deep_research_report = False
|
|
1301
1413
|
for data_part in data_parts:
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1414
|
+
if isinstance(data_part.data, dict):
|
|
1415
|
+
data_type = data_part.data.get("type")
|
|
1416
|
+
if data_type == "artifact_creation_progress":
|
|
1417
|
+
log.debug(
|
|
1418
|
+
"%s Filtered out artifact_creation_progress DataPart from peer sub-task %s. Not forwarding to user.",
|
|
1419
|
+
component.log_identifier,
|
|
1420
|
+
sub_task_id,
|
|
1421
|
+
)
|
|
1422
|
+
continue
|
|
1423
|
+
if data_type == "deep_research_report":
|
|
1424
|
+
# Track that we've seen a deep research report
|
|
1425
|
+
# This will be used to suppress text content in the final response
|
|
1426
|
+
has_deep_research_report = True
|
|
1427
|
+
log.info(
|
|
1428
|
+
"%s Detected deep_research_report DataPart from peer sub-task %s. Will suppress text in final response.",
|
|
1429
|
+
component.log_identifier,
|
|
1430
|
+
sub_task_id,
|
|
1431
|
+
)
|
|
1432
|
+
filtered_data_parts.append(data_part)
|
|
1433
|
+
|
|
1434
|
+
# Store the deep research report flag in correlation data for later use
|
|
1435
|
+
if has_deep_research_report:
|
|
1436
|
+
main_logical_task_id_for_flag = original_task_context.get("logical_task_id")
|
|
1437
|
+
with component.active_tasks_lock:
|
|
1438
|
+
task_context_for_flag = component.active_tasks.get(main_logical_task_id_for_flag)
|
|
1439
|
+
if task_context_for_flag:
|
|
1440
|
+
# Store flag in task context to suppress text in final response
|
|
1441
|
+
task_context_for_flag.set_flag("peer_sent_deep_research_report", True)
|
|
1442
|
+
log.info(
|
|
1443
|
+
"%s Set peer_sent_deep_research_report flag for task %s",
|
|
1444
|
+
component.log_identifier,
|
|
1445
|
+
main_logical_task_id_for_flag,
|
|
1446
|
+
)
|
|
1447
|
+
|
|
1448
|
+
# Only forward if there are non-filtered data parts
|
|
1449
|
+
if filtered_data_parts:
|
|
1450
|
+
for data_part in filtered_data_parts:
|
|
1451
|
+
log.info(
|
|
1452
|
+
"%s Received DataPart signal from peer for sub-task %s. Forwarding...",
|
|
1453
|
+
component.log_identifier,
|
|
1454
|
+
sub_task_id,
|
|
1455
|
+
)
|
|
1307
1456
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1457
|
+
forwarded_message = a2a.create_agent_parts_message(
|
|
1458
|
+
parts=[data_part],
|
|
1459
|
+
metadata=event_metadata,
|
|
1460
|
+
)
|
|
1312
1461
|
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
)
|
|
1319
|
-
if (
|
|
1320
|
-
status_event.status
|
|
1321
|
-
and status_event.status.timestamp
|
|
1322
|
-
):
|
|
1323
|
-
forwarded_event.status.timestamp = (
|
|
1324
|
-
status_event.status.timestamp
|
|
1462
|
+
forwarded_event = a2a.create_status_update(
|
|
1463
|
+
task_id=main_logical_task_id,
|
|
1464
|
+
context_id=main_context_id,
|
|
1465
|
+
message=forwarded_message,
|
|
1466
|
+
is_final=False,
|
|
1325
1467
|
)
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1468
|
+
if (
|
|
1469
|
+
status_event.status
|
|
1470
|
+
and status_event.status.timestamp
|
|
1471
|
+
):
|
|
1472
|
+
forwarded_event.status.timestamp = (
|
|
1473
|
+
status_event.status.timestamp
|
|
1474
|
+
)
|
|
1475
|
+
_forward_jsonrpc_response(
|
|
1476
|
+
component=component,
|
|
1477
|
+
original_jsonrpc_request_id=original_jsonrpc_request_id,
|
|
1478
|
+
result_data=forwarded_event,
|
|
1479
|
+
target_topic=target_topic_for_forward,
|
|
1480
|
+
main_logical_task_id=main_logical_task_id,
|
|
1481
|
+
peer_agent_name=peer_agent_name,
|
|
1482
|
+
message=message,
|
|
1483
|
+
)
|
|
1484
|
+
# Reset the timeout since we received a status update
|
|
1485
|
+
await component.reset_peer_timeout(sub_task_id)
|
|
1335
1486
|
return
|
|
1487
|
+
else:
|
|
1488
|
+
log.debug(
|
|
1489
|
+
"%s All DataParts from peer sub-task %s were filtered. Not forwarding.",
|
|
1490
|
+
component.log_identifier,
|
|
1491
|
+
sub_task_id,
|
|
1492
|
+
)
|
|
1336
1493
|
|
|
1337
1494
|
payload_to_queue = status_event.model_dump(
|
|
1338
1495
|
by_alias=True, exclude_none=True
|
|
@@ -1613,6 +1770,16 @@ async def handle_a2a_response(component, message: SolaceMessage):
|
|
|
1613
1770
|
header_text=header_text,
|
|
1614
1771
|
)
|
|
1615
1772
|
)
|
|
1773
|
+
|
|
1774
|
+
# Add guidance about artifact_return responsibility
|
|
1775
|
+
artifact_return_guidance = (
|
|
1776
|
+
f"\n\n**Note:** If any of these artifacts fulfill the user's request, "
|
|
1777
|
+
f"you should return them directly to the user using the "
|
|
1778
|
+
f"{EMBED_DELIMITER_OPEN}artifact_return:filename:version{EMBED_DELIMITER_CLOSE} embed. "
|
|
1779
|
+
f"This is more convenient for the user than just describing the artifacts. "
|
|
1780
|
+
f"Replace 'filename' and 'version' with the actual values from the artifact metadata above."
|
|
1781
|
+
)
|
|
1782
|
+
artifact_summary += artifact_return_guidance
|
|
1616
1783
|
else:
|
|
1617
1784
|
log.warning(
|
|
1618
1785
|
"%s Could not generate artifact summary: missing user_id or session_id in correlation data.",
|
|
@@ -1633,9 +1800,28 @@ async def handle_a2a_response(component, message: SolaceMessage):
|
|
|
1633
1800
|
else:
|
|
1634
1801
|
final_text = str(payload_to_queue)
|
|
1635
1802
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1803
|
+
# Check if a deep research report was sent by the peer agent
|
|
1804
|
+
# If so, suppress the verbose text but keep artifact info to use
|
|
1805
|
+
peer_sent_deep_research = task_context.get_flag("peer_sent_deep_research_report", False)
|
|
1806
|
+
if peer_sent_deep_research:
|
|
1807
|
+
# Clear the flag after using it
|
|
1808
|
+
task_context.set_flag("peer_sent_deep_research_report", False)
|
|
1809
|
+
if artifact_summary:
|
|
1810
|
+
full_response_text = (
|
|
1811
|
+
f"{artifact_summary}\n---\n\n"
|
|
1812
|
+
"SUCCESS: Deep research task completed. The report has been delivered to the user "
|
|
1813
|
+
"and is being displayed. Use artifact_return to include the artifact reference "
|
|
1814
|
+
"in your response so users can click on it."
|
|
1815
|
+
)
|
|
1816
|
+
else:
|
|
1817
|
+
full_response_text = (
|
|
1818
|
+
"SUCCESS: Deep research task completed successfully. "
|
|
1819
|
+
"The research report has been delivered to the user."
|
|
1820
|
+
)
|
|
1821
|
+
else:
|
|
1822
|
+
full_response_text = final_text
|
|
1823
|
+
if artifact_summary:
|
|
1824
|
+
full_response_text = f"{artifact_summary}\n---\n\nPeer Agent Response:\n\n{full_response_text}"
|
|
1639
1825
|
|
|
1640
1826
|
await _publish_peer_tool_result_notification(
|
|
1641
1827
|
component=component,
|