claude-mpm 0.3.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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/__init__.py +17 -0
- claude_mpm/__main__.py +14 -0
- claude_mpm/_version.py +32 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +88 -0
- claude_mpm/agents/INSTRUCTIONS.md +375 -0
- claude_mpm/agents/__init__.py +118 -0
- claude_mpm/agents/agent_loader.py +621 -0
- claude_mpm/agents/agent_loader_integration.py +229 -0
- claude_mpm/agents/agents_metadata.py +204 -0
- claude_mpm/agents/base_agent.json +27 -0
- claude_mpm/agents/base_agent_loader.py +519 -0
- claude_mpm/agents/schema/agent_schema.json +160 -0
- claude_mpm/agents/system_agent_config.py +587 -0
- claude_mpm/agents/templates/__init__.py +101 -0
- claude_mpm/agents/templates/data_engineer_agent.json +46 -0
- claude_mpm/agents/templates/documentation_agent.json +45 -0
- claude_mpm/agents/templates/engineer_agent.json +49 -0
- claude_mpm/agents/templates/ops_agent.json +46 -0
- claude_mpm/agents/templates/qa_agent.json +45 -0
- claude_mpm/agents/templates/research_agent.json +49 -0
- claude_mpm/agents/templates/security_agent.json +46 -0
- claude_mpm/agents/templates/update-optimized-specialized-agents.json +374 -0
- claude_mpm/agents/templates/version_control_agent.json +46 -0
- claude_mpm/agents/test_fix_deployment/.claude-pm/config/project.json +6 -0
- claude_mpm/cli.py +655 -0
- claude_mpm/cli_main.py +13 -0
- claude_mpm/cli_module/__init__.py +15 -0
- claude_mpm/cli_module/args.py +222 -0
- claude_mpm/cli_module/commands.py +203 -0
- claude_mpm/cli_module/migration_example.py +183 -0
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/cli_old/__init__.py +1 -0
- claude_mpm/cli_old/ticket_cli.py +102 -0
- claude_mpm/config/__init__.py +5 -0
- claude_mpm/config/hook_config.py +42 -0
- claude_mpm/constants.py +150 -0
- claude_mpm/core/__init__.py +45 -0
- claude_mpm/core/agent_name_normalizer.py +248 -0
- claude_mpm/core/agent_registry.py +627 -0
- claude_mpm/core/agent_registry.py.bak +312 -0
- claude_mpm/core/agent_session_manager.py +273 -0
- claude_mpm/core/base_service.py +747 -0
- claude_mpm/core/base_service.py.bak +406 -0
- claude_mpm/core/config.py +334 -0
- claude_mpm/core/config_aliases.py +292 -0
- claude_mpm/core/container.py +347 -0
- claude_mpm/core/factories.py +281 -0
- claude_mpm/core/framework_loader.py +472 -0
- claude_mpm/core/injectable_service.py +206 -0
- claude_mpm/core/interfaces.py +539 -0
- claude_mpm/core/logger.py +468 -0
- claude_mpm/core/minimal_framework_loader.py +107 -0
- claude_mpm/core/mixins.py +150 -0
- claude_mpm/core/service_registry.py +299 -0
- claude_mpm/core/session_manager.py +190 -0
- claude_mpm/core/simple_runner.py +511 -0
- claude_mpm/core/tool_access_control.py +173 -0
- claude_mpm/hooks/README.md +243 -0
- claude_mpm/hooks/__init__.py +5 -0
- claude_mpm/hooks/base_hook.py +154 -0
- claude_mpm/hooks/builtin/__init__.py +1 -0
- claude_mpm/hooks/builtin/logging_hook_example.py +165 -0
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +124 -0
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +125 -0
- claude_mpm/hooks/builtin/submit_hook_example.py +100 -0
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +237 -0
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +239 -0
- claude_mpm/hooks/builtin/workflow_start_hook.py +181 -0
- claude_mpm/hooks/hook_client.py +264 -0
- claude_mpm/hooks/hook_runner.py +370 -0
- claude_mpm/hooks/json_rpc_executor.py +259 -0
- claude_mpm/hooks/json_rpc_hook_client.py +319 -0
- claude_mpm/hooks/tool_call_interceptor.py +204 -0
- claude_mpm/init.py +246 -0
- claude_mpm/orchestration/SUBPROCESS_DESIGN.md +66 -0
- claude_mpm/orchestration/__init__.py +6 -0
- claude_mpm/orchestration/archive/direct_orchestrator.py +195 -0
- claude_mpm/orchestration/archive/factory.py +215 -0
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +188 -0
- claude_mpm/orchestration/archive/hook_integration_example.py +178 -0
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +826 -0
- claude_mpm/orchestration/archive/orchestrator.py +501 -0
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +252 -0
- claude_mpm/orchestration/archive/pty_orchestrator.py +270 -0
- claude_mpm/orchestration/archive/simple_orchestrator.py +82 -0
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +801 -0
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +278 -0
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +187 -0
- claude_mpm/scripts/__init__.py +1 -0
- claude_mpm/scripts/ticket.py +269 -0
- claude_mpm/services/__init__.py +10 -0
- claude_mpm/services/agent_deployment.py +955 -0
- claude_mpm/services/agent_lifecycle_manager.py +948 -0
- claude_mpm/services/agent_management_service.py +596 -0
- claude_mpm/services/agent_modification_tracker.py +841 -0
- claude_mpm/services/agent_profile_loader.py +606 -0
- claude_mpm/services/agent_registry.py +677 -0
- claude_mpm/services/base_agent_manager.py +380 -0
- claude_mpm/services/framework_agent_loader.py +337 -0
- claude_mpm/services/framework_claude_md_generator/README.md +92 -0
- claude_mpm/services/framework_claude_md_generator/__init__.py +206 -0
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +151 -0
- claude_mpm/services/framework_claude_md_generator/content_validator.py +126 -0
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +137 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +106 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +582 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +97 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +27 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +20 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +26 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +30 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +37 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +111 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +89 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +39 -0
- claude_mpm/services/framework_claude_md_generator/section_manager.py +106 -0
- claude_mpm/services/framework_claude_md_generator/version_manager.py +121 -0
- claude_mpm/services/framework_claude_md_generator.py +621 -0
- claude_mpm/services/hook_service.py +388 -0
- claude_mpm/services/hook_service_manager.py +223 -0
- claude_mpm/services/json_rpc_hook_manager.py +92 -0
- claude_mpm/services/parent_directory_manager/README.md +83 -0
- claude_mpm/services/parent_directory_manager/__init__.py +577 -0
- claude_mpm/services/parent_directory_manager/backup_manager.py +258 -0
- claude_mpm/services/parent_directory_manager/config_manager.py +210 -0
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +279 -0
- claude_mpm/services/parent_directory_manager/framework_protector.py +143 -0
- claude_mpm/services/parent_directory_manager/operations.py +186 -0
- claude_mpm/services/parent_directory_manager/state_manager.py +624 -0
- claude_mpm/services/parent_directory_manager/template_deployer.py +579 -0
- claude_mpm/services/parent_directory_manager/validation_manager.py +378 -0
- claude_mpm/services/parent_directory_manager/version_control_helper.py +339 -0
- claude_mpm/services/parent_directory_manager/version_manager.py +222 -0
- claude_mpm/services/shared_prompt_cache.py +819 -0
- claude_mpm/services/ticket_manager.py +213 -0
- claude_mpm/services/ticket_manager_di.py +318 -0
- claude_mpm/services/ticketing_service_original.py +508 -0
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/__init__.py +70 -0
- claude_mpm/services/version_control/branch_strategy.py +670 -0
- claude_mpm/services/version_control/conflict_resolution.py +744 -0
- claude_mpm/services/version_control/git_operations.py +784 -0
- claude_mpm/services/version_control/semantic_versioning.py +703 -0
- claude_mpm/ui/__init__.py +1 -0
- claude_mpm/ui/rich_terminal_ui.py +295 -0
- claude_mpm/ui/terminal_ui.py +328 -0
- claude_mpm/utils/__init__.py +16 -0
- claude_mpm/utils/config_manager.py +468 -0
- claude_mpm/utils/import_migration_example.py +80 -0
- claude_mpm/utils/imports.py +182 -0
- claude_mpm/utils/path_operations.py +357 -0
- claude_mpm/utils/paths.py +289 -0
- claude_mpm-0.3.0.dist-info/METADATA +290 -0
- claude_mpm-0.3.0.dist-info/RECORD +159 -0
- claude_mpm-0.3.0.dist-info/WHEEL +5 -0
- claude_mpm-0.3.0.dist-info/entry_points.txt +4 -0
- claude_mpm-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Base Agent Manager
|
|
4
|
+
==================
|
|
5
|
+
|
|
6
|
+
Specialized manager for base_agent.md with structured update capabilities.
|
|
7
|
+
Enforces template structure and provides section-specific update methods.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Dict, List, Optional, Any
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from dataclasses import dataclass, field
|
|
15
|
+
from enum import Enum
|
|
16
|
+
|
|
17
|
+
from .shared_prompt_cache import SharedPromptCache
|
|
18
|
+
from ..agents.base_agent_loader import clear_base_agent_cache
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class BaseAgentSection(str, Enum):
|
|
24
|
+
"""Base agent markdown sections."""
|
|
25
|
+
FRAMEWORK_CONTEXT = "Agent Framework Context"
|
|
26
|
+
BEHAVIORAL_RULES = "Common Behavioral Rules"
|
|
27
|
+
TEMPORAL_CONTEXT = "Temporal Context Integration"
|
|
28
|
+
QUALITY_STANDARDS = "Quality Standards"
|
|
29
|
+
TOOL_USAGE = "Tool Usage Guidelines"
|
|
30
|
+
COLLABORATION = "Collaboration Protocols"
|
|
31
|
+
PERFORMANCE = "Performance Optimization"
|
|
32
|
+
ESCALATION = "Escalation Triggers"
|
|
33
|
+
OUTPUT_FORMATS = "Output Formatting Standards"
|
|
34
|
+
FRAMEWORK_INTEGRATION = "Framework Integration"
|
|
35
|
+
CONSTRAINTS = "Universal Constraints"
|
|
36
|
+
SUCCESS_CRITERIA = "Success Criteria"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class BaseAgentStructure:
|
|
41
|
+
"""Structured representation of base_agent.md content."""
|
|
42
|
+
# Header
|
|
43
|
+
title: str = "Base Agent Instructions"
|
|
44
|
+
description: str = "These instructions are prepended to EVERY agent prompt."
|
|
45
|
+
|
|
46
|
+
# Main sections
|
|
47
|
+
framework_context: Dict[str, Any] = field(default_factory=dict)
|
|
48
|
+
behavioral_rules: Dict[str, List[str]] = field(default_factory=dict)
|
|
49
|
+
temporal_context: str = ""
|
|
50
|
+
quality_standards: Dict[str, List[str]] = field(default_factory=dict)
|
|
51
|
+
tool_usage: Dict[str, List[str]] = field(default_factory=dict)
|
|
52
|
+
collaboration_protocols: Dict[str, str] = field(default_factory=dict)
|
|
53
|
+
performance_optimization: Dict[str, str] = field(default_factory=dict)
|
|
54
|
+
escalation_triggers: List[str] = field(default_factory=list)
|
|
55
|
+
output_formats: Dict[str, str] = field(default_factory=dict)
|
|
56
|
+
framework_integration: Dict[str, List[str]] = field(default_factory=dict)
|
|
57
|
+
universal_constraints: List[str] = field(default_factory=list)
|
|
58
|
+
success_criteria: List[str] = field(default_factory=list)
|
|
59
|
+
|
|
60
|
+
# Raw sections for preservation
|
|
61
|
+
raw_sections: Dict[str, str] = field(default_factory=dict)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class BaseAgentManager:
|
|
65
|
+
"""Manages base_agent.md with structured updates and validation."""
|
|
66
|
+
|
|
67
|
+
def __init__(self, framework_dir: Optional[Path] = None):
|
|
68
|
+
"""Initialize BaseAgentManager."""
|
|
69
|
+
self.framework_dir = framework_dir or Path(__file__).parent.parent.parent / "framework" / "agent-roles"
|
|
70
|
+
self.base_agent_path = self.framework_dir / "base_agent.md"
|
|
71
|
+
self.cache = SharedPromptCache.get_instance()
|
|
72
|
+
|
|
73
|
+
def read_base_agent(self) -> Optional[BaseAgentStructure]:
|
|
74
|
+
"""
|
|
75
|
+
Read and parse base_agent.md into structured format.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
BaseAgentStructure or None if file doesn't exist
|
|
79
|
+
"""
|
|
80
|
+
if not self.base_agent_path.exists():
|
|
81
|
+
logger.error(f"base_agent.md not found at {self.base_agent_path}")
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
content = self.base_agent_path.read_text(encoding='utf-8')
|
|
86
|
+
return self._parse_base_agent(content)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
logger.error(f"Error reading base_agent.md: {e}")
|
|
89
|
+
return None
|
|
90
|
+
|
|
91
|
+
def update_base_agent(self, updates: Dict[str, Any],
|
|
92
|
+
backup: bool = True) -> Optional[BaseAgentStructure]:
|
|
93
|
+
"""
|
|
94
|
+
Update base_agent.md with structured updates.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
updates: Dictionary of updates to apply
|
|
98
|
+
backup: Whether to create backup before updating
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
Updated BaseAgentStructure or None if failed
|
|
102
|
+
"""
|
|
103
|
+
# Read current structure
|
|
104
|
+
current = self.read_base_agent()
|
|
105
|
+
if not current:
|
|
106
|
+
logger.error("Cannot update - base_agent.md not found")
|
|
107
|
+
return None
|
|
108
|
+
|
|
109
|
+
# Create backup if requested
|
|
110
|
+
if backup:
|
|
111
|
+
self._create_backup()
|
|
112
|
+
|
|
113
|
+
# Apply updates
|
|
114
|
+
for key, value in updates.items():
|
|
115
|
+
if hasattr(current, key):
|
|
116
|
+
setattr(current, key, value)
|
|
117
|
+
else:
|
|
118
|
+
logger.warning(f"Unknown base agent attribute: {key}")
|
|
119
|
+
|
|
120
|
+
# Convert back to markdown and save
|
|
121
|
+
content = self._structure_to_markdown(current)
|
|
122
|
+
self.base_agent_path.write_text(content, encoding='utf-8')
|
|
123
|
+
|
|
124
|
+
# Clear caches
|
|
125
|
+
clear_base_agent_cache()
|
|
126
|
+
self.cache.invalidate("base_agent:instructions")
|
|
127
|
+
|
|
128
|
+
logger.info("Base agent updated successfully")
|
|
129
|
+
return current
|
|
130
|
+
|
|
131
|
+
def update_section(self, section: BaseAgentSection, content: str,
|
|
132
|
+
backup: bool = True) -> Optional[BaseAgentStructure]:
|
|
133
|
+
"""
|
|
134
|
+
Update a specific section of base_agent.md.
|
|
135
|
+
|
|
136
|
+
Args:
|
|
137
|
+
section: Section to update
|
|
138
|
+
content: New section content
|
|
139
|
+
backup: Whether to create backup
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
Updated BaseAgentStructure or None
|
|
143
|
+
"""
|
|
144
|
+
current = self.read_base_agent()
|
|
145
|
+
if not current:
|
|
146
|
+
return None
|
|
147
|
+
|
|
148
|
+
# Map sections to structure attributes
|
|
149
|
+
section_map = {
|
|
150
|
+
BaseAgentSection.FRAMEWORK_CONTEXT: "framework_context",
|
|
151
|
+
BaseAgentSection.BEHAVIORAL_RULES: "behavioral_rules",
|
|
152
|
+
BaseAgentSection.TEMPORAL_CONTEXT: "temporal_context",
|
|
153
|
+
BaseAgentSection.QUALITY_STANDARDS: "quality_standards",
|
|
154
|
+
BaseAgentSection.TOOL_USAGE: "tool_usage",
|
|
155
|
+
BaseAgentSection.COLLABORATION: "collaboration_protocols",
|
|
156
|
+
BaseAgentSection.PERFORMANCE: "performance_optimization",
|
|
157
|
+
BaseAgentSection.ESCALATION: "escalation_triggers",
|
|
158
|
+
BaseAgentSection.OUTPUT_FORMATS: "output_formats",
|
|
159
|
+
BaseAgentSection.FRAMEWORK_INTEGRATION: "framework_integration",
|
|
160
|
+
BaseAgentSection.CONSTRAINTS: "universal_constraints",
|
|
161
|
+
BaseAgentSection.SUCCESS_CRITERIA: "success_criteria"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if section in section_map:
|
|
165
|
+
attr_name = section_map[section]
|
|
166
|
+
|
|
167
|
+
# Parse content based on section type
|
|
168
|
+
if section in [BaseAgentSection.ESCALATION, BaseAgentSection.CONSTRAINTS,
|
|
169
|
+
BaseAgentSection.SUCCESS_CRITERIA]:
|
|
170
|
+
# List sections
|
|
171
|
+
parsed_content = self._parse_list_content(content)
|
|
172
|
+
setattr(current, attr_name, parsed_content)
|
|
173
|
+
elif section == BaseAgentSection.TEMPORAL_CONTEXT:
|
|
174
|
+
# String section
|
|
175
|
+
setattr(current, attr_name, content.strip())
|
|
176
|
+
else:
|
|
177
|
+
# Dictionary sections - preserve raw for now
|
|
178
|
+
current.raw_sections[section.value] = content
|
|
179
|
+
|
|
180
|
+
# Update and return
|
|
181
|
+
return self.update_base_agent({}, backup=backup)
|
|
182
|
+
|
|
183
|
+
def add_behavioral_rule(self, category: str, rule: str) -> bool:
|
|
184
|
+
"""Add a new behavioral rule to a specific category."""
|
|
185
|
+
current = self.read_base_agent()
|
|
186
|
+
if not current:
|
|
187
|
+
return False
|
|
188
|
+
|
|
189
|
+
if category not in current.behavioral_rules:
|
|
190
|
+
current.behavioral_rules[category] = []
|
|
191
|
+
|
|
192
|
+
if rule not in current.behavioral_rules[category]:
|
|
193
|
+
current.behavioral_rules[category].append(rule)
|
|
194
|
+
self.update_base_agent({"behavioral_rules": current.behavioral_rules})
|
|
195
|
+
return True
|
|
196
|
+
|
|
197
|
+
return False
|
|
198
|
+
|
|
199
|
+
def add_quality_standard(self, category: str, standard: str) -> bool:
|
|
200
|
+
"""Add a new quality standard to a specific category."""
|
|
201
|
+
current = self.read_base_agent()
|
|
202
|
+
if not current:
|
|
203
|
+
return False
|
|
204
|
+
|
|
205
|
+
if category not in current.quality_standards:
|
|
206
|
+
current.quality_standards[category] = []
|
|
207
|
+
|
|
208
|
+
if standard not in current.quality_standards[category]:
|
|
209
|
+
current.quality_standards[category].append(standard)
|
|
210
|
+
self.update_base_agent({"quality_standards": current.quality_standards})
|
|
211
|
+
return True
|
|
212
|
+
|
|
213
|
+
return False
|
|
214
|
+
|
|
215
|
+
def add_escalation_trigger(self, trigger: str) -> bool:
|
|
216
|
+
"""Add a new escalation trigger."""
|
|
217
|
+
current = self.read_base_agent()
|
|
218
|
+
if not current:
|
|
219
|
+
return False
|
|
220
|
+
|
|
221
|
+
if trigger not in current.escalation_triggers:
|
|
222
|
+
current.escalation_triggers.append(trigger)
|
|
223
|
+
self.update_base_agent({"escalation_triggers": current.escalation_triggers})
|
|
224
|
+
return True
|
|
225
|
+
|
|
226
|
+
return False
|
|
227
|
+
|
|
228
|
+
def validate_structure(self) -> Dict[str, bool]:
|
|
229
|
+
"""
|
|
230
|
+
Validate that base_agent.md has all required sections.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
Dictionary of section names to validation status
|
|
234
|
+
"""
|
|
235
|
+
current = self.read_base_agent()
|
|
236
|
+
if not current:
|
|
237
|
+
return {section.value: False for section in BaseAgentSection}
|
|
238
|
+
|
|
239
|
+
validation = {}
|
|
240
|
+
|
|
241
|
+
# Check each section
|
|
242
|
+
for section in BaseAgentSection:
|
|
243
|
+
if section == BaseAgentSection.FRAMEWORK_CONTEXT:
|
|
244
|
+
validation[section.value] = bool(current.framework_context)
|
|
245
|
+
elif section == BaseAgentSection.BEHAVIORAL_RULES:
|
|
246
|
+
validation[section.value] = bool(current.behavioral_rules)
|
|
247
|
+
elif section == BaseAgentSection.TEMPORAL_CONTEXT:
|
|
248
|
+
validation[section.value] = bool(current.temporal_context)
|
|
249
|
+
elif section == BaseAgentSection.QUALITY_STANDARDS:
|
|
250
|
+
validation[section.value] = bool(current.quality_standards)
|
|
251
|
+
elif section == BaseAgentSection.TOOL_USAGE:
|
|
252
|
+
validation[section.value] = bool(current.tool_usage)
|
|
253
|
+
elif section == BaseAgentSection.COLLABORATION:
|
|
254
|
+
validation[section.value] = bool(current.collaboration_protocols)
|
|
255
|
+
elif section == BaseAgentSection.PERFORMANCE:
|
|
256
|
+
validation[section.value] = bool(current.performance_optimization)
|
|
257
|
+
elif section == BaseAgentSection.ESCALATION:
|
|
258
|
+
validation[section.value] = bool(current.escalation_triggers)
|
|
259
|
+
elif section == BaseAgentSection.OUTPUT_FORMATS:
|
|
260
|
+
validation[section.value] = bool(current.output_formats)
|
|
261
|
+
elif section == BaseAgentSection.FRAMEWORK_INTEGRATION:
|
|
262
|
+
validation[section.value] = bool(current.framework_integration)
|
|
263
|
+
elif section == BaseAgentSection.CONSTRAINTS:
|
|
264
|
+
validation[section.value] = bool(current.universal_constraints)
|
|
265
|
+
elif section == BaseAgentSection.SUCCESS_CRITERIA:
|
|
266
|
+
validation[section.value] = bool(current.success_criteria)
|
|
267
|
+
|
|
268
|
+
return validation
|
|
269
|
+
|
|
270
|
+
# Private helper methods
|
|
271
|
+
|
|
272
|
+
def _parse_base_agent(self, content: str) -> BaseAgentStructure:
|
|
273
|
+
"""Parse base_agent.md content into structured format."""
|
|
274
|
+
structure = BaseAgentStructure()
|
|
275
|
+
|
|
276
|
+
# For now, store raw content in sections
|
|
277
|
+
# Full parsing implementation would extract structured data
|
|
278
|
+
lines = content.split('\n')
|
|
279
|
+
current_section = None
|
|
280
|
+
section_content = []
|
|
281
|
+
|
|
282
|
+
for line in lines:
|
|
283
|
+
if line.startswith('## '):
|
|
284
|
+
# Save previous section
|
|
285
|
+
if current_section:
|
|
286
|
+
structure.raw_sections[current_section] = '\n'.join(section_content)
|
|
287
|
+
|
|
288
|
+
# Start new section
|
|
289
|
+
current_section = line[3:].strip()
|
|
290
|
+
section_content = []
|
|
291
|
+
elif current_section:
|
|
292
|
+
section_content.append(line)
|
|
293
|
+
|
|
294
|
+
# Save last section
|
|
295
|
+
if current_section:
|
|
296
|
+
structure.raw_sections[current_section] = '\n'.join(section_content)
|
|
297
|
+
|
|
298
|
+
# Parse specific sections
|
|
299
|
+
if BaseAgentSection.ESCALATION.value in structure.raw_sections:
|
|
300
|
+
structure.escalation_triggers = self._parse_list_content(
|
|
301
|
+
structure.raw_sections[BaseAgentSection.ESCALATION.value]
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
return structure
|
|
305
|
+
|
|
306
|
+
def _structure_to_markdown(self, structure: BaseAgentStructure) -> str:
|
|
307
|
+
"""Convert BaseAgentStructure back to markdown format."""
|
|
308
|
+
lines = []
|
|
309
|
+
|
|
310
|
+
# Header
|
|
311
|
+
lines.append(f"# {structure.title}")
|
|
312
|
+
lines.append("")
|
|
313
|
+
lines.append("<!-- ")
|
|
314
|
+
lines.append(structure.description)
|
|
315
|
+
lines.append("They contain common rules, behaviors, and constraints that apply to ALL agents.")
|
|
316
|
+
lines.append("-->")
|
|
317
|
+
lines.append("")
|
|
318
|
+
|
|
319
|
+
# Write sections from raw content (preserves formatting)
|
|
320
|
+
for section in BaseAgentSection:
|
|
321
|
+
if section.value in structure.raw_sections:
|
|
322
|
+
lines.append(f"## {section.value}")
|
|
323
|
+
lines.append(structure.raw_sections[section.value])
|
|
324
|
+
lines.append("")
|
|
325
|
+
|
|
326
|
+
return '\n'.join(lines)
|
|
327
|
+
|
|
328
|
+
def _parse_list_content(self, content: str) -> List[str]:
|
|
329
|
+
"""Parse list items from markdown content."""
|
|
330
|
+
items = []
|
|
331
|
+
for line in content.split('\n'):
|
|
332
|
+
line = line.strip()
|
|
333
|
+
if line.startswith('- '):
|
|
334
|
+
items.append(line[2:].strip())
|
|
335
|
+
elif line.startswith('* '):
|
|
336
|
+
items.append(line[2:].strip())
|
|
337
|
+
elif line.startswith('**') and line.endswith('**'):
|
|
338
|
+
# Skip bold headers
|
|
339
|
+
continue
|
|
340
|
+
return items
|
|
341
|
+
|
|
342
|
+
def _create_backup(self) -> Path:
|
|
343
|
+
"""Create a timestamped backup of base_agent.md."""
|
|
344
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
345
|
+
backup_path = self.base_agent_path.parent / f"base_agent_{timestamp}.backup"
|
|
346
|
+
|
|
347
|
+
if self.base_agent_path.exists():
|
|
348
|
+
content = self.base_agent_path.read_text(encoding='utf-8')
|
|
349
|
+
backup_path.write_text(content, encoding='utf-8')
|
|
350
|
+
logger.info(f"Created backup at {backup_path}")
|
|
351
|
+
|
|
352
|
+
return backup_path
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# Convenience functions
|
|
356
|
+
def get_base_agent_manager() -> BaseAgentManager:
|
|
357
|
+
"""Get a configured BaseAgentManager instance."""
|
|
358
|
+
return BaseAgentManager()
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def update_base_agent_section(section: BaseAgentSection, content: str) -> bool:
|
|
362
|
+
"""
|
|
363
|
+
Quick function to update a base agent section.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
section: Section to update
|
|
367
|
+
content: New content for the section
|
|
368
|
+
|
|
369
|
+
Returns:
|
|
370
|
+
True if successful, False otherwise
|
|
371
|
+
"""
|
|
372
|
+
manager = get_base_agent_manager()
|
|
373
|
+
result = manager.update_section(section, content)
|
|
374
|
+
return result is not None
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def validate_base_agent() -> Dict[str, bool]:
|
|
378
|
+
"""Quick function to validate base agent structure."""
|
|
379
|
+
manager = get_base_agent_manager()
|
|
380
|
+
return manager.validate_structure()
|