claude-mpm 4.1.2__py3-none-any.whl → 4.1.3__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.
Files changed (53) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/templates/engineer.json +33 -11
  3. claude_mpm/cli/commands/agents.py +556 -1009
  4. claude_mpm/cli/commands/memory.py +248 -927
  5. claude_mpm/cli/commands/run.py +139 -484
  6. claude_mpm/cli/startup_logging.py +76 -0
  7. claude_mpm/core/agent_registry.py +6 -10
  8. claude_mpm/core/framework_loader.py +114 -595
  9. claude_mpm/core/logging_config.py +2 -4
  10. claude_mpm/hooks/claude_hooks/event_handlers.py +7 -117
  11. claude_mpm/hooks/claude_hooks/hook_handler.py +91 -755
  12. claude_mpm/hooks/claude_hooks/hook_handler_original.py +1040 -0
  13. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +347 -0
  14. claude_mpm/hooks/claude_hooks/services/__init__.py +13 -0
  15. claude_mpm/hooks/claude_hooks/services/connection_manager.py +190 -0
  16. claude_mpm/hooks/claude_hooks/services/duplicate_detector.py +106 -0
  17. claude_mpm/hooks/claude_hooks/services/state_manager.py +282 -0
  18. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +374 -0
  19. claude_mpm/services/agents/deployment/agent_deployment.py +42 -454
  20. claude_mpm/services/agents/deployment/base_agent_locator.py +132 -0
  21. claude_mpm/services/agents/deployment/deployment_results_manager.py +185 -0
  22. claude_mpm/services/agents/deployment/single_agent_deployer.py +315 -0
  23. claude_mpm/services/agents/memory/agent_memory_manager.py +42 -508
  24. claude_mpm/services/agents/memory/memory_categorization_service.py +165 -0
  25. claude_mpm/services/agents/memory/memory_file_service.py +103 -0
  26. claude_mpm/services/agents/memory/memory_format_service.py +201 -0
  27. claude_mpm/services/agents/memory/memory_limits_service.py +99 -0
  28. claude_mpm/services/agents/registry/__init__.py +1 -1
  29. claude_mpm/services/cli/__init__.py +18 -0
  30. claude_mpm/services/cli/agent_cleanup_service.py +407 -0
  31. claude_mpm/services/cli/agent_dependency_service.py +395 -0
  32. claude_mpm/services/cli/agent_listing_service.py +463 -0
  33. claude_mpm/services/cli/agent_output_formatter.py +605 -0
  34. claude_mpm/services/cli/agent_validation_service.py +589 -0
  35. claude_mpm/services/cli/dashboard_launcher.py +424 -0
  36. claude_mpm/services/cli/memory_crud_service.py +617 -0
  37. claude_mpm/services/cli/memory_output_formatter.py +604 -0
  38. claude_mpm/services/cli/session_manager.py +513 -0
  39. claude_mpm/services/cli/socketio_manager.py +498 -0
  40. claude_mpm/services/cli/startup_checker.py +370 -0
  41. claude_mpm/services/core/cache_manager.py +311 -0
  42. claude_mpm/services/core/memory_manager.py +637 -0
  43. claude_mpm/services/core/path_resolver.py +498 -0
  44. claude_mpm/services/core/service_container.py +520 -0
  45. claude_mpm/services/core/service_interfaces.py +436 -0
  46. claude_mpm/services/diagnostics/checks/agent_check.py +65 -19
  47. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/METADATA +1 -1
  48. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/RECORD +52 -22
  49. claude_mpm/cli/commands/run_config_checker.py +0 -159
  50. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/WHEEL +0 -0
  51. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/entry_points.txt +0 -0
  52. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/licenses/LICENSE +0 -0
  53. {claude_mpm-4.1.2.dist-info → claude_mpm-4.1.3.dist-info}/top_level.txt +0 -0
@@ -27,13 +27,11 @@ from typing import Any, Dict, Optional, Union
27
27
  from claude_mpm.core.logger import (
28
28
  JsonFormatter,
29
29
  finalize_streaming_logs,
30
- )
31
- from claude_mpm.core.logger import get_logger as _get_logger
32
- from claude_mpm.core.logger import (
30
+ get_logger as _get_logger,
33
31
  log_async_performance,
34
32
  log_performance,
33
+ setup_logging as _setup_logging,
35
34
  )
36
- from claude_mpm.core.logger import setup_logging as _setup_logging
37
35
 
38
36
  # Standard log format for consistency
39
37
  STANDARD_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
@@ -5,7 +5,6 @@ This module provides individual event handlers for different types of
5
5
  Claude Code hook events.
6
6
  """
7
7
 
8
- import json
9
8
  import os
10
9
  import re
11
10
  import subprocess
@@ -544,122 +543,13 @@ class EventHandlers:
544
543
  self.hook_handler._emit_socketio_event("", "stop", stop_data)
545
544
 
546
545
  def handle_subagent_stop_fast(self, event):
547
- """Handle subagent stop events with improved agent type detection."""
548
- # Enhanced debug logging for session correlation
549
- session_id = event.get("session_id", "")
550
- if DEBUG:
551
- print(
552
- f" - session_id: {session_id[:16] if session_id else 'None'}...",
553
- file=sys.stderr,
554
- )
555
- print(f" - event keys: {list(event.keys())}", file=sys.stderr)
556
- print(
557
- f" - delegation_requests size: {len(self.hook_handler.delegation_requests)}",
558
- file=sys.stderr,
559
- )
560
-
561
- # First try to get agent type from our tracking
562
- agent_type = (
563
- self.hook_handler._get_delegation_agent_type(session_id)
564
- if session_id
565
- else "unknown"
566
- )
567
-
568
- # Fall back to event data if tracking didn't have it
569
- if agent_type == "unknown":
570
- agent_type = event.get("agent_type", event.get("subagent_type", "unknown"))
571
-
572
- agent_id = event.get("agent_id", event.get("subagent_id", ""))
573
- reason = event.get("reason", event.get("stop_reason", "unknown"))
574
-
575
- # Try to infer agent type from other fields if still unknown
576
- if agent_type == "unknown" and "task" in event:
577
- task_desc = str(event.get("task", "")).lower()
578
- if "research" in task_desc:
579
- agent_type = "research"
580
- elif "engineer" in task_desc or "code" in task_desc:
581
- agent_type = "engineer"
582
- elif "pm" in task_desc or "project" in task_desc:
583
- agent_type = "pm"
584
-
585
- # Always log SubagentStop events for debugging
586
- if DEBUG or agent_type != "unknown":
587
- print(
588
- f"Hook handler: Processing SubagentStop - agent: '{agent_type}', session: '{session_id}', reason: '{reason}'",
589
- file=sys.stderr,
590
- )
591
-
592
- # Get working directory and git branch
593
- working_dir = event.get("cwd", "")
594
- git_branch = self._get_git_branch(working_dir) if working_dir else "Unknown"
595
-
596
- # Try to extract structured response from output if available
597
- output = event.get("output", "")
598
- structured_response = None
599
- if output:
600
- try:
601
- json_match = re.search(
602
- r"```json\s*(\{.*?\})\s*```", str(output), re.DOTALL
603
- )
604
- if json_match:
605
- structured_response = json.loads(json_match.group(1))
606
- if DEBUG:
607
- print(
608
- f"Extracted structured response from {agent_type} agent in SubagentStop",
609
- file=sys.stderr,
610
- )
611
- except (json.JSONDecodeError, AttributeError):
612
- pass # No structured response, that's okay
613
-
614
- # Handle response tracking with fuzzy matching
615
- self._handle_subagent_response_tracking(
616
- session_id,
617
- agent_type,
618
- reason,
619
- output,
620
- structured_response,
621
- working_dir,
622
- git_branch,
623
- )
624
-
625
- # Prepare subagent stop data
626
- subagent_stop_data = {
627
- "agent_type": agent_type,
628
- "agent_id": agent_id,
629
- "reason": reason,
630
- "session_id": session_id,
631
- "working_directory": working_dir,
632
- "git_branch": git_branch,
633
- "timestamp": datetime.now().isoformat(),
634
- "is_successful_completion": reason in ["completed", "finished", "done"],
635
- "is_error_termination": reason in ["error", "timeout", "failed", "blocked"],
636
- "is_delegation_related": agent_type
637
- in ["research", "engineer", "pm", "ops", "qa", "documentation", "security"],
638
- "has_results": bool(event.get("results") or event.get("output")),
639
- "duration_context": event.get("duration_ms"),
640
- "hook_event_name": "SubagentStop", # Explicitly set for dashboard
641
- }
642
-
643
- # Add structured response data if available
644
- if structured_response:
645
- subagent_stop_data["structured_response"] = {
646
- "task_completed": structured_response.get("task_completed", False),
647
- "instructions": structured_response.get("instructions", ""),
648
- "results": structured_response.get("results", ""),
649
- "files_modified": structured_response.get("files_modified", []),
650
- "tools_used": structured_response.get("tools_used", []),
651
- "remember": structured_response.get("remember"),
652
- }
653
-
654
- # Debug log the processed data
655
- if DEBUG:
656
- print(
657
- f"SubagentStop processed data: agent_type='{agent_type}', session_id='{session_id}'",
658
- file=sys.stderr,
659
- )
660
-
661
- # Emit normalized event with high priority
662
- self.hook_handler._emit_socketio_event("", "subagent_stop", subagent_stop_data)
546
+ """Handle subagent stop events by delegating to the specialized processor."""
547
+ # Delegate to the specialized subagent processor
548
+ if hasattr(self.hook_handler, "subagent_processor"):
549
+ self.hook_handler.subagent_processor.process_subagent_stop(event)
550
+ else:
551
+ # Fallback to handle_subagent_stop if processor not available
552
+ self.hook_handler.handle_subagent_stop(event)
663
553
 
664
554
  def _handle_subagent_response_tracking(
665
555
  self,