empathy-framework 2.4.0__py3-none-any.whl → 3.8.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.
- coach_wizards/__init__.py +13 -12
- coach_wizards/accessibility_wizard.py +12 -12
- coach_wizards/api_wizard.py +12 -12
- coach_wizards/base_wizard.py +26 -20
- coach_wizards/cicd_wizard.py +15 -13
- coach_wizards/code_reviewer_README.md +60 -0
- coach_wizards/code_reviewer_wizard.py +180 -0
- coach_wizards/compliance_wizard.py +12 -12
- coach_wizards/database_wizard.py +12 -12
- coach_wizards/debugging_wizard.py +12 -12
- coach_wizards/documentation_wizard.py +12 -12
- coach_wizards/generate_wizards.py +1 -2
- coach_wizards/localization_wizard.py +101 -19
- coach_wizards/migration_wizard.py +12 -12
- coach_wizards/monitoring_wizard.py +12 -12
- coach_wizards/observability_wizard.py +12 -12
- coach_wizards/performance_wizard.py +12 -12
- coach_wizards/prompt_engineering_wizard.py +661 -0
- coach_wizards/refactoring_wizard.py +12 -12
- coach_wizards/scaling_wizard.py +12 -12
- coach_wizards/security_wizard.py +12 -12
- coach_wizards/testing_wizard.py +12 -12
- empathy_framework-3.8.2.dist-info/METADATA +1176 -0
- empathy_framework-3.8.2.dist-info/RECORD +333 -0
- empathy_framework-3.8.2.dist-info/entry_points.txt +22 -0
- {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/top_level.txt +5 -1
- empathy_healthcare_plugin/__init__.py +1 -2
- empathy_healthcare_plugin/monitors/__init__.py +9 -0
- empathy_healthcare_plugin/monitors/clinical_protocol_monitor.py +315 -0
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +44 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_checker.py +300 -0
- empathy_healthcare_plugin/monitors/monitoring/protocol_loader.py +214 -0
- empathy_healthcare_plugin/monitors/monitoring/sensor_parsers.py +306 -0
- empathy_healthcare_plugin/monitors/monitoring/trajectory_analyzer.py +389 -0
- empathy_llm_toolkit/__init__.py +7 -7
- empathy_llm_toolkit/agent_factory/__init__.py +53 -0
- empathy_llm_toolkit/agent_factory/adapters/__init__.py +85 -0
- empathy_llm_toolkit/agent_factory/adapters/autogen_adapter.py +312 -0
- empathy_llm_toolkit/agent_factory/adapters/crewai_adapter.py +454 -0
- empathy_llm_toolkit/agent_factory/adapters/haystack_adapter.py +298 -0
- empathy_llm_toolkit/agent_factory/adapters/langchain_adapter.py +362 -0
- empathy_llm_toolkit/agent_factory/adapters/langgraph_adapter.py +333 -0
- empathy_llm_toolkit/agent_factory/adapters/native.py +228 -0
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +426 -0
- empathy_llm_toolkit/agent_factory/base.py +305 -0
- empathy_llm_toolkit/agent_factory/crews/__init__.py +67 -0
- empathy_llm_toolkit/agent_factory/crews/code_review.py +1113 -0
- empathy_llm_toolkit/agent_factory/crews/health_check.py +1246 -0
- empathy_llm_toolkit/agent_factory/crews/refactoring.py +1128 -0
- empathy_llm_toolkit/agent_factory/crews/security_audit.py +1018 -0
- empathy_llm_toolkit/agent_factory/decorators.py +286 -0
- empathy_llm_toolkit/agent_factory/factory.py +558 -0
- empathy_llm_toolkit/agent_factory/framework.py +192 -0
- empathy_llm_toolkit/agent_factory/memory_integration.py +324 -0
- empathy_llm_toolkit/agent_factory/resilient.py +320 -0
- empathy_llm_toolkit/claude_memory.py +14 -15
- empathy_llm_toolkit/cli/__init__.py +8 -0
- empathy_llm_toolkit/cli/sync_claude.py +487 -0
- empathy_llm_toolkit/code_health.py +186 -28
- empathy_llm_toolkit/config/__init__.py +29 -0
- empathy_llm_toolkit/config/unified.py +295 -0
- empathy_llm_toolkit/contextual_patterns.py +11 -12
- empathy_llm_toolkit/core.py +168 -53
- empathy_llm_toolkit/git_pattern_extractor.py +17 -13
- empathy_llm_toolkit/levels.py +6 -13
- empathy_llm_toolkit/pattern_confidence.py +14 -18
- empathy_llm_toolkit/pattern_resolver.py +10 -12
- empathy_llm_toolkit/pattern_summary.py +16 -14
- empathy_llm_toolkit/providers.py +194 -28
- empathy_llm_toolkit/routing/__init__.py +32 -0
- empathy_llm_toolkit/routing/model_router.py +362 -0
- empathy_llm_toolkit/security/IMPLEMENTATION_SUMMARY.md +413 -0
- empathy_llm_toolkit/security/PHASE2_COMPLETE.md +384 -0
- empathy_llm_toolkit/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- empathy_llm_toolkit/security/QUICK_REFERENCE.md +316 -0
- empathy_llm_toolkit/security/README.md +262 -0
- empathy_llm_toolkit/security/__init__.py +62 -0
- empathy_llm_toolkit/security/audit_logger.py +929 -0
- empathy_llm_toolkit/security/audit_logger_example.py +152 -0
- empathy_llm_toolkit/security/pii_scrubber.py +640 -0
- empathy_llm_toolkit/security/secrets_detector.py +678 -0
- empathy_llm_toolkit/security/secrets_detector_example.py +304 -0
- empathy_llm_toolkit/security/secure_memdocs.py +1192 -0
- empathy_llm_toolkit/security/secure_memdocs_example.py +278 -0
- empathy_llm_toolkit/session_status.py +20 -22
- empathy_llm_toolkit/state.py +28 -21
- empathy_llm_toolkit/wizards/__init__.py +38 -0
- empathy_llm_toolkit/wizards/base_wizard.py +364 -0
- empathy_llm_toolkit/wizards/customer_support_wizard.py +190 -0
- empathy_llm_toolkit/wizards/healthcare_wizard.py +362 -0
- empathy_llm_toolkit/wizards/patient_assessment_README.md +64 -0
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +193 -0
- empathy_llm_toolkit/wizards/technology_wizard.py +194 -0
- empathy_os/__init__.py +125 -84
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/{monitoring.py → agent_monitoring.py} +28 -28
- empathy_os/cache/__init__.py +117 -0
- empathy_os/cache/base.py +166 -0
- empathy_os/cache/dependency_manager.py +253 -0
- empathy_os/cache/hash_only.py +248 -0
- empathy_os/cache/hybrid.py +390 -0
- empathy_os/cache/storage.py +282 -0
- empathy_os/cli.py +1516 -70
- empathy_os/cli_unified.py +597 -0
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/config.py +95 -37
- empathy_os/coordination.py +72 -68
- empathy_os/core.py +94 -107
- empathy_os/cost_tracker.py +74 -55
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/discovery.py +17 -14
- empathy_os/emergence.py +21 -22
- empathy_os/exceptions.py +18 -30
- empathy_os/feedback_loops.py +30 -33
- empathy_os/levels.py +32 -35
- empathy_os/leverage_points.py +31 -32
- empathy_os/logging_config.py +19 -16
- empathy_os/memory/__init__.py +195 -0
- empathy_os/memory/claude_memory.py +466 -0
- empathy_os/memory/config.py +224 -0
- empathy_os/memory/control_panel.py +1298 -0
- empathy_os/memory/edges.py +179 -0
- empathy_os/memory/graph.py +567 -0
- empathy_os/memory/long_term.py +1194 -0
- empathy_os/memory/nodes.py +179 -0
- empathy_os/memory/redis_bootstrap.py +540 -0
- empathy_os/memory/security/__init__.py +31 -0
- empathy_os/memory/security/audit_logger.py +930 -0
- empathy_os/memory/security/pii_scrubber.py +640 -0
- empathy_os/memory/security/secrets_detector.py +678 -0
- empathy_os/memory/short_term.py +2119 -0
- empathy_os/memory/storage/__init__.py +15 -0
- empathy_os/memory/summary_index.py +583 -0
- empathy_os/memory/unified.py +619 -0
- empathy_os/metrics/__init__.py +12 -0
- empathy_os/metrics/prompt_metrics.py +190 -0
- empathy_os/models/__init__.py +136 -0
- empathy_os/models/__main__.py +13 -0
- empathy_os/models/cli.py +655 -0
- empathy_os/models/empathy_executor.py +354 -0
- empathy_os/models/executor.py +252 -0
- empathy_os/models/fallback.py +671 -0
- empathy_os/models/provider_config.py +563 -0
- empathy_os/models/registry.py +382 -0
- empathy_os/models/tasks.py +302 -0
- empathy_os/models/telemetry.py +548 -0
- empathy_os/models/token_estimator.py +378 -0
- empathy_os/models/validation.py +274 -0
- empathy_os/monitoring/__init__.py +52 -0
- empathy_os/monitoring/alerts.py +23 -0
- empathy_os/monitoring/alerts_cli.py +268 -0
- empathy_os/monitoring/multi_backend.py +271 -0
- empathy_os/monitoring/otel_backend.py +363 -0
- empathy_os/optimization/__init__.py +19 -0
- empathy_os/optimization/context_optimizer.py +272 -0
- empathy_os/pattern_library.py +30 -29
- empathy_os/persistence.py +35 -37
- empathy_os/platform_utils.py +261 -0
- empathy_os/plugins/__init__.py +28 -0
- empathy_os/plugins/base.py +361 -0
- empathy_os/plugins/registry.py +268 -0
- empathy_os/project_index/__init__.py +30 -0
- empathy_os/project_index/cli.py +335 -0
- empathy_os/project_index/crew_integration.py +430 -0
- empathy_os/project_index/index.py +425 -0
- empathy_os/project_index/models.py +501 -0
- empathy_os/project_index/reports.py +473 -0
- empathy_os/project_index/scanner.py +538 -0
- empathy_os/prompts/__init__.py +61 -0
- empathy_os/prompts/config.py +77 -0
- empathy_os/prompts/context.py +177 -0
- empathy_os/prompts/parser.py +285 -0
- empathy_os/prompts/registry.py +313 -0
- empathy_os/prompts/templates.py +208 -0
- empathy_os/redis_config.py +144 -58
- empathy_os/redis_memory.py +79 -77
- empathy_os/resilience/__init__.py +56 -0
- empathy_os/resilience/circuit_breaker.py +256 -0
- empathy_os/resilience/fallback.py +179 -0
- empathy_os/resilience/health.py +300 -0
- empathy_os/resilience/retry.py +209 -0
- empathy_os/resilience/timeout.py +135 -0
- empathy_os/routing/__init__.py +43 -0
- empathy_os/routing/chain_executor.py +433 -0
- empathy_os/routing/classifier.py +217 -0
- empathy_os/routing/smart_router.py +234 -0
- empathy_os/routing/wizard_registry.py +307 -0
- empathy_os/templates.py +19 -14
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/trust_building.py +67 -58
- empathy_os/validation/__init__.py +19 -0
- empathy_os/validation/xml_validator.py +281 -0
- empathy_os/wizard_factory_cli.py +170 -0
- empathy_os/{workflows.py → workflow_commands.py} +131 -37
- empathy_os/workflows/__init__.py +360 -0
- empathy_os/workflows/base.py +1660 -0
- empathy_os/workflows/bug_predict.py +962 -0
- empathy_os/workflows/code_review.py +960 -0
- empathy_os/workflows/code_review_adapters.py +310 -0
- empathy_os/workflows/code_review_pipeline.py +720 -0
- empathy_os/workflows/config.py +600 -0
- empathy_os/workflows/dependency_check.py +648 -0
- empathy_os/workflows/document_gen.py +1069 -0
- empathy_os/workflows/documentation_orchestrator.py +1205 -0
- empathy_os/workflows/health_check.py +679 -0
- empathy_os/workflows/keyboard_shortcuts/__init__.py +39 -0
- empathy_os/workflows/keyboard_shortcuts/generators.py +386 -0
- empathy_os/workflows/keyboard_shortcuts/parsers.py +414 -0
- empathy_os/workflows/keyboard_shortcuts/prompts.py +295 -0
- empathy_os/workflows/keyboard_shortcuts/schema.py +193 -0
- empathy_os/workflows/keyboard_shortcuts/workflow.py +505 -0
- empathy_os/workflows/manage_documentation.py +804 -0
- empathy_os/workflows/new_sample_workflow1.py +146 -0
- empathy_os/workflows/new_sample_workflow1_README.md +150 -0
- empathy_os/workflows/perf_audit.py +687 -0
- empathy_os/workflows/pr_review.py +748 -0
- empathy_os/workflows/progress.py +445 -0
- empathy_os/workflows/progress_server.py +322 -0
- empathy_os/workflows/refactor_plan.py +693 -0
- empathy_os/workflows/release_prep.py +808 -0
- empathy_os/workflows/research_synthesis.py +404 -0
- empathy_os/workflows/secure_release.py +585 -0
- empathy_os/workflows/security_adapters.py +297 -0
- empathy_os/workflows/security_audit.py +1046 -0
- empathy_os/workflows/step_config.py +234 -0
- empathy_os/workflows/test5.py +125 -0
- empathy_os/workflows/test5_README.md +158 -0
- empathy_os/workflows/test_gen.py +1855 -0
- empathy_os/workflows/test_lifecycle.py +526 -0
- empathy_os/workflows/test_maintenance.py +626 -0
- empathy_os/workflows/test_maintenance_cli.py +590 -0
- empathy_os/workflows/test_maintenance_crew.py +821 -0
- empathy_os/workflows/xml_enhanced_crew.py +285 -0
- empathy_software_plugin/__init__.py +1 -2
- empathy_software_plugin/cli/__init__.py +120 -0
- empathy_software_plugin/cli/inspect.py +362 -0
- empathy_software_plugin/cli.py +49 -27
- empathy_software_plugin/plugin.py +4 -8
- empathy_software_plugin/wizards/__init__.py +42 -0
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +392 -0
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +511 -0
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +503 -0
- empathy_software_plugin/wizards/ai_context_wizard.py +441 -0
- empathy_software_plugin/wizards/ai_documentation_wizard.py +503 -0
- empathy_software_plugin/wizards/base_wizard.py +288 -0
- empathy_software_plugin/wizards/book_chapter_wizard.py +519 -0
- empathy_software_plugin/wizards/code_review_wizard.py +606 -0
- empathy_software_plugin/wizards/debugging/__init__.py +50 -0
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +414 -0
- empathy_software_plugin/wizards/debugging/config_loaders.py +442 -0
- empathy_software_plugin/wizards/debugging/fix_applier.py +469 -0
- empathy_software_plugin/wizards/debugging/language_patterns.py +383 -0
- empathy_software_plugin/wizards/debugging/linter_parsers.py +470 -0
- empathy_software_plugin/wizards/debugging/verification.py +369 -0
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +537 -0
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +816 -0
- empathy_software_plugin/wizards/multi_model_wizard.py +501 -0
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +422 -0
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +400 -0
- empathy_software_plugin/wizards/performance/__init__.py +9 -0
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +221 -0
- empathy_software_plugin/wizards/performance/profiler_parsers.py +278 -0
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +429 -0
- empathy_software_plugin/wizards/performance_profiling_wizard.py +305 -0
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +425 -0
- empathy_software_plugin/wizards/rag_pattern_wizard.py +461 -0
- empathy_software_plugin/wizards/security/__init__.py +32 -0
- empathy_software_plugin/wizards/security/exploit_analyzer.py +290 -0
- empathy_software_plugin/wizards/security/owasp_patterns.py +241 -0
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +604 -0
- empathy_software_plugin/wizards/security_analysis_wizard.py +322 -0
- empathy_software_plugin/wizards/security_learning_wizard.py +740 -0
- empathy_software_plugin/wizards/tech_debt_wizard.py +726 -0
- empathy_software_plugin/wizards/testing/__init__.py +27 -0
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +459 -0
- empathy_software_plugin/wizards/testing/quality_analyzer.py +531 -0
- empathy_software_plugin/wizards/testing/test_suggester.py +533 -0
- empathy_software_plugin/wizards/testing_wizard.py +274 -0
- hot_reload/README.md +473 -0
- hot_reload/__init__.py +62 -0
- hot_reload/config.py +84 -0
- hot_reload/integration.py +228 -0
- hot_reload/reloader.py +298 -0
- hot_reload/watcher.py +179 -0
- hot_reload/websocket.py +176 -0
- scaffolding/README.md +589 -0
- scaffolding/__init__.py +35 -0
- scaffolding/__main__.py +14 -0
- scaffolding/cli.py +240 -0
- test_generator/__init__.py +38 -0
- test_generator/__main__.py +14 -0
- test_generator/cli.py +226 -0
- test_generator/generator.py +325 -0
- test_generator/risk_analyzer.py +216 -0
- workflow_patterns/__init__.py +33 -0
- workflow_patterns/behavior.py +249 -0
- workflow_patterns/core.py +76 -0
- workflow_patterns/output.py +99 -0
- workflow_patterns/registry.py +255 -0
- workflow_patterns/structural.py +288 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
- agents/code_inspection/patterns/inspection/recurring_B112.json +0 -18
- agents/code_inspection/patterns/inspection/recurring_F541.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_FORMAT.json +0 -25
- agents/code_inspection/patterns/inspection/recurring_bug_20250822_def456.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20250915_abc123.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_3c5b9951.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_97c0f72f.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a0871d53.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_20251212_a9b6ec41.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_bug_null_001.json +0 -16
- agents/code_inspection/patterns/inspection/recurring_builtin.json +0 -16
- agents/compliance_anticipation_agent.py +0 -1427
- agents/epic_integration_wizard.py +0 -541
- agents/trust_building_behaviors.py +0 -891
- empathy_framework-2.4.0.dist-info/METADATA +0 -485
- empathy_framework-2.4.0.dist-info/RECORD +0 -102
- empathy_framework-2.4.0.dist-info/entry_points.txt +0 -6
- empathy_llm_toolkit/htmlcov/status.json +0 -1
- empathy_llm_toolkit/security/htmlcov/status.json +0 -1
- {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/WHEEL +0 -0
- {empathy_framework-2.4.0.dist-info → empathy_framework-3.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Code Health Assistant Module
|
|
1
|
+
"""Code Health Assistant Module
|
|
3
2
|
|
|
4
3
|
A comprehensive system for running health checks, tracking trends,
|
|
5
4
|
and auto-fixing common issues in codebases.
|
|
@@ -10,6 +9,7 @@ Licensed under Fair Source 0.9
|
|
|
10
9
|
|
|
11
10
|
import asyncio
|
|
12
11
|
import json
|
|
12
|
+
import logging
|
|
13
13
|
import shutil
|
|
14
14
|
import subprocess
|
|
15
15
|
from dataclasses import dataclass, field
|
|
@@ -18,6 +18,8 @@ from enum import Enum
|
|
|
18
18
|
from pathlib import Path
|
|
19
19
|
from typing import Any
|
|
20
20
|
|
|
21
|
+
logger = logging.getLogger(__name__)
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
class HealthStatus(Enum):
|
|
23
25
|
"""Health check result status."""
|
|
@@ -224,12 +226,12 @@ class HealthCheckRunner:
|
|
|
224
226
|
project_root: str = ".",
|
|
225
227
|
config: dict | None = None,
|
|
226
228
|
):
|
|
227
|
-
"""
|
|
228
|
-
Initialize the health check runner.
|
|
229
|
+
"""Initialize the health check runner.
|
|
229
230
|
|
|
230
231
|
Args:
|
|
231
232
|
project_root: Root directory of the project
|
|
232
233
|
config: Configuration dictionary (uses defaults if not provided)
|
|
234
|
+
|
|
233
235
|
"""
|
|
234
236
|
self.project_root = Path(project_root).resolve()
|
|
235
237
|
self.config = {**DEFAULT_CONFIG, **(config or {})}
|
|
@@ -312,13 +314,23 @@ class HealthCheckRunner:
|
|
|
312
314
|
handler,
|
|
313
315
|
config: dict,
|
|
314
316
|
) -> CheckResult:
|
|
315
|
-
"""Run a check handler asynchronously.
|
|
317
|
+
"""Run a check handler asynchronously.
|
|
318
|
+
|
|
319
|
+
This uses broad exception handling intentionally for graceful degradation.
|
|
320
|
+
Health checks are optional features - the system should continue even if some checks fail.
|
|
321
|
+
|
|
322
|
+
Note:
|
|
323
|
+
Full exception context is preserved via logger.exception() for debugging.
|
|
324
|
+
"""
|
|
316
325
|
start_time = datetime.now()
|
|
317
326
|
try:
|
|
318
327
|
result: CheckResult = await asyncio.to_thread(handler, config)
|
|
319
328
|
result.duration_ms = int((datetime.now() - start_time).total_seconds() * 1000)
|
|
320
329
|
return result
|
|
321
330
|
except Exception as e:
|
|
331
|
+
# INTENTIONAL: Broad exception handler for graceful degradation of optional checks
|
|
332
|
+
# Full traceback preserved for debugging
|
|
333
|
+
logger.exception(f"Health check failed for {category.value}: {e}")
|
|
322
334
|
return CheckResult(
|
|
323
335
|
category=category,
|
|
324
336
|
status=HealthStatus.ERROR,
|
|
@@ -345,6 +357,7 @@ class HealthCheckRunner:
|
|
|
345
357
|
if tool == "ruff":
|
|
346
358
|
result = subprocess.run(
|
|
347
359
|
["ruff", "check", "--output-format=json", str(self.project_root)],
|
|
360
|
+
check=False,
|
|
348
361
|
capture_output=True,
|
|
349
362
|
text=True,
|
|
350
363
|
cwd=str(self.project_root),
|
|
@@ -364,12 +377,13 @@ class HealthCheckRunner:
|
|
|
364
377
|
),
|
|
365
378
|
fixable=item.get("fix") is not None,
|
|
366
379
|
fix_command="ruff check --fix" if item.get("fix") else None,
|
|
367
|
-
)
|
|
380
|
+
),
|
|
368
381
|
)
|
|
369
382
|
else:
|
|
370
383
|
# Fallback to flake8
|
|
371
384
|
result = subprocess.run(
|
|
372
385
|
["flake8", "--format=json", str(self.project_root)],
|
|
386
|
+
check=False,
|
|
373
387
|
capture_output=True,
|
|
374
388
|
text=True,
|
|
375
389
|
cwd=str(self.project_root),
|
|
@@ -389,7 +403,30 @@ class HealthCheckRunner:
|
|
|
389
403
|
details={"total_files_checked": len({i.file_path for i in issues}) or "all"},
|
|
390
404
|
)
|
|
391
405
|
|
|
406
|
+
except json.JSONDecodeError as e:
|
|
407
|
+
# Tool output not in expected JSON format
|
|
408
|
+
logger.warning(f"Lint check JSON parse error ({tool}): {e}")
|
|
409
|
+
return CheckResult(
|
|
410
|
+
category=CheckCategory.LINT,
|
|
411
|
+
status=HealthStatus.ERROR,
|
|
412
|
+
score=0,
|
|
413
|
+
tool_used=tool,
|
|
414
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
415
|
+
)
|
|
416
|
+
except subprocess.SubprocessError as e:
|
|
417
|
+
# Tool execution failed
|
|
418
|
+
logger.error(f"Lint check subprocess error ({tool}): {e}")
|
|
419
|
+
return CheckResult(
|
|
420
|
+
category=CheckCategory.LINT,
|
|
421
|
+
status=HealthStatus.ERROR,
|
|
422
|
+
score=0,
|
|
423
|
+
tool_used=tool,
|
|
424
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
425
|
+
)
|
|
392
426
|
except Exception as e:
|
|
427
|
+
# Unexpected errors - preserve full context for debugging
|
|
428
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
429
|
+
logger.exception(f"Unexpected error in lint check ({tool}): {e}")
|
|
393
430
|
return CheckResult(
|
|
394
431
|
category=CheckCategory.LINT,
|
|
395
432
|
status=HealthStatus.ERROR,
|
|
@@ -416,6 +453,7 @@ class HealthCheckRunner:
|
|
|
416
453
|
if tool == "black":
|
|
417
454
|
result = subprocess.run(
|
|
418
455
|
["black", "--check", "--diff", str(self.project_root)],
|
|
456
|
+
check=False,
|
|
419
457
|
capture_output=True,
|
|
420
458
|
text=True,
|
|
421
459
|
cwd=str(self.project_root),
|
|
@@ -439,7 +477,7 @@ class HealthCheckRunner:
|
|
|
439
477
|
severity="warning",
|
|
440
478
|
fixable=True,
|
|
441
479
|
fix_command=f"black {current_file}",
|
|
442
|
-
)
|
|
480
|
+
),
|
|
443
481
|
)
|
|
444
482
|
|
|
445
483
|
# Also check stderr for files that would be reformatted
|
|
@@ -458,7 +496,7 @@ class HealthCheckRunner:
|
|
|
458
496
|
severity="warning",
|
|
459
497
|
fixable=True,
|
|
460
498
|
fix_command=f"black {file_path}",
|
|
461
|
-
)
|
|
499
|
+
),
|
|
462
500
|
)
|
|
463
501
|
|
|
464
502
|
score = max(0, 100 - len(issues) * 10) # -10 per file
|
|
@@ -473,7 +511,20 @@ class HealthCheckRunner:
|
|
|
473
511
|
details={"files_need_formatting": len(issues)},
|
|
474
512
|
)
|
|
475
513
|
|
|
514
|
+
except subprocess.SubprocessError as e:
|
|
515
|
+
# Tool execution failed
|
|
516
|
+
logger.error(f"Format check subprocess error ({tool}): {e}")
|
|
517
|
+
return CheckResult(
|
|
518
|
+
category=CheckCategory.FORMAT,
|
|
519
|
+
status=HealthStatus.ERROR,
|
|
520
|
+
score=0,
|
|
521
|
+
tool_used=tool,
|
|
522
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
523
|
+
)
|
|
476
524
|
except Exception as e:
|
|
525
|
+
# Unexpected errors - preserve full context for debugging
|
|
526
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
527
|
+
logger.exception(f"Unexpected error in format check ({tool}): {e}")
|
|
477
528
|
return CheckResult(
|
|
478
529
|
category=CheckCategory.FORMAT,
|
|
479
530
|
status=HealthStatus.ERROR,
|
|
@@ -500,6 +551,7 @@ class HealthCheckRunner:
|
|
|
500
551
|
if tool == "pyright":
|
|
501
552
|
result = subprocess.run(
|
|
502
553
|
["pyright", "--outputjson"],
|
|
554
|
+
check=False,
|
|
503
555
|
capture_output=True,
|
|
504
556
|
text=True,
|
|
505
557
|
cwd=str(self.project_root),
|
|
@@ -519,7 +571,7 @@ class HealthCheckRunner:
|
|
|
519
571
|
message=diag.get("message", ""),
|
|
520
572
|
severity="error" if diag.get("severity") == 1 else "warning",
|
|
521
573
|
fixable=False,
|
|
522
|
-
)
|
|
574
|
+
),
|
|
523
575
|
)
|
|
524
576
|
except json.JSONDecodeError:
|
|
525
577
|
pass
|
|
@@ -527,6 +579,7 @@ class HealthCheckRunner:
|
|
|
527
579
|
elif tool == "mypy":
|
|
528
580
|
result = subprocess.run(
|
|
529
581
|
["mypy", "--show-error-codes", "--no-error-summary", str(self.project_root)],
|
|
582
|
+
check=False,
|
|
530
583
|
capture_output=True,
|
|
531
584
|
text=True,
|
|
532
585
|
cwd=str(self.project_root),
|
|
@@ -546,7 +599,7 @@ class HealthCheckRunner:
|
|
|
546
599
|
message=parts[3].strip() if len(parts) > 3 else "",
|
|
547
600
|
severity="error",
|
|
548
601
|
fixable=False,
|
|
549
|
-
)
|
|
602
|
+
),
|
|
550
603
|
)
|
|
551
604
|
|
|
552
605
|
score = max(0, 100 - len(issues) * 10) # -10 per type error
|
|
@@ -565,7 +618,30 @@ class HealthCheckRunner:
|
|
|
565
618
|
details={"type_errors": len(issues)},
|
|
566
619
|
)
|
|
567
620
|
|
|
621
|
+
except json.JSONDecodeError as e:
|
|
622
|
+
# Tool output not in expected JSON format (pyright specific)
|
|
623
|
+
logger.warning(f"Type check JSON parse error ({tool}): {e}")
|
|
624
|
+
return CheckResult(
|
|
625
|
+
category=CheckCategory.TYPES,
|
|
626
|
+
status=HealthStatus.ERROR,
|
|
627
|
+
score=0,
|
|
628
|
+
tool_used=tool,
|
|
629
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
630
|
+
)
|
|
631
|
+
except subprocess.SubprocessError as e:
|
|
632
|
+
# Tool execution failed
|
|
633
|
+
logger.error(f"Type check subprocess error ({tool}): {e}")
|
|
634
|
+
return CheckResult(
|
|
635
|
+
category=CheckCategory.TYPES,
|
|
636
|
+
status=HealthStatus.ERROR,
|
|
637
|
+
score=0,
|
|
638
|
+
tool_used=tool,
|
|
639
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
640
|
+
)
|
|
568
641
|
except Exception as e:
|
|
642
|
+
# Unexpected errors - preserve full context for debugging
|
|
643
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
644
|
+
logger.exception(f"Unexpected error in type check ({tool}): {e}")
|
|
569
645
|
return CheckResult(
|
|
570
646
|
category=CheckCategory.TYPES,
|
|
571
647
|
status=HealthStatus.ERROR,
|
|
@@ -590,6 +666,7 @@ class HealthCheckRunner:
|
|
|
590
666
|
try:
|
|
591
667
|
result = subprocess.run(
|
|
592
668
|
["pytest", "--tb=no", "-q", "--co", "-q"], # Collect only, quiet
|
|
669
|
+
check=False,
|
|
593
670
|
capture_output=True,
|
|
594
671
|
text=True,
|
|
595
672
|
cwd=str(self.project_root),
|
|
@@ -604,6 +681,7 @@ class HealthCheckRunner:
|
|
|
604
681
|
# Run actual tests
|
|
605
682
|
result = subprocess.run(
|
|
606
683
|
["pytest", "--tb=short", "-q"],
|
|
684
|
+
check=False,
|
|
607
685
|
capture_output=True,
|
|
608
686
|
text=True,
|
|
609
687
|
cwd=str(self.project_root),
|
|
@@ -654,7 +732,7 @@ class HealthCheckRunner:
|
|
|
654
732
|
message=f"Test failed: {test_path}",
|
|
655
733
|
severity="error",
|
|
656
734
|
fixable=False,
|
|
657
|
-
)
|
|
735
|
+
),
|
|
658
736
|
)
|
|
659
737
|
|
|
660
738
|
total = passed + failed
|
|
@@ -675,6 +753,8 @@ class HealthCheckRunner:
|
|
|
675
753
|
)
|
|
676
754
|
|
|
677
755
|
except subprocess.TimeoutExpired:
|
|
756
|
+
# Tests took too long - specific timeout error
|
|
757
|
+
logger.error(f"Test check timeout ({tool}): Tests took longer than 5 minutes")
|
|
678
758
|
return CheckResult(
|
|
679
759
|
category=CheckCategory.TESTS,
|
|
680
760
|
status=HealthStatus.ERROR,
|
|
@@ -682,7 +762,20 @@ class HealthCheckRunner:
|
|
|
682
762
|
tool_used=tool,
|
|
683
763
|
details={"error": "Test suite timed out after 5 minutes"},
|
|
684
764
|
)
|
|
765
|
+
except subprocess.SubprocessError as e:
|
|
766
|
+
# Tool execution failed
|
|
767
|
+
logger.error(f"Test check subprocess error ({tool}): {e}")
|
|
768
|
+
return CheckResult(
|
|
769
|
+
category=CheckCategory.TESTS,
|
|
770
|
+
status=HealthStatus.ERROR,
|
|
771
|
+
score=0,
|
|
772
|
+
tool_used=tool,
|
|
773
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
774
|
+
)
|
|
685
775
|
except Exception as e:
|
|
776
|
+
# Unexpected errors - preserve full context for debugging
|
|
777
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
778
|
+
logger.exception(f"Unexpected error in test check ({tool}): {e}")
|
|
686
779
|
return CheckResult(
|
|
687
780
|
category=CheckCategory.TESTS,
|
|
688
781
|
status=HealthStatus.ERROR,
|
|
@@ -708,6 +801,7 @@ class HealthCheckRunner:
|
|
|
708
801
|
try:
|
|
709
802
|
result = subprocess.run(
|
|
710
803
|
["bandit", "-r", "-f", "json", str(self.project_root)],
|
|
804
|
+
check=False,
|
|
711
805
|
capture_output=True,
|
|
712
806
|
text=True,
|
|
713
807
|
cwd=str(self.project_root),
|
|
@@ -727,7 +821,7 @@ class HealthCheckRunner:
|
|
|
727
821
|
message=item.get("issue_text", ""),
|
|
728
822
|
severity="error" if severity in ["HIGH", "MEDIUM"] else "warning",
|
|
729
823
|
fixable=False,
|
|
730
|
-
)
|
|
824
|
+
),
|
|
731
825
|
)
|
|
732
826
|
except json.JSONDecodeError:
|
|
733
827
|
pass
|
|
@@ -754,7 +848,30 @@ class HealthCheckRunner:
|
|
|
754
848
|
},
|
|
755
849
|
)
|
|
756
850
|
|
|
851
|
+
except json.JSONDecodeError as e:
|
|
852
|
+
# Tool output not in expected JSON format
|
|
853
|
+
logger.warning(f"Security check JSON parse error ({tool}): {e}")
|
|
854
|
+
return CheckResult(
|
|
855
|
+
category=CheckCategory.SECURITY,
|
|
856
|
+
status=HealthStatus.ERROR,
|
|
857
|
+
score=0,
|
|
858
|
+
tool_used=tool,
|
|
859
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
860
|
+
)
|
|
861
|
+
except subprocess.SubprocessError as e:
|
|
862
|
+
# Tool execution failed
|
|
863
|
+
logger.error(f"Security check subprocess error ({tool}): {e}")
|
|
864
|
+
return CheckResult(
|
|
865
|
+
category=CheckCategory.SECURITY,
|
|
866
|
+
status=HealthStatus.ERROR,
|
|
867
|
+
score=0,
|
|
868
|
+
tool_used=tool,
|
|
869
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
870
|
+
)
|
|
757
871
|
except Exception as e:
|
|
872
|
+
# Unexpected errors - preserve full context for debugging
|
|
873
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
874
|
+
logger.exception(f"Unexpected error in security check ({tool}): {e}")
|
|
758
875
|
return CheckResult(
|
|
759
876
|
category=CheckCategory.SECURITY,
|
|
760
877
|
status=HealthStatus.ERROR,
|
|
@@ -780,6 +897,7 @@ class HealthCheckRunner:
|
|
|
780
897
|
try:
|
|
781
898
|
result = subprocess.run(
|
|
782
899
|
["pip-audit", "--format=json"],
|
|
900
|
+
check=False,
|
|
783
901
|
capture_output=True,
|
|
784
902
|
text=True,
|
|
785
903
|
cwd=str(self.project_root),
|
|
@@ -795,15 +913,11 @@ class HealthCheckRunner:
|
|
|
795
913
|
file_path="requirements.txt",
|
|
796
914
|
line=None,
|
|
797
915
|
code=item.get("id", "VULN"),
|
|
798
|
-
message=f"{item.get('name')}: {item.get('description', '
|
|
916
|
+
message=f"{item.get('name')}: {item.get('description', 'Vuln')}",
|
|
799
917
|
severity="error" if item.get("fix_versions") else "warning",
|
|
800
918
|
fixable=bool(item.get("fix_versions")),
|
|
801
|
-
fix_command=(
|
|
802
|
-
|
|
803
|
-
if item.get("fix_versions")
|
|
804
|
-
else None
|
|
805
|
-
),
|
|
806
|
-
)
|
|
919
|
+
fix_command=self._get_fix_cmd(item),
|
|
920
|
+
),
|
|
807
921
|
)
|
|
808
922
|
except json.JSONDecodeError:
|
|
809
923
|
pass
|
|
@@ -820,7 +934,30 @@ class HealthCheckRunner:
|
|
|
820
934
|
details={"vulnerable_packages": len(issues)},
|
|
821
935
|
)
|
|
822
936
|
|
|
937
|
+
except json.JSONDecodeError as e:
|
|
938
|
+
# Tool output not in expected JSON format
|
|
939
|
+
logger.warning(f"Dependency check JSON parse error ({tool}): {e}")
|
|
940
|
+
return CheckResult(
|
|
941
|
+
category=CheckCategory.DEPS,
|
|
942
|
+
status=HealthStatus.ERROR,
|
|
943
|
+
score=0,
|
|
944
|
+
tool_used=tool,
|
|
945
|
+
details={"error": f"Failed to parse {tool} output: {e}"},
|
|
946
|
+
)
|
|
947
|
+
except subprocess.SubprocessError as e:
|
|
948
|
+
# Tool execution failed
|
|
949
|
+
logger.error(f"Dependency check subprocess error ({tool}): {e}")
|
|
950
|
+
return CheckResult(
|
|
951
|
+
category=CheckCategory.DEPS,
|
|
952
|
+
status=HealthStatus.ERROR,
|
|
953
|
+
score=0,
|
|
954
|
+
tool_used=tool,
|
|
955
|
+
details={"error": f"Failed to run {tool}: {e}"},
|
|
956
|
+
)
|
|
823
957
|
except Exception as e:
|
|
958
|
+
# Unexpected errors - preserve full context for debugging
|
|
959
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional check
|
|
960
|
+
logger.exception(f"Unexpected error in dependency check ({tool}): {e}")
|
|
824
961
|
return CheckResult(
|
|
825
962
|
category=CheckCategory.DEPS,
|
|
826
963
|
status=HealthStatus.ERROR,
|
|
@@ -829,6 +966,13 @@ class HealthCheckRunner:
|
|
|
829
966
|
details={"error": str(e)},
|
|
830
967
|
)
|
|
831
968
|
|
|
969
|
+
def _get_fix_cmd(self, item: dict) -> str | None:
|
|
970
|
+
"""Get pip install command to fix a vulnerable package."""
|
|
971
|
+
fix_versions = item.get("fix_versions")
|
|
972
|
+
if fix_versions:
|
|
973
|
+
return f"pip install {item.get('name')}=={fix_versions[0]}"
|
|
974
|
+
return None
|
|
975
|
+
|
|
832
976
|
|
|
833
977
|
class AutoFixer:
|
|
834
978
|
"""Apply automatic fixes to code health issues."""
|
|
@@ -852,7 +996,7 @@ class AutoFixer:
|
|
|
852
996
|
"issue": issue.message,
|
|
853
997
|
"fix_command": issue.fix_command,
|
|
854
998
|
"safe": self._is_safe_fix(issue),
|
|
855
|
-
}
|
|
999
|
+
},
|
|
856
1000
|
)
|
|
857
1001
|
return fixes
|
|
858
1002
|
|
|
@@ -909,7 +1053,14 @@ class AutoFixer:
|
|
|
909
1053
|
return results
|
|
910
1054
|
|
|
911
1055
|
async def _apply_fix(self, issue: HealthIssue) -> bool:
|
|
912
|
-
"""Apply a single fix.
|
|
1056
|
+
"""Apply a single fix.
|
|
1057
|
+
|
|
1058
|
+
This uses broad exception handling intentionally for graceful degradation.
|
|
1059
|
+
Auto-fixes are optional - the system should continue even if some fixes fail.
|
|
1060
|
+
|
|
1061
|
+
Note:
|
|
1062
|
+
Full exception context is preserved via logger.exception() for debugging.
|
|
1063
|
+
"""
|
|
913
1064
|
if not issue.fix_command:
|
|
914
1065
|
return False
|
|
915
1066
|
|
|
@@ -921,7 +1072,14 @@ class AutoFixer:
|
|
|
921
1072
|
text=True,
|
|
922
1073
|
)
|
|
923
1074
|
return result.returncode == 0
|
|
924
|
-
except
|
|
1075
|
+
except subprocess.SubprocessError as e:
|
|
1076
|
+
# Fix command execution failed
|
|
1077
|
+
logger.error(f"Auto-fix subprocess error for {issue.file_path}: {e}")
|
|
1078
|
+
return False
|
|
1079
|
+
except Exception as e:
|
|
1080
|
+
# Unexpected errors - preserve full context for debugging
|
|
1081
|
+
# INTENTIONAL: Broad handler for graceful degradation of optional auto-fix
|
|
1082
|
+
logger.exception(f"Unexpected error applying fix to {issue.file_path}: {e}")
|
|
925
1083
|
return False
|
|
926
1084
|
|
|
927
1085
|
|
|
@@ -955,7 +1113,7 @@ class HealthTrendTracker:
|
|
|
955
1113
|
"status": report.status.value,
|
|
956
1114
|
"total_issues": report.total_issues,
|
|
957
1115
|
"results": {r.category.value: r.score for r in report.results},
|
|
958
|
-
}
|
|
1116
|
+
},
|
|
959
1117
|
)
|
|
960
1118
|
|
|
961
1119
|
filepath.write_text(json.dumps(history, indent=2))
|
|
@@ -986,7 +1144,7 @@ class HealthTrendTracker:
|
|
|
986
1144
|
{
|
|
987
1145
|
"date": date,
|
|
988
1146
|
"score": entry.get("overall_score", 0),
|
|
989
|
-
}
|
|
1147
|
+
},
|
|
990
1148
|
)
|
|
991
1149
|
except json.JSONDecodeError:
|
|
992
1150
|
pass
|
|
@@ -1040,13 +1198,13 @@ def format_health_output(
|
|
|
1040
1198
|
level: int = 1,
|
|
1041
1199
|
thresholds: dict | None = None,
|
|
1042
1200
|
) -> str:
|
|
1043
|
-
"""
|
|
1044
|
-
Format health report for display.
|
|
1201
|
+
"""Format health report for display.
|
|
1045
1202
|
|
|
1046
1203
|
Args:
|
|
1047
1204
|
report: The health report to format
|
|
1048
1205
|
level: Detail level (1=summary, 2=details, 3=full)
|
|
1049
1206
|
thresholds: Score thresholds for status icons
|
|
1207
|
+
|
|
1050
1208
|
"""
|
|
1051
1209
|
thresholds = thresholds or DEFAULT_THRESHOLDS
|
|
1052
1210
|
lines = []
|
|
@@ -1083,7 +1241,7 @@ def format_health_output(
|
|
|
1083
1241
|
if result.category == CheckCategory.TESTS:
|
|
1084
1242
|
details = result.details
|
|
1085
1243
|
lines.append(
|
|
1086
|
-
f"{icon} {category_name}: {details.get('passed', 0)}
|
|
1244
|
+
f"{icon} {category_name}: {details.get('passed', 0)}P/{details.get('failed', 0)}F",
|
|
1087
1245
|
)
|
|
1088
1246
|
elif result.category == CheckCategory.LINT:
|
|
1089
1247
|
lines.append(f"{icon} {category_name}: {result.issue_count} warnings")
|
|
@@ -1149,7 +1307,7 @@ def format_health_output(
|
|
|
1149
1307
|
lines.append("")
|
|
1150
1308
|
lines.append("━" * 40)
|
|
1151
1309
|
lines.append(
|
|
1152
|
-
f"[1] Fix {report.total_fixable} auto-fixable issues [2] See details [3] Full report"
|
|
1310
|
+
f"[1] Fix {report.total_fixable} auto-fixable issues [2] See details [3] Full report",
|
|
1153
1311
|
)
|
|
1154
1312
|
|
|
1155
1313
|
return "\n".join(lines)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Empathy Framework Configuration Module
|
|
2
|
+
|
|
3
|
+
Provides unified configuration models for agents, wizards, and workflows.
|
|
4
|
+
|
|
5
|
+
Copyright 2025 Smart-AI-Memory
|
|
6
|
+
Licensed under Fair Source License 0.9
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from empathy_llm_toolkit.config.unified import (
|
|
10
|
+
AgentOperationError,
|
|
11
|
+
BookProductionConfig,
|
|
12
|
+
MemDocsConfig,
|
|
13
|
+
ModelTier,
|
|
14
|
+
Provider,
|
|
15
|
+
RedisConfig,
|
|
16
|
+
UnifiedAgentConfig,
|
|
17
|
+
WorkflowMode,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"AgentOperationError",
|
|
22
|
+
"BookProductionConfig",
|
|
23
|
+
"MemDocsConfig",
|
|
24
|
+
"ModelTier",
|
|
25
|
+
"Provider",
|
|
26
|
+
"RedisConfig",
|
|
27
|
+
"UnifiedAgentConfig",
|
|
28
|
+
"WorkflowMode",
|
|
29
|
+
]
|