magicciv/tools/sprite-generation/monitor_pipeline.py

118 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Pipeline monitor — tracks tier progression and reports when Opus has candidates."""
import sqlite3
import time
import sys
from pathlib import Path
from datetime import datetime
DB_PATH = Path("spritegen.db")
def get_tier_status():
"""Get current tier progression status."""
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
# Get sprites in review + their tier progression
rows = conn.execute("""
SELECT
sprite_id,
COUNT(*) as total_variants,
SUM(CASE WHEN COALESCE(review_tier, 0) >= 0 THEN 1 ELSE 0 END) as tier0_scored,
SUM(CASE WHEN COALESCE(review_tier, 0) >= 1 THEN 1 ELSE 0 END) as tier1_scored,
SUM(CASE WHEN COALESCE(review_tier, 0) >= 2 THEN 1 ELSE 0 END) as tier2_scored,
SUM(CASE WHEN COALESCE(review_tier, 0) >= 3 THEN 1 ELSE 0 END) as fully_approved
FROM variants
WHERE job_status='completed' AND raw_path IS NOT NULL
GROUP BY sprite_id
ORDER BY tier2_scored DESC, tier1_scored DESC, tier0_scored DESC
""").fetchall()
conn.close()
return [dict(r) for r in rows]
def get_opus_candidates(sprite_id):
"""Get top 3 variants that passed through Opus (tier 2+)."""
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
# Get best 3 variants from tier 2 (Opus)
rows = conn.execute("""
SELECT
v.id, v.sprite_id, v.seed, v.rating, v.notes,
COALESCE(v.review_tier, 0) as review_tier
FROM variants v
WHERE v.sprite_id = ?
AND v.job_status = 'completed'
AND v.raw_path IS NOT NULL
AND COALESCE(v.review_tier, 0) >= 2
AND COALESCE(v.rating, 0) > 0
ORDER BY COALESCE(v.rating, 0) DESC
LIMIT 3
""", (sprite_id,)).fetchall()
conn.close()
return [dict(r) for r in rows]
def main():
print("\n" + "="*80)
print("SPRITE PIPELINE MONITOR — Tier Progression Tracker")
print("="*80)
opus_ready = {}
check_count = 0
while True:
status = get_tier_status()
# Group by tier progress
in_vlm = [s for s in status if s['tier0_scored'] > 0 and s['tier1_scored'] == 0]
in_haiku = [s for s in status if s['tier1_scored'] > 0 and s['tier2_scored'] == 0]
in_opus = [s for s in status if s['tier2_scored'] > 0 and s['fully_approved'] == 0]
ready_user = [s for s in status if s['fully_approved'] > 0]
timestamp = datetime.now().strftime("%H:%M:%S")
check_count += 1
# Print status summary
print(f"\n[{timestamp}] Check #{check_count} — Tier Progression:")
print(f" VLM (tier 0): {len(in_vlm)} sprites scoring")
print(f" Haiku (tier 1): {len(in_haiku)} sprites scoring")
print(f" Opus (tier 2): {len(in_opus)} sprites in review")
print(f" Ready for user: {len(ready_user)} sprites with candidates")
# Show Opus progress
if in_opus:
print(f"\n Opus candidates in progress:")
for s in in_opus:
print(f" {s['sprite_id']}: {s['tier2_scored']}/{s['total_variants']} in tier 2")
# Check for newly ready sprites (3+ candidates at tier 2)
new_ready = []
for s in in_opus + ready_user:
candidates = get_opus_candidates(s['sprite_id'])
if len(candidates) >= 3 and s['sprite_id'] not in opus_ready:
opus_ready[s['sprite_id']] = candidates
new_ready.append((s['sprite_id'], candidates))
if new_ready:
print(f"\n{'='*80}")
print(f"🎯 OPUS READY! {len(new_ready)} sprite(s) have 3 candidates for user final review:")
print(f"{'='*80}")
for sprite_id, candidates in new_ready:
print(f"\n{sprite_id}:")
for i, cand in enumerate(candidates, 1):
print(f" {i}. variant {cand['id']} (seed {cand['seed']}, rating {cand['rating']:.1f}/5)")
if len(opus_ready) > 0:
print(f"\n📊 Accumulated {len(opus_ready)} sprites ready for final review.")
sys.stdout.flush()
time.sleep(30) # Check every 30 seconds
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\nMonitor stopped.")
sys.exit(0)