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
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
"""Core data structures for progressive tier escalation.
|
|
2
|
+
|
|
3
|
+
This module defines the fundamental data structures used throughout the
|
|
4
|
+
progressive escalation system, including failure analysis, quality metrics,
|
|
5
|
+
tier results, and configuration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from enum import Enum
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Tier(Enum):
|
|
15
|
+
"""Model tier levels for progressive escalation.
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
CHEAP: Low-cost models (e.g., gpt-4o-mini, claude-3-haiku)
|
|
19
|
+
CAPABLE: Mid-tier models (e.g., claude-3-5-sonnet, gpt-4o)
|
|
20
|
+
PREMIUM: High-end models (e.g., claude-opus-4, o1)
|
|
21
|
+
"""
|
|
22
|
+
CHEAP = "cheap"
|
|
23
|
+
CAPABLE = "capable"
|
|
24
|
+
PREMIUM = "premium"
|
|
25
|
+
|
|
26
|
+
def __lt__(self, other: "Tier") -> bool:
|
|
27
|
+
"""Compare tiers for ordering (CHEAP < CAPABLE < PREMIUM)."""
|
|
28
|
+
order = {Tier.CHEAP: 0, Tier.CAPABLE: 1, Tier.PREMIUM: 2}
|
|
29
|
+
return order[self] < order[other]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class FailureAnalysis:
|
|
34
|
+
"""Multi-signal failure detection and quality analysis.
|
|
35
|
+
|
|
36
|
+
Combines multiple signals to provide robust failure detection:
|
|
37
|
+
1. Syntax errors in generated code
|
|
38
|
+
2. Execution failures (test pass rate)
|
|
39
|
+
3. Quality metrics (coverage, assertion depth)
|
|
40
|
+
4. LLM confidence signals
|
|
41
|
+
|
|
42
|
+
The composite quality score (CQS) provides an objective measure
|
|
43
|
+
that combines all signals with appropriate weighting.
|
|
44
|
+
|
|
45
|
+
Attributes:
|
|
46
|
+
syntax_errors: List of syntax errors found in generated code
|
|
47
|
+
test_failures: List of test execution failures
|
|
48
|
+
test_pass_rate: Percentage of tests that passed (0.0-1.0)
|
|
49
|
+
coverage_percent: Code coverage percentage (0.0-100.0)
|
|
50
|
+
assertion_depth: Average number of assertions per test
|
|
51
|
+
confidence_score: LLM confidence level (0.0-1.0)
|
|
52
|
+
llm_uncertainty_signals: Uncertainty phrases detected in LLM response
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
>>> analysis = FailureAnalysis(
|
|
56
|
+
... test_pass_rate=0.85,
|
|
57
|
+
... coverage_percent=78.0,
|
|
58
|
+
... assertion_depth=5.2,
|
|
59
|
+
... confidence_score=0.92
|
|
60
|
+
... )
|
|
61
|
+
>>> analysis.calculate_quality_score()
|
|
62
|
+
87.7
|
|
63
|
+
>>> analysis.should_escalate
|
|
64
|
+
False
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
syntax_errors: list[SyntaxError] = field(default_factory=list)
|
|
68
|
+
test_failures: list[dict[str, Any]] = field(default_factory=list)
|
|
69
|
+
test_pass_rate: float = 0.0
|
|
70
|
+
coverage_percent: float = 0.0
|
|
71
|
+
assertion_depth: float = 0.0
|
|
72
|
+
confidence_score: float = 0.0
|
|
73
|
+
llm_uncertainty_signals: list[str] = field(default_factory=list)
|
|
74
|
+
|
|
75
|
+
def calculate_quality_score(self) -> float:
|
|
76
|
+
"""Calculate composite quality score (CQS) from 0-100.
|
|
77
|
+
|
|
78
|
+
Formula:
|
|
79
|
+
CQS = (
|
|
80
|
+
0.40 × test_pass_rate +
|
|
81
|
+
0.25 × code_coverage +
|
|
82
|
+
0.20 × assertion_quality +
|
|
83
|
+
0.15 × llm_confidence
|
|
84
|
+
) × syntax_error_penalty
|
|
85
|
+
|
|
86
|
+
Weights:
|
|
87
|
+
- Test pass rate: 40% (most important - functionality must work)
|
|
88
|
+
- Code coverage: 25% (thoroughness matters)
|
|
89
|
+
- Assertion quality: 20% (test depth is important)
|
|
90
|
+
- LLM confidence: 15% (signals potential brittleness)
|
|
91
|
+
|
|
92
|
+
Penalties:
|
|
93
|
+
- Syntax errors: 50% penalty (halves the score)
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
Quality score from 0.0 (worst) to 100.0 (perfect)
|
|
97
|
+
|
|
98
|
+
Example:
|
|
99
|
+
>>> analysis = FailureAnalysis(
|
|
100
|
+
... test_pass_rate=0.90,
|
|
101
|
+
... coverage_percent=85.0,
|
|
102
|
+
... assertion_depth=6.0,
|
|
103
|
+
... confidence_score=0.95
|
|
104
|
+
... )
|
|
105
|
+
>>> analysis.calculate_quality_score()
|
|
106
|
+
91.25
|
|
107
|
+
"""
|
|
108
|
+
# Component scores (convert to 0-100 scale)
|
|
109
|
+
pass_rate_score = self.test_pass_rate * 100
|
|
110
|
+
coverage_score = self.coverage_percent
|
|
111
|
+
|
|
112
|
+
# Assertion quality: cap at 100% (10 assertions = 100%)
|
|
113
|
+
assertion_quality_score = min(self.assertion_depth * 10, 100)
|
|
114
|
+
|
|
115
|
+
confidence_score_scaled = self.confidence_score * 100
|
|
116
|
+
|
|
117
|
+
# Weighted composite
|
|
118
|
+
cqs = (
|
|
119
|
+
0.40 * pass_rate_score +
|
|
120
|
+
0.25 * coverage_score +
|
|
121
|
+
0.20 * assertion_quality_score +
|
|
122
|
+
0.15 * confidence_score_scaled
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Apply syntax error penalty
|
|
126
|
+
if len(self.syntax_errors) > 0:
|
|
127
|
+
cqs *= 0.5 # Halve score for any syntax errors
|
|
128
|
+
|
|
129
|
+
return min(cqs, 100.0)
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def should_escalate(self) -> bool:
|
|
133
|
+
"""Determine if this result should trigger escalation.
|
|
134
|
+
|
|
135
|
+
Multi-criteria decision based on:
|
|
136
|
+
- Low CQS (<70)
|
|
137
|
+
- Multiple syntax errors (>3)
|
|
138
|
+
- Low test pass rate (<70%)
|
|
139
|
+
- Low coverage (<60%)
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
True if escalation is recommended, False otherwise
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
>>> analysis = FailureAnalysis(test_pass_rate=0.50)
|
|
146
|
+
>>> analysis.should_escalate
|
|
147
|
+
True
|
|
148
|
+
"""
|
|
149
|
+
cqs = self.calculate_quality_score()
|
|
150
|
+
return (
|
|
151
|
+
cqs < 70 or
|
|
152
|
+
len(self.syntax_errors) > 3 or
|
|
153
|
+
self.test_pass_rate < 0.7 or
|
|
154
|
+
self.coverage_percent < 60
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def failure_severity(self) -> str:
|
|
159
|
+
"""Determine severity level of failures.
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
"CRITICAL": Severe failures, consider skipping to Premium
|
|
163
|
+
"HIGH": Significant failures, escalate to next tier
|
|
164
|
+
"MODERATE": Minor failures, retry at current tier
|
|
165
|
+
"LOW": Acceptable quality, no escalation needed
|
|
166
|
+
|
|
167
|
+
Example:
|
|
168
|
+
>>> analysis = FailureAnalysis(test_pass_rate=0.25)
|
|
169
|
+
>>> analysis.failure_severity
|
|
170
|
+
'CRITICAL'
|
|
171
|
+
"""
|
|
172
|
+
cqs = self.calculate_quality_score()
|
|
173
|
+
|
|
174
|
+
if len(self.syntax_errors) > 5 or self.test_pass_rate < 0.3:
|
|
175
|
+
return "CRITICAL"
|
|
176
|
+
elif cqs < 70 or self.test_pass_rate < 0.5:
|
|
177
|
+
return "HIGH"
|
|
178
|
+
elif cqs < 80 or self.test_pass_rate < 0.7:
|
|
179
|
+
return "MODERATE"
|
|
180
|
+
else:
|
|
181
|
+
return "LOW"
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@dataclass
|
|
185
|
+
class TierResult:
|
|
186
|
+
"""Results from a single tier execution attempt.
|
|
187
|
+
|
|
188
|
+
Captures all information about a tier's execution including
|
|
189
|
+
generated artifacts, quality analysis, cost, and escalation decision.
|
|
190
|
+
|
|
191
|
+
Attributes:
|
|
192
|
+
tier: Which tier executed (CHEAP, CAPABLE, or PREMIUM)
|
|
193
|
+
model: Specific model used (e.g., "gpt-4o-mini")
|
|
194
|
+
attempt: Attempt number at this tier (1-based)
|
|
195
|
+
timestamp: When this execution occurred
|
|
196
|
+
generated_items: Generated artifacts (tests, code, etc.)
|
|
197
|
+
failure_analysis: Quality and failure analysis
|
|
198
|
+
cost: Cost in USD for this execution
|
|
199
|
+
duration: Execution time in seconds
|
|
200
|
+
escalated: Whether this result triggered escalation
|
|
201
|
+
escalation_reason: Human-readable reason for escalation
|
|
202
|
+
|
|
203
|
+
Example:
|
|
204
|
+
>>> result = TierResult(
|
|
205
|
+
... tier=Tier.CHEAP,
|
|
206
|
+
... model="gpt-4o-mini",
|
|
207
|
+
... attempt=1,
|
|
208
|
+
... timestamp=datetime.now(),
|
|
209
|
+
... generated_items=[{"code": "test_foo()"}],
|
|
210
|
+
... failure_analysis=FailureAnalysis(test_pass_rate=0.65),
|
|
211
|
+
... cost=0.15,
|
|
212
|
+
... duration=12.5
|
|
213
|
+
... )
|
|
214
|
+
>>> result.quality_score
|
|
215
|
+
65.0
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
tier: Tier
|
|
219
|
+
model: str
|
|
220
|
+
attempt: int
|
|
221
|
+
timestamp: datetime
|
|
222
|
+
|
|
223
|
+
# Generated artifacts
|
|
224
|
+
generated_items: list[dict[str, Any]] = field(default_factory=list)
|
|
225
|
+
|
|
226
|
+
# Analysis
|
|
227
|
+
failure_analysis: FailureAnalysis = field(default_factory=FailureAnalysis)
|
|
228
|
+
cost: float = 0.0
|
|
229
|
+
duration: float = 0.0
|
|
230
|
+
tokens_used: dict[str, int] = field(default_factory=dict)
|
|
231
|
+
|
|
232
|
+
# Decision
|
|
233
|
+
escalated: bool = False
|
|
234
|
+
escalation_reason: str = ""
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def quality_score(self) -> float:
|
|
238
|
+
"""Get composite quality score for this tier result.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
CQS from 0.0 to 100.0
|
|
242
|
+
"""
|
|
243
|
+
return self.failure_analysis.calculate_quality_score()
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def success_count(self) -> int:
|
|
247
|
+
"""Count of successfully generated items (CQS >= 80).
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Number of items meeting quality threshold
|
|
251
|
+
"""
|
|
252
|
+
return sum(
|
|
253
|
+
1 for item in self.generated_items
|
|
254
|
+
if item.get("quality_score", 0) >= 80
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
@property
|
|
258
|
+
def success_rate(self) -> float:
|
|
259
|
+
"""Percentage of items successfully generated.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
Success rate from 0.0 to 1.0
|
|
263
|
+
"""
|
|
264
|
+
if not self.generated_items:
|
|
265
|
+
return 0.0
|
|
266
|
+
return self.success_count / len(self.generated_items)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@dataclass
|
|
270
|
+
class ProgressiveWorkflowResult:
|
|
271
|
+
"""Complete results from a progressive workflow execution.
|
|
272
|
+
|
|
273
|
+
Captures the full progression history across all tiers, including
|
|
274
|
+
costs, quality metrics, and escalation decisions.
|
|
275
|
+
|
|
276
|
+
Attributes:
|
|
277
|
+
workflow_name: Name of the workflow (e.g., "test-gen")
|
|
278
|
+
task_id: Unique identifier for this execution
|
|
279
|
+
tier_results: Chronological list of tier execution results
|
|
280
|
+
final_result: The last tier result (may be successful or failed)
|
|
281
|
+
total_cost: Total cost in USD across all tiers
|
|
282
|
+
total_duration: Total execution time in seconds
|
|
283
|
+
success: Whether the workflow completed successfully
|
|
284
|
+
|
|
285
|
+
Example:
|
|
286
|
+
>>> result = ProgressiveWorkflowResult(
|
|
287
|
+
... workflow_name="test-gen",
|
|
288
|
+
... task_id="test-gen-20260117-143022",
|
|
289
|
+
... tier_results=[cheap_result, capable_result],
|
|
290
|
+
... final_result=capable_result,
|
|
291
|
+
... total_cost=0.75,
|
|
292
|
+
... total_duration=45.2,
|
|
293
|
+
... success=True
|
|
294
|
+
... )
|
|
295
|
+
>>> print(result.generate_report())
|
|
296
|
+
🎯 PROGRESSIVE ESCALATION REPORT
|
|
297
|
+
...
|
|
298
|
+
"""
|
|
299
|
+
|
|
300
|
+
workflow_name: str
|
|
301
|
+
task_id: str
|
|
302
|
+
tier_results: list[TierResult]
|
|
303
|
+
|
|
304
|
+
final_result: TierResult
|
|
305
|
+
total_cost: float
|
|
306
|
+
total_duration: float
|
|
307
|
+
success: bool
|
|
308
|
+
|
|
309
|
+
def generate_report(self) -> str:
|
|
310
|
+
"""Generate human-readable progression report.
|
|
311
|
+
|
|
312
|
+
Creates a detailed report showing:
|
|
313
|
+
- Tier-by-tier breakdown
|
|
314
|
+
- Quality scores and success rates
|
|
315
|
+
- Cost analysis and savings
|
|
316
|
+
- Escalation decisions
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
Formatted report string
|
|
320
|
+
"""
|
|
321
|
+
# Implementation will be in reports.py module
|
|
322
|
+
from empathy_os.workflows.progressive.reports import generate_progression_report
|
|
323
|
+
return generate_progression_report(self)
|
|
324
|
+
|
|
325
|
+
def save_to_disk(self, storage_path: str) -> None:
|
|
326
|
+
"""Save detailed results to disk.
|
|
327
|
+
|
|
328
|
+
Creates a directory with:
|
|
329
|
+
- summary.json: High-level metrics
|
|
330
|
+
- tier_N_<tier_name>.json: Detailed tier results
|
|
331
|
+
- report.txt: Human-readable report
|
|
332
|
+
|
|
333
|
+
Args:
|
|
334
|
+
storage_path: Base path for saving results
|
|
335
|
+
"""
|
|
336
|
+
from empathy_os.workflows.progressive.reports import save_results_to_disk
|
|
337
|
+
save_results_to_disk(self, storage_path)
|
|
338
|
+
|
|
339
|
+
@property
|
|
340
|
+
def cost_savings(self) -> float:
|
|
341
|
+
"""Calculate cost savings vs running all items at Premium tier.
|
|
342
|
+
|
|
343
|
+
Returns:
|
|
344
|
+
Dollar amount saved by using progressive escalation
|
|
345
|
+
"""
|
|
346
|
+
# Estimate what it would cost if all items were Premium
|
|
347
|
+
total_items = sum(len(r.generated_items) for r in self.tier_results)
|
|
348
|
+
|
|
349
|
+
# Assume Premium costs ~$0.05 per item (conservative estimate)
|
|
350
|
+
all_premium_cost = total_items * 0.05
|
|
351
|
+
|
|
352
|
+
savings = all_premium_cost - self.total_cost
|
|
353
|
+
return max(savings, 0.0)
|
|
354
|
+
|
|
355
|
+
@property
|
|
356
|
+
def cost_savings_percent(self) -> float:
|
|
357
|
+
"""Calculate percentage of cost saved.
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
Savings percentage (0-100)
|
|
361
|
+
"""
|
|
362
|
+
total_items = sum(len(r.generated_items) for r in self.tier_results)
|
|
363
|
+
all_premium_cost = total_items * 0.05
|
|
364
|
+
|
|
365
|
+
if all_premium_cost == 0:
|
|
366
|
+
return 0.0
|
|
367
|
+
|
|
368
|
+
return (self.cost_savings / all_premium_cost) * 100
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
@dataclass
|
|
372
|
+
class EscalationConfig:
|
|
373
|
+
"""Configuration for progressive tier escalation.
|
|
374
|
+
|
|
375
|
+
Controls all aspects of the escalation system including retry logic,
|
|
376
|
+
thresholds, cost management, and storage.
|
|
377
|
+
|
|
378
|
+
Attributes:
|
|
379
|
+
enabled: Whether progressive escalation is active
|
|
380
|
+
tiers: Ordered list of tiers to use (default: all three)
|
|
381
|
+
|
|
382
|
+
Retry configuration:
|
|
383
|
+
cheap_min_attempts: Minimum attempts at cheap tier
|
|
384
|
+
cheap_max_attempts: Maximum attempts at cheap tier
|
|
385
|
+
capable_min_attempts: Minimum attempts at capable tier
|
|
386
|
+
capable_max_attempts: Maximum attempts at capable tier
|
|
387
|
+
premium_max_attempts: Maximum attempts at premium tier
|
|
388
|
+
|
|
389
|
+
Thresholds (Cheap → Capable):
|
|
390
|
+
cheap_to_capable_failure_rate: Max failure rate before escalation
|
|
391
|
+
cheap_to_capable_min_cqs: Min quality score to avoid escalation
|
|
392
|
+
cheap_to_capable_max_syntax_errors: Max syntax errors allowed
|
|
393
|
+
|
|
394
|
+
Thresholds (Capable → Premium):
|
|
395
|
+
capable_to_premium_failure_rate: Max failure rate before escalation
|
|
396
|
+
capable_to_premium_min_cqs: Min quality score to avoid escalation
|
|
397
|
+
capable_to_premium_max_syntax_errors: Max syntax errors allowed
|
|
398
|
+
|
|
399
|
+
Stagnation detection:
|
|
400
|
+
improvement_threshold: Min CQS improvement to avoid stagnation (%)
|
|
401
|
+
consecutive_stagnation_limit: Consecutive stagnations before escalation
|
|
402
|
+
|
|
403
|
+
Cost management:
|
|
404
|
+
max_cost: Maximum total cost in USD
|
|
405
|
+
auto_approve_under: Auto-approve escalations under this cost
|
|
406
|
+
warn_on_budget_exceeded: Print warning if budget exceeded
|
|
407
|
+
abort_on_budget_exceeded: Abort execution if budget exceeded
|
|
408
|
+
|
|
409
|
+
Storage:
|
|
410
|
+
save_tier_results: Whether to save tier results to disk
|
|
411
|
+
storage_path: Directory for saving results
|
|
412
|
+
|
|
413
|
+
Example:
|
|
414
|
+
>>> config = EscalationConfig(
|
|
415
|
+
... enabled=True,
|
|
416
|
+
... max_cost=10.00,
|
|
417
|
+
... auto_approve_under=5.00,
|
|
418
|
+
... cheap_min_attempts=2,
|
|
419
|
+
... capable_max_attempts=6
|
|
420
|
+
... )
|
|
421
|
+
"""
|
|
422
|
+
|
|
423
|
+
# Global settings
|
|
424
|
+
enabled: bool = False
|
|
425
|
+
tiers: list[Tier] = field(default_factory=lambda: [Tier.CHEAP, Tier.CAPABLE, Tier.PREMIUM])
|
|
426
|
+
|
|
427
|
+
# Retry configuration
|
|
428
|
+
cheap_min_attempts: int = 2
|
|
429
|
+
cheap_max_attempts: int = 3
|
|
430
|
+
capable_min_attempts: int = 2
|
|
431
|
+
capable_max_attempts: int = 6
|
|
432
|
+
premium_max_attempts: int = 1
|
|
433
|
+
|
|
434
|
+
# Thresholds: Cheap → Capable
|
|
435
|
+
cheap_to_capable_failure_rate: float = 0.30
|
|
436
|
+
cheap_to_capable_min_cqs: float = 70.0
|
|
437
|
+
cheap_to_capable_max_syntax_errors: int = 3
|
|
438
|
+
|
|
439
|
+
# Thresholds: Capable → Premium
|
|
440
|
+
capable_to_premium_failure_rate: float = 0.20
|
|
441
|
+
capable_to_premium_min_cqs: float = 80.0
|
|
442
|
+
capable_to_premium_max_syntax_errors: int = 1
|
|
443
|
+
|
|
444
|
+
# Stagnation detection
|
|
445
|
+
improvement_threshold: float = 5.0 # 5% CQS improvement required
|
|
446
|
+
consecutive_stagnation_limit: int = 2
|
|
447
|
+
|
|
448
|
+
# Cost management
|
|
449
|
+
max_cost: float = 5.00
|
|
450
|
+
auto_approve_under: float | None = None
|
|
451
|
+
warn_on_budget_exceeded: bool = True
|
|
452
|
+
abort_on_budget_exceeded: bool = False
|
|
453
|
+
|
|
454
|
+
# Storage
|
|
455
|
+
save_tier_results: bool = True
|
|
456
|
+
storage_path: str = ".empathy/progressive_runs"
|
|
457
|
+
|
|
458
|
+
def get_max_attempts(self, tier: Tier) -> int:
|
|
459
|
+
"""Get maximum attempts for a specific tier.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
tier: The tier to query
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
Maximum number of attempts allowed
|
|
466
|
+
"""
|
|
467
|
+
if tier == Tier.CHEAP:
|
|
468
|
+
return self.cheap_max_attempts
|
|
469
|
+
elif tier == Tier.CAPABLE:
|
|
470
|
+
return self.capable_max_attempts
|
|
471
|
+
else: # PREMIUM
|
|
472
|
+
return self.premium_max_attempts
|
|
473
|
+
|
|
474
|
+
def get_min_attempts(self, tier: Tier) -> int:
|
|
475
|
+
"""Get minimum attempts for a specific tier.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
tier: The tier to query
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
Minimum number of attempts required
|
|
482
|
+
"""
|
|
483
|
+
if tier == Tier.CHEAP:
|
|
484
|
+
return self.cheap_min_attempts
|
|
485
|
+
elif tier == Tier.CAPABLE:
|
|
486
|
+
return self.capable_min_attempts
|
|
487
|
+
else: # PREMIUM
|
|
488
|
+
return 1 # Premium always gets exactly 1 attempt
|
|
@@ -19,6 +19,7 @@ class Tier(Enum):
|
|
|
19
19
|
CAPABLE: Mid-tier models (e.g., claude-3-5-sonnet, gpt-4o)
|
|
20
20
|
PREMIUM: High-end models (e.g., claude-opus-4, o1)
|
|
21
21
|
"""
|
|
22
|
+
|
|
22
23
|
CHEAP = "cheap"
|
|
23
24
|
CAPABLE = "capable"
|
|
24
25
|
PREMIUM = "premium"
|
|
@@ -116,10 +117,10 @@ class FailureAnalysis:
|
|
|
116
117
|
|
|
117
118
|
# Weighted composite
|
|
118
119
|
cqs = (
|
|
119
|
-
0.40 * pass_rate_score
|
|
120
|
-
0.25 * coverage_score
|
|
121
|
-
0.20 * assertion_quality_score
|
|
122
|
-
0.15 * confidence_score_scaled
|
|
120
|
+
0.40 * pass_rate_score
|
|
121
|
+
+ 0.25 * coverage_score
|
|
122
|
+
+ 0.20 * assertion_quality_score
|
|
123
|
+
+ 0.15 * confidence_score_scaled
|
|
123
124
|
)
|
|
124
125
|
|
|
125
126
|
# Apply syntax error penalty
|
|
@@ -148,10 +149,10 @@ class FailureAnalysis:
|
|
|
148
149
|
"""
|
|
149
150
|
cqs = self.calculate_quality_score()
|
|
150
151
|
return (
|
|
151
|
-
cqs < 70
|
|
152
|
-
len(self.syntax_errors) > 3
|
|
153
|
-
self.test_pass_rate < 0.7
|
|
154
|
-
self.coverage_percent < 60
|
|
152
|
+
cqs < 70
|
|
153
|
+
or len(self.syntax_errors) > 3
|
|
154
|
+
or self.test_pass_rate < 0.7
|
|
155
|
+
or self.coverage_percent < 60
|
|
155
156
|
)
|
|
156
157
|
|
|
157
158
|
@property
|
|
@@ -249,10 +250,7 @@ class TierResult:
|
|
|
249
250
|
Returns:
|
|
250
251
|
Number of items meeting quality threshold
|
|
251
252
|
"""
|
|
252
|
-
return sum(
|
|
253
|
-
1 for item in self.generated_items
|
|
254
|
-
if item.get("quality_score", 0) >= 80
|
|
255
|
-
)
|
|
253
|
+
return sum(1 for item in self.generated_items if item.get("quality_score", 0) >= 80)
|
|
256
254
|
|
|
257
255
|
@property
|
|
258
256
|
def success_rate(self) -> float:
|
|
@@ -320,6 +318,7 @@ class ProgressiveWorkflowResult:
|
|
|
320
318
|
"""
|
|
321
319
|
# Implementation will be in reports.py module
|
|
322
320
|
from empathy_os.workflows.progressive.reports import generate_progression_report
|
|
321
|
+
|
|
323
322
|
return generate_progression_report(self)
|
|
324
323
|
|
|
325
324
|
def save_to_disk(self, storage_path: str) -> None:
|
|
@@ -334,6 +333,7 @@ class ProgressiveWorkflowResult:
|
|
|
334
333
|
storage_path: Base path for saving results
|
|
335
334
|
"""
|
|
336
335
|
from empathy_os.workflows.progressive.reports import save_results_to_disk
|
|
336
|
+
|
|
337
337
|
save_results_to_disk(self, storage_path)
|
|
338
338
|
|
|
339
339
|
@property
|