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
|
@@ -13,6 +13,10 @@ import threading
|
|
|
13
13
|
import time
|
|
14
14
|
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Tuple, Union
|
|
15
15
|
|
|
16
|
+
from litellm.exceptions import BadRequestError
|
|
17
|
+
|
|
18
|
+
from ...common.error_handlers import get_error_message
|
|
19
|
+
|
|
16
20
|
from a2a.types import (
|
|
17
21
|
AgentCard,
|
|
18
22
|
MessageSendParams,
|
|
@@ -39,6 +43,7 @@ from google.adk.models.llm_request import LlmRequest
|
|
|
39
43
|
from google.adk.runners import Runner
|
|
40
44
|
from google.adk.sessions import BaseSessionService
|
|
41
45
|
from google.adk.tools.mcp_tool import MCPToolset
|
|
46
|
+
from google.adk.tools.openapi_tool import OpenAPIToolset
|
|
42
47
|
from google.genai import types as adk_types
|
|
43
48
|
from pydantic import BaseModel, ValidationError
|
|
44
49
|
from solace_ai_connector.common.event import Event, EventType
|
|
@@ -73,9 +78,11 @@ from ...common.constants import (
|
|
|
73
78
|
HEALTH_CHECK_INTERVAL_SECONDS,
|
|
74
79
|
HEALTH_CHECK_TTL_SECONDS,
|
|
75
80
|
)
|
|
76
|
-
from ...common.
|
|
81
|
+
from ...common.a2a.types import ArtifactInfo
|
|
82
|
+
from ...common.data_parts import AgentProgressUpdateData, ArtifactSavedData
|
|
77
83
|
from ...common.middleware.registry import MiddlewareRegistry
|
|
78
84
|
from ...common.sac.sam_component_base import SamComponentBase
|
|
85
|
+
from ...common.utils.rbac_utils import validate_agent_access
|
|
79
86
|
|
|
80
87
|
log = logging.getLogger(__name__)
|
|
81
88
|
|
|
@@ -104,6 +111,7 @@ info = {
|
|
|
104
111
|
}
|
|
105
112
|
InstructionProvider = Callable[[ReadonlyContext], str]
|
|
106
113
|
|
|
114
|
+
|
|
107
115
|
class SamAgentComponent(SamComponentBase):
|
|
108
116
|
"""
|
|
109
117
|
A Solace AI Connector component that hosts a Google ADK agent,
|
|
@@ -128,7 +136,11 @@ class SamAgentComponent(SamComponentBase):
|
|
|
128
136
|
|
|
129
137
|
super().__init__(info, **kwargs)
|
|
130
138
|
self.agent_name = self.get_config("agent_name")
|
|
131
|
-
log.info(
|
|
139
|
+
log.info(
|
|
140
|
+
"%s Initializing agent: %s (A2A ADK Host Component)...",
|
|
141
|
+
self.log_identifier,
|
|
142
|
+
self.agent_name,
|
|
143
|
+
)
|
|
132
144
|
|
|
133
145
|
# Initialize the agent registry for health tracking
|
|
134
146
|
self.agent_registry = AgentRegistry()
|
|
@@ -416,28 +428,6 @@ class SamAgentComponent(SamComponentBase):
|
|
|
416
428
|
# We still need a future to signal completion from the async thread.
|
|
417
429
|
self._async_init_future = concurrent.futures.Future()
|
|
418
430
|
|
|
419
|
-
publish_interval_sec = self.agent_card_publishing_config.get(
|
|
420
|
-
"interval_seconds"
|
|
421
|
-
)
|
|
422
|
-
if publish_interval_sec and publish_interval_sec > 0:
|
|
423
|
-
log.info(
|
|
424
|
-
"%s Scheduling agent card publishing every %d seconds.",
|
|
425
|
-
self.log_identifier,
|
|
426
|
-
publish_interval_sec,
|
|
427
|
-
)
|
|
428
|
-
# Register timer with callback
|
|
429
|
-
self.add_timer(
|
|
430
|
-
delay_ms=1000,
|
|
431
|
-
timer_id=self._card_publish_timer_id,
|
|
432
|
-
interval_ms=publish_interval_sec * 1000,
|
|
433
|
-
callback=lambda timer_data: publish_agent_card(self),
|
|
434
|
-
)
|
|
435
|
-
else:
|
|
436
|
-
log.warning(
|
|
437
|
-
"%s Agent card publishing interval not configured or invalid, card will not be published periodically.",
|
|
438
|
-
self.log_identifier,
|
|
439
|
-
)
|
|
440
|
-
|
|
441
431
|
# Set up health check timer if enabled
|
|
442
432
|
health_check_interval_seconds = self.agent_discovery_config.get(
|
|
443
433
|
"health_check_interval_seconds", HEALTH_CHECK_INTERVAL_SECONDS
|
|
@@ -793,13 +783,8 @@ class SamAgentComponent(SamComponentBase):
|
|
|
793
783
|
log_retrigger,
|
|
794
784
|
len(new_response_parts),
|
|
795
785
|
)
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
author=self.agent_name,
|
|
799
|
-
content=adk_types.Content(role="tool", parts=new_response_parts),
|
|
800
|
-
)
|
|
801
|
-
await self.session_service.append_event(
|
|
802
|
-
session=session, event=new_adk_event
|
|
786
|
+
new_tool_response_content = adk_types.Content(
|
|
787
|
+
role="tool", parts=new_response_parts
|
|
803
788
|
)
|
|
804
789
|
|
|
805
790
|
# Always use SSE streaming mode for the ADK runner, even on re-trigger.
|
|
@@ -818,7 +803,12 @@ class SamAgentComponent(SamComponentBase):
|
|
|
818
803
|
)
|
|
819
804
|
try:
|
|
820
805
|
await run_adk_async_task_thread_wrapper(
|
|
821
|
-
self,
|
|
806
|
+
self,
|
|
807
|
+
session,
|
|
808
|
+
new_tool_response_content,
|
|
809
|
+
run_config,
|
|
810
|
+
original_task_context,
|
|
811
|
+
append_context_event=False,
|
|
822
812
|
)
|
|
823
813
|
finally:
|
|
824
814
|
log.info(
|
|
@@ -1007,12 +997,13 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1007
997
|
)
|
|
1008
998
|
if peer_tool_instance.name not in llm_request.tools_dict:
|
|
1009
999
|
peer_tools_to_add.append(peer_tool_instance)
|
|
1010
|
-
description
|
|
1011
|
-
|
|
1012
|
-
|
|
1000
|
+
# Get enhanced description from the tool instance
|
|
1001
|
+
# which includes capabilities, skills, and tools
|
|
1002
|
+
enhanced_desc = peer_tool_instance._build_enhanced_description(
|
|
1003
|
+
agent_card
|
|
1013
1004
|
)
|
|
1014
1005
|
allowed_peer_descriptions.append(
|
|
1015
|
-
f"
|
|
1006
|
+
f"\n### `peer_{peer_name}`\n{enhanced_desc}"
|
|
1016
1007
|
)
|
|
1017
1008
|
except Exception as e:
|
|
1018
1009
|
log.error(
|
|
@@ -1025,12 +1016,18 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1025
1016
|
if allowed_peer_descriptions:
|
|
1026
1017
|
peer_list_str = "\n".join(allowed_peer_descriptions)
|
|
1027
1018
|
instruction_text = (
|
|
1028
|
-
"
|
|
1029
|
-
"
|
|
1030
|
-
"
|
|
1031
|
-
"
|
|
1032
|
-
"
|
|
1033
|
-
"
|
|
1019
|
+
"## Peer Agent Delegation\n\n"
|
|
1020
|
+
"You can delegate tasks to other specialized agents if they are better suited.\n\n"
|
|
1021
|
+
"**How to delegate:**\n"
|
|
1022
|
+
"- Use the `peer_<agent_name>(task_description: str)` tool for delegation\n"
|
|
1023
|
+
"- Replace `<agent_name>` with the actual name of the target agent\n"
|
|
1024
|
+
"- Provide a clear and detailed `task_description` for the peer agent\n"
|
|
1025
|
+
"- **Important:** The peer agent does not have access to your session history, "
|
|
1026
|
+
"so you must provide all required context necessary to fulfill the request\n\n"
|
|
1027
|
+
"IMPORTANT: When a peer agent's response contains citation markers like [[cite:search0]], [[cite:file1]], etc., "
|
|
1028
|
+
"you MUST preserve these markers in your response to the user. These markers link to source references and are "
|
|
1029
|
+
"essential for proper attribution. Include them exactly as they appear in the peer's response. DO NOT repeat them without markers.\n\n"
|
|
1030
|
+
"## Available Peer Agents\n"
|
|
1034
1031
|
f"{peer_list_str}"
|
|
1035
1032
|
)
|
|
1036
1033
|
callback_context.state["peer_tool_instructions"] = instruction_text
|
|
@@ -1544,6 +1541,70 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1544
1541
|
)
|
|
1545
1542
|
return False
|
|
1546
1543
|
|
|
1544
|
+
async def notify_artifact_saved(
|
|
1545
|
+
self,
|
|
1546
|
+
artifact_info: ArtifactInfo,
|
|
1547
|
+
a2a_context: Dict[str, Any],
|
|
1548
|
+
function_call_id: Optional[str] = None,
|
|
1549
|
+
) -> None:
|
|
1550
|
+
"""
|
|
1551
|
+
Publishes an artifact saved notification signal.
|
|
1552
|
+
|
|
1553
|
+
This is a separate event from ArtifactCreationProgressData and does not
|
|
1554
|
+
follow the start->updates->end protocol. It's a single notification that
|
|
1555
|
+
an artifact has been successfully saved to storage.
|
|
1556
|
+
|
|
1557
|
+
Args:
|
|
1558
|
+
artifact_info: Information about the saved artifact
|
|
1559
|
+
a2a_context: The A2A context dictionary for the current task
|
|
1560
|
+
function_call_id: Optional function call ID if artifact was created by a tool
|
|
1561
|
+
"""
|
|
1562
|
+
log_identifier = (
|
|
1563
|
+
f"{self.log_identifier}[ArtifactSaved:{artifact_info.filename}]"
|
|
1564
|
+
)
|
|
1565
|
+
|
|
1566
|
+
try:
|
|
1567
|
+
# Create artifact saved signal
|
|
1568
|
+
artifact_signal = ArtifactSavedData(
|
|
1569
|
+
type="artifact_saved",
|
|
1570
|
+
filename=artifact_info.filename,
|
|
1571
|
+
version=artifact_info.version,
|
|
1572
|
+
mime_type=artifact_info.mime_type or "application/octet-stream",
|
|
1573
|
+
size_bytes=artifact_info.size,
|
|
1574
|
+
description=artifact_info.description,
|
|
1575
|
+
function_call_id=function_call_id,
|
|
1576
|
+
)
|
|
1577
|
+
|
|
1578
|
+
# Create and publish status update event
|
|
1579
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
1580
|
+
context_id = a2a_context.get("contextId")
|
|
1581
|
+
|
|
1582
|
+
status_update_event = a2a.create_data_signal_event(
|
|
1583
|
+
task_id=logical_task_id,
|
|
1584
|
+
context_id=context_id,
|
|
1585
|
+
signal_data=artifact_signal,
|
|
1586
|
+
agent_name=self.agent_name,
|
|
1587
|
+
)
|
|
1588
|
+
|
|
1589
|
+
await self._publish_status_update_with_buffer_flush(
|
|
1590
|
+
status_update_event,
|
|
1591
|
+
a2a_context,
|
|
1592
|
+
skip_buffer_flush=False,
|
|
1593
|
+
)
|
|
1594
|
+
|
|
1595
|
+
log.debug(
|
|
1596
|
+
"%s Published artifact saved notification for '%s' v%s.",
|
|
1597
|
+
log_identifier,
|
|
1598
|
+
artifact_info.filename,
|
|
1599
|
+
artifact_info.version,
|
|
1600
|
+
)
|
|
1601
|
+
except Exception as e:
|
|
1602
|
+
log.error(
|
|
1603
|
+
"%s Failed to publish artifact saved notification: %s",
|
|
1604
|
+
log_identifier,
|
|
1605
|
+
e,
|
|
1606
|
+
)
|
|
1607
|
+
|
|
1547
1608
|
async def _publish_status_update_with_buffer_flush(
|
|
1548
1609
|
self,
|
|
1549
1610
|
status_update_event: TaskStatusUpdateEvent,
|
|
@@ -1738,8 +1799,13 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1738
1799
|
is_final_turn_event = not adk_event.partial
|
|
1739
1800
|
|
|
1740
1801
|
try:
|
|
1741
|
-
from solace_agent_mesh_enterprise.auth.tool_auth import
|
|
1742
|
-
|
|
1802
|
+
from solace_agent_mesh_enterprise.auth.tool_auth import (
|
|
1803
|
+
handle_tool_auth_event,
|
|
1804
|
+
)
|
|
1805
|
+
|
|
1806
|
+
auth_status_update = await handle_tool_auth_event(
|
|
1807
|
+
adk_event, self, a2a_context
|
|
1808
|
+
)
|
|
1743
1809
|
if auth_status_update:
|
|
1744
1810
|
await self._publish_status_update_with_buffer_flush(
|
|
1745
1811
|
auth_status_update,
|
|
@@ -1754,6 +1820,25 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1754
1820
|
if adk_event.content and adk_event.content.parts:
|
|
1755
1821
|
for part in adk_event.content.parts:
|
|
1756
1822
|
if part.text is not None:
|
|
1823
|
+
# Check if this is a new turn by comparing invocation_id
|
|
1824
|
+
if adk_event.invocation_id:
|
|
1825
|
+
task_context.check_and_update_invocation(
|
|
1826
|
+
adk_event.invocation_id
|
|
1827
|
+
)
|
|
1828
|
+
is_first_text = task_context.is_first_text_in_turn()
|
|
1829
|
+
should_add_spacing = task_context.should_add_turn_spacing()
|
|
1830
|
+
|
|
1831
|
+
# Add spacing if this is the first text of a new turn
|
|
1832
|
+
# We add it BEFORE the text, regardless of current buffer content
|
|
1833
|
+
if should_add_spacing and is_first_text:
|
|
1834
|
+
# Add double newline to separate turns (new paragraph)
|
|
1835
|
+
task_context.append_to_streaming_buffer("\n\n")
|
|
1836
|
+
log.debug(
|
|
1837
|
+
"%s Added turn spacing before new invocation %s",
|
|
1838
|
+
log_id_main,
|
|
1839
|
+
adk_event.invocation_id,
|
|
1840
|
+
)
|
|
1841
|
+
|
|
1757
1842
|
task_context.append_to_streaming_buffer(part.text)
|
|
1758
1843
|
log.debug(
|
|
1759
1844
|
"%s Appended text to buffer. New buffer size: %d bytes",
|
|
@@ -2203,6 +2288,19 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2203
2288
|
self.log_identifier,
|
|
2204
2289
|
len(task_context.produced_artifacts),
|
|
2205
2290
|
)
|
|
2291
|
+
else:
|
|
2292
|
+
if not task_context:
|
|
2293
|
+
log.warning(
|
|
2294
|
+
"%s TaskExecutionContext not found for task %s during finalization, cannot attach produced artifacts.",
|
|
2295
|
+
self.log_identifier,
|
|
2296
|
+
logical_task_id,
|
|
2297
|
+
)
|
|
2298
|
+
else:
|
|
2299
|
+
log.debug(
|
|
2300
|
+
"%s No produced artifacts to attach for task %s.",
|
|
2301
|
+
self.log_identifier,
|
|
2302
|
+
logical_task_id,
|
|
2303
|
+
)
|
|
2206
2304
|
|
|
2207
2305
|
# Add token usage summary
|
|
2208
2306
|
if task_context:
|
|
@@ -2640,11 +2738,24 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2640
2738
|
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
2641
2739
|
namespace = self.get_config("namespace")
|
|
2642
2740
|
|
|
2741
|
+
# Detect context limit errors and provide user-friendly message
|
|
2742
|
+
error_message = "An unexpected error occurred during tool execution. Please try your request again. If the problem persists, contact an administrator."
|
|
2743
|
+
|
|
2744
|
+
if isinstance(exception, BadRequestError):
|
|
2745
|
+
# Use centralized error handler
|
|
2746
|
+
error_message, is_context_limit = get_error_message(exception)
|
|
2747
|
+
|
|
2748
|
+
if is_context_limit:
|
|
2749
|
+
log.error(
|
|
2750
|
+
"%s Context limit exceeded for task %s. Error: %s",
|
|
2751
|
+
self.log_identifier,
|
|
2752
|
+
logical_task_id,
|
|
2753
|
+
exception,
|
|
2754
|
+
)
|
|
2755
|
+
|
|
2643
2756
|
failed_status = a2a.create_task_status(
|
|
2644
2757
|
state=TaskState.failed,
|
|
2645
|
-
message=a2a.create_agent_text_message(
|
|
2646
|
-
text="An unexpected error occurred during tool execution. Please try your request again. If the problem persists, contact an administrator."
|
|
2647
|
-
),
|
|
2758
|
+
message=a2a.create_agent_text_message(text=error_message),
|
|
2648
2759
|
)
|
|
2649
2760
|
|
|
2650
2761
|
final_task = a2a.create_final_task(
|
|
@@ -2771,7 +2882,9 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2771
2882
|
with self.active_tasks_lock:
|
|
2772
2883
|
task_context = self.active_tasks.get(logical_task_id)
|
|
2773
2884
|
if task_context:
|
|
2774
|
-
original_message =
|
|
2885
|
+
original_message = (
|
|
2886
|
+
task_context.get_original_solace_message()
|
|
2887
|
+
)
|
|
2775
2888
|
|
|
2776
2889
|
if original_message:
|
|
2777
2890
|
try:
|
|
@@ -2953,6 +3066,17 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2953
3066
|
main_task_id,
|
|
2954
3067
|
)
|
|
2955
3068
|
|
|
3069
|
+
# Validate agent access is allowed
|
|
3070
|
+
validate_agent_access(
|
|
3071
|
+
user_config=user_config,
|
|
3072
|
+
target_agent_name=target_agent_name,
|
|
3073
|
+
validation_context={
|
|
3074
|
+
"delegating_agent": self.get_config("agent_name"),
|
|
3075
|
+
"source": "agent_delegation",
|
|
3076
|
+
},
|
|
3077
|
+
log_identifier=log_identifier_helper,
|
|
3078
|
+
)
|
|
3079
|
+
|
|
2956
3080
|
peer_request_topic = self._get_agent_request_topic(target_agent_name)
|
|
2957
3081
|
|
|
2958
3082
|
# Create a compliant SendMessageRequest
|
|
@@ -3103,6 +3227,31 @@ class SamAgentComponent(SamComponentBase):
|
|
|
3103
3227
|
or "No description available.",
|
|
3104
3228
|
}
|
|
3105
3229
|
)
|
|
3230
|
+
elif isinstance(tool, OpenAPIToolset):
|
|
3231
|
+
try:
|
|
3232
|
+
log.debug(
|
|
3233
|
+
"%s Retrieving tools from OpenAPIToolset for Agent %s...",
|
|
3234
|
+
self.log_identifier,
|
|
3235
|
+
self.agent_name,
|
|
3236
|
+
)
|
|
3237
|
+
openapi_tools = await tool.get_tools()
|
|
3238
|
+
except Exception as e:
|
|
3239
|
+
log.error(
|
|
3240
|
+
"%s Error retrieving tools from OpenAPIToolset for Agent Card %s: %s",
|
|
3241
|
+
self.log_identifier,
|
|
3242
|
+
self.agent_name,
|
|
3243
|
+
e,
|
|
3244
|
+
)
|
|
3245
|
+
continue
|
|
3246
|
+
for openapi_tool in openapi_tools:
|
|
3247
|
+
tool_manifest.append(
|
|
3248
|
+
{
|
|
3249
|
+
"id": openapi_tool.name,
|
|
3250
|
+
"name": openapi_tool.name,
|
|
3251
|
+
"description": openapi_tool.description
|
|
3252
|
+
or "No description available.",
|
|
3253
|
+
}
|
|
3254
|
+
)
|
|
3106
3255
|
else:
|
|
3107
3256
|
tool_name = getattr(tool, "name", getattr(tool, "__name__", None))
|
|
3108
3257
|
if tool_name is not None:
|
|
@@ -3160,6 +3309,7 @@ class SamAgentComponent(SamComponentBase):
|
|
|
3160
3309
|
"%s _perform_async_init: _async_init_future is None or already done before signaling failure.",
|
|
3161
3310
|
self.log_identifier,
|
|
3162
3311
|
)
|
|
3312
|
+
raise e
|
|
3163
3313
|
|
|
3164
3314
|
def cleanup(self):
|
|
3165
3315
|
"""Clean up resources on component shutdown."""
|
|
@@ -3288,6 +3438,80 @@ class SamAgentComponent(SamComponentBase):
|
|
|
3288
3438
|
"""Returns the dedicated asyncio event loop for this component's async tasks."""
|
|
3289
3439
|
return self._async_loop
|
|
3290
3440
|
|
|
3441
|
+
def publish_data_signal_from_thread(
|
|
3442
|
+
self,
|
|
3443
|
+
a2a_context: Dict[str, Any],
|
|
3444
|
+
signal_data: BaseModel,
|
|
3445
|
+
skip_buffer_flush: bool = False,
|
|
3446
|
+
log_identifier: Optional[str] = None,
|
|
3447
|
+
) -> bool:
|
|
3448
|
+
"""
|
|
3449
|
+
Publishes a data signal status update from any thread by scheduling it on the async loop.
|
|
3450
|
+
|
|
3451
|
+
This is a convenience method for tools and callbacks that need to publish status updates
|
|
3452
|
+
but are not running in an async context. It handles:
|
|
3453
|
+
1. Extracting task_id and context_id from a2a_context
|
|
3454
|
+
2. Creating the status update event
|
|
3455
|
+
3. Checking if the async loop is available and running
|
|
3456
|
+
4. Scheduling the publish operation on the async loop
|
|
3457
|
+
|
|
3458
|
+
Args:
|
|
3459
|
+
a2a_context: The A2A context dictionary containing logical_task_id and contextId
|
|
3460
|
+
signal_data: A Pydantic BaseModel instance (e.g., AgentProgressUpdateData,
|
|
3461
|
+
DeepResearchProgressData, ArtifactCreationProgressData)
|
|
3462
|
+
skip_buffer_flush: If True, skip buffer flushing before publishing
|
|
3463
|
+
log_identifier: Optional log identifier for debugging
|
|
3464
|
+
|
|
3465
|
+
Returns:
|
|
3466
|
+
bool: True if the publish was successfully scheduled, False otherwise
|
|
3467
|
+
"""
|
|
3468
|
+
from ...common import a2a
|
|
3469
|
+
|
|
3470
|
+
log_id = log_identifier or f"{self.log_identifier}[PublishDataSignal]"
|
|
3471
|
+
|
|
3472
|
+
if not a2a_context:
|
|
3473
|
+
log.error("%s No a2a_context provided. Cannot publish data signal.", log_id)
|
|
3474
|
+
return False
|
|
3475
|
+
|
|
3476
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
3477
|
+
context_id = a2a_context.get("contextId")
|
|
3478
|
+
|
|
3479
|
+
if not logical_task_id:
|
|
3480
|
+
log.error("%s No logical_task_id in a2a_context. Cannot publish data signal.", log_id)
|
|
3481
|
+
return False
|
|
3482
|
+
|
|
3483
|
+
# Create status update event using the standard data signal pattern
|
|
3484
|
+
status_update_event = a2a.create_data_signal_event(
|
|
3485
|
+
task_id=logical_task_id,
|
|
3486
|
+
context_id=context_id,
|
|
3487
|
+
signal_data=signal_data,
|
|
3488
|
+
agent_name=self.agent_name,
|
|
3489
|
+
)
|
|
3490
|
+
|
|
3491
|
+
# Get the async loop and schedule the publish
|
|
3492
|
+
loop = self.get_async_loop()
|
|
3493
|
+
if loop and loop.is_running():
|
|
3494
|
+
asyncio.run_coroutine_threadsafe(
|
|
3495
|
+
self._publish_status_update_with_buffer_flush(
|
|
3496
|
+
status_update_event,
|
|
3497
|
+
a2a_context,
|
|
3498
|
+
skip_buffer_flush=skip_buffer_flush,
|
|
3499
|
+
),
|
|
3500
|
+
loop,
|
|
3501
|
+
)
|
|
3502
|
+
log.debug(
|
|
3503
|
+
"%s Scheduled data signal status update (type: %s).",
|
|
3504
|
+
log_id,
|
|
3505
|
+
type(signal_data).__name__,
|
|
3506
|
+
)
|
|
3507
|
+
return True
|
|
3508
|
+
else:
|
|
3509
|
+
log.error(
|
|
3510
|
+
"%s Async loop not available or not running. Cannot publish data signal.",
|
|
3511
|
+
log_id,
|
|
3512
|
+
)
|
|
3513
|
+
return False
|
|
3514
|
+
|
|
3291
3515
|
def set_agent_system_instruction_string(self, instruction_string: str) -> None:
|
|
3292
3516
|
"""
|
|
3293
3517
|
Sets a static string to be injected into the LLM system prompt.
|
|
@@ -3551,16 +3775,62 @@ class SamAgentComponent(SamComponentBase):
|
|
|
3551
3775
|
)
|
|
3552
3776
|
return raw_text, [], ""
|
|
3553
3777
|
|
|
3778
|
+
def _publish_agent_card(self) -> None:
|
|
3779
|
+
"""
|
|
3780
|
+
Schedules periodic publishing of the agent card based on configuration.
|
|
3781
|
+
"""
|
|
3782
|
+
try:
|
|
3783
|
+
publish_interval_sec = self.agent_card_publishing_config.get(
|
|
3784
|
+
"interval_seconds"
|
|
3785
|
+
)
|
|
3786
|
+
if publish_interval_sec and publish_interval_sec > 0:
|
|
3787
|
+
log.info(
|
|
3788
|
+
"%s Scheduling agent card publishing every %d seconds.",
|
|
3789
|
+
self.log_identifier,
|
|
3790
|
+
publish_interval_sec,
|
|
3791
|
+
)
|
|
3792
|
+
# Register timer with callback
|
|
3793
|
+
self.add_timer(
|
|
3794
|
+
delay_ms=1000,
|
|
3795
|
+
timer_id=self._card_publish_timer_id,
|
|
3796
|
+
interval_ms=publish_interval_sec * 1000,
|
|
3797
|
+
callback=lambda timer_data: publish_agent_card(self),
|
|
3798
|
+
)
|
|
3799
|
+
else:
|
|
3800
|
+
log.warning(
|
|
3801
|
+
"%s Agent card publishing interval not configured or invalid, card will not be published periodically.",
|
|
3802
|
+
self.log_identifier,
|
|
3803
|
+
)
|
|
3804
|
+
except Exception as e:
|
|
3805
|
+
log.exception(
|
|
3806
|
+
"%s Error during _publish_agent_card setup: %s",
|
|
3807
|
+
self.log_identifier,
|
|
3808
|
+
e,
|
|
3809
|
+
)
|
|
3810
|
+
raise e
|
|
3811
|
+
|
|
3554
3812
|
async def _async_setup_and_run(self) -> None:
|
|
3555
3813
|
"""
|
|
3556
3814
|
Main async logic for the agent component.
|
|
3557
3815
|
This is called by the base class's `_run_async_operations`.
|
|
3558
3816
|
"""
|
|
3559
|
-
|
|
3560
|
-
|
|
3817
|
+
try:
|
|
3818
|
+
# Call base class to initialize Trust Manager
|
|
3819
|
+
await super()._async_setup_and_run()
|
|
3820
|
+
|
|
3821
|
+
# Perform agent-specific async initialization
|
|
3822
|
+
await self._perform_async_init()
|
|
3823
|
+
|
|
3824
|
+
self._publish_agent_card()
|
|
3561
3825
|
|
|
3562
|
-
|
|
3563
|
-
|
|
3826
|
+
except Exception as e:
|
|
3827
|
+
log.exception(
|
|
3828
|
+
"%s Error during _async_setup_and_run: %s",
|
|
3829
|
+
self.log_identifier,
|
|
3830
|
+
e,
|
|
3831
|
+
)
|
|
3832
|
+
self.cleanup()
|
|
3833
|
+
raise e
|
|
3564
3834
|
|
|
3565
3835
|
def _pre_async_cleanup(self) -> None:
|
|
3566
3836
|
"""
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
# Purpose: Fix event filtering and function response handling in LLM flows
|
|
8
8
|
# =============================================================================
|
|
9
9
|
import google.adk.flows.llm_flows.contents
|
|
10
|
+
from google.adk.flows.llm_flows.contents import _contains_empty_content
|
|
10
11
|
from google.adk.flows.llm_flows.contents import _is_event_belongs_to_branch
|
|
11
12
|
from google.adk.flows.llm_flows.contents import _is_auth_event
|
|
12
|
-
from google.adk.flows.llm_flows.contents import
|
|
13
|
+
from google.adk.flows.llm_flows.contents import _present_other_agent_message
|
|
13
14
|
from google.adk.flows.llm_flows.contents import _is_other_agent_reply
|
|
14
15
|
from google.adk.flows.llm_flows.contents import _rearrange_events_for_async_function_responses_in_history
|
|
15
16
|
from google.adk.flows.llm_flows.contents import remove_client_function_call_id
|
|
@@ -39,16 +40,7 @@ def _patch_get_contents(
|
|
|
39
40
|
# Parse the events, leaving the contents and the function calls and
|
|
40
41
|
# responses from the current agent.
|
|
41
42
|
for event in events:
|
|
42
|
-
if (
|
|
43
|
-
not event.content
|
|
44
|
-
or not event.content.role
|
|
45
|
-
or not event.content.parts
|
|
46
|
-
or (event.content.parts[0].text == '' and not event.content.parts[0].function_response)
|
|
47
|
-
):
|
|
48
|
-
# Skip events without content, or generated neither by user nor by model
|
|
49
|
-
# or has empty text.
|
|
50
|
-
# E.g. events purely for mutating session states.
|
|
51
|
-
|
|
43
|
+
if _contains_empty_content(event):
|
|
52
44
|
continue
|
|
53
45
|
if not _is_event_belongs_to_branch(current_branch, event):
|
|
54
46
|
# Skip events not belong to current branch.
|
|
@@ -56,11 +48,11 @@ def _patch_get_contents(
|
|
|
56
48
|
if _is_auth_event(event):
|
|
57
49
|
# Skip auth events.
|
|
58
50
|
continue
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
if _is_other_agent_reply(agent_name, event):
|
|
52
|
+
if converted_event := _present_other_agent_message(event):
|
|
53
|
+
filtered_events.append(converted_event)
|
|
54
|
+
else:
|
|
55
|
+
filtered_events.append(event)
|
|
64
56
|
|
|
65
57
|
# Rearrange events for proper function call/response pairing
|
|
66
58
|
result_events = filtered_events
|
|
@@ -45,6 +45,9 @@ class TaskExecutionContext:
|
|
|
45
45
|
self.token_usage_by_model: Dict[str, Dict[str, int]] = {}
|
|
46
46
|
self.token_usage_by_source: Dict[str, Dict[str, int]] = {}
|
|
47
47
|
|
|
48
|
+
# Generic flags storage for task-level state
|
|
49
|
+
self._flags: Dict[str, Any] = {}
|
|
50
|
+
|
|
48
51
|
# Generic security storage (enterprise use only)
|
|
49
52
|
self._security_context: Dict[str, Any] = {}
|
|
50
53
|
|
|
@@ -52,6 +55,11 @@ class TaskExecutionContext:
|
|
|
52
55
|
# Stored here instead of a2a_context to avoid serialization issues
|
|
53
56
|
self._original_solace_message: Optional["SolaceMessage"] = None
|
|
54
57
|
|
|
58
|
+
# Turn tracking for proper spacing between LLM turns
|
|
59
|
+
self._current_invocation_id: Optional[str] = None
|
|
60
|
+
self._first_text_seen_in_turn: bool = False
|
|
61
|
+
self._need_spacing_before_next_text: bool = False
|
|
62
|
+
|
|
55
63
|
def cancel(self) -> None:
|
|
56
64
|
"""Signals that the task should be cancelled."""
|
|
57
65
|
self.cancellation_event.set()
|
|
@@ -354,3 +362,85 @@ class TaskExecutionContext:
|
|
|
354
362
|
"""
|
|
355
363
|
with self.lock:
|
|
356
364
|
return self._original_solace_message
|
|
365
|
+
|
|
366
|
+
def check_and_update_invocation(self, new_invocation_id: str) -> bool:
|
|
367
|
+
"""
|
|
368
|
+
Check if this is a new turn (different invocation_id) and update tracking.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
new_invocation_id: The invocation_id from the current ADK event
|
|
372
|
+
|
|
373
|
+
Returns:
|
|
374
|
+
True if this is a new turn (invocation_id changed), False otherwise
|
|
375
|
+
"""
|
|
376
|
+
with self.lock:
|
|
377
|
+
is_new_turn = (
|
|
378
|
+
self._current_invocation_id is not None
|
|
379
|
+
and self._current_invocation_id != new_invocation_id
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
if is_new_turn:
|
|
383
|
+
# Mark that we need spacing before the next text
|
|
384
|
+
self._need_spacing_before_next_text = True
|
|
385
|
+
|
|
386
|
+
if is_new_turn or self._current_invocation_id is None:
|
|
387
|
+
self._current_invocation_id = new_invocation_id
|
|
388
|
+
self._first_text_seen_in_turn = False
|
|
389
|
+
|
|
390
|
+
return is_new_turn
|
|
391
|
+
|
|
392
|
+
def is_first_text_in_turn(self) -> bool:
|
|
393
|
+
"""
|
|
394
|
+
Check if this is the first text we're seeing in the current turn,
|
|
395
|
+
and mark it as seen.
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
True if this is the first text in the turn, False otherwise
|
|
399
|
+
"""
|
|
400
|
+
with self.lock:
|
|
401
|
+
if not self._first_text_seen_in_turn:
|
|
402
|
+
self._first_text_seen_in_turn = True
|
|
403
|
+
return True
|
|
404
|
+
return False
|
|
405
|
+
|
|
406
|
+
def should_add_turn_spacing(self) -> bool:
|
|
407
|
+
"""
|
|
408
|
+
Check if we need to add spacing before the next text (because it's a new turn).
|
|
409
|
+
This flag is set when a new invocation starts and cleared after spacing is added.
|
|
410
|
+
|
|
411
|
+
Returns:
|
|
412
|
+
True if spacing should be added, False otherwise
|
|
413
|
+
"""
|
|
414
|
+
with self.lock:
|
|
415
|
+
if self._need_spacing_before_next_text:
|
|
416
|
+
self._need_spacing_before_next_text = False
|
|
417
|
+
return True
|
|
418
|
+
return False
|
|
419
|
+
|
|
420
|
+
def set_flag(self, key: str, value: Any) -> None:
|
|
421
|
+
"""
|
|
422
|
+
Set a task-level flag.
|
|
423
|
+
|
|
424
|
+
This method provides a generic mechanism for storing task-level state
|
|
425
|
+
that needs to persist across different parts of the task execution.
|
|
426
|
+
|
|
427
|
+
Args:
|
|
428
|
+
key: The flag name
|
|
429
|
+
value: The flag value
|
|
430
|
+
"""
|
|
431
|
+
with self.lock:
|
|
432
|
+
self._flags[key] = value
|
|
433
|
+
|
|
434
|
+
def get_flag(self, key: str, default: Any = None) -> Any:
|
|
435
|
+
"""
|
|
436
|
+
Get a task-level flag.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
key: The flag name
|
|
440
|
+
default: Default value to return if flag not found
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
The flag value, or default if not found
|
|
444
|
+
"""
|
|
445
|
+
with self.lock:
|
|
446
|
+
return self._flags.get(key, default)
|