Files
luzia/luzia_research_agent.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

170 lines
5.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Luzia Research Agent Loop - Interactive Research Task Processing
Continuously monitors incoming research tasks and routes them intelligently
based on security, speed, and complexity filters.
Can run in:
- Interactive mode: Process individual tasks
- Loop mode: Monitor queue continuously (default)
"""
import sys
import json
import time
from pathlib import Path
from datetime import datetime
sys.path.insert(0, '/opt/server-agents/orchestrator/lib')
from research_agent import LuziaResearchAgent, TaskFilter, ToolRouter
def run_interactive():
"""Interactive mode: process user input"""
agent = LuziaResearchAgent()
print("\n" + "=" * 70)
print("🔬 LUZIA RESEARCH AGENT - INTERACTIVE MODE")
print("=" * 70)
print("\nEnter research tasks to analyze. Type 'exit' to quit.\n")
while True:
try:
task = input("📋 Research task: ").strip()
if task.lower() in ['exit', 'quit', 'q']:
print("✅ Exiting research agent")
break
if not task:
print("⚠️ Empty task, try again\n")
continue
# Process the task
result = agent.process_research_task(task)
print(f"\n{result['analysis']['routing_summary']}")
if result['clarification']:
print("❓ Clarification Questions:")
for q in result['clarification']['questions']:
print(f" {q}")
print()
except KeyboardInterrupt:
print("\n✅ Exiting research agent")
break
except Exception as e:
print(f"❌ Error: {e}\n")
def run_continuous():
"""Continuous loop mode: monitor and process tasks"""
agent = LuziaResearchAgent()
queue_file = Path("/opt/server-agents/state/research-queue.json")
agent.log("🔬 Luzia Research Agent started (continuous mode)")
while True:
try:
# Check if queue file exists
if not queue_file.exists():
time.sleep(10)
continue
# Read queue
with open(queue_file) as f:
queue_data = json.load(f)
pending = queue_data.get('pending', [])
if not pending:
time.sleep(10)
continue
# Process first pending task
task_entry = pending[0]
task_id = task_entry.get('id', str(uuid.uuid4()))
task = task_entry.get('task', '')
agent.log(f"📥 Processing task {task_id}: {task[:50]}...")
# Analyze and route
result = agent.process_research_task(task)
# Move to processed
queue_data['pending'].pop(0)
queue_data['processed'] = queue_data.get('processed', [])
queue_data['processed'].append({
'id': task_id,
'task': task,
'timestamp': datetime.now().isoformat(),
'analysis': result['analysis'],
'status': result['status'],
})
# Write back
with open(queue_file, 'w') as f:
json.dump(queue_data, f, indent=2)
agent.log(f"✅ Processed: {task[:50]}... → {result['analysis']['recommended_tool']}")
# Brief sleep between tasks
time.sleep(2)
except KeyboardInterrupt:
agent.log("🛑 Research agent stopped by user")
break
except Exception as e:
agent.log(f"❌ Error in loop: {e}")
time.sleep(5)
def show_demo():
"""Show demonstration of smart filtering"""
agent = LuziaResearchAgent()
demo_tasks = [
("quick answer: what is REST?", "Simple question, no urgency"),
("urgent critical vulnerability in auth system", "Critical security, needs immediate review"),
("research distributed caching approaches and tradeoffs", "Complex decision, needs exploration"),
("debug: zen-proxy max_tokens not working", "Error diagnosis, straightforward"),
("design: REST vs GraphQL for new API", "Architecture decision, multiple perspectives"),
]
print("\n" + "=" * 80)
print("🔬 LUZIA RESEARCH AGENT - SMART FILTER DEMONSTRATION")
print("=" * 80)
for task, context in demo_tasks:
print(f"\n📋 Task: {task}")
print(f" Context: {context}")
print(" " + "-" * 70)
analysis = agent.analyze_task(task)
print(f" Security: {analysis['security']}")
print(f" Speed: {analysis['speed']}")
print(f" Complexity: {analysis['complexity']}")
print(f" → Tool: {analysis['recommended_tool']}")
print(f" Reason: {analysis['reasoning']}")
if __name__ == "__main__":
if len(sys.argv) > 1:
if sys.argv[1] == "--demo":
show_demo()
elif sys.argv[1] == "--interactive":
run_interactive()
elif sys.argv[1] == "--continuous":
run_continuous()
else:
print("Usage:")
print(" luzia_research_agent.py --demo Show demonstration")
print(" luzia_research_agent.py --interactive Interactive mode")
print(" luzia_research_agent.py --continuous Continuous queue monitoring")
else:
# Default: interactive mode
run_interactive()