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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/INSTRUCTIONS.md +182 -299
- claude_mpm/agents/agent_loader.py +283 -57
- claude_mpm/agents/agent_loader_integration.py +6 -9
- claude_mpm/agents/base_agent.json +2 -1
- claude_mpm/agents/base_agent_loader.py +1 -1
- claude_mpm/cli/__init__.py +5 -7
- claude_mpm/cli/commands/__init__.py +0 -2
- claude_mpm/cli/commands/agents.py +1 -1
- claude_mpm/cli/commands/memory.py +1 -1
- claude_mpm/cli/commands/run.py +12 -0
- claude_mpm/cli/parser.py +0 -13
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/config/__init__.py +44 -2
- claude_mpm/config/agent_config.py +348 -0
- claude_mpm/config/paths.py +322 -0
- claude_mpm/constants.py +0 -1
- claude_mpm/core/__init__.py +2 -5
- claude_mpm/core/agent_registry.py +63 -17
- claude_mpm/core/claude_runner.py +354 -43
- claude_mpm/core/config.py +7 -1
- claude_mpm/core/config_aliases.py +4 -3
- claude_mpm/core/config_paths.py +151 -0
- claude_mpm/core/factories.py +4 -50
- claude_mpm/core/logger.py +11 -13
- claude_mpm/core/service_registry.py +2 -2
- claude_mpm/dashboard/static/js/components/agent-inference.js +101 -25
- claude_mpm/dashboard/static/js/components/event-processor.js +3 -2
- claude_mpm/hooks/claude_hooks/hook_handler.py +343 -83
- claude_mpm/hooks/memory_integration_hook.py +1 -1
- claude_mpm/init.py +37 -6
- claude_mpm/scripts/socketio_daemon.py +6 -2
- claude_mpm/services/__init__.py +71 -3
- claude_mpm/services/agents/__init__.py +85 -0
- claude_mpm/services/agents/deployment/__init__.py +21 -0
- claude_mpm/services/{agent_deployment.py → agents/deployment/agent_deployment.py} +192 -41
- claude_mpm/services/{agent_lifecycle_manager.py → agents/deployment/agent_lifecycle_manager.py} +11 -10
- claude_mpm/services/agents/loading/__init__.py +11 -0
- claude_mpm/services/{agent_profile_loader.py → agents/loading/agent_profile_loader.py} +9 -8
- claude_mpm/services/{base_agent_manager.py → agents/loading/base_agent_manager.py} +2 -2
- claude_mpm/services/{framework_agent_loader.py → agents/loading/framework_agent_loader.py} +116 -40
- claude_mpm/services/agents/management/__init__.py +9 -0
- claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py} +6 -5
- claude_mpm/services/agents/memory/__init__.py +21 -0
- claude_mpm/services/{agent_memory_manager.py → agents/memory/agent_memory_manager.py} +3 -3
- claude_mpm/services/agents/registry/__init__.py +29 -0
- claude_mpm/services/{agent_registry.py → agents/registry/agent_registry.py} +101 -16
- claude_mpm/services/{deployed_agent_discovery.py → agents/registry/deployed_agent_discovery.py} +12 -2
- claude_mpm/services/{agent_modification_tracker.py → agents/registry/modification_tracker.py} +6 -5
- claude_mpm/services/async_session_logger.py +584 -0
- claude_mpm/services/claude_session_logger.py +299 -0
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +2 -2
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +17 -17
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +3 -3
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +1 -1
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +1 -1
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +19 -24
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +1 -1
- claude_mpm/services/framework_claude_md_generator.py +4 -2
- claude_mpm/services/memory/__init__.py +17 -0
- claude_mpm/services/{memory_builder.py → memory/builder.py} +3 -3
- claude_mpm/services/memory/cache/__init__.py +14 -0
- claude_mpm/services/{shared_prompt_cache.py → memory/cache/shared_prompt_cache.py} +1 -1
- claude_mpm/services/memory/cache/simple_cache.py +317 -0
- claude_mpm/services/{memory_optimizer.py → memory/optimizer.py} +1 -1
- claude_mpm/services/{memory_router.py → memory/router.py} +1 -1
- claude_mpm/services/optimized_hook_service.py +542 -0
- claude_mpm/services/project_registry.py +14 -8
- claude_mpm/services/response_tracker.py +237 -0
- claude_mpm/services/ticketing_service_original.py +4 -2
- claude_mpm/services/version_control/branch_strategy.py +3 -1
- claude_mpm/utils/paths.py +12 -10
- claude_mpm/utils/session_logging.py +114 -0
- claude_mpm/validation/agent_validator.py +2 -1
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/METADATA +28 -20
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/RECORD +83 -106
- claude_mpm/cli/commands/ui.py +0 -57
- claude_mpm/core/simple_runner.py +0 -1046
- claude_mpm/hooks/builtin/__init__.py +0 -1
- claude_mpm/hooks/builtin/logging_hook_example.py +0 -165
- claude_mpm/hooks/builtin/memory_hooks_example.py +0 -67
- claude_mpm/hooks/builtin/mpm_command_hook.py +0 -125
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +0 -124
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +0 -125
- claude_mpm/hooks/builtin/submit_hook_example.py +0 -100
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +0 -237
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +0 -240
- claude_mpm/hooks/builtin/workflow_start_hook.py +0 -181
- claude_mpm/orchestration/__init__.py +0 -6
- claude_mpm/orchestration/archive/direct_orchestrator.py +0 -195
- claude_mpm/orchestration/archive/factory.py +0 -215
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +0 -188
- claude_mpm/orchestration/archive/hook_integration_example.py +0 -178
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +0 -826
- claude_mpm/orchestration/archive/orchestrator.py +0 -501
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +0 -252
- claude_mpm/orchestration/archive/pty_orchestrator.py +0 -270
- claude_mpm/orchestration/archive/simple_orchestrator.py +0 -82
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +0 -801
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +0 -278
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +0 -187
- claude_mpm/schemas/workflow_validator.py +0 -411
- claude_mpm/services/parent_directory_manager/__init__.py +0 -577
- claude_mpm/services/parent_directory_manager/backup_manager.py +0 -258
- claude_mpm/services/parent_directory_manager/config_manager.py +0 -210
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +0 -279
- claude_mpm/services/parent_directory_manager/framework_protector.py +0 -143
- claude_mpm/services/parent_directory_manager/operations.py +0 -186
- claude_mpm/services/parent_directory_manager/state_manager.py +0 -624
- claude_mpm/services/parent_directory_manager/template_deployer.py +0 -579
- claude_mpm/services/parent_directory_manager/validation_manager.py +0 -378
- claude_mpm/services/parent_directory_manager/version_control_helper.py +0 -339
- claude_mpm/services/parent_directory_manager/version_manager.py +0 -222
- claude_mpm/ui/__init__.py +0 -1
- claude_mpm/ui/rich_terminal_ui.py +0 -295
- claude_mpm/ui/terminal_ui.py +0 -328
- /claude_mpm/services/{agent_versioning.py → agents/deployment/agent_versioning.py} +0 -0
- /claude_mpm/services/{agent_capabilities_generator.py → agents/management/agent_capabilities_generator.py} +0 -0
- /claude_mpm/services/{agent_persistence_service.py → agents/memory/agent_persistence_service.py} +0 -0
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/WHEEL +0 -0
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/entry_points.txt +0 -0
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-3.4.27.dist-info → claude_mpm-3.5.1.dist-info}/top_level.txt +0 -0
claude_mpm/services/{agent_lifecycle_manager.py → agents/deployment/agent_lifecycle_manager.py}
RENAMED
|
@@ -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.
|
|
38
|
-
from claude_mpm.services.
|
|
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.
|
|
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.
|
|
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 =
|
|
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 =
|
|
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 =
|
|
792
|
+
base_path = ConfigPaths.get_user_agents_dir()
|
|
792
793
|
elif tier == ModificationTier.PROJECT:
|
|
793
|
-
base_path =
|
|
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 =
|
|
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.
|
|
38
|
-
from claude_mpm.services.
|
|
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
|
-
|
|
52
|
-
USER = "user"
|
|
53
|
-
|
|
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:
|
|
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 =
|
|
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
|
|
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.
|
|
6
|
-
2.
|
|
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 →
|
|
9
|
+
Loading precedence: Project → User → System
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
42
|
-
logger.info(f"
|
|
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-
|
|
100
|
+
"""Find project directory containing .claude-mpm"""
|
|
79
101
|
current = Path.cwd()
|
|
80
102
|
|
|
81
|
-
# Check current directory and parents for .claude-
|
|
103
|
+
# Check current directory and parents for .claude-mpm
|
|
82
104
|
for path in [current] + list(current.parents):
|
|
83
|
-
claude_pm_dir = path /
|
|
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 →
|
|
113
|
+
Load agent profile with precedence: Project → User → System
|
|
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
|
|
113
|
-
if not profile and self.
|
|
114
|
-
#
|
|
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.
|
|
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.
|
|
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
|
-
#
|
|
169
|
+
# Also check root system directory
|
|
126
170
|
if not profile:
|
|
127
171
|
profile = self._load_profile_from_directory(
|
|
128
|
-
self.
|
|
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
|
-
'
|
|
274
|
-
'
|
|
275
|
-
'framework_system': []
|
|
324
|
+
'user': [],
|
|
325
|
+
'system': []
|
|
276
326
|
}
|
|
277
327
|
|
|
278
328
|
# Project agents
|
|
279
329
|
if self.project_agents_dir:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
#
|
|
285
|
-
if self.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if
|
|
289
|
-
|
|
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
|
|
claude_mpm/services/{agent_management_service.py → agents/management/agent_management_service.py}
RENAMED
|
@@ -21,13 +21,14 @@ from datetime import datetime
|
|
|
21
21
|
import frontmatter
|
|
22
22
|
import mistune
|
|
23
23
|
|
|
24
|
-
from
|
|
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
|
|
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 /
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
+
]
|