empathy-framework 4.6.6__py3-none-any.whl → 4.7.0__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.6.6.dist-info → empathy_framework-4.7.0.dist-info}/METADATA +7 -6
- empathy_framework-4.7.0.dist-info/RECORD +354 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/top_level.txt +0 -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.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/__init__.py +2 -12
- empathy_os/workflows/progressive/cli.py +14 -37
- empathy_os/workflows/progressive/core.py +12 -12
- empathy_os/workflows/progressive/orchestrator.py +166 -144
- empathy_os/workflows/progressive/reports.py +22 -31
- empathy_os/workflows/progressive/telemetry.py +8 -14
- empathy_os/workflows/progressive/test_gen.py +29 -48
- 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
- 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/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.0.dist-info}/WHEEL +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/entry_points.txt +0 -0
- {empathy_framework-4.6.6.dist-info → empathy_framework-4.7.0.dist-info}/licenses/LICENSE +0 -0
empathy_os/workflows/__init__.py
CHANGED
|
@@ -34,9 +34,41 @@ import importlib.util
|
|
|
34
34
|
import os
|
|
35
35
|
from typing import TYPE_CHECKING
|
|
36
36
|
|
|
37
|
+
# =============================================================================
|
|
38
|
+
# LAZY IMPORTS - Deferred loading for faster startup
|
|
39
|
+
# =============================================================================
|
|
40
|
+
# Workflow imports are deferred until actually accessed, reducing initial
|
|
41
|
+
# import time from ~0.5s to ~0.05s for simple use cases.
|
|
42
|
+
|
|
37
43
|
if TYPE_CHECKING:
|
|
38
44
|
from .base import BaseWorkflow
|
|
39
|
-
|
|
45
|
+
from .bug_predict import BugPredictionWorkflow
|
|
46
|
+
from .code_review import CodeReviewWorkflow
|
|
47
|
+
from .code_review_pipeline import CodeReviewPipeline, CodeReviewPipelineResult
|
|
48
|
+
from .config import DEFAULT_MODELS, ModelConfig, WorkflowConfig
|
|
49
|
+
from .dependency_check import DependencyCheckWorkflow
|
|
50
|
+
from .document_gen import DocumentGenerationWorkflow
|
|
51
|
+
from .document_manager import DocumentManagerWorkflow
|
|
52
|
+
from .documentation_orchestrator import DocumentationOrchestrator, OrchestratorResult
|
|
53
|
+
from .keyboard_shortcuts import KeyboardShortcutWorkflow
|
|
54
|
+
from .manage_documentation import ManageDocumentationCrew, ManageDocumentationCrewResult
|
|
55
|
+
from .orchestrated_health_check import HealthCheckReport, OrchestratedHealthCheckWorkflow
|
|
56
|
+
from .orchestrated_release_prep import OrchestratedReleasePrepWorkflow, ReleaseReadinessReport
|
|
57
|
+
from .perf_audit import PerformanceAuditWorkflow
|
|
58
|
+
from .pr_review import PRReviewResult, PRReviewWorkflow
|
|
59
|
+
from .refactor_plan import RefactorPlanWorkflow
|
|
60
|
+
from .release_prep import ReleasePreparationWorkflow
|
|
61
|
+
from .release_prep_crew import ReleasePreparationCrew, ReleasePreparationCrewResult
|
|
62
|
+
from .research_synthesis import ResearchSynthesisWorkflow
|
|
63
|
+
from .secure_release import SecureReleasePipeline, SecureReleaseResult
|
|
64
|
+
from .security_audit import SecurityAuditWorkflow
|
|
65
|
+
from .step_config import WorkflowStepConfig
|
|
66
|
+
from .test5 import Test5Workflow
|
|
67
|
+
from .test_coverage_boost_crew import TestCoverageBoostCrew, TestCoverageBoostCrewResult
|
|
68
|
+
from .test_gen import TestGenerationWorkflow
|
|
69
|
+
from .xml_enhanced_crew import XMLAgent, XMLTask
|
|
70
|
+
|
|
71
|
+
# Only import base module eagerly (small, needed for type checks)
|
|
40
72
|
from .base import (
|
|
41
73
|
PROVIDER_MODELS,
|
|
42
74
|
BaseWorkflow,
|
|
@@ -48,122 +80,164 @@ from .base import (
|
|
|
48
80
|
get_workflow_stats,
|
|
49
81
|
)
|
|
50
82
|
|
|
51
|
-
#
|
|
52
|
-
from .bug_predict import BugPredictionWorkflow
|
|
53
|
-
from .code_review import CodeReviewWorkflow
|
|
54
|
-
|
|
55
|
-
# Code review crew integration (v3.1)
|
|
56
|
-
from .code_review_pipeline import CodeReviewPipeline, CodeReviewPipelineResult
|
|
83
|
+
# Config is small and frequently needed
|
|
57
84
|
from .config import DEFAULT_MODELS, ModelConfig, WorkflowConfig, create_example_config, get_model
|
|
58
|
-
from .dependency_check import DependencyCheckWorkflow
|
|
59
|
-
from .document_gen import DocumentGenerationWorkflow
|
|
60
|
-
|
|
61
|
-
# User-generated workflows
|
|
62
|
-
from .document_manager import DocumentManagerWorkflow
|
|
63
|
-
from .documentation_orchestrator import DocumentationOrchestrator, OrchestratorResult
|
|
64
|
-
|
|
65
|
-
# Removed deprecated: health_check.py, health_check_crew.py (use orchestrated_health_check instead)
|
|
66
|
-
# Keyboard Conductor (v3.6) - keyboard shortcut generation
|
|
67
|
-
from .keyboard_shortcuts import KeyboardShortcutWorkflow
|
|
68
|
-
from .manage_documentation import ManageDocumentationCrew, ManageDocumentationCrewResult
|
|
69
|
-
|
|
70
|
-
# Meta-orchestration workflows (v4.0)
|
|
71
|
-
from .orchestrated_health_check import HealthCheckReport, OrchestratedHealthCheckWorkflow
|
|
72
|
-
from .orchestrated_release_prep import OrchestratedReleasePrepWorkflow, ReleaseReadinessReport
|
|
73
|
-
from .perf_audit import PerformanceAuditWorkflow
|
|
74
|
-
from .pr_review import PRReviewResult, PRReviewWorkflow
|
|
75
|
-
from .refactor_plan import RefactorPlanWorkflow
|
|
76
|
-
from .release_prep import ReleasePreparationWorkflow
|
|
77
|
-
|
|
78
|
-
# CrewAI-based crews (working replacements for broken orchestrator)
|
|
79
|
-
from .release_prep_crew import ReleasePreparationCrew, ReleasePreparationCrewResult
|
|
80
|
-
from .research_synthesis import ResearchSynthesisWorkflow
|
|
81
|
-
|
|
82
|
-
# Security crew integration (v3.0)
|
|
83
|
-
from .secure_release import SecureReleasePipeline, SecureReleaseResult
|
|
84
|
-
from .security_audit import SecurityAuditWorkflow
|
|
85
85
|
from .step_config import WorkflowStepConfig, steps_from_tier_map, validate_step_config
|
|
86
|
-
from .test5 import Test5Workflow
|
|
87
86
|
|
|
88
|
-
#
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
# Lazy import mapping for workflow classes
|
|
88
|
+
_LAZY_WORKFLOW_IMPORTS: dict[str, tuple[str, str]] = {
|
|
89
|
+
# Core workflows
|
|
90
|
+
"BugPredictionWorkflow": (".bug_predict", "BugPredictionWorkflow"),
|
|
91
|
+
"CodeReviewWorkflow": (".code_review", "CodeReviewWorkflow"),
|
|
92
|
+
"CodeReviewPipeline": (".code_review_pipeline", "CodeReviewPipeline"),
|
|
93
|
+
"CodeReviewPipelineResult": (".code_review_pipeline", "CodeReviewPipelineResult"),
|
|
94
|
+
"DependencyCheckWorkflow": (".dependency_check", "DependencyCheckWorkflow"),
|
|
95
|
+
"DocumentGenerationWorkflow": (".document_gen", "DocumentGenerationWorkflow"),
|
|
96
|
+
"DocumentManagerWorkflow": (".document_manager", "DocumentManagerWorkflow"),
|
|
97
|
+
"DocumentationOrchestrator": (".documentation_orchestrator", "DocumentationOrchestrator"),
|
|
98
|
+
"OrchestratorResult": (".documentation_orchestrator", "OrchestratorResult"),
|
|
99
|
+
"KeyboardShortcutWorkflow": (".keyboard_shortcuts", "KeyboardShortcutWorkflow"),
|
|
100
|
+
"ManageDocumentationCrew": (".manage_documentation", "ManageDocumentationCrew"),
|
|
101
|
+
"ManageDocumentationCrewResult": (".manage_documentation", "ManageDocumentationCrewResult"),
|
|
102
|
+
"OrchestratedHealthCheckWorkflow": (".orchestrated_health_check", "OrchestratedHealthCheckWorkflow"),
|
|
103
|
+
"HealthCheckReport": (".orchestrated_health_check", "HealthCheckReport"),
|
|
104
|
+
"OrchestratedReleasePrepWorkflow": (".orchestrated_release_prep", "OrchestratedReleasePrepWorkflow"),
|
|
105
|
+
"ReleaseReadinessReport": (".orchestrated_release_prep", "ReleaseReadinessReport"),
|
|
106
|
+
"PerformanceAuditWorkflow": (".perf_audit", "PerformanceAuditWorkflow"),
|
|
107
|
+
"PRReviewWorkflow": (".pr_review", "PRReviewWorkflow"),
|
|
108
|
+
"PRReviewResult": (".pr_review", "PRReviewResult"),
|
|
109
|
+
"RefactorPlanWorkflow": (".refactor_plan", "RefactorPlanWorkflow"),
|
|
110
|
+
"ReleasePreparationWorkflow": (".release_prep", "ReleasePreparationWorkflow"),
|
|
111
|
+
"ReleasePreparationCrew": (".release_prep_crew", "ReleasePreparationCrew"),
|
|
112
|
+
"ReleasePreparationCrewResult": (".release_prep_crew", "ReleasePreparationCrewResult"),
|
|
113
|
+
"ResearchSynthesisWorkflow": (".research_synthesis", "ResearchSynthesisWorkflow"),
|
|
114
|
+
"SecureReleasePipeline": (".secure_release", "SecureReleasePipeline"),
|
|
115
|
+
"SecureReleaseResult": (".secure_release", "SecureReleaseResult"),
|
|
116
|
+
"SecurityAuditWorkflow": (".security_audit", "SecurityAuditWorkflow"),
|
|
117
|
+
"Test5Workflow": (".test5", "Test5Workflow"),
|
|
118
|
+
"TestCoverageBoostCrew": (".test_coverage_boost_crew", "TestCoverageBoostCrew"),
|
|
119
|
+
"TestCoverageBoostCrewResult": (".test_coverage_boost_crew", "TestCoverageBoostCrewResult"),
|
|
120
|
+
"TestGenerationWorkflow": (".test_gen", "TestGenerationWorkflow"),
|
|
121
|
+
"XMLAgent": (".xml_enhanced_crew", "XMLAgent"),
|
|
122
|
+
"XMLTask": (".xml_enhanced_crew", "XMLTask"),
|
|
123
|
+
"parse_xml_response": (".xml_enhanced_crew", "parse_xml_response"),
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# Cache for loaded workflow classes
|
|
127
|
+
_loaded_workflow_modules: dict[str, object] = {}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _lazy_import_workflow(name: str) -> object:
|
|
131
|
+
"""Import a workflow class lazily."""
|
|
132
|
+
if name not in _LAZY_WORKFLOW_IMPORTS:
|
|
133
|
+
raise AttributeError(f"module 'empathy_os.workflows' has no attribute '{name}'")
|
|
91
134
|
|
|
92
|
-
|
|
93
|
-
from .xml_enhanced_crew import XMLAgent, XMLTask, parse_xml_response
|
|
135
|
+
module_path, attr_name = _LAZY_WORKFLOW_IMPORTS[name]
|
|
94
136
|
|
|
95
|
-
#
|
|
137
|
+
# Check cache first
|
|
138
|
+
cache_key = f"{module_path}.{attr_name}"
|
|
139
|
+
if cache_key in _loaded_workflow_modules:
|
|
140
|
+
return _loaded_workflow_modules[cache_key]
|
|
141
|
+
|
|
142
|
+
# Import the module and get the attribute
|
|
143
|
+
import importlib
|
|
144
|
+
module = importlib.import_module(module_path, package="empathy_os.workflows")
|
|
145
|
+
attr = getattr(module, attr_name)
|
|
146
|
+
|
|
147
|
+
# Cache and return
|
|
148
|
+
_loaded_workflow_modules[cache_key] = attr
|
|
149
|
+
return attr
|
|
150
|
+
|
|
151
|
+
# Re-export CLI commands from workflow_commands.py (lazy loaded)
|
|
96
152
|
_parent_dir = os.path.dirname(os.path.dirname(__file__))
|
|
97
153
|
_workflows_module_path = os.path.join(_parent_dir, "workflow_commands.py")
|
|
98
154
|
|
|
99
|
-
# Initialize to None for type checking
|
|
155
|
+
# Initialize to None for type checking - loaded lazily via __getattr__
|
|
100
156
|
cmd_morning = None
|
|
101
157
|
cmd_ship = None
|
|
102
158
|
cmd_fix_all = None
|
|
103
159
|
cmd_learn = None
|
|
160
|
+
_cli_loaded = False
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _load_cli_commands() -> None:
|
|
164
|
+
"""Load CLI commands lazily."""
|
|
165
|
+
global cmd_morning, cmd_ship, cmd_fix_all, cmd_learn, _cli_loaded
|
|
166
|
+
if _cli_loaded:
|
|
167
|
+
return
|
|
168
|
+
|
|
169
|
+
if os.path.exists(_workflows_module_path):
|
|
170
|
+
_spec = importlib.util.spec_from_file_location("_workflows_cli", _workflows_module_path)
|
|
171
|
+
if _spec is not None and _spec.loader is not None:
|
|
172
|
+
_workflows_cli = importlib.util.module_from_spec(_spec)
|
|
173
|
+
_spec.loader.exec_module(_workflows_cli)
|
|
174
|
+
|
|
175
|
+
# Re-export CLI commands
|
|
176
|
+
cmd_morning = _workflows_cli.cmd_morning
|
|
177
|
+
cmd_ship = _workflows_cli.cmd_ship
|
|
178
|
+
cmd_fix_all = _workflows_cli.cmd_fix_all
|
|
179
|
+
cmd_learn = _workflows_cli.cmd_learn
|
|
104
180
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
# Re-export CLI commands
|
|
112
|
-
cmd_morning = _workflows_cli.cmd_morning
|
|
113
|
-
cmd_ship = _workflows_cli.cmd_ship
|
|
114
|
-
cmd_fix_all = _workflows_cli.cmd_fix_all
|
|
115
|
-
cmd_learn = _workflows_cli.cmd_learn
|
|
116
|
-
|
|
117
|
-
# Default workflow registry (statically defined for backwards compatibility)
|
|
118
|
-
# Note: Some entries are composite pipelines, not direct BaseWorkflow subclasses
|
|
119
|
-
_DEFAULT_WORKFLOWS: dict[str, type] = {
|
|
181
|
+
_cli_loaded = True
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# Default workflow registry - uses CLASS NAMES (strings) for lazy loading
|
|
185
|
+
# Actual classes are loaded on first access via _get_workflow_class()
|
|
186
|
+
_DEFAULT_WORKFLOW_NAMES: dict[str, str] = {
|
|
120
187
|
# Core workflows
|
|
121
|
-
"code-review": CodeReviewWorkflow,
|
|
122
|
-
"doc-gen": DocumentGenerationWorkflow,
|
|
188
|
+
"code-review": "CodeReviewWorkflow",
|
|
189
|
+
"doc-gen": "DocumentGenerationWorkflow",
|
|
123
190
|
# Analysis workflows
|
|
124
|
-
"bug-predict": BugPredictionWorkflow,
|
|
125
|
-
"security-audit": SecurityAuditWorkflow,
|
|
126
|
-
"perf-audit": PerformanceAuditWorkflow,
|
|
191
|
+
"bug-predict": "BugPredictionWorkflow",
|
|
192
|
+
"security-audit": "SecurityAuditWorkflow",
|
|
193
|
+
"perf-audit": "PerformanceAuditWorkflow",
|
|
127
194
|
# Generation workflows
|
|
128
|
-
"test-gen": TestGenerationWorkflow,
|
|
129
|
-
"refactor-plan": RefactorPlanWorkflow,
|
|
195
|
+
"test-gen": "TestGenerationWorkflow",
|
|
196
|
+
"refactor-plan": "RefactorPlanWorkflow",
|
|
130
197
|
# Operational workflows
|
|
131
|
-
"dependency-check": DependencyCheckWorkflow,
|
|
132
|
-
"release-prep-legacy": ReleasePreparationWorkflow,
|
|
198
|
+
"dependency-check": "DependencyCheckWorkflow",
|
|
199
|
+
"release-prep-legacy": "ReleasePreparationWorkflow",
|
|
133
200
|
# Composite security pipeline (v3.0)
|
|
134
|
-
"secure-release": SecureReleasePipeline,
|
|
201
|
+
"secure-release": "SecureReleasePipeline",
|
|
135
202
|
# Code review crew integration (v3.1)
|
|
136
|
-
"pro-review": CodeReviewPipeline,
|
|
137
|
-
"pr-review": PRReviewWorkflow,
|
|
203
|
+
"pro-review": "CodeReviewPipeline",
|
|
204
|
+
"pr-review": "PRReviewWorkflow",
|
|
138
205
|
# Documentation management (v3.5)
|
|
139
|
-
"doc-orchestrator": DocumentationOrchestrator,
|
|
140
|
-
"manage-docs":
|
|
141
|
-
# Keyboard Conductor (v3.6)
|
|
142
|
-
"keyboard-shortcuts": KeyboardShortcutWorkflow,
|
|
206
|
+
"doc-orchestrator": "DocumentationOrchestrator",
|
|
207
|
+
"manage-docs": "DocumentationOrchestrator", # Points to orchestrator (crew deprecated)
|
|
208
|
+
# Keyboard Conductor (v3.6)
|
|
209
|
+
"keyboard-shortcuts": "KeyboardShortcutWorkflow",
|
|
143
210
|
# User-generated workflows
|
|
144
|
-
"document-manager": DocumentManagerWorkflow,
|
|
145
|
-
"test5": Test5Workflow,
|
|
146
|
-
#
|
|
147
|
-
|
|
148
|
-
"release-prep":
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
"orchestrated-
|
|
152
|
-
|
|
153
|
-
"orchestrated-health-check": OrchestratedHealthCheckWorkflow, # ✅ v4.0.0 CANONICAL: Real security/coverage/quality analysis
|
|
154
|
-
"orchestrated-release-prep": OrchestratedReleasePrepWorkflow, # ✅ v4.0.0 CANONICAL: Real quality gate validation
|
|
155
|
-
# Experimental aliases (backward compat)
|
|
156
|
-
"orchestrated-health-check-experimental": OrchestratedHealthCheckWorkflow, # ALIAS
|
|
157
|
-
"orchestrated-release-prep-experimental": OrchestratedReleasePrepWorkflow, # ALIAS
|
|
211
|
+
"document-manager": "DocumentManagerWorkflow",
|
|
212
|
+
"test5": "Test5Workflow",
|
|
213
|
+
# Meta-orchestration workflows (v4.0.0 - CANONICAL)
|
|
214
|
+
"orchestrated-health-check": "OrchestratedHealthCheckWorkflow",
|
|
215
|
+
"orchestrated-release-prep": "OrchestratedReleasePrepWorkflow",
|
|
216
|
+
# Backward compatibility aliases (point to orchestrated versions)
|
|
217
|
+
"release-prep": "OrchestratedReleasePrepWorkflow",
|
|
218
|
+
"orchestrated-health-check-experimental": "OrchestratedHealthCheckWorkflow",
|
|
219
|
+
"orchestrated-release-prep-experimental": "OrchestratedReleasePrepWorkflow",
|
|
158
220
|
}
|
|
159
221
|
|
|
160
|
-
# Opt-in workflows -
|
|
161
|
-
|
|
162
|
-
# Use disabled_workflows in config to turn off specific workflows
|
|
163
|
-
_OPT_IN_WORKFLOWS: dict[str, type] = {}
|
|
222
|
+
# Opt-in workflows - class names for lazy loading
|
|
223
|
+
_OPT_IN_WORKFLOW_NAMES: dict[str, str] = {}
|
|
164
224
|
|
|
165
|
-
# Workflow registry populated
|
|
225
|
+
# Workflow registry - populated lazily on first access
|
|
166
226
|
WORKFLOW_REGISTRY: dict[str, type[BaseWorkflow]] = {}
|
|
227
|
+
_registry_initialized = False
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _get_workflow_class(class_name: str) -> type[BaseWorkflow]:
|
|
231
|
+
"""Get a workflow class by name (lazy loading)."""
|
|
232
|
+
return _lazy_import_workflow(class_name)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def _ensure_registry_initialized() -> None:
|
|
236
|
+
"""Initialize workflow registry on first access."""
|
|
237
|
+
global _registry_initialized
|
|
238
|
+
if not _registry_initialized:
|
|
239
|
+
WORKFLOW_REGISTRY.update(discover_workflows())
|
|
240
|
+
_registry_initialized = True
|
|
167
241
|
|
|
168
242
|
|
|
169
243
|
def discover_workflows(
|
|
@@ -176,12 +250,8 @@ def discover_workflows(
|
|
|
176
250
|
'empathy.workflows' group. This allows third-party packages to register
|
|
177
251
|
custom workflows that integrate with the Empathy Framework.
|
|
178
252
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
2. Opt-in workflows (test-gen) - must be explicitly enabled OR compliance_mode=hipaa
|
|
182
|
-
3. enabled_workflows config - explicitly enable specific workflows
|
|
183
|
-
4. disabled_workflows config - explicitly disable specific workflows
|
|
184
|
-
5. Entry point discovery - third-party workflows
|
|
253
|
+
Note: Workflows are loaded lazily - classes are only imported when
|
|
254
|
+
the workflow is actually used, reducing initial import time.
|
|
185
255
|
|
|
186
256
|
Args:
|
|
187
257
|
include_defaults: Whether to include default built-in workflows
|
|
@@ -191,36 +261,41 @@ def discover_workflows(
|
|
|
191
261
|
Dictionary mapping workflow names to workflow classes
|
|
192
262
|
|
|
193
263
|
Example:
|
|
194
|
-
# In your pyproject.toml:
|
|
195
|
-
[project.entry-points."empathy.workflows"]
|
|
196
|
-
my-workflow = "my_package.workflows:MyCustomWorkflow"
|
|
197
|
-
|
|
198
|
-
# In your code:
|
|
199
264
|
from empathy_os.workflows import discover_workflows
|
|
200
265
|
workflows = discover_workflows()
|
|
201
|
-
MyWorkflow = workflows.get("
|
|
202
|
-
|
|
203
|
-
# With HIPAA mode (enables test-gen):
|
|
204
|
-
config = WorkflowConfig.load() # compliance_mode: hipaa
|
|
205
|
-
workflows = discover_workflows(config=config)
|
|
266
|
+
MyWorkflow = workflows.get("code-review")
|
|
206
267
|
|
|
207
268
|
"""
|
|
208
269
|
discovered: dict[str, type[BaseWorkflow]] = {}
|
|
209
270
|
|
|
210
|
-
# Include default workflows if requested
|
|
271
|
+
# Include default workflows if requested (lazy load each)
|
|
211
272
|
if include_defaults:
|
|
212
|
-
|
|
273
|
+
for workflow_id, class_name in _DEFAULT_WORKFLOW_NAMES.items():
|
|
274
|
+
try:
|
|
275
|
+
discovered[workflow_id] = _get_workflow_class(class_name)
|
|
276
|
+
except (ImportError, AttributeError):
|
|
277
|
+
# Skip workflows that fail to load
|
|
278
|
+
pass
|
|
213
279
|
|
|
214
280
|
# Add opt-in workflows based on config
|
|
215
281
|
if config is not None:
|
|
216
282
|
# HIPAA mode auto-enables healthcare workflows
|
|
217
283
|
if config.is_hipaa_mode():
|
|
218
|
-
|
|
284
|
+
for workflow_id, class_name in _OPT_IN_WORKFLOW_NAMES.items():
|
|
285
|
+
try:
|
|
286
|
+
discovered[workflow_id] = _get_workflow_class(class_name)
|
|
287
|
+
except (ImportError, AttributeError):
|
|
288
|
+
pass
|
|
219
289
|
|
|
220
290
|
# Explicitly enabled workflows
|
|
221
291
|
for workflow_name in config.enabled_workflows:
|
|
222
|
-
if workflow_name in
|
|
223
|
-
|
|
292
|
+
if workflow_name in _OPT_IN_WORKFLOW_NAMES:
|
|
293
|
+
try:
|
|
294
|
+
discovered[workflow_name] = _get_workflow_class(
|
|
295
|
+
_OPT_IN_WORKFLOW_NAMES[workflow_name]
|
|
296
|
+
)
|
|
297
|
+
except (ImportError, AttributeError):
|
|
298
|
+
pass
|
|
224
299
|
|
|
225
300
|
# Explicitly disabled workflows
|
|
226
301
|
for workflow_name in config.disabled_workflows:
|
|
@@ -232,16 +307,12 @@ def discover_workflows(
|
|
|
232
307
|
for ep in eps:
|
|
233
308
|
try:
|
|
234
309
|
workflow_cls = ep.load()
|
|
235
|
-
# Validate it's a proper workflow class
|
|
236
310
|
if isinstance(workflow_cls, type) and hasattr(workflow_cls, "execute"):
|
|
237
|
-
# Check if disabled in config
|
|
238
311
|
if config is None or ep.name not in config.disabled_workflows:
|
|
239
312
|
discovered[ep.name] = workflow_cls
|
|
240
313
|
except Exception:
|
|
241
|
-
# Skip invalid entry points silently
|
|
242
314
|
pass
|
|
243
315
|
except Exception:
|
|
244
|
-
# If entry point discovery fails, just use defaults
|
|
245
316
|
pass
|
|
246
317
|
|
|
247
318
|
return discovered
|
|
@@ -269,11 +340,17 @@ def get_opt_in_workflows() -> dict[str, type]:
|
|
|
269
340
|
Dictionary of workflow name to class for opt-in workflows
|
|
270
341
|
|
|
271
342
|
"""
|
|
272
|
-
|
|
343
|
+
result = {}
|
|
344
|
+
for name, class_name in _OPT_IN_WORKFLOW_NAMES.items():
|
|
345
|
+
try:
|
|
346
|
+
result[name] = _get_workflow_class(class_name)
|
|
347
|
+
except (ImportError, AttributeError):
|
|
348
|
+
pass
|
|
349
|
+
return result
|
|
273
350
|
|
|
274
351
|
|
|
275
|
-
#
|
|
276
|
-
|
|
352
|
+
# Note: Registry is initialized lazily on first access via _ensure_registry_initialized()
|
|
353
|
+
# Do NOT call discover_workflows() here - it defeats lazy loading
|
|
277
354
|
|
|
278
355
|
|
|
279
356
|
def get_workflow(name: str) -> type[BaseWorkflow]:
|
|
@@ -289,6 +366,7 @@ def get_workflow(name: str) -> type[BaseWorkflow]:
|
|
|
289
366
|
KeyError: If workflow not found
|
|
290
367
|
|
|
291
368
|
"""
|
|
369
|
+
_ensure_registry_initialized()
|
|
292
370
|
if name not in WORKFLOW_REGISTRY:
|
|
293
371
|
available = ", ".join(WORKFLOW_REGISTRY.keys())
|
|
294
372
|
raise KeyError(f"Unknown workflow: {name}. Available: {available}")
|
|
@@ -302,6 +380,7 @@ def list_workflows() -> list[dict]:
|
|
|
302
380
|
List of workflow info dicts
|
|
303
381
|
|
|
304
382
|
"""
|
|
383
|
+
_ensure_registry_initialized()
|
|
305
384
|
workflows = []
|
|
306
385
|
for name, cls in WORKFLOW_REGISTRY.items():
|
|
307
386
|
# Handle both BaseWorkflow subclasses and composite pipelines
|
|
@@ -321,6 +400,19 @@ def list_workflows() -> list[dict]:
|
|
|
321
400
|
return workflows
|
|
322
401
|
|
|
323
402
|
|
|
403
|
+
def __getattr__(name: str) -> object:
|
|
404
|
+
"""Lazy import handler for workflow classes."""
|
|
405
|
+
if name in _LAZY_WORKFLOW_IMPORTS:
|
|
406
|
+
return _lazy_import_workflow(name)
|
|
407
|
+
|
|
408
|
+
# Handle CLI commands
|
|
409
|
+
if name in ("cmd_morning", "cmd_ship", "cmd_fix_all", "cmd_learn"):
|
|
410
|
+
_load_cli_commands()
|
|
411
|
+
return globals().get(name)
|
|
412
|
+
|
|
413
|
+
raise AttributeError(f"module 'empathy_os.workflows' has no attribute '{name}'")
|
|
414
|
+
|
|
415
|
+
|
|
324
416
|
__all__ = [
|
|
325
417
|
"DEFAULT_MODELS",
|
|
326
418
|
"PROVIDER_MODELS",
|
|
@@ -129,10 +129,7 @@ class BatchProcessingWorkflow:
|
|
|
129
129
|
logger.info(f"Submitting batch of {len(requests)} requests")
|
|
130
130
|
batch_id = self.batch_provider.create_batch(api_requests)
|
|
131
131
|
|
|
132
|
-
logger.info(
|
|
133
|
-
f"Batch {batch_id} created, polling every {poll_interval}s "
|
|
134
|
-
f"(max {timeout}s)"
|
|
135
|
-
)
|
|
132
|
+
logger.info(f"Batch {batch_id} created, polling every {poll_interval}s (max {timeout}s)")
|
|
136
133
|
|
|
137
134
|
# Wait for completion
|
|
138
135
|
try:
|
|
@@ -152,9 +149,7 @@ class BatchProcessingWorkflow:
|
|
|
152
149
|
except RuntimeError as e:
|
|
153
150
|
logger.error(f"Batch {batch_id} failed: {e}")
|
|
154
151
|
return [
|
|
155
|
-
BatchResult(
|
|
156
|
-
task_id=req.task_id, success=False, error=f"Batch failed: {e}"
|
|
157
|
-
)
|
|
152
|
+
BatchResult(task_id=req.task_id, success=False, error=f"Batch failed: {e}")
|
|
158
153
|
for req in requests
|
|
159
154
|
]
|
|
160
155
|
|
|
@@ -165,21 +160,15 @@ class BatchProcessingWorkflow:
|
|
|
165
160
|
|
|
166
161
|
if "error" in raw:
|
|
167
162
|
error_msg = raw["error"].get("message", "Unknown error")
|
|
168
|
-
results.append(
|
|
169
|
-
BatchResult(task_id=task_id, success=False, error=error_msg)
|
|
170
|
-
)
|
|
163
|
+
results.append(BatchResult(task_id=task_id, success=False, error=error_msg))
|
|
171
164
|
else:
|
|
172
165
|
results.append(
|
|
173
|
-
BatchResult(
|
|
174
|
-
task_id=task_id, success=True, output=raw.get("response")
|
|
175
|
-
)
|
|
166
|
+
BatchResult(task_id=task_id, success=True, output=raw.get("response"))
|
|
176
167
|
)
|
|
177
168
|
|
|
178
169
|
# Log summary
|
|
179
170
|
success_count = sum(r.success for r in results)
|
|
180
|
-
logger.info(
|
|
181
|
-
f"Batch {batch_id} completed: {success_count}/{len(results)} successful"
|
|
182
|
-
)
|
|
171
|
+
logger.info(f"Batch {batch_id} completed: {success_count}/{len(results)} successful")
|
|
183
172
|
|
|
184
173
|
return results
|
|
185
174
|
|
|
@@ -203,17 +192,14 @@ class BatchProcessingWorkflow:
|
|
|
203
192
|
}
|
|
204
193
|
|
|
205
194
|
# Get prompt template or use default
|
|
206
|
-
prompt_template = task_prompts.get(
|
|
207
|
-
request.task_type, "Process the following:\n\n{input}"
|
|
208
|
-
)
|
|
195
|
+
prompt_template = task_prompts.get(request.task_type, "Process the following:\n\n{input}")
|
|
209
196
|
|
|
210
197
|
# Format with input data
|
|
211
198
|
try:
|
|
212
199
|
content = prompt_template.format(**request.input_data)
|
|
213
200
|
except KeyError as e:
|
|
214
201
|
logger.warning(
|
|
215
|
-
f"Missing required field {e} for task {request.task_type}, "
|
|
216
|
-
f"using raw input"
|
|
202
|
+
f"Missing required field {e} for task {request.task_type}, using raw input"
|
|
217
203
|
)
|
|
218
204
|
content = prompt_template.format(input=json.dumps(request.input_data))
|
|
219
205
|
|
|
@@ -282,9 +268,7 @@ class BatchProcessingWorkflow:
|
|
|
282
268
|
|
|
283
269
|
return requests
|
|
284
270
|
|
|
285
|
-
def save_results_to_file(
|
|
286
|
-
self, results: list[BatchResult], output_path: str
|
|
287
|
-
) -> None:
|
|
271
|
+
def save_results_to_file(self, results: list[BatchResult], output_path: str) -> None:
|
|
288
272
|
"""Save batch results to JSON file.
|
|
289
273
|
|
|
290
274
|
Args:
|
|
@@ -372,7 +372,7 @@ def _remove_docstrings(content: str) -> str:
|
|
|
372
372
|
"""
|
|
373
373
|
# Remove triple-quoted strings (docstrings)
|
|
374
374
|
# Match """ ... """ and ''' ... ''' including multiline
|
|
375
|
-
content = re.sub(r'"""[\s\S]*?"""',
|
|
375
|
+
content = re.sub(r'"""[\s\S]*?"""', "# [docstring removed]", content)
|
|
376
376
|
content = re.sub(r"'''[\s\S]*?'''", "# [docstring removed]", content)
|
|
377
377
|
return content
|
|
378
378
|
|
|
@@ -359,11 +359,26 @@ Code:
|
|
|
359
359
|
"""
|
|
360
360
|
await self._initialize_crew()
|
|
361
361
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
362
|
+
try:
|
|
363
|
+
from .code_review_adapters import (
|
|
364
|
+
_check_crew_available,
|
|
365
|
+
_get_crew_review,
|
|
366
|
+
crew_report_to_workflow_format,
|
|
367
|
+
)
|
|
368
|
+
except ImportError:
|
|
369
|
+
# Crew adapters removed - return fallback
|
|
370
|
+
return (
|
|
371
|
+
{
|
|
372
|
+
"crew_review": {
|
|
373
|
+
"available": False,
|
|
374
|
+
"fallback": True,
|
|
375
|
+
"reason": "Crew adapters not installed",
|
|
376
|
+
},
|
|
377
|
+
**input_data,
|
|
378
|
+
},
|
|
379
|
+
0,
|
|
380
|
+
0,
|
|
381
|
+
)
|
|
367
382
|
|
|
368
383
|
# Get code to review
|
|
369
384
|
diff = input_data.get("diff", "") or input_data.get("code_to_review", "")
|
|
@@ -276,18 +276,23 @@ class CodeReviewPipeline:
|
|
|
276
276
|
) -> tuple[dict | None, Any]: # Second element is WorkflowResult or None
|
|
277
277
|
"""Run full mode with crew and workflow."""
|
|
278
278
|
from .code_review import CodeReviewWorkflow
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
from .code_review_adapters import (
|
|
282
|
+
_check_crew_available,
|
|
283
|
+
_get_crew_review,
|
|
284
|
+
crew_report_to_workflow_format,
|
|
285
|
+
)
|
|
286
|
+
crew_available = _check_crew_available()
|
|
287
|
+
except ImportError:
|
|
288
|
+
# Crew adapters removed - fall back to workflow only
|
|
289
|
+
crew_available = False
|
|
290
|
+
_get_crew_review = None
|
|
291
|
+
crew_report_to_workflow_format = None
|
|
284
292
|
|
|
285
293
|
crew_report: dict | None = None
|
|
286
294
|
workflow_result: Any = None # WorkflowResult or None
|
|
287
295
|
|
|
288
|
-
# Check if crew is available
|
|
289
|
-
crew_available = _check_crew_available()
|
|
290
|
-
|
|
291
296
|
if crew_available and self.parallel_crew:
|
|
292
297
|
# Run crew and workflow in parallel
|
|
293
298
|
crew_task = asyncio.create_task(
|
|
@@ -358,7 +358,9 @@ class KeyboardShortcutWorkflow(BaseWorkflow):
|
|
|
358
358
|
if isinstance(result, dict):
|
|
359
359
|
return result
|
|
360
360
|
return None
|
|
361
|
-
except Exception:
|
|
361
|
+
except Exception: # noqa: BLE001
|
|
362
|
+
# INTENTIONAL: LLM responses may have unparseable YAML.
|
|
363
|
+
# Return None and let caller handle fallback gracefully.
|
|
362
364
|
return None
|
|
363
365
|
|
|
364
366
|
def _parse_json_response(self, response: str) -> dict[str, Any] | None:
|
|
@@ -376,7 +378,9 @@ class KeyboardShortcutWorkflow(BaseWorkflow):
|
|
|
376
378
|
if isinstance(result, dict):
|
|
377
379
|
return result
|
|
378
380
|
return None
|
|
379
|
-
except Exception:
|
|
381
|
+
except Exception: # noqa: BLE001
|
|
382
|
+
# INTENTIONAL: LLM responses may have unparseable JSON.
|
|
383
|
+
# Return None and let caller handle fallback gracefully.
|
|
380
384
|
return None
|
|
381
385
|
|
|
382
386
|
def _update_manifest_from_analysis(
|