claude-mpm 3.4.27__py3-none-any.whl → 3.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/INSTRUCTIONS.md +182 -299
  3. claude_mpm/agents/agent_loader.py +283 -57
  4. claude_mpm/agents/agent_loader_integration.py +6 -9
  5. claude_mpm/agents/base_agent.json +2 -1
  6. claude_mpm/agents/base_agent_loader.py +1 -1
  7. claude_mpm/cli/__init__.py +5 -7
  8. claude_mpm/cli/commands/__init__.py +0 -2
  9. claude_mpm/cli/commands/agents.py +1 -1
  10. claude_mpm/cli/commands/memory.py +1 -1
  11. claude_mpm/cli/commands/run.py +12 -0
  12. claude_mpm/cli/parser.py +0 -13
  13. claude_mpm/cli/utils.py +1 -1
  14. claude_mpm/config/__init__.py +44 -2
  15. claude_mpm/config/agent_config.py +348 -0
  16. claude_mpm/config/paths.py +322 -0
  17. claude_mpm/constants.py +0 -1
  18. claude_mpm/core/__init__.py +2 -5
  19. claude_mpm/core/agent_registry.py +63 -17
  20. claude_mpm/core/claude_runner.py +354 -43
  21. claude_mpm/core/config.py +7 -1
  22. claude_mpm/core/config_aliases.py +4 -3
  23. claude_mpm/core/config_paths.py +151 -0
  24. claude_mpm/core/factories.py +4 -50
  25. claude_mpm/core/logger.py +11 -13
  26. claude_mpm/core/service_registry.py +2 -2
  27. claude_mpm/dashboard/static/js/components/agent-inference.js +101 -25
  28. claude_mpm/dashboard/static/js/components/event-processor.js +3 -2
  29. claude_mpm/hooks/claude_hooks/hook_handler.py +343 -83
  30. claude_mpm/hooks/memory_integration_hook.py +1 -1
  31. claude_mpm/init.py +37 -6
  32. claude_mpm/scripts/socketio_daemon.py +6 -2
  33. claude_mpm/services/__init__.py +71 -3
  34. claude_mpm/services/agents/__init__.py +85 -0
  35. claude_mpm/services/agents/deployment/__init__.py +21 -0
  36. claude_mpm/services/{agent_deployment.py → agents/deployment/agent_deployment.py} +192 -41
  37. claude_mpm/services/{agent_lifecycle_manager.py → agents/deployment/agent_lifecycle_manager.py} +11 -10
  38. claude_mpm/services/agents/loading/__init__.py +11 -0
  39. claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +9 -8
  40. claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +2 -2
  41. claude_mpm/services/{framework_agent_loader.py → agents/loading/framework_agent_loader.py} +116 -40
  42. claude_mpm/services/agents/management/__init__.py +9 -0
  43. claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +6 -5
  44. claude_mpm/services/agents/memory/__init__.py +21 -0
  45. claude_mpm/services/{agent_memory_manager.py → agents/memory/agent_memory_manager.py} +3 -3
  46. claude_mpm/services/agents/registry/__init__.py +29 -0
  47. claude_mpm/services/{agent_registry.py → agents/registry/agent_registry.py} +101 -16
  48. claude_mpm/services/{deployed_agent_discovery.py → agents/registry/deployed_agent_discovery.py} +12 -2
  49. claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +6 -5
  50. claude_mpm/services/async_session_logger.py +584 -0
  51. claude_mpm/services/claude_session_logger.py +299 -0
  52. claude_mpm/services/framework_claude_md_generator/content_assembler.py +2 -2
  53. claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +17 -17
  54. claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +3 -3
  55. claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +1 -1
  56. claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +1 -1
  57. claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +19 -24
  58. claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +1 -1
  59. claude_mpm/services/framework_claude_md_generator.py +4 -2
  60. claude_mpm/services/memory/__init__.py +17 -0
  61. claude_mpm/services/{memory_builder.py → memory/builder.py} +3 -3
  62. claude_mpm/services/memory/cache/__init__.py +14 -0
  63. claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +1 -1
  64. claude_mpm/services/memory/cache/simple_cache.py +317 -0
  65. claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +1 -1
  66. claude_mpm/services/{memory_router.py → memory/router.py} +1 -1
  67. claude_mpm/services/optimized_hook_service.py +542 -0
  68. claude_mpm/services/project_registry.py +14 -8
  69. claude_mpm/services/response_tracker.py +237 -0
  70. claude_mpm/services/ticketing_service_original.py +4 -2
  71. claude_mpm/services/version_control/branch_strategy.py +3 -1
  72. claude_mpm/utils/paths.py +12 -10
  73. claude_mpm/utils/session_logging.py +114 -0
  74. claude_mpm/validation/agent_validator.py +2 -1
  75. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/METADATA +28 -20
  76. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/RECORD +83 -106
  77. claude_mpm/cli/commands/ui.py +0 -57
  78. claude_mpm/core/simple_runner.py +0 -1046
  79. claude_mpm/hooks/builtin/__init__.py +0 -1
  80. claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
  81. claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
  82. claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
  83. claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
  84. claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
  85. claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
  86. claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
  87. claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
  88. claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
  89. claude_mpm/orchestration/__init__.py +0 -6
  90. claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
  91. claude_mpm/orchestration/archive/factory.py +0 -215
  92. claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
  93. claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
  94. claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
  95. claude_mpm/orchestration/archive/orchestrator.py +0 -501
  96. claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
  97. claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
  98. claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
  99. claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
  100. claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
  101. claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
  102. claude_mpm/schemas/workflow_validator.py +0 -411
  103. claude_mpm/services/parent_directory_manager/__init__.py +0 -577
  104. claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
  105. claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
  106. claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
  107. claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
  108. claude_mpm/services/parent_directory_manager/operations.py +0 -186
  109. claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
  110. claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
  111. claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
  112. claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
  113. claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
  114. claude_mpm/ui/__init__.py +0 -1
  115. claude_mpm/ui/rich_terminal_ui.py +0 -295
  116. claude_mpm/ui/terminal_ui.py +0 -328
  117. /claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +0 -0
  118. /claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +0 -0
  119. /claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +0 -0
  120. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/WHEEL +0 -0
  121. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/entry_points.txt +0 -0
  122. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/licenses/LICENSE +0 -0
  123. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/top_level.txt +0 -0
@@ -1,188 +0,0 @@
1
- """Example orchestrator that integrates with the hook service."""
2
-
3
- import asyncio
4
- import logging
5
- from typing import Any, Dict, List, Optional
6
-
7
- from src.hooks.hook_client import get_hook_client, HookServiceClient
8
- from src.hooks.base_hook import HookType
9
- from src.orchestration.orchestrator import Orchestrator
10
- from src.services.ticket_manager import TicketManager
11
- from src.utils.logger import get_logger
12
-
13
- logger = get_logger(__name__)
14
-
15
-
16
- class HookEnabledOrchestrator(Orchestrator):
17
- """Orchestrator that integrates with the centralized hook service."""
18
-
19
- def __init__(self, *args, **kwargs):
20
- """Initialize hook-enabled orchestrator."""
21
- super().__init__(*args, **kwargs)
22
-
23
- # Initialize hook client
24
- self.hook_client = get_hook_client()
25
-
26
- # Check hook service health
27
- health = self.hook_client.health_check()
28
- if health.get('status') == 'healthy':
29
- logger.info(f"Hook service is healthy with {health.get('hooks_count', 0)} hooks")
30
- else:
31
- logger.warning(f"Hook service is not available: {health.get('error')}")
32
-
33
- async def process_prompt(self, prompt: str) -> str:
34
- """Process user prompt with hook integration.
35
-
36
- Args:
37
- prompt: User prompt to process
38
-
39
- Returns:
40
- Response from orchestration
41
- """
42
- try:
43
- # Execute submit hooks
44
- logger.debug("Executing submit hooks...")
45
- submit_results = self.hook_client.execute_submit_hook(
46
- prompt=prompt,
47
- session_id=getattr(self, 'session_id', None)
48
- )
49
-
50
- # Get modified prompt data
51
- modified_data = self.hook_client.get_modified_data(submit_results)
52
- if modified_data.get('prompt'):
53
- prompt = modified_data['prompt']
54
-
55
- # Check for priority override
56
- if modified_data.get('priority'):
57
- logger.info(f"Priority detected: {modified_data['priority']}")
58
-
59
- # Process prompt through normal orchestration
60
- response = await super().process_prompt(prompt)
61
-
62
- # Execute ticket extraction hooks on the conversation
63
- logger.debug("Executing ticket extraction hooks...")
64
- extraction_results = self.hook_client.execute_ticket_extraction_hook(
65
- content={
66
- 'prompt': prompt,
67
- 'response': response
68
- }
69
- )
70
-
71
- # Extract and create tickets
72
- tickets = self.hook_client.get_extracted_tickets(extraction_results)
73
- if tickets:
74
- logger.info(f"Extracted {len(tickets)} tickets from conversation")
75
- await self._create_tickets(tickets)
76
-
77
- return response
78
-
79
- except Exception as e:
80
- logger.error(f"Error in hook-enabled orchestration: {e}")
81
- # Fallback to normal orchestration if hooks fail
82
- return await super().process_prompt(prompt)
83
-
84
- async def delegate_to_agent(self, agent_name: str, context: Dict[str, Any]) -> Any:
85
- """Delegate to agent with hook integration.
86
-
87
- Args:
88
- agent_name: Name of agent to delegate to
89
- context: Context to pass to agent
90
-
91
- Returns:
92
- Result from agent
93
- """
94
- try:
95
- # Execute pre-delegation hooks
96
- logger.debug(f"Executing pre-delegation hooks for {agent_name}...")
97
- pre_results = self.hook_client.execute_pre_delegation_hook(
98
- agent=agent_name,
99
- context=context
100
- )
101
-
102
- # Get modified context
103
- modified_data = self.hook_client.get_modified_data(pre_results)
104
- if 'context' in modified_data:
105
- context = modified_data['context']
106
- logger.debug("Context modified by pre-delegation hooks")
107
-
108
- # Delegate to agent
109
- result = await super().delegate_to_agent(agent_name, context)
110
-
111
- # Execute post-delegation hooks
112
- logger.debug(f"Executing post-delegation hooks for {agent_name}...")
113
- post_results = self.hook_client.execute_post_delegation_hook(
114
- agent=agent_name,
115
- result=result,
116
- execution_time_ms=context.get('execution_time_ms')
117
- )
118
-
119
- # Get modified result
120
- modified_data = self.hook_client.get_modified_data(post_results)
121
- if 'result' in modified_data:
122
- result = modified_data['result']
123
- logger.debug("Result modified by post-delegation hooks")
124
-
125
- # Check for validation issues
126
- for post_result in post_results:
127
- if 'validation_issues' in post_result.get('data', {}):
128
- issues = post_result['data']['validation_issues']
129
- logger.warning(f"Validation issues: {issues}")
130
-
131
- return result
132
-
133
- except Exception as e:
134
- logger.error(f"Error in hook-enabled delegation: {e}")
135
- # Fallback to normal delegation if hooks fail
136
- return await super().delegate_to_agent(agent_name, context)
137
-
138
- async def _create_tickets(self, tickets: List[Dict[str, Any]]):
139
- """Create tickets in the ticket system.
140
-
141
- Args:
142
- tickets: List of ticket dictionaries
143
- """
144
- try:
145
- # Initialize ticket manager if needed
146
- if not hasattr(self, 'ticket_manager'):
147
- self.ticket_manager = TicketManager()
148
-
149
- for ticket in tickets:
150
- try:
151
- # Create ticket
152
- ticket_id = await self.ticket_manager.create_ticket(
153
- title=ticket.get('title', 'Untitled'),
154
- description=ticket.get('description', ''),
155
- priority=ticket.get('priority', 'normal'),
156
- ticket_type=ticket.get('type', 'task'),
157
- metadata=ticket.get('metadata', {})
158
- )
159
- logger.info(f"Created ticket {ticket_id}: {ticket['title']}")
160
- except Exception as e:
161
- logger.error(f"Failed to create ticket: {e}")
162
-
163
- except Exception as e:
164
- logger.error(f"Error creating tickets: {e}")
165
-
166
-
167
- # Example usage
168
- async def main():
169
- """Example usage of hook-enabled orchestrator."""
170
- # Create orchestrator
171
- orchestrator = HookEnabledOrchestrator()
172
-
173
- # Process some prompts
174
- prompts = [
175
- "URGENT: Fix the bug in the login system",
176
- "TODO: Add unit tests for the new API endpoints",
177
- "Can you create ticket: Implement user dashboard feature",
178
- "Research the best practices for React performance optimization"
179
- ]
180
-
181
- for prompt in prompts:
182
- print(f"\nProcessing: {prompt}")
183
- response = await orchestrator.process_prompt(prompt)
184
- print(f"Response: {response[:100]}...")
185
-
186
-
187
- if __name__ == "__main__":
188
- asyncio.run(main())
@@ -1,178 +0,0 @@
1
- """Example of how to integrate hooks into orchestrator methods."""
2
-
3
- from typing import Optional
4
- from ..hooks.hook_client import HookServiceClient
5
-
6
-
7
- class HookIntegrationExample:
8
- """Example methods showing how to integrate hooks into orchestrators."""
9
-
10
- def __init__(self, hook_client: Optional[HookServiceClient] = None):
11
- """Initialize with optional hook client."""
12
- self.hook_client = hook_client
13
-
14
- def process_user_input_with_hooks(self, user_input: str) -> str:
15
- """Process user input through submit hooks before sending to Claude.
16
-
17
- This method shows how to:
18
- 1. Send user input to hook service
19
- 2. Get modified input back
20
- 3. Use the modified input for Claude
21
- """
22
- if not self.hook_client:
23
- # No hooks available, return original input
24
- return user_input
25
-
26
- try:
27
- # Execute submit hooks
28
- results = self.hook_client.execute_submit_hook(
29
- prompt=user_input,
30
- session_id="current_session"
31
- )
32
-
33
- # Get modified data from hooks
34
- modified_data = self.hook_client.get_modified_data(results)
35
-
36
- # Use modified prompt if available
37
- if modified_data.get('prompt'):
38
- return modified_data['prompt']
39
-
40
- # Check for priority changes
41
- if modified_data.get('priority'):
42
- # Could adjust Claude model or other settings based on priority
43
- print(f"Priority set by hooks: {modified_data['priority']}")
44
-
45
- return user_input
46
-
47
- except Exception as e:
48
- print(f"Hook processing failed: {e}")
49
- # Fallback to original input
50
- return user_input
51
-
52
- def process_agent_delegation_with_hooks(self, agent_name: str, task: str) -> tuple[str, str]:
53
- """Process agent delegation through pre-delegation hooks.
54
-
55
- Returns:
56
- Tuple of (agent_name, task) potentially modified by hooks
57
- """
58
- if not self.hook_client:
59
- return agent_name, task
60
-
61
- try:
62
- # Execute pre-delegation hooks
63
- context = {
64
- 'agent': agent_name,
65
- 'task': task
66
- }
67
-
68
- results = self.hook_client.execute_pre_delegation_hook(
69
- agent=agent_name,
70
- context=context
71
- )
72
-
73
- # Get modified data
74
- modified_data = self.hook_client.get_modified_data(results)
75
-
76
- # Update agent or task if modified
77
- new_agent = modified_data.get('agent', agent_name)
78
- new_context = modified_data.get('context', {})
79
- new_task = new_context.get('task', task)
80
-
81
- return new_agent, new_task
82
-
83
- except Exception as e:
84
- print(f"Pre-delegation hook failed: {e}")
85
- return agent_name, task
86
-
87
- def process_agent_response_with_hooks(self, agent_name: str, response: str) -> str:
88
- """Process agent response through post-delegation hooks.
89
-
90
- Returns:
91
- Potentially modified response
92
- """
93
- if not self.hook_client:
94
- return response
95
-
96
- try:
97
- # Execute post-delegation hooks
98
- result = {
99
- 'response': response,
100
- 'success': True
101
- }
102
-
103
- results = self.hook_client.execute_post_delegation_hook(
104
- agent=agent_name,
105
- result=result
106
- )
107
-
108
- # Get modified data
109
- modified_data = self.hook_client.get_modified_data(results)
110
-
111
- # Use modified response if available
112
- if modified_data.get('result', {}).get('response'):
113
- return modified_data['result']['response']
114
-
115
- return response
116
-
117
- except Exception as e:
118
- print(f"Post-delegation hook failed: {e}")
119
- return response
120
-
121
- def extract_tickets_with_hooks(self, conversation: str) -> list:
122
- """Extract tickets from conversation using ticket extraction hooks.
123
-
124
- Returns:
125
- List of extracted tickets
126
- """
127
- if not self.hook_client:
128
- return []
129
-
130
- try:
131
- # Execute ticket extraction hooks
132
- results = self.hook_client.execute_ticket_extraction_hook(
133
- content={'conversation': conversation}
134
- )
135
-
136
- # Get extracted tickets
137
- tickets = self.hook_client.get_extracted_tickets(results)
138
-
139
- return tickets
140
-
141
- except Exception as e:
142
- print(f"Ticket extraction hook failed: {e}")
143
- return []
144
-
145
-
146
- # Example of integrating into an existing orchestrator method
147
- def example_orchestrator_run_method(self, user_input: str):
148
- """Example of how to modify an existing orchestrator run method."""
149
-
150
- # Process input through hooks if available
151
- if self.hook_client:
152
- user_input = self.process_user_input_with_hooks(user_input)
153
-
154
- # Continue with normal orchestration
155
- # ... existing orchestrator code ...
156
-
157
- # When delegating to agents
158
- if needs_delegation:
159
- agent_name = "Engineer"
160
- task = "Implement the feature"
161
-
162
- # Process through pre-delegation hooks
163
- if self.hook_client:
164
- agent_name, task = self.process_agent_delegation_with_hooks(agent_name, task)
165
-
166
- # Perform delegation
167
- response = self.delegate_to_agent(agent_name, task)
168
-
169
- # Process response through post-delegation hooks
170
- if self.hook_client:
171
- response = self.process_agent_response_with_hooks(agent_name, response)
172
-
173
- # Extract tickets from the conversation
174
- if self.hook_client:
175
- conversation = f"User: {user_input}\nAssistant: {response}"
176
- tickets = self.extract_tickets_with_hooks(conversation)
177
- for ticket in tickets:
178
- print(f"Extracted ticket: {ticket['title']}")