Add ReflectionEngine

This commit is contained in:
2026-03-22 23:30:15 +00:00
parent b41bd7aa56
commit 066e8bbb9c

82
src/timmy/reflection.py Normal file
View File

@@ -0,0 +1,82 @@
import logging
from datetime import UTC, datetime, timedelta
from typing import List, Optional
from sqlalchemy.orm import Session
from dashboard.models.database import SessionLocal
from dashboard.models.calm import Task, JournalEntry
from dashboard.models.reflection import Reflection
from integrations.llm.ollama import query_ollama
logger = logging.getLogger(__name__)
class ReflectionEngine:
"""Engine for Timmy's self-reflection loop."""
async def reflect_once(self) -> Optional[Reflection]:
"""Review recent activity and generate a reflection."""
logger.info("Starting self-reflection cycle...")
db = SessionLocal()
try:
# 1. Gather context
now = datetime.now(UTC)
since = now - timedelta(hours=24)
recent_tasks = db.query(Task).filter(Task.updated_at >= since).all()
recent_journal = db.query(JournalEntry).filter(JournalEntry.created_at >= since).first()
# 2. Build prompt
context = f"Recent Tasks: {[t.title for t in recent_tasks]}\n"
if recent_journal:
context += f"Journal: {recent_journal.evening_reflection}\n"
prompt = f"""
You are Timmy, an AI agent. Review your recent activity and provide a short, insightful self-reflection.
Focus on what you've achieved, what you've missed, and how you're feeling about your current progress.
Context:
{context}
Output format:
Reflection: [Your reflection text]
Sentiment: [positive/neutral/negative]
Focus Area: [e.g., Productivity, Health, Learning]
"""
# 3. Query LLM
response = await query_ollama(prompt)
# 4. Parse and save
reflection_text = ""
sentiment = "neutral"
focus_area = "General"
for line in response.split("\n"):
if line.startswith("Reflection:"):
reflection_text = line.replace("Reflection:", "").strip()
elif line.startswith("Sentiment:"):
sentiment = line.replace("Sentiment:", "").strip().lower()
elif line.startswith("Focus Area:"):
focus_area = line.replace("Focus Area:", "").strip()
if reflection_text:
reflection = Reflection(
content=reflection_text,
sentiment=sentiment,
focus_area=focus_area
)
db.add(reflection)
db.commit()
db.refresh(reflection)
logger.info("Self-reflection saved: %s", reflection_text[:50])
return reflection
except Exception as exc:
logger.error("Reflection error: %s", exc)
finally:
db.close()
return None
reflection_engine = ReflectionEngine()