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,816 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Abstract base class for proxy components.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import concurrent.futures
|
|
9
|
+
import threading
|
|
10
|
+
import time
|
|
11
|
+
from abc import ABC, abstractmethod
|
|
12
|
+
from typing import Any, Dict, Optional, Tuple, TYPE_CHECKING
|
|
13
|
+
|
|
14
|
+
import httpx
|
|
15
|
+
|
|
16
|
+
from solace_ai_connector.common.event import Event, EventType
|
|
17
|
+
from solace_ai_connector.common.log import log
|
|
18
|
+
from solace_ai_connector.common.message import Message as SolaceMessage
|
|
19
|
+
from solace_ai_connector.components.component_base import ComponentBase
|
|
20
|
+
|
|
21
|
+
from ....common.agent_registry import AgentRegistry
|
|
22
|
+
from pydantic import TypeAdapter, ValidationError
|
|
23
|
+
|
|
24
|
+
from ....common import a2a
|
|
25
|
+
from ....common.a2a.message import get_file_parts_from_message, update_message_parts
|
|
26
|
+
from ....common.a2a.protocol import (
|
|
27
|
+
create_error_response,
|
|
28
|
+
create_success_response,
|
|
29
|
+
get_message_from_send_request,
|
|
30
|
+
get_request_id,
|
|
31
|
+
get_task_id_from_cancel_request,
|
|
32
|
+
)
|
|
33
|
+
from a2a.types import (
|
|
34
|
+
A2ARequest,
|
|
35
|
+
AgentCard,
|
|
36
|
+
AgentCapabilities,
|
|
37
|
+
AgentExtension,
|
|
38
|
+
CancelTaskRequest,
|
|
39
|
+
FilePart,
|
|
40
|
+
InternalError,
|
|
41
|
+
InvalidRequestError,
|
|
42
|
+
SendMessageRequest,
|
|
43
|
+
SendStreamingMessageRequest,
|
|
44
|
+
Task,
|
|
45
|
+
TaskArtifactUpdateEvent,
|
|
46
|
+
TaskStatusUpdateEvent,
|
|
47
|
+
)
|
|
48
|
+
from ...adk.services import initialize_artifact_service
|
|
49
|
+
|
|
50
|
+
if TYPE_CHECKING:
|
|
51
|
+
from google.adk.artifacts import BaseArtifactService
|
|
52
|
+
|
|
53
|
+
from .proxy_task_context import ProxyTaskContext
|
|
54
|
+
|
|
55
|
+
info = {
|
|
56
|
+
"class_name": "BaseProxyComponent",
|
|
57
|
+
"description": (
|
|
58
|
+
"Abstract base class for proxy components. Handles Solace interaction, "
|
|
59
|
+
"discovery, and task lifecycle management."
|
|
60
|
+
),
|
|
61
|
+
"config_parameters": [],
|
|
62
|
+
"input_schema": {},
|
|
63
|
+
"output_schema": {},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class BaseProxyComponent(ComponentBase, ABC):
|
|
68
|
+
"""
|
|
69
|
+
Abstract base class for proxy components.
|
|
70
|
+
|
|
71
|
+
Initializes shared services and manages the core lifecycle for proxying
|
|
72
|
+
requests between the Solace event mesh and a downstream agent protocol.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
def __init__(self, **kwargs: Any):
|
|
76
|
+
super().__init__(info, **kwargs)
|
|
77
|
+
self.namespace = self.get_config("namespace")
|
|
78
|
+
self.proxied_agents_config = self.get_config("proxied_agents", [])
|
|
79
|
+
self.artifact_service_config = self.get_config(
|
|
80
|
+
"artifact_service", {"type": "memory"}
|
|
81
|
+
)
|
|
82
|
+
self.discovery_interval_sec = self.get_config("discovery_interval_seconds", 60)
|
|
83
|
+
self.task_state_ttl_minutes = self.get_config("task_state_ttl_minutes", 60)
|
|
84
|
+
self.task_cleanup_interval_minutes = self.get_config(
|
|
85
|
+
"task_cleanup_interval_minutes", 10
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
self.agent_registry = AgentRegistry()
|
|
89
|
+
self.artifact_service: Optional[BaseArtifactService] = None
|
|
90
|
+
# Store (timestamp, ProxyTaskContext) tuples for TTL-based cleanup
|
|
91
|
+
self.active_tasks: Dict[str, Tuple[float, ProxyTaskContext]] = {}
|
|
92
|
+
self.active_tasks_lock = threading.Lock()
|
|
93
|
+
|
|
94
|
+
self._async_loop: Optional[asyncio.AbstractEventLoop] = None
|
|
95
|
+
self._async_thread: Optional[threading.Thread] = None
|
|
96
|
+
self._async_init_future: Optional[concurrent.futures.Future] = None
|
|
97
|
+
self._discovery_timer_id = f"proxy_discovery_{self.name}"
|
|
98
|
+
self._task_cleanup_timer_id = f"proxy_task_cleanup_{self.name}"
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
# Initialize synchronous services first
|
|
102
|
+
self.artifact_service = initialize_artifact_service(self)
|
|
103
|
+
log.info("%s Artifact service initialized.", self.log_identifier)
|
|
104
|
+
|
|
105
|
+
# Start the dedicated asyncio event loop
|
|
106
|
+
self._async_loop = asyncio.new_event_loop()
|
|
107
|
+
self._async_init_future = concurrent.futures.Future()
|
|
108
|
+
self._async_thread = threading.Thread(
|
|
109
|
+
target=self._start_async_loop, daemon=True
|
|
110
|
+
)
|
|
111
|
+
self._async_thread.start()
|
|
112
|
+
|
|
113
|
+
# Schedule async initialization and wait for it to complete
|
|
114
|
+
init_coro_future = asyncio.run_coroutine_threadsafe(
|
|
115
|
+
self._perform_async_init(), self._async_loop
|
|
116
|
+
)
|
|
117
|
+
init_coro_future.result(timeout=60)
|
|
118
|
+
self._async_init_future.result(timeout=1)
|
|
119
|
+
log.info("%s Async initialization completed.", self.log_identifier)
|
|
120
|
+
|
|
121
|
+
# Perform initial synchronous discovery to populate the registry
|
|
122
|
+
self._initial_discovery_sync()
|
|
123
|
+
|
|
124
|
+
except Exception as e:
|
|
125
|
+
log.exception("%s Initialization failed: %s", self.log_identifier, e)
|
|
126
|
+
self.cleanup()
|
|
127
|
+
raise
|
|
128
|
+
|
|
129
|
+
def invoke(self, message: SolaceMessage, data: dict) -> dict:
|
|
130
|
+
"""Placeholder invoke method. Primary logic resides in process_event."""
|
|
131
|
+
log.warning(
|
|
132
|
+
"%s 'invoke' method called, but primary logic resides in 'process_event'. This should not happen in normal operation.",
|
|
133
|
+
self.log_identifier,
|
|
134
|
+
)
|
|
135
|
+
return None
|
|
136
|
+
|
|
137
|
+
def process_event(self, event: Event):
|
|
138
|
+
"""Processes incoming events by routing them to the async loop."""
|
|
139
|
+
if not self._async_loop or not self._async_loop.is_running():
|
|
140
|
+
log.error(
|
|
141
|
+
"%s Async loop not available. Cannot process event: %s",
|
|
142
|
+
self.log_identifier,
|
|
143
|
+
event.event_type,
|
|
144
|
+
)
|
|
145
|
+
if event.event_type == EventType.MESSAGE:
|
|
146
|
+
event.data.call_negative_acknowledgements()
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
future = asyncio.run_coroutine_threadsafe(
|
|
150
|
+
self._process_event_async(event), self._async_loop
|
|
151
|
+
)
|
|
152
|
+
# Pass the event to the completion handler so it can NACK on failure
|
|
153
|
+
future.add_done_callback(
|
|
154
|
+
lambda f: self._handle_scheduled_task_completion(f, event)
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
async def _process_event_async(self, event: Event):
|
|
158
|
+
"""Asynchronous event processing logic."""
|
|
159
|
+
if event.event_type == EventType.MESSAGE:
|
|
160
|
+
message_handled = False
|
|
161
|
+
try:
|
|
162
|
+
await self._handle_a2a_request(event.data)
|
|
163
|
+
message_handled = True
|
|
164
|
+
finally:
|
|
165
|
+
# Mark that we attempted to handle the message
|
|
166
|
+
# (success/failure ack/nack is done inside _handle_a2a_request)
|
|
167
|
+
if not hasattr(event, "_proxy_message_handled"):
|
|
168
|
+
event._proxy_message_handled = message_handled
|
|
169
|
+
elif event.event_type == EventType.TIMER:
|
|
170
|
+
timer_id = event.data.get("timer_id")
|
|
171
|
+
if timer_id == self._discovery_timer_id:
|
|
172
|
+
await self._discover_and_publish_agents()
|
|
173
|
+
elif timer_id == self._task_cleanup_timer_id:
|
|
174
|
+
await self._cleanup_stale_tasks()
|
|
175
|
+
else:
|
|
176
|
+
log.debug(
|
|
177
|
+
"%s Ignoring unhandled event type: %s",
|
|
178
|
+
self.log_identifier,
|
|
179
|
+
event.event_type,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
async def _handle_a2a_request(self, message: SolaceMessage):
|
|
183
|
+
"""Handles an incoming A2A request message from Solace."""
|
|
184
|
+
jsonrpc_request_id = None
|
|
185
|
+
logical_task_id = None
|
|
186
|
+
try:
|
|
187
|
+
payload = message.get_payload()
|
|
188
|
+
if not isinstance(payload, dict):
|
|
189
|
+
raise ValueError("Payload is not a dictionary.")
|
|
190
|
+
|
|
191
|
+
# Directly validate the payload against the modern A2A spec
|
|
192
|
+
adapter = TypeAdapter(A2ARequest)
|
|
193
|
+
a2a_request = adapter.validate_python(payload)
|
|
194
|
+
|
|
195
|
+
jsonrpc_request_id = get_request_id(a2a_request)
|
|
196
|
+
|
|
197
|
+
# Get agent name from topic
|
|
198
|
+
topic = message.get_topic()
|
|
199
|
+
if not topic:
|
|
200
|
+
raise ValueError("Message has no topic.")
|
|
201
|
+
target_agent_name = topic.split("/")[-1]
|
|
202
|
+
|
|
203
|
+
if isinstance(
|
|
204
|
+
a2a_request.root, (SendMessageRequest, SendStreamingMessageRequest)
|
|
205
|
+
):
|
|
206
|
+
from .proxy_task_context import ProxyTaskContext
|
|
207
|
+
|
|
208
|
+
logical_task_id = jsonrpc_request_id
|
|
209
|
+
|
|
210
|
+
# Resolve inbound artifacts before forwarding
|
|
211
|
+
resolved_message = await self._resolve_inbound_artifacts(a2a_request)
|
|
212
|
+
a2a_request.root.params.message = resolved_message
|
|
213
|
+
|
|
214
|
+
a2a_context = {
|
|
215
|
+
"jsonrpc_request_id": jsonrpc_request_id,
|
|
216
|
+
"logical_task_id": logical_task_id,
|
|
217
|
+
"session_id": a2a.get_context_id(resolved_message),
|
|
218
|
+
"user_id": message.get_user_properties().get(
|
|
219
|
+
"userId", "default_user"
|
|
220
|
+
),
|
|
221
|
+
"status_topic": message.get_user_properties().get("a2aStatusTopic"),
|
|
222
|
+
"reply_to_topic": message.get_user_properties().get("replyTo"),
|
|
223
|
+
"is_streaming": isinstance(a2a_request.root, SendStreamingMessageRequest),
|
|
224
|
+
"user_properties": message.get_user_properties(),
|
|
225
|
+
}
|
|
226
|
+
task_context = ProxyTaskContext(
|
|
227
|
+
task_id=logical_task_id, a2a_context=a2a_context
|
|
228
|
+
)
|
|
229
|
+
with self.active_tasks_lock:
|
|
230
|
+
self.active_tasks[logical_task_id] = (time.time(), task_context)
|
|
231
|
+
|
|
232
|
+
log.info(
|
|
233
|
+
"%s Forwarding request for task %s to agent %s.",
|
|
234
|
+
self.log_identifier,
|
|
235
|
+
logical_task_id,
|
|
236
|
+
target_agent_name,
|
|
237
|
+
)
|
|
238
|
+
await self._forward_request(
|
|
239
|
+
task_context, a2a_request.root, target_agent_name
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
elif isinstance(a2a_request.root, CancelTaskRequest):
|
|
243
|
+
logical_task_id = get_task_id_from_cancel_request(a2a_request)
|
|
244
|
+
|
|
245
|
+
# Get the agent name from the topic (same as for send_message)
|
|
246
|
+
target_agent_name = topic.split("/")[-1]
|
|
247
|
+
|
|
248
|
+
with self.active_tasks_lock:
|
|
249
|
+
task_entry = self.active_tasks.get(logical_task_id)
|
|
250
|
+
task_context = task_entry[1] if task_entry else None
|
|
251
|
+
|
|
252
|
+
if task_context:
|
|
253
|
+
log.info(
|
|
254
|
+
"%s Forwarding cancellation request for task %s to agent %s.",
|
|
255
|
+
self.log_identifier,
|
|
256
|
+
logical_task_id,
|
|
257
|
+
target_agent_name,
|
|
258
|
+
)
|
|
259
|
+
# Forward the cancel request to the downstream agent
|
|
260
|
+
await self._forward_request(
|
|
261
|
+
task_context, a2a_request.root, target_agent_name
|
|
262
|
+
)
|
|
263
|
+
else:
|
|
264
|
+
# Task not found in active tasks
|
|
265
|
+
log.warning(
|
|
266
|
+
"%s Received cancel request for unknown task %s.",
|
|
267
|
+
self.log_identifier,
|
|
268
|
+
logical_task_id,
|
|
269
|
+
)
|
|
270
|
+
from a2a.types import TaskNotFoundError
|
|
271
|
+
error = TaskNotFoundError(data={"taskId": logical_task_id})
|
|
272
|
+
await self._publish_error_response(jsonrpc_request_id, error, message)
|
|
273
|
+
else:
|
|
274
|
+
log.warning(
|
|
275
|
+
"%s Received unhandled A2A request type: %s",
|
|
276
|
+
self.log_identifier,
|
|
277
|
+
type(a2a_request.root).__name__,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
message.call_acknowledgements()
|
|
281
|
+
|
|
282
|
+
except (ValueError, TypeError, ValidationError) as e:
|
|
283
|
+
log.error(
|
|
284
|
+
"%s Failed to parse or validate A2A request: %s",
|
|
285
|
+
self.log_identifier,
|
|
286
|
+
e,
|
|
287
|
+
)
|
|
288
|
+
error_data = {"taskId": logical_task_id} if logical_task_id else None
|
|
289
|
+
error = InvalidRequestError(message=str(e), data=error_data)
|
|
290
|
+
await self._publish_error_response(jsonrpc_request_id, error, message)
|
|
291
|
+
message.call_negative_acknowledgements()
|
|
292
|
+
except Exception as e:
|
|
293
|
+
log.exception(
|
|
294
|
+
"%s Unexpected error handling A2A request: %s",
|
|
295
|
+
self.log_identifier,
|
|
296
|
+
e,
|
|
297
|
+
)
|
|
298
|
+
error = InternalError(
|
|
299
|
+
message=f"Unexpected proxy error: {e}",
|
|
300
|
+
data={"taskId": logical_task_id},
|
|
301
|
+
)
|
|
302
|
+
await self._publish_error_response(jsonrpc_request_id, error, message)
|
|
303
|
+
message.call_negative_acknowledgements()
|
|
304
|
+
|
|
305
|
+
async def _resolve_inbound_artifacts(self, request: A2ARequest) -> a2a.Message:
|
|
306
|
+
"""
|
|
307
|
+
Resolves artifact URIs in an incoming message into byte content.
|
|
308
|
+
This is necessary before forwarding to a downstream agent that may not
|
|
309
|
+
share the same artifact store.
|
|
310
|
+
"""
|
|
311
|
+
original_message = get_message_from_send_request(request)
|
|
312
|
+
if not original_message:
|
|
313
|
+
return None
|
|
314
|
+
|
|
315
|
+
file_parts = get_file_parts_from_message(original_message)
|
|
316
|
+
if not file_parts:
|
|
317
|
+
return original_message # No files to resolve
|
|
318
|
+
|
|
319
|
+
log_id = f"{self.log_identifier}[ResolveInbound:{get_request_id(request)}]"
|
|
320
|
+
log.info("%s Found %d file parts to resolve.", log_id, len(file_parts))
|
|
321
|
+
|
|
322
|
+
resolved_parts = []
|
|
323
|
+
all_parts = a2a.get_parts_from_message(original_message)
|
|
324
|
+
|
|
325
|
+
for part in all_parts:
|
|
326
|
+
if isinstance(part, FilePart):
|
|
327
|
+
resolved_part = await a2a.resolve_file_part_uri(
|
|
328
|
+
part, self.artifact_service, log_id
|
|
329
|
+
)
|
|
330
|
+
resolved_parts.append(resolved_part)
|
|
331
|
+
else:
|
|
332
|
+
resolved_parts.append(part)
|
|
333
|
+
|
|
334
|
+
return update_message_parts(original_message, resolved_parts)
|
|
335
|
+
|
|
336
|
+
def _update_agent_card_for_proxy(self, agent_card: AgentCard, agent_alias: str) -> AgentCard:
|
|
337
|
+
"""
|
|
338
|
+
Updates an agent card for proxying by:
|
|
339
|
+
1. Setting the name to the proxy alias
|
|
340
|
+
2. Adding/updating the display-name extension to preserve the original name
|
|
341
|
+
|
|
342
|
+
Args:
|
|
343
|
+
agent_card: The original agent card fetched from the remote agent
|
|
344
|
+
agent_alias: The alias/name to use for this agent in SAM
|
|
345
|
+
|
|
346
|
+
Returns:
|
|
347
|
+
A modified copy of the agent card with updated name and display-name extension
|
|
348
|
+
"""
|
|
349
|
+
# Create a deep copy to avoid modifying the original
|
|
350
|
+
card_copy = agent_card.model_copy(deep=True)
|
|
351
|
+
|
|
352
|
+
# Store the original name as the display name (if not already set)
|
|
353
|
+
# This preserves the agent's identity while allowing it to be proxied under an alias
|
|
354
|
+
original_display_name = agent_card.name
|
|
355
|
+
|
|
356
|
+
# Check if there's already a display-name extension to preserve
|
|
357
|
+
display_name_uri = "https://solace.com/a2a/extensions/display-name"
|
|
358
|
+
if card_copy.capabilities and card_copy.capabilities.extensions:
|
|
359
|
+
for ext in card_copy.capabilities.extensions:
|
|
360
|
+
if ext.uri == display_name_uri and ext.params and ext.params.get("display_name"):
|
|
361
|
+
# Use the existing display name from the extension
|
|
362
|
+
original_display_name = ext.params["display_name"]
|
|
363
|
+
break
|
|
364
|
+
|
|
365
|
+
# Update the card's name to the proxy alias
|
|
366
|
+
card_copy.name = agent_alias
|
|
367
|
+
|
|
368
|
+
# Ensure capabilities and extensions exist
|
|
369
|
+
if not card_copy.capabilities:
|
|
370
|
+
card_copy.capabilities = AgentCapabilities(extensions=[])
|
|
371
|
+
if not card_copy.capabilities.extensions:
|
|
372
|
+
card_copy.capabilities.extensions = []
|
|
373
|
+
|
|
374
|
+
# Find or create the display-name extension
|
|
375
|
+
display_name_ext = None
|
|
376
|
+
for ext in card_copy.capabilities.extensions:
|
|
377
|
+
if ext.uri == display_name_uri:
|
|
378
|
+
display_name_ext = ext
|
|
379
|
+
break
|
|
380
|
+
|
|
381
|
+
if display_name_ext:
|
|
382
|
+
# Update existing extension
|
|
383
|
+
if not display_name_ext.params:
|
|
384
|
+
display_name_ext.params = {}
|
|
385
|
+
display_name_ext.params["display_name"] = original_display_name
|
|
386
|
+
else:
|
|
387
|
+
# Create new extension
|
|
388
|
+
new_ext = AgentExtension(
|
|
389
|
+
uri=display_name_uri,
|
|
390
|
+
params={"display_name": original_display_name}
|
|
391
|
+
)
|
|
392
|
+
card_copy.capabilities.extensions.append(new_ext)
|
|
393
|
+
|
|
394
|
+
log.debug(
|
|
395
|
+
"%s Updated agent card: name='%s', display_name='%s'",
|
|
396
|
+
self.log_identifier,
|
|
397
|
+
agent_alias,
|
|
398
|
+
original_display_name
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
return card_copy
|
|
402
|
+
|
|
403
|
+
def _initial_discovery_sync(self):
|
|
404
|
+
"""
|
|
405
|
+
Synchronously fetches agent cards to populate the registry at startup.
|
|
406
|
+
This method does NOT publish the cards to the mesh.
|
|
407
|
+
"""
|
|
408
|
+
log.info(
|
|
409
|
+
"%s Performing initial synchronous agent discovery...", self.log_identifier
|
|
410
|
+
)
|
|
411
|
+
with httpx.Client() as client:
|
|
412
|
+
for agent_config in self.proxied_agents_config:
|
|
413
|
+
agent_alias = agent_config["name"]
|
|
414
|
+
agent_url = agent_config.get("url")
|
|
415
|
+
if not agent_url:
|
|
416
|
+
log.error(
|
|
417
|
+
"%s Skipping agent '%s' in initial discovery: no URL configured.",
|
|
418
|
+
self.log_identifier,
|
|
419
|
+
agent_alias,
|
|
420
|
+
)
|
|
421
|
+
continue
|
|
422
|
+
try:
|
|
423
|
+
# Use a synchronous client for this initial blocking call
|
|
424
|
+
response = client.get(f"{agent_url}/.well-known/agent-card.json")
|
|
425
|
+
response.raise_for_status()
|
|
426
|
+
agent_card = AgentCard.model_validate(response.json())
|
|
427
|
+
|
|
428
|
+
# Update the card for proxying (preserves display name)
|
|
429
|
+
card_for_proxy = self._update_agent_card_for_proxy(agent_card, agent_alias)
|
|
430
|
+
self.agent_registry.add_or_update_agent(card_for_proxy)
|
|
431
|
+
log.info(
|
|
432
|
+
"%s Initial discovery successful for alias '%s' (actual name: '%s').",
|
|
433
|
+
self.log_identifier,
|
|
434
|
+
agent_alias,
|
|
435
|
+
agent_card.name,
|
|
436
|
+
)
|
|
437
|
+
except Exception as e:
|
|
438
|
+
log.error(
|
|
439
|
+
"%s Failed initial discovery for agent '%s' at URL '%s': %s",
|
|
440
|
+
self.log_identifier,
|
|
441
|
+
agent_alias,
|
|
442
|
+
agent_url,
|
|
443
|
+
e,
|
|
444
|
+
)
|
|
445
|
+
log.info("%s Initial synchronous discovery complete.", self.log_identifier)
|
|
446
|
+
|
|
447
|
+
async def _discover_and_publish_agents(self):
|
|
448
|
+
"""
|
|
449
|
+
Asynchronously fetches agent cards, updates the registry, and publishes them.
|
|
450
|
+
This is intended for the recurring timer.
|
|
451
|
+
"""
|
|
452
|
+
log.info("%s Starting recurring agent discovery cycle...", self.log_identifier)
|
|
453
|
+
for agent_config in self.proxied_agents_config:
|
|
454
|
+
try:
|
|
455
|
+
modern_card = await self._fetch_agent_card(agent_config)
|
|
456
|
+
if not modern_card:
|
|
457
|
+
continue
|
|
458
|
+
|
|
459
|
+
agent_alias = agent_config["name"]
|
|
460
|
+
# Update the card for proxying (preserves display name)
|
|
461
|
+
card_for_registry = self._update_agent_card_for_proxy(modern_card, agent_alias)
|
|
462
|
+
self.agent_registry.add_or_update_agent(card_for_registry)
|
|
463
|
+
|
|
464
|
+
# Create a separate copy for publishing
|
|
465
|
+
card_to_publish = card_for_registry.model_copy(deep=True)
|
|
466
|
+
card_to_publish.url = (
|
|
467
|
+
f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
|
|
468
|
+
)
|
|
469
|
+
discovery_topic = a2a.get_discovery_topic(self.namespace)
|
|
470
|
+
self._publish_a2a_message(
|
|
471
|
+
card_to_publish.model_dump(exclude_none=True), discovery_topic
|
|
472
|
+
)
|
|
473
|
+
log.info(
|
|
474
|
+
"%s Refreshed and published card for agent '%s'.",
|
|
475
|
+
self.log_identifier,
|
|
476
|
+
agent_alias,
|
|
477
|
+
)
|
|
478
|
+
except Exception as e:
|
|
479
|
+
log.error(
|
|
480
|
+
"%s Failed to discover or publish card for agent '%s' in recurring cycle: %s",
|
|
481
|
+
self.log_identifier,
|
|
482
|
+
agent_config.get("name", "unknown"),
|
|
483
|
+
e,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
async def _publish_status_update(
|
|
487
|
+
self, event: TaskStatusUpdateEvent, a2a_context: Dict
|
|
488
|
+
):
|
|
489
|
+
"""Publishes a TaskStatusUpdateEvent to the appropriate Solace topic."""
|
|
490
|
+
target_topic = a2a_context.get("status_topic")
|
|
491
|
+
if not target_topic:
|
|
492
|
+
log.warning(
|
|
493
|
+
"%s No statusTopic in context for task %s. Cannot publish status update.",
|
|
494
|
+
self.log_identifier,
|
|
495
|
+
event.task_id,
|
|
496
|
+
)
|
|
497
|
+
return
|
|
498
|
+
|
|
499
|
+
response = create_success_response(
|
|
500
|
+
result=event, request_id=a2a_context.get("jsonrpc_request_id")
|
|
501
|
+
)
|
|
502
|
+
self._publish_a2a_message(
|
|
503
|
+
response.model_dump(exclude_none=True),
|
|
504
|
+
target_topic,
|
|
505
|
+
user_properties=a2a_context.get("user_properties")
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
async def _publish_task_response(self, task: Task, a2a_context: Dict):
|
|
509
|
+
"""Publishes a Task object to the reply topic."""
|
|
510
|
+
target_topic = a2a_context.get("reply_to_topic")
|
|
511
|
+
if not target_topic:
|
|
512
|
+
log.warning(
|
|
513
|
+
"%s No replyToTopic in context for task %s. Cannot publish final response.",
|
|
514
|
+
self.log_identifier,
|
|
515
|
+
task.id,
|
|
516
|
+
)
|
|
517
|
+
return
|
|
518
|
+
|
|
519
|
+
response = create_success_response(
|
|
520
|
+
result=task, request_id=a2a_context.get("jsonrpc_request_id")
|
|
521
|
+
)
|
|
522
|
+
self._publish_a2a_message(
|
|
523
|
+
response.model_dump(exclude_none=True),
|
|
524
|
+
target_topic,
|
|
525
|
+
user_properties=a2a_context.get("user_properties")
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
async def _publish_artifact_update(
|
|
529
|
+
self, event: TaskArtifactUpdateEvent, a2a_context: Dict
|
|
530
|
+
):
|
|
531
|
+
"""Publishes a TaskArtifactUpdateEvent to the appropriate Solace topic."""
|
|
532
|
+
target_topic = a2a_context.get("status_topic")
|
|
533
|
+
if not target_topic:
|
|
534
|
+
log.warning(
|
|
535
|
+
"%s No statusTopic in context for task %s. Cannot publish artifact update.",
|
|
536
|
+
self.log_identifier,
|
|
537
|
+
event.task_id,
|
|
538
|
+
)
|
|
539
|
+
return
|
|
540
|
+
|
|
541
|
+
response = create_success_response(
|
|
542
|
+
result=event, request_id=a2a_context.get("jsonrpc_request_id")
|
|
543
|
+
)
|
|
544
|
+
self._publish_a2a_message(
|
|
545
|
+
response.model_dump(exclude_none=True),
|
|
546
|
+
target_topic,
|
|
547
|
+
user_properties=a2a_context.get("user_properties")
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
async def _publish_error_response(
|
|
551
|
+
self,
|
|
552
|
+
request_id: str,
|
|
553
|
+
error: InternalError | InvalidRequestError,
|
|
554
|
+
message: SolaceMessage,
|
|
555
|
+
):
|
|
556
|
+
"""Publishes a JSON-RPC error response."""
|
|
557
|
+
target_topic = message.get_user_properties().get("replyTo")
|
|
558
|
+
if not target_topic:
|
|
559
|
+
log.warning(
|
|
560
|
+
"%s No replyToTopic in message. Cannot publish error response.",
|
|
561
|
+
self.log_identifier,
|
|
562
|
+
)
|
|
563
|
+
return
|
|
564
|
+
|
|
565
|
+
response = create_error_response(error=error, request_id=request_id)
|
|
566
|
+
self._publish_a2a_message(response.model_dump(exclude_none=True), target_topic)
|
|
567
|
+
|
|
568
|
+
def _publish_a2a_message(
|
|
569
|
+
self, payload: Dict, topic: str, user_properties: Optional[Dict] = None
|
|
570
|
+
):
|
|
571
|
+
"""Helper to publish A2A messages via the SAC App."""
|
|
572
|
+
app = self.get_app()
|
|
573
|
+
if app:
|
|
574
|
+
app.send_message(
|
|
575
|
+
payload=payload, topic=topic, user_properties=user_properties
|
|
576
|
+
)
|
|
577
|
+
else:
|
|
578
|
+
log.error(
|
|
579
|
+
"%s Cannot publish message: Not running within a SAC App context.",
|
|
580
|
+
self.log_identifier,
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
def _start_async_loop(self):
|
|
584
|
+
"""Target method for the dedicated async thread."""
|
|
585
|
+
log.info("%s Dedicated async thread started.", self.log_identifier)
|
|
586
|
+
try:
|
|
587
|
+
asyncio.set_event_loop(self._async_loop)
|
|
588
|
+
self._async_loop.run_forever()
|
|
589
|
+
except Exception as e:
|
|
590
|
+
log.exception(
|
|
591
|
+
"%s Exception in dedicated async thread loop: %s",
|
|
592
|
+
self.log_identifier,
|
|
593
|
+
e,
|
|
594
|
+
)
|
|
595
|
+
if self._async_init_future and not self._async_init_future.done():
|
|
596
|
+
self._async_init_future.set_exception(e)
|
|
597
|
+
finally:
|
|
598
|
+
log.info("%s Dedicated async thread loop finishing.", self.log_identifier)
|
|
599
|
+
if self._async_loop.is_running():
|
|
600
|
+
self._async_loop.call_soon_threadsafe(self._async_loop.stop)
|
|
601
|
+
|
|
602
|
+
async def _perform_async_init(self):
|
|
603
|
+
"""Coroutine to perform async initialization."""
|
|
604
|
+
try:
|
|
605
|
+
log.info("%s Performing async initialization...", self.log_identifier)
|
|
606
|
+
# Placeholder for any future async init steps
|
|
607
|
+
if self._async_init_future and not self._async_init_future.done():
|
|
608
|
+
self._async_loop.call_soon_threadsafe(
|
|
609
|
+
self._async_init_future.set_result, True
|
|
610
|
+
)
|
|
611
|
+
except Exception as e:
|
|
612
|
+
if self._async_init_future and not self._async_init_future.done():
|
|
613
|
+
self._async_loop.call_soon_threadsafe(
|
|
614
|
+
self._async_init_future.set_exception, e
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
def _handle_scheduled_task_completion(
|
|
618
|
+
self, future: concurrent.futures.Future, event: Event
|
|
619
|
+
):
|
|
620
|
+
"""Callback to log exceptions from tasks scheduled on the async loop and NACK messages on failure."""
|
|
621
|
+
if future.done() and future.exception():
|
|
622
|
+
log.error(
|
|
623
|
+
"%s Coroutine scheduled on async loop failed: %s",
|
|
624
|
+
self.log_identifier,
|
|
625
|
+
future.exception(),
|
|
626
|
+
exc_info=future.exception(),
|
|
627
|
+
)
|
|
628
|
+
# NACK the message if this was a MESSAGE event that failed before being handled
|
|
629
|
+
# The _proxy_message_handled flag is set in _process_event_async to track
|
|
630
|
+
# whether _handle_a2a_request was entered (where ack/nack is normally done)
|
|
631
|
+
if event.event_type == EventType.MESSAGE:
|
|
632
|
+
message_handled = getattr(event, "_proxy_message_handled", False)
|
|
633
|
+
if not message_handled:
|
|
634
|
+
try:
|
|
635
|
+
event.data.call_negative_acknowledgements()
|
|
636
|
+
log.warning(
|
|
637
|
+
"%s NACKed message due to async processing failure before entering request handler.",
|
|
638
|
+
self.log_identifier,
|
|
639
|
+
)
|
|
640
|
+
except Exception as nack_e:
|
|
641
|
+
log.error(
|
|
642
|
+
"%s Failed to NACK message after async processing failure: %s",
|
|
643
|
+
self.log_identifier,
|
|
644
|
+
nack_e,
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
async def _cleanup_stale_tasks(self):
|
|
648
|
+
"""
|
|
649
|
+
Removes task state older than configured TTL.
|
|
650
|
+
This prevents memory leaks from tasks that complete without sending terminal events
|
|
651
|
+
(e.g., due to agent crashes or network failures).
|
|
652
|
+
"""
|
|
653
|
+
ttl_seconds = self.task_state_ttl_minutes * 60
|
|
654
|
+
cutoff_time = time.time() - ttl_seconds
|
|
655
|
+
|
|
656
|
+
with self.active_tasks_lock:
|
|
657
|
+
stale_task_ids = [
|
|
658
|
+
task_id
|
|
659
|
+
for task_id, (timestamp, _) in self.active_tasks.items()
|
|
660
|
+
if timestamp < cutoff_time
|
|
661
|
+
]
|
|
662
|
+
for task_id in stale_task_ids:
|
|
663
|
+
del self.active_tasks[task_id]
|
|
664
|
+
log.warning(
|
|
665
|
+
"%s Cleaned up stale task %s (exceeded TTL of %d minutes)",
|
|
666
|
+
self.log_identifier,
|
|
667
|
+
task_id,
|
|
668
|
+
self.task_state_ttl_minutes,
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
if stale_task_ids:
|
|
672
|
+
log.info(
|
|
673
|
+
"%s Stale task cleanup removed %d tasks",
|
|
674
|
+
self.log_identifier,
|
|
675
|
+
len(stale_task_ids),
|
|
676
|
+
)
|
|
677
|
+
|
|
678
|
+
def _cleanup_task_state(self, task_id: str) -> None:
|
|
679
|
+
"""
|
|
680
|
+
Cleans up state for a completed task.
|
|
681
|
+
Called when a terminal event is detected (Task with terminal state,
|
|
682
|
+
or TaskStatusUpdateEvent with final=true).
|
|
683
|
+
|
|
684
|
+
Args:
|
|
685
|
+
task_id: The ID of the task to clean up
|
|
686
|
+
"""
|
|
687
|
+
with self.active_tasks_lock:
|
|
688
|
+
entry = self.active_tasks.pop(task_id, None)
|
|
689
|
+
if entry:
|
|
690
|
+
log.info(
|
|
691
|
+
"%s Removed task %s from active_tasks (terminal event detected)",
|
|
692
|
+
self.log_identifier,
|
|
693
|
+
task_id,
|
|
694
|
+
)
|
|
695
|
+
else:
|
|
696
|
+
log.debug(
|
|
697
|
+
"%s Task %s not found in active_tasks during cleanup (already removed)",
|
|
698
|
+
self.log_identifier,
|
|
699
|
+
task_id,
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
def _publish_discovered_cards(self):
|
|
703
|
+
"""Publishes all agent cards currently in the registry."""
|
|
704
|
+
log.info(
|
|
705
|
+
"%s Publishing initially discovered agent cards...", self.log_identifier
|
|
706
|
+
)
|
|
707
|
+
for agent_alias in self.agent_registry.get_agent_names():
|
|
708
|
+
original_card = self.agent_registry.get_agent(agent_alias)
|
|
709
|
+
if not original_card:
|
|
710
|
+
continue
|
|
711
|
+
|
|
712
|
+
# Create a copy for publishing to avoid modifying the card in the registry
|
|
713
|
+
card_to_publish = original_card.model_copy(deep=True)
|
|
714
|
+
card_to_publish.url = (
|
|
715
|
+
f"solace:{a2a.get_agent_request_topic(self.namespace, agent_alias)}"
|
|
716
|
+
)
|
|
717
|
+
discovery_topic = a2a.get_discovery_topic(self.namespace)
|
|
718
|
+
self._publish_a2a_message(
|
|
719
|
+
card_to_publish.model_dump(exclude_none=True), discovery_topic
|
|
720
|
+
)
|
|
721
|
+
log.info(
|
|
722
|
+
"%s Published initially discovered card for agent '%s'.",
|
|
723
|
+
self.log_identifier,
|
|
724
|
+
agent_alias,
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
def run(self):
|
|
728
|
+
"""
|
|
729
|
+
Called by the framework to start the component's background tasks.
|
|
730
|
+
This is the component's main entry point for active operations.
|
|
731
|
+
"""
|
|
732
|
+
log.info(
|
|
733
|
+
"%s Component is ready. Starting active operations.", self.log_identifier
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
# Publish the cards that were discovered synchronously during init
|
|
737
|
+
self._publish_discovered_cards()
|
|
738
|
+
|
|
739
|
+
# Schedule the recurring discovery timer
|
|
740
|
+
if self.discovery_interval_sec > 0:
|
|
741
|
+
self.add_timer(
|
|
742
|
+
delay_ms=self.discovery_interval_sec * 1000,
|
|
743
|
+
timer_id=self._discovery_timer_id,
|
|
744
|
+
interval_ms=self.discovery_interval_sec * 1000,
|
|
745
|
+
)
|
|
746
|
+
log.info(
|
|
747
|
+
"%s Scheduled recurring agent discovery every %d seconds.",
|
|
748
|
+
self.log_identifier,
|
|
749
|
+
self.discovery_interval_sec,
|
|
750
|
+
)
|
|
751
|
+
|
|
752
|
+
# Schedule the recurring task cleanup timer
|
|
753
|
+
if self.task_cleanup_interval_minutes > 0:
|
|
754
|
+
cleanup_interval_ms = self.task_cleanup_interval_minutes * 60 * 1000
|
|
755
|
+
self.add_timer(
|
|
756
|
+
delay_ms=cleanup_interval_ms,
|
|
757
|
+
timer_id=self._task_cleanup_timer_id,
|
|
758
|
+
interval_ms=cleanup_interval_ms,
|
|
759
|
+
)
|
|
760
|
+
log.info(
|
|
761
|
+
"%s Scheduled recurring stale task cleanup every %d minutes (TTL: %d minutes).",
|
|
762
|
+
self.log_identifier,
|
|
763
|
+
self.task_cleanup_interval_minutes,
|
|
764
|
+
self.task_state_ttl_minutes,
|
|
765
|
+
)
|
|
766
|
+
|
|
767
|
+
super().run()
|
|
768
|
+
|
|
769
|
+
def clear_client_cache(self):
|
|
770
|
+
"""
|
|
771
|
+
Clears all cached clients. Useful for testing when authentication
|
|
772
|
+
configuration changes between tests.
|
|
773
|
+
"""
|
|
774
|
+
# This method is intentionally empty in the base class.
|
|
775
|
+
# Concrete implementations should override it if they cache clients.
|
|
776
|
+
pass
|
|
777
|
+
|
|
778
|
+
def cleanup(self):
|
|
779
|
+
"""Cleans up resources on component shutdown."""
|
|
780
|
+
log.info("%s Cleaning up proxy component.", self.log_identifier)
|
|
781
|
+
self.cancel_timer(self._discovery_timer_id)
|
|
782
|
+
self.cancel_timer(self._task_cleanup_timer_id)
|
|
783
|
+
|
|
784
|
+
# Clear active tasks (no need to signal cancellation - downstream agents own their tasks)
|
|
785
|
+
with self.active_tasks_lock:
|
|
786
|
+
self.active_tasks.clear()
|
|
787
|
+
|
|
788
|
+
if self._async_loop and self._async_loop.is_running():
|
|
789
|
+
self._async_loop.call_soon_threadsafe(self._async_loop.stop)
|
|
790
|
+
if self._async_thread and self._async_thread.is_alive():
|
|
791
|
+
self._async_thread.join(timeout=5)
|
|
792
|
+
if self._async_thread.is_alive():
|
|
793
|
+
log.warning(
|
|
794
|
+
"%s Async thread did not exit cleanly.", self.log_identifier
|
|
795
|
+
)
|
|
796
|
+
|
|
797
|
+
super().cleanup()
|
|
798
|
+
log.info("%s Component cleanup finished.", self.log_identifier)
|
|
799
|
+
|
|
800
|
+
@abstractmethod
|
|
801
|
+
async def _fetch_agent_card(self, agent_config: dict) -> Optional[AgentCard]:
|
|
802
|
+
"""
|
|
803
|
+
Fetches the AgentCard from a single downstream agent.
|
|
804
|
+
To be implemented by concrete proxy classes.
|
|
805
|
+
"""
|
|
806
|
+
raise NotImplementedError
|
|
807
|
+
|
|
808
|
+
@abstractmethod
|
|
809
|
+
async def _forward_request(
|
|
810
|
+
self, task_context: "ProxyTaskContext", request: A2ARequest, agent_name: str
|
|
811
|
+
):
|
|
812
|
+
"""
|
|
813
|
+
Forwards a request to the downstream agent using its specific protocol.
|
|
814
|
+
To be implemented by concrete proxy classes.
|
|
815
|
+
"""
|
|
816
|
+
raise NotImplementedError
|