empathy-framework 3.2.3__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 +11 -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 +22 -25
- 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.2.3.dist-info → empathy_framework-3.8.2.dist-info}/METADATA +513 -58
- empathy_framework-3.8.2.dist-info/RECORD +333 -0
- empathy_framework-3.8.2.dist-info/entry_points.txt +22 -0
- {empathy_framework-3.2.3.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 +177 -22
- 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 +51 -49
- empathy_llm_toolkit/git_pattern_extractor.py +16 -12
- 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 +13 -11
- 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 +18 -20
- empathy_llm_toolkit/state.py +20 -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 +76 -77
- empathy_os/adaptive/__init__.py +13 -0
- empathy_os/adaptive/task_complexity.py +127 -0
- empathy_os/{monitoring.py → agent_monitoring.py} +27 -27
- 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 +515 -109
- empathy_os/cli_unified.py +189 -42
- empathy_os/config/__init__.py +63 -0
- empathy_os/config/xml_config.py +239 -0
- empathy_os/config.py +87 -36
- empathy_os/coordination.py +48 -54
- empathy_os/core.py +90 -99
- empathy_os/cost_tracker.py +20 -23
- empathy_os/dashboard/__init__.py +15 -0
- empathy_os/dashboard/server.py +743 -0
- empathy_os/discovery.py +9 -11
- empathy_os/emergence.py +20 -21
- empathy_os/exceptions.py +18 -30
- empathy_os/feedback_loops.py +27 -30
- empathy_os/levels.py +31 -34
- empathy_os/leverage_points.py +27 -28
- empathy_os/logging_config.py +11 -12
- 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 +29 -28
- empathy_os/persistence.py +30 -34
- 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 +53 -56
- 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 +12 -11
- empathy_os/trust/__init__.py +28 -0
- empathy_os/trust/circuit_breaker.py +579 -0
- empathy_os/trust_building.py +44 -36
- 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} +123 -31
- 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 +35 -26
- 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-3.2.3.dist-info/RECORD +0 -104
- empathy_framework-3.2.3.dist-info/entry_points.txt +0 -7
- empathy_llm_toolkit/htmlcov/status.json +0 -1
- empathy_llm_toolkit/security/htmlcov/status.json +0 -1
- {empathy_framework-3.2.3.dist-info → empathy_framework-3.8.2.dist-info}/WHEEL +0 -0
- {empathy_framework-3.2.3.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),
|
|
@@ -799,7 +917,7 @@ class HealthCheckRunner:
|
|
|
799
917
|
severity="error" if item.get("fix_versions") else "warning",
|
|
800
918
|
fixable=bool(item.get("fix_versions")),
|
|
801
919
|
fix_command=self._get_fix_cmd(item),
|
|
802
|
-
)
|
|
920
|
+
),
|
|
803
921
|
)
|
|
804
922
|
except json.JSONDecodeError:
|
|
805
923
|
pass
|
|
@@ -816,7 +934,30 @@ class HealthCheckRunner:
|
|
|
816
934
|
details={"vulnerable_packages": len(issues)},
|
|
817
935
|
)
|
|
818
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
|
+
)
|
|
819
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}")
|
|
820
961
|
return CheckResult(
|
|
821
962
|
category=CheckCategory.DEPS,
|
|
822
963
|
status=HealthStatus.ERROR,
|
|
@@ -855,7 +996,7 @@ class AutoFixer:
|
|
|
855
996
|
"issue": issue.message,
|
|
856
997
|
"fix_command": issue.fix_command,
|
|
857
998
|
"safe": self._is_safe_fix(issue),
|
|
858
|
-
}
|
|
999
|
+
},
|
|
859
1000
|
)
|
|
860
1001
|
return fixes
|
|
861
1002
|
|
|
@@ -912,7 +1053,14 @@ class AutoFixer:
|
|
|
912
1053
|
return results
|
|
913
1054
|
|
|
914
1055
|
async def _apply_fix(self, issue: HealthIssue) -> bool:
|
|
915
|
-
"""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
|
+
"""
|
|
916
1064
|
if not issue.fix_command:
|
|
917
1065
|
return False
|
|
918
1066
|
|
|
@@ -924,7 +1072,14 @@ class AutoFixer:
|
|
|
924
1072
|
text=True,
|
|
925
1073
|
)
|
|
926
1074
|
return result.returncode == 0
|
|
927
|
-
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}")
|
|
928
1083
|
return False
|
|
929
1084
|
|
|
930
1085
|
|
|
@@ -958,7 +1113,7 @@ class HealthTrendTracker:
|
|
|
958
1113
|
"status": report.status.value,
|
|
959
1114
|
"total_issues": report.total_issues,
|
|
960
1115
|
"results": {r.category.value: r.score for r in report.results},
|
|
961
|
-
}
|
|
1116
|
+
},
|
|
962
1117
|
)
|
|
963
1118
|
|
|
964
1119
|
filepath.write_text(json.dumps(history, indent=2))
|
|
@@ -989,7 +1144,7 @@ class HealthTrendTracker:
|
|
|
989
1144
|
{
|
|
990
1145
|
"date": date,
|
|
991
1146
|
"score": entry.get("overall_score", 0),
|
|
992
|
-
}
|
|
1147
|
+
},
|
|
993
1148
|
)
|
|
994
1149
|
except json.JSONDecodeError:
|
|
995
1150
|
pass
|
|
@@ -1043,13 +1198,13 @@ def format_health_output(
|
|
|
1043
1198
|
level: int = 1,
|
|
1044
1199
|
thresholds: dict | None = None,
|
|
1045
1200
|
) -> str:
|
|
1046
|
-
"""
|
|
1047
|
-
Format health report for display.
|
|
1201
|
+
"""Format health report for display.
|
|
1048
1202
|
|
|
1049
1203
|
Args:
|
|
1050
1204
|
report: The health report to format
|
|
1051
1205
|
level: Detail level (1=summary, 2=details, 3=full)
|
|
1052
1206
|
thresholds: Score thresholds for status icons
|
|
1207
|
+
|
|
1053
1208
|
"""
|
|
1054
1209
|
thresholds = thresholds or DEFAULT_THRESHOLDS
|
|
1055
1210
|
lines = []
|
|
@@ -1086,7 +1241,7 @@ def format_health_output(
|
|
|
1086
1241
|
if result.category == CheckCategory.TESTS:
|
|
1087
1242
|
details = result.details
|
|
1088
1243
|
lines.append(
|
|
1089
|
-
f"{icon} {category_name}: {details.get('passed', 0)}P/{details.get('failed', 0)}F"
|
|
1244
|
+
f"{icon} {category_name}: {details.get('passed', 0)}P/{details.get('failed', 0)}F",
|
|
1090
1245
|
)
|
|
1091
1246
|
elif result.category == CheckCategory.LINT:
|
|
1092
1247
|
lines.append(f"{icon} {category_name}: {result.issue_count} warnings")
|
|
@@ -1152,7 +1307,7 @@ def format_health_output(
|
|
|
1152
1307
|
lines.append("")
|
|
1153
1308
|
lines.append("━" * 40)
|
|
1154
1309
|
lines.append(
|
|
1155
|
-
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",
|
|
1156
1311
|
)
|
|
1157
1312
|
|
|
1158
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
|
+
]
|