Files
luzia/lib/maintenance_orchestrator.py
admin ec33ac1936 Refactor cockpit to use DockerTmuxController pattern
Based on claude-code-tools TmuxCLIController, this refactor:

- Added DockerTmuxController class for robust tmux session management
- Implements send_keys() with configurable delay_enter
- Implements capture_pane() for output retrieval
- Implements wait_for_prompt() for pattern-based completion detection
- Implements wait_for_idle() for content-hash-based idle detection
- Implements wait_for_shell_prompt() for shell prompt detection

Also includes workflow improvements:
- Pre-task git snapshot before agent execution
- Post-task commit protocol in agent guidelines

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 10:42:16 -03:00

188 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""
Maintenance Orchestrator
Coordinates all maintenance operations across systems:
- KG maintenance
- Conductor cleanup
- Context tuning
- Summary reporting
"""
import time
from typing import List, Dict
from kg_maintainer import KGMaintainer
from conductor_maintainer import ConductorMaintainer
from context_maintainer import ContextMaintainer
class MaintenanceOrchestrator:
"""Orchestrate all system maintenance operations."""
def __init__(self):
"""Initialize maintenance orchestrator."""
self.kg_maintainer = KGMaintainer()
self.conductor_maintainer = ConductorMaintainer()
self.context_maintainer = ContextMaintainer()
def run_full_system_maintenance(self, dry_run: bool = True) -> Dict:
"""
Run comprehensive system maintenance.
Args:
dry_run: If True, preview only
Returns:
Dict with maintenance summary
"""
result = {
'timestamp': time.time(),
'dry_run': dry_run,
'status': 'success',
'modules': {},
'total_space_freed_mb': 0,
'actions_completed': []
}
# 1. KG Maintenance
kg_result = self.kg_maintainer.run_full_kg_maintenance(dry_run=dry_run)
result['modules']['kg'] = {
'duplicates_found': kg_result['duplicates_found'],
'duplicates_merged': kg_result['duplicates_merged'],
'indexes_optimized': kg_result['indexes_optimized'],
'relations_strengthened': kg_result['relations_strengthened'],
'status': 'success'
}
result['actions_completed'].append(f"KG: Merged {kg_result['duplicates_merged']} duplicates")
# 2. Conductor Maintenance
conductor_result = self.conductor_maintainer.run_full_conductor_maintenance(dry_run=dry_run)
result['modules']['conductor'] = conductor_result['summary']
result['total_space_freed_mb'] += conductor_result['summary'].get('space_freed_mb', 0)
result['total_space_freed_mb'] += conductor_result['summary'].get('space_freed_temp_mb', 0)
result['actions_completed'].append(
f"Conductor: Archived {conductor_result['summary']['tasks_archived']} tasks, "
f"freed {conductor_result['summary']['space_freed_mb']:.1f}MB"
)
# 3. Context Maintenance
context_result = self.context_maintainer.run_full_context_maintenance(dry_run=dry_run)
result['modules']['context'] = {
'performance_metrics': context_result.get('performance_metrics', {}),
'actions': context_result['actions_completed'],
'status': 'success'
}
result['actions_completed'].append(f"Context: Tuned retrieval and buckets")
return result
def run_kg_only_maintenance(self, dry_run: bool = True) -> Dict:
"""Run KG maintenance only."""
result = self.kg_maintainer.run_full_kg_maintenance(dry_run=dry_run)
return {
'module': 'kg',
'result': result,
'timestamp': time.time()
}
def run_conductor_only_maintenance(self, dry_run: bool = True) -> Dict:
"""Run conductor maintenance only."""
result = self.conductor_maintainer.run_full_conductor_maintenance(dry_run=dry_run)
return {
'module': 'conductor',
'result': result,
'timestamp': time.time()
}
def run_context_only_maintenance(self, dry_run: bool = True) -> Dict:
"""Run context maintenance only."""
result = self.context_maintainer.run_full_context_maintenance(dry_run=dry_run)
return {
'module': 'context',
'result': result,
'timestamp': time.time()
}
def run_targeted_maintenance(self, target: str, dry_run: bool = True) -> Dict:
"""
Run targeted maintenance on specific subsystem.
Args:
target: 'kg' | 'conductor' | 'context' | 'all'
dry_run: If True, preview only
Returns:
Maintenance result
"""
if target == 'kg':
return self.run_kg_only_maintenance(dry_run=dry_run)
elif target == 'conductor':
return self.run_conductor_only_maintenance(dry_run=dry_run)
elif target == 'context':
return self.run_context_only_maintenance(dry_run=dry_run)
elif target == 'all':
return self.run_full_system_maintenance(dry_run=dry_run)
else:
return {
'error': f'Unknown target: {target}',
'valid_targets': ['kg', 'conductor', 'context', 'all']
}
def generate_maintenance_report(self, maintenance_data: Dict) -> str:
"""
Generate formatted maintenance report.
Args:
maintenance_data: Result from maintenance operation
Returns:
Formatted report string
"""
import datetime
timestamp = datetime.datetime.fromtimestamp(maintenance_data['timestamp']).strftime('%Y-%m-%d %H:%M UTC')
report = f"""
╔════════════════════════════════════════════════════════════════════╗
║ SYSTEM MAINTENANCE REPORT ║
{timestamp:42}
╚════════════════════════════════════════════════════════════════════╝
MODE: {'DRY RUN (preview only)' if maintenance_data['dry_run'] else 'ACTUAL (changes applied)'}
STATUS: {maintenance_data['status'].upper()}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ACTIONS COMPLETED:
"""
for action in maintenance_data['actions_completed']:
report += f"{action}\n"
if 'total_space_freed_mb' in maintenance_data:
report += f"\nSpace Freed: {maintenance_data['total_space_freed_mb']:.1f}MB\n"
report += f"\n{'' * 70}\n"
return report
if __name__ == '__main__':
orchestrator = MaintenanceOrchestrator()
print("=" * 70)
print("FULL SYSTEM MAINTENANCE DRY RUN")
print("=" * 70)
result = orchestrator.run_full_system_maintenance(dry_run=True)
print(orchestrator.generate_maintenance_report(result))
print("\nDetailed Results by Module:")
for module, data in result['modules'].items():
print(f"\n{module.upper()}:")
for key, value in data.items():
if key != 'status':
print(f" {key}: {value}")