Initial commit: Natiris AI Agent Orchestration System

This commit is contained in:
Arch Agent
2026-03-01 14:28:26 +01:00
commit 3b5f6ba83d
3127 changed files with 86184 additions and 0 deletions

View File

@@ -0,0 +1,370 @@
#!/usr/bin/env python3
"""
Natiris Recovery Agent Status-Tracker und Wiederanlauf
Überwacht den Projektstatus und ermöglicht nahtlose Fortsetzung
Features:
- Status-Tracking nach jedem Schritt
- Checkpoint-System für Unterbrechungen
- Automatischer Resume nach Token-Limit/Neustart
- Fortschrittsbericht generierung
"""
import json
import os
import sys
import time
from datetime import datetime
from pathlib import Path
PROJECT_ROOT = os.path.expanduser("~/natiris")
STATE_FILE = os.path.join(PROJECT_ROOT, "agent_state.json")
CHECKPOINT_FILE = os.path.join(PROJECT_ROOT, "checkpoints", "latest.json")
try:
import requests
except ImportError:
requests = None
def log(msg, level="INFO"):
"""Log mit Timestamp"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] [{level}] {msg}")
# Auch in Log-Datei
log_file = os.path.join(PROJECT_ROOT, "agent_recovery.log")
with open(log_file, "a") as f:
f.write(f"[{timestamp}] [{level}] {msg}\n")
class NatirisRecoveryAgent:
"""
Verwaltet den Zustand des Natiris-Projekts
und ermöglicht Wiederanlauf nach Unterbrechungen
"""
def __init__(self):
self.project_root = Path(PROJECT_ROOT)
self.checkpoints_dir = self.project_root / "checkpoints"
self.checkpoints_dir.mkdir(exist_ok=True)
# Aktueller Zustand
self.state = self.load_state()
# Task-Queue (was als nächstes zu tun ist)
self.task_queue = []
def load_state(self):
"""Lädt den aktuellen Agent-State"""
if os.path.exists(STATE_FILE):
try:
with open(STATE_FILE) as f:
return json.load(f)
except:
return self.get_default_state()
return self.get_default_state()
def get_default_state(self):
"""Standard-Zustand für neuen Start"""
return {
"phase": "initialization",
"last_action": None,
"last_action_time": None,
"completed_tasks": [],
"pending_tasks": [
"update_comfybridge_with_ipadapter",
"test_ipadapter_integration",
"integrate_vision_loop",
"optimize_natural_language",
"final_testing",
"documentation"
],
"checkpoint_count": 0,
"last_error": None,
"session_count": 0
}
def save_state(self):
"""Speichert aktuellen Zustand"""
self.state["last_action_time"] = datetime.now().isoformat()
with open(STATE_FILE, "w") as f:
json.dump(self.state, f, indent=2)
# Zusätzlich als Checkpoint
checkpoint_id = self.state.get("checkpoint_count", 0) + 1
checkpoint_file = self.checkpoints_dir / f"checkpoint_{checkpoint_id:04d}.json"
with open(checkpoint_file, "w") as f:
json.dump(self.state, f, indent=2)
self.state["checkpoint_count"] = checkpoint_id
log(f"State saved (checkpoint {checkpoint_id})")
def mark_task_complete(self, task_name, details=None):
"""Markiert eine Task als abgeschlossen"""
if task_name in self.state["pending_tasks"]:
self.state["pending_tasks"].remove(task_name)
completion_entry = {
"task": task_name,
"completed_at": datetime.now().isoformat(),
"details": details or {}
}
self.state["completed_tasks"].append(completion_entry)
self.state["last_action"] = f"completed_{task_name}"
log(f"Task completed: {task_name}")
self.save_state()
def set_phase(self, phase_name):
"""Setzt aktuelle Phase"""
self.state["phase"] = phase_name
self.state["last_action"] = f"phase_change_{phase_name}"
log(f"Phase changed to: {phase_name}")
self.save_state()
def record_error(self, error_msg):
"""Speichert Fehler für spätere Analyse"""
self.state["last_error"] = {
"message": str(error_msg),
"timestamp": datetime.now().isoformat(),
"phase": self.state["phase"]
}
self.save_state()
log(f"ERROR recorded: {error_msg}", level="ERROR")
def get_next_task(self):
"""Liefert nächste zu erledigende Task"""
if self.state["pending_tasks"]:
return self.state["pending_tasks"][0]
return None
def get_progress_report(self):
"""Generiert Fortschrittsbericht"""
total = len(self.state["completed_tasks"]) + len(self.state["pending_tasks"])
completed = len(self.state["completed_tasks"])
if total > 0:
percent = (completed / total) * 100
else:
percent = 0
report = f"""
╔══════════════════════════════════════════════════════════════╗
║ NATIRIS RECOVERY AGENT - STATUS REPORT ║
╠══════════════════════════════════════════════════════════════╣
║ Current Phase: {self.state['phase']:<38}
║ Last Action: {str(self.state['last_action'])[:38]:<38}
║ Checkpoints: {self.state['checkpoint_count']:<38}
║ Progress: {completed}/{total} ({percent:.1f}%) {'' * int(percent/5):<20}
╠══════════════════════════════════════════════════════════════╣
║ PENDING TASKS: ║
"""
for i, task in enumerate(self.state["pending_tasks"][:5], 1):
report += f"{i}. {task[:50]:<51}\n"
if len(self.state["pending_tasks"]) > 5:
report += f"║ ... and {len(self.state['pending_tasks']) - 5} more{'':<36}\n"
report += """╠══════════════════════════════════════════════════════════════╣
║ RECENTLY COMPLETED: ║
"""
recent = self.state["completed_tasks"][-3:]
for entry in recent:
task = entry["task"]
time_str = entry["completed_at"][11:19] # HH:MM:SS
report += f"║ ✓ {task[:20]:<20} at {time_str:<24}\n"
if not recent:
report += f"║ (none yet){'':<47}\n"
report += """╚══════════════════════════════════════════════════════════════╝
"""
return report
def generate_resume_instructions(self):
"""Generiert Befehle für Wiederanlauf"""
next_task = self.get_next_task()
instructions = f"""
╔══════════════════════════════════════════════════════════════╗
║ NATIRIS RESUME INSTRUCTIONS ║
╠══════════════════════════════════════════════════════════════╣
Current Status:
Phase: {self.state['phase']}
Last Action: {self.state['last_action']}
Pending Tasks: {len(self.state['pending_tasks'])}
NEXT IMMEDIATE TASK:
{next_task or 'ALL TASKS COMPLETED'}
QUICK START COMMANDS:
"""
if next_task == "update_comfybridge_with_ipadapter":
instructions += """
1. Update ComfyBridge with correct IPAdapter paths:
cd ~/natiris && nano bridges/ComfyBridge.py
- Update MODEL_PATHS with correct paths
- Test with: python3 bridges/ComfyBridge.py --test
2. Verify IPAdapter models exist:
ls /opt/pinokio/drive/drives/peers/d1753059260169/ipadapter/
"""
elif next_task == "test_ipadapter_integration":
instructions += """
1. Generate test image with IPAdapter:
cd ~/natiris && python3 bridges/ComfyBridge.py --test
2. Check if image was generated with face consistency:
ls -la ~/natiris/generated/
"""
elif next_task == "integrate_vision_loop":
instructions += """
1. Connect VisionBridge to Core:
- Update Orchestrator to trigger Vision after ComfyBridge
- Test full loop: Text → Image → Vision → Response
2. Verify state updates:
cat ~/natiris/core/natiris_full_state.json
"""
instructions += """
TO CONTINUE WHERE YOU LEFT OFF:
python3 ~/natiris/agents/natiris_recovery_agent.py --resume
TO CHECK STATUS:
python3 ~/natiris/agents/natiris_recovery_agent.py --status
═══════════════════════════════════════════════════════════════
"""
return instructions
def create_recovery_script(self):
"""Erstellt Recovery-Skript für automatischen Wiederanlauf"""
script_path = self.project_root / "resume_natiris.sh"
script_content = """#!/bin/bash
# Natiris Auto-Recovery Script
# Generated by Recovery Agent
echo "╭────────────────────────────────────────────────────────────╮"
echo "│ NATIRIS PROJECT RESUMER │"
echo "╰────────────────────────────────────────────────────────────╯"
echo ""
# Check if state exists
if [ -f ~/natiris/agent_state.json ]; then
echo "📋 Found existing state - loading progress..."
python3 ~/natiris/agents/natiris_recovery_agent.py --resume
else
echo "⚠️ No state found - starting fresh..."
python3 ~/natiris/agents/natiris_recovery_agent.py --init
fi
"""
with open(script_path, "w") as f:
f.write(script_content)
# Make executable
os.chmod(script_path, 0o755)
log(f"Recovery script created: {script_path}")
return str(script_path)
def monitor_and_track(self):
"""Haupt-Monitoring-Loop (kann im Hintergrund laufen)"""
log("Recovery Agent started - monitoring project...")
while True:
# Speichere State regelmäßig
self.save_state()
# Prüfe auf Probleme (z.B. Prozesse, Dateien)
self.check_system_health()
time.sleep(30) # Alle 30 Sekunden
def check_system_health(self):
"""Prüft System-Health"""
issues = []
# Prüfe ComfyUI
try:
import requests
resp = requests.get("http://localhost:8188/system_stats", timeout=2)
if resp.status_code != 200:
issues.append("ComfyUI not responding properly")
except:
issues.append("ComfyUI unreachable")
# Prüfe Ollama
try:
resp = requests.get("http://localhost:11434/api/tags", timeout=2)
if resp.status_code != 200:
issues.append("Ollama not responding")
except:
issues.append("Ollama unreachable")
if issues:
log(f"System health issues: {', '.join(issues)}", level="WARN")
return len(issues) == 0
def main():
"""CLI Entry Point"""
import argparse
parser = argparse.ArgumentParser(description="Natiris Recovery Agent")
parser.add_argument("--status", action="store_true", help="Show status report")
parser.add_argument("--resume", action="store_true", help="Resume from last checkpoint")
parser.add_argument("--init", action="store_true", help="Initialize new state")
parser.add_argument("--complete", help="Mark task as complete")
parser.add_argument("--phase", help="Set current phase")
parser.add_argument("--create-recovery", action="store_true", help="Create recovery script")
parser.add_argument("--monitor", action="store_true", help="Start monitoring mode")
args = parser.parse_args()
agent = NatirisRecoveryAgent()
if args.status:
print(agent.get_progress_report())
elif args.resume:
print(agent.get_progress_report())
print("\n" + "="*60)
print(agent.generate_resume_instructions())
elif args.init:
agent.state = agent.get_default_state()
agent.state["session_count"] = 1
agent.save_state()
log("Initialized fresh state")
print("✓ Fresh state initialized")
elif args.complete:
agent.mark_task_complete(args.complete)
print(f"✓ Marked as complete: {args.complete}")
elif args.phase:
agent.set_phase(args.phase)
print(f"✓ Phase set to: {args.phase}")
elif args.create_recovery:
script = agent.create_recovery_script()
print(f"✓ Recovery script created: {script}")
print(f"\nTo use: ./{script}")
elif args.monitor:
agent.monitor_and_track()
else:
# Default: show status
print(agent.get_progress_report())
print("\nUse --resume to see continuation instructions")
if __name__ == "__main__":
main()