claude-mpm 4.7.4__py3-none-any.whl → 4.18.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
- claude_mpm/agents/BASE_ENGINEER.md +286 -0
- claude_mpm/agents/BASE_PM.md +106 -1
- claude_mpm/agents/OUTPUT_STYLE.md +329 -11
- claude_mpm/agents/PM_INSTRUCTIONS.md +397 -459
- claude_mpm/agents/agent_loader.py +17 -5
- claude_mpm/agents/frontmatter_validator.py +284 -253
- claude_mpm/agents/templates/README.md +465 -0
- claude_mpm/agents/templates/agent-manager.json +4 -1
- claude_mpm/agents/templates/agentic-coder-optimizer.json +13 -3
- claude_mpm/agents/templates/api_qa.json +11 -2
- claude_mpm/agents/templates/circuit_breakers.md +638 -0
- claude_mpm/agents/templates/clerk-ops.json +12 -2
- claude_mpm/agents/templates/code_analyzer.json +8 -2
- claude_mpm/agents/templates/content-agent.json +358 -0
- claude_mpm/agents/templates/dart_engineer.json +15 -2
- claude_mpm/agents/templates/data_engineer.json +15 -2
- claude_mpm/agents/templates/documentation.json +10 -2
- claude_mpm/agents/templates/engineer.json +21 -1
- claude_mpm/agents/templates/gcp_ops_agent.json +12 -2
- claude_mpm/agents/templates/git_file_tracking.md +584 -0
- claude_mpm/agents/templates/golang_engineer.json +270 -0
- claude_mpm/agents/templates/imagemagick.json +4 -1
- claude_mpm/agents/templates/java_engineer.json +346 -0
- claude_mpm/agents/templates/local_ops_agent.json +1227 -6
- claude_mpm/agents/templates/memory_manager.json +4 -1
- claude_mpm/agents/templates/nextjs_engineer.json +141 -133
- claude_mpm/agents/templates/ops.json +12 -2
- claude_mpm/agents/templates/php-engineer.json +270 -174
- claude_mpm/agents/templates/pm_examples.md +474 -0
- claude_mpm/agents/templates/pm_red_flags.md +240 -0
- claude_mpm/agents/templates/product_owner.json +338 -0
- claude_mpm/agents/templates/project_organizer.json +14 -4
- claude_mpm/agents/templates/prompt-engineer.json +13 -2
- claude_mpm/agents/templates/python_engineer.json +174 -81
- claude_mpm/agents/templates/qa.json +11 -2
- claude_mpm/agents/templates/react_engineer.json +16 -3
- claude_mpm/agents/templates/refactoring_engineer.json +12 -2
- claude_mpm/agents/templates/research.json +34 -21
- claude_mpm/agents/templates/response_format.md +583 -0
- claude_mpm/agents/templates/ruby-engineer.json +129 -192
- claude_mpm/agents/templates/rust_engineer.json +270 -0
- claude_mpm/agents/templates/security.json +10 -2
- claude_mpm/agents/templates/svelte-engineer.json +225 -0
- claude_mpm/agents/templates/ticketing.json +10 -2
- claude_mpm/agents/templates/typescript_engineer.json +116 -125
- claude_mpm/agents/templates/validation_templates.md +312 -0
- claude_mpm/agents/templates/vercel_ops_agent.json +12 -2
- claude_mpm/agents/templates/version_control.json +12 -2
- claude_mpm/agents/templates/web_qa.json +11 -2
- claude_mpm/agents/templates/web_ui.json +15 -2
- claude_mpm/cli/__init__.py +34 -614
- claude_mpm/cli/commands/agent_manager.py +25 -12
- claude_mpm/cli/commands/agent_state_manager.py +186 -0
- claude_mpm/cli/commands/agents.py +235 -148
- claude_mpm/cli/commands/agents_detect.py +380 -0
- claude_mpm/cli/commands/agents_recommend.py +309 -0
- claude_mpm/cli/commands/aggregate.py +7 -3
- claude_mpm/cli/commands/analyze.py +9 -4
- claude_mpm/cli/commands/analyze_code.py +7 -2
- claude_mpm/cli/commands/auto_configure.py +570 -0
- claude_mpm/cli/commands/config.py +47 -13
- claude_mpm/cli/commands/configure.py +419 -1571
- claude_mpm/cli/commands/configure_agent_display.py +261 -0
- claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
- claude_mpm/cli/commands/configure_hook_manager.py +225 -0
- claude_mpm/cli/commands/configure_models.py +18 -0
- claude_mpm/cli/commands/configure_navigation.py +167 -0
- claude_mpm/cli/commands/configure_paths.py +104 -0
- claude_mpm/cli/commands/configure_persistence.py +254 -0
- claude_mpm/cli/commands/configure_startup_manager.py +646 -0
- claude_mpm/cli/commands/configure_template_editor.py +497 -0
- claude_mpm/cli/commands/configure_validators.py +73 -0
- claude_mpm/cli/commands/local_deploy.py +537 -0
- claude_mpm/cli/commands/memory.py +54 -20
- claude_mpm/cli/commands/mpm_init.py +585 -196
- claude_mpm/cli/commands/mpm_init_handler.py +37 -3
- claude_mpm/cli/commands/search.py +170 -4
- claude_mpm/cli/commands/upgrade.py +152 -0
- claude_mpm/cli/executor.py +202 -0
- claude_mpm/cli/helpers.py +105 -0
- claude_mpm/cli/interactive/__init__.py +3 -0
- claude_mpm/cli/interactive/skills_wizard.py +491 -0
- claude_mpm/cli/parsers/__init__.py +7 -1
- claude_mpm/cli/parsers/agents_parser.py +9 -0
- claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
- claude_mpm/cli/parsers/base_parser.py +110 -3
- claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
- claude_mpm/cli/parsers/mpm_init_parser.py +65 -5
- claude_mpm/cli/shared/output_formatters.py +28 -19
- claude_mpm/cli/startup.py +481 -0
- claude_mpm/cli/utils.py +52 -1
- claude_mpm/commands/mpm-agents-detect.md +168 -0
- claude_mpm/commands/mpm-agents-recommend.md +214 -0
- claude_mpm/commands/mpm-agents.md +75 -1
- claude_mpm/commands/mpm-auto-configure.md +217 -0
- claude_mpm/commands/mpm-help.md +163 -0
- claude_mpm/commands/mpm-init.md +148 -3
- claude_mpm/commands/mpm-version.md +113 -0
- claude_mpm/commands/mpm.md +1 -0
- claude_mpm/config/agent_config.py +2 -2
- claude_mpm/config/model_config.py +428 -0
- claude_mpm/constants.py +1 -0
- claude_mpm/core/base_service.py +13 -12
- claude_mpm/core/enums.py +452 -0
- claude_mpm/core/factories.py +1 -1
- claude_mpm/core/instruction_reinforcement_hook.py +2 -1
- claude_mpm/core/interactive_session.py +9 -3
- claude_mpm/core/log_manager.py +2 -0
- claude_mpm/core/logging_config.py +6 -2
- claude_mpm/core/oneshot_session.py +8 -4
- claude_mpm/core/optimized_agent_loader.py +3 -3
- claude_mpm/core/output_style_manager.py +12 -192
- claude_mpm/core/service_registry.py +5 -1
- claude_mpm/core/types.py +2 -9
- claude_mpm/core/typing_utils.py +7 -6
- claude_mpm/dashboard/static/js/dashboard.js +0 -14
- claude_mpm/dashboard/templates/index.html +3 -41
- claude_mpm/hooks/__init__.py +20 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +4 -2
- claude_mpm/hooks/claude_hooks/response_tracking.py +35 -1
- claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +23 -2
- claude_mpm/hooks/failure_learning/__init__.py +60 -0
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
- claude_mpm/hooks/instruction_reinforcement.py +7 -2
- claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
- claude_mpm/hooks/kuzu_memory_hook.py +37 -12
- claude_mpm/hooks/kuzu_response_hook.py +183 -0
- claude_mpm/models/resume_log.py +340 -0
- claude_mpm/services/agents/__init__.py +18 -5
- claude_mpm/services/agents/auto_config_manager.py +796 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
- claude_mpm/services/agents/deployment/agent_record_service.py +1 -1
- claude_mpm/services/agents/deployment/agent_validator.py +17 -1
- claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
- claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
- claude_mpm/services/agents/deployment/local_template_deployment.py +1 -1
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +7 -6
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +5 -3
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
- claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
- claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
- claude_mpm/services/agents/local_template_manager.py +1 -1
- claude_mpm/services/agents/memory/agent_memory_manager.py +5 -2
- claude_mpm/services/agents/observers.py +547 -0
- claude_mpm/services/agents/recommender.py +568 -0
- claude_mpm/services/agents/registry/modification_tracker.py +5 -2
- claude_mpm/services/command_handler_service.py +11 -5
- claude_mpm/services/core/__init__.py +33 -1
- claude_mpm/services/core/interfaces/__init__.py +90 -3
- claude_mpm/services/core/interfaces/agent.py +184 -0
- claude_mpm/services/core/interfaces/health.py +172 -0
- claude_mpm/services/core/interfaces/model.py +281 -0
- claude_mpm/services/core/interfaces/process.py +372 -0
- claude_mpm/services/core/interfaces/project.py +121 -0
- claude_mpm/services/core/interfaces/restart.py +307 -0
- claude_mpm/services/core/interfaces/stability.py +260 -0
- claude_mpm/services/core/memory_manager.py +11 -24
- claude_mpm/services/core/models/__init__.py +79 -0
- claude_mpm/services/core/models/agent_config.py +381 -0
- claude_mpm/services/core/models/health.py +162 -0
- claude_mpm/services/core/models/process.py +235 -0
- claude_mpm/services/core/models/restart.py +302 -0
- claude_mpm/services/core/models/stability.py +264 -0
- claude_mpm/services/core/models/toolchain.py +306 -0
- claude_mpm/services/core/path_resolver.py +23 -7
- claude_mpm/services/diagnostics/__init__.py +2 -2
- claude_mpm/services/diagnostics/checks/agent_check.py +25 -24
- claude_mpm/services/diagnostics/checks/claude_code_check.py +24 -23
- claude_mpm/services/diagnostics/checks/common_issues_check.py +25 -24
- claude_mpm/services/diagnostics/checks/configuration_check.py +24 -23
- claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
- claude_mpm/services/diagnostics/checks/installation_check.py +30 -29
- claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
- claude_mpm/services/diagnostics/checks/mcp_check.py +50 -36
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +38 -33
- claude_mpm/services/diagnostics/checks/monitor_check.py +23 -22
- claude_mpm/services/diagnostics/checks/startup_log_check.py +9 -8
- claude_mpm/services/diagnostics/diagnostic_runner.py +6 -5
- claude_mpm/services/diagnostics/doctor_reporter.py +28 -25
- claude_mpm/services/diagnostics/models.py +19 -24
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
- claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
- claude_mpm/services/infrastructure/monitoring/base.py +5 -13
- claude_mpm/services/infrastructure/monitoring/network.py +7 -6
- claude_mpm/services/infrastructure/monitoring/process.py +13 -12
- claude_mpm/services/infrastructure/monitoring/resources.py +7 -6
- claude_mpm/services/infrastructure/monitoring/service.py +16 -15
- claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
- claude_mpm/services/local_ops/__init__.py +163 -0
- claude_mpm/services/local_ops/crash_detector.py +257 -0
- claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
- claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
- claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
- claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
- claude_mpm/services/local_ops/health_manager.py +430 -0
- claude_mpm/services/local_ops/log_monitor.py +396 -0
- claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
- claude_mpm/services/local_ops/process_manager.py +595 -0
- claude_mpm/services/local_ops/resource_monitor.py +331 -0
- claude_mpm/services/local_ops/restart_manager.py +401 -0
- claude_mpm/services/local_ops/restart_policy.py +387 -0
- claude_mpm/services/local_ops/state_manager.py +372 -0
- claude_mpm/services/local_ops/unified_manager.py +600 -0
- claude_mpm/services/mcp_config_manager.py +9 -4
- claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
- claude_mpm/services/mcp_gateway/core/base.py +18 -31
- claude_mpm/services/mcp_gateway/main.py +30 -0
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +206 -32
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +30 -28
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +25 -5
- claude_mpm/services/mcp_service_verifier.py +1 -1
- claude_mpm/services/memory/failure_tracker.py +563 -0
- claude_mpm/services/memory_hook_service.py +165 -4
- claude_mpm/services/model/__init__.py +147 -0
- claude_mpm/services/model/base_provider.py +365 -0
- claude_mpm/services/model/claude_provider.py +412 -0
- claude_mpm/services/model/model_router.py +453 -0
- claude_mpm/services/model/ollama_provider.py +415 -0
- claude_mpm/services/monitor/daemon_manager.py +3 -2
- claude_mpm/services/monitor/handlers/dashboard.py +2 -1
- claude_mpm/services/monitor/handlers/hooks.py +2 -1
- claude_mpm/services/monitor/management/lifecycle.py +3 -2
- claude_mpm/services/monitor/server.py +2 -1
- claude_mpm/services/project/__init__.py +23 -0
- claude_mpm/services/project/detection_strategies.py +719 -0
- claude_mpm/services/project/toolchain_analyzer.py +581 -0
- claude_mpm/services/self_upgrade_service.py +342 -0
- claude_mpm/services/session_management_service.py +3 -2
- claude_mpm/services/session_manager.py +205 -1
- claude_mpm/services/shared/async_service_base.py +16 -27
- claude_mpm/services/shared/lifecycle_service_base.py +1 -14
- claude_mpm/services/socketio/handlers/__init__.py +5 -2
- claude_mpm/services/socketio/handlers/hook.py +13 -2
- claude_mpm/services/socketio/handlers/registry.py +4 -2
- claude_mpm/services/socketio/server/main.py +10 -8
- claude_mpm/services/subprocess_launcher_service.py +14 -5
- claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +6 -5
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +8 -7
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +7 -6
- claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +5 -4
- claude_mpm/services/unified/config_strategies/validation_strategy.py +13 -9
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +10 -3
- claude_mpm/services/unified/deployment_strategies/local.py +6 -5
- claude_mpm/services/unified/deployment_strategies/utils.py +6 -5
- claude_mpm/services/unified/deployment_strategies/vercel.py +7 -6
- claude_mpm/services/unified/interfaces.py +3 -1
- claude_mpm/services/unified/unified_analyzer.py +14 -10
- claude_mpm/services/unified/unified_config.py +2 -1
- claude_mpm/services/unified/unified_deployment.py +9 -4
- claude_mpm/services/version_service.py +104 -1
- claude_mpm/skills/__init__.py +21 -0
- claude_mpm/skills/bundled/__init__.py +6 -0
- claude_mpm/skills/bundled/api-documentation.md +393 -0
- claude_mpm/skills/bundled/async-testing.md +571 -0
- claude_mpm/skills/bundled/code-review.md +143 -0
- claude_mpm/skills/bundled/database-migration.md +199 -0
- claude_mpm/skills/bundled/docker-containerization.md +194 -0
- claude_mpm/skills/bundled/express-local-dev.md +1429 -0
- claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
- claude_mpm/skills/bundled/git-workflow.md +414 -0
- claude_mpm/skills/bundled/imagemagick.md +204 -0
- claude_mpm/skills/bundled/json-data-handling.md +223 -0
- claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
- claude_mpm/skills/bundled/pdf.md +141 -0
- claude_mpm/skills/bundled/performance-profiling.md +567 -0
- claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
- claude_mpm/skills/bundled/security-scanning.md +327 -0
- claude_mpm/skills/bundled/systematic-debugging.md +473 -0
- claude_mpm/skills/bundled/test-driven-development.md +378 -0
- claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
- claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
- claude_mpm/skills/bundled/xlsx.md +157 -0
- claude_mpm/skills/registry.py +286 -0
- claude_mpm/skills/skill_manager.py +310 -0
- claude_mpm/storage/state_storage.py +15 -15
- claude_mpm/tools/code_tree_analyzer.py +177 -141
- claude_mpm/tools/code_tree_events.py +4 -2
- claude_mpm/utils/agent_dependency_loader.py +40 -20
- claude_mpm/utils/display_helper.py +260 -0
- claude_mpm/utils/git_analyzer.py +407 -0
- claude_mpm/utils/robust_installer.py +73 -19
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/METADATA +129 -12
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/RECORD +295 -193
- claude_mpm/dashboard/static/css/code-tree.css +0 -1639
- claude_mpm/dashboard/static/index-hub-backup.html +0 -713
- claude_mpm/dashboard/static/js/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/js/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/js/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/js/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/js/components/code-tree.js +0 -5869
- claude_mpm/dashboard/static/js/components/code-viewer.js +0 -1386
- claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
- claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1041
- claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
- claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
- claude_mpm/services/project/analyzer_refactored.py +0 -450
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.7.4.dist-info → claude_mpm-4.18.2.dist-info}/top_level.txt +0 -0
|
@@ -40,9 +40,11 @@ class MemoryManager(IMemoryManager):
|
|
|
40
40
|
4. Legacy format migration (e.g., PM.md -> PM_memories.md)
|
|
41
41
|
5. Memory caching for performance
|
|
42
42
|
|
|
43
|
-
Memory
|
|
44
|
-
-
|
|
45
|
-
-
|
|
43
|
+
Memory Scope:
|
|
44
|
+
- Project-level ONLY: ./.claude-mpm/memories/ (project-scoped isolation)
|
|
45
|
+
- User-level memories are NOT loaded to prevent cross-project contamination
|
|
46
|
+
|
|
47
|
+
Note: As of v4.7.10+, memories are strictly project-scoped for complete isolation.
|
|
46
48
|
"""
|
|
47
49
|
|
|
48
50
|
def __init__(
|
|
@@ -279,7 +281,10 @@ class MemoryManager(IMemoryManager):
|
|
|
279
281
|
|
|
280
282
|
def _load_actual_memories(self, deployed_agents: Set[str]) -> Dict[str, Any]:
|
|
281
283
|
"""
|
|
282
|
-
Load actual memories from
|
|
284
|
+
Load actual memories from project directory only.
|
|
285
|
+
|
|
286
|
+
Memories are project-scoped to ensure complete isolation between projects.
|
|
287
|
+
User-level memories are no longer supported to prevent cross-project contamination.
|
|
283
288
|
|
|
284
289
|
Args:
|
|
285
290
|
deployed_agents: Set of deployed agent names
|
|
@@ -287,32 +292,14 @@ class MemoryManager(IMemoryManager):
|
|
|
287
292
|
Returns:
|
|
288
293
|
Dictionary with actual_memories and agent_memories
|
|
289
294
|
"""
|
|
290
|
-
# Define memory
|
|
291
|
-
user_memories_dir = Path.home() / ".claude-mpm" / "memories"
|
|
295
|
+
# Define project memory directory (project-scoped only)
|
|
292
296
|
project_memories_dir = Path.cwd() / ".claude-mpm" / "memories"
|
|
293
297
|
|
|
294
298
|
# Dictionary to store aggregated memories
|
|
295
299
|
pm_memories = []
|
|
296
300
|
agent_memories_dict = {}
|
|
297
301
|
|
|
298
|
-
# Load memories from
|
|
299
|
-
if user_memories_dir.exists():
|
|
300
|
-
self.logger.info(
|
|
301
|
-
f"Loading user-level memory files from: {user_memories_dir}"
|
|
302
|
-
)
|
|
303
|
-
self._load_memories_from_directory(
|
|
304
|
-
user_memories_dir,
|
|
305
|
-
deployed_agents,
|
|
306
|
-
pm_memories,
|
|
307
|
-
agent_memories_dict,
|
|
308
|
-
"user",
|
|
309
|
-
)
|
|
310
|
-
else:
|
|
311
|
-
self.logger.debug(
|
|
312
|
-
f"No user memories directory found at: {user_memories_dir}"
|
|
313
|
-
)
|
|
314
|
-
|
|
315
|
-
# Load memories from project directory (overrides user memories)
|
|
302
|
+
# Load memories from project directory only
|
|
316
303
|
if project_memories_dir.exists():
|
|
317
304
|
self.logger.info(
|
|
318
305
|
f"Loading project-level memory files from: {project_memories_dir}"
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core Models Package for Claude MPM Framework
|
|
3
|
+
============================================
|
|
4
|
+
|
|
5
|
+
WHY: This package contains data models used across the service layer.
|
|
6
|
+
Models are organized by domain to maintain clear boundaries and enable
|
|
7
|
+
independent evolution of different model types.
|
|
8
|
+
|
|
9
|
+
DESIGN DECISION: Models are grouped by domain (toolchain, agent_config)
|
|
10
|
+
to create logical cohesion and make it easier to understand dependencies
|
|
11
|
+
between different parts of the system.
|
|
12
|
+
|
|
13
|
+
Part of TSK-0054: Auto-Configuration Feature - Phase 1
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from .agent_config import (
|
|
17
|
+
AgentCapabilities,
|
|
18
|
+
AgentRecommendation,
|
|
19
|
+
ConfigurationPreview,
|
|
20
|
+
ConfigurationResult,
|
|
21
|
+
ValidationResult,
|
|
22
|
+
)
|
|
23
|
+
from .process import (
|
|
24
|
+
PROTECTED_PORT_RANGES,
|
|
25
|
+
DeploymentState,
|
|
26
|
+
ProcessInfo,
|
|
27
|
+
StartConfig,
|
|
28
|
+
is_port_protected,
|
|
29
|
+
)
|
|
30
|
+
from .restart import (
|
|
31
|
+
CircuitBreakerState,
|
|
32
|
+
RestartAttempt,
|
|
33
|
+
RestartConfig,
|
|
34
|
+
RestartHistory,
|
|
35
|
+
)
|
|
36
|
+
from .stability import (
|
|
37
|
+
LogPatternMatch,
|
|
38
|
+
MemoryTrend,
|
|
39
|
+
ResourceUsage,
|
|
40
|
+
)
|
|
41
|
+
from .toolchain import (
|
|
42
|
+
ConfidenceLevel,
|
|
43
|
+
DeploymentTarget,
|
|
44
|
+
Framework,
|
|
45
|
+
LanguageDetection,
|
|
46
|
+
ToolchainAnalysis,
|
|
47
|
+
ToolchainComponent,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__all__ = [ # noqa: RUF022 - Grouped by category with comments for clarity
|
|
51
|
+
# Toolchain models
|
|
52
|
+
"ConfidenceLevel",
|
|
53
|
+
"ToolchainComponent",
|
|
54
|
+
"LanguageDetection",
|
|
55
|
+
"Framework",
|
|
56
|
+
"DeploymentTarget",
|
|
57
|
+
"ToolchainAnalysis",
|
|
58
|
+
# Agent configuration models
|
|
59
|
+
"AgentCapabilities",
|
|
60
|
+
"AgentRecommendation",
|
|
61
|
+
"ConfigurationResult",
|
|
62
|
+
"ValidationResult",
|
|
63
|
+
"ConfigurationPreview",
|
|
64
|
+
# Process management models
|
|
65
|
+
"DeploymentState",
|
|
66
|
+
"ProcessInfo",
|
|
67
|
+
"StartConfig",
|
|
68
|
+
"PROTECTED_PORT_RANGES",
|
|
69
|
+
"is_port_protected",
|
|
70
|
+
# Restart management models
|
|
71
|
+
"CircuitBreakerState",
|
|
72
|
+
"RestartAttempt",
|
|
73
|
+
"RestartHistory",
|
|
74
|
+
"RestartConfig",
|
|
75
|
+
# Stability monitoring models
|
|
76
|
+
"MemoryTrend",
|
|
77
|
+
"LogPatternMatch",
|
|
78
|
+
"ResourceUsage",
|
|
79
|
+
]
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent Configuration Data Models for Claude MPM Framework
|
|
3
|
+
========================================================
|
|
4
|
+
|
|
5
|
+
WHY: These models represent agent capabilities, recommendations, and
|
|
6
|
+
configuration results. They provide a standardized way to communicate
|
|
7
|
+
agent suitability, deployment plans, and validation outcomes.
|
|
8
|
+
|
|
9
|
+
DESIGN DECISION: Uses dataclasses with validation to ensure data consistency.
|
|
10
|
+
Includes confidence scores and reasoning to enable transparent decision-making.
|
|
11
|
+
Supports both successful and error states for robust error handling.
|
|
12
|
+
|
|
13
|
+
Part of TSK-0054: Auto-Configuration Feature - Phase 1
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from enum import Enum
|
|
18
|
+
from typing import Any, Dict, List, Optional
|
|
19
|
+
|
|
20
|
+
from ....core.enums import OperationResult, ValidationSeverity
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AgentSpecialization(str, Enum):
|
|
24
|
+
"""Agent specialization categories.
|
|
25
|
+
|
|
26
|
+
WHY: Agents have different areas of expertise. This enum provides
|
|
27
|
+
a standardized taxonomy for categorizing agent capabilities.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
GENERAL = "general"
|
|
31
|
+
LANGUAGE_SPECIFIC = "language_specific"
|
|
32
|
+
FRAMEWORK_SPECIFIC = "framework_specific"
|
|
33
|
+
DEVOPS = "devops"
|
|
34
|
+
SECURITY = "security"
|
|
35
|
+
TESTING = "testing"
|
|
36
|
+
DOCUMENTATION = "documentation"
|
|
37
|
+
PERFORMANCE = "performance"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class AgentCapabilities:
|
|
42
|
+
"""Represents the capabilities of an agent.
|
|
43
|
+
|
|
44
|
+
WHY: Understanding what an agent can do is essential for matching
|
|
45
|
+
agents to projects. This model captures all relevant capability
|
|
46
|
+
information in a structured format.
|
|
47
|
+
|
|
48
|
+
DESIGN DECISION: Frozen to prevent modification of capability definitions.
|
|
49
|
+
Includes both broad categories (specializations) and specific skills
|
|
50
|
+
(languages, frameworks) to enable fine-grained matching.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
agent_id: str
|
|
54
|
+
agent_name: str
|
|
55
|
+
specializations: List[AgentSpecialization] = field(default_factory=list)
|
|
56
|
+
supported_languages: List[str] = field(default_factory=list)
|
|
57
|
+
supported_frameworks: List[str] = field(default_factory=list)
|
|
58
|
+
required_tools: List[str] = field(default_factory=list)
|
|
59
|
+
optional_tools: List[str] = field(default_factory=list)
|
|
60
|
+
deployment_targets: List[str] = field(default_factory=list)
|
|
61
|
+
description: str = ""
|
|
62
|
+
strengths: List[str] = field(default_factory=list)
|
|
63
|
+
limitations: List[str] = field(default_factory=list)
|
|
64
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
65
|
+
|
|
66
|
+
def __post_init__(self):
|
|
67
|
+
"""Validate agent capabilities."""
|
|
68
|
+
if not self.agent_id or not self.agent_id.strip():
|
|
69
|
+
raise ValueError("Agent ID cannot be empty")
|
|
70
|
+
if not self.agent_name or not self.agent_name.strip():
|
|
71
|
+
raise ValueError("Agent name cannot be empty")
|
|
72
|
+
|
|
73
|
+
def supports_language(self, language: str) -> bool:
|
|
74
|
+
"""Check if agent supports a specific language (case-insensitive)."""
|
|
75
|
+
return any(
|
|
76
|
+
lang.lower() == language.lower() for lang in self.supported_languages
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
def supports_framework(self, framework: str) -> bool:
|
|
80
|
+
"""Check if agent supports a specific framework (case-insensitive)."""
|
|
81
|
+
return any(fw.lower() == framework.lower() for fw in self.supported_frameworks)
|
|
82
|
+
|
|
83
|
+
def has_specialization(self, specialization: AgentSpecialization) -> bool:
|
|
84
|
+
"""Check if agent has a specific specialization."""
|
|
85
|
+
return specialization in self.specializations
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass
|
|
89
|
+
class AgentRecommendation:
|
|
90
|
+
"""Represents a recommended agent with reasoning.
|
|
91
|
+
|
|
92
|
+
WHY: Users need to understand why agents are recommended. This model
|
|
93
|
+
captures the recommendation along with confidence score, match reasoning,
|
|
94
|
+
and any warnings or considerations.
|
|
95
|
+
|
|
96
|
+
DESIGN DECISION: Includes detailed reasoning to support transparency
|
|
97
|
+
and enable users to make informed decisions. Confidence score enables
|
|
98
|
+
filtering and ranking of recommendations.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
agent_id: str
|
|
102
|
+
agent_name: str
|
|
103
|
+
confidence_score: float # 0.0-1.0
|
|
104
|
+
match_reasons: List[str] = field(default_factory=list)
|
|
105
|
+
concerns: List[str] = field(default_factory=list)
|
|
106
|
+
capabilities: Optional[AgentCapabilities] = None
|
|
107
|
+
deployment_priority: int = 1 # Lower = higher priority
|
|
108
|
+
configuration_hints: Dict[str, Any] = field(default_factory=dict)
|
|
109
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
110
|
+
|
|
111
|
+
def __post_init__(self):
|
|
112
|
+
"""Validate agent recommendation."""
|
|
113
|
+
if not self.agent_id or not self.agent_id.strip():
|
|
114
|
+
raise ValueError("Agent ID cannot be empty")
|
|
115
|
+
if not self.agent_name or not self.agent_name.strip():
|
|
116
|
+
raise ValueError("Agent name cannot be empty")
|
|
117
|
+
if not (0.0 <= self.confidence_score <= 1.0):
|
|
118
|
+
raise ValueError(
|
|
119
|
+
f"Confidence score must be 0.0-1.0, got {self.confidence_score}"
|
|
120
|
+
)
|
|
121
|
+
if self.deployment_priority < 1:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
f"Deployment priority must be >= 1, got {self.deployment_priority}"
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def is_high_confidence(self) -> bool:
|
|
128
|
+
"""Check if recommendation has high confidence (>= 0.8)."""
|
|
129
|
+
return self.confidence_score >= 0.8
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def is_medium_confidence(self) -> bool:
|
|
133
|
+
"""Check if recommendation has medium confidence (0.5-0.8)."""
|
|
134
|
+
return 0.5 <= self.confidence_score < 0.8
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def is_low_confidence(self) -> bool:
|
|
138
|
+
"""Check if recommendation has low confidence (< 0.5)."""
|
|
139
|
+
return self.confidence_score < 0.5
|
|
140
|
+
|
|
141
|
+
@property
|
|
142
|
+
def has_concerns(self) -> bool:
|
|
143
|
+
"""Check if recommendation has any concerns."""
|
|
144
|
+
return len(self.concerns) > 0
|
|
145
|
+
|
|
146
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
147
|
+
"""Convert recommendation to dictionary."""
|
|
148
|
+
return {
|
|
149
|
+
"agent_id": self.agent_id,
|
|
150
|
+
"agent_name": self.agent_name,
|
|
151
|
+
"confidence_score": self.confidence_score,
|
|
152
|
+
"match_reasons": self.match_reasons,
|
|
153
|
+
"concerns": self.concerns,
|
|
154
|
+
"deployment_priority": self.deployment_priority,
|
|
155
|
+
"configuration_hints": self.configuration_hints,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass
|
|
160
|
+
class ConfigurationResult:
|
|
161
|
+
"""Result of automated configuration operation.
|
|
162
|
+
|
|
163
|
+
WHY: Configuration operations need to return comprehensive results
|
|
164
|
+
including what was deployed, what failed, and any warnings. This model
|
|
165
|
+
provides a complete picture of the configuration outcome.
|
|
166
|
+
|
|
167
|
+
DESIGN DECISION: Separates successful and failed deployments to enable
|
|
168
|
+
proper error handling. Includes validation results and user-facing
|
|
169
|
+
messages for transparency.
|
|
170
|
+
|
|
171
|
+
NOTE: Uses core OperationResult enum (consolidated from ConfigurationStatus
|
|
172
|
+
in Phase 3A Batch 25). Mappings:
|
|
173
|
+
- SUCCESS → OperationResult.SUCCESS
|
|
174
|
+
- PARTIAL_SUCCESS → OperationResult.WARNING (partial success with issues)
|
|
175
|
+
- FAILURE → OperationResult.FAILED
|
|
176
|
+
- VALIDATION_ERROR → OperationResult.ERROR
|
|
177
|
+
- USER_CANCELLED → OperationResult.CANCELLED
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
status: OperationResult
|
|
181
|
+
deployed_agents: List[str] = field(default_factory=list)
|
|
182
|
+
failed_agents: List[str] = field(default_factory=list)
|
|
183
|
+
validation_warnings: List[str] = field(default_factory=list)
|
|
184
|
+
validation_errors: List[str] = field(default_factory=list)
|
|
185
|
+
recommendations: List[AgentRecommendation] = field(default_factory=list)
|
|
186
|
+
message: str = ""
|
|
187
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
188
|
+
|
|
189
|
+
@property
|
|
190
|
+
def is_successful(self) -> bool:
|
|
191
|
+
"""Check if configuration was completely successful."""
|
|
192
|
+
return self.status == OperationResult.SUCCESS
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def has_failures(self) -> bool:
|
|
196
|
+
"""Check if any agents failed to deploy."""
|
|
197
|
+
return len(self.failed_agents) > 0
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def has_warnings(self) -> bool:
|
|
201
|
+
"""Check if there are any warnings."""
|
|
202
|
+
return len(self.validation_warnings) > 0
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def deployment_count(self) -> int:
|
|
206
|
+
"""Get number of successfully deployed agents."""
|
|
207
|
+
return len(self.deployed_agents)
|
|
208
|
+
|
|
209
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
210
|
+
"""Convert result to dictionary."""
|
|
211
|
+
return {
|
|
212
|
+
"status": self.status.value,
|
|
213
|
+
"deployed_agents": self.deployed_agents,
|
|
214
|
+
"failed_agents": self.failed_agents,
|
|
215
|
+
"validation_warnings": self.validation_warnings,
|
|
216
|
+
"validation_errors": self.validation_errors,
|
|
217
|
+
"message": self.message,
|
|
218
|
+
"deployment_count": self.deployment_count,
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
@dataclass
|
|
223
|
+
class ValidationIssue:
|
|
224
|
+
"""Represents a validation issue.
|
|
225
|
+
|
|
226
|
+
WHY: Validation can identify multiple types of issues. This model
|
|
227
|
+
provides structured representation of issues with context and
|
|
228
|
+
suggested resolutions.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
severity: ValidationSeverity
|
|
232
|
+
message: str
|
|
233
|
+
agent_id: Optional[str] = None
|
|
234
|
+
field: Optional[str] = None
|
|
235
|
+
suggested_fix: Optional[str] = None
|
|
236
|
+
|
|
237
|
+
def __post_init__(self):
|
|
238
|
+
"""Validate issue data."""
|
|
239
|
+
if not self.message or not self.message.strip():
|
|
240
|
+
raise ValueError("Validation issue message cannot be empty")
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@dataclass
|
|
244
|
+
class ValidationResult:
|
|
245
|
+
"""Result of configuration validation.
|
|
246
|
+
|
|
247
|
+
WHY: Validation produces multiple types of findings (errors, warnings, info).
|
|
248
|
+
This model aggregates all validation results and provides summary properties.
|
|
249
|
+
|
|
250
|
+
DESIGN DECISION: Separates issues by severity to enable appropriate handling.
|
|
251
|
+
Provides convenience properties for common checks (is_valid, has_errors).
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
is_valid: bool
|
|
255
|
+
issues: List[ValidationIssue] = field(default_factory=list)
|
|
256
|
+
validated_agents: List[str] = field(default_factory=list)
|
|
257
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def errors(self) -> List[ValidationIssue]:
|
|
261
|
+
"""Get all error-level issues."""
|
|
262
|
+
return [
|
|
263
|
+
issue for issue in self.issues if issue.severity == ValidationSeverity.ERROR
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
@property
|
|
267
|
+
def warnings(self) -> List[ValidationIssue]:
|
|
268
|
+
"""Get all warning-level issues."""
|
|
269
|
+
return [
|
|
270
|
+
issue
|
|
271
|
+
for issue in self.issues
|
|
272
|
+
if issue.severity == ValidationSeverity.WARNING
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
@property
|
|
276
|
+
def infos(self) -> List[ValidationIssue]:
|
|
277
|
+
"""Get all info-level issues."""
|
|
278
|
+
return [
|
|
279
|
+
issue for issue in self.issues if issue.severity == ValidationSeverity.INFO
|
|
280
|
+
]
|
|
281
|
+
|
|
282
|
+
@property
|
|
283
|
+
def has_errors(self) -> bool:
|
|
284
|
+
"""Check if validation has any errors."""
|
|
285
|
+
return len(self.errors) > 0
|
|
286
|
+
|
|
287
|
+
@property
|
|
288
|
+
def has_warnings(self) -> bool:
|
|
289
|
+
"""Check if validation has any warnings."""
|
|
290
|
+
return len(self.warnings) > 0
|
|
291
|
+
|
|
292
|
+
@property
|
|
293
|
+
def error_count(self) -> int:
|
|
294
|
+
"""Get number of errors."""
|
|
295
|
+
return len(self.errors)
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def warning_count(self) -> int:
|
|
299
|
+
"""Get number of warnings."""
|
|
300
|
+
return len(self.warnings)
|
|
301
|
+
|
|
302
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
303
|
+
"""Convert validation result to dictionary."""
|
|
304
|
+
return {
|
|
305
|
+
"is_valid": self.is_valid,
|
|
306
|
+
"error_count": self.error_count,
|
|
307
|
+
"warning_count": self.warning_count,
|
|
308
|
+
"validated_agents": self.validated_agents,
|
|
309
|
+
"errors": [
|
|
310
|
+
{
|
|
311
|
+
"severity": issue.severity.value,
|
|
312
|
+
"message": issue.message,
|
|
313
|
+
"agent_id": issue.agent_id,
|
|
314
|
+
}
|
|
315
|
+
for issue in self.errors
|
|
316
|
+
],
|
|
317
|
+
"warnings": [
|
|
318
|
+
{
|
|
319
|
+
"severity": issue.severity.value,
|
|
320
|
+
"message": issue.message,
|
|
321
|
+
"agent_id": issue.agent_id,
|
|
322
|
+
}
|
|
323
|
+
for issue in self.warnings
|
|
324
|
+
],
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
@dataclass
|
|
329
|
+
class ConfigurationPreview:
|
|
330
|
+
"""Preview of what would be configured.
|
|
331
|
+
|
|
332
|
+
WHY: Users need to see what would change before committing. This model
|
|
333
|
+
provides a complete preview including recommendations, validation results,
|
|
334
|
+
and estimated impact.
|
|
335
|
+
|
|
336
|
+
DESIGN DECISION: Includes validation results to show potential issues
|
|
337
|
+
before deployment. Provides summary statistics for quick assessment.
|
|
338
|
+
"""
|
|
339
|
+
|
|
340
|
+
recommendations: List[AgentRecommendation] = field(default_factory=list)
|
|
341
|
+
validation_result: Optional[ValidationResult] = None
|
|
342
|
+
estimated_deployment_time: float = 0.0 # seconds
|
|
343
|
+
would_deploy: List[str] = field(default_factory=list)
|
|
344
|
+
would_skip: List[str] = field(default_factory=list)
|
|
345
|
+
requires_confirmation: bool = True
|
|
346
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
347
|
+
|
|
348
|
+
@property
|
|
349
|
+
def deployment_count(self) -> int:
|
|
350
|
+
"""Get number of agents that would be deployed."""
|
|
351
|
+
return len(self.would_deploy)
|
|
352
|
+
|
|
353
|
+
@property
|
|
354
|
+
def skip_count(self) -> int:
|
|
355
|
+
"""Get number of agents that would be skipped."""
|
|
356
|
+
return len(self.would_skip)
|
|
357
|
+
|
|
358
|
+
@property
|
|
359
|
+
def is_valid(self) -> bool:
|
|
360
|
+
"""Check if preview represents a valid configuration."""
|
|
361
|
+
if self.validation_result is None:
|
|
362
|
+
return True
|
|
363
|
+
return self.validation_result.is_valid
|
|
364
|
+
|
|
365
|
+
@property
|
|
366
|
+
def high_confidence_count(self) -> int:
|
|
367
|
+
"""Get number of high-confidence recommendations."""
|
|
368
|
+
return sum(1 for rec in self.recommendations if rec.is_high_confidence)
|
|
369
|
+
|
|
370
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
371
|
+
"""Convert preview to dictionary."""
|
|
372
|
+
return {
|
|
373
|
+
"deployment_count": self.deployment_count,
|
|
374
|
+
"skip_count": self.skip_count,
|
|
375
|
+
"high_confidence_count": self.high_confidence_count,
|
|
376
|
+
"estimated_deployment_time": self.estimated_deployment_time,
|
|
377
|
+
"is_valid": self.is_valid,
|
|
378
|
+
"would_deploy": self.would_deploy,
|
|
379
|
+
"would_skip": self.would_skip,
|
|
380
|
+
"recommendations": [rec.to_dict() for rec in self.recommendations],
|
|
381
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Health Monitoring Data Models for Claude MPM Framework
|
|
3
|
+
=======================================================
|
|
4
|
+
|
|
5
|
+
WHY: This module defines data structures for health monitoring operations,
|
|
6
|
+
including health status, check results, and deployment health aggregations.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISION: Uses dataclasses for immutability and type safety. Provides
|
|
9
|
+
clear health status enum and structured check results.
|
|
10
|
+
|
|
11
|
+
ARCHITECTURE:
|
|
12
|
+
- HealthStatus: Enum of health states (HEALTHY, DEGRADED, UNHEALTHY, UNKNOWN)
|
|
13
|
+
- HealthCheckResult: Result of a single health check
|
|
14
|
+
- DeploymentHealth: Aggregated health status for a deployment
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from dataclasses import asdict, dataclass, field
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Any, Dict, List
|
|
20
|
+
|
|
21
|
+
from ....core.enums import HealthStatus
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class HealthCheckResult:
|
|
26
|
+
"""
|
|
27
|
+
Result of a single health check.
|
|
28
|
+
|
|
29
|
+
WHY: Contains all information about a specific health check execution,
|
|
30
|
+
enabling detailed analysis and debugging of health issues.
|
|
31
|
+
|
|
32
|
+
Attributes:
|
|
33
|
+
status: HealthStatus of the check
|
|
34
|
+
check_type: Type of health check (http, process, resource)
|
|
35
|
+
message: Human-readable description of the result
|
|
36
|
+
details: Additional check-specific data
|
|
37
|
+
checked_at: Timestamp when check was performed
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
status: HealthStatus
|
|
41
|
+
check_type: str
|
|
42
|
+
message: str
|
|
43
|
+
details: Dict[str, Any] = field(default_factory=dict)
|
|
44
|
+
checked_at: datetime = field(default_factory=datetime.now)
|
|
45
|
+
|
|
46
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
47
|
+
"""
|
|
48
|
+
Convert to dictionary for JSON serialization.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Dictionary representation with datetime converted to ISO format
|
|
52
|
+
"""
|
|
53
|
+
data = asdict(self)
|
|
54
|
+
data["status"] = self.status.value
|
|
55
|
+
data["checked_at"] = self.checked_at.isoformat()
|
|
56
|
+
return data
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def from_dict(cls, data: Dict[str, Any]) -> "HealthCheckResult":
|
|
60
|
+
"""
|
|
61
|
+
Create HealthCheckResult from dictionary.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
data: Dictionary from JSON deserialization
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
HealthCheckResult instance
|
|
68
|
+
"""
|
|
69
|
+
# Convert ISO string to datetime
|
|
70
|
+
if isinstance(data.get("checked_at"), str):
|
|
71
|
+
data["checked_at"] = datetime.fromisoformat(data["checked_at"])
|
|
72
|
+
|
|
73
|
+
# Convert status string to enum
|
|
74
|
+
if isinstance(data.get("status"), str):
|
|
75
|
+
data["status"] = HealthStatus(data["status"])
|
|
76
|
+
|
|
77
|
+
return cls(**data)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class DeploymentHealth:
|
|
82
|
+
"""
|
|
83
|
+
Aggregated health status for a deployment.
|
|
84
|
+
|
|
85
|
+
WHY: Combines results from multiple health checks to provide a
|
|
86
|
+
comprehensive health assessment of a deployment.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
deployment_id: Unique deployment identifier
|
|
90
|
+
overall_status: Aggregated health status
|
|
91
|
+
checks: List of individual health check results
|
|
92
|
+
last_check: Timestamp of the most recent health check
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
deployment_id: str
|
|
96
|
+
overall_status: HealthStatus
|
|
97
|
+
checks: List[HealthCheckResult] = field(default_factory=list)
|
|
98
|
+
last_check: datetime = field(default_factory=datetime.now)
|
|
99
|
+
|
|
100
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
101
|
+
"""
|
|
102
|
+
Convert to dictionary for JSON serialization.
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
Dictionary representation
|
|
106
|
+
"""
|
|
107
|
+
return {
|
|
108
|
+
"deployment_id": self.deployment_id,
|
|
109
|
+
"overall_status": self.overall_status.value,
|
|
110
|
+
"checks": [check.to_dict() for check in self.checks],
|
|
111
|
+
"last_check": self.last_check.isoformat(),
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_dict(cls, data: Dict[str, Any]) -> "DeploymentHealth":
|
|
116
|
+
"""
|
|
117
|
+
Create DeploymentHealth from dictionary.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
data: Dictionary from JSON deserialization
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
DeploymentHealth instance
|
|
124
|
+
"""
|
|
125
|
+
# Convert ISO string to datetime
|
|
126
|
+
if isinstance(data.get("last_check"), str):
|
|
127
|
+
data["last_check"] = datetime.fromisoformat(data["last_check"])
|
|
128
|
+
|
|
129
|
+
# Convert status string to enum
|
|
130
|
+
if isinstance(data.get("overall_status"), str):
|
|
131
|
+
data["overall_status"] = HealthStatus(data["overall_status"])
|
|
132
|
+
|
|
133
|
+
# Convert check dicts to HealthCheckResult objects
|
|
134
|
+
if isinstance(data.get("checks"), list):
|
|
135
|
+
data["checks"] = [
|
|
136
|
+
HealthCheckResult.from_dict(check) if isinstance(check, dict) else check
|
|
137
|
+
for check in data["checks"]
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
return cls(**data)
|
|
141
|
+
|
|
142
|
+
def get_check_by_type(self, check_type: str) -> HealthCheckResult | None:
|
|
143
|
+
"""
|
|
144
|
+
Get the result of a specific check type.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
check_type: Type of health check to retrieve
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
HealthCheckResult if found, None otherwise
|
|
151
|
+
"""
|
|
152
|
+
for check in self.checks:
|
|
153
|
+
if check.check_type == check_type:
|
|
154
|
+
return check
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
__all__ = [
|
|
159
|
+
"DeploymentHealth",
|
|
160
|
+
"HealthCheckResult",
|
|
161
|
+
"HealthStatus",
|
|
162
|
+
]
|