solace-agent-mesh 0.2.4__py3-none-any.whl → 1.0.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/__init__.py +5 -0
- solace_agent_mesh/agent/adk/adk_llm.txt +93 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/callbacks.py +1716 -0
- solace_agent_mesh/agent/adk/filesystem_artifact_service.py +381 -0
- solace_agent_mesh/agent/adk/invocation_monitor.py +295 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +872 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +94 -0
- solace_agent_mesh/agent/adk/runner.py +357 -0
- solace_agent_mesh/agent/adk/services.py +240 -0
- solace_agent_mesh/agent/adk/setup.py +751 -0
- solace_agent_mesh/agent/adk/stream_parser.py +214 -0
- solace_agent_mesh/agent/adk/tool_wrapper.py +139 -0
- solace_agent_mesh/agent/agent_llm.txt +41 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +1444 -0
- solace_agent_mesh/agent/protocol/protocol_llm.txt +21 -0
- solace_agent_mesh/agent/sac/app.py +640 -0
- solace_agent_mesh/agent/sac/component.py +3496 -0
- solace_agent_mesh/agent/sac/patch_adk.py +111 -0
- solace_agent_mesh/agent/sac/sac_llm.txt +105 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +185 -0
- solace_agent_mesh/agent/testing/__init__.py +3 -0
- solace_agent_mesh/agent/testing/debug_utils.py +135 -0
- solace_agent_mesh/agent/testing/testing_llm.txt +90 -0
- solace_agent_mesh/agent/tools/__init__.py +14 -0
- solace_agent_mesh/agent/tools/audio_tools.py +1622 -0
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +1954 -0
- solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +238 -0
- solace_agent_mesh/agent/tools/general_agent_tools.py +571 -0
- solace_agent_mesh/agent/tools/image_tools.py +1184 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +290 -0
- solace_agent_mesh/agent/tools/registry.py +36 -0
- solace_agent_mesh/agent/tools/test_tools.py +135 -0
- solace_agent_mesh/agent/tools/tool_definition.py +45 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +104 -0
- solace_agent_mesh/agent/tools/web_tools.py +381 -0
- solace_agent_mesh/agent/utils/artifact_helpers.py +927 -0
- solace_agent_mesh/agent/utils/config_parser.py +47 -0
- solace_agent_mesh/agent/utils/context_helpers.py +60 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +153 -0
- solace_agent_mesh/assets/docs/404.html +16 -0
- solace_agent_mesh/assets/docs/assets/css/styles.906a1503.css +1 -0
- solace_agent_mesh/assets/docs/assets/images/Solace_AI_Framework_With_Broker-85f0a306a9bcdd20b390b7a949f6d862.png +0 -0
- solace_agent_mesh/assets/docs/assets/images/sac-flows-80d5b603c6aafd33e87945680ce0abf3.png +0 -0
- solace_agent_mesh/assets/docs/assets/images/sac_parts_of_a_component-cb3d0424b1d0c17734c5435cca6b4082.png +0 -0
- solace_agent_mesh/assets/docs/assets/js/04989206.674a8007.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/0e682baa.79f0ab22.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1001.0182a8bd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1023fc19.015679ca.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1039.0bd46aa1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/149.b797a808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1523c6b4.91c7bc01.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/165.6a39807d.js.LICENSE.txt +9 -0
- solace_agent_mesh/assets/docs/assets/js/166ab619.7d97ccaf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/17896441.a5e82f9b.js.LICENSE.txt +7 -0
- solace_agent_mesh/assets/docs/assets/js/1c6e87d2.a8c5ce5a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2130.ab9fd314.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/21ceee5f.614fa8dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2237.5e477fc6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2334.622a6395.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2a9cab12.8909df92.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3219.adc1d663.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/332e10b5.7a103f42.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3624.b524e433.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/375.708d48db.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3834.b6cd790e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3d406171.f722eaf5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4250.95455b28.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/42b3f8d8.36090198.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4356.d169ab5b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/442a8107.5ba94b65.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4458.518e66fa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4488.c7cc3442.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4494.6ee23046.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4855.fc4444b6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4866.22daefc0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4950.ca4caeda.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4c2787c2.66ee00e9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5388.7a136447.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55f47984.c484bf96.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5607.081356f8.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5864.b0d0e9de.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5b4258a4.bda20761.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5e95c892.558d5167.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6143.0a1464c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6395.e9c73649.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6796.51d2c9b7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6976.379be23b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6978.ee0b945c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7040.cb436723.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7195.412f418a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7280.3fb73bdb.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/768e31b0.a12673db.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7845.e33e7c4c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7900.69516146.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8356.8a379c04.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/85387663.6bf41934.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8567.4732c6b7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8573.cb04eda5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8577.1d54e766.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8591.d7c16be6.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/8591.d7c16be6.js.LICENSE.txt +61 -0
- solace_agent_mesh/assets/docs/assets/js/8709.7ecd4047.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8731.49e930c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8908.f9d1b506.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9157.b4093d07.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9278.a4fd875d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/945fb41e.74d728aa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9616.b75c2f6d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9793.c6d16376.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9eff14a2.1bf8f61c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a3a92b25.26ca071f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7bd4aaa.2204d2f7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.0438dbc2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba21aa0.c42a534c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba87c2f.d3e2dcc3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ae4415af.8e279b5d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/b7006a3a.40b10c9d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/bac0be12.f50d9bac.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/bb2ef573.207e6990.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c2c06897.63b76e9e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cc969b05.954186d4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cd3d4052.ca6eed8c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ced92a13.fb92e7ca.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cee5d587.f5b73ca1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.ecc3d195.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f897a61a.f8c53b0f.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/fbfa3e75.aca209c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.c6286d7c.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/main.c6286d7c.js.LICENSE.txt +81 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d5133813.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +128 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +91 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +201 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +91 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +82 -0
- solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +77 -0
- solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +48 -0
- solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +17 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +45 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +76 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +150 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +267 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +136 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +116 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +80 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +164 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +57 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +102 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +99 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +107 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +152 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +103 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +170 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +200 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +69 -0
- solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +59 -0
- solace_agent_mesh/assets/docs/img/Solace_AI_Framework_README.png +0 -0
- solace_agent_mesh/assets/docs/img/Solace_AI_Framework_With_Broker.png +0 -0
- solace_agent_mesh/assets/docs/img/logo.png +0 -0
- solace_agent_mesh/assets/docs/img/sac-flows.png +0 -0
- solace_agent_mesh/assets/docs/img/sac_parts_of_a_component.png +0 -0
- solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1754075282978.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -0
- solace_agent_mesh/assets/docs/search-doc-1754075282978.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -0
- solace_agent_mesh/assets/docs/sitemap.xml +1 -0
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/__init__.py +15 -0
- solace_agent_mesh/cli/commands/add_cmd/add_cmd_llm.txt +250 -0
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +659 -0
- solace_agent_mesh/cli/commands/add_cmd/gateway_cmd.py +322 -0
- solace_agent_mesh/cli/commands/add_cmd/web_add_agent_step.py +93 -0
- solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +118 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +57 -0
- solace_agent_mesh/cli/commands/eval_cmd.py +64 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +404 -0
- solace_agent_mesh/cli/commands/init_cmd/broker_step.py +201 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +28 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +205 -0
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +407 -0
- solace_agent_mesh/cli/commands/init_cmd/project_files_step.py +38 -0
- solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +110 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +183 -0
- solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +18 -0
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +372 -0
- solace_agent_mesh/cli/commands/plugin_cmd/build_cmd.py +86 -0
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +139 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +309 -0
- solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +175 -0
- solace_agent_mesh/cli/commands/plugin_cmd/plugin_cmd_llm.txt +305 -0
- solace_agent_mesh/cli/commands/run_cmd.py +158 -0
- solace_agent_mesh/cli/main.py +17 -294
- solace_agent_mesh/cli/utils.py +135 -204
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-DvlO62me.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-bp6u3qVZ.js +49 -0
- solace_agent_mesh/client/webui/frontend/static/assets/favicon-BLgzUch9.ico +0 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-D11Lmy9p.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Gfk3BYn5.js +663 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +14 -0
- solace_agent_mesh/client/webui/frontend/static/index.html +15 -0
- solace_agent_mesh/common/__init__.py +1 -0
- solace_agent_mesh/common/a2a_protocol.py +564 -0
- solace_agent_mesh/common/agent_registry.py +42 -0
- solace_agent_mesh/common/client/__init__.py +4 -0
- solace_agent_mesh/common/client/card_resolver.py +21 -0
- solace_agent_mesh/common/client/client.py +85 -0
- solace_agent_mesh/common/client/client_llm.txt +133 -0
- solace_agent_mesh/common/common_llm.txt +144 -0
- solace_agent_mesh/common/constants.py +1 -14
- solace_agent_mesh/common/middleware/__init__.py +12 -0
- solace_agent_mesh/common/middleware/config_resolver.py +130 -0
- solace_agent_mesh/common/middleware/middleware_llm.txt +174 -0
- solace_agent_mesh/common/middleware/registry.py +125 -0
- solace_agent_mesh/common/server/__init__.py +4 -0
- solace_agent_mesh/common/server/server.py +122 -0
- solace_agent_mesh/common/server/server_llm.txt +169 -0
- solace_agent_mesh/common/server/task_manager.py +291 -0
- solace_agent_mesh/common/server/utils.py +28 -0
- solace_agent_mesh/common/services/__init__.py +4 -0
- solace_agent_mesh/common/services/employee_service.py +162 -0
- solace_agent_mesh/common/services/identity_service.py +129 -0
- solace_agent_mesh/common/services/providers/__init__.py +4 -0
- solace_agent_mesh/common/services/providers/local_file_identity_service.py +148 -0
- solace_agent_mesh/common/services/providers/providers_llm.txt +113 -0
- solace_agent_mesh/common/services/services_llm.txt +132 -0
- solace_agent_mesh/common/types.py +411 -0
- solace_agent_mesh/common/utils/__init__.py +7 -0
- solace_agent_mesh/common/utils/asyncio_macos_fix.py +86 -0
- solace_agent_mesh/common/utils/embeds/__init__.py +33 -0
- solace_agent_mesh/common/utils/embeds/constants.py +55 -0
- solace_agent_mesh/common/utils/embeds/converter.py +452 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +124 -0
- solace_agent_mesh/common/utils/embeds/evaluators.py +394 -0
- solace_agent_mesh/common/utils/embeds/modifiers.py +816 -0
- solace_agent_mesh/common/utils/embeds/resolver.py +865 -0
- solace_agent_mesh/common/utils/embeds/types.py +14 -0
- solace_agent_mesh/common/utils/in_memory_cache.py +108 -0
- solace_agent_mesh/common/utils/initializer.py +51 -0
- solace_agent_mesh/common/utils/log_formatters.py +44 -0
- solace_agent_mesh/common/utils/mime_helpers.py +106 -0
- solace_agent_mesh/common/utils/push_notification_auth.py +134 -0
- solace_agent_mesh/common/utils/utils_llm.txt +67 -0
- solace_agent_mesh/config_portal/backend/common.py +66 -24
- solace_agent_mesh/config_portal/backend/plugin_catalog/constants.py +24 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/models.py +49 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +164 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +521 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +217 -0
- solace_agent_mesh/config_portal/backend/server.py +551 -181
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-_7yox_eh.js +48 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/components-B7lKcHVY.js +140 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{entry.client-DX1misIU.js → entry.client-CEumGClk.js} +3 -3
- solace_agent_mesh/config_portal/frontend/static/client/assets/index-DSo1AH_7.js +68 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-e5c3acfe.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{root-BApq5dPK.js → root-C4XmHinv.js} +2 -2
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DxRwaWiE.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +3 -3
- solace_agent_mesh/core_a2a/__init__.py +1 -0
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +88 -0
- solace_agent_mesh/core_a2a/service.py +331 -0
- solace_agent_mesh/evaluation/config_loader.py +657 -0
- solace_agent_mesh/evaluation/evaluator.py +667 -0
- solace_agent_mesh/evaluation/message_organizer.py +568 -0
- solace_agent_mesh/evaluation/report/benchmark_info.html +35 -0
- solace_agent_mesh/evaluation/report/chart_section.html +141 -0
- solace_agent_mesh/evaluation/report/detailed_breakdown.html +28 -0
- solace_agent_mesh/evaluation/report/modal.html +59 -0
- solace_agent_mesh/evaluation/report/modal_chart_functions.js +411 -0
- solace_agent_mesh/evaluation/report/modal_script.js +296 -0
- solace_agent_mesh/evaluation/report/modal_styles.css +340 -0
- solace_agent_mesh/evaluation/report/performance_metrics_styles.css +93 -0
- solace_agent_mesh/evaluation/report/templates/footer.html +2 -0
- solace_agent_mesh/evaluation/report/templates/header.html +340 -0
- solace_agent_mesh/evaluation/report_data_processor.py +972 -0
- solace_agent_mesh/evaluation/report_generator.py +613 -0
- solace_agent_mesh/evaluation/run.py +613 -0
- solace_agent_mesh/evaluation/subscriber.py +872 -0
- solace_agent_mesh/evaluation/summary_builder.py +775 -0
- solace_agent_mesh/evaluation/test_case_loader.py +714 -0
- solace_agent_mesh/gateway/base/__init__.py +1 -0
- solace_agent_mesh/gateway/base/app.py +266 -0
- solace_agent_mesh/gateway/base/base_llm.txt +119 -0
- solace_agent_mesh/gateway/base/component.py +1542 -0
- solace_agent_mesh/gateway/base/task_context.py +74 -0
- solace_agent_mesh/gateway/gateway_llm.txt +125 -0
- solace_agent_mesh/gateway/http_sse/app.py +190 -0
- solace_agent_mesh/gateway/http_sse/component.py +1602 -0
- solace_agent_mesh/gateway/http_sse/components/__init__.py +7 -0
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +65 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +108 -0
- solace_agent_mesh/gateway/http_sse/dependencies.py +316 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +63 -0
- solace_agent_mesh/gateway/http_sse/main.py +442 -0
- solace_agent_mesh/gateway/http_sse/routers/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/routers/agents.py +41 -0
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +827 -0
- solace_agent_mesh/gateway/http_sse/routers/auth.py +212 -0
- solace_agent_mesh/gateway/http_sse/routers/config.py +55 -0
- solace_agent_mesh/gateway/http_sse/routers/people.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +37 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +80 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +138 -0
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +294 -0
- solace_agent_mesh/gateway/http_sse/routers/users.py +59 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +1131 -0
- solace_agent_mesh/gateway/http_sse/services/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/services/agent_service.py +69 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +158 -0
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +179 -0
- solace_agent_mesh/gateway/http_sse/services/task_service.py +121 -0
- solace_agent_mesh/gateway/http_sse/session_manager.py +187 -0
- solace_agent_mesh/gateway/http_sse/sse_manager.py +328 -0
- solace_agent_mesh/llm.txt +228 -0
- solace_agent_mesh/llm_detail.txt +2835 -0
- solace_agent_mesh/templates/agent_template.yaml +53 -0
- solace_agent_mesh/templates/eval_backend_template.yaml +54 -0
- solace_agent_mesh/templates/gateway_app_template.py +73 -0
- solace_agent_mesh/templates/gateway_component_template.py +431 -0
- solace_agent_mesh/templates/gateway_config_template.yaml +43 -0
- solace_agent_mesh/templates/logging_config_template.ini +64 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +55 -0
- solace_agent_mesh/templates/plugin_agent_config_template.yaml +122 -0
- solace_agent_mesh/templates/plugin_custom_config_template.yaml +27 -0
- solace_agent_mesh/templates/plugin_custom_template.py +10 -0
- solace_agent_mesh/templates/plugin_gateway_config_template.yaml +63 -0
- solace_agent_mesh/templates/plugin_pyproject_template.toml +33 -0
- solace_agent_mesh/templates/plugin_readme_template.md +34 -0
- solace_agent_mesh/templates/plugin_tools_template.py +224 -0
- solace_agent_mesh/templates/shared_config.yaml +66 -0
- solace_agent_mesh/templates/templates_llm.txt +147 -0
- solace_agent_mesh/templates/webui.yaml +53 -0
- solace_agent_mesh-1.0.2.dist-info/METADATA +432 -0
- solace_agent_mesh-1.0.2.dist-info/RECORD +361 -0
- solace_agent_mesh-1.0.2.dist-info/entry_points.txt +3 -0
- {solace_agent_mesh-0.2.4.dist-info → solace_agent_mesh-1.0.2.dist-info}/licenses/LICENSE +1 -1
- solace_agent_mesh/agents/base_agent_component.py +0 -256
- solace_agent_mesh/agents/global/actions/agent_state_change.py +0 -54
- solace_agent_mesh/agents/global/actions/clear_history.py +0 -32
- solace_agent_mesh/agents/global/actions/convert_file_to_markdown.py +0 -160
- solace_agent_mesh/agents/global/actions/create_file.py +0 -70
- solace_agent_mesh/agents/global/actions/error_action.py +0 -45
- solace_agent_mesh/agents/global/actions/plantuml_diagram.py +0 -163
- solace_agent_mesh/agents/global/actions/plotly_graph.py +0 -152
- solace_agent_mesh/agents/global/actions/retrieve_file.py +0 -51
- solace_agent_mesh/agents/global/global_agent_component.py +0 -38
- solace_agent_mesh/agents/image_processing/actions/create_image.py +0 -75
- solace_agent_mesh/agents/image_processing/actions/describe_image.py +0 -115
- solace_agent_mesh/agents/image_processing/image_processing_agent_component.py +0 -23
- solace_agent_mesh/agents/slack/__init__.py +0 -1
- solace_agent_mesh/agents/slack/actions/__init__.py +0 -1
- solace_agent_mesh/agents/slack/actions/post_message.py +0 -177
- solace_agent_mesh/agents/slack/slack_agent_component.py +0 -59
- solace_agent_mesh/agents/web_request/actions/do_image_search.py +0 -84
- solace_agent_mesh/agents/web_request/actions/do_news_search.py +0 -47
- solace_agent_mesh/agents/web_request/actions/do_suggestion_search.py +0 -34
- solace_agent_mesh/agents/web_request/actions/do_web_request.py +0 -135
- solace_agent_mesh/agents/web_request/actions/download_file.py +0 -69
- solace_agent_mesh/agents/web_request/web_request_agent_component.py +0 -33
- solace_agent_mesh/assets/web-visualizer/assets/index-D0qORgkg.css +0 -1
- solace_agent_mesh/assets/web-visualizer/assets/index-DnDr1pnu.js +0 -109
- solace_agent_mesh/assets/web-visualizer/index.html +0 -14
- solace_agent_mesh/assets/web-visualizer/vite.svg +0 -1
- solace_agent_mesh/cli/commands/add/__init__.py +0 -3
- solace_agent_mesh/cli/commands/add/add.py +0 -88
- solace_agent_mesh/cli/commands/add/agent.py +0 -110
- solace_agent_mesh/cli/commands/add/copy_from_plugin.py +0 -92
- solace_agent_mesh/cli/commands/add/gateway.py +0 -374
- solace_agent_mesh/cli/commands/build.py +0 -670
- solace_agent_mesh/cli/commands/chat/__init__.py +0 -3
- solace_agent_mesh/cli/commands/chat/chat.py +0 -361
- solace_agent_mesh/cli/commands/config.py +0 -29
- solace_agent_mesh/cli/commands/init/__init__.py +0 -3
- solace_agent_mesh/cli/commands/init/ai_provider_step.py +0 -93
- solace_agent_mesh/cli/commands/init/broker_step.py +0 -99
- solace_agent_mesh/cli/commands/init/builtin_agent_step.py +0 -83
- solace_agent_mesh/cli/commands/init/check_if_already_done.py +0 -13
- solace_agent_mesh/cli/commands/init/create_config_file_step.py +0 -65
- solace_agent_mesh/cli/commands/init/create_other_project_files_step.py +0 -147
- solace_agent_mesh/cli/commands/init/file_service_step.py +0 -73
- solace_agent_mesh/cli/commands/init/init.py +0 -92
- solace_agent_mesh/cli/commands/init/project_structure_step.py +0 -16
- solace_agent_mesh/cli/commands/init/web_init_step.py +0 -32
- solace_agent_mesh/cli/commands/plugin/__init__.py +0 -3
- solace_agent_mesh/cli/commands/plugin/add.py +0 -100
- solace_agent_mesh/cli/commands/plugin/build.py +0 -268
- solace_agent_mesh/cli/commands/plugin/create.py +0 -117
- solace_agent_mesh/cli/commands/plugin/plugin.py +0 -124
- solace_agent_mesh/cli/commands/plugin/remove.py +0 -73
- solace_agent_mesh/cli/commands/run.py +0 -68
- solace_agent_mesh/cli/commands/visualizer.py +0 -138
- solace_agent_mesh/cli/config.py +0 -85
- solace_agent_mesh/common/action.py +0 -91
- solace_agent_mesh/common/action_list.py +0 -37
- solace_agent_mesh/common/action_response.py +0 -340
- solace_agent_mesh/common/mysql_database.py +0 -40
- solace_agent_mesh/common/postgres_database.py +0 -85
- solace_agent_mesh/common/prompt_templates.py +0 -28
- solace_agent_mesh/common/stimulus_utils.py +0 -152
- solace_agent_mesh/common/time.py +0 -24
- solace_agent_mesh/common/utils.py +0 -712
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-a-zJ6rLx.js +0 -46
- solace_agent_mesh/config_portal/frontend/static/client/assets/components-ZIfdTbrV.js +0 -191
- solace_agent_mesh/config_portal/frontend/static/client/assets/index-BJHAE5s4.js +0 -17
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-44c41103.js +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-DX4gQ516.css +0 -1
- solace_agent_mesh/configs/agent_global.yaml +0 -74
- solace_agent_mesh/configs/agent_image_processing.yaml +0 -82
- solace_agent_mesh/configs/agent_slack.yaml +0 -64
- solace_agent_mesh/configs/agent_web_request.yaml +0 -75
- solace_agent_mesh/configs/conversation_to_file.yaml +0 -56
- solace_agent_mesh/configs/error_catcher.yaml +0 -56
- solace_agent_mesh/configs/monitor.yaml +0 -0
- solace_agent_mesh/configs/monitor_stim_and_errors_to_slack.yaml +0 -109
- solace_agent_mesh/configs/monitor_user_feedback.yaml +0 -58
- solace_agent_mesh/configs/orchestrator.yaml +0 -241
- solace_agent_mesh/configs/service_embedding.yaml +0 -81
- solace_agent_mesh/configs/service_llm.yaml +0 -265
- solace_agent_mesh/configs/visualize_websocket.yaml +0 -55
- solace_agent_mesh/gateway/components/gateway_base.py +0 -47
- solace_agent_mesh/gateway/components/gateway_input.py +0 -278
- solace_agent_mesh/gateway/components/gateway_output.py +0 -298
- solace_agent_mesh/gateway/identity/bamboohr_identity.py +0 -18
- solace_agent_mesh/gateway/identity/identity_base.py +0 -10
- solace_agent_mesh/gateway/identity/identity_provider.py +0 -60
- solace_agent_mesh/gateway/identity/no_identity.py +0 -9
- solace_agent_mesh/gateway/identity/passthru_identity.py +0 -9
- solace_agent_mesh/monitors/base_monitor_component.py +0 -26
- solace_agent_mesh/monitors/feedback/user_feedback_monitor.py +0 -75
- solace_agent_mesh/monitors/stim_and_errors/stim_and_error_monitor.py +0 -560
- solace_agent_mesh/orchestrator/__init__.py +0 -0
- solace_agent_mesh/orchestrator/action_manager.py +0 -237
- solace_agent_mesh/orchestrator/components/__init__.py +0 -0
- solace_agent_mesh/orchestrator/components/orchestrator_action_manager_timeout_component.py +0 -58
- solace_agent_mesh/orchestrator/components/orchestrator_action_response_component.py +0 -179
- solace_agent_mesh/orchestrator/components/orchestrator_register_component.py +0 -107
- solace_agent_mesh/orchestrator/components/orchestrator_stimulus_processor_component.py +0 -527
- solace_agent_mesh/orchestrator/components/orchestrator_streaming_output_component.py +0 -260
- solace_agent_mesh/orchestrator/orchestrator_main.py +0 -172
- solace_agent_mesh/orchestrator/orchestrator_prompt.py +0 -539
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/authorization/providers/base_authorization_provider.py +0 -56
- solace_agent_mesh/services/bamboo_hr_service/__init__.py +0 -3
- solace_agent_mesh/services/bamboo_hr_service/bamboo_hr.py +0 -182
- solace_agent_mesh/services/common/__init__.py +0 -4
- solace_agent_mesh/services/common/auto_expiry.py +0 -45
- solace_agent_mesh/services/common/singleton.py +0 -18
- solace_agent_mesh/services/file_service/__init__.py +0 -14
- solace_agent_mesh/services/file_service/file_manager/__init__.py +0 -0
- solace_agent_mesh/services/file_service/file_manager/bucket_file_manager.py +0 -149
- solace_agent_mesh/services/file_service/file_manager/file_manager_base.py +0 -162
- solace_agent_mesh/services/file_service/file_manager/memory_file_manager.py +0 -64
- solace_agent_mesh/services/file_service/file_manager/volume_file_manager.py +0 -106
- solace_agent_mesh/services/file_service/file_service.py +0 -437
- solace_agent_mesh/services/file_service/file_service_constants.py +0 -54
- solace_agent_mesh/services/file_service/file_transformations.py +0 -141
- solace_agent_mesh/services/file_service/file_utils.py +0 -324
- solace_agent_mesh/services/file_service/transformers/__init__.py +0 -5
- solace_agent_mesh/services/history_service/__init__.py +0 -3
- solace_agent_mesh/services/history_service/history_providers/__init__.py +0 -0
- solace_agent_mesh/services/history_service/history_providers/base_history_provider.py +0 -54
- solace_agent_mesh/services/history_service/history_providers/file_history_provider.py +0 -74
- solace_agent_mesh/services/history_service/history_providers/index.py +0 -40
- solace_agent_mesh/services/history_service/history_providers/memory_history_provider.py +0 -33
- solace_agent_mesh/services/history_service/history_providers/mongodb_history_provider.py +0 -66
- solace_agent_mesh/services/history_service/history_providers/redis_history_provider.py +0 -66
- solace_agent_mesh/services/history_service/history_providers/sql_history_provider.py +0 -93
- solace_agent_mesh/services/history_service/history_service.py +0 -413
- solace_agent_mesh/services/history_service/long_term_memory/__init__.py +0 -0
- solace_agent_mesh/services/history_service/long_term_memory/long_term_memory.py +0 -399
- solace_agent_mesh/services/llm_service/components/llm_request_component.py +0 -340
- solace_agent_mesh/services/llm_service/components/llm_service_component_base.py +0 -152
- solace_agent_mesh/services/middleware_service/__init__.py +0 -0
- solace_agent_mesh/services/middleware_service/middleware_service.py +0 -20
- solace_agent_mesh/templates/action.py +0 -38
- solace_agent_mesh/templates/agent.py +0 -29
- solace_agent_mesh/templates/agent.yaml +0 -70
- solace_agent_mesh/templates/gateway-config-template.yaml +0 -6
- solace_agent_mesh/templates/gateway-default-config.yaml +0 -28
- solace_agent_mesh/templates/gateway-flows.yaml +0 -78
- solace_agent_mesh/templates/gateway-header.yaml +0 -16
- solace_agent_mesh/templates/gateway_base.py +0 -15
- solace_agent_mesh/templates/gateway_input.py +0 -98
- solace_agent_mesh/templates/gateway_output.py +0 -71
- solace_agent_mesh/templates/plugin-gateway-default-config.yaml +0 -29
- solace_agent_mesh/templates/plugin-pyproject.toml +0 -30
- solace_agent_mesh/templates/rest-api-default-config.yaml +0 -31
- solace_agent_mesh/templates/rest-api-flows.yaml +0 -81
- solace_agent_mesh/templates/slack-default-config.yaml +0 -16
- solace_agent_mesh/templates/slack-flows.yaml +0 -81
- solace_agent_mesh/templates/solace-agent-mesh-default.yaml +0 -86
- solace_agent_mesh/templates/solace-agent-mesh-plugin-default.yaml +0 -8
- solace_agent_mesh/templates/web-default-config.yaml +0 -10
- solace_agent_mesh/templates/web-flows.yaml +0 -76
- solace_agent_mesh/tools/__init__.py +0 -0
- solace_agent_mesh/tools/components/__init__.py +0 -0
- solace_agent_mesh/tools/components/conversation_formatter.py +0 -111
- solace_agent_mesh/tools/components/file_resolver_component.py +0 -58
- solace_agent_mesh/tools/config/runtime_config.py +0 -26
- solace_agent_mesh-0.2.4.dist-info/METADATA +0 -176
- solace_agent_mesh-0.2.4.dist-info/RECORD +0 -193
- solace_agent_mesh-0.2.4.dist-info/entry_points.txt +0 -3
- /solace_agent_mesh/{agents → agent}/__init__.py +0 -0
- /solace_agent_mesh/{agents/global → agent/adk}/__init__.py +0 -0
- /solace_agent_mesh/{agents/global/actions → agent/protocol}/__init__.py +0 -0
- /solace_agent_mesh/{agents/image_processing → agent/sac}/__init__.py +0 -0
- /solace_agent_mesh/{agents/image_processing/actions → agent/utils}/__init__.py +0 -0
- /solace_agent_mesh/{agents/web_request → config_portal/backend/plugin_catalog}/__init__.py +0 -0
- /solace_agent_mesh/{agents/web_request/actions → evaluation}/__init__.py +0 -0
- /solace_agent_mesh/gateway/{components → http_sse}/__init__.py +0 -0
- {solace_agent_mesh-0.2.4.dist-info → solace_agent_mesh-1.0.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/assets/favicon-BLgzUch9.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Solace Agent Mesh</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/authCallback-DvlO62me.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/client-bp6u3qVZ.js">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/assets/favicon-BLgzUch9.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Solace Agent Mesh</title>
|
|
8
|
+
<script type="module" crossorigin src="/assets/main-Gfk3BYn5.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/client-bp6u3qVZ.js">
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/main-D11Lmy9p.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div id="root"></div>
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Common utilities and types shared across A2A components."""
|
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Handles A2A topic construction and translation between A2A and ADK message formats.
|
|
3
|
+
Consolidated from src/a2a_adk_host/a2a_protocol.py and src/tools/common/a2a_protocol.py.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
7
|
+
import json
|
|
8
|
+
import base64
|
|
9
|
+
import re
|
|
10
|
+
from datetime import datetime, timezone
|
|
11
|
+
from solace_ai_connector.common.log import log
|
|
12
|
+
from google.genai import types as adk_types
|
|
13
|
+
from google.adk.events import Event as ADKEvent
|
|
14
|
+
|
|
15
|
+
from .types import (
|
|
16
|
+
Message as A2AMessage,
|
|
17
|
+
TextPart,
|
|
18
|
+
FilePart,
|
|
19
|
+
DataPart,
|
|
20
|
+
Part as A2APart,
|
|
21
|
+
JSONRPCResponse,
|
|
22
|
+
InternalError,
|
|
23
|
+
TaskStatus,
|
|
24
|
+
TaskState,
|
|
25
|
+
TaskStatusUpdateEvent,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
A2A_VERSION = "v1"
|
|
29
|
+
A2A_BASE_PATH = f"a2a/{A2A_VERSION}"
|
|
30
|
+
A2A_LLM_STREAM_CHUNKS_PROCESSED_KEY = "temp:llm_stream_chunks_processed"
|
|
31
|
+
A2A_STATUS_SIGNAL_STORAGE_KEY = "temp:a2a_status_signals_collected"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_a2a_base_topic(namespace: str) -> str:
|
|
35
|
+
"""Returns the base topic prefix for all A2A communication."""
|
|
36
|
+
if not namespace:
|
|
37
|
+
raise ValueError("A2A namespace cannot be empty.")
|
|
38
|
+
return f"{namespace.rstrip('/')}/{A2A_BASE_PATH}"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_discovery_topic(namespace: str) -> str:
|
|
42
|
+
"""Returns the topic for agent card discovery."""
|
|
43
|
+
return f"{get_a2a_base_topic(namespace)}/discovery/agentcards"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_agent_request_topic(namespace: str, agent_name: str) -> str:
|
|
47
|
+
"""Returns the topic for sending requests to a specific agent."""
|
|
48
|
+
if not agent_name:
|
|
49
|
+
raise ValueError("Agent name cannot be empty.")
|
|
50
|
+
return f"{get_a2a_base_topic(namespace)}/agent/request/{agent_name}"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_gateway_status_topic(namespace: str, gateway_id: str, task_id: str) -> str:
|
|
54
|
+
"""
|
|
55
|
+
Returns the specific topic for an agent to publish status updates TO a specific gateway instance.
|
|
56
|
+
"""
|
|
57
|
+
if not gateway_id:
|
|
58
|
+
raise ValueError("Gateway ID cannot be empty.")
|
|
59
|
+
if not task_id:
|
|
60
|
+
raise ValueError("Task ID cannot be empty.")
|
|
61
|
+
return f"{get_a2a_base_topic(namespace)}/gateway/status/{gateway_id}/{task_id}"
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_gateway_response_topic(namespace: str, gateway_id: str, task_id: str) -> str:
|
|
65
|
+
"""
|
|
66
|
+
Returns the specific topic for an agent to publish the final response TO a specific gateway instance.
|
|
67
|
+
Includes task_id for potential correlation/filtering, though gateway might subscribe more broadly.
|
|
68
|
+
"""
|
|
69
|
+
if not gateway_id:
|
|
70
|
+
raise ValueError("Gateway ID cannot be empty.")
|
|
71
|
+
if not task_id:
|
|
72
|
+
raise ValueError("Task ID cannot be empty.")
|
|
73
|
+
return f"{get_a2a_base_topic(namespace)}/gateway/response/{gateway_id}/{task_id}"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_gateway_status_subscription_topic(namespace: str, self_gateway_id: str) -> str:
|
|
77
|
+
"""
|
|
78
|
+
Returns the wildcard topic for a gateway instance to subscribe to receive status updates
|
|
79
|
+
intended for it.
|
|
80
|
+
"""
|
|
81
|
+
if not self_gateway_id:
|
|
82
|
+
raise ValueError("Gateway ID is required for gateway status subscription")
|
|
83
|
+
return f"{get_a2a_base_topic(namespace)}/gateway/status/{self_gateway_id}/>"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_gateway_response_subscription_topic(
|
|
87
|
+
namespace: str, self_gateway_id: str
|
|
88
|
+
) -> str:
|
|
89
|
+
"""
|
|
90
|
+
Returns the wildcard topic for a gateway instance to subscribe to receive final responses
|
|
91
|
+
intended for it.
|
|
92
|
+
"""
|
|
93
|
+
if not self_gateway_id:
|
|
94
|
+
raise ValueError("Gateway ID is required for gateway response subscription")
|
|
95
|
+
return f"{get_a2a_base_topic(namespace)}/gateway/response/{self_gateway_id}/>"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_peer_agent_status_topic(
|
|
99
|
+
namespace: str, delegating_agent_name: str, sub_task_id: str
|
|
100
|
+
) -> str:
|
|
101
|
+
"""
|
|
102
|
+
Returns the topic for publishing status updates for a sub-task *back to the delegating agent*.
|
|
103
|
+
This topic includes the delegating agent's name.
|
|
104
|
+
"""
|
|
105
|
+
if not delegating_agent_name:
|
|
106
|
+
raise ValueError("delegating_agent_name is required for peer status topic")
|
|
107
|
+
return f"{get_a2a_base_topic(namespace)}/agent/status/{delegating_agent_name}/{sub_task_id}"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_agent_response_topic(
|
|
111
|
+
namespace: str, delegating_agent_name: str, sub_task_id: str
|
|
112
|
+
) -> str:
|
|
113
|
+
"""
|
|
114
|
+
Returns the specific topic for publishing the final response for a sub-task
|
|
115
|
+
back to the delegating agent. Includes the delegating agent's name.
|
|
116
|
+
"""
|
|
117
|
+
if not delegating_agent_name:
|
|
118
|
+
raise ValueError("delegating_agent_name is required for peer response topic")
|
|
119
|
+
if not sub_task_id:
|
|
120
|
+
raise ValueError("sub_task_id is required for peer response topic")
|
|
121
|
+
return f"{get_a2a_base_topic(namespace)}/agent/response/{delegating_agent_name}/{sub_task_id}"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_agent_response_subscription_topic(namespace: str, self_agent_name: str) -> str:
|
|
125
|
+
"""
|
|
126
|
+
Returns the wildcard topic for an agent to subscribe to receive responses
|
|
127
|
+
for tasks it delegated. Includes the agent's own name.
|
|
128
|
+
"""
|
|
129
|
+
if not self_agent_name:
|
|
130
|
+
raise ValueError("self_agent_name is required for agent response subscription")
|
|
131
|
+
return f"{get_a2a_base_topic(namespace)}/agent/response/{self_agent_name}/>"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def get_agent_status_subscription_topic(namespace: str, self_agent_name: str) -> str:
|
|
135
|
+
"""
|
|
136
|
+
Returns the wildcard topic for an agent to subscribe to receive status updates
|
|
137
|
+
for tasks it delegated. Includes the agent's own name.
|
|
138
|
+
"""
|
|
139
|
+
if not self_agent_name:
|
|
140
|
+
raise ValueError("self_agent_name is required for agent status subscription")
|
|
141
|
+
return f"{get_a2a_base_topic(namespace)}/agent/status/{self_agent_name}/>"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def get_client_response_topic(namespace: str, client_id: str) -> str:
|
|
145
|
+
"""Returns the topic for publishing the final response TO a specific client."""
|
|
146
|
+
if not client_id:
|
|
147
|
+
raise ValueError("Client ID cannot be empty.")
|
|
148
|
+
return f"{get_a2a_base_topic(namespace)}/client/response/{client_id}"
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def get_client_status_topic(namespace: str, client_id: str, task_id: str) -> str:
|
|
152
|
+
"""
|
|
153
|
+
Returns the specific topic for publishing status updates for a task *to the original client*.
|
|
154
|
+
This topic is client and task-specific.
|
|
155
|
+
"""
|
|
156
|
+
if not client_id:
|
|
157
|
+
raise ValueError("Client ID cannot be empty.")
|
|
158
|
+
if not task_id:
|
|
159
|
+
raise ValueError("Task ID cannot be empty.")
|
|
160
|
+
return f"{get_a2a_base_topic(namespace)}/client/status/{client_id}/{task_id}"
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def get_client_status_subscription_topic(namespace: str, client_id: str) -> str:
|
|
164
|
+
"""
|
|
165
|
+
Returns the wildcard topic for a client to subscribe to receive status updates
|
|
166
|
+
for tasks it initiated. Includes the client's own ID.
|
|
167
|
+
"""
|
|
168
|
+
if not client_id:
|
|
169
|
+
raise ValueError("Client ID cannot be empty.")
|
|
170
|
+
return f"{get_a2a_base_topic(namespace)}/client/status/{client_id}/>"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def _subscription_to_regex(subscription: str) -> str:
|
|
174
|
+
"""Converts a Solace topic subscription string to a regex pattern."""
|
|
175
|
+
# Escape regex special characters except for Solace wildcards
|
|
176
|
+
pattern = re.escape(subscription)
|
|
177
|
+
# Replace Solace single-level wildcard '*' with regex equivalent '[^/]+'
|
|
178
|
+
pattern = pattern.replace(r"\*", r"[^/]+")
|
|
179
|
+
# Replace Solace multi-level wildcard '>' at the end with regex equivalent '.*'
|
|
180
|
+
if pattern.endswith(r"/>"):
|
|
181
|
+
pattern = pattern[:-1] + r".*" # Remove escaped '>' and add '.*'
|
|
182
|
+
return pattern
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _topic_matches_subscription(topic: str, subscription: str) -> bool:
|
|
186
|
+
"""Checks if a topic matches a Solace subscription pattern."""
|
|
187
|
+
regex_pattern = _subscription_to_regex(subscription)
|
|
188
|
+
return re.fullmatch(regex_pattern, topic) is not None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def translate_a2a_to_adk_content(
|
|
192
|
+
a2a_message: A2AMessage, log_identifier: str
|
|
193
|
+
) -> adk_types.Content:
|
|
194
|
+
"""Translates an A2A Message object to ADK Content."""
|
|
195
|
+
adk_parts: List[adk_types.Part] = []
|
|
196
|
+
for part in a2a_message.parts:
|
|
197
|
+
try:
|
|
198
|
+
if isinstance(part, TextPart):
|
|
199
|
+
adk_parts.append(adk_types.Part(text=part.text))
|
|
200
|
+
elif isinstance(part, FilePart):
|
|
201
|
+
file_info = f"Received file: name='{part.file.name}', mimeType='{part.file.mimeType}'"
|
|
202
|
+
if part.file.uri:
|
|
203
|
+
file_info += f", uri='{part.file.uri}'"
|
|
204
|
+
elif part.file.bytes:
|
|
205
|
+
try:
|
|
206
|
+
byte_len = len(base64.b64decode(part.file.bytes))
|
|
207
|
+
file_info += f", size={byte_len} bytes (base64 encoded)"
|
|
208
|
+
except Exception:
|
|
209
|
+
file_info += ", size=unknown (base64 encoded)"
|
|
210
|
+
adk_parts.append(adk_types.Part(text=file_info))
|
|
211
|
+
elif isinstance(part, DataPart):
|
|
212
|
+
try:
|
|
213
|
+
data_str = json.dumps(part.data, indent=2)
|
|
214
|
+
adk_parts.append(
|
|
215
|
+
adk_types.Part(text=f"Received data:\n```json\n{data_str}\n```")
|
|
216
|
+
)
|
|
217
|
+
except Exception as e:
|
|
218
|
+
log.warning(
|
|
219
|
+
"%s Could not serialize DataPart for ADK: %s", log_identifier, e
|
|
220
|
+
)
|
|
221
|
+
adk_parts.append(
|
|
222
|
+
adk_types.Part(text="Received unserializable structured data.")
|
|
223
|
+
)
|
|
224
|
+
else:
|
|
225
|
+
log.warning(
|
|
226
|
+
"%s Unsupported A2A part type: %s", log_identifier, type(part)
|
|
227
|
+
)
|
|
228
|
+
except Exception as e:
|
|
229
|
+
log.exception("%s Error translating A2A part: %s", log_identifier, e)
|
|
230
|
+
adk_parts.append(adk_types.Part(text="[Error processing received part]"))
|
|
231
|
+
|
|
232
|
+
adk_role = "user" if a2a_message.role == "user" else "model"
|
|
233
|
+
return adk_types.Content(role=adk_role, parts=adk_parts)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def _extract_text_from_parts(parts: List[A2APart]) -> str:
|
|
237
|
+
"""
|
|
238
|
+
Extracts and combines text/file info from a list of A2A parts
|
|
239
|
+
into a single string for display or logging.
|
|
240
|
+
|
|
241
|
+
Note: This function intentionally ignores DataPart types.
|
|
242
|
+
"""
|
|
243
|
+
output_parts = []
|
|
244
|
+
for part in parts:
|
|
245
|
+
if isinstance(part, TextPart):
|
|
246
|
+
output_parts.append(part.text)
|
|
247
|
+
elif isinstance(part, DataPart):
|
|
248
|
+
log.debug("Skipping DataPart in _extract_text_from_parts")
|
|
249
|
+
continue
|
|
250
|
+
elif isinstance(part, FilePart):
|
|
251
|
+
file_info = "File: '%s' (%s)" % (
|
|
252
|
+
part.file.name or "unknown",
|
|
253
|
+
part.file.mimeType or "unknown",
|
|
254
|
+
)
|
|
255
|
+
if part.file.uri:
|
|
256
|
+
file_info += " URI: %s" % part.file.uri
|
|
257
|
+
elif part.file.bytes:
|
|
258
|
+
try:
|
|
259
|
+
size = len(base64.b64decode(part.file.bytes))
|
|
260
|
+
file_info += " (Size: %d bytes)" % size
|
|
261
|
+
except Exception:
|
|
262
|
+
file_info += " (Encoded Bytes)"
|
|
263
|
+
output_parts.append(file_info)
|
|
264
|
+
else:
|
|
265
|
+
if isinstance(part, dict):
|
|
266
|
+
part_type = part.get("type")
|
|
267
|
+
if part_type == "text":
|
|
268
|
+
output_parts.append(part.get("text", "[Missing text content]"))
|
|
269
|
+
elif part_type == "data":
|
|
270
|
+
log.debug("Skipping DataPart (dict) in _extract_text_from_parts")
|
|
271
|
+
continue
|
|
272
|
+
elif part_type == "file":
|
|
273
|
+
file_content = part.get("file", {})
|
|
274
|
+
file_info = "File: '%s' (%s)" % (
|
|
275
|
+
file_content.get("name", "unknown"),
|
|
276
|
+
file_content.get("mimeType", "unknown"),
|
|
277
|
+
)
|
|
278
|
+
if file_content.get("uri"):
|
|
279
|
+
file_info += " URI: %s" % file_content["uri"]
|
|
280
|
+
elif file_content.get("bytes"):
|
|
281
|
+
try:
|
|
282
|
+
size = len(base64.b64decode(file_content["bytes"]))
|
|
283
|
+
file_info += " (Size: %d bytes)" % size
|
|
284
|
+
except Exception:
|
|
285
|
+
file_info += " (Encoded Bytes)"
|
|
286
|
+
output_parts.append(file_info)
|
|
287
|
+
else:
|
|
288
|
+
output_parts.append(
|
|
289
|
+
"[Unsupported part type in dict: %s]" % part_type
|
|
290
|
+
)
|
|
291
|
+
else:
|
|
292
|
+
output_parts.append("[Unsupported part type: %s]" % type(part))
|
|
293
|
+
|
|
294
|
+
return "\n".join(output_parts)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def format_adk_event_as_a2a(
|
|
298
|
+
adk_event: ADKEvent,
|
|
299
|
+
a2a_context: Dict,
|
|
300
|
+
log_identifier: str,
|
|
301
|
+
) -> Tuple[Optional[JSONRPCResponse], List[Tuple[int, Any]]]:
|
|
302
|
+
"""
|
|
303
|
+
Translates an intermediate ADK Event (containing content or errors during the run)
|
|
304
|
+
into an A2A JSON-RPC message payload (TaskStatusUpdateEvent or InternalError).
|
|
305
|
+
Also extracts any "a2a_status_signals_collected" from the event's state_delta.
|
|
306
|
+
Returns None if the event should not result in an intermediate A2A message (e.g., empty, non-streaming final).
|
|
307
|
+
Artifact updates are handled separately by the calling component.
|
|
308
|
+
|
|
309
|
+
Note: This function preserves DataPart from function responses.
|
|
310
|
+
"""
|
|
311
|
+
jsonrpc_request_id = a2a_context.get("jsonrpc_request_id")
|
|
312
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
313
|
+
is_streaming = a2a_context.get("is_streaming", False)
|
|
314
|
+
|
|
315
|
+
if adk_event.error_code or adk_event.error_message:
|
|
316
|
+
error_msg = f"Agent error during execution: {adk_event.error_message or adk_event.error_code}"
|
|
317
|
+
log.error("%s ADK Event contains error: %s", log_identifier, error_msg)
|
|
318
|
+
a2a_error = InternalError(
|
|
319
|
+
message=error_msg,
|
|
320
|
+
data={
|
|
321
|
+
"adk_error_code": adk_event.error_code,
|
|
322
|
+
"taskId": logical_task_id,
|
|
323
|
+
},
|
|
324
|
+
)
|
|
325
|
+
return JSONRPCResponse(id=jsonrpc_request_id, error=a2a_error), []
|
|
326
|
+
|
|
327
|
+
signals_to_forward: List[Tuple[int, Any]] = []
|
|
328
|
+
is_final_adk_event = (
|
|
329
|
+
# We have a different definition of final for ADK events:
|
|
330
|
+
# For now, the only long running tool IDs are peer agent tasks, which we
|
|
331
|
+
# need to wait for before considering the event final.
|
|
332
|
+
adk_event.is_final_response()
|
|
333
|
+
and (not hasattr(adk_event, 'long_running_tool_ids') or not adk_event.long_running_tool_ids)
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
a2a_parts: List[A2APart] = []
|
|
337
|
+
if adk_event.content and adk_event.content.parts:
|
|
338
|
+
for part in adk_event.content.parts:
|
|
339
|
+
try:
|
|
340
|
+
if part.text:
|
|
341
|
+
a2a_parts.append(TextPart(text=part.text))
|
|
342
|
+
elif part.inline_data:
|
|
343
|
+
log.debug(
|
|
344
|
+
"%s Skipping ADK inline_data part in status update translation.",
|
|
345
|
+
log_identifier,
|
|
346
|
+
)
|
|
347
|
+
elif part.function_call:
|
|
348
|
+
log.debug(
|
|
349
|
+
"%s Skipping ADK function call part in A2A translation.",
|
|
350
|
+
log_identifier,
|
|
351
|
+
)
|
|
352
|
+
elif part.function_response:
|
|
353
|
+
try:
|
|
354
|
+
response_data = part.function_response.response
|
|
355
|
+
tool_metadata = {
|
|
356
|
+
"tool_name": part.function_response.name,
|
|
357
|
+
"function_call_id": part.function_response.id,
|
|
358
|
+
"status_from_tool": "success",
|
|
359
|
+
}
|
|
360
|
+
if isinstance(response_data, dict):
|
|
361
|
+
a2a_parts.append(
|
|
362
|
+
DataPart(data=response_data, metadata=tool_metadata)
|
|
363
|
+
)
|
|
364
|
+
elif isinstance(response_data, str):
|
|
365
|
+
a2a_parts.append(
|
|
366
|
+
DataPart(
|
|
367
|
+
data={"text": response_data}, metadata=tool_metadata
|
|
368
|
+
)
|
|
369
|
+
)
|
|
370
|
+
else:
|
|
371
|
+
a2a_parts.append(
|
|
372
|
+
DataPart(
|
|
373
|
+
data={"value": str(response_data)},
|
|
374
|
+
metadata=tool_metadata,
|
|
375
|
+
)
|
|
376
|
+
)
|
|
377
|
+
except Exception as func_resp_ex:
|
|
378
|
+
log.warning(
|
|
379
|
+
"%s Could not process function response for tool %s: %s. Creating error TextPart.",
|
|
380
|
+
log_identifier,
|
|
381
|
+
part.function_response.name,
|
|
382
|
+
func_resp_ex,
|
|
383
|
+
)
|
|
384
|
+
a2a_parts.append(
|
|
385
|
+
TextPart(
|
|
386
|
+
text=f"[Error processing tool response for {part.function_response.name}: {func_resp_ex}]"
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
else:
|
|
390
|
+
log.warning(
|
|
391
|
+
"%s Skipping unknown ADK part type during A2A translation: %s",
|
|
392
|
+
log_identifier,
|
|
393
|
+
part,
|
|
394
|
+
)
|
|
395
|
+
except Exception as e:
|
|
396
|
+
log.exception("%s Error translating ADK part: %s", log_identifier, e)
|
|
397
|
+
a2a_parts.append(TextPart(text="[Error processing agent output part]"))
|
|
398
|
+
|
|
399
|
+
if is_final_adk_event and not is_streaming:
|
|
400
|
+
if not a2a_parts:
|
|
401
|
+
log.debug(
|
|
402
|
+
"%s Skipping non-streaming final ADK event %s with no content in format_adk_event_as_a2a.",
|
|
403
|
+
log_identifier,
|
|
404
|
+
adk_event.id,
|
|
405
|
+
)
|
|
406
|
+
return None, signals_to_forward
|
|
407
|
+
else:
|
|
408
|
+
log.debug(
|
|
409
|
+
"%s Processing non-streaming final ADK event %s with content in format_adk_event_as_a2a.",
|
|
410
|
+
log_identifier,
|
|
411
|
+
adk_event.id,
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
is_function_response_event = any(
|
|
415
|
+
p.function_response
|
|
416
|
+
for p in (adk_event.content.parts if adk_event.content else [])
|
|
417
|
+
)
|
|
418
|
+
should_send_status = (
|
|
419
|
+
(is_streaming and bool(a2a_parts))
|
|
420
|
+
or is_function_response_event
|
|
421
|
+
or (is_final_adk_event and bool(a2a_parts))
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
if not should_send_status:
|
|
425
|
+
log.debug(
|
|
426
|
+
"%s ADK event %s resulted in no intermediate A2A status update to send. Skipping.",
|
|
427
|
+
log_identifier,
|
|
428
|
+
adk_event.id,
|
|
429
|
+
)
|
|
430
|
+
return None, signals_to_forward
|
|
431
|
+
|
|
432
|
+
message_metadata = None
|
|
433
|
+
if is_function_response_event:
|
|
434
|
+
message_metadata = {"type": "tool_response_content"}
|
|
435
|
+
log.debug(
|
|
436
|
+
"%s Prepared message metadata for tool_response_content.", log_identifier
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
a2a_message = A2AMessage(role="agent", parts=a2a_parts, metadata=message_metadata)
|
|
440
|
+
task_status = TaskStatus(
|
|
441
|
+
state=TaskState.WORKING,
|
|
442
|
+
message=a2a_message,
|
|
443
|
+
timestamp=datetime.now(timezone.utc),
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
is_final_update_for_this_event = is_final_adk_event
|
|
447
|
+
|
|
448
|
+
host_agent_name = a2a_context.get("host_agent_name", "unknown_agent")
|
|
449
|
+
event_metadata = {"agent_name": host_agent_name}
|
|
450
|
+
|
|
451
|
+
intermediate_result_obj = TaskStatusUpdateEvent(
|
|
452
|
+
id=logical_task_id,
|
|
453
|
+
status=task_status,
|
|
454
|
+
final=is_final_update_for_this_event,
|
|
455
|
+
metadata=event_metadata,
|
|
456
|
+
)
|
|
457
|
+
log.debug(
|
|
458
|
+
"%s Formatting intermediate A2A response (TaskStatusUpdateEvent, final=%s) for Task ID %s. Event type: %s",
|
|
459
|
+
log_identifier,
|
|
460
|
+
is_final_update_for_this_event,
|
|
461
|
+
logical_task_id,
|
|
462
|
+
message_metadata.get("type") if message_metadata else "llm_stream_chunk",
|
|
463
|
+
)
|
|
464
|
+
json_rpc_response_obj = JSONRPCResponse(
|
|
465
|
+
id=jsonrpc_request_id, result=intermediate_result_obj
|
|
466
|
+
)
|
|
467
|
+
return json_rpc_response_obj, signals_to_forward
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
async def format_and_route_adk_event(
|
|
471
|
+
adk_event: ADKEvent,
|
|
472
|
+
a2a_context: Dict,
|
|
473
|
+
component,
|
|
474
|
+
) -> Tuple[Optional[Dict], Optional[str], Optional[Dict], List[Tuple[int, Any]]]:
|
|
475
|
+
"""
|
|
476
|
+
Formats an intermediate ADK event (content or error) to an A2A payload dict,
|
|
477
|
+
and determines the target status topic.
|
|
478
|
+
Returns (None, None, []) if no intermediate message should be sent.
|
|
479
|
+
Signal extraction from state_delta is REMOVED as it's handled upstream by SamAgentComponent.
|
|
480
|
+
Final responses and artifact updates are handled elsewhere.
|
|
481
|
+
"""
|
|
482
|
+
signals_found: List[Tuple[int, Any]] = []
|
|
483
|
+
try:
|
|
484
|
+
a2a_response_obj, _ = format_adk_event_as_a2a(
|
|
485
|
+
adk_event, a2a_context, component.log_identifier
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
if not a2a_response_obj:
|
|
489
|
+
return None, None, None, []
|
|
490
|
+
|
|
491
|
+
a2a_payload = a2a_response_obj.model_dump(exclude_none=True)
|
|
492
|
+
target_topic = None
|
|
493
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
494
|
+
peer_status_topic = a2a_context.get("statusTopic")
|
|
495
|
+
namespace = component.get_config("namespace")
|
|
496
|
+
|
|
497
|
+
if peer_status_topic:
|
|
498
|
+
target_topic = peer_status_topic
|
|
499
|
+
log.debug(
|
|
500
|
+
"%s Determined status update topic (to peer delegator): %s",
|
|
501
|
+
component.log_identifier,
|
|
502
|
+
target_topic,
|
|
503
|
+
)
|
|
504
|
+
else:
|
|
505
|
+
gateway_id = component.get_gateway_id()
|
|
506
|
+
target_topic = get_gateway_status_topic(
|
|
507
|
+
namespace, gateway_id, logical_task_id
|
|
508
|
+
)
|
|
509
|
+
log.debug(
|
|
510
|
+
"%s Determined status update topic (to gateway): %s",
|
|
511
|
+
component.log_identifier,
|
|
512
|
+
target_topic,
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
user_properties = {}
|
|
516
|
+
if a2a_context.get("a2a_user_config"):
|
|
517
|
+
user_properties["a2aUserConfig"] = a2a_context["a2a_user_config"]
|
|
518
|
+
|
|
519
|
+
return a2a_payload, target_topic, user_properties, signals_found
|
|
520
|
+
|
|
521
|
+
except Exception as e:
|
|
522
|
+
log.exception(
|
|
523
|
+
"%s Error formatting or routing intermediate ADK event %s: %s",
|
|
524
|
+
component.log_identifier,
|
|
525
|
+
adk_event.id,
|
|
526
|
+
e,
|
|
527
|
+
)
|
|
528
|
+
try:
|
|
529
|
+
jsonrpc_request_id = a2a_context.get("jsonrpc_request_id")
|
|
530
|
+
logical_task_id = a2a_context.get("logical_task_id")
|
|
531
|
+
namespace = component.get_config("namespace")
|
|
532
|
+
gateway_id = component.get_gateway_id()
|
|
533
|
+
peer_reply_topic = a2a_context.get("replyToTopic")
|
|
534
|
+
|
|
535
|
+
error_response = JSONRPCResponse(
|
|
536
|
+
id=jsonrpc_request_id,
|
|
537
|
+
error=InternalError(
|
|
538
|
+
message=f"Error processing agent event: {e}",
|
|
539
|
+
data={"taskId": logical_task_id},
|
|
540
|
+
),
|
|
541
|
+
)
|
|
542
|
+
if peer_reply_topic:
|
|
543
|
+
target_topic = peer_reply_topic
|
|
544
|
+
else:
|
|
545
|
+
target_topic = get_gateway_response_topic(
|
|
546
|
+
namespace, gateway_id, logical_task_id
|
|
547
|
+
)
|
|
548
|
+
user_properties = {}
|
|
549
|
+
if a2a_context.get("a2a_user_config"):
|
|
550
|
+
user_properties["a2aUserConfig"] = a2a_context["a2a_user_config"]
|
|
551
|
+
|
|
552
|
+
return (
|
|
553
|
+
error_response.model_dump(exclude_none=True),
|
|
554
|
+
target_topic,
|
|
555
|
+
user_properties,
|
|
556
|
+
[],
|
|
557
|
+
)
|
|
558
|
+
except Exception as inner_e:
|
|
559
|
+
log.error(
|
|
560
|
+
"%s Failed to generate error response after formatting error: %s",
|
|
561
|
+
component.log_identifier,
|
|
562
|
+
inner_e,
|
|
563
|
+
)
|
|
564
|
+
return None, None, None, []
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manages discovered A2A agents.
|
|
3
|
+
Consolidated from src/tools/common/agent_registry.py and src/tools/a2a_cli_client/agent_registry.py.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import threading
|
|
7
|
+
from typing import Dict, List, Optional
|
|
8
|
+
|
|
9
|
+
from ..common.types import AgentCard
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AgentRegistry:
|
|
13
|
+
"""Stores and manages discovered AgentCards."""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
self._agents: Dict[str, AgentCard] = {}
|
|
17
|
+
self._lock = threading.Lock()
|
|
18
|
+
|
|
19
|
+
def add_or_update_agent(self, agent_card: AgentCard):
|
|
20
|
+
"""Adds a new agent or updates an existing one."""
|
|
21
|
+
if not agent_card or not agent_card.name:
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
with self._lock:
|
|
25
|
+
is_new = agent_card.name not in self._agents
|
|
26
|
+
self._agents[agent_card.name] = agent_card
|
|
27
|
+
return is_new
|
|
28
|
+
|
|
29
|
+
def get_agent(self, agent_name: str) -> Optional[AgentCard]:
|
|
30
|
+
"""Retrieves an agent card by name."""
|
|
31
|
+
with self._lock:
|
|
32
|
+
return self._agents.get(agent_name)
|
|
33
|
+
|
|
34
|
+
def get_agent_names(self) -> List[str]:
|
|
35
|
+
"""Returns a sorted list of discovered agent names."""
|
|
36
|
+
with self._lock:
|
|
37
|
+
return sorted(list(self._agents.keys()))
|
|
38
|
+
|
|
39
|
+
def clear(self):
|
|
40
|
+
"""Clears all registered agents."""
|
|
41
|
+
with self._lock:
|
|
42
|
+
self._agents.clear()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import httpx
|
|
2
|
+
from ...common.types import (
|
|
3
|
+
AgentCard,
|
|
4
|
+
A2AClientJSONError,
|
|
5
|
+
)
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class A2ACardResolver:
|
|
10
|
+
def __init__(self, base_url, agent_card_path="/.well-known/agent.json"):
|
|
11
|
+
self.base_url = base_url.rstrip("/")
|
|
12
|
+
self.agent_card_path = agent_card_path.lstrip("/")
|
|
13
|
+
|
|
14
|
+
def get_agent_card(self) -> AgentCard:
|
|
15
|
+
with httpx.Client() as client:
|
|
16
|
+
response = client.get(self.base_url + "/" + self.agent_card_path)
|
|
17
|
+
response.raise_for_status()
|
|
18
|
+
try:
|
|
19
|
+
return AgentCard(**response.json())
|
|
20
|
+
except json.JSONDecodeError as e:
|
|
21
|
+
raise A2AClientJSONError(str(e)) from e
|