solace-agent-mesh 1.5.1__py3-none-any.whl → 1.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of solace-agent-mesh might be problematic. Click here for more details.
- solace_agent_mesh/agent/adk/callbacks.py +0 -5
- solace_agent_mesh/agent/adk/models/lite_llm.py +123 -8
- solace_agent_mesh/agent/adk/models/oauth2_token_manager.py +245 -0
- solace_agent_mesh/agent/protocol/event_handlers.py +213 -31
- 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/app.py +55 -0
- solace_agent_mesh/agent/proxies/a2a/component.py +1115 -0
- solace_agent_mesh/agent/proxies/a2a/config.py +140 -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 +99 -0
- solace_agent_mesh/agent/proxies/base/component.py +650 -0
- solace_agent_mesh/agent/proxies/base/config.py +85 -0
- solace_agent_mesh/agent/proxies/base/proxy_task_context.py +17 -0
- solace_agent_mesh/agent/sac/app.py +58 -5
- solace_agent_mesh/agent/sac/component.py +238 -75
- solace_agent_mesh/agent/sac/task_execution_context.py +46 -0
- solace_agent_mesh/agent/tools/audio_tools.py +125 -8
- solace_agent_mesh/agent/tools/web_tools.py +10 -5
- solace_agent_mesh/agent/utils/artifact_helpers.py +141 -3
- solace_agent_mesh/assets/docs/404.html +3 -3
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.eda4bcb2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.f4b15f3b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/71da7b71.38583438.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/77cf947d.48cb18a2.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/924ffdeb.8095e148.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.570c057b.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{ad71b5ed.60668e9e.js → ad71b5ed.af3ecfd1.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/ceb2a7a6.5d92d7d0.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{da0b5bad.9d369087.js → da0b5bad.d08a9466.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/db924877.e98d12a1.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/de915948.27d6b065.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{e3d9abda.2b916f9e.js → e3d9abda.6b9493d0.js} +1 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.e74a984d.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/f284c35a.42f59cdd.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.15b02f97.js +1 -0
- solace_agent_mesh/assets/docs/assets/js/{main.bd3c34f3.js → main.b12eac43.js} +2 -2
- solace_agent_mesh/assets/docs/assets/js/runtime~main.e268214e.js +1 -0
- solace_agent_mesh/assets/docs/docs/documentation/components/agents/index.html +15 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/artifact-management/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/audio-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/data-analysis-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/embeds/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/builtin-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/cli/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/gateways/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/orchestrator/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/plugins/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/components/proxies/index.html +262 -0
- solace_agent_mesh/assets/docs/docs/documentation/deploying/debugging/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/deployment-options/index.html +31 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/deploying/observability/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/create-gateways/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-python-tools/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/creating-service-providers/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/evaluations/index.html +135 -0
- solace_agent_mesh/assets/docs/docs/documentation/developing/index.html +6 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/structure/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/bedrock-agents/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/custom-agent/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/event-mesh-gateway/index.html +5 -5
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mcp-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/mongodb-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rag-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/rest-gateway/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/slack-integration/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/developing/tutorials/sql-database/index.html +4 -4
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/rbac-setup-guide/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/enterprise/single-sign-on/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/architecture/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/getting-started/try-agent-mesh/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/configurations/index.html +6 -5
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/installation/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/large_language_models/index.html +100 -3
- solace_agent_mesh/assets/docs/docs/documentation/installing-and-configuring/run-project/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-gateway-upgrade-to-0.3.0/index.html +3 -3
- solace_agent_mesh/assets/docs/docs/documentation/migrations/a2a-upgrade/a2a-technical-migration-map/index.html +3 -3
- solace_agent_mesh/assets/docs/lunr-index-1761248203150.json +1 -0
- solace_agent_mesh/assets/docs/lunr-index.json +1 -1
- solace_agent_mesh/assets/docs/search-doc-1761248203150.json +1 -0
- solace_agent_mesh/assets/docs/search-doc.json +1 -1
- solace_agent_mesh/assets/docs/sitemap.xml +1 -1
- solace_agent_mesh/cli/__init__.py +1 -1
- solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +2 -69
- solace_agent_mesh/cli/commands/eval_cmd.py +11 -49
- solace_agent_mesh/cli/commands/init_cmd/__init__.py +0 -5
- solace_agent_mesh/cli/commands/init_cmd/env_step.py +10 -12
- solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +9 -61
- solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +9 -49
- solace_agent_mesh/cli/commands/plugin_cmd/add_cmd.py +1 -2
- solace_agent_mesh/client/webui/frontend/static/assets/{authCallback-DwrxZE0E.js → authCallback-BTf6dqwp.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/{client-DarGQzyw.js → client-CaY59VuC.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-B32noGmR.js +342 -0
- solace_agent_mesh/client/webui/frontend/static/assets/main-DHJKSW1S.css +1 -0
- solace_agent_mesh/client/webui/frontend/static/assets/{vendor-BKIeiHj_.js → vendor-BEmvJSYz.js} +1 -1
- solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -3
- solace_agent_mesh/client/webui/frontend/static/index.html +4 -4
- solace_agent_mesh/common/a2a/__init__.py +24 -0
- solace_agent_mesh/common/a2a/artifact.py +39 -0
- solace_agent_mesh/common/a2a/events.py +29 -0
- solace_agent_mesh/common/a2a/message.py +68 -0
- solace_agent_mesh/common/a2a/protocol.py +151 -1
- solace_agent_mesh/common/agent_registry.py +83 -3
- solace_agent_mesh/common/constants.py +3 -1
- solace_agent_mesh/common/sac/sam_component_base.py +383 -4
- solace_agent_mesh/common/utils/pydantic_utils.py +12 -0
- solace_agent_mesh/config_portal/backend/common.py +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-ByU1X1HD.js +98 -0
- solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-44d62be6.js → manifest-61038fc6.js} +1 -1
- solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
- solace_agent_mesh/evaluation/evaluator.py +128 -104
- solace_agent_mesh/evaluation/message_organizer.py +116 -110
- solace_agent_mesh/evaluation/report_data_processor.py +84 -86
- solace_agent_mesh/evaluation/report_generator.py +73 -79
- solace_agent_mesh/evaluation/run.py +421 -235
- 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 +111 -232
- solace_agent_mesh/evaluation/summary_builder.py +227 -117
- solace_agent_mesh/gateway/base/app.py +16 -1
- solace_agent_mesh/gateway/base/component.py +112 -39
- solace_agent_mesh/gateway/http_sse/alembic/versions/20251015_add_session_performance_indexes.py +70 -0
- solace_agent_mesh/gateway/http_sse/component.py +99 -3
- solace_agent_mesh/gateway/http_sse/dependencies.py +4 -4
- solace_agent_mesh/gateway/http_sse/main.py +1 -0
- solace_agent_mesh/gateway/http_sse/repository/chat_task_repository.py +12 -13
- solace_agent_mesh/gateway/http_sse/repository/feedback_repository.py +15 -18
- solace_agent_mesh/gateway/http_sse/repository/interfaces.py +25 -18
- solace_agent_mesh/gateway/http_sse/repository/session_repository.py +30 -26
- solace_agent_mesh/gateway/http_sse/repository/task_repository.py +35 -44
- solace_agent_mesh/gateway/http_sse/routers/agent_cards.py +4 -3
- solace_agent_mesh/gateway/http_sse/routers/artifacts.py +95 -203
- solace_agent_mesh/gateway/http_sse/routers/dto/responses/session_responses.py +4 -3
- solace_agent_mesh/gateway/http_sse/routers/sessions.py +2 -2
- solace_agent_mesh/gateway/http_sse/routers/tasks.py +33 -41
- solace_agent_mesh/gateway/http_sse/routers/users.py +47 -1
- solace_agent_mesh/gateway/http_sse/routers/visualization.py +17 -11
- solace_agent_mesh/gateway/http_sse/services/data_retention_service.py +4 -4
- solace_agent_mesh/gateway/http_sse/services/feedback_service.py +51 -43
- solace_agent_mesh/gateway/http_sse/services/session_service.py +20 -20
- solace_agent_mesh/gateway/http_sse/services/task_logger_service.py +8 -8
- solace_agent_mesh/gateway/http_sse/shared/base_repository.py +45 -71
- solace_agent_mesh/gateway/http_sse/shared/types.py +0 -18
- solace_agent_mesh/templates/gateway_config_template.yaml +0 -5
- solace_agent_mesh/templates/logging_config_template.ini +10 -6
- solace_agent_mesh/templates/plugin_gateway_config_template.yaml +0 -3
- solace_agent_mesh/templates/shared_config.yaml +40 -0
- {solace_agent_mesh-1.5.1.dist-info → solace_agent_mesh-1.6.1.dist-info}/METADATA +47 -21
- {solace_agent_mesh-1.5.1.dist-info → solace_agent_mesh-1.6.1.dist-info}/RECORD +166 -145
- solace_agent_mesh/assets/docs/assets/js/5c2bd65f.e49689dd.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/6ad8f0bd.39d5851d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/71da7b71.804d6567.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/77cf947d.64c9bd6c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/9e9d0a82.dd810042.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/db924877.cbc66f02.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/de915948.139b4b9c.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/e6f9706b.582a78ca.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/f284c35a.5766a13d.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/ff4d71f2.9c0297a6.js +0 -1
- solace_agent_mesh/assets/docs/assets/js/runtime~main.18dc45dd.js +0 -1
- solace_agent_mesh/assets/docs/lunr-index-1760121512891.json +0 -1
- solace_agent_mesh/assets/docs/search-doc-1760121512891.json +0 -1
- solace_agent_mesh/client/webui/frontend/static/assets/main-2nd1gbaH.js +0 -339
- solace_agent_mesh/client/webui/frontend/static/assets/main-DoKXctCM.css +0 -1
- solace_agent_mesh/config_portal/frontend/static/client/assets/_index-BNuqpWDc.js +0 -98
- solace_agent_mesh/evaluation/config_loader.py +0 -657
- solace_agent_mesh/evaluation/test_case_loader.py +0 -714
- /solace_agent_mesh/assets/docs/assets/js/{main.bd3c34f3.js.LICENSE.txt → main.b12eac43.js.LICENSE.txt} +0 -0
- {solace_agent_mesh-1.5.1.dist-info → solace_agent_mesh-1.6.1.dist-info}/WHEEL +0 -0
- {solace_agent_mesh-1.5.1.dist-info → solace_agent_mesh-1.6.1.dist-info}/entry_points.txt +0 -0
- {solace_agent_mesh-1.5.1.dist-info → solace_agent_mesh-1.6.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,27 +5,23 @@ This module generates HTML reports from evaluation results with a clean, modular
|
|
|
5
5
|
|
|
6
6
|
import json
|
|
7
7
|
import logging
|
|
8
|
-
from datetime import datetime
|
|
9
8
|
from dataclasses import dataclass, field
|
|
10
|
-
from
|
|
9
|
+
from datetime import datetime
|
|
11
10
|
from pathlib import Path
|
|
12
11
|
|
|
13
|
-
# Set up logging
|
|
14
|
-
logging.basicConfig(level=logging.INFO)
|
|
15
|
-
logger = logging.getLogger(__name__)
|
|
16
|
-
|
|
17
|
-
# Import configuration and data services
|
|
18
|
-
from .config_loader import ConfigLoader
|
|
19
12
|
from .report_data_processor import ReportDataProcessor
|
|
13
|
+
from .shared import EvaluationConfigLoader, TestSuiteConfiguration
|
|
14
|
+
|
|
15
|
+
log = logging.getLogger(__name__)
|
|
20
16
|
|
|
21
17
|
|
|
22
18
|
@dataclass
|
|
23
19
|
class ReportConfig:
|
|
24
20
|
"""Centralized configuration for report generation."""
|
|
25
21
|
|
|
26
|
-
def __init__(self,
|
|
27
|
-
self.
|
|
28
|
-
self.results_dir_name =
|
|
22
|
+
def __init__(self, config: TestSuiteConfiguration, results_dir: Path):
|
|
23
|
+
self.config = config
|
|
24
|
+
self.results_dir_name = config.results_directory
|
|
29
25
|
|
|
30
26
|
# Calculate paths
|
|
31
27
|
self.script_dir = Path(__file__).parent
|
|
@@ -78,19 +74,19 @@ class ConfigurationService:
|
|
|
78
74
|
"""Handles configuration loading and validation."""
|
|
79
75
|
|
|
80
76
|
def __init__(self, config_path: str):
|
|
81
|
-
self.config_loader =
|
|
77
|
+
self.config_loader = EvaluationConfigLoader(config_path)
|
|
82
78
|
self._config_cache = None
|
|
83
79
|
|
|
84
|
-
def get_config(self) ->
|
|
80
|
+
def get_config(self) -> TestSuiteConfiguration:
|
|
85
81
|
"""Get the main configuration."""
|
|
86
82
|
if self._config_cache is None:
|
|
87
|
-
self._config_cache = self.config_loader.
|
|
83
|
+
self._config_cache = self.config_loader.load_configuration()
|
|
88
84
|
return self._config_cache
|
|
89
85
|
|
|
90
86
|
def create_report_config(self, results_dir: Path) -> ReportConfig:
|
|
91
87
|
"""Create a ReportConfig instance."""
|
|
92
|
-
|
|
93
|
-
return ReportConfig(
|
|
88
|
+
config = self.get_config()
|
|
89
|
+
return ReportConfig(config, results_dir)
|
|
94
90
|
|
|
95
91
|
|
|
96
92
|
class FileService:
|
|
@@ -100,13 +96,12 @@ class FileService:
|
|
|
100
96
|
def read_file(filepath: Path, encoding: str = "utf-8") -> str:
|
|
101
97
|
"""Read file content with error handling."""
|
|
102
98
|
try:
|
|
103
|
-
|
|
104
|
-
return f.read()
|
|
99
|
+
return filepath.read_text(encoding=encoding)
|
|
105
100
|
except FileNotFoundError:
|
|
106
|
-
|
|
101
|
+
log.error(f"File not found: {filepath}")
|
|
107
102
|
raise
|
|
108
103
|
except Exception as e:
|
|
109
|
-
|
|
104
|
+
log.error(f"Error reading file {filepath}: {e}")
|
|
110
105
|
raise
|
|
111
106
|
|
|
112
107
|
@staticmethod
|
|
@@ -116,11 +111,10 @@ class FileService:
|
|
|
116
111
|
# Ensure directory exists
|
|
117
112
|
filepath.parent.mkdir(parents=True, exist_ok=True)
|
|
118
113
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
logger.info(f"File written successfully: {filepath}")
|
|
114
|
+
filepath.write_text(content, encoding=encoding)
|
|
115
|
+
log.info(f"File written successfully: {filepath}")
|
|
122
116
|
except Exception as e:
|
|
123
|
-
|
|
117
|
+
log.error(f"Error writing file {filepath}: {e}")
|
|
124
118
|
raise
|
|
125
119
|
|
|
126
120
|
@staticmethod
|
|
@@ -138,20 +132,20 @@ class TemplateService:
|
|
|
138
132
|
def load_template(self, template_path: Path) -> str:
|
|
139
133
|
"""Load a single template file."""
|
|
140
134
|
if not self.file_service.file_exists(template_path):
|
|
141
|
-
|
|
135
|
+
log.warning(f"Template file not found: {template_path}")
|
|
142
136
|
return ""
|
|
143
137
|
|
|
144
138
|
try:
|
|
145
139
|
content = self.file_service.read_file(template_path)
|
|
146
|
-
|
|
140
|
+
log.debug(f"Loaded template: {template_path}")
|
|
147
141
|
return content
|
|
148
142
|
except Exception as e:
|
|
149
|
-
|
|
143
|
+
log.error(f"Failed to load template {template_path}: {e}")
|
|
150
144
|
return ""
|
|
151
145
|
|
|
152
146
|
def load_all_templates(self, config: ReportConfig) -> TemplateAssets:
|
|
153
147
|
"""Load all required templates including modal components."""
|
|
154
|
-
|
|
148
|
+
log.info("Loading HTML templates and modal components...")
|
|
155
149
|
|
|
156
150
|
assets = TemplateAssets()
|
|
157
151
|
|
|
@@ -170,7 +164,7 @@ class TemplateService:
|
|
|
170
164
|
content = self.load_template(template_path)
|
|
171
165
|
setattr(assets, template_name, content)
|
|
172
166
|
|
|
173
|
-
|
|
167
|
+
log.info(f"Loaded {len(template_files)} templates")
|
|
174
168
|
return assets
|
|
175
169
|
|
|
176
170
|
|
|
@@ -185,38 +179,38 @@ class AssetService:
|
|
|
185
179
|
css_path = report_dir / "performance_metrics_styles.css"
|
|
186
180
|
|
|
187
181
|
if not self.file_service.file_exists(css_path):
|
|
188
|
-
|
|
182
|
+
log.warning(f"CSS file not found: {css_path}")
|
|
189
183
|
return ""
|
|
190
184
|
|
|
191
185
|
try:
|
|
192
186
|
content = self.file_service.read_file(css_path)
|
|
193
|
-
|
|
187
|
+
log.info(f"Loaded CSS content from: {css_path}")
|
|
194
188
|
return content
|
|
195
189
|
except Exception as e:
|
|
196
|
-
|
|
190
|
+
log.error(f"Failed to load CSS content: {e}")
|
|
197
191
|
return ""
|
|
198
192
|
|
|
199
193
|
def load_modal_assets(self, report_dir: Path, assets: TemplateAssets):
|
|
200
194
|
"""Load modal CSS and JavaScript files."""
|
|
201
|
-
|
|
195
|
+
log.info("Loading modal assets...")
|
|
202
196
|
|
|
203
197
|
# Load modal CSS
|
|
204
198
|
modal_css_path = report_dir / "modal_styles.css"
|
|
205
199
|
if self.file_service.file_exists(modal_css_path):
|
|
206
200
|
try:
|
|
207
201
|
assets.modal_css = self.file_service.read_file(modal_css_path)
|
|
208
|
-
|
|
202
|
+
log.info("Loaded modal CSS")
|
|
209
203
|
except Exception as e:
|
|
210
|
-
|
|
204
|
+
log.error(f"Failed to load modal CSS: {e}")
|
|
211
205
|
|
|
212
206
|
# Load modal JavaScript files
|
|
213
207
|
modal_script_path = report_dir / "modal_script.js"
|
|
214
208
|
if self.file_service.file_exists(modal_script_path):
|
|
215
209
|
try:
|
|
216
210
|
assets.modal_script_js = self.file_service.read_file(modal_script_path)
|
|
217
|
-
|
|
211
|
+
log.info("Loaded modal script JS")
|
|
218
212
|
except Exception as e:
|
|
219
|
-
|
|
213
|
+
log.error(f"Failed to load modal script JS: {e}")
|
|
220
214
|
|
|
221
215
|
modal_chart_functions_path = report_dir / "modal_chart_functions.js"
|
|
222
216
|
if self.file_service.file_exists(modal_chart_functions_path):
|
|
@@ -224,18 +218,18 @@ class AssetService:
|
|
|
224
218
|
assets.modal_chart_functions_js = self.file_service.read_file(
|
|
225
219
|
modal_chart_functions_path
|
|
226
220
|
)
|
|
227
|
-
|
|
221
|
+
log.info("Loaded modal chart functions JS")
|
|
228
222
|
except Exception as e:
|
|
229
|
-
|
|
223
|
+
log.error(f"Failed to load modal chart functions JS: {e}")
|
|
230
224
|
|
|
231
|
-
|
|
225
|
+
log.info("Modal assets loaded successfully")
|
|
232
226
|
|
|
233
227
|
|
|
234
228
|
class TemplateProcessor:
|
|
235
229
|
"""Handles template rendering and placeholder replacement."""
|
|
236
230
|
|
|
237
231
|
@staticmethod
|
|
238
|
-
def replace_placeholders(template_content: str, data:
|
|
232
|
+
def replace_placeholders(template_content: str, data: dict[str, any]) -> str:
|
|
239
233
|
"""Replace placeholders in template with actual data."""
|
|
240
234
|
try:
|
|
241
235
|
# Convert all values to strings for replacement
|
|
@@ -264,15 +258,15 @@ class TemplateProcessor:
|
|
|
264
258
|
return processed_content
|
|
265
259
|
|
|
266
260
|
except Exception as e:
|
|
267
|
-
|
|
261
|
+
log.error(f"Error replacing placeholders: {e}")
|
|
268
262
|
return template_content
|
|
269
263
|
|
|
270
264
|
def process_template_with_data(
|
|
271
|
-
self, template_content: str, data:
|
|
265
|
+
self, template_content: str, data: dict[str, any]
|
|
272
266
|
) -> str:
|
|
273
267
|
"""Process a template with evaluation data."""
|
|
274
268
|
if not template_content:
|
|
275
|
-
|
|
269
|
+
log.warning("Empty template content provided")
|
|
276
270
|
return ""
|
|
277
271
|
|
|
278
272
|
return self.replace_placeholders(template_content, data)
|
|
@@ -295,11 +289,11 @@ class CSSProcessor:
|
|
|
295
289
|
inline_css_block = f"<style>\n{css_content}\n</style>"
|
|
296
290
|
|
|
297
291
|
processed_html = html_content.replace(css_link_pattern, inline_css_block)
|
|
298
|
-
|
|
292
|
+
log.debug("CSS content inlined successfully")
|
|
299
293
|
return processed_html
|
|
300
294
|
|
|
301
295
|
except Exception as e:
|
|
302
|
-
|
|
296
|
+
log.error(f"Error inlining CSS: {e}")
|
|
303
297
|
return html_content
|
|
304
298
|
|
|
305
299
|
@staticmethod
|
|
@@ -380,11 +374,11 @@ class CSSProcessor:
|
|
|
380
374
|
# Fallback: append to end
|
|
381
375
|
processed_html += modal_content
|
|
382
376
|
|
|
383
|
-
|
|
377
|
+
log.debug("Modal assets inlined successfully")
|
|
384
378
|
return processed_html
|
|
385
379
|
|
|
386
380
|
except Exception as e:
|
|
387
|
-
|
|
381
|
+
log.error(f"Error inlining modal assets: {e}")
|
|
388
382
|
return html_content
|
|
389
383
|
|
|
390
384
|
|
|
@@ -400,11 +394,11 @@ class HTMLAssembler:
|
|
|
400
394
|
def assemble_report(
|
|
401
395
|
self,
|
|
402
396
|
assets: TemplateAssets,
|
|
403
|
-
evaluation_data:
|
|
404
|
-
detailed_data:
|
|
397
|
+
evaluation_data: dict[str, any],
|
|
398
|
+
detailed_data: dict[str, any],
|
|
405
399
|
) -> str:
|
|
406
400
|
"""Assemble the complete HTML report with modal functionality."""
|
|
407
|
-
|
|
401
|
+
log.info("Assembling HTML report with modal functionality...")
|
|
408
402
|
|
|
409
403
|
try:
|
|
410
404
|
# Process each template with appropriate data
|
|
@@ -447,11 +441,11 @@ class HTMLAssembler:
|
|
|
447
441
|
# Inline CSS and modal assets into the complete HTML
|
|
448
442
|
final_html = self.css_processor.inline_modal_assets(final_html, assets)
|
|
449
443
|
|
|
450
|
-
|
|
444
|
+
log.info("HTML report with modal functionality assembled successfully")
|
|
451
445
|
return final_html
|
|
452
446
|
|
|
453
447
|
except Exception as e:
|
|
454
|
-
|
|
448
|
+
log.error(f"Error assembling HTML report: {e}")
|
|
455
449
|
raise
|
|
456
450
|
|
|
457
451
|
|
|
@@ -460,8 +454,8 @@ class ReportSummaryService:
|
|
|
460
454
|
|
|
461
455
|
@staticmethod
|
|
462
456
|
def generate_summary(
|
|
463
|
-
evaluation_data:
|
|
464
|
-
) ->
|
|
457
|
+
evaluation_data: dict[str, any], output_path: Path
|
|
458
|
+
) -> dict[str, str]:
|
|
465
459
|
"""Generate summary information for logging."""
|
|
466
460
|
models = evaluation_data.get("models", [])
|
|
467
461
|
execution_time = evaluation_data.get(
|
|
@@ -496,7 +490,7 @@ class ReportGenerator:
|
|
|
496
490
|
|
|
497
491
|
def generate_report(self, results_dir: Path):
|
|
498
492
|
"""Main entry point for report generation."""
|
|
499
|
-
|
|
493
|
+
log.info("--- Starting HTML report generation ---")
|
|
500
494
|
|
|
501
495
|
try:
|
|
502
496
|
# Load configuration
|
|
@@ -519,22 +513,22 @@ class ReportGenerator:
|
|
|
519
513
|
# Generate and log summary
|
|
520
514
|
self._log_summary(evaluation_data, config.output_path)
|
|
521
515
|
|
|
522
|
-
|
|
516
|
+
log.info("--- HTML report generation completed successfully ---")
|
|
523
517
|
|
|
524
518
|
except Exception as e:
|
|
525
|
-
|
|
519
|
+
log.error(f"Report generation failed: {e}")
|
|
526
520
|
raise
|
|
527
521
|
|
|
528
522
|
def _load_configuration(self, results_dir: Path) -> ReportConfig:
|
|
529
523
|
"""Load and validate configuration."""
|
|
530
|
-
|
|
524
|
+
log.info("Loading configuration...")
|
|
531
525
|
config = self.config_service.create_report_config(results_dir)
|
|
532
|
-
|
|
526
|
+
log.info(f"Configuration loaded. Results directory: {config.results_dir}")
|
|
533
527
|
return config
|
|
534
528
|
|
|
535
529
|
def _load_assets(self, config: ReportConfig) -> TemplateAssets:
|
|
536
530
|
"""Load all templates and assets including modal components."""
|
|
537
|
-
|
|
531
|
+
log.info("Loading templates and assets...")
|
|
538
532
|
|
|
539
533
|
# Load templates
|
|
540
534
|
assets = self.template_service.load_all_templates(config)
|
|
@@ -545,53 +539,53 @@ class ReportGenerator:
|
|
|
545
539
|
# Load modal assets
|
|
546
540
|
self.asset_service.load_modal_assets(config.report_dir, assets)
|
|
547
541
|
|
|
548
|
-
|
|
542
|
+
log.info("Templates and assets loaded successfully")
|
|
549
543
|
return assets
|
|
550
544
|
|
|
551
545
|
def _get_evaluation_data(
|
|
552
546
|
self, config: ReportConfig
|
|
553
|
-
) -> tuple[
|
|
547
|
+
) -> tuple[dict[str, any], dict[str, any]]:
|
|
554
548
|
"""Get evaluation data from the data processor."""
|
|
555
|
-
|
|
549
|
+
log.info("Extracting evaluation data...")
|
|
556
550
|
|
|
557
551
|
evaluation_data = self.data_processor.get_evaluation_data(config.results_dir)
|
|
558
552
|
detailed_data = self.data_processor.get_detailed_evaluation_data(
|
|
559
553
|
config.results_dir
|
|
560
554
|
)
|
|
561
555
|
|
|
562
|
-
|
|
556
|
+
log.info("Evaluation data extracted successfully")
|
|
563
557
|
return evaluation_data, detailed_data
|
|
564
558
|
|
|
565
559
|
def _generate_html_content(
|
|
566
560
|
self,
|
|
567
561
|
assets: TemplateAssets,
|
|
568
|
-
evaluation_data:
|
|
569
|
-
detailed_data:
|
|
562
|
+
evaluation_data: dict[str, any],
|
|
563
|
+
detailed_data: dict[str, any],
|
|
570
564
|
) -> str:
|
|
571
565
|
"""Generate the complete HTML content."""
|
|
572
|
-
|
|
566
|
+
log.info("Generating HTML content...")
|
|
573
567
|
|
|
574
568
|
html_content = self.html_assembler.assemble_report(
|
|
575
569
|
assets, evaluation_data, detailed_data
|
|
576
570
|
)
|
|
577
571
|
|
|
578
|
-
|
|
572
|
+
log.info("HTML content generated successfully")
|
|
579
573
|
return html_content
|
|
580
574
|
|
|
581
575
|
def _write_report(self, html_content: str, output_path: Path):
|
|
582
576
|
"""Write the HTML report to file."""
|
|
583
|
-
|
|
577
|
+
log.info(f"Writing report to: {output_path}")
|
|
584
578
|
self.file_service.write_file(output_path, html_content)
|
|
585
579
|
|
|
586
|
-
def _log_summary(self, evaluation_data:
|
|
580
|
+
def _log_summary(self, evaluation_data: dict[str, any], output_path: Path):
|
|
587
581
|
"""Log summary information about the generated report."""
|
|
588
582
|
summary = self.summary_service.generate_summary(evaluation_data, output_path)
|
|
589
583
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
584
|
+
log.info("--- Report Generation Summary ---")
|
|
585
|
+
log.info(f"Report generated at: {summary['output_path']}")
|
|
586
|
+
log.info(f"Models evaluated: {summary['models_evaluated']}")
|
|
587
|
+
log.info(f"Total execution time: {summary['total_execution_time']}")
|
|
588
|
+
log.info(f"Generation completed at: {summary['generation_time']}")
|
|
595
589
|
|
|
596
590
|
|
|
597
591
|
def main(config_path: str = "evaluation/test_suite_config.json"):
|
|
@@ -599,13 +593,13 @@ def main(config_path: str = "evaluation/test_suite_config.json"):
|
|
|
599
593
|
try:
|
|
600
594
|
generator = ReportGenerator(config_path)
|
|
601
595
|
# For standalone execution, calculate results_dir based on config
|
|
602
|
-
|
|
603
|
-
results_dir_name =
|
|
596
|
+
config = generator.config_service.get_config()
|
|
597
|
+
results_dir_name = config.results_directory
|
|
604
598
|
script_dir = Path(__file__).parent
|
|
605
599
|
results_dir = script_dir / "results" / results_dir_name
|
|
606
600
|
generator.generate_report(results_dir)
|
|
607
601
|
except Exception as e:
|
|
608
|
-
|
|
602
|
+
log.error(f"Report generation failed: {e}")
|
|
609
603
|
raise
|
|
610
604
|
|
|
611
605
|
|