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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.0.dist-info}/METADATA +26 -20
  76. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.0.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.0.dist-info}/WHEEL +0 -0
  121. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.0.dist-info}/entry_points.txt +0 -0
  122. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.0.dist-info}/licenses/LICENSE +0 -0
  123. {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.0.dist-info}/top_level.txt +0 -0
@@ -33,23 +33,24 @@ from enum import Enum
33
33
  from pathlib import Path
34
34
  from typing import Dict, List, Optional, Set, Any, Tuple, Union
35
35
 
36
- from claude_mpm.services.shared_prompt_cache import SharedPromptCache
37
- from claude_mpm.services.agent_registry import AgentRegistry, AgentMetadata
38
- from claude_mpm.services.agent_modification_tracker import (
36
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
37
+ from claude_mpm.services.agents.registry import AgentRegistry, AgentMetadata
38
+ from claude_mpm.services.agents.registry.modification_tracker import (
39
39
  AgentModificationTracker,
40
40
  AgentModification,
41
41
  ModificationType,
42
42
  ModificationTier
43
43
  )
44
- from claude_mpm.services.agent_persistence_service import (
44
+ from claude_mpm.services.agents.memory import (
45
45
  AgentPersistenceService,
46
46
  PersistenceStrategy,
47
47
  PersistenceRecord,
48
48
  PersistenceOperation
49
49
  )
50
- from claude_mpm.services.agent_management_service import AgentManager
50
+ from claude_mpm.services.agents.management import AgentManager
51
51
  from claude_mpm.models.agent_definition import AgentDefinition, AgentType
52
52
  from claude_mpm.core.base_service import BaseService
53
+ from claude_mpm.core.config_paths import ConfigPaths
53
54
  from claude_mpm.utils.path_operations import path_ops
54
55
  from claude_mpm.utils.config_manager import ConfigurationManager
55
56
 
@@ -275,7 +276,7 @@ class AgentLifecycleManager(BaseService):
275
276
  async def _load_agent_records(self) -> None:
276
277
  """Load existing agent lifecycle records."""
277
278
  try:
278
- records_file = Path.home() / '.claude-pm' / 'agent_tracking' / 'lifecycle_records.json'
279
+ records_file = ConfigPaths.get_tracking_dir() / 'lifecycle_records.json'
279
280
  if path_ops.validate_exists(records_file):
280
281
  data = self.config_mgr.load_json(records_file)
281
282
 
@@ -294,7 +295,7 @@ class AgentLifecycleManager(BaseService):
294
295
  async def _save_agent_records(self) -> None:
295
296
  """Save agent lifecycle records to disk."""
296
297
  try:
297
- records_file = Path.home() / '.claude-pm' / 'agent_tracking' / 'lifecycle_records.json'
298
+ records_file = ConfigPaths.get_tracking_dir() / 'lifecycle_records.json'
298
299
  path_ops.ensure_dir(records_file.parent)
299
300
 
300
301
  data = {}
@@ -788,9 +789,9 @@ class AgentLifecycleManager(BaseService):
788
789
  async def _determine_agent_file_path(self, agent_name: str, tier: ModificationTier) -> Path:
789
790
  """Determine appropriate file path for agent."""
790
791
  if tier == ModificationTier.USER:
791
- base_path = Path.home() / '.claude-pm' / 'agents'
792
+ base_path = ConfigPaths.get_user_agents_dir()
792
793
  elif tier == ModificationTier.PROJECT:
793
- base_path = Path.cwd() / '.claude-pm' / 'agents'
794
+ base_path = ConfigPaths.get_project_agents_dir()
794
795
  else: # SYSTEM
795
796
  base_path = Path.cwd() / 'claude_pm' / 'agents'
796
797
 
@@ -804,7 +805,7 @@ class AgentLifecycleManager(BaseService):
804
805
  if not path_ops.validate_exists(source_path):
805
806
  return None
806
807
 
807
- backup_dir = Path.home() / '.claude-pm' / 'agent_tracking' / 'backups'
808
+ backup_dir = ConfigPaths.get_tracking_dir() / 'backups'
808
809
  path_ops.ensure_dir(backup_dir)
809
810
 
810
811
  timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
@@ -0,0 +1,11 @@
1
+ """Agent loading and profile management services."""
2
+
3
+ from .framework_agent_loader import FrameworkAgentLoader
4
+ from .agent_profile_loader import AgentProfileLoader
5
+ from .base_agent_manager import BaseAgentManager
6
+
7
+ __all__ = [
8
+ "FrameworkAgentLoader",
9
+ "AgentProfileLoader",
10
+ "BaseAgentManager",
11
+ ]
@@ -34,8 +34,9 @@ import yaml
34
34
 
35
35
  from claude_mpm.core.base_service import BaseService
36
36
  from claude_mpm.core.config import Config
37
- from claude_mpm.services.shared_prompt_cache import SharedPromptCache
38
- from claude_mpm.services.agent_registry import AgentRegistry
37
+ from claude_mpm.core.config_paths import ConfigPaths
38
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
39
+ from claude_mpm.services.agents.registry import AgentRegistry
39
40
  from claude_mpm.utils.path_operations import path_ops
40
41
 
41
42
 
@@ -47,10 +48,10 @@ logger = logging.getLogger(__name__)
47
48
  # ============================================================================
48
49
 
49
50
  class ProfileTier(Enum):
50
- """Agent profile hierarchy tiers."""
51
- SYSTEM = "system"
52
- USER = "user"
53
- PROJECT = "project"
51
+ """Agent profile hierarchy tiers with precedence order."""
52
+ PROJECT = "project" # Highest precedence - project-specific agents
53
+ USER = "user" # Medium precedence - user-level agents
54
+ SYSTEM = "system" # Lowest precedence - framework/built-in agents
54
55
 
55
56
 
56
57
  class ProfileStatus(Enum):
@@ -117,7 +118,7 @@ class AgentProfileLoader(BaseService):
117
118
  # Tier paths configuration
118
119
  self.tier_paths = {
119
120
  ProfileTier.PROJECT: self.working_directory / 'agents',
120
- ProfileTier.USER: self.user_home / '.claude-pm' / 'agents',
121
+ ProfileTier.USER: ConfigPaths.get_user_agents_dir(),
121
122
  ProfileTier.SYSTEM: Path(__file__).parent.parent / 'agents' / 'templates'
122
123
  }
123
124
 
@@ -133,7 +134,7 @@ class AgentProfileLoader(BaseService):
133
134
  self.agent_registry: Optional[AgentRegistry] = None
134
135
 
135
136
  # Improved prompts storage
136
- self.improved_prompts_path = self.user_home / '.claude-pm' / 'improved_prompts'
137
+ self.improved_prompts_path = ConfigPaths.get_user_config_dir() / 'improved_prompts'
137
138
  self.improved_prompts_path.mkdir(parents=True, exist_ok=True)
138
139
 
139
140
  # Performance tracking
@@ -14,8 +14,8 @@ from datetime import datetime
14
14
  from dataclasses import dataclass, field
15
15
  from enum import Enum
16
16
 
17
- from .shared_prompt_cache import SharedPromptCache
18
- from ..agents.base_agent_loader import clear_base_agent_cache
17
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
18
+ from claude_mpm.agents.base_agent_loader import clear_base_agent_cache
19
19
 
20
20
  logger = logging.getLogger(__name__)
21
21
 
@@ -2,10 +2,14 @@
2
2
  Framework Agent Loader Service
3
3
 
4
4
  Implements agent profile loading logic based on directory hierarchy:
5
- 1. Framework .claude-pm (next to agents/INSTRUCTIONS.md or CLAUDE.md): system, trained, user agents
6
- 2. Project .claude-pm (in project root): project agents
5
+ 1. Project .claude-mpm (in project root): project agents - HIGHEST PRECEDENCE
6
+ 2. User .claude-mpm (~/.claude-mpm): user agents - MEDIUM PRECEDENCE
7
+ 3. Framework/System agents: built-in agents - LOWEST PRECEDENCE
7
8
 
8
- Loading precedence: Project → Framework (user trained → system)
9
+ Loading precedence: Project → UserSystem
10
+
11
+ This service integrates with the main agent_loader.py to provide
12
+ markdown-based agent profiles alongside JSON-based templates.
9
13
  """
10
14
 
11
15
  import os
@@ -14,38 +18,56 @@ from pathlib import Path
14
18
  from typing import Dict, Optional, Any
15
19
  import logging
16
20
 
21
+ from claude_mpm.core.config_paths import ConfigPaths
22
+ from claude_mpm.agents.agent_loader import AgentTier, get_agent_tier, list_agents_by_tier
23
+
17
24
  logger = logging.getLogger(__name__)
18
25
 
19
26
  class FrameworkAgentLoader:
20
- """Loads agent profiles from framework and project .claude-pm directories"""
27
+ """Loads agent profiles from project, user, and system directories with proper precedence"""
21
28
 
22
29
  def __init__(self):
23
- self.framework_agents_dir = None
24
30
  self.project_agents_dir = None
31
+ self.user_agents_dir = None
32
+ self.system_agents_dir = None
25
33
  self._profile_cache = {}
34
+ self._tier_mapping = {
35
+ AgentTier.PROJECT: 'project',
36
+ AgentTier.USER: 'user',
37
+ AgentTier.SYSTEM: 'system'
38
+ }
26
39
 
27
40
  def initialize(self, framework_claude_md_path: Optional[str] = None):
28
41
  """
29
- Initialize loader with framework and project directory detection
42
+ Initialize loader with project, user, and system directory detection
30
43
 
31
44
  Args:
32
45
  framework_claude_md_path: Optional explicit path to agents/INSTRUCTIONS.md or CLAUDE.md
33
46
  """
34
- # Find framework .claude-pm directory (next to framework/CLAUDE.md)
47
+ # Find project .claude-mpm directory (highest precedence)
48
+ project_dir = self._find_project_directory()
49
+ if project_dir:
50
+ self.project_agents_dir = project_dir / ConfigPaths.CONFIG_DIR / "agents"
51
+ logger.info(f"Project agents directory: {self.project_agents_dir}")
52
+
53
+ # Find user .claude-mpm directory (medium precedence)
54
+ user_config_dir = ConfigPaths.get_user_config_dir()
55
+ if user_config_dir:
56
+ self.user_agents_dir = user_config_dir / "agents"
57
+ if self.user_agents_dir.exists():
58
+ logger.info(f"User agents directory: {self.user_agents_dir}")
59
+ else:
60
+ self.user_agents_dir = None
61
+
62
+ # Find system/framework agents directory (lowest precedence)
35
63
  if framework_claude_md_path:
36
64
  framework_dir = Path(framework_claude_md_path).parent.parent
37
65
  else:
38
66
  framework_dir = self._find_framework_directory()
39
67
 
40
68
  if framework_dir:
41
- self.framework_agents_dir = framework_dir / ".claude-pm" / "agents"
42
- logger.info(f"Framework agents directory: {self.framework_agents_dir}")
43
-
44
- # Find project .claude-pm directory
45
- project_dir = self._find_project_directory()
46
- if project_dir:
47
- self.project_agents_dir = project_dir / ".claude-pm" / "agents"
48
- logger.info(f"Project agents directory: {self.project_agents_dir}")
69
+ self.system_agents_dir = framework_dir / ConfigPaths.CONFIG_DIR / "agents"
70
+ logger.info(f"System agents directory: {self.system_agents_dir}")
49
71
 
50
72
  def _find_framework_directory(self) -> Optional[Path]:
51
73
  """Find directory containing agents/INSTRUCTIONS.md (or legacy CLAUDE.md)"""
@@ -75,12 +97,12 @@ class FrameworkAgentLoader:
75
97
  return None
76
98
 
77
99
  def _find_project_directory(self) -> Optional[Path]:
78
- """Find project directory containing .claude-pm"""
100
+ """Find project directory containing .claude-mpm"""
79
101
  current = Path.cwd()
80
102
 
81
- # Check current directory and parents for .claude-pm
103
+ # Check current directory and parents for .claude-mpm
82
104
  for path in [current] + list(current.parents):
83
- claude_pm_dir = path / ".claude-pm"
105
+ claude_pm_dir = path / ConfigPaths.CONFIG_DIR
84
106
  if claude_pm_dir.exists():
85
107
  return path
86
108
 
@@ -88,7 +110,10 @@ class FrameworkAgentLoader:
88
110
 
89
111
  def load_agent_profile(self, agent_type: str) -> Optional[Dict[str, Any]]:
90
112
  """
91
- Load agent profile with precedence: Project → Framework (user trained → system)
113
+ Load agent profile with precedence: Project → UserSystem
114
+
115
+ This method now properly integrates with the main agent_loader.py
116
+ tier system for consistent precedence handling.
92
117
 
93
118
  Args:
94
119
  agent_type: Agent type (Engineer, Documenter, QA, etc.)
@@ -102,31 +127,57 @@ class FrameworkAgentLoader:
102
127
  return self._profile_cache[cache_key]
103
128
 
104
129
  profile = None
130
+ loaded_tier = None
105
131
 
106
132
  # 1. Try project agents first (highest precedence)
107
133
  if self.project_agents_dir:
134
+ # Check both 'project' subdirectory and direct directory
108
135
  profile = self._load_profile_from_directory(
109
136
  self.project_agents_dir / "project", agent_type
110
137
  )
138
+ if not profile:
139
+ profile = self._load_profile_from_directory(
140
+ self.project_agents_dir, agent_type
141
+ )
142
+ if profile:
143
+ loaded_tier = AgentTier.PROJECT
111
144
 
112
- # 2. Try framework agents (user → trained → system)
113
- if not profile and self.framework_agents_dir:
114
- # Framework user agents
145
+ # 2. Try user agents (medium precedence)
146
+ if not profile and self.user_agents_dir:
147
+ # Check both 'user' subdirectory and direct directory
115
148
  profile = self._load_profile_from_directory(
116
- self.framework_agents_dir / "user", agent_type
149
+ self.user_agents_dir / "user", agent_type
117
150
  )
118
-
119
- # Framework trained agents
120
151
  if not profile:
121
152
  profile = self._load_profile_from_directory(
122
- self.framework_agents_dir / "trained", agent_type
153
+ self.user_agents_dir, agent_type
154
+ )
155
+ if profile:
156
+ loaded_tier = AgentTier.USER
157
+
158
+ # 3. Try system agents (lowest precedence)
159
+ if not profile and self.system_agents_dir:
160
+ # Check subdirectories in order: trained → system
161
+ for subdir in ["trained", "system"]:
162
+ profile = self._load_profile_from_directory(
163
+ self.system_agents_dir / subdir, agent_type
123
164
  )
165
+ if profile:
166
+ loaded_tier = AgentTier.SYSTEM
167
+ break
124
168
 
125
- # Framework system agents (fallback)
169
+ # Also check root system directory
126
170
  if not profile:
127
171
  profile = self._load_profile_from_directory(
128
- self.framework_agents_dir / "system", agent_type
172
+ self.system_agents_dir, agent_type
129
173
  )
174
+ if profile:
175
+ loaded_tier = AgentTier.SYSTEM
176
+
177
+ # Add tier information to profile
178
+ if profile and loaded_tier:
179
+ profile['_tier'] = loaded_tier.value
180
+ logger.debug(f"Loaded {agent_type} profile from {loaded_tier.value} tier")
130
181
 
131
182
  # Cache result
132
183
  if profile:
@@ -270,23 +321,48 @@ class FrameworkAgentLoader:
270
321
  """Get list of available agents by tier"""
271
322
  agents = {
272
323
  'project': [],
273
- 'framework_user': [],
274
- 'framework_trained': [],
275
- 'framework_system': []
324
+ 'user': [],
325
+ 'system': []
276
326
  }
277
327
 
278
328
  # Project agents
279
329
  if self.project_agents_dir:
280
- project_dir = self.project_agents_dir / "project"
281
- if project_dir.exists():
282
- agents['project'] = [f.stem for f in project_dir.glob("*.md")]
330
+ # Check both project subdirectory and root
331
+ for search_dir in [self.project_agents_dir / "project", self.project_agents_dir]:
332
+ if search_dir.exists():
333
+ md_files = [f.stem for f in search_dir.glob("*.md")]
334
+ agents['project'].extend([f for f in md_files if f not in agents['project']])
335
+
336
+ # User agents
337
+ if self.user_agents_dir:
338
+ # Check both user subdirectory and root
339
+ for search_dir in [self.user_agents_dir / "user", self.user_agents_dir]:
340
+ if search_dir.exists():
341
+ md_files = [f.stem for f in search_dir.glob("*.md")]
342
+ agents['user'].extend([f for f in md_files if f not in agents['user']])
283
343
 
284
- # Framework agents
285
- if self.framework_agents_dir:
286
- for tier in ['user', 'trained', 'system']:
287
- tier_dir = self.framework_agents_dir / tier
288
- if tier_dir.exists():
289
- agents[f'framework_{tier}'] = [f.stem for f in tier_dir.glob("*.md")]
344
+ # System agents
345
+ if self.system_agents_dir:
346
+ # Check subdirectories and root
347
+ for subdir in ["trained", "system", ""]:
348
+ search_dir = self.system_agents_dir / subdir if subdir else self.system_agents_dir
349
+ if search_dir.exists():
350
+ md_files = [f.stem for f in search_dir.glob("*.md")]
351
+ agents['system'].extend([f for f in md_files if f not in agents['system']])
352
+
353
+ # Also integrate with main agent_loader to get JSON-based agents
354
+ try:
355
+ json_agents = list_agents_by_tier()
356
+ for tier, agent_list in json_agents.items():
357
+ if tier in agents:
358
+ # Merge lists, avoiding duplicates
359
+ for agent in agent_list:
360
+ # Remove _agent suffix for consistency
361
+ agent_name = agent.replace('_agent', '')
362
+ if agent_name not in agents[tier]:
363
+ agents[tier].append(agent_name)
364
+ except Exception as e:
365
+ logger.debug(f"Could not integrate with agent_loader: {e}")
290
366
 
291
367
  return agents
292
368
 
@@ -0,0 +1,9 @@
1
+ """High-level agent management services."""
2
+
3
+ from .agent_management_service import AgentManager
4
+ from .agent_capabilities_generator import AgentCapabilitiesGenerator
5
+
6
+ __all__ = [
7
+ "AgentManager",
8
+ "AgentCapabilitiesGenerator",
9
+ ]
@@ -21,13 +21,14 @@ from datetime import datetime
21
21
  import frontmatter
22
22
  import mistune
23
23
 
24
- from ..models.agent_definition import (
24
+ from claude_mpm.models.agent_definition import (
25
25
  AgentDefinition, AgentMetadata, AgentType,
26
26
  AgentSection, AgentWorkflow, AgentPermissions
27
27
  )
28
- from .agent_versioning import AgentVersionManager
29
- from .shared_prompt_cache import SharedPromptCache
30
- from ..utils.paths import PathResolver
28
+ from ..deployment.agent_versioning import AgentVersionManager
29
+ from claude_mpm.services.memory.cache.shared_prompt_cache import SharedPromptCache
30
+ from claude_mpm.utils.paths import PathResolver
31
+ from claude_mpm.core.config_paths import ConfigPaths
31
32
 
32
33
  logger = logging.getLogger(__name__)
33
34
 
@@ -56,7 +57,7 @@ class AgentManager:
56
57
 
57
58
  if project_dir is None:
58
59
  project_root = PathResolver.get_project_root()
59
- self.project_dir = project_root / ".claude-pm" / "agents" / "project-specific"
60
+ self.project_dir = project_root / ConfigPaths.CONFIG_DIR / "agents" / "project-specific"
60
61
  else:
61
62
  self.project_dir = project_dir
62
63
  self.version_manager = AgentVersionManager()
@@ -0,0 +1,21 @@
1
+ """Agent memory and persistence services."""
2
+
3
+ from .agent_memory_manager import (
4
+ AgentMemoryManager,
5
+ get_memory_manager,
6
+ )
7
+ from .agent_persistence_service import (
8
+ AgentPersistenceService,
9
+ PersistenceStrategy,
10
+ PersistenceOperation,
11
+ PersistenceRecord,
12
+ )
13
+
14
+ __all__ = [
15
+ "AgentMemoryManager",
16
+ "get_memory_manager",
17
+ "AgentPersistenceService",
18
+ "PersistenceStrategy",
19
+ "PersistenceOperation",
20
+ "PersistenceRecord",
21
+ ]
@@ -946,7 +946,7 @@ class AgentMemoryManager:
946
946
  Dict containing optimization results and statistics
947
947
  """
948
948
  try:
949
- from claude_mpm.services.memory_optimizer import MemoryOptimizer
949
+ from claude_mpm.services.memory.optimizer import MemoryOptimizer
950
950
  optimizer = MemoryOptimizer(self.config, self.working_directory)
951
951
 
952
952
  if agent_id:
@@ -974,7 +974,7 @@ class AgentMemoryManager:
974
974
  Dict containing build results and statistics
975
975
  """
976
976
  try:
977
- from claude_mpm.services.memory_builder import MemoryBuilder
977
+ from claude_mpm.services.memory.builder import MemoryBuilder
978
978
  builder = MemoryBuilder(self.config, self.working_directory)
979
979
 
980
980
  result = builder.build_from_documentation(force_rebuild)
@@ -1000,7 +1000,7 @@ class AgentMemoryManager:
1000
1000
  Dict containing routing decision and reasoning
1001
1001
  """
1002
1002
  try:
1003
- from claude_mpm.services.memory_router import MemoryRouter
1003
+ from claude_mpm.services.memory.router import MemoryRouter
1004
1004
  router = MemoryRouter(self.config)
1005
1005
 
1006
1006
  routing_result = router.analyze_and_route(content, context)
@@ -0,0 +1,29 @@
1
+ """Agent registry services for discovery and tracking."""
2
+
3
+ from .agent_registry import (
4
+ AgentRegistry,
5
+ AgentMetadata,
6
+ AgentTier,
7
+ AgentType,
8
+ )
9
+ from .deployed_agent_discovery import DeployedAgentDiscovery
10
+ from .modification_tracker import (
11
+ AgentModificationTracker,
12
+ ModificationType,
13
+ ModificationTier,
14
+ AgentModification,
15
+ ModificationHistory,
16
+ )
17
+
18
+ __all__ = [
19
+ "AgentRegistry",
20
+ "AgentMetadata",
21
+ "AgentTier",
22
+ "AgentType",
23
+ "DeployedAgentDiscovery",
24
+ "AgentModificationTracker",
25
+ "ModificationType",
26
+ "ModificationTier",
27
+ "AgentModification",
28
+ "ModificationHistory",
29
+ ]