solace-agent-mesh 1.11.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.
- solace_agent_mesh/__init__.py +0 -0
- solace_agent_mesh/agent/__init__.py +0 -0
- solace_agent_mesh/agent/adk/__init__.py +0 -0
- solace_agent_mesh/agent/adk/adk_llm.txt +226 -0
- solace_agent_mesh/agent/adk/adk_llm_detail.txt +566 -0
- solace_agent_mesh/agent/adk/alembic/README +74 -0
- solace_agent_mesh/agent/adk/alembic/env.py +77 -0
- solace_agent_mesh/agent/adk/alembic/script.py.mako +28 -0
- solace_agent_mesh/agent/adk/alembic/versions/e2902798564d_adk_session_db_upgrade.py +52 -0
- solace_agent_mesh/agent/adk/alembic.ini +112 -0
- solace_agent_mesh/agent/adk/app_llm_agent.py +52 -0
- solace_agent_mesh/agent/adk/artifacts/__init__.py +1 -0
- solace_agent_mesh/agent/adk/artifacts/artifacts_llm.txt +171 -0
- solace_agent_mesh/agent/adk/artifacts/filesystem_artifact_service.py +545 -0
- solace_agent_mesh/agent/adk/artifacts/s3_artifact_service.py +609 -0
- solace_agent_mesh/agent/adk/callbacks.py +2318 -0
- solace_agent_mesh/agent/adk/embed_resolving_mcp_toolset.py +406 -0
- solace_agent_mesh/agent/adk/intelligent_mcp_callbacks.py +415 -0
- solace_agent_mesh/agent/adk/mcp_content_processor.py +666 -0
- solace_agent_mesh/agent/adk/models/lite_llm.py +1026 -0
- solace_agent_mesh/agent/adk/models/models_llm.txt +189 -0
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +132 -0
- solace_agent_mesh/agent/adk/runner.py +390 -0
- solace_agent_mesh/agent/adk/schema_migration.py +88 -0
- solace_agent_mesh/agent/adk/services.py +468 -0
- solace_agent_mesh/agent/adk/setup.py +1325 -0
- solace_agent_mesh/agent/adk/stream_parser.py +415 -0
- solace_agent_mesh/agent/adk/tool_wrapper.py +165 -0
- solace_agent_mesh/agent/agent_llm.txt +369 -0
- solace_agent_mesh/agent/agent_llm_detail.txt +1702 -0
- solace_agent_mesh/agent/protocol/__init__.py +0 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +2041 -0
- solace_agent_mesh/agent/protocol/protocol_llm.txt +81 -0
- solace_agent_mesh/agent/protocol/protocol_llm_detail.txt +92 -0
- solace_agent_mesh/agent/proxies/__init__.py +0 -0
- solace_agent_mesh/agent/proxies/a2a/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/a2a/a2a_llm.txt +190 -0
- solace_agent_mesh/agent/proxies/a2a/app.py +56 -0
- solace_agent_mesh/agent/proxies/a2a/component.py +1585 -0
- solace_agent_mesh/agent/proxies/a2a/config.py +216 -0
- solace_agent_mesh/agent/proxies/a2a/oauth_token_cache.py +104 -0
- solace_agent_mesh/agent/proxies/base/__init__.py +3 -0
- solace_agent_mesh/agent/proxies/base/app.py +100 -0
- solace_agent_mesh/agent/proxies/base/base_llm.txt +148 -0
- solace_agent_mesh/agent/proxies/base/component.py +816 -0
- solace_agent_mesh/agent/proxies/base/config.py +85 -0
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +19 -0
- solace_agent_mesh/agent/proxies/proxies_llm.txt +283 -0
- solace_agent_mesh/agent/sac/__init__.py +0 -0
- solace_agent_mesh/agent/sac/app.py +595 -0
- solace_agent_mesh/agent/sac/component.py +3668 -0
- solace_agent_mesh/agent/sac/patch_adk.py +103 -0
- solace_agent_mesh/agent/sac/sac_llm.txt +189 -0
- solace_agent_mesh/agent/sac/sac_llm_detail.txt +200 -0
- solace_agent_mesh/agent/sac/task_execution_context.py +415 -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 +58 -0
- solace_agent_mesh/agent/testing/testing_llm_detail.txt +68 -0
- solace_agent_mesh/agent/tools/__init__.py +16 -0
- solace_agent_mesh/agent/tools/audio_tools.py +1740 -0
- solace_agent_mesh/agent/tools/builtin_artifact_tools.py +2500 -0
- solace_agent_mesh/agent/tools/builtin_data_analysis_tools.py +244 -0
- solace_agent_mesh/agent/tools/dynamic_tool.py +396 -0
- solace_agent_mesh/agent/tools/general_agent_tools.py +572 -0
- solace_agent_mesh/agent/tools/image_tools.py +1185 -0
- solace_agent_mesh/agent/tools/peer_agent_tool.py +363 -0
- solace_agent_mesh/agent/tools/registry.py +38 -0
- solace_agent_mesh/agent/tools/test_tools.py +136 -0
- solace_agent_mesh/agent/tools/time_tools.py +126 -0
- solace_agent_mesh/agent/tools/tool_config_types.py +93 -0
- solace_agent_mesh/agent/tools/tool_definition.py +53 -0
- solace_agent_mesh/agent/tools/tools_llm.txt +276 -0
- solace_agent_mesh/agent/tools/tools_llm_detail.txt +275 -0
- solace_agent_mesh/agent/tools/web_tools.py +392 -0
- solace_agent_mesh/agent/utils/__init__.py +0 -0
- solace_agent_mesh/agent/utils/artifact_helpers.py +1353 -0
- solace_agent_mesh/agent/utils/config_parser.py +49 -0
- solace_agent_mesh/agent/utils/context_helpers.py +77 -0
- solace_agent_mesh/agent/utils/utils_llm.txt +152 -0
- solace_agent_mesh/agent/utils/utils_llm_detail.txt +149 -0
- solace_agent_mesh/assets/docs/404.html +16 -0
- solace_agent_mesh/assets/docs/assets/css/styles.8162edfb.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/sam-enterprise-credentials-b269f095349473118b2b33bdfcc40122.png +0 -0
- solace_agent_mesh/assets/docs/assets/js/032c2d61.f3d37824.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/05749d90.19ac4f35.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/0bcf40b7.c019ad46.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/1001.0182a8bd.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/15ba94aa.92fea363.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/15e40e79.434bb30f.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/17896441.e612dfb4.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2130.ab9fd314.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2131ec11.5c7a1f6e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2237.5e477fc6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/2279.550aa580.js.LICENSE.txt +13 -0
- solace_agent_mesh/assets/docs/assets/js/2334.1cf50a20.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/240a0364.9ad94d1b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2987107d.a80604f9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/2e32b5e0.33f5d75b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3219.adc1d663.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/341393d4.0fac2613.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3624.0eaa1fd0.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/3a6c6137.f5940cfa.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ac1795d.28b7c67b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/3ff0015d.2ddc75c0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/41adc471.48b12a4e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4250.95455b28.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/4356.d169ab5b.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/509e993c.a1fbf45a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5388.7a136447.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/547e15cc.2f7790c1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/55b7b518.29d6e75d.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/5c2bd65f.90a87880.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/5e95c892.558d5167.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6063ff4c.ef84f702.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/60702c0e.a8bdd79b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6143.0a1464c9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/631738c7.fa471607.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6395.e9c73649.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/64195356.c498c4d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/66d4869e.b77431fc.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/6a520c9d.b6e3f2ce.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6aaedf65.7253541d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.a5b36a60.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6d84eae0.fd23ba4a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6fdfefc7.99de744e.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/71da7b71.374b9d54.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/722f809d.965da774.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/7280.3fb73bdb.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/742f027b.46c07808.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.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/8024126c.fa0e7186.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/81a99df0.2484b8d9.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/82fbfb93.161823a5.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8356.8a379c04.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.5d015485.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/8591.5d015485.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.6c1dbf0c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8908.f9d1b506.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/8b032486.91a91afc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9157.b4093d07.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.975e428a.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9278.a4fd875d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/945fb41e.6f4cdffd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/94e8668d.16083b3f.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/9bb13469.b2333011.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a7bd4aaa.2204d2f7.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/a94703ab.3e5fbcb3.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ab9708a8.245ae0ef.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/aba21aa0.c42a534c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad71b5ed.af3ecfd1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ad87452a.9d73dad6.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c198a0dc.8f31f867.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/c93cbaa0.0e0d8baf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cab03b5b.6a073091.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/cbe2e9ea.07e170dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ceb2a7a6.5d92d7d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/da0b5bad.b62f7b08.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db5d6442.3daf1696.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd817ffc.c37a755e.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/dd81e2b8.b682e9c2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de5f4c65.e8241890.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.44a432bc.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e04b235d.52cb25ed.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e1b6eeb4.b1068f9b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e3d9abda.1476f570.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.4488e34c.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/e92d0134.3bda61dd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.250993bf.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.74710fc1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js +2 -0
- solace_agent_mesh/assets/docs/assets/js/main.7acf7ace.js.LICENSE.txt +81 -0
- solace_agent_mesh/assets/docs/assets/js/runtime~main.9e0813a2.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +154 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +99 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +90 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +107 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +166 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +101 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +219 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +92 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +29 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +110 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/projects/index.html +182 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/prompts/index.html +147 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +345 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/speech/index.html +52 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +83 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +84 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/kubernetes-deployment/index.html +47 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/logging/index.html +85 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +60 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/proxy_configuration/index.html +49 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +144 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +191 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +128 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +34 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +55 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +267 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +116 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +164 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +140 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +57 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +72 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +102 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/teams-integration/index.html +115 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/agent-builder/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/connectors/index.html +67 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +37 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +86 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/openapi-tools/index.html +324 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +247 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/secure-user-delegated-access/index.html +440 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +184 -0
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/wheel-installation/index.html +62 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +75 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +54 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +85 -0
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +41 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/artifact-storage/index.html +290 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +78 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +25 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +78 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +160 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +142 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/session-storage/index.html +251 -0
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/user-feedback/index.html +88 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +100 -0
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +52 -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/sam-enterprise-credentials.png +0 -0
- solace_agent_mesh/assets/docs/img/solace-logo-text.svg +18 -0
- solace_agent_mesh/assets/docs/img/solace-logo.png +0 -0
- solace_agent_mesh/assets/docs/lunr-index-1765810064709.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -0
- solace_agent_mesh/assets/docs/search-doc-1765810064709.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 -0
- solace_agent_mesh/cli/commands/__init__.py +0 -0
- 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 +729 -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 +102 -0
- solace_agent_mesh/cli/commands/add_cmd/web_add_gateway_step.py +114 -0
- solace_agent_mesh/cli/commands/docs_cmd.py +60 -0
- solace_agent_mesh/cli/commands/eval_cmd.py +46 -0
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +439 -0
- solace_agent_mesh/cli/commands/init_cmd/broker_step.py +201 -0
- solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
- solace_agent_mesh/cli/commands/init_cmd/directory_step.py +28 -0
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +238 -0
- solace_agent_mesh/cli/commands/init_cmd/init_cmd_llm.txt +365 -0
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +464 -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 +119 -0
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +215 -0
- solace_agent_mesh/cli/commands/plugin_cmd/__init__.py +20 -0
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +137 -0
- solace_agent_mesh/cli/commands/plugin_cmd/build_cmd.py +86 -0
- solace_agent_mesh/cli/commands/plugin_cmd/catalog_cmd.py +144 -0
- solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +306 -0
- solace_agent_mesh/cli/commands/plugin_cmd/install_cmd.py +283 -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 +215 -0
- solace_agent_mesh/cli/main.py +52 -0
- solace_agent_mesh/cli/utils.py +262 -0
- solace_agent_mesh/client/webui/frontend/static/assets/authCallback-Dj3JtK42.js +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/client-ZKk9kEJ5.js +25 -0
- solace_agent_mesh/client/webui/frontend/static/assets/favicon-BLgzUch9.ico +0 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-BcUaNZ-Q.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-vjch4RYc.js +435 -0
- solace_agent_mesh/client/webui/frontend/static/assets/vendor-BNV4kZN0.js +535 -0
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +15 -0
- solace_agent_mesh/client/webui/frontend/static/index.html +16 -0
- solace_agent_mesh/client/webui/frontend/static/mockServiceWorker.js +336 -0
- solace_agent_mesh/client/webui/frontend/static/ui-version.json +6 -0
- solace_agent_mesh/common/__init__.py +1 -0
- solace_agent_mesh/common/a2a/__init__.py +241 -0
- solace_agent_mesh/common/a2a/a2a_llm.txt +175 -0
- solace_agent_mesh/common/a2a/a2a_llm_detail.txt +193 -0
- solace_agent_mesh/common/a2a/artifact.py +368 -0
- solace_agent_mesh/common/a2a/events.py +213 -0
- solace_agent_mesh/common/a2a/message.py +375 -0
- solace_agent_mesh/common/a2a/protocol.py +689 -0
- solace_agent_mesh/common/a2a/task.py +127 -0
- solace_agent_mesh/common/a2a/translation.py +655 -0
- solace_agent_mesh/common/a2a/types.py +55 -0
- solace_agent_mesh/common/a2a_spec/a2a.json +2576 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm.txt +445 -0
- solace_agent_mesh/common/a2a_spec/a2a_spec_llm_detail.txt +736 -0
- solace_agent_mesh/common/a2a_spec/schemas/agent_progress_update.json +18 -0
- solace_agent_mesh/common/a2a_spec/schemas/artifact_creation_progress.json +48 -0
- solace_agent_mesh/common/a2a_spec/schemas/feedback_event.json +51 -0
- solace_agent_mesh/common/a2a_spec/schemas/llm_invocation.json +41 -0
- solace_agent_mesh/common/a2a_spec/schemas/schemas_llm.txt +330 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_invocation_start.json +26 -0
- solace_agent_mesh/common/a2a_spec/schemas/tool_result.json +48 -0
- solace_agent_mesh/common/agent_registry.py +122 -0
- solace_agent_mesh/common/common_llm.txt +230 -0
- solace_agent_mesh/common/common_llm_detail.txt +2562 -0
- solace_agent_mesh/common/constants.py +6 -0
- solace_agent_mesh/common/data_parts.py +150 -0
- solace_agent_mesh/common/exceptions.py +49 -0
- solace_agent_mesh/common/middleware/__init__.py +12 -0
- solace_agent_mesh/common/middleware/config_resolver.py +132 -0
- solace_agent_mesh/common/middleware/middleware_llm.txt +174 -0
- solace_agent_mesh/common/middleware/middleware_llm_detail.txt +185 -0
- solace_agent_mesh/common/middleware/registry.py +127 -0
- solace_agent_mesh/common/oauth/__init__.py +17 -0
- solace_agent_mesh/common/oauth/oauth_client.py +408 -0
- solace_agent_mesh/common/oauth/utils.py +50 -0
- solace_agent_mesh/common/sac/__init__.py +0 -0
- solace_agent_mesh/common/sac/sac_llm.txt +71 -0
- solace_agent_mesh/common/sac/sac_llm_detail.txt +82 -0
- solace_agent_mesh/common/sac/sam_component_base.py +730 -0
- solace_agent_mesh/common/sam_events/__init__.py +9 -0
- solace_agent_mesh/common/sam_events/event_service.py +208 -0
- solace_agent_mesh/common/sam_events/sam_events_llm.txt +104 -0
- solace_agent_mesh/common/sam_events/sam_events_llm_detail.txt +115 -0
- solace_agent_mesh/common/services/__init__.py +4 -0
- solace_agent_mesh/common/services/employee_service.py +164 -0
- solace_agent_mesh/common/services/identity_service.py +134 -0
- solace_agent_mesh/common/services/providers/__init__.py +4 -0
- solace_agent_mesh/common/services/providers/local_file_identity_service.py +151 -0
- solace_agent_mesh/common/services/providers/providers_llm.txt +81 -0
- solace_agent_mesh/common/services/services_llm.txt +368 -0
- solace_agent_mesh/common/services/services_llm_detail.txt +459 -0
- solace_agent_mesh/common/utils/__init__.py +7 -0
- solace_agent_mesh/common/utils/artifact_utils.py +31 -0
- solace_agent_mesh/common/utils/asyncio_macos_fix.py +88 -0
- solace_agent_mesh/common/utils/embeds/__init__.py +33 -0
- solace_agent_mesh/common/utils/embeds/constants.py +56 -0
- solace_agent_mesh/common/utils/embeds/converter.py +447 -0
- solace_agent_mesh/common/utils/embeds/embeds_llm.txt +220 -0
- solace_agent_mesh/common/utils/embeds/evaluators.py +395 -0
- solace_agent_mesh/common/utils/embeds/modifiers.py +793 -0
- solace_agent_mesh/common/utils/embeds/resolver.py +967 -0
- solace_agent_mesh/common/utils/embeds/types.py +23 -0
- solace_agent_mesh/common/utils/in_memory_cache.py +108 -0
- solace_agent_mesh/common/utils/initializer.py +52 -0
- solace_agent_mesh/common/utils/log_formatters.py +64 -0
- solace_agent_mesh/common/utils/message_utils.py +80 -0
- solace_agent_mesh/common/utils/mime_helpers.py +172 -0
- solace_agent_mesh/common/utils/push_notification_auth.py +135 -0
- solace_agent_mesh/common/utils/pydantic_utils.py +159 -0
- solace_agent_mesh/common/utils/rbac_utils.py +69 -0
- solace_agent_mesh/common/utils/templates/__init__.py +8 -0
- solace_agent_mesh/common/utils/templates/liquid_renderer.py +210 -0
- solace_agent_mesh/common/utils/templates/template_resolver.py +161 -0
- solace_agent_mesh/common/utils/type_utils.py +28 -0
- solace_agent_mesh/common/utils/utils_llm.txt +335 -0
- solace_agent_mesh/common/utils/utils_llm_detail.txt +572 -0
- solace_agent_mesh/config_portal/__init__.py +0 -0
- solace_agent_mesh/config_portal/backend/__init__.py +0 -0
- solace_agent_mesh/config_portal/backend/common.py +77 -0
- solace_agent_mesh/config_portal/backend/plugin_catalog/__init__.py +0 -0
- 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 +166 -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 +644 -0
- solace_agent_mesh/config_portal/frontend/static/client/Solace_community_logo.png +0 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-DiOiAjzL.js +103 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/components-Rk0n-9cK.js +140 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/entry.client-mvZjNKiz.js +19 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/index-DzNKzXrc.js +68 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/manifest-ba77705e.js +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-B17tZKK7.css +1 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/root-V2BeTIUc.js +10 -0
- solace_agent_mesh/config_portal/frontend/static/client/favicon.ico +0 -0
- solace_agent_mesh/config_portal/frontend/static/client/index.html +7 -0
- solace_agent_mesh/core_a2a/__init__.py +1 -0
- solace_agent_mesh/core_a2a/core_a2a_llm.txt +90 -0
- solace_agent_mesh/core_a2a/core_a2a_llm_detail.txt +101 -0
- solace_agent_mesh/core_a2a/service.py +307 -0
- solace_agent_mesh/evaluation/__init__.py +0 -0
- solace_agent_mesh/evaluation/evaluator.py +691 -0
- solace_agent_mesh/evaluation/message_organizer.py +553 -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 +970 -0
- solace_agent_mesh/evaluation/report_generator.py +607 -0
- solace_agent_mesh/evaluation/run.py +954 -0
- solace_agent_mesh/evaluation/shared/__init__.py +92 -0
- solace_agent_mesh/evaluation/shared/constants.py +47 -0
- solace_agent_mesh/evaluation/shared/exceptions.py +50 -0
- solace_agent_mesh/evaluation/shared/helpers.py +35 -0
- solace_agent_mesh/evaluation/shared/test_case_loader.py +167 -0
- solace_agent_mesh/evaluation/shared/test_suite_loader.py +280 -0
- solace_agent_mesh/evaluation/subscriber.py +776 -0
- solace_agent_mesh/evaluation/summary_builder.py +880 -0
- solace_agent_mesh/gateway/__init__.py +0 -0
- solace_agent_mesh/gateway/adapter/__init__.py +1 -0
- solace_agent_mesh/gateway/adapter/base.py +143 -0
- solace_agent_mesh/gateway/adapter/types.py +221 -0
- solace_agent_mesh/gateway/base/__init__.py +1 -0
- solace_agent_mesh/gateway/base/app.py +345 -0
- solace_agent_mesh/gateway/base/base_llm.txt +226 -0
- solace_agent_mesh/gateway/base/base_llm_detail.txt +235 -0
- solace_agent_mesh/gateway/base/component.py +2030 -0
- solace_agent_mesh/gateway/base/task_context.py +75 -0
- solace_agent_mesh/gateway/gateway_llm.txt +369 -0
- solace_agent_mesh/gateway/gateway_llm_detail.txt +3885 -0
- solace_agent_mesh/gateway/generic/__init__.py +1 -0
- solace_agent_mesh/gateway/generic/app.py +50 -0
- solace_agent_mesh/gateway/generic/component.py +727 -0
- solace_agent_mesh/gateway/http_sse/__init__.py +0 -0
- solace_agent_mesh/gateway/http_sse/alembic/alembic_llm.txt +345 -0
- solace_agent_mesh/gateway/http_sse/alembic/env.py +87 -0
- solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250910_d5b3f8f2e9a0_create_initial_database.py +58 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250911_b1c2d3e4f5g6_add_database_indexes.py +83 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20250916_f6e7d8c9b0a1_convert_timestamps_to_epoch_and_align_columns.py +412 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251006_98882922fa59_add_tasks_events_feedback_chat_tasks.py +190 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_project_users_table.py +72 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251023_add_soft_delete_and_search.py +109 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_default_agent_to_projects.py +26 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251024_add_projects_table.py +135 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251108_create_prompt_tables_with_sharing.py +154 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251115_add_parent_task_id.py +32 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251126_add_background_task_fields.py +47 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251202_add_versioned_fields_to_prompts.py +52 -0
- solace_agent_mesh/gateway/http_sse/alembic/versions/versions_llm.txt +161 -0
- solace_agent_mesh/gateway/http_sse/alembic.ini +109 -0
- solace_agent_mesh/gateway/http_sse/app.py +351 -0
- solace_agent_mesh/gateway/http_sse/component.py +2360 -0
- solace_agent_mesh/gateway/http_sse/components/__init__.py +7 -0
- solace_agent_mesh/gateway/http_sse/components/components_llm.txt +105 -0
- solace_agent_mesh/gateway/http_sse/components/task_logger_forwarder.py +109 -0
- solace_agent_mesh/gateway/http_sse/components/visualization_forwarder_component.py +110 -0
- solace_agent_mesh/gateway/http_sse/dependencies.py +653 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm.txt +299 -0
- solace_agent_mesh/gateway/http_sse/http_sse_llm_detail.txt +3278 -0
- solace_agent_mesh/gateway/http_sse/main.py +789 -0
- solace_agent_mesh/gateway/http_sse/repository/__init__.py +46 -0
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +102 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/__init__.py +11 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/chat_task.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/entities_llm.txt +221 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/feedback.py +20 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project.py +81 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/project_user.py +47 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session.py +66 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/session_history.py +0 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task.py +32 -0
- solace_agent_mesh/gateway/http_sse/repository/entities/task_event.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +125 -0
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +239 -0
- solace_agent_mesh/gateway/http_sse/repository/models/__init__.py +34 -0
- solace_agent_mesh/gateway/http_sse/repository/models/base.py +7 -0
- solace_agent_mesh/gateway/http_sse/repository/models/chat_task_model.py +31 -0
- solace_agent_mesh/gateway/http_sse/repository/models/feedback_model.py +21 -0
- solace_agent_mesh/gateway/http_sse/repository/models/models_llm.txt +257 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_model.py +51 -0
- solace_agent_mesh/gateway/http_sse/repository/models/project_user_model.py +75 -0
- solace_agent_mesh/gateway/http_sse/repository/models/prompt_model.py +159 -0
- solace_agent_mesh/gateway/http_sse/repository/models/session_model.py +53 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_event_model.py +25 -0
- solace_agent_mesh/gateway/http_sse/repository/models/task_model.py +39 -0
- solace_agent_mesh/gateway/http_sse/repository/project_repository.py +172 -0
- solace_agent_mesh/gateway/http_sse/repository/project_user_repository.py +186 -0
- solace_agent_mesh/gateway/http_sse/repository/repository_llm.txt +308 -0
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +268 -0
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +248 -0
- solace_agent_mesh/gateway/http_sse/routers/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +74 -0
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +1137 -0
- solace_agent_mesh/gateway/http_sse/routers/auth.py +311 -0
- solace_agent_mesh/gateway/http_sse/routers/config.py +371 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/__init__.py +10 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/dto_llm.txt +450 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/project_dto.py +69 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/prompt_dto.py +255 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/__init__.py +15 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/project_requests.py +48 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/requests_llm.txt +133 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/session_requests.py +33 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/requests/task_requests.py +58 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/__init__.py +18 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/base_responses.py +42 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/project_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/responses_llm.txt +123 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +33 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/task_responses.py +30 -0
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/version_responses.py +31 -0
- solace_agent_mesh/gateway/http_sse/routers/feedback.py +168 -0
- solace_agent_mesh/gateway/http_sse/routers/people.py +38 -0
- solace_agent_mesh/gateway/http_sse/routers/projects.py +767 -0
- solace_agent_mesh/gateway/http_sse/routers/prompts.py +1415 -0
- solace_agent_mesh/gateway/http_sse/routers/routers_llm.txt +312 -0
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +634 -0
- solace_agent_mesh/gateway/http_sse/routers/speech.py +355 -0
- solace_agent_mesh/gateway/http_sse/routers/sse.py +230 -0
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +1089 -0
- solace_agent_mesh/gateway/http_sse/routers/users.py +83 -0
- solace_agent_mesh/gateway/http_sse/routers/version.py +343 -0
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +1220 -0
- solace_agent_mesh/gateway/http_sse/services/__init__.py +4 -0
- solace_agent_mesh/gateway/http_sse/services/agent_card_service.py +71 -0
- solace_agent_mesh/gateway/http_sse/services/audio_service.py +1227 -0
- solace_agent_mesh/gateway/http_sse/services/background_task_monitor.py +186 -0
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +273 -0
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +250 -0
- solace_agent_mesh/gateway/http_sse/services/people_service.py +78 -0
- solace_agent_mesh/gateway/http_sse/services/project_service.py +930 -0
- solace_agent_mesh/gateway/http_sse/services/prompt_builder_assistant.py +303 -0
- solace_agent_mesh/gateway/http_sse/services/services_llm.txt +303 -0
- solace_agent_mesh/gateway/http_sse/services/session_service.py +702 -0
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +593 -0
- solace_agent_mesh/gateway/http_sse/services/task_service.py +119 -0
- solace_agent_mesh/gateway/http_sse/session_manager.py +219 -0
- solace_agent_mesh/gateway/http_sse/shared/__init__.py +146 -0
- solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
- solace_agent_mesh/gateway/http_sse/shared/base_repository.py +252 -0
- solace_agent_mesh/gateway/http_sse/shared/database_exceptions.py +274 -0
- solace_agent_mesh/gateway/http_sse/shared/database_helpers.py +43 -0
- solace_agent_mesh/gateway/http_sse/shared/enums.py +40 -0
- solace_agent_mesh/gateway/http_sse/shared/error_dto.py +107 -0
- solace_agent_mesh/gateway/http_sse/shared/exception_handlers.py +217 -0
- solace_agent_mesh/gateway/http_sse/shared/exceptions.py +192 -0
- solace_agent_mesh/gateway/http_sse/shared/pagination.py +138 -0
- solace_agent_mesh/gateway/http_sse/shared/response_utils.py +134 -0
- solace_agent_mesh/gateway/http_sse/shared/shared_llm.txt +319 -0
- solace_agent_mesh/gateway/http_sse/shared/timestamp_utils.py +97 -0
- solace_agent_mesh/gateway/http_sse/shared/types.py +50 -0
- solace_agent_mesh/gateway/http_sse/shared/utils.py +22 -0
- solace_agent_mesh/gateway/http_sse/sse_event_buffer.py +88 -0
- solace_agent_mesh/gateway/http_sse/sse_manager.py +491 -0
- solace_agent_mesh/gateway/http_sse/utils/__init__.py +1 -0
- solace_agent_mesh/gateway/http_sse/utils/artifact_copy_utils.py +370 -0
- solace_agent_mesh/gateway/http_sse/utils/stim_utils.py +72 -0
- solace_agent_mesh/gateway/http_sse/utils/utils_llm.txt +47 -0
- solace_agent_mesh/llm.txt +228 -0
- solace_agent_mesh/llm_detail.txt +2835 -0
- solace_agent_mesh/services/__init__.py +0 -0
- solace_agent_mesh/services/platform/__init__.py +18 -0
- solace_agent_mesh/services/platform/alembic/env.py +85 -0
- solace_agent_mesh/services/platform/alembic/script.py.mako +28 -0
- solace_agent_mesh/services/platform/alembic.ini +109 -0
- solace_agent_mesh/services/platform/api/__init__.py +3 -0
- solace_agent_mesh/services/platform/api/dependencies.py +147 -0
- solace_agent_mesh/services/platform/api/main.py +280 -0
- solace_agent_mesh/services/platform/api/middleware.py +51 -0
- solace_agent_mesh/services/platform/api/routers/__init__.py +24 -0
- solace_agent_mesh/services/platform/app.py +114 -0
- solace_agent_mesh/services/platform/component.py +235 -0
- solace_agent_mesh/solace_agent_mesh_llm.txt +362 -0
- solace_agent_mesh/solace_agent_mesh_llm_detail.txt +8599 -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 +75 -0
- solace_agent_mesh/templates/gateway_component_template.py +484 -0
- solace_agent_mesh/templates/gateway_config_template.yaml +38 -0
- solace_agent_mesh/templates/logging_config_template.yaml +48 -0
- solace_agent_mesh/templates/main_orchestrator.yaml +66 -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 +60 -0
- solace_agent_mesh/templates/plugin_pyproject_template.toml +32 -0
- solace_agent_mesh/templates/plugin_readme_template.md +12 -0
- solace_agent_mesh/templates/plugin_tool_config_template.yaml +109 -0
- solace_agent_mesh/templates/plugin_tools_template.py +224 -0
- solace_agent_mesh/templates/shared_config.yaml +112 -0
- solace_agent_mesh/templates/templates_llm.txt +147 -0
- solace_agent_mesh/templates/webui.yaml +177 -0
- solace_agent_mesh-1.11.2.dist-info/METADATA +504 -0
- solace_agent_mesh-1.11.2.dist-info/RECORD +624 -0
- solace_agent_mesh-1.11.2.dist-info/WHEEL +4 -0
- solace_agent_mesh-1.11.2.dist-info/entry_points.txt +3 -0
- solace_agent_mesh-1.11.2.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Refactored message subscriber with improved structure and readability.
|
|
3
|
+
This module handles Solace message subscription and processing for evaluation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from dotenv import load_dotenv
|
|
15
|
+
from solace.messaging.messaging_service import MessagingService
|
|
16
|
+
from solace.messaging.resources.topic_subscription import TopicSubscription
|
|
17
|
+
|
|
18
|
+
from .shared import (
|
|
19
|
+
ALLOWED_TOPIC_INFIXES,
|
|
20
|
+
BLOCKED_TOPIC_INFIXES,
|
|
21
|
+
MESSAGE_TIMEOUT,
|
|
22
|
+
BrokerConfig,
|
|
23
|
+
BrokerConnectionError,
|
|
24
|
+
ConfigurationError,
|
|
25
|
+
ConnectionState,
|
|
26
|
+
MessageProcessingError,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
log = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
# Load environment variables
|
|
32
|
+
load_dotenv()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class SubscriptionConfig:
|
|
37
|
+
"""Subscription configuration and topic filters."""
|
|
38
|
+
|
|
39
|
+
namespace: str
|
|
40
|
+
allowed_topic_infixes: list[str] = field(
|
|
41
|
+
default_factory=lambda: ALLOWED_TOPIC_INFIXES
|
|
42
|
+
)
|
|
43
|
+
blocked_topic_infixes: list[str] = field(
|
|
44
|
+
default_factory=lambda: BLOCKED_TOPIC_INFIXES
|
|
45
|
+
)
|
|
46
|
+
message_timeout: int = MESSAGE_TIMEOUT
|
|
47
|
+
filter_non_final_status: bool = True
|
|
48
|
+
remove_config_keys: bool = False
|
|
49
|
+
|
|
50
|
+
def __post_init__(self):
|
|
51
|
+
"""Validate subscription configuration."""
|
|
52
|
+
if not self.namespace or not self.namespace.strip():
|
|
53
|
+
raise ConfigurationError("Namespace cannot be empty")
|
|
54
|
+
|
|
55
|
+
if not self.allowed_topic_infixes:
|
|
56
|
+
raise ConfigurationError("At least one topic infix must be allowed")
|
|
57
|
+
|
|
58
|
+
if self.message_timeout <= 0:
|
|
59
|
+
raise ConfigurationError("Message timeout must be positive")
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def topic_pattern(self) -> str:
|
|
63
|
+
"""Get the topic subscription pattern."""
|
|
64
|
+
return f"{self.namespace}/a2a/v1/>"
|
|
65
|
+
|
|
66
|
+
def is_topic_allowed(self, topic: str) -> bool:
|
|
67
|
+
"""Check if a topic is allowed based on configured infixes."""
|
|
68
|
+
# return any(infix in topic for infix in self.allowed_topic_infixes)
|
|
69
|
+
return not any(infix in topic for infix in self.blocked_topic_infixes)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@dataclass
|
|
73
|
+
class ProcessedMessage:
|
|
74
|
+
"""Structured representation of a processed message."""
|
|
75
|
+
|
|
76
|
+
topic: str
|
|
77
|
+
payload: any
|
|
78
|
+
timestamp: float = field(default_factory=time.time)
|
|
79
|
+
message_type: str | None = None
|
|
80
|
+
|
|
81
|
+
def to_dict(self) -> dict[str, any]:
|
|
82
|
+
"""Convert to dictionary for JSON serialization."""
|
|
83
|
+
return {
|
|
84
|
+
"topic": self.topic,
|
|
85
|
+
"payload": self.payload,
|
|
86
|
+
"timestamp": self.timestamp,
|
|
87
|
+
"message_type": self.message_type,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass
|
|
92
|
+
class TaskCompletionEvent:
|
|
93
|
+
"""Represents a task completion event."""
|
|
94
|
+
|
|
95
|
+
task_id: str
|
|
96
|
+
topic: str
|
|
97
|
+
timestamp: float = field(default_factory=time.time)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MessageSanitizer:
|
|
101
|
+
"""Handles message sanitization and cleaning."""
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def remove_key_recursive(obj: any, key_to_remove: str) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Recursively remove a key from nested dictionaries and lists.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
obj: The object to process (dict, list, or other)
|
|
110
|
+
key_to_remove: The key to remove from dictionaries
|
|
111
|
+
"""
|
|
112
|
+
try:
|
|
113
|
+
if isinstance(obj, dict):
|
|
114
|
+
# Create a list of keys to avoid modifying dict during iteration
|
|
115
|
+
keys_to_process = list(obj.keys())
|
|
116
|
+
for key in keys_to_process:
|
|
117
|
+
if key == key_to_remove:
|
|
118
|
+
del obj[key]
|
|
119
|
+
else:
|
|
120
|
+
MessageSanitizer.remove_key_recursive(obj[key], key_to_remove)
|
|
121
|
+
elif isinstance(obj, list):
|
|
122
|
+
for item in obj:
|
|
123
|
+
MessageSanitizer.remove_key_recursive(item, key_to_remove)
|
|
124
|
+
except Exception as e:
|
|
125
|
+
log.warning(f"Error during key removal: {e}")
|
|
126
|
+
|
|
127
|
+
@staticmethod
|
|
128
|
+
def sanitize_message(payload: any, remove_config: bool = True) -> any:
|
|
129
|
+
"""
|
|
130
|
+
Sanitize message payload by removing unwanted keys.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
payload: The payload to sanitize
|
|
134
|
+
remove_config: Whether to remove 'config' keys
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
Sanitized payload
|
|
138
|
+
"""
|
|
139
|
+
if remove_config and isinstance(payload, (dict, list)):
|
|
140
|
+
# Work on a copy to avoid modifying the original
|
|
141
|
+
import copy
|
|
142
|
+
|
|
143
|
+
sanitized = copy.deepcopy(payload)
|
|
144
|
+
MessageSanitizer.remove_key_recursive(sanitized, "config")
|
|
145
|
+
return sanitized
|
|
146
|
+
return payload
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class MessageProcessor:
|
|
150
|
+
"""Processes and filters incoming messages."""
|
|
151
|
+
|
|
152
|
+
def __init__(self, config: SubscriptionConfig):
|
|
153
|
+
self.config = config
|
|
154
|
+
self.sanitizer = MessageSanitizer()
|
|
155
|
+
self.processed_count = 0
|
|
156
|
+
self.error_count = 0
|
|
157
|
+
|
|
158
|
+
def process_message(self, inbound_message) -> ProcessedMessage | None:
|
|
159
|
+
"""
|
|
160
|
+
Process an inbound message and return a ProcessedMessage if valid.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
inbound_message: The inbound Solace message
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
ProcessedMessage if the message should be kept, None otherwise
|
|
167
|
+
"""
|
|
168
|
+
try:
|
|
169
|
+
topic = inbound_message.get_destination_name()
|
|
170
|
+
|
|
171
|
+
# Check if topic is allowed
|
|
172
|
+
if not self.config.is_topic_allowed(topic):
|
|
173
|
+
return None
|
|
174
|
+
|
|
175
|
+
# Extract and parse payload
|
|
176
|
+
payload = self._extract_payload(inbound_message)
|
|
177
|
+
if payload is None:
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
# Filter status messages if configured
|
|
181
|
+
if self._should_filter_status_message(topic, payload):
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
# Sanitize payload
|
|
185
|
+
if self.config.remove_config_keys:
|
|
186
|
+
payload = self.sanitizer.sanitize_message(payload)
|
|
187
|
+
|
|
188
|
+
# Determine message type
|
|
189
|
+
message_type = self._determine_message_type(topic)
|
|
190
|
+
|
|
191
|
+
self.processed_count += 1
|
|
192
|
+
|
|
193
|
+
return ProcessedMessage(
|
|
194
|
+
topic=topic, payload=payload, message_type=message_type
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
except Exception as e:
|
|
198
|
+
self.error_count += 1
|
|
199
|
+
log.warning(f"Error processing message: {e}")
|
|
200
|
+
return None
|
|
201
|
+
|
|
202
|
+
def _extract_payload(self, inbound_message):
|
|
203
|
+
"""Extract and parse payload from inbound message."""
|
|
204
|
+
try:
|
|
205
|
+
payload_bytes = inbound_message.get_payload_as_bytes()
|
|
206
|
+
if not payload_bytes:
|
|
207
|
+
return None
|
|
208
|
+
|
|
209
|
+
payload_str = payload_bytes.decode("utf-8", errors="ignore")
|
|
210
|
+
|
|
211
|
+
# Try to parse as JSON
|
|
212
|
+
try:
|
|
213
|
+
return json.loads(payload_str)
|
|
214
|
+
except json.JSONDecodeError:
|
|
215
|
+
# Return as string if not valid JSON
|
|
216
|
+
return payload_str
|
|
217
|
+
|
|
218
|
+
except Exception as e:
|
|
219
|
+
log.warning(f"Error extracting payload: {e}")
|
|
220
|
+
return None
|
|
221
|
+
|
|
222
|
+
def _should_filter_status_message(self, topic: str, payload: any) -> bool:
|
|
223
|
+
"""Check if a status message should be filtered out."""
|
|
224
|
+
if not self.config.filter_non_final_status:
|
|
225
|
+
return False
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
# Filter only for llm_invocation
|
|
229
|
+
if self._find_part_type(payload, "llm_invocation"):
|
|
230
|
+
return True
|
|
231
|
+
|
|
232
|
+
# Filter only for llm_response
|
|
233
|
+
if self._find_part_type(payload, "llm_response"):
|
|
234
|
+
return True
|
|
235
|
+
|
|
236
|
+
# Filter out agent progress update messages
|
|
237
|
+
if self._find_part_type(payload, "agent_progress_update"):
|
|
238
|
+
return True
|
|
239
|
+
except Exception:
|
|
240
|
+
pass
|
|
241
|
+
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
def _find_part_type(self, data: any, type_to_find: str) -> bool:
|
|
245
|
+
"""Recursively search for a part with a specific type."""
|
|
246
|
+
if isinstance(data, dict):
|
|
247
|
+
if data.get("type") == type_to_find:
|
|
248
|
+
return True
|
|
249
|
+
for _key, value in data.items():
|
|
250
|
+
if self._find_part_type(value, type_to_find):
|
|
251
|
+
return True
|
|
252
|
+
elif isinstance(data, list):
|
|
253
|
+
for item in data:
|
|
254
|
+
if self._find_part_type(item, type_to_find):
|
|
255
|
+
return True
|
|
256
|
+
return False
|
|
257
|
+
|
|
258
|
+
def _determine_message_type(self, topic: str) -> str:
|
|
259
|
+
"""Determine the type of message based on topic."""
|
|
260
|
+
if "/agent/request/" in topic:
|
|
261
|
+
return "agent_request"
|
|
262
|
+
elif "/gateway/status/" in topic:
|
|
263
|
+
return "gateway_status"
|
|
264
|
+
elif "/gateway/response/" in topic:
|
|
265
|
+
return "gateway_response"
|
|
266
|
+
else:
|
|
267
|
+
return "unknown"
|
|
268
|
+
|
|
269
|
+
def get_stats(self) -> dict[str, int]:
|
|
270
|
+
"""Get processing statistics."""
|
|
271
|
+
return {
|
|
272
|
+
"processed_count": self.processed_count,
|
|
273
|
+
"error_count": self.error_count,
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class TaskTracker:
|
|
278
|
+
"""Tracks task completion and manages active tasks."""
|
|
279
|
+
|
|
280
|
+
def __init__(
|
|
281
|
+
self, active_tasks: set[str], wave_complete_event: threading.Event | None
|
|
282
|
+
):
|
|
283
|
+
self.active_tasks = active_tasks
|
|
284
|
+
self.wave_complete_event = wave_complete_event
|
|
285
|
+
self.completed_tasks: list[TaskCompletionEvent] = []
|
|
286
|
+
self._lock = threading.Lock()
|
|
287
|
+
|
|
288
|
+
def handle_task_completion(self, topic: str) -> TaskCompletionEvent | None:
|
|
289
|
+
"""
|
|
290
|
+
Handle task completion based on topic.
|
|
291
|
+
|
|
292
|
+
Args:
|
|
293
|
+
topic: The message topic
|
|
294
|
+
|
|
295
|
+
Returns:
|
|
296
|
+
TaskCompletionEvent if a task was completed, None otherwise
|
|
297
|
+
"""
|
|
298
|
+
if "response" not in topic:
|
|
299
|
+
return None
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
task_id = self._extract_task_id(topic)
|
|
303
|
+
if not task_id:
|
|
304
|
+
return None
|
|
305
|
+
|
|
306
|
+
with self._lock:
|
|
307
|
+
if task_id in self.active_tasks:
|
|
308
|
+
log.info(f"Task {task_id} completed")
|
|
309
|
+
self.active_tasks.remove(task_id)
|
|
310
|
+
|
|
311
|
+
completion_event = TaskCompletionEvent(task_id=task_id, topic=topic)
|
|
312
|
+
self.completed_tasks.append(completion_event)
|
|
313
|
+
|
|
314
|
+
# Check if all tasks are complete
|
|
315
|
+
if not self.active_tasks and self.wave_complete_event:
|
|
316
|
+
log.info("All tasks completed, setting wave complete event")
|
|
317
|
+
self.wave_complete_event.set()
|
|
318
|
+
|
|
319
|
+
return completion_event
|
|
320
|
+
|
|
321
|
+
except Exception as e:
|
|
322
|
+
log.error(f"Error handling task completion: {e}")
|
|
323
|
+
|
|
324
|
+
return None
|
|
325
|
+
|
|
326
|
+
def _extract_task_id(self, topic: str) -> str | None:
|
|
327
|
+
"""Extract task ID from topic."""
|
|
328
|
+
try:
|
|
329
|
+
return topic.split("/")[-1]
|
|
330
|
+
except (IndexError, AttributeError):
|
|
331
|
+
return None
|
|
332
|
+
|
|
333
|
+
def get_active_task_count(self) -> int:
|
|
334
|
+
"""Get the number of active tasks."""
|
|
335
|
+
with self._lock:
|
|
336
|
+
return len(self.active_tasks)
|
|
337
|
+
|
|
338
|
+
def get_completed_task_count(self) -> int:
|
|
339
|
+
"""Get the number of completed tasks."""
|
|
340
|
+
with self._lock:
|
|
341
|
+
return len(self.completed_tasks)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
class MessageStorage:
|
|
345
|
+
"""Handles message storage and file operations."""
|
|
346
|
+
|
|
347
|
+
def __init__(self, results_path: str | Path):
|
|
348
|
+
self.results_path = Path(results_path)
|
|
349
|
+
self.messages: list[ProcessedMessage] = []
|
|
350
|
+
self._lock = threading.Lock()
|
|
351
|
+
|
|
352
|
+
def add_message(self, message: ProcessedMessage) -> None:
|
|
353
|
+
"""Add a message to storage."""
|
|
354
|
+
with self._lock:
|
|
355
|
+
self.messages.append(message)
|
|
356
|
+
|
|
357
|
+
def get_message_count(self) -> int:
|
|
358
|
+
"""Get the number of stored messages."""
|
|
359
|
+
with self._lock:
|
|
360
|
+
return len(self.messages)
|
|
361
|
+
|
|
362
|
+
def save_messages(self, filename: str = "full_messages.json") -> str:
|
|
363
|
+
"""
|
|
364
|
+
Save all messages to a JSON file.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
filename: The filename to save to
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
The full path to the saved file
|
|
371
|
+
"""
|
|
372
|
+
output_file = self.results_path / filename
|
|
373
|
+
|
|
374
|
+
try:
|
|
375
|
+
# Ensure directory exists
|
|
376
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
377
|
+
|
|
378
|
+
with self._lock:
|
|
379
|
+
# Convert messages to dictionaries for JSON serialization
|
|
380
|
+
message_dicts = [msg.to_dict() for msg in self.messages]
|
|
381
|
+
|
|
382
|
+
with output_file.open("w") as f:
|
|
383
|
+
json.dump(message_dicts, f, indent=4)
|
|
384
|
+
|
|
385
|
+
log.info(f"Saved {len(message_dicts)} messages to {output_file}")
|
|
386
|
+
return str(output_file)
|
|
387
|
+
|
|
388
|
+
except Exception as e:
|
|
389
|
+
log.error(f"Error saving messages: {e}")
|
|
390
|
+
raise MessageProcessingError(f"Failed to save messages: {e}") from e
|
|
391
|
+
|
|
392
|
+
def clear_messages(self) -> None:
|
|
393
|
+
"""Clear all stored messages."""
|
|
394
|
+
with self._lock:
|
|
395
|
+
self.messages.clear()
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
class BrokerConnectionService:
|
|
399
|
+
"""Handles Solace broker connection and lifecycle."""
|
|
400
|
+
|
|
401
|
+
def __init__(self, config: BrokerConfig):
|
|
402
|
+
self.config = config
|
|
403
|
+
self.messaging_service: MessagingService | None = None
|
|
404
|
+
self.connection_state = ConnectionState.DISCONNECTED
|
|
405
|
+
self._connection_lock = threading.Lock()
|
|
406
|
+
|
|
407
|
+
def connect(self) -> None:
|
|
408
|
+
"""Connect to the Solace broker."""
|
|
409
|
+
with self._connection_lock:
|
|
410
|
+
if self.connection_state == ConnectionState.CONNECTED:
|
|
411
|
+
log.warning("Already connected to broker")
|
|
412
|
+
return
|
|
413
|
+
|
|
414
|
+
self.connection_state = ConnectionState.CONNECTING
|
|
415
|
+
|
|
416
|
+
try:
|
|
417
|
+
log.info("Connecting to Solace PubSub+ Broker...")
|
|
418
|
+
|
|
419
|
+
broker_props = self.config.to_solace_properties()
|
|
420
|
+
self.messaging_service = (
|
|
421
|
+
MessagingService.builder().from_properties(broker_props).build()
|
|
422
|
+
)
|
|
423
|
+
self.messaging_service.connect()
|
|
424
|
+
|
|
425
|
+
self.connection_state = ConnectionState.CONNECTED
|
|
426
|
+
log.info("Successfully connected to broker")
|
|
427
|
+
|
|
428
|
+
except Exception as e:
|
|
429
|
+
self.connection_state = ConnectionState.ERROR
|
|
430
|
+
log.error(f"Failed to connect to broker: {e}")
|
|
431
|
+
raise BrokerConnectionError(f"Connection failed: {e}") from e
|
|
432
|
+
|
|
433
|
+
def disconnect(self) -> None:
|
|
434
|
+
"""Disconnect from the Solace broker."""
|
|
435
|
+
with self._connection_lock:
|
|
436
|
+
if self.connection_state == ConnectionState.DISCONNECTED:
|
|
437
|
+
log.warning("Already disconnected from broker")
|
|
438
|
+
return
|
|
439
|
+
|
|
440
|
+
self.connection_state = ConnectionState.DISCONNECTING
|
|
441
|
+
|
|
442
|
+
try:
|
|
443
|
+
if self.messaging_service:
|
|
444
|
+
log.info("Disconnecting from broker...")
|
|
445
|
+
self.messaging_service.disconnect()
|
|
446
|
+
self.messaging_service = None
|
|
447
|
+
|
|
448
|
+
self.connection_state = ConnectionState.DISCONNECTED
|
|
449
|
+
log.info("Successfully disconnected from broker")
|
|
450
|
+
|
|
451
|
+
except Exception as e:
|
|
452
|
+
self.connection_state = ConnectionState.ERROR
|
|
453
|
+
log.error(f"Error during disconnect: {e}")
|
|
454
|
+
raise BrokerConnectionError(f"Disconnect failed: {e}") from e
|
|
455
|
+
|
|
456
|
+
def get_messaging_service(self) -> MessagingService | None:
|
|
457
|
+
"""Get the messaging service instance."""
|
|
458
|
+
return self.messaging_service
|
|
459
|
+
|
|
460
|
+
def is_connected(self) -> bool:
|
|
461
|
+
"""Check if currently connected to broker."""
|
|
462
|
+
return self.connection_state == ConnectionState.CONNECTED
|
|
463
|
+
|
|
464
|
+
def get_connection_state(self) -> ConnectionState:
|
|
465
|
+
"""Get the current connection state."""
|
|
466
|
+
return self.connection_state
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
class SubscriptionManager:
|
|
470
|
+
"""Manages topic subscriptions and message receiving."""
|
|
471
|
+
|
|
472
|
+
def __init__(
|
|
473
|
+
self, connection_service: BrokerConnectionService, config: SubscriptionConfig
|
|
474
|
+
):
|
|
475
|
+
self.connection_service = connection_service
|
|
476
|
+
self.config = config
|
|
477
|
+
self.message_receiver = None
|
|
478
|
+
self.subscription_active = False
|
|
479
|
+
self._receiver_lock = threading.Lock()
|
|
480
|
+
|
|
481
|
+
def start_subscription(
|
|
482
|
+
self, subscription_ready_event: threading.Event | None = None
|
|
483
|
+
) -> None:
|
|
484
|
+
"""Start message subscription."""
|
|
485
|
+
with self._receiver_lock:
|
|
486
|
+
if self.subscription_active:
|
|
487
|
+
log.warning("Subscription already active")
|
|
488
|
+
return
|
|
489
|
+
|
|
490
|
+
if not self.connection_service.is_connected():
|
|
491
|
+
raise BrokerConnectionError(
|
|
492
|
+
"Must be connected to broker before starting subscription"
|
|
493
|
+
)
|
|
494
|
+
|
|
495
|
+
try:
|
|
496
|
+
messaging_service = self.connection_service.get_messaging_service()
|
|
497
|
+
if not messaging_service:
|
|
498
|
+
raise BrokerConnectionError("No messaging service available")
|
|
499
|
+
|
|
500
|
+
# Create and start message receiver
|
|
501
|
+
self.message_receiver = (
|
|
502
|
+
messaging_service.create_direct_message_receiver_builder().build()
|
|
503
|
+
)
|
|
504
|
+
self.message_receiver.start()
|
|
505
|
+
|
|
506
|
+
# Add subscription
|
|
507
|
+
subscription = TopicSubscription.of(self.config.topic_pattern)
|
|
508
|
+
self.message_receiver.add_subscription(subscription)
|
|
509
|
+
|
|
510
|
+
self.subscription_active = True
|
|
511
|
+
log.info(f"Started subscription to: {self.config.topic_pattern}")
|
|
512
|
+
|
|
513
|
+
# Signal that subscription is ready
|
|
514
|
+
if subscription_ready_event:
|
|
515
|
+
subscription_ready_event.set()
|
|
516
|
+
|
|
517
|
+
except Exception as e:
|
|
518
|
+
log.error(f"Failed to start subscription: {e}")
|
|
519
|
+
raise BrokerConnectionError(f"Subscription failed: {e}") from e
|
|
520
|
+
|
|
521
|
+
def receive_message(self, timeout: int | None = None):
|
|
522
|
+
"""
|
|
523
|
+
Receive a message from the subscription.
|
|
524
|
+
|
|
525
|
+
Args:
|
|
526
|
+
timeout: Timeout in milliseconds, uses config default if None
|
|
527
|
+
|
|
528
|
+
Returns:
|
|
529
|
+
Received message or None if timeout
|
|
530
|
+
"""
|
|
531
|
+
if not self.subscription_active or not self.message_receiver:
|
|
532
|
+
return None
|
|
533
|
+
|
|
534
|
+
timeout_ms = timeout or self.config.message_timeout
|
|
535
|
+
|
|
536
|
+
try:
|
|
537
|
+
return self.message_receiver.receive_message(timeout=timeout_ms)
|
|
538
|
+
except Exception as e:
|
|
539
|
+
log.warning(f"Error receiving message: {e}")
|
|
540
|
+
return None
|
|
541
|
+
|
|
542
|
+
def stop_subscription(self) -> None:
|
|
543
|
+
"""Stop message subscription."""
|
|
544
|
+
with self._receiver_lock:
|
|
545
|
+
if not self.subscription_active:
|
|
546
|
+
return
|
|
547
|
+
|
|
548
|
+
try:
|
|
549
|
+
if self.message_receiver:
|
|
550
|
+
log.info("Stopping message receiver...")
|
|
551
|
+
self.message_receiver.terminate()
|
|
552
|
+
self.message_receiver = None
|
|
553
|
+
|
|
554
|
+
self.subscription_active = False
|
|
555
|
+
log.info("Subscription stopped")
|
|
556
|
+
|
|
557
|
+
except Exception as e:
|
|
558
|
+
log.error(f"Error stopping subscription: {e}")
|
|
559
|
+
|
|
560
|
+
def is_active(self) -> bool:
|
|
561
|
+
"""Check if subscription is active."""
|
|
562
|
+
return self.subscription_active
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
class Subscriber(threading.Thread):
|
|
566
|
+
"""
|
|
567
|
+
Main message subscriber class that orchestrates all components.
|
|
568
|
+
This is the refactored version of the original Subscriber class,
|
|
569
|
+
maintaining the same interface while providing better structure.
|
|
570
|
+
"""
|
|
571
|
+
|
|
572
|
+
def __init__(
|
|
573
|
+
self,
|
|
574
|
+
broker_config: BrokerConfig,
|
|
575
|
+
namespace: str,
|
|
576
|
+
active_tasks: set[str],
|
|
577
|
+
wave_complete_event: threading.Event | None,
|
|
578
|
+
subscription_ready_event: threading.Event | None,
|
|
579
|
+
results_path: str,
|
|
580
|
+
):
|
|
581
|
+
"""
|
|
582
|
+
Initialize the message subscriber.
|
|
583
|
+
Args:
|
|
584
|
+
broker_config: The broker configuration object
|
|
585
|
+
namespace: The namespace for topic subscription
|
|
586
|
+
active_tasks: Set of active task IDs to track
|
|
587
|
+
wave_complete_event: Event to set when all tasks complete
|
|
588
|
+
subscription_ready_event: Event to set when subscription is ready
|
|
589
|
+
results_path: Path to save results
|
|
590
|
+
"""
|
|
591
|
+
super().__init__(name="Subscriber")
|
|
592
|
+
|
|
593
|
+
# Initialize configuration
|
|
594
|
+
self.broker_config = broker_config
|
|
595
|
+
self.subscription_config = SubscriptionConfig(namespace=namespace)
|
|
596
|
+
|
|
597
|
+
# Initialize services
|
|
598
|
+
self.connection_service = BrokerConnectionService(self.broker_config)
|
|
599
|
+
self.subscription_manager = SubscriptionManager(
|
|
600
|
+
self.connection_service, self.subscription_config
|
|
601
|
+
)
|
|
602
|
+
self.message_processor = MessageProcessor(self.subscription_config)
|
|
603
|
+
self.task_tracker = TaskTracker(active_tasks, wave_complete_event)
|
|
604
|
+
self.message_storage = MessageStorage(results_path)
|
|
605
|
+
|
|
606
|
+
# Thread control
|
|
607
|
+
self._running = False
|
|
608
|
+
self._subscription_ready_event = subscription_ready_event
|
|
609
|
+
|
|
610
|
+
# Statistics
|
|
611
|
+
self.start_time = time.time()
|
|
612
|
+
self.messages_received = 0
|
|
613
|
+
self.messages_processed = 0
|
|
614
|
+
|
|
615
|
+
def run(self) -> None:
|
|
616
|
+
"""Main thread execution method."""
|
|
617
|
+
try:
|
|
618
|
+
self._running = True
|
|
619
|
+
log.info("Starting message subscriber...")
|
|
620
|
+
|
|
621
|
+
# Connect to broker
|
|
622
|
+
self.connection_service.connect()
|
|
623
|
+
|
|
624
|
+
# Start subscription
|
|
625
|
+
self.subscription_manager.start_subscription(self._subscription_ready_event)
|
|
626
|
+
|
|
627
|
+
# Main message processing loop
|
|
628
|
+
self._message_processing_loop()
|
|
629
|
+
|
|
630
|
+
except Exception as e:
|
|
631
|
+
log.error(f"Error in subscriber thread: {e}")
|
|
632
|
+
finally:
|
|
633
|
+
self._cleanup()
|
|
634
|
+
|
|
635
|
+
def _message_processing_loop(self) -> None:
|
|
636
|
+
"""Main message processing loop."""
|
|
637
|
+
log.info("Starting message processing loop...")
|
|
638
|
+
|
|
639
|
+
while self._running:
|
|
640
|
+
try:
|
|
641
|
+
# Receive message with timeout
|
|
642
|
+
inbound_message = self.subscription_manager.receive_message()
|
|
643
|
+
|
|
644
|
+
if inbound_message:
|
|
645
|
+
self.messages_received += 1
|
|
646
|
+
self._handle_inbound_message(inbound_message)
|
|
647
|
+
|
|
648
|
+
except Exception as e:
|
|
649
|
+
if self._running:
|
|
650
|
+
log.error(f"Error in message processing loop: {e}")
|
|
651
|
+
# Continue processing other messages
|
|
652
|
+
continue
|
|
653
|
+
|
|
654
|
+
def _handle_inbound_message(self, inbound_message) -> None:
|
|
655
|
+
"""Handle a single inbound message."""
|
|
656
|
+
try:
|
|
657
|
+
# Process the message
|
|
658
|
+
processed_message = self.message_processor.process_message(inbound_message)
|
|
659
|
+
|
|
660
|
+
if processed_message:
|
|
661
|
+
self.messages_processed += 1
|
|
662
|
+
|
|
663
|
+
# Store the message
|
|
664
|
+
self.message_storage.add_message(processed_message)
|
|
665
|
+
|
|
666
|
+
# Handle task completion if applicable
|
|
667
|
+
self.task_tracker.handle_task_completion(processed_message.topic)
|
|
668
|
+
|
|
669
|
+
except Exception as e:
|
|
670
|
+
log.warning(f"Error handling message: {e}")
|
|
671
|
+
|
|
672
|
+
def stop(self) -> None:
|
|
673
|
+
"""Stop the subscriber and clean up resources."""
|
|
674
|
+
log.info("Stopping message subscriber...")
|
|
675
|
+
self._running = False
|
|
676
|
+
|
|
677
|
+
def _cleanup(self) -> None:
|
|
678
|
+
"""Clean up all resources."""
|
|
679
|
+
try:
|
|
680
|
+
# Stop subscription
|
|
681
|
+
self.subscription_manager.stop_subscription()
|
|
682
|
+
|
|
683
|
+
# Disconnect from broker
|
|
684
|
+
self.connection_service.disconnect()
|
|
685
|
+
|
|
686
|
+
# Save messages
|
|
687
|
+
self.message_storage.save_messages()
|
|
688
|
+
|
|
689
|
+
# Log final statistics
|
|
690
|
+
self._log_final_statistics()
|
|
691
|
+
|
|
692
|
+
except Exception as e:
|
|
693
|
+
log.error(f"Error during cleanup: {e}")
|
|
694
|
+
|
|
695
|
+
def _log_final_statistics(self) -> None:
|
|
696
|
+
"""Log final processing statistics."""
|
|
697
|
+
runtime = time.time() - self.start_time
|
|
698
|
+
processor_stats = self.message_processor.get_stats()
|
|
699
|
+
|
|
700
|
+
log.info("=== SUBSCRIBER STATISTICS ===")
|
|
701
|
+
log.info(f"Runtime: {runtime:.2f} seconds")
|
|
702
|
+
log.info(f"Messages received: {self.messages_received}")
|
|
703
|
+
log.info(f"Messages processed: {self.messages_processed}")
|
|
704
|
+
log.info(f"Messages stored: {self.message_storage.get_message_count()}")
|
|
705
|
+
log.info(f"Processing errors: {processor_stats['error_count']}")
|
|
706
|
+
log.info(
|
|
707
|
+
f"Active tasks remaining: {self.task_tracker.get_active_task_count()}"
|
|
708
|
+
)
|
|
709
|
+
log.info(f"Tasks completed: {self.task_tracker.get_completed_task_count()}")
|
|
710
|
+
log.info("=============================")
|
|
711
|
+
|
|
712
|
+
# Backward compatibility properties
|
|
713
|
+
@property
|
|
714
|
+
def active_tasks(self) -> set[str]:
|
|
715
|
+
"""Get active tasks set for backward compatibility."""
|
|
716
|
+
return self.task_tracker.active_tasks
|
|
717
|
+
|
|
718
|
+
@property
|
|
719
|
+
def messages(self) -> list[dict[str, any]]:
|
|
720
|
+
"""Get messages list for backward compatibility."""
|
|
721
|
+
return [msg.to_dict() for msg in self.message_storage.messages]
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def main():
|
|
727
|
+
"""Main entry point for testing the subscriber."""
|
|
728
|
+
import signal
|
|
729
|
+
import sys
|
|
730
|
+
|
|
731
|
+
# Set up signal handling for graceful shutdown
|
|
732
|
+
def signal_handler(signum, frame):
|
|
733
|
+
log.info("\nShutting down subscriber...")
|
|
734
|
+
if "subscriber" in locals():
|
|
735
|
+
subscriber.stop()
|
|
736
|
+
subscriber.join()
|
|
737
|
+
sys.exit(0)
|
|
738
|
+
|
|
739
|
+
signal.signal(signal.SIGINT, signal_handler)
|
|
740
|
+
signal.signal(signal.SIGTERM, signal_handler)
|
|
741
|
+
|
|
742
|
+
# Create test subscriber
|
|
743
|
+
active_tasks = set()
|
|
744
|
+
subscription_ready = threading.Event()
|
|
745
|
+
|
|
746
|
+
try:
|
|
747
|
+
broker_config = BrokerConfig(
|
|
748
|
+
host=os.environ.get("SOLACE_BROKER_URL", ""),
|
|
749
|
+
vpn_name=os.environ.get("SOLACE_BROKER_VPN", ""),
|
|
750
|
+
username=os.environ.get("SOLACE_BROKER_USERNAME", ""),
|
|
751
|
+
password=os.environ.get("SOLACE_BROKER_PASSWORD", ""),
|
|
752
|
+
)
|
|
753
|
+
subscriber = Subscriber(
|
|
754
|
+
broker_config=broker_config,
|
|
755
|
+
namespace="test",
|
|
756
|
+
active_tasks=active_tasks,
|
|
757
|
+
subscription_ready_event=subscription_ready,
|
|
758
|
+
results_path=".",
|
|
759
|
+
)
|
|
760
|
+
|
|
761
|
+
subscriber.start()
|
|
762
|
+
|
|
763
|
+
# Wait for subscription to be ready
|
|
764
|
+
subscription_ready.wait(timeout=30)
|
|
765
|
+
log.info("Subscriber is ready and running...")
|
|
766
|
+
|
|
767
|
+
# Keep running until interrupted
|
|
768
|
+
subscriber.join()
|
|
769
|
+
|
|
770
|
+
except Exception as e:
|
|
771
|
+
log.error(f"Error running subscriber: {e}")
|
|
772
|
+
sys.exit(1)
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
if __name__ == "__main__":
|
|
776
|
+
main()
|