empathy-framework 4.6.6__py3-none-any.whl → 4.7.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.
- empathy_framework-4.7.1.dist-info/METADATA +690 -0
- empathy_framework-4.7.1.dist-info/RECORD +379 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/top_level.txt +1 -2
- empathy_healthcare_plugin/monitors/monitoring/__init__.py +9 -9
- empathy_llm_toolkit/agent_factory/__init__.py +6 -6
- empathy_llm_toolkit/agent_factory/adapters/wizard_adapter.py +7 -10
- empathy_llm_toolkit/agents_md/__init__.py +22 -0
- empathy_llm_toolkit/agents_md/loader.py +218 -0
- empathy_llm_toolkit/agents_md/parser.py +271 -0
- empathy_llm_toolkit/agents_md/registry.py +307 -0
- empathy_llm_toolkit/commands/__init__.py +51 -0
- empathy_llm_toolkit/commands/context.py +375 -0
- empathy_llm_toolkit/commands/loader.py +301 -0
- empathy_llm_toolkit/commands/models.py +231 -0
- empathy_llm_toolkit/commands/parser.py +371 -0
- empathy_llm_toolkit/commands/registry.py +429 -0
- empathy_llm_toolkit/config/__init__.py +8 -8
- empathy_llm_toolkit/config/unified.py +3 -7
- empathy_llm_toolkit/context/__init__.py +22 -0
- empathy_llm_toolkit/context/compaction.py +455 -0
- empathy_llm_toolkit/context/manager.py +434 -0
- empathy_llm_toolkit/hooks/__init__.py +24 -0
- empathy_llm_toolkit/hooks/config.py +306 -0
- empathy_llm_toolkit/hooks/executor.py +289 -0
- empathy_llm_toolkit/hooks/registry.py +302 -0
- empathy_llm_toolkit/hooks/scripts/__init__.py +39 -0
- empathy_llm_toolkit/hooks/scripts/evaluate_session.py +201 -0
- empathy_llm_toolkit/hooks/scripts/first_time_init.py +285 -0
- empathy_llm_toolkit/hooks/scripts/pre_compact.py +207 -0
- empathy_llm_toolkit/hooks/scripts/session_end.py +183 -0
- empathy_llm_toolkit/hooks/scripts/session_start.py +163 -0
- empathy_llm_toolkit/hooks/scripts/suggest_compact.py +225 -0
- empathy_llm_toolkit/learning/__init__.py +30 -0
- empathy_llm_toolkit/learning/evaluator.py +438 -0
- empathy_llm_toolkit/learning/extractor.py +514 -0
- empathy_llm_toolkit/learning/storage.py +560 -0
- empathy_llm_toolkit/providers.py +4 -11
- empathy_llm_toolkit/security/__init__.py +17 -17
- empathy_llm_toolkit/utils/tokens.py +2 -5
- empathy_os/__init__.py +202 -70
- empathy_os/cache_monitor.py +5 -3
- empathy_os/cli/__init__.py +11 -55
- empathy_os/cli/__main__.py +29 -15
- empathy_os/cli/commands/inspection.py +21 -12
- empathy_os/cli/commands/memory.py +4 -12
- empathy_os/cli/commands/profiling.py +198 -0
- empathy_os/cli/commands/utilities.py +27 -7
- empathy_os/cli.py +28 -57
- empathy_os/cli_unified.py +525 -1164
- empathy_os/cost_tracker.py +9 -3
- empathy_os/dashboard/server.py +200 -2
- empathy_os/hot_reload/__init__.py +7 -7
- empathy_os/hot_reload/config.py +6 -7
- empathy_os/hot_reload/integration.py +35 -35
- empathy_os/hot_reload/reloader.py +57 -57
- empathy_os/hot_reload/watcher.py +28 -28
- empathy_os/hot_reload/websocket.py +2 -2
- empathy_os/memory/__init__.py +11 -4
- empathy_os/memory/claude_memory.py +1 -1
- empathy_os/memory/cross_session.py +8 -12
- empathy_os/memory/edges.py +6 -6
- empathy_os/memory/file_session.py +770 -0
- empathy_os/memory/graph.py +30 -30
- empathy_os/memory/nodes.py +6 -6
- empathy_os/memory/short_term.py +15 -9
- empathy_os/memory/unified.py +606 -140
- empathy_os/meta_workflows/agent_creator.py +3 -9
- empathy_os/meta_workflows/cli_meta_workflows.py +113 -53
- empathy_os/meta_workflows/form_engine.py +6 -18
- empathy_os/meta_workflows/intent_detector.py +64 -24
- empathy_os/meta_workflows/models.py +3 -1
- empathy_os/meta_workflows/pattern_learner.py +13 -31
- empathy_os/meta_workflows/plan_generator.py +55 -47
- empathy_os/meta_workflows/session_context.py +2 -3
- empathy_os/meta_workflows/workflow.py +20 -51
- empathy_os/models/cli.py +2 -2
- empathy_os/models/tasks.py +1 -2
- empathy_os/models/telemetry.py +4 -1
- empathy_os/models/token_estimator.py +3 -1
- empathy_os/monitoring/alerts.py +938 -9
- empathy_os/monitoring/alerts_cli.py +346 -183
- empathy_os/orchestration/execution_strategies.py +12 -29
- empathy_os/orchestration/pattern_learner.py +20 -26
- empathy_os/orchestration/real_tools.py +6 -15
- empathy_os/platform_utils.py +2 -1
- empathy_os/plugins/__init__.py +2 -2
- empathy_os/plugins/base.py +64 -64
- empathy_os/plugins/registry.py +32 -32
- empathy_os/project_index/index.py +49 -15
- empathy_os/project_index/models.py +1 -2
- empathy_os/project_index/reports.py +1 -1
- empathy_os/project_index/scanner.py +1 -0
- empathy_os/redis_memory.py +10 -7
- empathy_os/resilience/__init__.py +1 -1
- empathy_os/resilience/health.py +10 -10
- empathy_os/routing/__init__.py +7 -7
- empathy_os/routing/chain_executor.py +37 -37
- empathy_os/routing/classifier.py +36 -36
- empathy_os/routing/smart_router.py +40 -40
- empathy_os/routing/{wizard_registry.py → workflow_registry.py} +47 -47
- empathy_os/scaffolding/__init__.py +8 -8
- empathy_os/scaffolding/__main__.py +1 -1
- empathy_os/scaffolding/cli.py +28 -28
- empathy_os/socratic/__init__.py +3 -19
- empathy_os/socratic/ab_testing.py +25 -36
- empathy_os/socratic/blueprint.py +38 -38
- empathy_os/socratic/cli.py +34 -20
- empathy_os/socratic/collaboration.py +30 -28
- empathy_os/socratic/domain_templates.py +9 -1
- empathy_os/socratic/embeddings.py +17 -13
- empathy_os/socratic/engine.py +135 -70
- empathy_os/socratic/explainer.py +70 -60
- empathy_os/socratic/feedback.py +24 -19
- empathy_os/socratic/forms.py +15 -10
- empathy_os/socratic/generator.py +51 -35
- empathy_os/socratic/llm_analyzer.py +25 -23
- empathy_os/socratic/mcp_server.py +99 -159
- empathy_os/socratic/session.py +19 -13
- empathy_os/socratic/storage.py +98 -67
- empathy_os/socratic/success.py +38 -27
- empathy_os/socratic/visual_editor.py +51 -39
- empathy_os/socratic/web_ui.py +99 -66
- empathy_os/telemetry/cli.py +3 -1
- empathy_os/telemetry/usage_tracker.py +1 -3
- empathy_os/test_generator/__init__.py +3 -3
- empathy_os/test_generator/cli.py +28 -28
- empathy_os/test_generator/generator.py +64 -66
- empathy_os/test_generator/risk_analyzer.py +11 -11
- empathy_os/vscode_bridge 2.py +173 -0
- empathy_os/vscode_bridge.py +173 -0
- empathy_os/workflows/__init__.py +212 -120
- empathy_os/workflows/batch_processing.py +8 -24
- empathy_os/workflows/bug_predict.py +1 -1
- empathy_os/workflows/code_review.py +20 -5
- empathy_os/workflows/code_review_pipeline.py +13 -8
- empathy_os/workflows/keyboard_shortcuts/workflow.py +6 -2
- empathy_os/workflows/manage_documentation.py +1 -0
- empathy_os/workflows/orchestrated_health_check.py +6 -11
- empathy_os/workflows/orchestrated_release_prep.py +3 -3
- empathy_os/workflows/pr_review.py +18 -10
- empathy_os/workflows/progressive/README 2.md +454 -0
- empathy_os/workflows/progressive/__init__ 2.py +92 -0
- empathy_os/workflows/progressive/__init__.py +2 -12
- empathy_os/workflows/progressive/cli 2.py +242 -0
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core 2.py +488 -0
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator 2.py +701 -0
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports 2.py +528 -0
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry 2.py +280 -0
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen 2.py +514 -0
- empathy_os/workflows/progressive/test_gen.py +29 -48
- empathy_os/workflows/progressive/workflow 2.py +628 -0
- empathy_os/workflows/progressive/workflow.py +31 -70
- empathy_os/workflows/release_prep.py +21 -6
- empathy_os/workflows/release_prep_crew.py +1 -0
- empathy_os/workflows/secure_release.py +13 -6
- empathy_os/workflows/security_audit.py +8 -3
- empathy_os/workflows/test_coverage_boost_crew.py +3 -2
- empathy_os/workflows/test_maintenance_crew.py +1 -0
- empathy_os/workflows/test_runner.py +16 -12
- empathy_software_plugin/SOFTWARE_PLUGIN_README.md +25 -703
- empathy_software_plugin/cli.py +0 -122
- patterns/README.md +119 -0
- patterns/__init__.py +95 -0
- patterns/behavior.py +298 -0
- patterns/code_review_memory.json +441 -0
- patterns/core.py +97 -0
- patterns/debugging.json +3763 -0
- patterns/empathy.py +268 -0
- patterns/health_check_memory.json +505 -0
- patterns/input.py +161 -0
- patterns/memory_graph.json +8 -0
- patterns/refactoring_memory.json +1113 -0
- patterns/registry.py +663 -0
- patterns/security_memory.json +8 -0
- patterns/structural.py +415 -0
- patterns/validation.py +194 -0
- coach_wizards/__init__.py +0 -45
- coach_wizards/accessibility_wizard.py +0 -91
- coach_wizards/api_wizard.py +0 -91
- coach_wizards/base_wizard.py +0 -209
- coach_wizards/cicd_wizard.py +0 -91
- coach_wizards/code_reviewer_README.md +0 -60
- coach_wizards/code_reviewer_wizard.py +0 -180
- coach_wizards/compliance_wizard.py +0 -91
- coach_wizards/database_wizard.py +0 -91
- coach_wizards/debugging_wizard.py +0 -91
- coach_wizards/documentation_wizard.py +0 -91
- coach_wizards/generate_wizards.py +0 -347
- coach_wizards/localization_wizard.py +0 -173
- coach_wizards/migration_wizard.py +0 -91
- coach_wizards/monitoring_wizard.py +0 -91
- coach_wizards/observability_wizard.py +0 -91
- coach_wizards/performance_wizard.py +0 -91
- coach_wizards/prompt_engineering_wizard.py +0 -661
- coach_wizards/refactoring_wizard.py +0 -91
- coach_wizards/scaling_wizard.py +0 -90
- coach_wizards/security_wizard.py +0 -92
- coach_wizards/testing_wizard.py +0 -91
- empathy_framework-4.6.6.dist-info/METADATA +0 -1597
- empathy_framework-4.6.6.dist-info/RECORD +0 -410
- empathy_llm_toolkit/wizards/__init__.py +0 -43
- empathy_llm_toolkit/wizards/base_wizard.py +0 -364
- empathy_llm_toolkit/wizards/customer_support_wizard.py +0 -190
- empathy_llm_toolkit/wizards/healthcare_wizard.py +0 -378
- empathy_llm_toolkit/wizards/patient_assessment_README.md +0 -64
- empathy_llm_toolkit/wizards/patient_assessment_wizard.py +0 -193
- empathy_llm_toolkit/wizards/technology_wizard.py +0 -209
- empathy_os/wizard_factory_cli.py +0 -170
- empathy_software_plugin/wizards/__init__.py +0 -42
- empathy_software_plugin/wizards/advanced_debugging_wizard.py +0 -395
- empathy_software_plugin/wizards/agent_orchestration_wizard.py +0 -511
- empathy_software_plugin/wizards/ai_collaboration_wizard.py +0 -503
- empathy_software_plugin/wizards/ai_context_wizard.py +0 -441
- empathy_software_plugin/wizards/ai_documentation_wizard.py +0 -503
- empathy_software_plugin/wizards/base_wizard.py +0 -288
- empathy_software_plugin/wizards/book_chapter_wizard.py +0 -519
- empathy_software_plugin/wizards/code_review_wizard.py +0 -604
- empathy_software_plugin/wizards/debugging/__init__.py +0 -50
- empathy_software_plugin/wizards/debugging/bug_risk_analyzer.py +0 -414
- empathy_software_plugin/wizards/debugging/config_loaders.py +0 -446
- empathy_software_plugin/wizards/debugging/fix_applier.py +0 -469
- empathy_software_plugin/wizards/debugging/language_patterns.py +0 -385
- empathy_software_plugin/wizards/debugging/linter_parsers.py +0 -470
- empathy_software_plugin/wizards/debugging/verification.py +0 -369
- empathy_software_plugin/wizards/enhanced_testing_wizard.py +0 -537
- empathy_software_plugin/wizards/memory_enhanced_debugging_wizard.py +0 -816
- empathy_software_plugin/wizards/multi_model_wizard.py +0 -501
- empathy_software_plugin/wizards/pattern_extraction_wizard.py +0 -422
- empathy_software_plugin/wizards/pattern_retriever_wizard.py +0 -400
- empathy_software_plugin/wizards/performance/__init__.py +0 -9
- empathy_software_plugin/wizards/performance/bottleneck_detector.py +0 -221
- empathy_software_plugin/wizards/performance/profiler_parsers.py +0 -278
- empathy_software_plugin/wizards/performance/trajectory_analyzer.py +0 -429
- empathy_software_plugin/wizards/performance_profiling_wizard.py +0 -305
- empathy_software_plugin/wizards/prompt_engineering_wizard.py +0 -425
- empathy_software_plugin/wizards/rag_pattern_wizard.py +0 -461
- empathy_software_plugin/wizards/security/__init__.py +0 -32
- empathy_software_plugin/wizards/security/exploit_analyzer.py +0 -290
- empathy_software_plugin/wizards/security/owasp_patterns.py +0 -241
- empathy_software_plugin/wizards/security/vulnerability_scanner.py +0 -604
- empathy_software_plugin/wizards/security_analysis_wizard.py +0 -322
- empathy_software_plugin/wizards/security_learning_wizard.py +0 -740
- empathy_software_plugin/wizards/tech_debt_wizard.py +0 -726
- empathy_software_plugin/wizards/testing/__init__.py +0 -27
- empathy_software_plugin/wizards/testing/coverage_analyzer.py +0 -459
- empathy_software_plugin/wizards/testing/quality_analyzer.py +0 -525
- empathy_software_plugin/wizards/testing/test_suggester.py +0 -533
- empathy_software_plugin/wizards/testing_wizard.py +0 -274
- wizards/__init__.py +0 -82
- wizards/admission_assessment_wizard.py +0 -644
- wizards/care_plan.py +0 -321
- wizards/clinical_assessment.py +0 -769
- wizards/discharge_planning.py +0 -77
- wizards/discharge_summary_wizard.py +0 -468
- wizards/dosage_calculation.py +0 -497
- wizards/incident_report_wizard.py +0 -454
- wizards/medication_reconciliation.py +0 -85
- wizards/nursing_assessment.py +0 -171
- wizards/patient_education.py +0 -654
- wizards/quality_improvement.py +0 -705
- wizards/sbar_report.py +0 -324
- wizards/sbar_wizard.py +0 -608
- wizards/shift_handoff_wizard.py +0 -535
- wizards/soap_note_wizard.py +0 -679
- wizards/treatment_plan.py +0 -15
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Test generator core implementation.
|
|
2
2
|
|
|
3
|
-
Generates comprehensive tests for
|
|
3
|
+
Generates comprehensive tests for workflows using Jinja2 templates
|
|
4
4
|
and risk-based prioritization.
|
|
5
5
|
|
|
6
6
|
Copyright 2025 Smart AI Memory, LLC
|
|
@@ -46,7 +46,7 @@ def _get_default_template_dir() -> Path:
|
|
|
46
46
|
|
|
47
47
|
# Last resort: Try to find from sys.modules
|
|
48
48
|
this_module = sys.modules.get(__name__)
|
|
49
|
-
if this_module and hasattr(this_module, "__file__"):
|
|
49
|
+
if this_module and hasattr(this_module, "__file__") and this_module.__file__:
|
|
50
50
|
return Path(this_module.__file__).parent / "templates"
|
|
51
51
|
|
|
52
52
|
# Final fallback: Use current working directory
|
|
@@ -54,7 +54,7 @@ def _get_default_template_dir() -> Path:
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
class TestGenerator:
|
|
57
|
-
"""Generates tests for
|
|
57
|
+
"""Generates tests for workflows based on patterns and risk analysis.
|
|
58
58
|
|
|
59
59
|
Uses Jinja2 templates to generate:
|
|
60
60
|
- Unit tests with risk-prioritized coverage
|
|
@@ -87,18 +87,18 @@ class TestGenerator:
|
|
|
87
87
|
|
|
88
88
|
def generate_tests(
|
|
89
89
|
self,
|
|
90
|
-
|
|
90
|
+
workflow_id: str,
|
|
91
91
|
pattern_ids: list[str],
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
workflow_module: str | None = None,
|
|
93
|
+
workflow_class: str | None = None,
|
|
94
94
|
) -> dict[str, str | None]:
|
|
95
|
-
"""Generate tests for a
|
|
95
|
+
"""Generate tests for a workflow.
|
|
96
96
|
|
|
97
97
|
Args:
|
|
98
|
-
|
|
99
|
-
pattern_ids: List of pattern IDs used by
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
workflow_id: Workflow identifier
|
|
99
|
+
pattern_ids: List of pattern IDs used by workflow
|
|
100
|
+
workflow_module: Python module path (e.g., "workflows.soap_note")
|
|
101
|
+
workflow_class: Workflow class name (e.g., "SOAPNoteWorkflow")
|
|
102
102
|
|
|
103
103
|
Returns:
|
|
104
104
|
Dictionary with test types:
|
|
@@ -109,31 +109,31 @@ class TestGenerator:
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
"""
|
|
112
|
-
logger.info(f"Generating tests for
|
|
112
|
+
logger.info(f"Generating tests for workflow: {workflow_id}")
|
|
113
113
|
|
|
114
114
|
# Perform risk analysis
|
|
115
|
-
risk_analysis = self.risk_analyzer.analyze(
|
|
115
|
+
risk_analysis = self.risk_analyzer.analyze(workflow_id, pattern_ids)
|
|
116
116
|
|
|
117
117
|
# Infer module and class if not provided
|
|
118
|
-
if not
|
|
119
|
-
|
|
118
|
+
if not workflow_module:
|
|
119
|
+
workflow_module = self._infer_module(workflow_id)
|
|
120
120
|
|
|
121
|
-
if not
|
|
122
|
-
|
|
121
|
+
if not workflow_class:
|
|
122
|
+
workflow_class = self._infer_class_name(workflow_id)
|
|
123
123
|
|
|
124
124
|
# Gather template context
|
|
125
125
|
context = self._build_template_context(
|
|
126
|
-
|
|
126
|
+
workflow_id=workflow_id,
|
|
127
127
|
pattern_ids=pattern_ids,
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
workflow_module=workflow_module,
|
|
129
|
+
workflow_class=workflow_class,
|
|
130
130
|
risk_analysis=risk_analysis,
|
|
131
131
|
)
|
|
132
132
|
|
|
133
133
|
# Generate unit tests (always)
|
|
134
134
|
unit_tests = self._generate_unit_tests(context)
|
|
135
135
|
|
|
136
|
-
# Generate integration tests (for multi-step
|
|
136
|
+
# Generate integration tests (for multi-step workflows)
|
|
137
137
|
integration_tests = None
|
|
138
138
|
if self._needs_integration_tests(pattern_ids):
|
|
139
139
|
integration_tests = self._generate_integration_tests(context)
|
|
@@ -142,7 +142,7 @@ class TestGenerator:
|
|
|
142
142
|
fixtures = self._generate_fixtures(context)
|
|
143
143
|
|
|
144
144
|
logger.info(
|
|
145
|
-
f"Generated tests for {
|
|
145
|
+
f"Generated tests for {workflow_id}: "
|
|
146
146
|
f"unit={len(unit_tests)} chars, "
|
|
147
147
|
f"integration={'yes' if integration_tests else 'no'}, "
|
|
148
148
|
f"fixtures={len(fixtures)} chars"
|
|
@@ -156,19 +156,19 @@ class TestGenerator:
|
|
|
156
156
|
|
|
157
157
|
def _build_template_context(
|
|
158
158
|
self,
|
|
159
|
-
|
|
159
|
+
workflow_id: str,
|
|
160
160
|
pattern_ids: list[str],
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
workflow_module: str,
|
|
162
|
+
workflow_class: str,
|
|
163
163
|
risk_analysis: Any,
|
|
164
164
|
) -> dict:
|
|
165
165
|
"""Build Jinja2 template context.
|
|
166
166
|
|
|
167
167
|
Args:
|
|
168
|
-
|
|
168
|
+
workflow_id: Workflow identifier
|
|
169
169
|
pattern_ids: Pattern IDs
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
workflow_module: Module path
|
|
171
|
+
workflow_class: Class name
|
|
172
172
|
risk_analysis: RiskAnalysis object
|
|
173
173
|
|
|
174
174
|
Returns:
|
|
@@ -182,7 +182,7 @@ class TestGenerator:
|
|
|
182
182
|
has_linear_flow = "linear_flow" in pattern_ids
|
|
183
183
|
has_phased = "phased_processing" in pattern_ids
|
|
184
184
|
has_approval = "approval" in pattern_ids
|
|
185
|
-
has_async = True # Assume async by default for modern
|
|
185
|
+
has_async = True # Assume async by default for modern workflows
|
|
186
186
|
|
|
187
187
|
# Get linear flow details if present
|
|
188
188
|
total_steps = None
|
|
@@ -199,9 +199,9 @@ class TestGenerator:
|
|
|
199
199
|
phases = phased_pattern.phases
|
|
200
200
|
|
|
201
201
|
return {
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
"
|
|
202
|
+
"workflow_id": workflow_id,
|
|
203
|
+
"workflow_module": workflow_module,
|
|
204
|
+
"workflow_class": workflow_class,
|
|
205
205
|
"pattern_ids": pattern_ids,
|
|
206
206
|
"patterns": patterns,
|
|
207
207
|
"risk_analysis": risk_analysis,
|
|
@@ -239,30 +239,30 @@ class TestGenerator:
|
|
|
239
239
|
"""
|
|
240
240
|
# For now, return a simple integration test template
|
|
241
241
|
# In full implementation, would use integration_test.py.jinja2
|
|
242
|
-
return f'''"""Integration tests for {context["
|
|
242
|
+
return f'''"""Integration tests for {context["workflow_id"]} workflow.
|
|
243
243
|
|
|
244
244
|
Auto-generated by Empathy Framework Test Generator
|
|
245
|
-
Tests end-to-end
|
|
245
|
+
Tests end-to-end workflow workflows.
|
|
246
246
|
"""
|
|
247
247
|
|
|
248
248
|
import pytest
|
|
249
|
-
from {context["
|
|
249
|
+
from {context["workflow_module"]} import {context["workflow_class"]}
|
|
250
250
|
|
|
251
251
|
|
|
252
|
-
class TestIntegration{context["
|
|
253
|
-
"""Integration tests for {context["
|
|
252
|
+
class TestIntegration{context["workflow_class"]}:
|
|
253
|
+
"""Integration tests for {context["workflow_id"]} workflow."""
|
|
254
254
|
|
|
255
255
|
@pytest.fixture
|
|
256
|
-
async def
|
|
257
|
-
"""Create
|
|
258
|
-
return {context["
|
|
256
|
+
async def workflow(self):
|
|
257
|
+
"""Create workflow instance."""
|
|
258
|
+
return {context["workflow_class"]}()
|
|
259
259
|
|
|
260
260
|
@pytest.mark.asyncio
|
|
261
|
-
async def
|
|
262
|
-
"""Test complete
|
|
263
|
-
# Start
|
|
264
|
-
session = await
|
|
265
|
-
|
|
261
|
+
async def test_complete_workflow_workflow(self, workflow):
|
|
262
|
+
"""Test complete workflow workflow end-to-end."""
|
|
263
|
+
# Start workflow
|
|
264
|
+
session = await workflow.start()
|
|
265
|
+
workflow_id = session["workflow_id"]
|
|
266
266
|
|
|
267
267
|
# Complete all steps with valid data
|
|
268
268
|
# TODO: Add step completion logic
|
|
@@ -281,7 +281,7 @@ class TestIntegration{context["wizard_class"]}:
|
|
|
281
281
|
Generated fixture code
|
|
282
282
|
|
|
283
283
|
"""
|
|
284
|
-
return f'''"""Test fixtures for {context["
|
|
284
|
+
return f'''"""Test fixtures for {context["workflow_id"]} workflow.
|
|
285
285
|
|
|
286
286
|
Auto-generated by Empathy Framework Test Generator
|
|
287
287
|
Provides common test data and mocks.
|
|
@@ -292,8 +292,8 @@ from unittest.mock import MagicMock
|
|
|
292
292
|
|
|
293
293
|
|
|
294
294
|
@pytest.fixture
|
|
295
|
-
def sample_{context["
|
|
296
|
-
"""Sample data for {context["
|
|
295
|
+
def sample_{context["workflow_id"]}_data():
|
|
296
|
+
"""Sample data for {context["workflow_id"]} workflow."""
|
|
297
297
|
return {{
|
|
298
298
|
"field1": "test value 1",
|
|
299
299
|
"field2": "test value 2",
|
|
@@ -301,8 +301,8 @@ def sample_{context["wizard_id"]}_data():
|
|
|
301
301
|
|
|
302
302
|
|
|
303
303
|
@pytest.fixture
|
|
304
|
-
def mock_{context["
|
|
305
|
-
"""Mock dependencies for {context["
|
|
304
|
+
def mock_{context["workflow_id"]}_dependencies():
|
|
305
|
+
"""Mock dependencies for {context["workflow_id"]} workflow."""
|
|
306
306
|
return {{
|
|
307
307
|
"database": MagicMock(),
|
|
308
308
|
"api_client": MagicMock(),
|
|
@@ -319,39 +319,37 @@ def mock_{context["wizard_id"]}_dependencies():
|
|
|
319
319
|
True if integration tests recommended
|
|
320
320
|
|
|
321
321
|
"""
|
|
322
|
-
# Integration tests for multi-step or phased
|
|
322
|
+
# Integration tests for multi-step or phased workflows
|
|
323
323
|
return "linear_flow" in pattern_ids or "phased_processing" in pattern_ids
|
|
324
324
|
|
|
325
|
-
def _infer_module(self,
|
|
326
|
-
"""Infer module path from
|
|
325
|
+
def _infer_module(self, workflow_id: str) -> str:
|
|
326
|
+
"""Infer module path from workflow ID.
|
|
327
327
|
|
|
328
328
|
Args:
|
|
329
|
-
|
|
329
|
+
workflow_id: Workflow identifier
|
|
330
330
|
|
|
331
331
|
Returns:
|
|
332
332
|
Inferred module path
|
|
333
333
|
|
|
334
334
|
"""
|
|
335
|
-
# Try to determine
|
|
335
|
+
# Try to determine workflow location
|
|
336
336
|
# This is a simple heuristic - can be improved
|
|
337
|
-
if
|
|
338
|
-
return f"
|
|
339
|
-
elif wizard_id in ["debugging", "testing", "security"]:
|
|
340
|
-
return f"coach_wizards.{wizard_id}_wizard"
|
|
337
|
+
if workflow_id in ["soap_note", "sbar", "care_plan"]:
|
|
338
|
+
return f"workflows.{workflow_id}"
|
|
341
339
|
else:
|
|
342
|
-
return f"
|
|
340
|
+
return f"workflows.{workflow_id}_workflow"
|
|
343
341
|
|
|
344
|
-
def _infer_class_name(self,
|
|
345
|
-
"""Infer
|
|
342
|
+
def _infer_class_name(self, workflow_id: str) -> str:
|
|
343
|
+
"""Infer workflow class name from ID.
|
|
346
344
|
|
|
347
345
|
Args:
|
|
348
|
-
|
|
346
|
+
workflow_id: Workflow identifier
|
|
349
347
|
|
|
350
348
|
Returns:
|
|
351
349
|
Inferred class name
|
|
352
350
|
|
|
353
351
|
"""
|
|
354
|
-
# Convert snake_case to PascalCase and add "
|
|
355
|
-
parts =
|
|
352
|
+
# Convert snake_case to PascalCase and add "Workflow"
|
|
353
|
+
parts = workflow_id.split("_")
|
|
356
354
|
class_name = "".join(part.capitalize() for part in parts)
|
|
357
|
-
return f"{class_name}
|
|
355
|
+
return f"{class_name}Workflow"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Risk analyzer for test generation.
|
|
2
2
|
|
|
3
|
-
Analyzes
|
|
3
|
+
Analyzes workflow patterns to identify critical paths and determine
|
|
4
4
|
appropriate test coverage levels.
|
|
5
5
|
|
|
6
6
|
Copyright 2025 Smart AI Memory, LLC
|
|
@@ -20,9 +20,9 @@ logger = logging.getLogger(__name__)
|
|
|
20
20
|
|
|
21
21
|
@dataclass
|
|
22
22
|
class RiskAnalysis:
|
|
23
|
-
"""Risk analysis results for a
|
|
23
|
+
"""Risk analysis results for a workflow."""
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
workflow_id: str
|
|
26
26
|
pattern_ids: list[str]
|
|
27
27
|
critical_paths: list[str] = field(default_factory=list)
|
|
28
28
|
high_risk_inputs: list[str] = field(default_factory=list)
|
|
@@ -54,7 +54,7 @@ class RiskAnalysis:
|
|
|
54
54
|
def to_dict(self) -> dict:
|
|
55
55
|
"""Convert to dictionary."""
|
|
56
56
|
return {
|
|
57
|
-
"
|
|
57
|
+
"workflow_id": self.workflow_id,
|
|
58
58
|
"pattern_ids": self.pattern_ids,
|
|
59
59
|
"critical_paths": self.critical_paths,
|
|
60
60
|
"high_risk_inputs": self.high_risk_inputs,
|
|
@@ -65,7 +65,7 @@ class RiskAnalysis:
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
class RiskAnalyzer:
|
|
68
|
-
"""Analyzes
|
|
68
|
+
"""Analyzes workflow patterns to determine testing requirements.
|
|
69
69
|
|
|
70
70
|
Uses pattern analysis to identify:
|
|
71
71
|
- Critical execution paths
|
|
@@ -78,21 +78,21 @@ class RiskAnalyzer:
|
|
|
78
78
|
"""Initialize risk analyzer."""
|
|
79
79
|
self.registry = get_pattern_registry()
|
|
80
80
|
|
|
81
|
-
def analyze(self,
|
|
82
|
-
"""Analyze
|
|
81
|
+
def analyze(self, workflow_id: str, pattern_ids: list[str]) -> RiskAnalysis:
|
|
82
|
+
"""Analyze workflow patterns for risk.
|
|
83
83
|
|
|
84
84
|
Args:
|
|
85
|
-
|
|
86
|
-
pattern_ids: List of pattern IDs used by
|
|
85
|
+
workflow_id: Workflow identifier
|
|
86
|
+
pattern_ids: List of pattern IDs used by workflow
|
|
87
87
|
|
|
88
88
|
Returns:
|
|
89
89
|
RiskAnalysis with recommendations
|
|
90
90
|
|
|
91
91
|
"""
|
|
92
|
-
logger.info(f"Analyzing risk for
|
|
92
|
+
logger.info(f"Analyzing risk for workflow: {workflow_id}")
|
|
93
93
|
|
|
94
94
|
analysis = RiskAnalysis(
|
|
95
|
-
|
|
95
|
+
workflow_id=workflow_id,
|
|
96
96
|
pattern_ids=pattern_ids,
|
|
97
97
|
)
|
|
98
98
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""VS Code Extension Bridge
|
|
2
|
+
|
|
3
|
+
Provides functions to write data that the VS Code extension can pick up.
|
|
4
|
+
Enables Claude Code CLI output to appear in VS Code webview panels.
|
|
5
|
+
|
|
6
|
+
Copyright 2026 Smart-AI-Memory
|
|
7
|
+
Licensed under Fair Source License 0.9
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from dataclasses import asdict, dataclass
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ReviewFinding:
|
|
19
|
+
"""A code review finding."""
|
|
20
|
+
|
|
21
|
+
id: str
|
|
22
|
+
file: str
|
|
23
|
+
line: int
|
|
24
|
+
severity: str # 'critical' | 'high' | 'medium' | 'low' | 'info'
|
|
25
|
+
category: str # 'security' | 'performance' | 'maintainability' | 'style' | 'correctness'
|
|
26
|
+
message: str
|
|
27
|
+
column: int = 1
|
|
28
|
+
details: str | None = None
|
|
29
|
+
recommendation: str | None = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class CodeReviewResult:
|
|
34
|
+
"""Code review results for VS Code bridge."""
|
|
35
|
+
|
|
36
|
+
findings: list[dict[str, Any]]
|
|
37
|
+
summary: dict[str, Any]
|
|
38
|
+
verdict: str # 'approve' | 'approve_with_suggestions' | 'request_changes' | 'reject'
|
|
39
|
+
security_score: int
|
|
40
|
+
formatted_report: str
|
|
41
|
+
model_tier_used: str
|
|
42
|
+
timestamp: str
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_empathy_dir() -> Path:
|
|
46
|
+
"""Get the .empathy directory, creating if needed."""
|
|
47
|
+
empathy_dir = Path(".empathy")
|
|
48
|
+
empathy_dir.mkdir(exist_ok=True)
|
|
49
|
+
return empathy_dir
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def write_code_review_results(
|
|
53
|
+
findings: list[dict[str, Any]] | None = None,
|
|
54
|
+
summary: dict[str, Any] | None = None,
|
|
55
|
+
verdict: str = "approve_with_suggestions",
|
|
56
|
+
security_score: int = 85,
|
|
57
|
+
formatted_report: str = "",
|
|
58
|
+
model_tier_used: str = "capable",
|
|
59
|
+
) -> Path:
|
|
60
|
+
"""Write code review results for VS Code extension to pick up.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
findings: List of finding dicts with keys: id, file, line, severity, category, message
|
|
64
|
+
summary: Summary dict with keys: total_findings, by_severity, by_category, files_affected
|
|
65
|
+
verdict: One of 'approve', 'approve_with_suggestions', 'request_changes', 'reject'
|
|
66
|
+
security_score: 0-100 score
|
|
67
|
+
formatted_report: Markdown formatted report
|
|
68
|
+
model_tier_used: 'cheap', 'capable', or 'premium'
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Path to the written file
|
|
72
|
+
"""
|
|
73
|
+
findings = findings or []
|
|
74
|
+
|
|
75
|
+
# Build summary if not provided
|
|
76
|
+
if summary is None:
|
|
77
|
+
by_severity: dict[str, int] = {}
|
|
78
|
+
by_category: dict[str, int] = {}
|
|
79
|
+
files_affected: set[str] = set()
|
|
80
|
+
|
|
81
|
+
for f in findings:
|
|
82
|
+
sev = f.get("severity", "info")
|
|
83
|
+
cat = f.get("category", "correctness")
|
|
84
|
+
by_severity[sev] = by_severity.get(sev, 0) + 1
|
|
85
|
+
by_category[cat] = by_category.get(cat, 0) + 1
|
|
86
|
+
if f.get("file"):
|
|
87
|
+
files_affected.add(f["file"])
|
|
88
|
+
|
|
89
|
+
summary = {
|
|
90
|
+
"total_findings": len(findings),
|
|
91
|
+
"by_severity": by_severity,
|
|
92
|
+
"by_category": by_category,
|
|
93
|
+
"files_affected": list(files_affected),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
result = CodeReviewResult(
|
|
97
|
+
findings=findings,
|
|
98
|
+
summary=summary,
|
|
99
|
+
verdict=verdict,
|
|
100
|
+
security_score=security_score,
|
|
101
|
+
formatted_report=formatted_report,
|
|
102
|
+
model_tier_used=model_tier_used,
|
|
103
|
+
timestamp=datetime.now().isoformat(),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
output_path = get_empathy_dir() / "code-review-results.json"
|
|
107
|
+
|
|
108
|
+
with open(output_path, "w") as f:
|
|
109
|
+
json.dump(asdict(result), f, indent=2)
|
|
110
|
+
|
|
111
|
+
return output_path
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def write_pr_review_results(
|
|
115
|
+
pr_number: int | str,
|
|
116
|
+
title: str,
|
|
117
|
+
findings: list[dict[str, Any]],
|
|
118
|
+
verdict: str = "approve_with_suggestions",
|
|
119
|
+
summary_text: str = "",
|
|
120
|
+
) -> Path:
|
|
121
|
+
"""Write PR review results for VS Code extension.
|
|
122
|
+
|
|
123
|
+
Convenience wrapper for PR reviews from GitHub.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
pr_number: The PR number
|
|
127
|
+
title: PR title
|
|
128
|
+
findings: List of review findings
|
|
129
|
+
verdict: Review verdict
|
|
130
|
+
summary_text: Summary of the review
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Path to the written file
|
|
134
|
+
"""
|
|
135
|
+
formatted_report = f"""## PR #{pr_number}: {title}
|
|
136
|
+
|
|
137
|
+
{summary_text}
|
|
138
|
+
|
|
139
|
+
### Findings ({len(findings)})
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
for f in findings:
|
|
143
|
+
formatted_report += f"- **{f.get('severity', 'info').upper()}** [{f.get('file', 'unknown')}:{f.get('line', 0)}]: {f.get('message', '')}\n"
|
|
144
|
+
|
|
145
|
+
return write_code_review_results(
|
|
146
|
+
findings=findings,
|
|
147
|
+
verdict=verdict,
|
|
148
|
+
formatted_report=formatted_report,
|
|
149
|
+
model_tier_used="capable",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Quick helper for Claude Code to call
|
|
154
|
+
def send_to_vscode(
|
|
155
|
+
message: str,
|
|
156
|
+
findings: list[dict[str, Any]] | None = None,
|
|
157
|
+
verdict: str = "approve_with_suggestions",
|
|
158
|
+
) -> str:
|
|
159
|
+
"""Quick helper to send review results to VS Code.
|
|
160
|
+
|
|
161
|
+
Usage in Claude Code:
|
|
162
|
+
from empathy_os.vscode_bridge import send_to_vscode
|
|
163
|
+
send_to_vscode("Review complete", findings=[...])
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Confirmation message
|
|
167
|
+
"""
|
|
168
|
+
path = write_code_review_results(
|
|
169
|
+
findings=findings or [],
|
|
170
|
+
formatted_report=message,
|
|
171
|
+
verdict=verdict,
|
|
172
|
+
)
|
|
173
|
+
return f"Results written to {path} - VS Code will update automatically"
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""VS Code Extension Bridge
|
|
2
|
+
|
|
3
|
+
Provides functions to write data that the VS Code extension can pick up.
|
|
4
|
+
Enables Claude Code CLI output to appear in VS Code webview panels.
|
|
5
|
+
|
|
6
|
+
Copyright 2026 Smart-AI-Memory
|
|
7
|
+
Licensed under Fair Source License 0.9
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
from dataclasses import asdict, dataclass
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class ReviewFinding:
|
|
19
|
+
"""A code review finding."""
|
|
20
|
+
|
|
21
|
+
id: str
|
|
22
|
+
file: str
|
|
23
|
+
line: int
|
|
24
|
+
severity: str # 'critical' | 'high' | 'medium' | 'low' | 'info'
|
|
25
|
+
category: str # 'security' | 'performance' | 'maintainability' | 'style' | 'correctness'
|
|
26
|
+
message: str
|
|
27
|
+
column: int = 1
|
|
28
|
+
details: str | None = None
|
|
29
|
+
recommendation: str | None = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class CodeReviewResult:
|
|
34
|
+
"""Code review results for VS Code bridge."""
|
|
35
|
+
|
|
36
|
+
findings: list[dict[str, Any]]
|
|
37
|
+
summary: dict[str, Any]
|
|
38
|
+
verdict: str # 'approve' | 'approve_with_suggestions' | 'request_changes' | 'reject'
|
|
39
|
+
security_score: int
|
|
40
|
+
formatted_report: str
|
|
41
|
+
model_tier_used: str
|
|
42
|
+
timestamp: str
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_empathy_dir() -> Path:
|
|
46
|
+
"""Get the .empathy directory, creating if needed."""
|
|
47
|
+
empathy_dir = Path(".empathy")
|
|
48
|
+
empathy_dir.mkdir(exist_ok=True)
|
|
49
|
+
return empathy_dir
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def write_code_review_results(
|
|
53
|
+
findings: list[dict[str, Any]] | None = None,
|
|
54
|
+
summary: dict[str, Any] | None = None,
|
|
55
|
+
verdict: str = "approve_with_suggestions",
|
|
56
|
+
security_score: int = 85,
|
|
57
|
+
formatted_report: str = "",
|
|
58
|
+
model_tier_used: str = "capable",
|
|
59
|
+
) -> Path:
|
|
60
|
+
"""Write code review results for VS Code extension to pick up.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
findings: List of finding dicts with keys: id, file, line, severity, category, message
|
|
64
|
+
summary: Summary dict with keys: total_findings, by_severity, by_category, files_affected
|
|
65
|
+
verdict: One of 'approve', 'approve_with_suggestions', 'request_changes', 'reject'
|
|
66
|
+
security_score: 0-100 score
|
|
67
|
+
formatted_report: Markdown formatted report
|
|
68
|
+
model_tier_used: 'cheap', 'capable', or 'premium'
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Path to the written file
|
|
72
|
+
"""
|
|
73
|
+
findings = findings or []
|
|
74
|
+
|
|
75
|
+
# Build summary if not provided
|
|
76
|
+
if summary is None:
|
|
77
|
+
by_severity: dict[str, int] = {}
|
|
78
|
+
by_category: dict[str, int] = {}
|
|
79
|
+
files_affected: set[str] = set()
|
|
80
|
+
|
|
81
|
+
for f in findings:
|
|
82
|
+
sev = f.get("severity", "info")
|
|
83
|
+
cat = f.get("category", "correctness")
|
|
84
|
+
by_severity[sev] = by_severity.get(sev, 0) + 1
|
|
85
|
+
by_category[cat] = by_category.get(cat, 0) + 1
|
|
86
|
+
if f.get("file"):
|
|
87
|
+
files_affected.add(f["file"])
|
|
88
|
+
|
|
89
|
+
summary = {
|
|
90
|
+
"total_findings": len(findings),
|
|
91
|
+
"by_severity": by_severity,
|
|
92
|
+
"by_category": by_category,
|
|
93
|
+
"files_affected": list(files_affected),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
result = CodeReviewResult(
|
|
97
|
+
findings=findings,
|
|
98
|
+
summary=summary,
|
|
99
|
+
verdict=verdict,
|
|
100
|
+
security_score=security_score,
|
|
101
|
+
formatted_report=formatted_report,
|
|
102
|
+
model_tier_used=model_tier_used,
|
|
103
|
+
timestamp=datetime.now().isoformat(),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
output_path = get_empathy_dir() / "code-review-results.json"
|
|
107
|
+
|
|
108
|
+
with open(output_path, "w") as f:
|
|
109
|
+
json.dump(asdict(result), f, indent=2)
|
|
110
|
+
|
|
111
|
+
return output_path
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def write_pr_review_results(
|
|
115
|
+
pr_number: int | str,
|
|
116
|
+
title: str,
|
|
117
|
+
findings: list[dict[str, Any]],
|
|
118
|
+
verdict: str = "approve_with_suggestions",
|
|
119
|
+
summary_text: str = "",
|
|
120
|
+
) -> Path:
|
|
121
|
+
"""Write PR review results for VS Code extension.
|
|
122
|
+
|
|
123
|
+
Convenience wrapper for PR reviews from GitHub.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
pr_number: The PR number
|
|
127
|
+
title: PR title
|
|
128
|
+
findings: List of review findings
|
|
129
|
+
verdict: Review verdict
|
|
130
|
+
summary_text: Summary of the review
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Path to the written file
|
|
134
|
+
"""
|
|
135
|
+
formatted_report = f"""## PR #{pr_number}: {title}
|
|
136
|
+
|
|
137
|
+
{summary_text}
|
|
138
|
+
|
|
139
|
+
### Findings ({len(findings)})
|
|
140
|
+
|
|
141
|
+
"""
|
|
142
|
+
for f in findings:
|
|
143
|
+
formatted_report += f"- **{f.get('severity', 'info').upper()}** [{f.get('file', 'unknown')}:{f.get('line', 0)}]: {f.get('message', '')}\n"
|
|
144
|
+
|
|
145
|
+
return write_code_review_results(
|
|
146
|
+
findings=findings,
|
|
147
|
+
verdict=verdict,
|
|
148
|
+
formatted_report=formatted_report,
|
|
149
|
+
model_tier_used="capable",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Quick helper for Claude Code to call
|
|
154
|
+
def send_to_vscode(
|
|
155
|
+
message: str,
|
|
156
|
+
findings: list[dict[str, Any]] | None = None,
|
|
157
|
+
verdict: str = "approve_with_suggestions",
|
|
158
|
+
) -> str:
|
|
159
|
+
"""Quick helper to send review results to VS Code.
|
|
160
|
+
|
|
161
|
+
Usage in Claude Code:
|
|
162
|
+
from empathy_os.vscode_bridge import send_to_vscode
|
|
163
|
+
send_to_vscode("Review complete", findings=[...])
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Confirmation message
|
|
167
|
+
"""
|
|
168
|
+
path = write_code_review_results(
|
|
169
|
+
findings=findings or [],
|
|
170
|
+
formatted_report=message,
|
|
171
|
+
verdict=verdict,
|
|
172
|
+
)
|
|
173
|
+
return f"Results written to {path} - VS Code will update automatically"
|