solace-agent-mesh 0.2.4__py3-none-any.whl → 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/adk_llm.txt +93 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +26 -0
- solace_agent_mesh/agent/adk/callbacks.py +1694 -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 +353 -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 +1469 -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 +3388 -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 +176 -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 +569 -0
- solace_agent_mesh/agent/tools/image_tools.py +1184 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +289 -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.23bccffb.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.2c2e152c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/fbfa3e75.aca209c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.7ed3319f.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/main.7ed3319f.js.LICENSE.txt +81 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.d9520ae2.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 +60 -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-1753813536522.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -0
- solace_agent_mesh/assets/docs/search-doc-1753813536522.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 +197 -0
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +387 -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 +138 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +309 -0
- solace_agent_mesh/cli/commands/plugin_cmd/official_registry.py +174 -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-An0a5j5k.js +663 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-Bu5-4Bac.css +1 -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/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 +23 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/models.py +49 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/registry_manager.py +160 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/scraper.py +525 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog_server.py +216 -0
- solace_agent_mesh/config_portal/backend/server.py +550 -181
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DNxCwAGB.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-d2b54a97.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 +821 -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 +400 -0
- solace_agent_mesh/templates/gateway_config_template.yaml +43 -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.1.dist-info/METADATA +432 -0
- solace_agent_mesh-1.0.1.dist-info/RECORD +359 -0
- solace_agent_mesh-1.0.1.dist-info/entry_points.txt +3 -0
- {solace_agent_mesh-0.2.4.dist-info → solace_agent_mesh-1.0.1.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.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manages web user sessions and mapping to A2A Client IDs.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import uuid
|
|
6
|
+
from starlette.requests import Request
|
|
7
|
+
from typing import Optional, Callable, Dict, Any
|
|
8
|
+
|
|
9
|
+
from solace_ai_connector.common.log import log
|
|
10
|
+
|
|
11
|
+
SESSION_KEY_CLIENT_ID = "a2a_client_id"
|
|
12
|
+
SESSION_KEY_SESSION_ID = "a2a_session_id"
|
|
13
|
+
SESSION_KEY_ACCESS_TOKEN = "access_token"
|
|
14
|
+
SESSION_KEY_REFRESH_TOKEN = "refresh_token"
|
|
15
|
+
SESSION_KEY_USER_ID = "user_id"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class SessionManager:
|
|
19
|
+
"""
|
|
20
|
+
Handles web user sessions using Starlette's SessionMiddleware.
|
|
21
|
+
Generates and stores unique A2A Client IDs and manages the current A2A Session ID per web session.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
def __init__(self, secret_key: str, app_config: Dict[str, Any]):
|
|
25
|
+
if not secret_key:
|
|
26
|
+
raise ValueError("Session secret key cannot be empty.")
|
|
27
|
+
self.secret_key = secret_key
|
|
28
|
+
self.force_user_identity = app_config.get("force_user_identity")
|
|
29
|
+
self.default_user_identity = app_config.get("default_user_identity")
|
|
30
|
+
self._temp_code_cache = {}
|
|
31
|
+
log.info("[SessionManager] Initialized.")
|
|
32
|
+
if self.force_user_identity:
|
|
33
|
+
log.warning(
|
|
34
|
+
f"[SessionManager] Forcing user identity to: {self.force_user_identity}"
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def _get_or_create_client_id(self, request: Request) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Retrieves the A2A Client ID. It prioritizes the authenticated user from
|
|
40
|
+
`request.state.user` and falls back to session-based or generated IDs.
|
|
41
|
+
"""
|
|
42
|
+
if self.force_user_identity:
|
|
43
|
+
return self.force_user_identity
|
|
44
|
+
|
|
45
|
+
if hasattr(request.state, "user") and request.state.user:
|
|
46
|
+
user_id = request.state.user.get("id")
|
|
47
|
+
if user_id:
|
|
48
|
+
log.debug(
|
|
49
|
+
"[SessionManager] Using authenticated user ID from request.state: %s",
|
|
50
|
+
user_id,
|
|
51
|
+
)
|
|
52
|
+
return user_id
|
|
53
|
+
else:
|
|
54
|
+
log.warning(
|
|
55
|
+
"[SessionManager] request.state.user exists but has no 'id' field. Falling back to other methods."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
user_id = self.get_user_id(request)
|
|
59
|
+
if user_id:
|
|
60
|
+
log.debug(
|
|
61
|
+
"[SessionManager] Using authenticated user_id from session as A2A Client ID: %s",
|
|
62
|
+
user_id,
|
|
63
|
+
)
|
|
64
|
+
return user_id
|
|
65
|
+
|
|
66
|
+
client_id = request.session.get(SESSION_KEY_CLIENT_ID)
|
|
67
|
+
if not client_id:
|
|
68
|
+
if self.default_user_identity:
|
|
69
|
+
log.info(
|
|
70
|
+
"[SessionManager] Using default_user_identity as A2A Client ID: %s",
|
|
71
|
+
self.default_user_identity,
|
|
72
|
+
)
|
|
73
|
+
client_id = self.default_user_identity
|
|
74
|
+
else:
|
|
75
|
+
client_id = f"web-client-{uuid.uuid4().hex}"
|
|
76
|
+
log.info(
|
|
77
|
+
"[SessionManager] Created new A2A Client ID: %s for web session.",
|
|
78
|
+
client_id,
|
|
79
|
+
)
|
|
80
|
+
request.session[SESSION_KEY_CLIENT_ID] = client_id
|
|
81
|
+
else:
|
|
82
|
+
log.debug(
|
|
83
|
+
"[SessionManager] Using existing A2A Client ID: %s for web session.",
|
|
84
|
+
client_id,
|
|
85
|
+
)
|
|
86
|
+
return client_id
|
|
87
|
+
|
|
88
|
+
def get_a2a_client_id(self, request: Request) -> str:
|
|
89
|
+
"""
|
|
90
|
+
FastAPI dependency callable to get the A2A Client ID for the current request.
|
|
91
|
+
Ensures a client ID exists in the session.
|
|
92
|
+
"""
|
|
93
|
+
return self._get_or_create_client_id(request)
|
|
94
|
+
|
|
95
|
+
def get_a2a_session_id(self, request: Request) -> Optional[str]:
|
|
96
|
+
"""
|
|
97
|
+
FastAPI dependency callable to get the current A2A Session ID for the current request.
|
|
98
|
+
Returns None if no session has been started for the current agent in this web session.
|
|
99
|
+
"""
|
|
100
|
+
session_id = request.session.get(SESSION_KEY_SESSION_ID)
|
|
101
|
+
log.debug("[SessionManager] Retrieving A2A Session ID: %s", session_id)
|
|
102
|
+
return session_id
|
|
103
|
+
|
|
104
|
+
def start_new_a2a_session(self, request: Request) -> str:
|
|
105
|
+
"""
|
|
106
|
+
Generates a new A2A Session ID, stores it in the web session, and returns it.
|
|
107
|
+
This should be called when the user explicitly starts a new chat or switches agents.
|
|
108
|
+
"""
|
|
109
|
+
client_id = self._get_or_create_client_id(request)
|
|
110
|
+
new_session_id = f"web-session-{uuid.uuid4().hex}"
|
|
111
|
+
request.session[SESSION_KEY_SESSION_ID] = new_session_id
|
|
112
|
+
log.info(
|
|
113
|
+
"[SessionManager] Started new A2A Session ID: %s for Client ID: %s",
|
|
114
|
+
new_session_id,
|
|
115
|
+
client_id,
|
|
116
|
+
)
|
|
117
|
+
return new_session_id
|
|
118
|
+
|
|
119
|
+
def ensure_a2a_session(self, request: Request) -> str:
|
|
120
|
+
"""
|
|
121
|
+
Ensures an A2A session ID exists, creating one if necessary.
|
|
122
|
+
Use this when an operation requires a session ID but one might not have been explicitly started yet.
|
|
123
|
+
"""
|
|
124
|
+
session_id = self.get_a2a_session_id(request)
|
|
125
|
+
if not session_id:
|
|
126
|
+
session_id = self.start_new_a2a_session(request)
|
|
127
|
+
log.info(
|
|
128
|
+
"[SessionManager] No A2A Session ID found, created new one via ensure_a2a_session: %s",
|
|
129
|
+
session_id,
|
|
130
|
+
)
|
|
131
|
+
return session_id
|
|
132
|
+
|
|
133
|
+
def store_auth_tokens(
|
|
134
|
+
self, request: Request, access_token: str, refresh_token: Optional[str] = None
|
|
135
|
+
):
|
|
136
|
+
"""
|
|
137
|
+
Stores authentication tokens directly in the user's session.
|
|
138
|
+
"""
|
|
139
|
+
request.session[SESSION_KEY_ACCESS_TOKEN] = access_token
|
|
140
|
+
if refresh_token:
|
|
141
|
+
request.session[SESSION_KEY_REFRESH_TOKEN] = refresh_token
|
|
142
|
+
log.info("[SessionManager] Stored auth tokens directly in session.")
|
|
143
|
+
|
|
144
|
+
def get_access_token(self, request: Request) -> Optional[str]:
|
|
145
|
+
"""
|
|
146
|
+
Retrieves the access token from the web session.
|
|
147
|
+
"""
|
|
148
|
+
return request.session.get(SESSION_KEY_ACCESS_TOKEN)
|
|
149
|
+
|
|
150
|
+
def get_refresh_token(self, request: Request) -> Optional[str]:
|
|
151
|
+
"""
|
|
152
|
+
Retrieves the refresh token from the web session.
|
|
153
|
+
"""
|
|
154
|
+
return request.session.get(SESSION_KEY_REFRESH_TOKEN)
|
|
155
|
+
|
|
156
|
+
def clear_auth_tokens(self, request: Request) -> None:
|
|
157
|
+
"""
|
|
158
|
+
Clears authentication tokens from the web session.
|
|
159
|
+
"""
|
|
160
|
+
request.session.pop(SESSION_KEY_ACCESS_TOKEN, None)
|
|
161
|
+
request.session.pop(SESSION_KEY_REFRESH_TOKEN, None)
|
|
162
|
+
log.info("[SessionManager] Cleared auth tokens from session")
|
|
163
|
+
|
|
164
|
+
def store_user_id(self, request: Request, user_id: str) -> None:
|
|
165
|
+
"""
|
|
166
|
+
Stores the user ID in the web session.
|
|
167
|
+
"""
|
|
168
|
+
request.session[SESSION_KEY_USER_ID] = user_id
|
|
169
|
+
log.info("[SessionManager] Stored user ID in session: %s", user_id)
|
|
170
|
+
|
|
171
|
+
def get_user_id(self, request: Request) -> Optional[str]:
|
|
172
|
+
"""
|
|
173
|
+
Retrieves the user ID from the web session.
|
|
174
|
+
"""
|
|
175
|
+
return request.session.get(SESSION_KEY_USER_ID)
|
|
176
|
+
|
|
177
|
+
def dep_get_client_id(self) -> Callable[[Request], str]:
|
|
178
|
+
"""Returns a callable suitable for FastAPI Depends to get the client ID."""
|
|
179
|
+
return self.get_a2a_client_id
|
|
180
|
+
|
|
181
|
+
def dep_get_session_id(self) -> Callable[[Request], Optional[str]]:
|
|
182
|
+
"""Returns a callable suitable for FastAPI Depends to get the current session ID."""
|
|
183
|
+
return self.get_a2a_session_id
|
|
184
|
+
|
|
185
|
+
def dep_ensure_session_id(self) -> Callable[[Request], str]:
|
|
186
|
+
"""Returns a callable suitable for FastAPI Depends to ensure a session ID exists."""
|
|
187
|
+
return self.ensure_a2a_session
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Manages Server-Sent Event (SSE) connections for streaming task updates.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import threading
|
|
7
|
+
from typing import Dict, List, Any
|
|
8
|
+
import json
|
|
9
|
+
|
|
10
|
+
from solace_ai_connector.common.log import log
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SSEManager:
|
|
14
|
+
"""
|
|
15
|
+
Manages active SSE connections and distributes events based on task ID.
|
|
16
|
+
Uses asyncio Queues for buffering events per connection.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, max_queue_size: int = 200):
|
|
20
|
+
self._connections: Dict[str, List[asyncio.Queue]] = {}
|
|
21
|
+
self._locks: Dict[asyncio.AbstractEventLoop, asyncio.Lock] = {}
|
|
22
|
+
self._locks_lock = threading.Lock()
|
|
23
|
+
self.log_identifier = "[SSEManager]"
|
|
24
|
+
self._max_queue_size = max_queue_size
|
|
25
|
+
|
|
26
|
+
def _get_lock(self) -> asyncio.Lock:
|
|
27
|
+
"""Get or create a lock for the current event loop."""
|
|
28
|
+
try:
|
|
29
|
+
current_loop = asyncio.get_running_loop()
|
|
30
|
+
except RuntimeError:
|
|
31
|
+
log.error(
|
|
32
|
+
"%s _get_lock must be called from within an async context.",
|
|
33
|
+
self.log_identifier,
|
|
34
|
+
)
|
|
35
|
+
raise RuntimeError(
|
|
36
|
+
"SSEManager methods must be called from within an async context"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
with self._locks_lock:
|
|
40
|
+
if current_loop not in self._locks:
|
|
41
|
+
self._locks[current_loop] = asyncio.Lock()
|
|
42
|
+
log.debug(
|
|
43
|
+
"%s Created new lock for event loop %s",
|
|
44
|
+
self.log_identifier,
|
|
45
|
+
id(current_loop),
|
|
46
|
+
)
|
|
47
|
+
return self._locks[current_loop]
|
|
48
|
+
|
|
49
|
+
async def create_sse_connection(self, task_id: str) -> asyncio.Queue:
|
|
50
|
+
"""
|
|
51
|
+
Creates a new queue for an SSE connection subscribing to a task.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
task_id: The ID of the task the connection is interested in.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
An asyncio.Queue that the SSE endpoint can consume from.
|
|
58
|
+
"""
|
|
59
|
+
lock = self._get_lock()
|
|
60
|
+
async with lock:
|
|
61
|
+
if task_id not in self._connections:
|
|
62
|
+
self._connections[task_id] = []
|
|
63
|
+
|
|
64
|
+
connection_queue = asyncio.Queue(maxsize=self._max_queue_size)
|
|
65
|
+
self._connections[task_id].append(connection_queue)
|
|
66
|
+
log.info(
|
|
67
|
+
"%s Created SSE connection queue for Task ID: %s. Total queues for task: %d",
|
|
68
|
+
self.log_identifier,
|
|
69
|
+
task_id,
|
|
70
|
+
len(self._connections[task_id]),
|
|
71
|
+
)
|
|
72
|
+
return connection_queue
|
|
73
|
+
|
|
74
|
+
async def remove_sse_connection(
|
|
75
|
+
self, task_id: str, connection_queue: asyncio.Queue
|
|
76
|
+
):
|
|
77
|
+
"""
|
|
78
|
+
Removes a specific SSE connection queue for a task.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
task_id: The ID of the task.
|
|
82
|
+
connection_queue: The specific queue instance to remove.
|
|
83
|
+
"""
|
|
84
|
+
lock = self._get_lock()
|
|
85
|
+
async with lock:
|
|
86
|
+
if task_id in self._connections:
|
|
87
|
+
try:
|
|
88
|
+
self._connections[task_id].remove(connection_queue)
|
|
89
|
+
log.info(
|
|
90
|
+
"%s Removed SSE connection queue for Task ID: %s. Remaining queues: %d",
|
|
91
|
+
self.log_identifier,
|
|
92
|
+
task_id,
|
|
93
|
+
len(self._connections[task_id]),
|
|
94
|
+
)
|
|
95
|
+
if not self._connections[task_id]:
|
|
96
|
+
del self._connections[task_id]
|
|
97
|
+
log.info(
|
|
98
|
+
"%s Removed Task ID entry: %s as no connections remain.",
|
|
99
|
+
self.log_identifier,
|
|
100
|
+
task_id,
|
|
101
|
+
)
|
|
102
|
+
except ValueError:
|
|
103
|
+
log.debug(
|
|
104
|
+
"%s Attempted to remove an already removed queue for Task ID: %s.",
|
|
105
|
+
self.log_identifier,
|
|
106
|
+
task_id,
|
|
107
|
+
)
|
|
108
|
+
else:
|
|
109
|
+
log.warning(
|
|
110
|
+
"%s Attempted to remove queue for non-existent Task ID: %s.",
|
|
111
|
+
self.log_identifier,
|
|
112
|
+
task_id,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
async def send_event(
|
|
116
|
+
self, task_id: str, event_data: Dict[str, Any], event_type: str = "message"
|
|
117
|
+
):
|
|
118
|
+
"""
|
|
119
|
+
Sends an event (as a dictionary) to all active SSE connections for a specific task.
|
|
120
|
+
The event_data dictionary will be JSON serialized for the SSE 'data' field.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
task_id: The ID of the task the event belongs to.
|
|
124
|
+
event_data: The dictionary representing the A2A event (e.g., TaskStatusUpdateEvent).
|
|
125
|
+
event_type: The type of the SSE event (default: "message").
|
|
126
|
+
"""
|
|
127
|
+
lock = self._get_lock()
|
|
128
|
+
async with lock:
|
|
129
|
+
if task_id not in self._connections:
|
|
130
|
+
log.debug(
|
|
131
|
+
"%s No active SSE connections for Task ID: %s. Event not sent.",
|
|
132
|
+
self.log_identifier,
|
|
133
|
+
task_id,
|
|
134
|
+
)
|
|
135
|
+
return
|
|
136
|
+
|
|
137
|
+
queues_to_remove = []
|
|
138
|
+
try:
|
|
139
|
+
serialized_data = json.dumps(event_data)
|
|
140
|
+
except Exception as json_err:
|
|
141
|
+
log.error(
|
|
142
|
+
"%s Failed to JSON serialize event data for Task ID %s: %s",
|
|
143
|
+
self.log_identifier,
|
|
144
|
+
task_id,
|
|
145
|
+
json_err,
|
|
146
|
+
)
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
sse_payload = {"event": event_type, "data": serialized_data}
|
|
150
|
+
log.debug(
|
|
151
|
+
"%s Prepared SSE payload for Task ID %s: %s",
|
|
152
|
+
self.log_identifier,
|
|
153
|
+
task_id,
|
|
154
|
+
sse_payload,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
for connection_queue in list(self._connections.get(task_id, [])):
|
|
158
|
+
try:
|
|
159
|
+
await asyncio.wait_for(
|
|
160
|
+
connection_queue.put(sse_payload), timeout=0.1
|
|
161
|
+
)
|
|
162
|
+
log.debug(
|
|
163
|
+
"%s Queued event for Task ID: %s to one connection.",
|
|
164
|
+
self.log_identifier,
|
|
165
|
+
task_id,
|
|
166
|
+
)
|
|
167
|
+
except asyncio.QueueFull:
|
|
168
|
+
log.warning(
|
|
169
|
+
"%s SSE connection queue full for Task ID: %s. Event dropped for one connection.",
|
|
170
|
+
self.log_identifier,
|
|
171
|
+
task_id,
|
|
172
|
+
)
|
|
173
|
+
queues_to_remove.append(connection_queue)
|
|
174
|
+
except asyncio.TimeoutError:
|
|
175
|
+
log.warning(
|
|
176
|
+
"%s Timeout putting event onto SSE queue for Task ID: %s. Event dropped for one connection.",
|
|
177
|
+
self.log_identifier,
|
|
178
|
+
task_id,
|
|
179
|
+
)
|
|
180
|
+
queues_to_remove.append(connection_queue)
|
|
181
|
+
except Exception as e:
|
|
182
|
+
log.error(
|
|
183
|
+
"%s Error putting event onto queue for Task ID %s: %s",
|
|
184
|
+
self.log_identifier,
|
|
185
|
+
task_id,
|
|
186
|
+
e,
|
|
187
|
+
)
|
|
188
|
+
queues_to_remove.append(connection_queue)
|
|
189
|
+
|
|
190
|
+
if queues_to_remove and task_id in self._connections:
|
|
191
|
+
current_queues = self._connections[task_id]
|
|
192
|
+
for q in queues_to_remove:
|
|
193
|
+
try:
|
|
194
|
+
current_queues.remove(q)
|
|
195
|
+
log.warning(
|
|
196
|
+
"%s Removed potentially broken/full SSE queue for Task ID: %s",
|
|
197
|
+
self.log_identifier,
|
|
198
|
+
task_id,
|
|
199
|
+
)
|
|
200
|
+
except ValueError:
|
|
201
|
+
pass
|
|
202
|
+
|
|
203
|
+
if not current_queues:
|
|
204
|
+
del self._connections[task_id]
|
|
205
|
+
log.info(
|
|
206
|
+
"%s Removed Task ID entry: %s after cleaning queues.",
|
|
207
|
+
self.log_identifier,
|
|
208
|
+
task_id,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
async def close_connection(self, task_id: str, connection_queue: asyncio.Queue):
|
|
212
|
+
"""
|
|
213
|
+
Signals a specific SSE connection queue to close by putting None.
|
|
214
|
+
Also removes the queue from the manager.
|
|
215
|
+
"""
|
|
216
|
+
log.info(
|
|
217
|
+
"%s Closing specific SSE connection queue for Task ID: %s",
|
|
218
|
+
self.log_identifier,
|
|
219
|
+
task_id,
|
|
220
|
+
)
|
|
221
|
+
try:
|
|
222
|
+
await asyncio.wait_for(connection_queue.put(None), timeout=0.1)
|
|
223
|
+
except asyncio.QueueFull:
|
|
224
|
+
log.warning(
|
|
225
|
+
"%s Could not put None (close signal) on full queue for Task ID: %s. Connection might not close cleanly.",
|
|
226
|
+
self.log_identifier,
|
|
227
|
+
task_id,
|
|
228
|
+
)
|
|
229
|
+
except asyncio.TimeoutError:
|
|
230
|
+
log.warning(
|
|
231
|
+
"%s Timeout putting None (close signal) on queue for Task ID: %s.",
|
|
232
|
+
self.log_identifier,
|
|
233
|
+
task_id,
|
|
234
|
+
)
|
|
235
|
+
except Exception as e:
|
|
236
|
+
log.error(
|
|
237
|
+
"%s Error putting None (close signal) on queue for Task ID %s: %s",
|
|
238
|
+
self.log_identifier,
|
|
239
|
+
task_id,
|
|
240
|
+
e,
|
|
241
|
+
)
|
|
242
|
+
finally:
|
|
243
|
+
await self.remove_sse_connection(task_id, connection_queue)
|
|
244
|
+
|
|
245
|
+
async def close_all_for_task(self, task_id: str):
|
|
246
|
+
"""
|
|
247
|
+
Closes all SSE connections associated with a specific task.
|
|
248
|
+
"""
|
|
249
|
+
lock = self._get_lock()
|
|
250
|
+
async with lock:
|
|
251
|
+
if task_id in self._connections:
|
|
252
|
+
queues_to_close = self._connections.pop(task_id)
|
|
253
|
+
log.info(
|
|
254
|
+
"%s Closing %d SSE connections for Task ID: %s",
|
|
255
|
+
self.log_identifier,
|
|
256
|
+
len(queues_to_close),
|
|
257
|
+
task_id,
|
|
258
|
+
)
|
|
259
|
+
for q in queues_to_close:
|
|
260
|
+
try:
|
|
261
|
+
await asyncio.wait_for(q.put(None), timeout=0.1)
|
|
262
|
+
except asyncio.QueueFull:
|
|
263
|
+
log.warning(
|
|
264
|
+
"%s Could not put None (close signal) on full queue during close_all for Task ID: %s.",
|
|
265
|
+
self.log_identifier,
|
|
266
|
+
task_id,
|
|
267
|
+
)
|
|
268
|
+
except asyncio.TimeoutError:
|
|
269
|
+
log.warning(
|
|
270
|
+
"%s Timeout putting None (close signal) on queue during close_all for Task ID: %s.",
|
|
271
|
+
self.log_identifier,
|
|
272
|
+
task_id,
|
|
273
|
+
)
|
|
274
|
+
except Exception as e:
|
|
275
|
+
log.error(
|
|
276
|
+
"%s Error putting None (close signal) on queue during close_all for Task ID %s: %s",
|
|
277
|
+
self.log_identifier,
|
|
278
|
+
task_id,
|
|
279
|
+
e,
|
|
280
|
+
)
|
|
281
|
+
log.info(
|
|
282
|
+
"%s Removed Task ID entry: %s and signaled queues to close.",
|
|
283
|
+
self.log_identifier,
|
|
284
|
+
task_id,
|
|
285
|
+
)
|
|
286
|
+
else:
|
|
287
|
+
log.debug(
|
|
288
|
+
"%s No connections found to close for Task ID: %s",
|
|
289
|
+
self.log_identifier,
|
|
290
|
+
task_id,
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
def cleanup_old_locks(self):
|
|
294
|
+
"""Remove locks for closed event loops to prevent memory leaks."""
|
|
295
|
+
with self._locks_lock:
|
|
296
|
+
closed_loops = [loop for loop in self._locks if loop.is_closed()]
|
|
297
|
+
for loop in closed_loops:
|
|
298
|
+
del self._locks[loop]
|
|
299
|
+
log.debug(
|
|
300
|
+
"%s Cleaned up lock for closed event loop %s",
|
|
301
|
+
self.log_identifier,
|
|
302
|
+
id(loop),
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
async def close_all(self):
|
|
306
|
+
"""Closes all active SSE connections managed by this instance."""
|
|
307
|
+
self.cleanup_old_locks()
|
|
308
|
+
lock = self._get_lock()
|
|
309
|
+
async with lock:
|
|
310
|
+
log.info("%s Closing all active SSE connections...", self.log_identifier)
|
|
311
|
+
all_task_ids = list(self._connections.keys())
|
|
312
|
+
closed_count = 0
|
|
313
|
+
for task_id in all_task_ids:
|
|
314
|
+
if task_id in self._connections:
|
|
315
|
+
queues = self._connections.pop(task_id)
|
|
316
|
+
closed_count += len(queues)
|
|
317
|
+
for q in queues:
|
|
318
|
+
try:
|
|
319
|
+
await asyncio.wait_for(q.put(None), timeout=0.1)
|
|
320
|
+
except Exception:
|
|
321
|
+
pass
|
|
322
|
+
log.info(
|
|
323
|
+
"%s Closed %d connections for tasks: %s",
|
|
324
|
+
self.log_identifier,
|
|
325
|
+
closed_count,
|
|
326
|
+
all_task_ids,
|
|
327
|
+
)
|
|
328
|
+
self._connections.clear()
|