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,970 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Refactored report data processor with improved structure and readability.
|
|
3
|
+
This module extracts and processes evaluation data for HTML report generation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import logging
|
|
8
|
+
import random
|
|
9
|
+
from collections import Counter, defaultdict
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from .shared import load_test_case
|
|
15
|
+
|
|
16
|
+
log = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class EvaluationMetrics:
|
|
21
|
+
"""Core evaluation data structure."""
|
|
22
|
+
|
|
23
|
+
models: list[str] = field(default_factory=list)
|
|
24
|
+
total_execution_time: float | None = None
|
|
25
|
+
total_execution_time_formatted: str = "Not available"
|
|
26
|
+
generation_time: str = field(
|
|
27
|
+
default_factory=lambda: datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
28
|
+
)
|
|
29
|
+
timestamp: str = field(
|
|
30
|
+
default_factory=lambda: datetime.now().strftime("%B %d, %Y at %I:%M %p")
|
|
31
|
+
)
|
|
32
|
+
runs: str = "Not available"
|
|
33
|
+
total_tests: int = 0
|
|
34
|
+
duration: str = "Not available"
|
|
35
|
+
test_case_names: list[str] = field(default_factory=list)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class ModelPerformance:
|
|
40
|
+
"""Individual model performance data."""
|
|
41
|
+
|
|
42
|
+
model_name: str
|
|
43
|
+
average_score: float = 0.0
|
|
44
|
+
success_rate: float = 0.0
|
|
45
|
+
test_count: int = 0
|
|
46
|
+
estimated_cost: float = 0.0
|
|
47
|
+
scores: list[float] = field(default_factory=list)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass
|
|
51
|
+
class TestCaseResult:
|
|
52
|
+
"""Test case specific results."""
|
|
53
|
+
|
|
54
|
+
test_case_id: str
|
|
55
|
+
category: str
|
|
56
|
+
description: str = ""
|
|
57
|
+
model_results: dict[str, any] = field(default_factory=dict)
|
|
58
|
+
average_score: float = 0.0
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@dataclass
|
|
62
|
+
class ChartConfiguration:
|
|
63
|
+
"""Chart and visualization data."""
|
|
64
|
+
|
|
65
|
+
categories: list[str] = field(default_factory=list)
|
|
66
|
+
datasets: list[dict[str, any]] = field(default_factory=list)
|
|
67
|
+
category_scores: dict[str, dict[str, float]] = field(default_factory=dict)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@dataclass
|
|
71
|
+
class CategoryStatistics:
|
|
72
|
+
"""Category-based statistics."""
|
|
73
|
+
|
|
74
|
+
category_name: str
|
|
75
|
+
test_cases: list[str] = field(default_factory=list)
|
|
76
|
+
model_scores: dict[str, float] = field(default_factory=dict)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FileService:
|
|
80
|
+
"""Handles file I/O operations with proper error handling."""
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def load_json(filepath: Path) -> any:
|
|
84
|
+
"""Load JSON data from file."""
|
|
85
|
+
try:
|
|
86
|
+
with open(filepath) as f:
|
|
87
|
+
return json.load(f)
|
|
88
|
+
except FileNotFoundError:
|
|
89
|
+
log.warning(f"File not found: {filepath}")
|
|
90
|
+
return None
|
|
91
|
+
except json.JSONDecodeError as e:
|
|
92
|
+
log.error(f"Invalid JSON in file {filepath}: {e}")
|
|
93
|
+
return None
|
|
94
|
+
except Exception as e:
|
|
95
|
+
log.error(f"Error reading file {filepath}: {e}")
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
@staticmethod
|
|
99
|
+
def file_exists(filepath: Path) -> bool:
|
|
100
|
+
"""Check if file exists."""
|
|
101
|
+
return filepath.exists() and filepath.is_file()
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def list_directories(path: Path) -> list[str]:
|
|
105
|
+
"""List directories in the given path."""
|
|
106
|
+
try:
|
|
107
|
+
return [
|
|
108
|
+
item.name
|
|
109
|
+
for item in path.iterdir()
|
|
110
|
+
if item.is_dir() and not item.name.startswith(".")
|
|
111
|
+
]
|
|
112
|
+
except Exception as e:
|
|
113
|
+
log.error(f"Error listing directories in {path}: {e}")
|
|
114
|
+
return []
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ResultsExtractionService:
|
|
118
|
+
"""Extracts raw data from results directories."""
|
|
119
|
+
|
|
120
|
+
def __init__(self, file_service: FileService):
|
|
121
|
+
self.file_service = file_service
|
|
122
|
+
|
|
123
|
+
def extract_model_results(self, results_dir: Path) -> dict[str, any]:
|
|
124
|
+
"""Extract results for all models."""
|
|
125
|
+
model_results = {}
|
|
126
|
+
|
|
127
|
+
for model_name in self.file_service.list_directories(results_dir):
|
|
128
|
+
model_path = results_dir / model_name
|
|
129
|
+
results_file = model_path / "results.json"
|
|
130
|
+
|
|
131
|
+
if self.file_service.file_exists(results_file):
|
|
132
|
+
results_data = self.file_service.load_json(results_file)
|
|
133
|
+
if results_data:
|
|
134
|
+
model_results[model_name] = results_data
|
|
135
|
+
log.debug(f"Loaded results for model: {model_name}")
|
|
136
|
+
|
|
137
|
+
log.info(f"Extracted results for {len(model_results)} models")
|
|
138
|
+
return model_results
|
|
139
|
+
|
|
140
|
+
def extract_execution_stats(self, results_dir: Path) -> dict[str, any] | None:
|
|
141
|
+
"""Extract execution statistics."""
|
|
142
|
+
stats_file = results_dir / "stats.json"
|
|
143
|
+
|
|
144
|
+
if self.file_service.file_exists(stats_file):
|
|
145
|
+
stats_data = self.file_service.load_json(stats_file)
|
|
146
|
+
if stats_data:
|
|
147
|
+
log.debug("Loaded execution statistics")
|
|
148
|
+
return stats_data
|
|
149
|
+
|
|
150
|
+
log.warning("No execution statistics found")
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class MetricsCalculationService:
|
|
155
|
+
"""Calculates performance statistics and aggregations."""
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def calculate_model_performance(
|
|
159
|
+
model_name: str, results_data: dict[str, any]
|
|
160
|
+
) -> ModelPerformance:
|
|
161
|
+
"""Calculate performance metrics for a single model."""
|
|
162
|
+
performance = ModelPerformance(model_name=model_name)
|
|
163
|
+
|
|
164
|
+
scores = []
|
|
165
|
+
test_count = 0
|
|
166
|
+
|
|
167
|
+
# Handle new data structure with test_cases array
|
|
168
|
+
if "test_cases" in results_data:
|
|
169
|
+
for test_case in results_data["test_cases"]:
|
|
170
|
+
if "runs" in test_case:
|
|
171
|
+
for run_data in test_case["runs"]:
|
|
172
|
+
if isinstance(run_data, dict):
|
|
173
|
+
# Use llm_eval score if available, otherwise use response_match
|
|
174
|
+
score = run_data.get("llm_eval", {}).get("score")
|
|
175
|
+
if score is None:
|
|
176
|
+
score = run_data.get("response_match", 0)
|
|
177
|
+
|
|
178
|
+
# Ensure score is valid
|
|
179
|
+
if score is not None and isinstance(score, (int, float)):
|
|
180
|
+
scores.append(score)
|
|
181
|
+
|
|
182
|
+
test_count += 1
|
|
183
|
+
|
|
184
|
+
# Calculate metrics
|
|
185
|
+
if scores:
|
|
186
|
+
performance.scores = scores
|
|
187
|
+
performance.average_score = sum(scores) / len(scores)
|
|
188
|
+
performance.success_rate = (
|
|
189
|
+
len([s for s in scores if s >= 0.7]) / len(scores) * 100
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
performance.test_count = test_count
|
|
193
|
+
performance.estimated_cost = test_count * 0.02 # Rough estimate
|
|
194
|
+
|
|
195
|
+
return performance
|
|
196
|
+
|
|
197
|
+
@staticmethod
|
|
198
|
+
def format_execution_time(total_time: float) -> tuple[str, str]:
|
|
199
|
+
"""Format execution time into readable strings."""
|
|
200
|
+
minutes = int(total_time // 60)
|
|
201
|
+
seconds = int(total_time % 60)
|
|
202
|
+
formatted = f"{minutes}m {seconds}s"
|
|
203
|
+
duration = f"{minutes} minutes {seconds} seconds"
|
|
204
|
+
return formatted, duration
|
|
205
|
+
|
|
206
|
+
@staticmethod
|
|
207
|
+
def calculate_run_statistics(model_results: dict[str, any]) -> tuple[int, str]:
|
|
208
|
+
"""Calculate run statistics from model results."""
|
|
209
|
+
test_cases = set()
|
|
210
|
+
all_run_counts = []
|
|
211
|
+
|
|
212
|
+
for _model_name, results in model_results.items():
|
|
213
|
+
if "test_cases" in results:
|
|
214
|
+
for test_case in results["test_cases"]:
|
|
215
|
+
test_case_id = test_case.get("test_case_id")
|
|
216
|
+
if test_case_id:
|
|
217
|
+
test_cases.add(test_case_id)
|
|
218
|
+
|
|
219
|
+
# Count unique runs
|
|
220
|
+
if "runs" in test_case:
|
|
221
|
+
unique_runs = set()
|
|
222
|
+
for run in test_case["runs"]:
|
|
223
|
+
if isinstance(run, dict) and "run" in run:
|
|
224
|
+
unique_runs.add(run["run"])
|
|
225
|
+
if unique_runs:
|
|
226
|
+
all_run_counts.append(len(unique_runs))
|
|
227
|
+
|
|
228
|
+
total_tests = len(test_cases)
|
|
229
|
+
|
|
230
|
+
# Determine run count description
|
|
231
|
+
if all_run_counts:
|
|
232
|
+
run_count_mode = Counter(all_run_counts).most_common(1)[0][0]
|
|
233
|
+
runs_description = f"{run_count_mode} run{'s' if run_count_mode != 1 else ''} per test case"
|
|
234
|
+
else:
|
|
235
|
+
runs_description = "Not available"
|
|
236
|
+
|
|
237
|
+
return total_tests, runs_description
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class ChartDataService:
|
|
241
|
+
"""Generates chart and visualization data."""
|
|
242
|
+
|
|
243
|
+
def __init__(self, file_service: FileService):
|
|
244
|
+
self.file_service = file_service
|
|
245
|
+
|
|
246
|
+
def generate_chart_configuration(
|
|
247
|
+
self, model_results: dict[str, any], test_cases: dict[str, dict[str, any]]
|
|
248
|
+
) -> ChartConfiguration:
|
|
249
|
+
"""Generate chart configuration data."""
|
|
250
|
+
chart_config = ChartConfiguration()
|
|
251
|
+
|
|
252
|
+
# Extract categories and organize test cases
|
|
253
|
+
category_test_mapping = self._extract_category_mapping(model_results)
|
|
254
|
+
|
|
255
|
+
# Calculate category scores for each model
|
|
256
|
+
category_scores = self._calculate_category_scores(
|
|
257
|
+
category_test_mapping, test_cases, model_results
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Prepare chart data
|
|
261
|
+
if category_scores:
|
|
262
|
+
chart_config.categories = sorted(category_scores.keys())
|
|
263
|
+
chart_config.category_scores = category_scores
|
|
264
|
+
chart_config.datasets = self._generate_chart_datasets(
|
|
265
|
+
category_scores, model_results
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
return chart_config
|
|
269
|
+
|
|
270
|
+
def _extract_category_mapping(
|
|
271
|
+
self, model_results: dict[str, any]
|
|
272
|
+
) -> dict[str, set[str]]:
|
|
273
|
+
"""Extract category to test case mapping."""
|
|
274
|
+
category_test_mapping = defaultdict(set)
|
|
275
|
+
|
|
276
|
+
for _model_name, results in model_results.items():
|
|
277
|
+
if "test_cases" in results:
|
|
278
|
+
for test_case in results["test_cases"]:
|
|
279
|
+
test_id = test_case.get("test_case_id")
|
|
280
|
+
category = test_case.get("category")
|
|
281
|
+
if test_id and category:
|
|
282
|
+
category_test_mapping[category].add(test_id)
|
|
283
|
+
|
|
284
|
+
# Convert sets to sorted lists
|
|
285
|
+
return {
|
|
286
|
+
cat: sorted(tests) for cat, tests in category_test_mapping.items()
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
def _calculate_category_scores(
|
|
290
|
+
self,
|
|
291
|
+
category_test_mapping: dict[str, list[str]],
|
|
292
|
+
test_cases: dict[str, dict[str, any]],
|
|
293
|
+
model_results: dict[str, any],
|
|
294
|
+
) -> dict[str, dict[str, float]]:
|
|
295
|
+
"""Calculate average scores by category for each model."""
|
|
296
|
+
category_scores = {}
|
|
297
|
+
|
|
298
|
+
for category, test_names in category_test_mapping.items():
|
|
299
|
+
category_scores[category] = {}
|
|
300
|
+
|
|
301
|
+
for model_name in model_results:
|
|
302
|
+
scores = []
|
|
303
|
+
|
|
304
|
+
# Collect scores for this category and model
|
|
305
|
+
for test_name in test_names:
|
|
306
|
+
if test_name in test_cases and model_name in test_cases[test_name]:
|
|
307
|
+
test_data = test_cases[test_name][model_name]
|
|
308
|
+
if isinstance(test_data, dict) and "runs" in test_data:
|
|
309
|
+
for run in test_data["runs"]:
|
|
310
|
+
if isinstance(run, dict):
|
|
311
|
+
# Prioritize llm_eval score over response_match
|
|
312
|
+
score = run.get("llm_eval", {}).get("score")
|
|
313
|
+
if score is not None and isinstance(
|
|
314
|
+
score, (int, float)
|
|
315
|
+
):
|
|
316
|
+
scores.append(score)
|
|
317
|
+
else:
|
|
318
|
+
score = run.get("response_match", 0)
|
|
319
|
+
if score is not None and isinstance(
|
|
320
|
+
score, (int, float)
|
|
321
|
+
):
|
|
322
|
+
scores.append(score)
|
|
323
|
+
|
|
324
|
+
# Calculate average score for this category and model
|
|
325
|
+
category_scores[category][model_name] = (
|
|
326
|
+
sum(scores) / len(scores) if scores else 0
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
return category_scores
|
|
330
|
+
|
|
331
|
+
def _generate_chart_datasets(
|
|
332
|
+
self,
|
|
333
|
+
category_scores: dict[str, dict[str, float]],
|
|
334
|
+
model_results: dict[str, any],
|
|
335
|
+
) -> list[dict[str, any]]:
|
|
336
|
+
"""Generate chart datasets for visualization."""
|
|
337
|
+
# Enhanced model colors with better contrast
|
|
338
|
+
model_colors = {
|
|
339
|
+
"gpt-4": "#059669",
|
|
340
|
+
"gpt-4-1": "#10b981",
|
|
341
|
+
"claude-3-sonnet": "#0ea5e9",
|
|
342
|
+
"gemini-pro": "#f59e0b",
|
|
343
|
+
"gemini-2.5-pro": "#f59e0b",
|
|
344
|
+
"gemini-flash": "#8b5cf6",
|
|
345
|
+
"gemini-2.5-flash": "#a855f7",
|
|
346
|
+
"gpt-3.5-turbo": "#ef4444",
|
|
347
|
+
"claude-3-haiku": "#84cc16",
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
chart_datasets = []
|
|
351
|
+
categories = sorted(category_scores.keys())
|
|
352
|
+
|
|
353
|
+
for model_name in sorted(model_results.keys()):
|
|
354
|
+
model_data = []
|
|
355
|
+
for category in categories:
|
|
356
|
+
score = category_scores[category].get(model_name, 0)
|
|
357
|
+
model_data.append(round(score, 3))
|
|
358
|
+
|
|
359
|
+
color = model_colors.get(model_name)
|
|
360
|
+
if color is None:
|
|
361
|
+
# Generate a random color if not in the predefined list
|
|
362
|
+
def generate_random_component():
|
|
363
|
+
return random.randint(0, 255)
|
|
364
|
+
|
|
365
|
+
color = f"#{generate_random_component():02x}{generate_random_component():02x}{generate_random_component():02x}"
|
|
366
|
+
|
|
367
|
+
chart_datasets.append(
|
|
368
|
+
{
|
|
369
|
+
"label": model_name,
|
|
370
|
+
"data": model_data,
|
|
371
|
+
"backgroundColor": color,
|
|
372
|
+
"borderColor": color,
|
|
373
|
+
"borderWidth": 1,
|
|
374
|
+
"borderRadius": 4,
|
|
375
|
+
"borderSkipped": False,
|
|
376
|
+
}
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
return chart_datasets
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class ModalDataService:
|
|
383
|
+
"""Generates data specifically for modal functionality."""
|
|
384
|
+
|
|
385
|
+
def __init__(self, file_service: FileService):
|
|
386
|
+
self.file_service = file_service
|
|
387
|
+
|
|
388
|
+
def generate_modal_test_data(
|
|
389
|
+
self, test_case_id: str, model_results: dict[str, any]
|
|
390
|
+
) -> dict[str, any]:
|
|
391
|
+
"""Generate test data for modal JavaScript consumption."""
|
|
392
|
+
modal_data = {"model_scores": {}, "tool_scores": {}, "individual_runs": {}}
|
|
393
|
+
|
|
394
|
+
# Extract data for this specific test case
|
|
395
|
+
for model_name, results in model_results.items():
|
|
396
|
+
if "test_cases" in results:
|
|
397
|
+
for test_case in results["test_cases"]:
|
|
398
|
+
if test_case.get("test_case_id") == test_case_id:
|
|
399
|
+
# Extract model scores
|
|
400
|
+
runs = test_case.get("runs", [])
|
|
401
|
+
if runs:
|
|
402
|
+
response_scores = []
|
|
403
|
+
tool_scores = []
|
|
404
|
+
individual_runs = []
|
|
405
|
+
|
|
406
|
+
for run_data in runs:
|
|
407
|
+
if isinstance(run_data, dict):
|
|
408
|
+
# Get response score (prioritize llm_eval)
|
|
409
|
+
response_score = run_data.get("response_match", 0)
|
|
410
|
+
llm_score = run_data.get("llm_eval", {}).get(
|
|
411
|
+
"score"
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
# Get tool score
|
|
415
|
+
tool_score = run_data.get("tool_match", 1.0)
|
|
416
|
+
|
|
417
|
+
# Get other data
|
|
418
|
+
duration = run_data.get("duration_seconds", 0)
|
|
419
|
+
run_number = run_data.get("run", 1)
|
|
420
|
+
reasoning = run_data.get("llm_eval", {}).get(
|
|
421
|
+
"reasoning", "No reasoning provided"
|
|
422
|
+
)
|
|
423
|
+
|
|
424
|
+
if response_score is not None:
|
|
425
|
+
response_scores.append(response_score)
|
|
426
|
+
tool_scores.append(tool_score)
|
|
427
|
+
|
|
428
|
+
individual_runs.append(
|
|
429
|
+
{
|
|
430
|
+
"run_number": run_number,
|
|
431
|
+
"response_score": response_score,
|
|
432
|
+
"tool_score": tool_score,
|
|
433
|
+
"llm_eval": llm_score,
|
|
434
|
+
"llm_reasoning": reasoning,
|
|
435
|
+
"execution_time": duration,
|
|
436
|
+
"query": "",
|
|
437
|
+
"actual_response": "",
|
|
438
|
+
"expected_response": "",
|
|
439
|
+
}
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
# Calculate averages
|
|
443
|
+
if response_scores:
|
|
444
|
+
modal_data["model_scores"][model_name] = sum(
|
|
445
|
+
response_scores
|
|
446
|
+
) / len(response_scores)
|
|
447
|
+
modal_data["tool_scores"][model_name] = sum(
|
|
448
|
+
tool_scores
|
|
449
|
+
) / len(tool_scores)
|
|
450
|
+
modal_data["individual_runs"][
|
|
451
|
+
model_name
|
|
452
|
+
] = individual_runs
|
|
453
|
+
|
|
454
|
+
return modal_data
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
class TemplateDataService:
|
|
458
|
+
"""Formats data for template consumption."""
|
|
459
|
+
|
|
460
|
+
def __init__(self, file_service: FileService):
|
|
461
|
+
self.file_service = file_service
|
|
462
|
+
self.modal_service = ModalDataService(file_service)
|
|
463
|
+
|
|
464
|
+
def generate_performance_metrics_table(
|
|
465
|
+
self, model_performances: dict[str, ModelPerformance]
|
|
466
|
+
) -> str:
|
|
467
|
+
"""Generate HTML table rows for performance metrics."""
|
|
468
|
+
metrics_rows = []
|
|
469
|
+
|
|
470
|
+
for model_name, performance in model_performances.items():
|
|
471
|
+
if performance.scores:
|
|
472
|
+
score_class = self._get_score_class(performance.average_score)
|
|
473
|
+
|
|
474
|
+
metrics_rows.append(
|
|
475
|
+
f"""
|
|
476
|
+
<tr>
|
|
477
|
+
<td class="model-name">{model_name}</td>
|
|
478
|
+
<td class="metric-value {score_class}">{performance.average_score:.2f}</td>
|
|
479
|
+
<td class="metric-value {score_class}">{performance.success_rate:.0f}%</td>
|
|
480
|
+
<td class="metric-value">{performance.test_count}</td>
|
|
481
|
+
<td class="estimated-cost">${performance.estimated_cost:.2f}</td>
|
|
482
|
+
</tr>
|
|
483
|
+
"""
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
return "".join(metrics_rows)
|
|
487
|
+
|
|
488
|
+
def generate_breakdown_content(
|
|
489
|
+
self,
|
|
490
|
+
test_case_results: list[TestCaseResult],
|
|
491
|
+
model_performances: dict[str, ModelPerformance],
|
|
492
|
+
model_results: dict[str, any] = None,
|
|
493
|
+
) -> str:
|
|
494
|
+
"""Generate detailed breakdown content by category with modal support."""
|
|
495
|
+
# Group test cases by category
|
|
496
|
+
categories_with_tests = defaultdict(list)
|
|
497
|
+
for test_result in test_case_results:
|
|
498
|
+
categories_with_tests[test_result.category].append(test_result)
|
|
499
|
+
|
|
500
|
+
breakdown_sections = []
|
|
501
|
+
|
|
502
|
+
for category, test_results in sorted(categories_with_tests.items()):
|
|
503
|
+
category_tests = []
|
|
504
|
+
|
|
505
|
+
for test_result in test_results:
|
|
506
|
+
test_scores = []
|
|
507
|
+
|
|
508
|
+
for model_name, _performance in model_performances.items():
|
|
509
|
+
if test_result.test_case_id in test_result.model_results:
|
|
510
|
+
model_data = test_result.model_results[
|
|
511
|
+
test_result.test_case_id
|
|
512
|
+
].get(model_name, {})
|
|
513
|
+
|
|
514
|
+
if isinstance(model_data, dict) and "runs" in model_data:
|
|
515
|
+
scores = []
|
|
516
|
+
durations = []
|
|
517
|
+
success_count = 0
|
|
518
|
+
|
|
519
|
+
for run in model_data["runs"]:
|
|
520
|
+
if isinstance(run, dict):
|
|
521
|
+
# Use llm_eval score if available, otherwise use response_match
|
|
522
|
+
score = run.get("llm_eval", {}).get("score")
|
|
523
|
+
if score is not None and isinstance(
|
|
524
|
+
score, (int, float)
|
|
525
|
+
):
|
|
526
|
+
scores.append(score)
|
|
527
|
+
else:
|
|
528
|
+
score = run.get("response_match", 0)
|
|
529
|
+
if score is not None and isinstance(
|
|
530
|
+
score, (int, float)
|
|
531
|
+
):
|
|
532
|
+
scores.append(score)
|
|
533
|
+
|
|
534
|
+
# Track duration and success
|
|
535
|
+
duration = run.get("duration_seconds", 0)
|
|
536
|
+
if duration is not None and isinstance(
|
|
537
|
+
duration, (int, float)
|
|
538
|
+
):
|
|
539
|
+
durations.append(duration)
|
|
540
|
+
if (
|
|
541
|
+
score is not None
|
|
542
|
+
and isinstance(score, (int, float))
|
|
543
|
+
and score >= 0.7
|
|
544
|
+
):
|
|
545
|
+
success_count += 1
|
|
546
|
+
|
|
547
|
+
if scores:
|
|
548
|
+
avg_score = sum(scores) / len(scores)
|
|
549
|
+
avg_duration = (
|
|
550
|
+
sum(durations) / len(durations) if durations else 0
|
|
551
|
+
)
|
|
552
|
+
score_class = self._get_score_class(avg_score)
|
|
553
|
+
|
|
554
|
+
test_scores.append(
|
|
555
|
+
f"""
|
|
556
|
+
<div class="model-result {score_class}">
|
|
557
|
+
<span class="model-score">{model_name}</span>
|
|
558
|
+
<span class="score-value">LLM Eval: {avg_score:.3f}</span>
|
|
559
|
+
<span class="avg-duration">Avg time: {avg_duration:.1f}s</span>
|
|
560
|
+
</div>
|
|
561
|
+
"""
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
if test_scores:
|
|
565
|
+
# Generate modal data for this test case
|
|
566
|
+
modal_data = {}
|
|
567
|
+
if model_results:
|
|
568
|
+
modal_data = self.modal_service.generate_modal_test_data(
|
|
569
|
+
test_result.test_case_id, model_results
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
# Escape JSON for HTML attribute
|
|
573
|
+
modal_data_json = json.dumps(modal_data).replace('"', """)
|
|
574
|
+
|
|
575
|
+
category_tests.append(
|
|
576
|
+
f"""
|
|
577
|
+
<div class="test-item"
|
|
578
|
+
data-test-name="{test_result.test_case_id}"
|
|
579
|
+
data-test-description="{test_result.description}"
|
|
580
|
+
data-test-data="{modal_data_json}">
|
|
581
|
+
<div class="test-header">
|
|
582
|
+
<span class="test-name">{test_result.test_case_id}</span>
|
|
583
|
+
<span class="test-description">{test_result.description}</span>
|
|
584
|
+
</div>
|
|
585
|
+
<div class="model-results">
|
|
586
|
+
{''.join(test_scores)}
|
|
587
|
+
</div>
|
|
588
|
+
</div>
|
|
589
|
+
"""
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
if category_tests:
|
|
593
|
+
test_count = len(category_tests)
|
|
594
|
+
breakdown_sections.append(
|
|
595
|
+
f"""
|
|
596
|
+
<div class="category-section">
|
|
597
|
+
<div class="category-header">
|
|
598
|
+
<h3 class="category-title">{category} ({test_count} test case{'s' if test_count != 1 else ''})</h3>
|
|
599
|
+
<span class="category-toggle">▶</span>
|
|
600
|
+
</div>
|
|
601
|
+
<div class="category-content">
|
|
602
|
+
{''.join(category_tests)}
|
|
603
|
+
</div>
|
|
604
|
+
</div>
|
|
605
|
+
"""
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
return "".join(breakdown_sections)
|
|
609
|
+
|
|
610
|
+
def generate_model_execution_times(self, model_results: dict[str, any]) -> str:
|
|
611
|
+
"""Generate model execution times HTML."""
|
|
612
|
+
execution_times_html = []
|
|
613
|
+
|
|
614
|
+
# Model colors for consistency
|
|
615
|
+
model_colors = {
|
|
616
|
+
"gpt-4": "#059669",
|
|
617
|
+
"gpt-4-1": "#10b981",
|
|
618
|
+
"claude-3-sonnet": "#0ea5e9",
|
|
619
|
+
"gemini-pro": "#f59e0b",
|
|
620
|
+
"gemini-2.5-pro": "#f59e0b",
|
|
621
|
+
"gemini-flash": "#8b5cf6",
|
|
622
|
+
"gpt-3.5-turbo": "#ef4444",
|
|
623
|
+
"claude-3-haiku": "#84cc16",
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
for model_name in sorted(model_results.keys()):
|
|
627
|
+
results = model_results[model_name]
|
|
628
|
+
execution_time = results.get("total_execution_time")
|
|
629
|
+
|
|
630
|
+
if execution_time is not None:
|
|
631
|
+
# Format time as minutes and seconds
|
|
632
|
+
minutes = int(execution_time // 60)
|
|
633
|
+
seconds = int(execution_time % 60)
|
|
634
|
+
time_formatted = f"{minutes}m {seconds}s"
|
|
635
|
+
|
|
636
|
+
color = model_colors.get(model_name, "#6b7280")
|
|
637
|
+
execution_times_html.append(
|
|
638
|
+
f"""
|
|
639
|
+
<div style="background: #f9fafb; padding: 15px; border-radius: 8px; border-left: 4px solid {color}; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
|
640
|
+
<div style="font-weight: 600; color: #1f2937; margin-bottom: 5px; font-size: 1rem;">{model_name}</div>
|
|
641
|
+
<div style="color: {color}; font-weight: 700; font-size: 1.25rem; font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;">{time_formatted}</div>
|
|
642
|
+
<div style="color: #6b7280; font-size: 0.85rem; margin-top: 2px;">Total execution time</div>
|
|
643
|
+
</div>
|
|
644
|
+
"""
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
return "".join(execution_times_html)
|
|
648
|
+
|
|
649
|
+
def calculate_best_worst_tests(
|
|
650
|
+
self, test_case_results: list[TestCaseResult]
|
|
651
|
+
) -> tuple[str, str]:
|
|
652
|
+
"""Calculate best and worst performing tests."""
|
|
653
|
+
test_averages = {}
|
|
654
|
+
|
|
655
|
+
for test_result in test_case_results:
|
|
656
|
+
if test_result.average_score > 0:
|
|
657
|
+
test_averages[test_result.test_case_id] = test_result.average_score
|
|
658
|
+
|
|
659
|
+
if test_averages:
|
|
660
|
+
best_test = max(test_averages, key=test_averages.get)
|
|
661
|
+
worst_test = min(test_averages, key=test_averages.get)
|
|
662
|
+
|
|
663
|
+
best_result = f"{best_test} (avg: {test_averages[best_test]:.2f})"
|
|
664
|
+
worst_result = f"{worst_test} (avg: {test_averages[worst_test]:.2f})"
|
|
665
|
+
|
|
666
|
+
return best_result, worst_result
|
|
667
|
+
|
|
668
|
+
return "Not available", "Not available"
|
|
669
|
+
|
|
670
|
+
def calculate_average_time(
|
|
671
|
+
self, model_performances: dict[str, ModelPerformance]
|
|
672
|
+
) -> str:
|
|
673
|
+
"""Calculate overall average time."""
|
|
674
|
+
all_durations = []
|
|
675
|
+
|
|
676
|
+
# Extract durations from model results if available
|
|
677
|
+
for performance in model_performances.values():
|
|
678
|
+
if hasattr(performance, "durations") and performance.durations:
|
|
679
|
+
all_durations.extend(performance.durations)
|
|
680
|
+
|
|
681
|
+
if all_durations:
|
|
682
|
+
avg_duration = sum(all_durations) / len(all_durations)
|
|
683
|
+
return f"{avg_duration:.1f}s"
|
|
684
|
+
|
|
685
|
+
return "Not available"
|
|
686
|
+
|
|
687
|
+
def _get_score_class(self, score: float) -> str:
|
|
688
|
+
"""Get CSS class based on score value."""
|
|
689
|
+
if score >= 0.7:
|
|
690
|
+
return "score-high"
|
|
691
|
+
elif score >= 0.4:
|
|
692
|
+
return "score-medium"
|
|
693
|
+
else:
|
|
694
|
+
return "score-low"
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
class ModelResultsProcessor:
|
|
698
|
+
"""Processes individual model results."""
|
|
699
|
+
|
|
700
|
+
def __init__(self, file_service: FileService):
|
|
701
|
+
self.file_service = file_service
|
|
702
|
+
|
|
703
|
+
def organize_test_cases(
|
|
704
|
+
self, model_results: dict[str, any]
|
|
705
|
+
) -> dict[str, dict[str, any]]:
|
|
706
|
+
"""Organize test cases by test case ID and model."""
|
|
707
|
+
test_cases = {}
|
|
708
|
+
|
|
709
|
+
for model_name, results in model_results.items():
|
|
710
|
+
if "test_cases" in results:
|
|
711
|
+
for test_case in results["test_cases"]:
|
|
712
|
+
test_case_id = test_case.get("test_case_id")
|
|
713
|
+
if test_case_id:
|
|
714
|
+
if test_case_id not in test_cases:
|
|
715
|
+
test_cases[test_case_id] = {}
|
|
716
|
+
test_cases[test_case_id][model_name] = test_case
|
|
717
|
+
|
|
718
|
+
return test_cases
|
|
719
|
+
|
|
720
|
+
def create_test_case_results(
|
|
721
|
+
self, test_cases: dict[str, dict[str, any]]
|
|
722
|
+
) -> list[TestCaseResult]:
|
|
723
|
+
"""Create TestCaseResult objects from organized test cases."""
|
|
724
|
+
test_case_results = []
|
|
725
|
+
|
|
726
|
+
for test_case_id, models_data in test_cases.items():
|
|
727
|
+
# Get test case metadata
|
|
728
|
+
try:
|
|
729
|
+
# Get path from the first available run data
|
|
730
|
+
first_model_data = next(iter(models_data.values()))
|
|
731
|
+
test_case_path = first_model_data["runs"][0]["test_case_path"]
|
|
732
|
+
test_case_data = load_test_case(test_case_path)
|
|
733
|
+
category = test_case_data.get("category", "Uncategorized")
|
|
734
|
+
description = test_case_data.get(
|
|
735
|
+
"description", f"Test case: {test_case_id}"
|
|
736
|
+
)
|
|
737
|
+
except (StopIteration, IndexError, KeyError):
|
|
738
|
+
category = "Uncategorized"
|
|
739
|
+
description = f"Test case: {test_case_id}"
|
|
740
|
+
|
|
741
|
+
# Calculate average score across all models and runs
|
|
742
|
+
all_scores = []
|
|
743
|
+
for model_data in models_data.values():
|
|
744
|
+
if isinstance(model_data, dict) and "runs" in model_data:
|
|
745
|
+
for run in model_data["runs"]:
|
|
746
|
+
if isinstance(run, dict):
|
|
747
|
+
score = run.get("llm_eval", {}).get("score")
|
|
748
|
+
if score is None:
|
|
749
|
+
score = run.get("response_match", 0)
|
|
750
|
+
if score is not None and isinstance(score, (int, float)):
|
|
751
|
+
all_scores.append(score)
|
|
752
|
+
|
|
753
|
+
average_score = sum(all_scores) / len(all_scores) if all_scores else 0
|
|
754
|
+
|
|
755
|
+
test_result = TestCaseResult(
|
|
756
|
+
test_case_id=test_case_id,
|
|
757
|
+
category=category,
|
|
758
|
+
description=description,
|
|
759
|
+
model_results={test_case_id: models_data},
|
|
760
|
+
average_score=average_score,
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
test_case_results.append(test_result)
|
|
764
|
+
|
|
765
|
+
return test_case_results
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
class ReportDataProcessor:
|
|
769
|
+
"""Main processor that coordinates the entire data processing pipeline."""
|
|
770
|
+
|
|
771
|
+
def __init__(self):
|
|
772
|
+
self.file_service = FileService()
|
|
773
|
+
self.extraction_service = ResultsExtractionService(self.file_service)
|
|
774
|
+
self.metrics_service = MetricsCalculationService()
|
|
775
|
+
self.chart_service = ChartDataService(self.file_service)
|
|
776
|
+
self.template_service = TemplateDataService(self.file_service)
|
|
777
|
+
self.processor = ModelResultsProcessor(self.file_service)
|
|
778
|
+
|
|
779
|
+
def get_evaluation_data(self, results_dir: Path) -> dict[str, any]:
|
|
780
|
+
"""Extract and process basic evaluation data."""
|
|
781
|
+
log.info("Processing evaluation data...")
|
|
782
|
+
|
|
783
|
+
# Initialize metrics
|
|
784
|
+
metrics = EvaluationMetrics()
|
|
785
|
+
|
|
786
|
+
# Extract model results
|
|
787
|
+
model_results = self.extraction_service.extract_model_results(results_dir)
|
|
788
|
+
if not model_results:
|
|
789
|
+
log.warning("No model results found")
|
|
790
|
+
return self._metrics_to_dict(metrics)
|
|
791
|
+
|
|
792
|
+
# Set basic model information
|
|
793
|
+
metrics.models = list(model_results.keys())
|
|
794
|
+
|
|
795
|
+
# Calculate test statistics
|
|
796
|
+
total_tests, runs_description = self.metrics_service.calculate_run_statistics(
|
|
797
|
+
model_results
|
|
798
|
+
)
|
|
799
|
+
metrics.total_tests = total_tests
|
|
800
|
+
metrics.runs = runs_description
|
|
801
|
+
metrics.test_case_names = self._extract_test_case_names(model_results)
|
|
802
|
+
|
|
803
|
+
# Extract execution statistics
|
|
804
|
+
stats_data = self.extraction_service.extract_execution_stats(results_dir)
|
|
805
|
+
if stats_data and "total_execution_time" in stats_data:
|
|
806
|
+
total_time = stats_data["total_execution_time"]
|
|
807
|
+
metrics.total_execution_time = total_time
|
|
808
|
+
formatted_time, duration = self.metrics_service.format_execution_time(
|
|
809
|
+
total_time
|
|
810
|
+
)
|
|
811
|
+
metrics.total_execution_time_formatted = formatted_time
|
|
812
|
+
metrics.duration = duration
|
|
813
|
+
|
|
814
|
+
log.info(f"Processed evaluation data for {len(metrics.models)} models")
|
|
815
|
+
return self._metrics_to_dict(metrics)
|
|
816
|
+
|
|
817
|
+
def get_detailed_evaluation_data(self, results_dir: Path) -> dict[str, any]:
|
|
818
|
+
"""Extract and process detailed evaluation data for charts and breakdowns."""
|
|
819
|
+
log.info("Processing detailed evaluation data...")
|
|
820
|
+
|
|
821
|
+
# Extract model results
|
|
822
|
+
model_results = self.extraction_service.extract_model_results(results_dir)
|
|
823
|
+
if not model_results:
|
|
824
|
+
log.warning("No model results found for detailed data")
|
|
825
|
+
return self._empty_detailed_data()
|
|
826
|
+
|
|
827
|
+
# Calculate model performances
|
|
828
|
+
model_performances = {}
|
|
829
|
+
total_evaluations = 0
|
|
830
|
+
|
|
831
|
+
for model_name, results_data in model_results.items():
|
|
832
|
+
performance = self.metrics_service.calculate_model_performance(
|
|
833
|
+
model_name, results_data
|
|
834
|
+
)
|
|
835
|
+
model_performances[model_name] = performance
|
|
836
|
+
total_evaluations += performance.test_count
|
|
837
|
+
|
|
838
|
+
# Organize test cases
|
|
839
|
+
test_cases = self.processor.organize_test_cases(model_results)
|
|
840
|
+
test_case_results = self.processor.create_test_case_results(test_cases)
|
|
841
|
+
|
|
842
|
+
# Generate chart configuration
|
|
843
|
+
chart_config = self.chart_service.generate_chart_configuration(
|
|
844
|
+
model_results, test_cases
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
# Generate template data
|
|
848
|
+
performance_metrics_rows = (
|
|
849
|
+
self.template_service.generate_performance_metrics_table(model_performances)
|
|
850
|
+
)
|
|
851
|
+
breakdown_content = self.template_service.generate_breakdown_content(
|
|
852
|
+
test_case_results, model_performances, model_results
|
|
853
|
+
)
|
|
854
|
+
model_execution_times = self.template_service.generate_model_execution_times(
|
|
855
|
+
model_results
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
# Calculate best/worst tests and average time
|
|
859
|
+
best_test, worst_test = self.template_service.calculate_best_worst_tests(
|
|
860
|
+
test_case_results
|
|
861
|
+
)
|
|
862
|
+
avg_time = self.template_service.calculate_average_time(model_performances)
|
|
863
|
+
|
|
864
|
+
detailed_data = {
|
|
865
|
+
"performance_metrics_rows": performance_metrics_rows,
|
|
866
|
+
"breakdown_content": breakdown_content,
|
|
867
|
+
"best_test": best_test,
|
|
868
|
+
"worst_test": worst_test,
|
|
869
|
+
"avg_time": avg_time,
|
|
870
|
+
"total_evaluations": total_evaluations,
|
|
871
|
+
"categories_data": json.dumps(chart_config.categories),
|
|
872
|
+
"chart_datasets_data": json.dumps(chart_config.datasets),
|
|
873
|
+
"model_execution_times": model_execution_times,
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
log.info("Processed detailed evaluation data successfully")
|
|
877
|
+
return detailed_data
|
|
878
|
+
|
|
879
|
+
def _extract_test_case_names(self, model_results: dict[str, any]) -> list[str]:
|
|
880
|
+
"""Extract unique test case names from model results."""
|
|
881
|
+
test_case_names = set()
|
|
882
|
+
|
|
883
|
+
for results in model_results.values():
|
|
884
|
+
if "test_cases" in results:
|
|
885
|
+
for test_case in results["test_cases"]:
|
|
886
|
+
test_case_id = test_case.get("test_case_id")
|
|
887
|
+
if test_case_id:
|
|
888
|
+
test_case_names.add(test_case_id)
|
|
889
|
+
|
|
890
|
+
return sorted(test_case_names)
|
|
891
|
+
|
|
892
|
+
def _metrics_to_dict(self, metrics: EvaluationMetrics) -> dict[str, any]:
|
|
893
|
+
"""Convert EvaluationMetrics to dictionary."""
|
|
894
|
+
# Generate model tags HTML
|
|
895
|
+
model_tags = ""
|
|
896
|
+
if metrics.models:
|
|
897
|
+
model_tags = "".join(
|
|
898
|
+
[f'<span class="model-tag">{model}</span>' for model in metrics.models]
|
|
899
|
+
)
|
|
900
|
+
|
|
901
|
+
# Generate test cases list HTML
|
|
902
|
+
test_cases_list = ""
|
|
903
|
+
if metrics.test_case_names:
|
|
904
|
+
test_cases_list = "".join(
|
|
905
|
+
[
|
|
906
|
+
f"<li>{test_case}.test.json</li>"
|
|
907
|
+
for test_case in metrics.test_case_names
|
|
908
|
+
]
|
|
909
|
+
)
|
|
910
|
+
elif metrics.total_tests > 0:
|
|
911
|
+
test_cases_list = "<li>Test cases available (names not loaded)</li>"
|
|
912
|
+
|
|
913
|
+
return {
|
|
914
|
+
"models": metrics.models,
|
|
915
|
+
"total_execution_time": metrics.total_execution_time,
|
|
916
|
+
"total_execution_time_formatted": metrics.total_execution_time_formatted,
|
|
917
|
+
"generation_time": metrics.generation_time,
|
|
918
|
+
"timestamp": metrics.timestamp,
|
|
919
|
+
"runs": metrics.runs,
|
|
920
|
+
"total_tests": metrics.total_tests,
|
|
921
|
+
"duration": metrics.duration,
|
|
922
|
+
"test_case_names": metrics.test_case_names,
|
|
923
|
+
# Template-specific keys
|
|
924
|
+
"total_models": str(len(metrics.models)),
|
|
925
|
+
"model_tags": model_tags,
|
|
926
|
+
"test_cases_list": test_cases_list,
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
def _empty_detailed_data(self) -> dict[str, any]:
|
|
930
|
+
"""Return empty detailed data structure."""
|
|
931
|
+
return {
|
|
932
|
+
"performance_metrics_rows": "",
|
|
933
|
+
"breakdown_content": "",
|
|
934
|
+
"best_test": "Not available",
|
|
935
|
+
"worst_test": "Not available",
|
|
936
|
+
"avg_time": "Not available",
|
|
937
|
+
"total_evaluations": 0,
|
|
938
|
+
"categories_data": "[]",
|
|
939
|
+
"chart_datasets_data": "[]",
|
|
940
|
+
"model_execution_times": "",
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def main():
|
|
945
|
+
"""Main entry point for testing the report data processor."""
|
|
946
|
+
import sys
|
|
947
|
+
from pathlib import Path
|
|
948
|
+
|
|
949
|
+
if len(sys.argv) > 1:
|
|
950
|
+
results_dir = Path(sys.argv[1])
|
|
951
|
+
else:
|
|
952
|
+
# Default to test results directory
|
|
953
|
+
script_dir = Path(__file__).parent
|
|
954
|
+
results_dir = script_dir / "results" / "tests"
|
|
955
|
+
|
|
956
|
+
processor = ReportDataProcessor()
|
|
957
|
+
|
|
958
|
+
log.info("Testing evaluation data extraction...")
|
|
959
|
+
eval_data = processor.get_evaluation_data(results_dir)
|
|
960
|
+
log.info(f"Found {len(eval_data.get('models', []))} models")
|
|
961
|
+
|
|
962
|
+
log.info("Testing detailed evaluation data extraction...")
|
|
963
|
+
detailed_data = processor.get_detailed_evaluation_data(results_dir)
|
|
964
|
+
log.info(f"Total evaluations: {detailed_data.get('total_evaluations', 0)}")
|
|
965
|
+
|
|
966
|
+
log.info("Report data processing completed successfully!")
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
if __name__ == "__main__":
|
|
970
|
+
main()
|