claude-mpm 3.9.11__py3-none-any.whl → 4.0.4__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/__init__.py +2 -2
- claude_mpm/__main__.py +3 -2
- claude_mpm/agents/__init__.py +85 -79
- claude_mpm/agents/agent_loader.py +464 -1003
- claude_mpm/agents/agent_loader_integration.py +45 -45
- claude_mpm/agents/agents_metadata.py +29 -30
- claude_mpm/agents/async_agent_loader.py +156 -138
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/base_agent_loader.py +179 -151
- claude_mpm/agents/frontmatter_validator.py +229 -130
- claude_mpm/agents/schema/agent_schema.json +1 -1
- claude_mpm/agents/system_agent_config.py +213 -147
- claude_mpm/agents/templates/__init__.py +13 -13
- claude_mpm/agents/templates/code_analyzer.json +2 -2
- claude_mpm/agents/templates/data_engineer.json +1 -1
- claude_mpm/agents/templates/documentation.json +23 -11
- claude_mpm/agents/templates/engineer.json +22 -6
- claude_mpm/agents/templates/memory_manager.json +1 -1
- claude_mpm/agents/templates/ops.json +2 -2
- claude_mpm/agents/templates/project_organizer.json +1 -1
- claude_mpm/agents/templates/qa.json +1 -1
- claude_mpm/agents/templates/refactoring_engineer.json +222 -0
- claude_mpm/agents/templates/research.json +20 -14
- claude_mpm/agents/templates/security.json +1 -1
- claude_mpm/agents/templates/ticketing.json +2 -2
- claude_mpm/agents/templates/version_control.json +1 -1
- claude_mpm/agents/templates/web_qa.json +3 -1
- claude_mpm/agents/templates/web_ui.json +2 -2
- claude_mpm/cli/__init__.py +79 -51
- claude_mpm/cli/__main__.py +3 -2
- claude_mpm/cli/commands/__init__.py +20 -20
- claude_mpm/cli/commands/agents.py +279 -247
- claude_mpm/cli/commands/aggregate.py +138 -157
- claude_mpm/cli/commands/cleanup.py +147 -147
- claude_mpm/cli/commands/config.py +93 -76
- claude_mpm/cli/commands/info.py +17 -16
- claude_mpm/cli/commands/mcp.py +140 -905
- claude_mpm/cli/commands/mcp_command_router.py +139 -0
- claude_mpm/cli/commands/mcp_config_commands.py +20 -0
- claude_mpm/cli/commands/mcp_install_commands.py +20 -0
- claude_mpm/cli/commands/mcp_server_commands.py +175 -0
- claude_mpm/cli/commands/mcp_tool_commands.py +34 -0
- claude_mpm/cli/commands/memory.py +239 -203
- claude_mpm/cli/commands/monitor.py +330 -86
- claude_mpm/cli/commands/run.py +380 -429
- claude_mpm/cli/commands/run_config_checker.py +160 -0
- claude_mpm/cli/commands/socketio_monitor.py +235 -0
- claude_mpm/cli/commands/tickets.py +363 -220
- claude_mpm/cli/parser.py +24 -1156
- claude_mpm/cli/parsers/__init__.py +29 -0
- claude_mpm/cli/parsers/agents_parser.py +136 -0
- claude_mpm/cli/parsers/base_parser.py +331 -0
- claude_mpm/cli/parsers/config_parser.py +85 -0
- claude_mpm/cli/parsers/mcp_parser.py +152 -0
- claude_mpm/cli/parsers/memory_parser.py +138 -0
- claude_mpm/cli/parsers/monitor_parser.py +124 -0
- claude_mpm/cli/parsers/run_parser.py +147 -0
- claude_mpm/cli/parsers/tickets_parser.py +203 -0
- claude_mpm/cli/ticket_cli.py +7 -3
- claude_mpm/cli/utils.py +55 -37
- claude_mpm/cli_module/__init__.py +6 -6
- claude_mpm/cli_module/args.py +188 -140
- claude_mpm/cli_module/commands.py +79 -70
- claude_mpm/cli_module/migration_example.py +38 -60
- claude_mpm/config/__init__.py +32 -25
- claude_mpm/config/agent_config.py +151 -119
- claude_mpm/config/experimental_features.py +71 -73
- claude_mpm/config/paths.py +94 -208
- claude_mpm/config/socketio_config.py +84 -73
- claude_mpm/constants.py +35 -18
- claude_mpm/core/__init__.py +9 -6
- claude_mpm/core/agent_name_normalizer.py +68 -71
- claude_mpm/core/agent_registry.py +372 -521
- claude_mpm/core/agent_session_manager.py +74 -63
- claude_mpm/core/base_service.py +116 -87
- claude_mpm/core/cache.py +119 -153
- claude_mpm/core/claude_runner.py +425 -1120
- claude_mpm/core/config.py +263 -168
- claude_mpm/core/config_aliases.py +69 -61
- claude_mpm/core/config_constants.py +292 -0
- claude_mpm/core/constants.py +57 -99
- claude_mpm/core/container.py +211 -178
- claude_mpm/core/exceptions.py +233 -89
- claude_mpm/core/factories.py +92 -54
- claude_mpm/core/framework_loader.py +378 -220
- claude_mpm/core/hook_manager.py +198 -83
- claude_mpm/core/hook_performance_config.py +136 -0
- claude_mpm/core/injectable_service.py +61 -55
- claude_mpm/core/interactive_session.py +165 -155
- claude_mpm/core/interfaces.py +221 -195
- claude_mpm/core/lazy.py +96 -96
- claude_mpm/core/logger.py +133 -107
- claude_mpm/core/logging_config.py +185 -157
- claude_mpm/core/minimal_framework_loader.py +20 -15
- claude_mpm/core/mixins.py +30 -29
- claude_mpm/core/oneshot_session.py +215 -181
- claude_mpm/core/optimized_agent_loader.py +134 -138
- claude_mpm/core/optimized_startup.py +159 -157
- claude_mpm/core/pm_hook_interceptor.py +85 -72
- claude_mpm/core/service_registry.py +103 -101
- claude_mpm/core/session_manager.py +97 -87
- claude_mpm/core/socketio_pool.py +212 -158
- claude_mpm/core/tool_access_control.py +58 -51
- claude_mpm/core/types.py +46 -24
- claude_mpm/core/typing_utils.py +166 -82
- claude_mpm/core/unified_agent_registry.py +721 -0
- claude_mpm/core/unified_config.py +550 -0
- claude_mpm/core/unified_paths.py +549 -0
- claude_mpm/dashboard/index.html +1 -1
- claude_mpm/dashboard/open_dashboard.py +51 -17
- claude_mpm/dashboard/static/built/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/built/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/built/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/built/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/built/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/built/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/built/dashboard.js +2 -0
- claude_mpm/dashboard/static/built/socket-client.js +2 -0
- claude_mpm/dashboard/static/css/dashboard.css +27 -8
- claude_mpm/dashboard/static/dist/components/agent-inference.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-processor.js +2 -0
- claude_mpm/dashboard/static/dist/components/event-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/export-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +2 -0
- claude_mpm/dashboard/static/dist/components/module-viewer.js +2 -0
- claude_mpm/dashboard/static/dist/components/session-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/socket-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +2 -0
- claude_mpm/dashboard/static/dist/components/working-directory.js +2 -0
- claude_mpm/dashboard/static/dist/dashboard.js +2 -0
- claude_mpm/dashboard/static/dist/socket-client.js +2 -0
- claude_mpm/dashboard/static/js/components/agent-inference.js +80 -76
- claude_mpm/dashboard/static/js/components/event-processor.js +71 -67
- claude_mpm/dashboard/static/js/components/event-viewer.js +93 -72
- claude_mpm/dashboard/static/js/components/export-manager.js +31 -28
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +110 -96
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +11 -11
- claude_mpm/dashboard/static/js/components/hud-manager.js +73 -73
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +163 -163
- claude_mpm/dashboard/static/js/components/module-viewer.js +305 -233
- claude_mpm/dashboard/static/js/components/session-manager.js +32 -29
- claude_mpm/dashboard/static/js/components/socket-manager.js +27 -20
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +21 -18
- claude_mpm/dashboard/static/js/components/working-directory.js +74 -71
- claude_mpm/dashboard/static/js/dashboard.js +178 -453
- claude_mpm/dashboard/static/js/extension-error-handler.js +164 -0
- claude_mpm/dashboard/static/js/socket-client.js +133 -53
- claude_mpm/dashboard/templates/index.html +40 -50
- claude_mpm/experimental/cli_enhancements.py +60 -58
- claude_mpm/generators/__init__.py +1 -1
- claude_mpm/generators/agent_profile_generator.py +75 -65
- claude_mpm/hooks/__init__.py +1 -1
- claude_mpm/hooks/base_hook.py +33 -28
- claude_mpm/hooks/claude_hooks/__init__.py +1 -1
- claude_mpm/hooks/claude_hooks/connection_pool.py +120 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +743 -0
- claude_mpm/hooks/claude_hooks/hook_handler.py +415 -1331
- claude_mpm/hooks/claude_hooks/hook_wrapper.sh +4 -4
- claude_mpm/hooks/claude_hooks/memory_integration.py +221 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +348 -0
- claude_mpm/hooks/claude_hooks/tool_analysis.py +230 -0
- claude_mpm/hooks/memory_integration_hook.py +140 -100
- claude_mpm/hooks/tool_call_interceptor.py +89 -76
- claude_mpm/hooks/validation_hooks.py +57 -49
- claude_mpm/init.py +145 -121
- claude_mpm/models/__init__.py +9 -9
- claude_mpm/models/agent_definition.py +33 -23
- claude_mpm/models/agent_session.py +228 -200
- claude_mpm/scripts/__init__.py +1 -1
- claude_mpm/scripts/socketio_daemon.py +192 -75
- claude_mpm/scripts/socketio_server_manager.py +328 -0
- claude_mpm/scripts/start_activity_logging.py +25 -22
- claude_mpm/services/__init__.py +68 -43
- claude_mpm/services/agent_capabilities_service.py +271 -0
- claude_mpm/services/agents/__init__.py +23 -32
- claude_mpm/services/agents/deployment/__init__.py +3 -3
- claude_mpm/services/agents/deployment/agent_config_provider.py +310 -0
- claude_mpm/services/agents/deployment/agent_configuration_manager.py +359 -0
- claude_mpm/services/agents/deployment/agent_definition_factory.py +84 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +415 -2113
- claude_mpm/services/agents/deployment/agent_discovery_service.py +387 -0
- claude_mpm/services/agents/deployment/agent_environment_manager.py +293 -0
- claude_mpm/services/agents/deployment/agent_filesystem_manager.py +387 -0
- claude_mpm/services/agents/deployment/agent_format_converter.py +453 -0
- claude_mpm/services/agents/deployment/agent_frontmatter_validator.py +161 -0
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +345 -495
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +279 -0
- claude_mpm/services/agents/deployment/agent_restore_handler.py +88 -0
- claude_mpm/services/agents/deployment/agent_template_builder.py +406 -0
- claude_mpm/services/agents/deployment/agent_validator.py +352 -0
- claude_mpm/services/agents/deployment/agent_version_manager.py +313 -0
- claude_mpm/services/agents/deployment/agent_versioning.py +6 -9
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +79 -0
- claude_mpm/services/agents/deployment/async_agent_deployment.py +298 -234
- claude_mpm/services/agents/deployment/config/__init__.py +13 -0
- claude_mpm/services/agents/deployment/config/deployment_config.py +182 -0
- claude_mpm/services/agents/deployment/config/deployment_config_manager.py +200 -0
- claude_mpm/services/agents/deployment/deployment_config_loader.py +54 -0
- claude_mpm/services/agents/deployment/deployment_type_detector.py +124 -0
- claude_mpm/services/agents/deployment/facade/__init__.py +18 -0
- claude_mpm/services/agents/deployment/facade/async_deployment_executor.py +159 -0
- claude_mpm/services/agents/deployment/facade/deployment_executor.py +73 -0
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +270 -0
- claude_mpm/services/agents/deployment/facade/sync_deployment_executor.py +178 -0
- claude_mpm/services/agents/deployment/interface_adapter.py +227 -0
- claude_mpm/services/agents/deployment/lifecycle_health_checker.py +85 -0
- claude_mpm/services/agents/deployment/lifecycle_performance_tracker.py +100 -0
- claude_mpm/services/agents/deployment/pipeline/__init__.py +32 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_builder.py +158 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_context.py +159 -0
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +169 -0
- claude_mpm/services/agents/deployment/pipeline/steps/__init__.py +19 -0
- claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +195 -0
- claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +119 -0
- claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +79 -0
- claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +90 -0
- claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +100 -0
- claude_mpm/services/agents/deployment/processors/__init__.py +15 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_context.py +98 -0
- claude_mpm/services/agents/deployment/processors/agent_deployment_result.py +235 -0
- claude_mpm/services/agents/deployment/processors/agent_processor.py +258 -0
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +318 -0
- claude_mpm/services/agents/deployment/results/__init__.py +13 -0
- claude_mpm/services/agents/deployment/results/deployment_metrics.py +200 -0
- claude_mpm/services/agents/deployment/results/deployment_result_builder.py +249 -0
- claude_mpm/services/agents/deployment/strategies/__init__.py +25 -0
- claude_mpm/services/agents/deployment/strategies/base_strategy.py +119 -0
- claude_mpm/services/agents/deployment/strategies/project_strategy.py +150 -0
- claude_mpm/services/agents/deployment/strategies/strategy_selector.py +117 -0
- claude_mpm/services/agents/deployment/strategies/system_strategy.py +116 -0
- claude_mpm/services/agents/deployment/strategies/user_strategy.py +137 -0
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +108 -0
- claude_mpm/services/agents/deployment/validation/__init__.py +19 -0
- claude_mpm/services/agents/deployment/validation/agent_validator.py +323 -0
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +238 -0
- claude_mpm/services/agents/deployment/validation/template_validator.py +299 -0
- claude_mpm/services/agents/deployment/validation/validation_result.py +226 -0
- claude_mpm/services/agents/loading/__init__.py +2 -2
- claude_mpm/services/agents/loading/agent_profile_loader.py +259 -229
- claude_mpm/services/agents/loading/base_agent_manager.py +90 -81
- claude_mpm/services/agents/loading/framework_agent_loader.py +154 -129
- claude_mpm/services/agents/management/__init__.py +2 -2
- claude_mpm/services/agents/management/agent_capabilities_generator.py +72 -58
- claude_mpm/services/agents/management/agent_management_service.py +209 -156
- claude_mpm/services/agents/memory/__init__.py +9 -6
- claude_mpm/services/agents/memory/agent_memory_manager.py +218 -1152
- claude_mpm/services/agents/memory/agent_persistence_service.py +20 -16
- claude_mpm/services/agents/memory/analyzer.py +430 -0
- claude_mpm/services/agents/memory/content_manager.py +376 -0
- claude_mpm/services/agents/memory/template_generator.py +468 -0
- claude_mpm/services/agents/registry/__init__.py +7 -10
- claude_mpm/services/agents/registry/deployed_agent_discovery.py +122 -97
- claude_mpm/services/agents/registry/modification_tracker.py +351 -285
- claude_mpm/services/async_session_logger.py +187 -153
- claude_mpm/services/claude_session_logger.py +87 -72
- claude_mpm/services/command_handler_service.py +217 -0
- claude_mpm/services/communication/__init__.py +3 -2
- claude_mpm/services/core/__init__.py +50 -97
- claude_mpm/services/core/base.py +60 -53
- claude_mpm/services/core/interfaces/__init__.py +188 -0
- claude_mpm/services/core/interfaces/agent.py +351 -0
- claude_mpm/services/core/interfaces/communication.py +343 -0
- claude_mpm/services/core/interfaces/infrastructure.py +413 -0
- claude_mpm/services/core/interfaces/service.py +434 -0
- claude_mpm/services/core/interfaces.py +19 -944
- claude_mpm/services/event_aggregator.py +208 -170
- claude_mpm/services/exceptions.py +387 -308
- claude_mpm/services/framework_claude_md_generator/__init__.py +75 -79
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +69 -60
- claude_mpm/services/framework_claude_md_generator/content_validator.py +65 -61
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +68 -49
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +34 -34
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +25 -22
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +10 -10
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +8 -7
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +6 -5
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +9 -8
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +4 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +5 -4
- claude_mpm/services/framework_claude_md_generator/section_manager.py +28 -27
- claude_mpm/services/framework_claude_md_generator/version_manager.py +30 -28
- claude_mpm/services/hook_service.py +106 -114
- claude_mpm/services/infrastructure/__init__.py +7 -5
- claude_mpm/services/infrastructure/context_preservation.py +233 -199
- claude_mpm/services/infrastructure/daemon_manager.py +279 -0
- claude_mpm/services/infrastructure/logging.py +83 -76
- claude_mpm/services/infrastructure/monitoring.py +547 -404
- claude_mpm/services/mcp_gateway/__init__.py +30 -13
- claude_mpm/services/mcp_gateway/config/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/config/config_loader.py +61 -56
- claude_mpm/services/mcp_gateway/config/config_schema.py +50 -41
- claude_mpm/services/mcp_gateway/config/configuration.py +82 -75
- claude_mpm/services/mcp_gateway/core/__init__.py +13 -20
- claude_mpm/services/mcp_gateway/core/base.py +80 -67
- claude_mpm/services/mcp_gateway/core/exceptions.py +60 -46
- claude_mpm/services/mcp_gateway/core/interfaces.py +87 -84
- claude_mpm/services/mcp_gateway/main.py +287 -137
- claude_mpm/services/mcp_gateway/registry/__init__.py +1 -1
- claude_mpm/services/mcp_gateway/registry/service_registry.py +97 -94
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +135 -126
- claude_mpm/services/mcp_gateway/server/__init__.py +2 -2
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +105 -110
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +105 -107
- claude_mpm/services/mcp_gateway/server/stdio_server.py +691 -0
- claude_mpm/services/mcp_gateway/tools/__init__.py +4 -2
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +109 -119
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +283 -215
- claude_mpm/services/mcp_gateway/tools/hello_world.py +122 -120
- claude_mpm/services/mcp_gateway/tools/ticket_tools.py +652 -0
- claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +606 -0
- claude_mpm/services/memory/__init__.py +2 -2
- claude_mpm/services/memory/builder.py +451 -362
- claude_mpm/services/memory/cache/__init__.py +2 -2
- claude_mpm/services/memory/cache/shared_prompt_cache.py +232 -194
- claude_mpm/services/memory/cache/simple_cache.py +107 -93
- claude_mpm/services/memory/indexed_memory.py +195 -193
- claude_mpm/services/memory/optimizer.py +267 -234
- claude_mpm/services/memory/router.py +571 -263
- claude_mpm/services/memory_hook_service.py +237 -0
- claude_mpm/services/port_manager.py +575 -0
- claude_mpm/services/project/__init__.py +3 -3
- claude_mpm/services/project/analyzer.py +451 -305
- claude_mpm/services/project/registry.py +262 -240
- claude_mpm/services/recovery_manager.py +287 -231
- claude_mpm/services/response_tracker.py +87 -67
- claude_mpm/services/runner_configuration_service.py +587 -0
- claude_mpm/services/session_management_service.py +304 -0
- claude_mpm/services/socketio/__init__.py +4 -4
- claude_mpm/services/socketio/client_proxy.py +174 -0
- claude_mpm/services/socketio/handlers/__init__.py +3 -3
- claude_mpm/services/socketio/handlers/base.py +44 -30
- claude_mpm/services/socketio/handlers/connection.py +166 -64
- claude_mpm/services/socketio/handlers/file.py +123 -108
- claude_mpm/services/socketio/handlers/git.py +607 -373
- claude_mpm/services/socketio/handlers/hook.py +185 -0
- claude_mpm/services/socketio/handlers/memory.py +4 -4
- claude_mpm/services/socketio/handlers/project.py +4 -4
- claude_mpm/services/socketio/handlers/registry.py +53 -38
- claude_mpm/services/socketio/server/__init__.py +18 -0
- claude_mpm/services/socketio/server/broadcaster.py +252 -0
- claude_mpm/services/socketio/server/core.py +399 -0
- claude_mpm/services/socketio/server/main.py +323 -0
- claude_mpm/services/socketio_client_manager.py +160 -133
- claude_mpm/services/socketio_server.py +36 -1885
- claude_mpm/services/subprocess_launcher_service.py +316 -0
- claude_mpm/services/system_instructions_service.py +258 -0
- claude_mpm/services/ticket_manager.py +19 -533
- claude_mpm/services/utility_service.py +285 -0
- claude_mpm/services/version_control/__init__.py +18 -21
- claude_mpm/services/version_control/branch_strategy.py +20 -10
- claude_mpm/services/version_control/conflict_resolution.py +37 -13
- claude_mpm/services/version_control/git_operations.py +52 -21
- claude_mpm/services/version_control/semantic_versioning.py +92 -53
- claude_mpm/services/version_control/version_parser.py +145 -125
- claude_mpm/services/version_service.py +270 -0
- claude_mpm/storage/__init__.py +2 -2
- claude_mpm/storage/state_storage.py +177 -181
- claude_mpm/ticket_wrapper.py +2 -2
- claude_mpm/utils/__init__.py +2 -2
- claude_mpm/utils/agent_dependency_loader.py +453 -243
- claude_mpm/utils/config_manager.py +157 -118
- claude_mpm/utils/console.py +1 -1
- claude_mpm/utils/dependency_cache.py +102 -107
- claude_mpm/utils/dependency_manager.py +52 -47
- claude_mpm/utils/dependency_strategies.py +131 -96
- claude_mpm/utils/environment_context.py +110 -102
- claude_mpm/utils/error_handler.py +75 -55
- claude_mpm/utils/file_utils.py +80 -67
- claude_mpm/utils/framework_detection.py +12 -11
- claude_mpm/utils/import_migration_example.py +12 -60
- claude_mpm/utils/imports.py +48 -45
- claude_mpm/utils/path_operations.py +100 -93
- claude_mpm/utils/robust_installer.py +172 -164
- claude_mpm/utils/session_logging.py +30 -23
- claude_mpm/utils/subprocess_utils.py +99 -61
- claude_mpm/validation/__init__.py +1 -1
- claude_mpm/validation/agent_validator.py +151 -111
- claude_mpm/validation/frontmatter_validator.py +92 -71
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/METADATA +90 -22
- claude_mpm-4.0.4.dist-info/RECORD +417 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/entry_points.txt +1 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/licenses/LICENSE +1 -1
- claude_mpm/cli/commands/run_guarded.py +0 -511
- claude_mpm/config/memory_guardian_config.py +0 -325
- claude_mpm/config/memory_guardian_yaml.py +0 -335
- claude_mpm/core/config_paths.py +0 -150
- claude_mpm/core/memory_aware_runner.py +0 -353
- claude_mpm/dashboard/static/js/dashboard-original.js +0 -4134
- claude_mpm/deployment_paths.py +0 -261
- claude_mpm/hooks/claude_hooks/hook_handler_fixed.py +0 -454
- claude_mpm/models/state_models.py +0 -433
- claude_mpm/services/agent/__init__.py +0 -24
- claude_mpm/services/agent/deployment.py +0 -2548
- claude_mpm/services/agent/management.py +0 -598
- claude_mpm/services/agent/registry.py +0 -813
- claude_mpm/services/agents/registry/agent_registry.py +0 -813
- claude_mpm/services/communication/socketio.py +0 -1935
- claude_mpm/services/communication/websocket.py +0 -479
- claude_mpm/services/framework_claude_md_generator.py +0 -624
- claude_mpm/services/health_monitor.py +0 -893
- claude_mpm/services/infrastructure/graceful_degradation.py +0 -616
- claude_mpm/services/infrastructure/health_monitor.py +0 -775
- claude_mpm/services/infrastructure/memory_dashboard.py +0 -479
- claude_mpm/services/infrastructure/memory_guardian.py +0 -944
- claude_mpm/services/infrastructure/restart_protection.py +0 -642
- claude_mpm/services/infrastructure/state_manager.py +0 -774
- claude_mpm/services/mcp_gateway/manager.py +0 -334
- claude_mpm/services/optimized_hook_service.py +0 -542
- claude_mpm/services/project_analyzer.py +0 -864
- claude_mpm/services/project_registry.py +0 -608
- claude_mpm/services/standalone_socketio_server.py +0 -1300
- claude_mpm/services/ticket_manager_di.py +0 -318
- claude_mpm/services/ticketing_service_original.py +0 -510
- claude_mpm/utils/paths.py +0 -395
- claude_mpm/utils/platform_memory.py +0 -524
- claude_mpm-3.9.11.dist-info/RECORD +0 -306
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/WHEEL +0 -0
- {claude_mpm-3.9.11.dist-info → claude_mpm-4.0.4.dist-info}/top_level.txt +0 -0
    
        claude_mpm/core/base_service.py
    CHANGED
    
    | @@ -18,19 +18,17 @@ Provides: | |
| 18 18 |  | 
| 19 19 | 
             
            import asyncio
         | 
| 20 20 | 
             
            import logging
         | 
| 21 | 
            -
            import signal
         | 
| 22 | 
            -
            import sys
         | 
| 23 21 | 
             
            import os
         | 
| 22 | 
            +
            import signal
         | 
| 23 | 
            +
            import threading
         | 
| 24 24 | 
             
            import time
         | 
| 25 25 | 
             
            import traceback
         | 
| 26 | 
            -
            import threading
         | 
| 27 26 | 
             
            from abc import ABC, abstractmethod
         | 
| 27 | 
            +
            from contextlib import asynccontextmanager
         | 
| 28 28 | 
             
            from dataclasses import dataclass, field
         | 
| 29 29 | 
             
            from datetime import datetime, timedelta
         | 
| 30 | 
            -
            from typing import Any, Dict, List, Optional, Union, Type, Callable
         | 
| 31 30 | 
             
            from pathlib import Path
         | 
| 32 | 
            -
            from  | 
| 33 | 
            -
            import json
         | 
| 31 | 
            +
            from typing import Any, Callable, Dict, List, Optional, Type, Union
         | 
| 34 32 |  | 
| 35 33 | 
             
            from .config import Config
         | 
| 36 34 | 
             
            from .logger import setup_logging
         | 
| @@ -40,6 +38,7 @@ from .mixins import LoggerMixin | |
| 40 38 | 
             
            @dataclass
         | 
| 41 39 | 
             
            class ServiceHealth:
         | 
| 42 40 | 
             
                """Service health status information."""
         | 
| 41 | 
            +
             | 
| 43 42 | 
             
                status: str  # healthy, degraded, unhealthy, unknown
         | 
| 44 43 | 
             
                message: str
         | 
| 45 44 | 
             
                timestamp: str
         | 
| @@ -50,6 +49,7 @@ class ServiceHealth: | |
| 50 49 | 
             
            @dataclass
         | 
| 51 50 | 
             
            class ServiceMetrics:
         | 
| 52 51 | 
             
                """Service metrics collection."""
         | 
| 52 | 
            +
             | 
| 53 53 | 
             
                requests_total: int = 0
         | 
| 54 54 | 
             
                requests_failed: int = 0
         | 
| 55 55 | 
             
                response_time_avg: float = 0.0
         | 
| @@ -61,6 +61,7 @@ class ServiceMetrics: | |
| 61 61 | 
             
            @dataclass
         | 
| 62 62 | 
             
            class ServiceContext:
         | 
| 63 63 | 
             
                """Service execution context with request tracking (enhanced feature)."""
         | 
| 64 | 
            +
             | 
| 64 65 | 
             
                request_id: str
         | 
| 65 66 | 
             
                start_time: float
         | 
| 66 67 | 
             
                service_name: str
         | 
| @@ -71,6 +72,7 @@ class ServiceContext: | |
| 71 72 | 
             
            @dataclass
         | 
| 72 73 | 
             
            class CircuitBreakerState:
         | 
| 73 74 | 
             
                """Circuit breaker state for service resilience (enhanced feature)."""
         | 
| 75 | 
            +
             | 
| 74 76 | 
             
                failure_count: int = 0
         | 
| 75 77 | 
             
                last_failure_time: Optional[float] = None
         | 
| 76 78 | 
             
                state: str = "closed"  # closed, open, half_open
         | 
| @@ -100,12 +102,12 @@ class BaseService(LoggerMixin, ABC): | |
| 100 102 | 
             
                """
         | 
| 101 103 |  | 
| 102 104 | 
             
                def __init__(
         | 
| 103 | 
            -
                    self, | 
| 104 | 
            -
                    name: str, | 
| 105 | 
            -
                    config: Optional[Dict[str, Any]] = None, | 
| 105 | 
            +
                    self,
         | 
| 106 | 
            +
                    name: str,
         | 
| 107 | 
            +
                    config: Optional[Dict[str, Any]] = None,
         | 
| 106 108 | 
             
                    config_path: Optional[Path] = None,
         | 
| 107 109 | 
             
                    enable_enhanced_features: bool = False,
         | 
| 108 | 
            -
                    container: Optional[Any] = None
         | 
| 110 | 
            +
                    container: Optional[Any] = None,
         | 
| 109 111 | 
             
                ):
         | 
| 110 112 | 
             
                    """
         | 
| 111 113 | 
             
                    Initialize the base service.
         | 
| @@ -121,9 +123,11 @@ class BaseService(LoggerMixin, ABC): | |
| 121 123 | 
             
                    self.config = Config(config or {}, config_path)
         | 
| 122 124 | 
             
                    self._enable_enhanced = enable_enhanced_features
         | 
| 123 125 | 
             
                    self._container = container
         | 
| 124 | 
            -
             | 
| 126 | 
            +
             | 
| 125 127 | 
             
                    # Set custom logger name based on service name
         | 
| 126 | 
            -
                    self._logger_name =  | 
| 128 | 
            +
                    self._logger_name = (
         | 
| 129 | 
            +
                        f"{self.__class__.__module__}.{self.__class__.__name__}.{name}"
         | 
| 130 | 
            +
                    )
         | 
| 127 131 |  | 
| 128 132 | 
             
                    # Service state
         | 
| 129 133 | 
             
                    self._running = False
         | 
| @@ -133,7 +137,9 @@ class BaseService(LoggerMixin, ABC): | |
| 133 137 |  | 
| 134 138 | 
             
                    # Health and metrics
         | 
| 135 139 | 
             
                    self._health = ServiceHealth(
         | 
| 136 | 
            -
                        status="unknown", | 
| 140 | 
            +
                        status="unknown",
         | 
| 141 | 
            +
                        message="Service not started",
         | 
| 142 | 
            +
                        timestamp=datetime.now().isoformat(),
         | 
| 137 143 | 
             
                    )
         | 
| 138 144 | 
             
                    self._metrics = ServiceMetrics()
         | 
| 139 145 | 
             
                    self._last_health_check: Optional[float] = None
         | 
| @@ -144,39 +150,39 @@ class BaseService(LoggerMixin, ABC): | |
| 144 150 | 
             
                    # Enhanced features (only initialized if enabled)
         | 
| 145 151 | 
             
                    if self._enable_enhanced:
         | 
| 146 152 | 
             
                        self._init_enhanced_features()
         | 
| 147 | 
            -
             | 
| 153 | 
            +
             | 
| 148 154 | 
             
                    # Check for quiet mode
         | 
| 149 155 | 
             
                    default_log_level = "INFO"
         | 
| 150 | 
            -
                    if os.getenv( | 
| 156 | 
            +
                    if os.getenv("CLAUDE_PM_QUIET_MODE") == "true":
         | 
| 151 157 | 
             
                        default_log_level = "WARNING"
         | 
| 152 158 | 
             
                        self.logger.setLevel(logging.WARNING)
         | 
| 153 | 
            -
             | 
| 159 | 
            +
             | 
| 154 160 | 
             
                    # Only log if not in quiet mode
         | 
| 155 | 
            -
                    if not os.environ.get( | 
| 161 | 
            +
                    if not os.environ.get("CLAUDE_PM_QUIET_MODE", "").lower() == "true":
         | 
| 156 162 | 
             
                        self.logger.info(f"Initialized {self.name} service")
         | 
| 157 163 |  | 
| 158 164 | 
             
                def _init_enhanced_features(self):
         | 
| 159 165 | 
             
                    """Initialize enhanced features when enabled."""
         | 
| 160 166 | 
             
                    # Circuit breaker for resilience
         | 
| 161 167 | 
             
                    self._circuit_breaker = CircuitBreakerState()
         | 
| 162 | 
            -
             | 
| 168 | 
            +
             | 
| 163 169 | 
             
                    # Error tracking
         | 
| 164 170 | 
             
                    self._error_counts: Dict[str, int] = {}
         | 
| 165 | 
            -
             | 
| 171 | 
            +
             | 
| 166 172 | 
             
                    # Request tracking
         | 
| 167 173 | 
             
                    self._request_contexts: Dict[str, ServiceContext] = {}
         | 
| 168 | 
            -
             | 
| 174 | 
            +
             | 
| 169 175 | 
             
                    # Performance metrics
         | 
| 170 176 | 
             
                    self._performance_metrics: Dict[str, List[float]] = {}
         | 
| 171 | 
            -
             | 
| 177 | 
            +
             | 
| 172 178 | 
             
                    # Thread safety
         | 
| 173 179 | 
             
                    self._lock = threading.RLock()
         | 
| 174 | 
            -
             | 
| 180 | 
            +
             | 
| 175 181 | 
             
                    # Optional service dependencies
         | 
| 176 182 | 
             
                    self._health_monitor: Optional[Any] = None
         | 
| 177 183 | 
             
                    self._error_handler: Optional[Any] = None
         | 
| 178 184 | 
             
                    self._cache: Optional[Any] = None
         | 
| 179 | 
            -
             | 
| 185 | 
            +
             | 
| 180 186 | 
             
                    # Register dependencies if container provided
         | 
| 181 187 | 
             
                    if self._container:
         | 
| 182 188 | 
             
                        self._register_service_dependencies()
         | 
| @@ -231,9 +237,11 @@ class BaseService(LoggerMixin, ABC): | |
| 231 237 | 
             
                            timestamp=datetime.now().isoformat(),
         | 
| 232 238 | 
             
                            checks={"startup": False},
         | 
| 233 239 | 
             
                        )
         | 
| 234 | 
            -
             | 
| 235 | 
            -
                        if self._enable_enhanced and hasattr(self,  | 
| 236 | 
            -
                            await self._handle_error( | 
| 240 | 
            +
             | 
| 241 | 
            +
                        if self._enable_enhanced and hasattr(self, "_handle_error"):
         | 
| 242 | 
            +
                            await self._handle_error(
         | 
| 243 | 
            +
                                e, {"operation": "start", "service": self.name}
         | 
| 244 | 
            +
                            )
         | 
| 237 245 | 
             
                        raise
         | 
| 238 246 |  | 
| 239 247 | 
             
                async def _start_internal(self):
         | 
| @@ -242,7 +250,7 @@ class BaseService(LoggerMixin, ABC): | |
| 242 250 | 
             
                    self._setup_signal_handlers()
         | 
| 243 251 |  | 
| 244 252 | 
             
                    # Initialize dependencies if enhanced
         | 
| 245 | 
            -
                    if self._enable_enhanced and hasattr(self,  | 
| 253 | 
            +
                    if self._enable_enhanced and hasattr(self, "_initialize_dependencies"):
         | 
| 246 254 | 
             
                        await self._initialize_dependencies()
         | 
| 247 255 |  | 
| 248 256 | 
             
                    # Initialize service
         | 
| @@ -252,7 +260,7 @@ class BaseService(LoggerMixin, ABC): | |
| 252 260 | 
             
                    await self._start_background_tasks()
         | 
| 253 261 |  | 
| 254 262 | 
             
                    # Register with health monitor if available
         | 
| 255 | 
            -
                    if self._enable_enhanced and hasattr(self,  | 
| 263 | 
            +
                    if self._enable_enhanced and hasattr(self, "_register_with_health_monitor"):
         | 
| 256 264 | 
             
                        await self._register_with_health_monitor()
         | 
| 257 265 |  | 
| 258 266 | 
             
                    # Mark as running
         | 
| @@ -265,7 +273,7 @@ class BaseService(LoggerMixin, ABC): | |
| 265 273 | 
             
                        message="Service started successfully",
         | 
| 266 274 | 
             
                        timestamp=datetime.now().isoformat(),
         | 
| 267 275 | 
             
                        checks={"startup": True},
         | 
| 268 | 
            -
                        metrics=self._get_health_metrics() if self._enable_enhanced else {}
         | 
| 276 | 
            +
                        metrics=self._get_health_metrics() if self._enable_enhanced else {},
         | 
| 269 277 | 
             
                    )
         | 
| 270 278 |  | 
| 271 279 | 
             
                async def stop(self) -> None:
         | 
| @@ -295,7 +303,7 @@ class BaseService(LoggerMixin, ABC): | |
| 295 303 | 
             
                        raise
         | 
| 296 304 | 
             
                    except Exception as e:
         | 
| 297 305 | 
             
                        self.logger.error(f"Error stopping service {self.name}: {e}")
         | 
| 298 | 
            -
                        if self._enable_enhanced and hasattr(self,  | 
| 306 | 
            +
                        if self._enable_enhanced and hasattr(self, "_handle_error"):
         | 
| 299 307 | 
             
                            await self._handle_error(e, {"operation": "stop", "service": self.name})
         | 
| 300 308 | 
             
                        raise
         | 
| 301 309 |  | 
| @@ -305,7 +313,7 @@ class BaseService(LoggerMixin, ABC): | |
| 305 313 | 
             
                    self._stop_event.set()
         | 
| 306 314 |  | 
| 307 315 | 
             
                    # Unregister from health monitor if available
         | 
| 308 | 
            -
                    if self._enable_enhanced and hasattr(self,  | 
| 316 | 
            +
                    if self._enable_enhanced and hasattr(self, "_unregister_from_health_monitor"):
         | 
| 309 317 | 
             
                        await self._unregister_from_health_monitor()
         | 
| 310 318 |  | 
| 311 319 | 
             
                    # Cancel background tasks
         | 
| @@ -346,7 +354,7 @@ class BaseService(LoggerMixin, ABC): | |
| 346 354 | 
             
                    """
         | 
| 347 355 | 
             
                    try:
         | 
| 348 356 | 
             
                        # Use enhanced health check if enabled
         | 
| 349 | 
            -
                        if self._enable_enhanced and hasattr(self,  | 
| 357 | 
            +
                        if self._enable_enhanced and hasattr(self, "_enhanced_health_check"):
         | 
| 350 358 | 
             
                            return await self._enhanced_health_check()
         | 
| 351 359 |  | 
| 352 360 | 
             
                        # Basic health check
         | 
| @@ -412,8 +420,11 @@ class BaseService(LoggerMixin, ABC): | |
| 412 420 |  | 
| 413 421 | 
             
                def _setup_signal_handlers(self) -> None:
         | 
| 414 422 | 
             
                    """Setup signal handlers for graceful shutdown."""
         | 
| 423 | 
            +
             | 
| 415 424 | 
             
                    def signal_handler(signum, frame):
         | 
| 416 | 
            -
                        self.logger.info( | 
| 425 | 
            +
                        self.logger.info(
         | 
| 426 | 
            +
                            f"Received signal {signum}, initiating graceful shutdown..."
         | 
| 427 | 
            +
                        )
         | 
| 417 428 | 
             
                        asyncio.create_task(self.stop())
         | 
| 418 429 |  | 
| 419 430 | 
             
                    signal.signal(signal.SIGINT, signal_handler)
         | 
| @@ -472,6 +483,7 @@ class BaseService(LoggerMixin, ABC): | |
| 472 483 | 
             
                        # Memory usage (basic implementation)
         | 
| 473 484 | 
             
                        try:
         | 
| 474 485 | 
             
                            import psutil
         | 
| 486 | 
            +
             | 
| 475 487 | 
             
                            process = psutil.Process()
         | 
| 476 488 | 
             
                            self._metrics.memory_usage_mb = process.memory_info().rss / 1024 / 1024
         | 
| 477 489 | 
             
                        except ImportError:
         | 
| @@ -484,72 +496,76 @@ class BaseService(LoggerMixin, ABC): | |
| 484 496 | 
             
                        self.logger.warning(f"Failed to collect metrics: {e}")
         | 
| 485 497 |  | 
| 486 498 | 
             
                # Enhanced features (conditionally included)
         | 
| 487 | 
            -
             | 
| 499 | 
            +
             | 
| 488 500 | 
             
                @asynccontextmanager
         | 
| 489 501 | 
             
                async def _service_operation(self, operation: str):
         | 
| 490 502 | 
             
                    """Context manager for tracking service operations (enhanced feature)."""
         | 
| 491 503 | 
             
                    if not self._enable_enhanced:
         | 
| 492 504 | 
             
                        yield
         | 
| 493 505 | 
             
                        return
         | 
| 494 | 
            -
             | 
| 506 | 
            +
             | 
| 495 507 | 
             
                    request_id = f"{self.name}_{operation}_{time.time()}"
         | 
| 496 508 | 
             
                    context = ServiceContext(
         | 
| 497 509 | 
             
                        request_id=request_id,
         | 
| 498 510 | 
             
                        start_time=time.time(),
         | 
| 499 511 | 
             
                        service_name=self.name,
         | 
| 500 | 
            -
                        operation=operation
         | 
| 512 | 
            +
                        operation=operation,
         | 
| 501 513 | 
             
                    )
         | 
| 502 | 
            -
             | 
| 514 | 
            +
             | 
| 503 515 | 
             
                    self._request_contexts[request_id] = context
         | 
| 504 | 
            -
             | 
| 516 | 
            +
             | 
| 505 517 | 
             
                    try:
         | 
| 506 518 | 
             
                        yield context
         | 
| 507 | 
            -
             | 
| 519 | 
            +
             | 
| 508 520 | 
             
                        # Record success metrics
         | 
| 509 521 | 
             
                        duration = time.time() - context.start_time
         | 
| 510 522 | 
             
                        self._record_operation_metrics(operation, duration, success=True)
         | 
| 511 | 
            -
             | 
| 523 | 
            +
             | 
| 512 524 | 
             
                    except Exception as e:
         | 
| 513 525 | 
             
                        # Record failure metrics
         | 
| 514 526 | 
             
                        duration = time.time() - context.start_time
         | 
| 515 527 | 
             
                        self._record_operation_metrics(operation, duration, success=False)
         | 
| 516 | 
            -
             | 
| 528 | 
            +
             | 
| 517 529 | 
             
                        # Update error counts
         | 
| 518 530 | 
             
                        error_type = type(e).__name__
         | 
| 519 531 | 
             
                        self._error_counts[error_type] = self._error_counts.get(error_type, 0) + 1
         | 
| 520 | 
            -
             | 
| 532 | 
            +
             | 
| 521 533 | 
             
                        raise
         | 
| 522 | 
            -
             | 
| 534 | 
            +
             | 
| 523 535 | 
             
                    finally:
         | 
| 524 536 | 
             
                        # Cleanup context
         | 
| 525 537 | 
             
                        self._request_contexts.pop(request_id, None)
         | 
| 526 538 |  | 
| 527 | 
            -
                def _record_operation_metrics( | 
| 539 | 
            +
                def _record_operation_metrics(
         | 
| 540 | 
            +
                    self, operation: str, duration: float, success: bool
         | 
| 541 | 
            +
                ) -> None:
         | 
| 528 542 | 
             
                    """Record operation performance metrics (enhanced feature)."""
         | 
| 529 543 | 
             
                    if not self._enable_enhanced:
         | 
| 530 544 | 
             
                        return
         | 
| 531 | 
            -
             | 
| 545 | 
            +
             | 
| 532 546 | 
             
                    with self._lock:
         | 
| 533 547 | 
             
                        # Update general metrics
         | 
| 534 548 | 
             
                        self._metrics.requests_total += 1
         | 
| 535 549 | 
             
                        if not success:
         | 
| 536 550 | 
             
                            self._metrics.requests_failed += 1
         | 
| 537 | 
            -
             | 
| 551 | 
            +
             | 
| 538 552 | 
             
                        # Update performance tracking
         | 
| 539 553 | 
             
                        if operation not in self._performance_metrics:
         | 
| 540 554 | 
             
                            self._performance_metrics[operation] = []
         | 
| 541 | 
            -
             | 
| 555 | 
            +
             | 
| 542 556 | 
             
                        self._performance_metrics[operation].append(duration)
         | 
| 543 | 
            -
             | 
| 557 | 
            +
             | 
| 544 558 | 
             
                        # Keep only recent metrics (last 100 operations)
         | 
| 545 559 | 
             
                        if len(self._performance_metrics[operation]) > 100:
         | 
| 546 | 
            -
                            self._performance_metrics[operation] = self._performance_metrics[ | 
| 547 | 
            -
             | 
| 560 | 
            +
                            self._performance_metrics[operation] = self._performance_metrics[
         | 
| 561 | 
            +
                                operation
         | 
| 562 | 
            +
                            ][-100:]
         | 
| 563 | 
            +
             | 
| 548 564 | 
             
                        # Calculate average
         | 
| 549 565 | 
             
                        all_times = []
         | 
| 550 566 | 
             
                        for times in self._performance_metrics.values():
         | 
| 551 567 | 
             
                            all_times.extend(times)
         | 
| 552 | 
            -
             | 
| 568 | 
            +
             | 
| 553 569 | 
             
                        if all_times:
         | 
| 554 570 | 
             
                            self._metrics.response_time_avg = sum(all_times) / len(all_times)
         | 
| 555 571 |  | 
| @@ -560,32 +576,34 @@ class BaseService(LoggerMixin, ABC): | |
| 560 576 | 
             
                        if self._circuit_breaker.state == "open":
         | 
| 561 577 | 
             
                            if self._should_attempt_circuit_recovery():
         | 
| 562 578 | 
             
                                self._circuit_breaker.state = "half_open"
         | 
| 563 | 
            -
                                self.logger.info( | 
| 579 | 
            +
                                self.logger.info(
         | 
| 580 | 
            +
                                    f"Circuit breaker for {self.name} moved to half-open"
         | 
| 581 | 
            +
                                )
         | 
| 564 582 | 
             
                            else:
         | 
| 565 583 | 
             
                                return ServiceHealth(
         | 
| 566 584 | 
             
                                    status="degraded",
         | 
| 567 585 | 
             
                                    message="Service circuit breaker is open",
         | 
| 568 586 | 
             
                                    timestamp=datetime.now().isoformat(),
         | 
| 569 587 | 
             
                                    checks={"circuit_breaker": False},
         | 
| 570 | 
            -
                                    metrics=self._get_health_metrics()
         | 
| 588 | 
            +
                                    metrics=self._get_health_metrics(),
         | 
| 571 589 | 
             
                                )
         | 
| 572 | 
            -
             | 
| 590 | 
            +
             | 
| 573 591 | 
             
                        # Perform standard health check
         | 
| 574 592 | 
             
                        health = await self.health_check()
         | 
| 575 | 
            -
             | 
| 593 | 
            +
             | 
| 576 594 | 
             
                        # Update circuit breaker
         | 
| 577 595 | 
             
                        if health.status in ["healthy", "degraded"]:
         | 
| 578 596 | 
             
                            self._record_circuit_success()
         | 
| 579 597 | 
             
                        else:
         | 
| 580 598 | 
             
                            self._record_circuit_failure()
         | 
| 581 | 
            -
             | 
| 599 | 
            +
             | 
| 582 600 | 
             
                        return health
         | 
| 583 601 |  | 
| 584 602 | 
             
                def _should_attempt_circuit_recovery(self) -> bool:
         | 
| 585 603 | 
             
                    """Check if circuit breaker should attempt recovery."""
         | 
| 586 604 | 
             
                    if not self._enable_enhanced or self._circuit_breaker.last_failure_time is None:
         | 
| 587 605 | 
             
                        return True
         | 
| 588 | 
            -
             | 
| 606 | 
            +
             | 
| 589 607 | 
             
                    time_since_failure = time.time() - self._circuit_breaker.last_failure_time
         | 
| 590 608 | 
             
                    return time_since_failure >= self._circuit_breaker.timeout_seconds
         | 
| 591 609 |  | 
| @@ -593,11 +611,14 @@ class BaseService(LoggerMixin, ABC): | |
| 593 611 | 
             
                    """Record circuit breaker failure."""
         | 
| 594 612 | 
             
                    if not self._enable_enhanced:
         | 
| 595 613 | 
             
                        return
         | 
| 596 | 
            -
             | 
| 614 | 
            +
             | 
| 597 615 | 
             
                    self._circuit_breaker.failure_count += 1
         | 
| 598 616 | 
             
                    self._circuit_breaker.last_failure_time = time.time()
         | 
| 599 | 
            -
             | 
| 600 | 
            -
                    if  | 
| 617 | 
            +
             | 
| 618 | 
            +
                    if (
         | 
| 619 | 
            +
                        self._circuit_breaker.failure_count
         | 
| 620 | 
            +
                        >= self._circuit_breaker.failure_threshold
         | 
| 621 | 
            +
                    ):
         | 
| 601 622 | 
             
                        if self._circuit_breaker.state != "open":
         | 
| 602 623 | 
             
                            self._circuit_breaker.state = "open"
         | 
| 603 624 | 
             
                            self.logger.warning(f"Circuit breaker opened for service {self.name}")
         | 
| @@ -606,14 +627,18 @@ class BaseService(LoggerMixin, ABC): | |
| 606 627 | 
             
                    """Record circuit breaker success."""
         | 
| 607 628 | 
             
                    if not self._enable_enhanced:
         | 
| 608 629 | 
             
                        return
         | 
| 609 | 
            -
             | 
| 630 | 
            +
             | 
| 610 631 | 
             
                    if self._circuit_breaker.state == "half_open":
         | 
| 611 | 
            -
                        self._circuit_breaker.failure_count = max( | 
| 632 | 
            +
                        self._circuit_breaker.failure_count = max(
         | 
| 633 | 
            +
                            0, self._circuit_breaker.failure_count - 1
         | 
| 634 | 
            +
                        )
         | 
| 612 635 | 
             
                        if self._circuit_breaker.failure_count == 0:
         | 
| 613 636 | 
             
                            self._circuit_breaker.state = "closed"
         | 
| 614 637 | 
             
                            self.logger.info(f"Circuit breaker closed for service {self.name}")
         | 
| 615 638 | 
             
                    elif self._circuit_breaker.state == "closed":
         | 
| 616 | 
            -
                        self._circuit_breaker.failure_count = max( | 
| 639 | 
            +
                        self._circuit_breaker.failure_count = max(
         | 
| 640 | 
            +
                            0, self._circuit_breaker.failure_count - 1
         | 
| 641 | 
            +
                        )
         | 
| 617 642 |  | 
| 618 643 | 
             
                def _get_health_metrics(self) -> Dict[str, Any]:
         | 
| 619 644 | 
             
                    """Get metrics for health status."""
         | 
| @@ -623,22 +648,24 @@ class BaseService(LoggerMixin, ABC): | |
| 623 648 | 
             
                        "requests_failed": self._metrics.requests_failed,
         | 
| 624 649 | 
             
                        "response_time_avg": self._metrics.response_time_avg,
         | 
| 625 650 | 
             
                    }
         | 
| 626 | 
            -
             | 
| 651 | 
            +
             | 
| 627 652 | 
             
                    if self._enable_enhanced:
         | 
| 628 | 
            -
                        base_metrics.update( | 
| 629 | 
            -
                             | 
| 630 | 
            -
             | 
| 631 | 
            -
             | 
| 632 | 
            -
             | 
| 653 | 
            +
                        base_metrics.update(
         | 
| 654 | 
            +
                            {
         | 
| 655 | 
            +
                                "circuit_breaker_state": self._circuit_breaker.state,
         | 
| 656 | 
            +
                                "error_counts": self._error_counts.copy(),
         | 
| 657 | 
            +
                            }
         | 
| 658 | 
            +
                        )
         | 
| 659 | 
            +
             | 
| 633 660 | 
             
                    return base_metrics
         | 
| 634 661 |  | 
| 635 662 | 
             
                async def _handle_error(self, error: Exception, context: Dict[str, Any]) -> None:
         | 
| 636 663 | 
             
                    """Handle service errors with context (enhanced feature)."""
         | 
| 637 664 | 
             
                    if not self._enable_enhanced:
         | 
| 638 665 | 
             
                        return
         | 
| 639 | 
            -
             | 
| 666 | 
            +
             | 
| 640 667 | 
             
                    try:
         | 
| 641 | 
            -
                        if hasattr(self,  | 
| 668 | 
            +
                        if hasattr(self, "_error_handler") and self._error_handler:
         | 
| 642 669 | 
             
                            await self._error_handler.handle_error(error, context)
         | 
| 643 670 | 
             
                        else:
         | 
| 644 671 | 
             
                            # Default error handling
         | 
| @@ -647,8 +674,8 @@ class BaseService(LoggerMixin, ABC): | |
| 647 674 | 
             
                                extra={
         | 
| 648 675 | 
             
                                    "service": self.name,
         | 
| 649 676 | 
             
                                    "context": context,
         | 
| 650 | 
            -
                                    "traceback": traceback.format_exc()
         | 
| 651 | 
            -
                                }
         | 
| 677 | 
            +
                                    "traceback": traceback.format_exc(),
         | 
| 678 | 
            +
                                },
         | 
| 652 679 | 
             
                            )
         | 
| 653 680 | 
             
                    except Exception as handler_error:
         | 
| 654 681 | 
             
                        self.logger.error(f"Error handler failed: {handler_error}")
         | 
| @@ -657,14 +684,16 @@ class BaseService(LoggerMixin, ABC): | |
| 657 684 | 
             
                    """Register service dependencies (enhanced feature)."""
         | 
| 658 685 | 
             
                    if not self._container:
         | 
| 659 686 | 
             
                        return
         | 
| 660 | 
            -
             | 
| 687 | 
            +
             | 
| 661 688 | 
             
                    try:
         | 
| 662 689 | 
             
                        # Get optional dependencies from container
         | 
| 663 690 | 
             
                        # This is a simplified version - real implementation would use interfaces
         | 
| 664 | 
            -
                        if hasattr(self._container,  | 
| 665 | 
            -
                            self._health_monitor = self._container.get_service( | 
| 666 | 
            -
             | 
| 667 | 
            -
                             | 
| 691 | 
            +
                        if hasattr(self._container, "get_service"):
         | 
| 692 | 
            +
                            self._health_monitor = self._container.get_service(
         | 
| 693 | 
            +
                                "IHealthMonitor", None
         | 
| 694 | 
            +
                            )
         | 
| 695 | 
            +
                            self._error_handler = self._container.get_service("IErrorHandler", None)
         | 
| 696 | 
            +
                            self._cache = self._container.get_service("ICacheService", None)
         | 
| 668 697 | 
             
                    except Exception as e:
         | 
| 669 698 | 
             
                        self.logger.warning(f"Failed to register dependencies for {self.name}: {e}")
         | 
| 670 699 |  | 
| @@ -721,29 +750,29 @@ class BaseService(LoggerMixin, ABC): | |
| 721 750 |  | 
| 722 751 | 
             
                async def _collect_custom_metrics(self) -> None:
         | 
| 723 752 | 
             
                    """Collect custom metrics. Override in subclasses.
         | 
| 724 | 
            -
             | 
| 753 | 
            +
             | 
| 725 754 | 
             
                    METRICS COLLECTION PATTERN:
         | 
| 726 755 | 
             
                    This method is called periodically by the metrics task to collect
         | 
| 727 756 | 
             
                    service-specific metrics. Subclasses should override this to:
         | 
| 728 | 
            -
             | 
| 757 | 
            +
             | 
| 729 758 | 
             
                    1. COLLECT OPERATIONAL METRICS:
         | 
| 730 759 | 
             
                       - Request rates and latencies
         | 
| 731 760 | 
             
                       - Queue depths and processing times
         | 
| 732 761 | 
             
                       - Error rates by type
         | 
| 733 762 | 
             
                       - Resource utilization
         | 
| 734 | 
            -
             | 
| 763 | 
            +
             | 
| 735 764 | 
             
                    2. COLLECT BUSINESS METRICS:
         | 
| 736 765 | 
             
                       - Agent usage patterns
         | 
| 737 766 | 
             
                       - Model selection distribution
         | 
| 738 767 | 
             
                       - Task complexity trends
         | 
| 739 768 | 
             
                       - Cost tracking metrics
         | 
| 740 | 
            -
             | 
| 769 | 
            +
             | 
| 741 770 | 
             
                    3. COLLECT PERFORMANCE METRICS:
         | 
| 742 771 | 
             
                       - Cache hit rates
         | 
| 743 772 | 
             
                       - Database query times
         | 
| 744 773 | 
             
                       - API call latencies
         | 
| 745 774 | 
             
                       - Memory usage patterns
         | 
| 746 | 
            -
             | 
| 775 | 
            +
             | 
| 747 776 | 
             
                    EXAMPLE IMPLEMENTATION:
         | 
| 748 777 | 
             
                    ```python
         | 
| 749 778 | 
             
                    async def _collect_custom_metrics(self) -> None:
         | 
| @@ -754,7 +783,7 @@ class BaseService(LoggerMixin, ABC): | |
| 754 783 | 
             
                                cache_hit_rate=loader_metrics['cache_hit_rate_percent'],
         | 
| 755 784 | 
             
                                top_agents=loader_metrics['top_agents_by_usage']
         | 
| 756 785 | 
             
                            )
         | 
| 757 | 
            -
             | 
| 786 | 
            +
             | 
| 758 787 | 
             
                        # Collect deployment metrics
         | 
| 759 788 | 
             
                        if hasattr(self, 'deployment_service'):
         | 
| 760 789 | 
             
                            deploy_metrics = self.deployment_service.get_deployment_metrics()
         | 
| @@ -762,7 +791,7 @@ class BaseService(LoggerMixin, ABC): | |
| 762 791 | 
             
                                deployment_success_rate=deploy_metrics['success_rate_percent'],
         | 
| 763 792 | 
             
                                avg_deployment_time=deploy_metrics['average_deployment_time_ms']
         | 
| 764 793 | 
             
                            )
         | 
| 765 | 
            -
             | 
| 794 | 
            +
             | 
| 766 795 | 
             
                        # Collect resource metrics
         | 
| 767 796 | 
             
                        import psutil
         | 
| 768 797 | 
             
                        process = psutil.Process()
         | 
| @@ -773,7 +802,7 @@ class BaseService(LoggerMixin, ABC): | |
| 773 802 | 
             
                            thread_count=process.num_threads()
         | 
| 774 803 | 
             
                        )
         | 
| 775 804 | 
             
                    ```
         | 
| 776 | 
            -
             | 
| 805 | 
            +
             | 
| 777 806 | 
             
                    BEST PRACTICES:
         | 
| 778 807 | 
             
                    - Keep collection fast (< 100ms)
         | 
| 779 808 | 
             
                    - Handle errors gracefully
         | 
| @@ -804,4 +833,4 @@ class BaseService(LoggerMixin, ABC): | |
| 804 833 |  | 
| 805 834 |  | 
| 806 835 | 
             
            # For backwards compatibility, create an alias
         | 
| 807 | 
            -
            EnhancedBaseService = BaseService
         | 
| 836 | 
            +
            EnhancedBaseService = BaseService
         |