solace-agent-mesh 1.11.2__py3-none-any.whl → 1.12.0__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.
- solace_agent_mesh/agent/adk/callbacks.py +177 -10
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +3 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +34 -16
- solace_agent_mesh/agent/adk/runner.py +66 -8
- solace_agent_mesh/agent/adk/setup.py +61 -26
- solace_agent_mesh/agent/protocol/event_handlers.py +48 -0
- solace_agent_mesh/agent/proxies/a2a/component.py +27 -0
- solace_agent_mesh/agent/sac/component.py +84 -2
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +41 -22
- solace_agent_mesh/agent/tools/peer_agent_tool.py +19 -12
- solace_agent_mesh/agent/tools/tool_config_types.py +21 -1
- solace_agent_mesh/agent/utils/artifact_helpers.py +54 -0
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/15ba94aa.e186750d.js +1 -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.28b7c67b.js → 3ac1795d.dc006e20.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.f08618fb.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4667dc50.bf2ad456.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.8e6da617.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/64195356.09dbd087.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.30340bd3.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.95be65d4.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/ab9708a8.3e563275.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/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.08fab659.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.b241af3e.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.4ca7d2e2.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +4 -4
- 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 +14 -12
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +30 -9
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +6 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +4 -4
- 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 +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/{kubernetes-deployment → kubernetes}/index.html +6 -6
- 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 +11 -6
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +23 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +17 -8
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +6 -5
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +4 -4
- 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 +25 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/migrations/platform-service-split/index.html +85 -0
- solace_agent_mesh/assets/docs/lunr-index-1767712284328.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1767712284328.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/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 +29 -2
- solace_agent_mesh/cli/commands/init_cmd/platform_service_step.py +85 -0
- solace_agent_mesh/cli/commands/tools_cmd.py +315 -0
- solace_agent_mesh/cli/main.py +2 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-Dj3JtK42.js → authCallback-8Nihi8rv.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-ZKk9kEJ5.js → client-DYtZN8p-.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-BYGUHQMk.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-D2CSH1bp.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BNV4kZN0.js → vendor-XBWAmrun.js} +106 -101
- 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/ui-version.json +1 -1
- 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 +28 -0
- solace_agent_mesh/common/error_handlers.py +83 -0
- solace_agent_mesh/common/sam_events/event_service.py +2 -2
- solace_agent_mesh/config_portal/backend/common.py +2 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ZV-jX48T.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-ba77705e.js → manifest-ce5bc5da.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- 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/auth_interface.py +103 -0
- solace_agent_mesh/gateway/base/component.py +68 -1
- solace_agent_mesh/gateway/generic/component.py +195 -30
- solace_agent_mesh/gateway/http_sse/app.py +23 -6
- solace_agent_mesh/gateway/http_sse/component.py +9 -61
- solace_agent_mesh/gateway/http_sse/dependencies.py +9 -51
- solace_agent_mesh/gateway/http_sse/main.py +28 -418
- 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 +2 -2
- 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/prompt_model.py +1 -1
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +1 -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 +4 -4
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +16 -15
- solace_agent_mesh/gateway/http_sse/routers/auth.py +61 -132
- solace_agent_mesh/gateway/http_sse/routers/config.py +12 -8
- 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/session_responses.py +2 -2
- 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 +2 -1
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +2 -1
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +3 -3
- solace_agent_mesh/gateway/http_sse/routers/speech.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +3 -2
- solace_agent_mesh/gateway/http_sse/routers/users.py +1 -1
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +2 -1
- solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +1 -1
- 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/session_service.py +4 -4
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +1 -1
- solace_agent_mesh/services/platform/__init__.py +23 -12
- solace_agent_mesh/services/platform/api/dependencies.py +23 -16
- solace_agent_mesh/services/platform/api/main.py +118 -43
- solace_agent_mesh/services/platform/api/routers/__init__.py +12 -3
- solace_agent_mesh/services/platform/api/routers/health_router.py +31 -0
- solace_agent_mesh/services/platform/app.py +101 -7
- solace_agent_mesh/services/platform/component.py +552 -33
- 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 +291 -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/platform.yaml +49 -0
- solace_agent_mesh/templates/webui.yaml +12 -3
- {solace_agent_mesh-1.11.2.dist-info → solace_agent_mesh-1.12.0.dist-info}/METADATA +2 -1
- {solace_agent_mesh-1.11.2.dist-info → solace_agent_mesh-1.12.0.dist-info}/RECORD +214 -258
- 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/15ba94aa.92fea363.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/240a0364.9ad94d1b.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/3ff0015d.2ddc75c0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.90a87880.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/66d4869e.b77431fc.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/8024126c.fa0e7186.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/81a99df0.2484b8d9.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9bb13469.b2333011.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e04b235d.52cb25ed.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.b1068f9b.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.4488e34c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.250993bf.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js +0 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.9e0813a2.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1765810064709.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1765810064709.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/main-BcUaNZ-Q.css +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-vjch4RYc.js +0 -435
- 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-DiOiAjzL.js +0 -103
- 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/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/templates_llm.txt +0 -147
- /solace_agent_mesh/assets/docs/assets/js/{main.7acf7ace.js.LICENSE.txt → main.b241af3e.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.11.2.dist-info → solace_agent_mesh-1.12.0.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.11.2.dist-info → solace_agent_mesh-1.12.0.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.11.2.dist-info → solace_agent_mesh-1.12.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -15,6 +15,7 @@ from google.adk.models.llm_request import LlmRequest
|
|
|
15
15
|
from google.adk.models.llm_response import LlmResponse
|
|
16
16
|
from google.adk.runners import Runner
|
|
17
17
|
from google.adk.tools import BaseTool, ToolContext
|
|
18
|
+
from google.adk.tools.mcp_tool import MCPTool
|
|
18
19
|
from google.adk.tools.mcp_tool.mcp_session_manager import (
|
|
19
20
|
SseServerParams,
|
|
20
21
|
StdioConnectionParams,
|
|
@@ -625,14 +626,30 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
|
|
|
625
626
|
else:
|
|
626
627
|
raise ValueError(f"Unsupported MCP connection type: {connection_type}")
|
|
627
628
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
629
|
+
# Determine tool filter based on configuration
|
|
630
|
+
# tool_name, allow_list, and deny_list are mutually exclusive (validated by pydantic)
|
|
631
|
+
tool_filter = None
|
|
632
|
+
filter_description = "none (all tools)"
|
|
633
|
+
|
|
634
|
+
if tool_config_model.tool_name:
|
|
635
|
+
# Backward compatible: single tool name becomes a list
|
|
636
|
+
tool_filter = [tool_config_model.tool_name]
|
|
637
|
+
filter_description = f"tool_name='{tool_config_model.tool_name}'"
|
|
638
|
+
elif tool_config_model.allow_list:
|
|
639
|
+
# Allow list: pass directly as list of tool names
|
|
640
|
+
tool_filter = tool_config_model.allow_list
|
|
641
|
+
filter_description = f"allow_list={tool_config_model.allow_list}"
|
|
642
|
+
elif tool_config_model.deny_list:
|
|
643
|
+
# Deny list: create a ToolPredicate that excludes these tools
|
|
644
|
+
deny_set = set(tool_config_model.deny_list)
|
|
645
|
+
tool_filter = lambda tool, ctx=None, _deny=deny_set: tool.name not in _deny
|
|
646
|
+
filter_description = f"deny_list={tool_config_model.deny_list}"
|
|
647
|
+
|
|
648
|
+
if tool_filter:
|
|
632
649
|
log.info(
|
|
633
|
-
"%s MCP tool config specifies
|
|
650
|
+
"%s MCP tool config specifies filter: %s",
|
|
634
651
|
component.log_identifier,
|
|
635
|
-
|
|
652
|
+
filter_description,
|
|
636
653
|
)
|
|
637
654
|
|
|
638
655
|
additional_params = {}
|
|
@@ -647,7 +664,7 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
|
|
|
647
664
|
tool_type="mcp",
|
|
648
665
|
tool_config=tool_config,
|
|
649
666
|
connection_params=connection_params,
|
|
650
|
-
tool_filter=
|
|
667
|
+
tool_filter=tool_filter,
|
|
651
668
|
)
|
|
652
669
|
except Exception as e:
|
|
653
670
|
log.error(
|
|
@@ -664,7 +681,8 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
|
|
|
664
681
|
# Create the EmbedResolvingMCPToolset with base parameters
|
|
665
682
|
toolset_params = {
|
|
666
683
|
"connection_params": connection_params,
|
|
667
|
-
"tool_filter":
|
|
684
|
+
"tool_filter": tool_filter,
|
|
685
|
+
"tool_name_prefix": tool_config_model.tool_name_prefix,
|
|
668
686
|
"tool_config": tool_config,
|
|
669
687
|
}
|
|
670
688
|
|
|
@@ -677,7 +695,7 @@ async def _load_mcp_tool(component: "SamAgentComponent", tool_config: Dict) -> T
|
|
|
677
695
|
log.info(
|
|
678
696
|
"%s Initialized MCPToolset (filter: %s) for server: %s",
|
|
679
697
|
component.log_identifier,
|
|
680
|
-
|
|
698
|
+
filter_description,
|
|
681
699
|
connection_params,
|
|
682
700
|
)
|
|
683
701
|
|
|
@@ -893,19 +911,7 @@ async def load_adk_tools(
|
|
|
893
911
|
for tool in new_tools:
|
|
894
912
|
if isinstance(tool, EmbedResolvingMCPToolset):
|
|
895
913
|
# Special handling for MCPToolset which can load multiple tools
|
|
896
|
-
|
|
897
|
-
mcp_tools = await tool.get_tools()
|
|
898
|
-
for mcp_tool in mcp_tools:
|
|
899
|
-
_check_and_register_tool_name(
|
|
900
|
-
mcp_tool.name, "mcp", loaded_tool_names
|
|
901
|
-
)
|
|
902
|
-
except Exception as e:
|
|
903
|
-
log.error(
|
|
904
|
-
"%s Failed to discover tools from MCP server for name registration: %s",
|
|
905
|
-
component.log_identifier,
|
|
906
|
-
str(e),
|
|
907
|
-
)
|
|
908
|
-
raise
|
|
914
|
+
await _check_and_register_tool_name_mcp(component, loaded_tool_names, tool)
|
|
909
915
|
else:
|
|
910
916
|
tool_name = getattr(
|
|
911
917
|
tool, "name", getattr(tool, "__name__", None)
|
|
@@ -949,6 +955,25 @@ async def load_adk_tools(
|
|
|
949
955
|
return loaded_tools, enabled_builtin_tools, cleanup_hooks
|
|
950
956
|
|
|
951
957
|
|
|
958
|
+
async def _check_and_register_tool_name_mcp(component, loaded_tool_names: set[str], tool: EmbedResolvingMCPToolset):
|
|
959
|
+
try:
|
|
960
|
+
mcp_tools: list[MCPTool] = await tool.get_tools()
|
|
961
|
+
for mcp_tool in mcp_tools:
|
|
962
|
+
toolname = mcp_tool.name
|
|
963
|
+
if tool.tool_name_prefix != None:
|
|
964
|
+
toolname = f"{tool.tool_name_prefix}_{toolname}"
|
|
965
|
+
_check_and_register_tool_name(
|
|
966
|
+
toolname, "mcp", loaded_tool_names
|
|
967
|
+
)
|
|
968
|
+
except Exception as e:
|
|
969
|
+
log.error(
|
|
970
|
+
"%s Failed to discover tools from MCP server for name registration: %s",
|
|
971
|
+
component.log_identifier,
|
|
972
|
+
str(e),
|
|
973
|
+
)
|
|
974
|
+
raise
|
|
975
|
+
|
|
976
|
+
|
|
952
977
|
def initialize_adk_agent(
|
|
953
978
|
component,
|
|
954
979
|
loaded_explicit_tools: List[Union[BaseTool, Callable]],
|
|
@@ -1221,7 +1246,17 @@ def initialize_adk_agent(
|
|
|
1221
1246
|
# The callbacks are executed in the order they are added to this list.
|
|
1222
1247
|
callbacks_in_order_for_after_model = []
|
|
1223
1248
|
|
|
1224
|
-
# 1.
|
|
1249
|
+
# 1. Pre-register long-running tools (must run BEFORE tool execution)
|
|
1250
|
+
preregister_cb = functools.partial(
|
|
1251
|
+
adk_callbacks.preregister_long_running_tools_callback, host_component=component
|
|
1252
|
+
)
|
|
1253
|
+
callbacks_in_order_for_after_model.append(preregister_cb)
|
|
1254
|
+
log.debug(
|
|
1255
|
+
"%s Added preregister_long_running_tools_callback to after_model chain.",
|
|
1256
|
+
component.log_identifier,
|
|
1257
|
+
)
|
|
1258
|
+
|
|
1259
|
+
# 2. Fenced Artifact Block Processing (must run before auto-continue)
|
|
1225
1260
|
artifact_block_cb = functools.partial(
|
|
1226
1261
|
adk_callbacks.process_artifact_blocks_callback, host_component=component
|
|
1227
1262
|
)
|
|
@@ -1231,7 +1266,7 @@ def initialize_adk_agent(
|
|
|
1231
1266
|
component.log_identifier,
|
|
1232
1267
|
)
|
|
1233
1268
|
|
|
1234
|
-
#
|
|
1269
|
+
# 3. Auto-Continuation (may short-circuit the chain)
|
|
1235
1270
|
auto_continue_cb = functools.partial(
|
|
1236
1271
|
adk_callbacks.auto_continue_on_max_tokens_callback, host_component=component
|
|
1237
1272
|
)
|
|
@@ -1241,13 +1276,13 @@ def initialize_adk_agent(
|
|
|
1241
1276
|
component.log_identifier,
|
|
1242
1277
|
)
|
|
1243
1278
|
|
|
1244
|
-
#
|
|
1279
|
+
# 4. Solace LLM Response Logging
|
|
1245
1280
|
solace_llm_response_cb = functools.partial(
|
|
1246
1281
|
adk_callbacks.solace_llm_response_callback, host_component=component
|
|
1247
1282
|
)
|
|
1248
1283
|
callbacks_in_order_for_after_model.append(solace_llm_response_cb)
|
|
1249
1284
|
|
|
1250
|
-
#
|
|
1285
|
+
# 5. Chunk Logging
|
|
1251
1286
|
log_chunk_cb = functools.partial(
|
|
1252
1287
|
adk_callbacks.log_streaming_chunk_callback, host_component=component
|
|
1253
1288
|
)
|
|
@@ -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,
|
|
@@ -31,6 +33,7 @@ from ...agent.adk.callbacks import _publish_data_part_status_update
|
|
|
31
33
|
from ...agent.adk.runner import TaskCancelledError, run_adk_async_task_thread_wrapper
|
|
32
34
|
from ...agent.utils.artifact_helpers import generate_artifact_metadata_summary
|
|
33
35
|
from ...common import a2a
|
|
36
|
+
from ...common.error_handlers import get_error_message
|
|
34
37
|
from ...common.utils.embeds.constants import (
|
|
35
38
|
EMBED_DELIMITER_OPEN,
|
|
36
39
|
EMBED_DELIMITER_CLOSE,
|
|
@@ -975,6 +978,51 @@ async def handle_a2a_request(component, message: SolaceMessage):
|
|
|
975
978
|
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
976
979
|
return None
|
|
977
980
|
|
|
981
|
+
except BadRequestError as e:
|
|
982
|
+
log.error(
|
|
983
|
+
"%s Bad Request error handling A2A request: %s", component.log_identifier, e
|
|
984
|
+
)
|
|
985
|
+
|
|
986
|
+
# Use centralized error handler
|
|
987
|
+
error_message, is_context_limit = get_error_message(e)
|
|
988
|
+
|
|
989
|
+
if is_context_limit:
|
|
990
|
+
log.error(
|
|
991
|
+
"%s Context limit exceeded for task %s",
|
|
992
|
+
component.log_identifier,
|
|
993
|
+
logical_task_id,
|
|
994
|
+
)
|
|
995
|
+
|
|
996
|
+
error_response = a2a.create_invalid_request_error_response(
|
|
997
|
+
message=error_message,
|
|
998
|
+
request_id=jsonrpc_request_id,
|
|
999
|
+
data={"taskId": logical_task_id},
|
|
1000
|
+
)
|
|
1001
|
+
target_topic = reply_topic_from_peer or (
|
|
1002
|
+
get_client_response_topic(namespace, client_id) if client_id else None
|
|
1003
|
+
)
|
|
1004
|
+
if target_topic:
|
|
1005
|
+
component.publish_a2a_message(
|
|
1006
|
+
error_response.model_dump(exclude_none=True),
|
|
1007
|
+
target_topic,
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
try:
|
|
1011
|
+
message.call_negative_acknowledgements()
|
|
1012
|
+
log.warning(
|
|
1013
|
+
"%s NACKed original A2A request due to bad request error.",
|
|
1014
|
+
component.log_identifier,
|
|
1015
|
+
)
|
|
1016
|
+
except Exception as nack_e:
|
|
1017
|
+
log.error(
|
|
1018
|
+
"%s Failed to NACK message after bad request error: %s",
|
|
1019
|
+
component.log_identifier,
|
|
1020
|
+
nack_e,
|
|
1021
|
+
)
|
|
1022
|
+
|
|
1023
|
+
component.handle_error(e, Event(EventType.MESSAGE, message))
|
|
1024
|
+
return None
|
|
1025
|
+
|
|
978
1026
|
except OperationalError as e:
|
|
979
1027
|
log.error(
|
|
980
1028
|
"%s Database error while processing A2A request: %s",
|
|
@@ -28,6 +28,7 @@ from a2a.types import (
|
|
|
28
28
|
Artifact,
|
|
29
29
|
CancelTaskRequest,
|
|
30
30
|
DataPart,
|
|
31
|
+
InternalError,
|
|
31
32
|
Message,
|
|
32
33
|
SendMessageRequest,
|
|
33
34
|
SendStreamingMessageRequest,
|
|
@@ -322,6 +323,8 @@ class A2AProxyComponent(BaseProxyComponent):
|
|
|
322
323
|
|
|
323
324
|
# Step 3: Normal request flow for all other auth types
|
|
324
325
|
# (static_bearer, static_apikey, oauth2_client_credentials, or authorized oauth2_authorization_code)
|
|
326
|
+
received_final_task = False
|
|
327
|
+
|
|
325
328
|
while auth_retry_count <= max_auth_retries:
|
|
326
329
|
try:
|
|
327
330
|
# Get or create A2AClient
|
|
@@ -382,6 +385,10 @@ class A2AProxyComponent(BaseProxyComponent):
|
|
|
382
385
|
await self._process_downstream_response(
|
|
383
386
|
raw_event, task_context, client, agent_name
|
|
384
387
|
)
|
|
388
|
+
# Check if this is a final task
|
|
389
|
+
if isinstance(raw_event, Task) and raw_event.status:
|
|
390
|
+
if raw_event.status.state in [TaskState.completed, TaskState.failed, TaskState.canceled]:
|
|
391
|
+
received_final_task = True
|
|
385
392
|
else:
|
|
386
393
|
# Non-streaming: use normal client method (works fine)
|
|
387
394
|
log.debug(
|
|
@@ -394,6 +401,12 @@ class A2AProxyComponent(BaseProxyComponent):
|
|
|
394
401
|
await self._process_downstream_response(
|
|
395
402
|
event, task_context, client, agent_name
|
|
396
403
|
)
|
|
404
|
+
# Check if this is a final task (event is tuple of (Task, Optional[UpdateEvent]))
|
|
405
|
+
if isinstance(event, tuple) and len(event) > 0:
|
|
406
|
+
task = event[0]
|
|
407
|
+
if isinstance(task, Task) and task.status:
|
|
408
|
+
if task.status.state in [TaskState.completed, TaskState.failed, TaskState.canceled]:
|
|
409
|
+
received_final_task = True
|
|
397
410
|
elif isinstance(request, CancelTaskRequest):
|
|
398
411
|
# Forward cancel request to downstream agent using the downstream task ID
|
|
399
412
|
# The request.params.id contains SAM's task ID, but we need to send
|
|
@@ -555,6 +568,20 @@ class A2AProxyComponent(BaseProxyComponent):
|
|
|
555
568
|
# and publish an error response.
|
|
556
569
|
raise
|
|
557
570
|
|
|
571
|
+
# After retry loop completes - check if we received a final task
|
|
572
|
+
# This detects cases where the stream closes without error but also without final response
|
|
573
|
+
if not received_final_task and isinstance(request, (SendStreamingMessageRequest, SendMessageRequest)):
|
|
574
|
+
from ....common.a2a import create_error_response
|
|
575
|
+
|
|
576
|
+
error_msg = f"Remote agent '{agent_name}' disconnected without completing the task. Agent may have crashed."
|
|
577
|
+
log.error("%s %s", log_identifier, error_msg)
|
|
578
|
+
|
|
579
|
+
error = InternalError(message=error_msg, data={"agent_name": agent_name})
|
|
580
|
+
reply_topic = task_context.a2a_context.get("reply_to_topic")
|
|
581
|
+
if reply_topic:
|
|
582
|
+
response = create_error_response(error=error, request_id=task_context.a2a_context.get("jsonrpc_request_id"))
|
|
583
|
+
self._publish_a2a_message(response.model_dump(exclude_none=True), reply_topic)
|
|
584
|
+
|
|
558
585
|
async def _handle_auth_error(
|
|
559
586
|
self, agent_name: str, task_context: ProxyTaskContext
|
|
560
587
|
) -> bool:
|
|
@@ -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,
|
|
@@ -74,7 +78,8 @@ from ...common.constants import (
|
|
|
74
78
|
HEALTH_CHECK_INTERVAL_SECONDS,
|
|
75
79
|
HEALTH_CHECK_TTL_SECONDS,
|
|
76
80
|
)
|
|
77
|
-
from ...common.
|
|
81
|
+
from ...common.a2a.types import ArtifactInfo
|
|
82
|
+
from ...common.data_parts import AgentProgressUpdateData, ArtifactSavedData
|
|
78
83
|
from ...common.middleware.registry import MiddlewareRegistry
|
|
79
84
|
from ...common.sac.sam_component_base import SamComponentBase
|
|
80
85
|
from ...common.utils.rbac_utils import validate_agent_access
|
|
@@ -1526,6 +1531,68 @@ class SamAgentComponent(SamComponentBase):
|
|
|
1526
1531
|
)
|
|
1527
1532
|
return False
|
|
1528
1533
|
|
|
1534
|
+
async def notify_artifact_saved(
|
|
1535
|
+
self,
|
|
1536
|
+
artifact_info: ArtifactInfo,
|
|
1537
|
+
a2a_context: Dict[str, Any],
|
|
1538
|
+
function_call_id: Optional[str] = None,
|
|
1539
|
+
) -> None:
|
|
1540
|
+
"""
|
|
1541
|
+
Publishes an artifact saved notification signal.
|
|
1542
|
+
|
|
1543
|
+
This is a separate event from ArtifactCreationProgressData and does not
|
|
1544
|
+
follow the start->updates->end protocol. It's a single notification that
|
|
1545
|
+
an artifact has been successfully saved to storage.
|
|
1546
|
+
|
|
1547
|
+
Args:
|
|
1548
|
+
artifact_info: Information about the saved artifact
|
|
1549
|
+
a2a_context: The A2A context dictionary for the current task
|
|
1550
|
+
function_call_id: Optional function call ID if artifact was created by a tool
|
|
1551
|
+
"""
|
|
1552
|
+
log_identifier = f"{self.log_identifier}[ArtifactSaved:{artifact_info.filename}]"
|
|
1553
|
+
|
|
1554
|
+
try:
|
|
1555
|
+
# Create artifact saved signal
|
|
1556
|
+
artifact_signal = ArtifactSavedData(
|
|
1557
|
+
type="artifact_saved",
|
|
1558
|
+
filename=artifact_info.filename,
|
|
1559
|
+
version=artifact_info.version,
|
|
1560
|
+
mime_type=artifact_info.mime_type or "application/octet-stream",
|
|
1561
|
+
size_bytes=artifact_info.size,
|
|
1562
|
+
description=artifact_info.description,
|
|
1563
|
+
function_call_id=function_call_id,
|
|
1564
|
+
)
|
|
1565
|
+
|
|
1566
|
+
# Create and publish status update event
|
|
1567
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
1568
|
+
context_id = a2a_context.get("contextId")
|
|
1569
|
+
|
|
1570
|
+
status_update_event = a2a.create_data_signal_event(
|
|
1571
|
+
task_id=logical_task_id,
|
|
1572
|
+
context_id=context_id,
|
|
1573
|
+
signal_data=artifact_signal,
|
|
1574
|
+
agent_name=self.agent_name,
|
|
1575
|
+
)
|
|
1576
|
+
|
|
1577
|
+
await self._publish_status_update_with_buffer_flush(
|
|
1578
|
+
status_update_event,
|
|
1579
|
+
a2a_context,
|
|
1580
|
+
skip_buffer_flush=False,
|
|
1581
|
+
)
|
|
1582
|
+
|
|
1583
|
+
log.debug(
|
|
1584
|
+
"%s Published artifact saved notification for '%s' v%s.",
|
|
1585
|
+
log_identifier,
|
|
1586
|
+
artifact_info.filename,
|
|
1587
|
+
artifact_info.version,
|
|
1588
|
+
)
|
|
1589
|
+
except Exception as e:
|
|
1590
|
+
log.error(
|
|
1591
|
+
"%s Failed to publish artifact saved notification: %s",
|
|
1592
|
+
log_identifier,
|
|
1593
|
+
e,
|
|
1594
|
+
)
|
|
1595
|
+
|
|
1529
1596
|
async def _publish_status_update_with_buffer_flush(
|
|
1530
1597
|
self,
|
|
1531
1598
|
status_update_event: TaskStatusUpdateEvent,
|
|
@@ -2646,10 +2713,25 @@ class SamAgentComponent(SamComponentBase):
|
|
|
2646
2713
|
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
2647
2714
|
namespace = self.get_config("namespace")
|
|
2648
2715
|
|
|
2716
|
+
# Detect context limit errors and provide user-friendly message
|
|
2717
|
+
error_message = "An unexpected error occurred during tool execution. Please try your request again. If the problem persists, contact an administrator."
|
|
2718
|
+
|
|
2719
|
+
if isinstance(exception, BadRequestError):
|
|
2720
|
+
# Use centralized error handler
|
|
2721
|
+
error_message, is_context_limit = get_error_message(exception)
|
|
2722
|
+
|
|
2723
|
+
if is_context_limit:
|
|
2724
|
+
log.error(
|
|
2725
|
+
"%s Context limit exceeded for task %s. Error: %s",
|
|
2726
|
+
self.log_identifier,
|
|
2727
|
+
logical_task_id,
|
|
2728
|
+
exception,
|
|
2729
|
+
)
|
|
2730
|
+
|
|
2649
2731
|
failed_status = a2a.create_task_status(
|
|
2650
2732
|
state=TaskState.failed,
|
|
2651
2733
|
message=a2a.create_agent_text_message(
|
|
2652
|
-
text=
|
|
2734
|
+
text=error_message
|
|
2653
2735
|
),
|
|
2654
2736
|
)
|
|
2655
2737
|
|
|
@@ -175,6 +175,7 @@ async def _internal_create_artifact(
|
|
|
175
175
|
timestamp=timestamp_for_artifact,
|
|
176
176
|
schema_max_keys=max_keys_to_use,
|
|
177
177
|
tool_context=tool_context,
|
|
178
|
+
suppress_visualization_signal=True, # Fenced blocks handle their own visualization signals
|
|
178
179
|
)
|
|
179
180
|
log.info(
|
|
180
181
|
"%s Result from save_artifact_with_metadata: %s", log_identifier, result
|
|
@@ -1740,18 +1741,20 @@ tool_registry.register(extract_content_from_artifact_tool_def)
|
|
|
1740
1741
|
async def delete_artifact(
|
|
1741
1742
|
filename: str,
|
|
1742
1743
|
version: Optional[int] = None,
|
|
1744
|
+
confirm_delete: bool = False,
|
|
1743
1745
|
tool_context: ToolContext = None,
|
|
1744
1746
|
) -> Dict[str, Any]:
|
|
1745
1747
|
"""
|
|
1746
|
-
Deletes
|
|
1748
|
+
Deletes all versions of an artifact. Version-specific deletion is not currently supported.
|
|
1747
1749
|
|
|
1748
1750
|
Args:
|
|
1749
1751
|
filename: The name of the artifact to delete.
|
|
1750
|
-
version:
|
|
1752
|
+
version: Reserved for future use. Currently not supported - returns error if specified.
|
|
1753
|
+
confirm_delete: Must be set to True to confirm deletion. If False, returns confirmation prompt.
|
|
1751
1754
|
tool_context: The context provided by the ADK framework.
|
|
1752
1755
|
|
|
1753
1756
|
Returns:
|
|
1754
|
-
A dictionary indicating the result of the deletion.
|
|
1757
|
+
A dictionary indicating the result of the deletion or requesting confirmation.
|
|
1755
1758
|
"""
|
|
1756
1759
|
if not tool_context:
|
|
1757
1760
|
return {
|
|
@@ -1760,9 +1763,7 @@ async def delete_artifact(
|
|
|
1760
1763
|
"message": "ToolContext is missing, cannot delete artifact.",
|
|
1761
1764
|
}
|
|
1762
1765
|
|
|
1763
|
-
log_identifier =
|
|
1764
|
-
f"[BuiltinArtifactTool:delete_artifact:{filename}:{version or 'all'}]"
|
|
1765
|
-
)
|
|
1766
|
+
log_identifier = f"[BuiltinArtifactTool:delete_artifact:{filename}]"
|
|
1766
1767
|
log.debug("%s Processing request.", log_identifier)
|
|
1767
1768
|
|
|
1768
1769
|
try:
|
|
@@ -1780,14 +1781,32 @@ async def delete_artifact(
|
|
|
1780
1781
|
"ArtifactService does not support deleting artifacts."
|
|
1781
1782
|
)
|
|
1782
1783
|
|
|
1784
|
+
# Error if version-specific deletion requested (not currently supported)
|
|
1783
1785
|
if version is not None:
|
|
1784
|
-
|
|
1785
|
-
"
|
|
1786
|
-
"
|
|
1787
|
-
|
|
1788
|
-
version,
|
|
1789
|
-
|
|
1786
|
+
return {
|
|
1787
|
+
"status": "error",
|
|
1788
|
+
"filename": filename,
|
|
1789
|
+
"version_requested": version,
|
|
1790
|
+
"message": f"Deleting a specific version ({version}) is not currently supported. Only deletion of ALL versions is supported. To delete all versions, omit 'version' and set confirm_delete=True.",
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
# Get version list for confirmation message
|
|
1794
|
+
versions = await artifact_service.list_versions(
|
|
1795
|
+
app_name=app_name, user_id=user_id, session_id=session_id, filename=filename
|
|
1796
|
+
)
|
|
1790
1797
|
|
|
1798
|
+
# Require confirmation before deleting
|
|
1799
|
+
if not confirm_delete:
|
|
1800
|
+
count = len(versions) if versions else "unknown number of"
|
|
1801
|
+
return {
|
|
1802
|
+
"status": "confirmation_required",
|
|
1803
|
+
"filename": filename,
|
|
1804
|
+
"version_count": len(versions) if versions else None,
|
|
1805
|
+
"versions": versions,
|
|
1806
|
+
"message": f"WARNING: This operation is irreversible and will permanently delete artifact '{filename}' and ALL {count} version(s). To proceed, call this tool again with confirm_delete=True.",
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
# Proceed with deletion
|
|
1791
1810
|
await artifact_service.delete_artifact(
|
|
1792
1811
|
app_name=app_name,
|
|
1793
1812
|
user_id=user_id,
|
|
@@ -1795,17 +1814,12 @@ async def delete_artifact(
|
|
|
1795
1814
|
filename=filename,
|
|
1796
1815
|
)
|
|
1797
1816
|
|
|
1798
|
-
log.info(
|
|
1799
|
-
"%s Successfully deleted artifact '%s' version '%s'.",
|
|
1800
|
-
log_identifier,
|
|
1801
|
-
filename,
|
|
1802
|
-
version or "all",
|
|
1803
|
-
)
|
|
1817
|
+
log.info("%s Successfully deleted artifact '%s'.", log_identifier, filename)
|
|
1804
1818
|
return {
|
|
1805
1819
|
"status": "success",
|
|
1806
1820
|
"filename": filename,
|
|
1807
|
-
"
|
|
1808
|
-
"message": f"Artifact '{filename}'
|
|
1821
|
+
"versions_deleted": len(versions) if versions else None,
|
|
1822
|
+
"message": f"Artifact '{filename}' deleted successfully.",
|
|
1809
1823
|
}
|
|
1810
1824
|
|
|
1811
1825
|
except FileNotFoundError as e:
|
|
@@ -1829,7 +1843,7 @@ async def delete_artifact(
|
|
|
1829
1843
|
delete_artifact_tool_def = BuiltinTool(
|
|
1830
1844
|
name="delete_artifact",
|
|
1831
1845
|
implementation=delete_artifact,
|
|
1832
|
-
description="Deletes
|
|
1846
|
+
description="Deletes all versions of an artifact. IMPORTANT: Requires explicit confirmation via confirm_delete=True parameter. The first call without confirmation will return details about what will be deleted.",
|
|
1833
1847
|
category="artifact_management",
|
|
1834
1848
|
category_name=CATEGORY_NAME,
|
|
1835
1849
|
category_description=CATEGORY_DESCRIPTION,
|
|
@@ -1843,7 +1857,12 @@ delete_artifact_tool_def = BuiltinTool(
|
|
|
1843
1857
|
),
|
|
1844
1858
|
"version": adk_types.Schema(
|
|
1845
1859
|
type=adk_types.Type.INTEGER,
|
|
1846
|
-
description="
|
|
1860
|
+
description="Reserved for future use. Version-specific deletion is not currently supported - will return error if specified.",
|
|
1861
|
+
nullable=True,
|
|
1862
|
+
),
|
|
1863
|
+
"confirm_delete": adk_types.Schema(
|
|
1864
|
+
type=adk_types.Type.BOOLEAN,
|
|
1865
|
+
description="Must be set to True to actually perform the deletion. If False or omitted, returns a confirmation prompt with details about what will be deleted (including version count).",
|
|
1847
1866
|
nullable=True,
|
|
1848
1867
|
),
|
|
1849
1868
|
},
|
|
@@ -20,6 +20,7 @@ from ...common.exceptions import MessageSizeExceededError
|
|
|
20
20
|
|
|
21
21
|
log = logging.getLogger(__name__)
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
class ArtifactIdentifier(BaseModel):
|
|
24
25
|
"""Identifies a specific version of an artifact."""
|
|
25
26
|
|
|
@@ -90,7 +91,10 @@ class PeerAgentTool(BaseTool):
|
|
|
90
91
|
Enhanced description string with markdown formatting
|
|
91
92
|
"""
|
|
92
93
|
# Start with base description - ensure it's clean (no extra whitespace)
|
|
93
|
-
base_desc =
|
|
94
|
+
base_desc = (
|
|
95
|
+
agent_card.description
|
|
96
|
+
or f"Interact with the {self.target_agent_name} agent."
|
|
97
|
+
)
|
|
94
98
|
base_desc = " ".join(base_desc.split()) # Normalize whitespace
|
|
95
99
|
|
|
96
100
|
# Extract skills information
|
|
@@ -101,7 +105,7 @@ class PeerAgentTool(BaseTool):
|
|
|
101
105
|
skill_names = []
|
|
102
106
|
for skill in agent_card.skills[:max_skills_to_show]:
|
|
103
107
|
# Prefer name, fallback to id
|
|
104
|
-
skill_name = getattr(skill,
|
|
108
|
+
skill_name = getattr(skill, "name", None) or getattr(skill, "id", None)
|
|
105
109
|
if skill_name:
|
|
106
110
|
skill_names.append(skill_name)
|
|
107
111
|
|
|
@@ -113,7 +117,9 @@ class PeerAgentTool(BaseTool):
|
|
|
113
117
|
|
|
114
118
|
# Include skill count in the header
|
|
115
119
|
if skill_count > 1:
|
|
116
|
-
enhanced_desc =
|
|
120
|
+
enhanced_desc = (
|
|
121
|
+
f"{base_desc}\n\n**Skills ({skill_count}):** {skills_str}"
|
|
122
|
+
)
|
|
117
123
|
else:
|
|
118
124
|
enhanced_desc = f"{base_desc}\n\n**Skills:** {skills_str}"
|
|
119
125
|
|
|
@@ -122,7 +128,9 @@ class PeerAgentTool(BaseTool):
|
|
|
122
128
|
# Truncate to first 4 skills to keep it concise
|
|
123
129
|
skill_names = []
|
|
124
130
|
for skill in agent_card.skills[:4]:
|
|
125
|
-
skill_name = getattr(skill,
|
|
131
|
+
skill_name = getattr(skill, "name", None) or getattr(
|
|
132
|
+
skill, "id", None
|
|
133
|
+
)
|
|
126
134
|
if skill_name:
|
|
127
135
|
skill_names.append(skill_name)
|
|
128
136
|
skills_str = ", ".join(skill_names)
|
|
@@ -131,7 +139,9 @@ class PeerAgentTool(BaseTool):
|
|
|
131
139
|
skills_str += f" ({remaining} more...)"
|
|
132
140
|
|
|
133
141
|
if skill_count > 1:
|
|
134
|
-
enhanced_desc =
|
|
142
|
+
enhanced_desc = (
|
|
143
|
+
f"{base_desc}\n\n**Skills ({skill_count}):** {skills_str}"
|
|
144
|
+
)
|
|
135
145
|
else:
|
|
136
146
|
enhanced_desc = f"{base_desc}\n\n**Skills:** {skills_str}"
|
|
137
147
|
else:
|
|
@@ -264,13 +274,10 @@ class PeerAgentTool(BaseTool):
|
|
|
264
274
|
f"TaskExecutionContext not found for task '{main_logical_task_id}'"
|
|
265
275
|
)
|
|
266
276
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
invocation_id,
|
|
272
|
-
task_context_obj.parallel_tool_calls.get(invocation_id),
|
|
273
|
-
)
|
|
277
|
+
# NOTE: register_parallel_call_sent is called in
|
|
278
|
+
# preregister_long_running_tools_callback (after_model_callback)
|
|
279
|
+
# BEFORE tool execution begins. This prevents race conditions where
|
|
280
|
+
# one tool completes before another registers.
|
|
274
281
|
|
|
275
282
|
a2a_message_parts = self._prepare_a2a_parts(args, tool_context)
|
|
276
283
|
a2a_metadata = {}
|
|
@@ -47,11 +47,31 @@ class McpToolConfig(BaseToolConfig):
|
|
|
47
47
|
"""Configuration for an MCP tool or toolset."""
|
|
48
48
|
tool_type: Literal["mcp"]
|
|
49
49
|
connection_params: Dict[str, Any]
|
|
50
|
-
tool_name: Optional[str] = None
|
|
50
|
+
tool_name: Optional[str] = None # Single tool filter (backward compat)
|
|
51
|
+
tool_name_prefix: Optional[str] = None # Optional prefix for tool names
|
|
51
52
|
environment_variables: Optional[Dict[str, Any]] = None
|
|
52
53
|
auth: dict[str, Any] | None = None
|
|
53
54
|
manifest: list[dict[str, Any]] | None = None
|
|
54
55
|
|
|
56
|
+
# Tool filtering options (mutually exclusive with each other AND with tool_name)
|
|
57
|
+
allow_list: Optional[List[str]] = None # Include only these tools
|
|
58
|
+
deny_list: Optional[List[str]] = None # Exclude these tools
|
|
59
|
+
|
|
60
|
+
@model_validator(mode='after')
|
|
61
|
+
def validate_tool_filtering(self):
|
|
62
|
+
"""Ensure tool_name, allow_list, and deny_list are mutually exclusive."""
|
|
63
|
+
filters_specified = [
|
|
64
|
+
self.tool_name is not None,
|
|
65
|
+
self.allow_list is not None,
|
|
66
|
+
self.deny_list is not None,
|
|
67
|
+
]
|
|
68
|
+
if sum(filters_specified) > 1:
|
|
69
|
+
raise ValueError(
|
|
70
|
+
"MCP tool configuration error: 'tool_name', 'allow_list', and 'deny_list' "
|
|
71
|
+
"are mutually exclusive. Please use only one."
|
|
72
|
+
)
|
|
73
|
+
return self
|
|
74
|
+
|
|
55
75
|
|
|
56
76
|
class OpenApiToolConfig(BaseToolConfig):
|
|
57
77
|
"""Configuration for OpenAPI-based tools."""
|