"""Daily job: proactive review for all users with stored data.""" import asyncio import json import logging from anthropic import AsyncAnthropic from sqlalchemy import select from app.config import settings from app.database import async_session_factory from app.models.user import User from app.services.memory_service import get_critical_memories from app.services.notification_service import create_notification from app.services.ws_manager import manager logger = logging.getLogger(__name__) client = AsyncAnthropic(api_key=settings.ANTHROPIC_API_KEY) async def run_daily_review(): """Review each user's profile and generate reminder notifications.""" if not settings.ANTHROPIC_API_KEY: return async with async_session_factory() as db: result = await db.execute(select(User).where(User.is_active == True)) # noqa: E712 users = result.scalars().all() for user in users: try: await _review_user(user) await asyncio.sleep(1) # Rate limit except Exception: logger.exception(f"Daily review failed for user {user.id}") async def _review_user(user: User): async with async_session_factory() as db: memories = await get_critical_memories(db, user.id) if not memories: return memory_text = "\n".join(f"- [{m.category}] {m.title}: {m.content}" for m in memories) response = await client.messages.create( model=settings.CLAUDE_MODEL, max_tokens=500, system="You are a personal assistant. Based on the user's stored information, suggest any upcoming actions, deadlines, follow-ups, or reminders that would be helpful. Respond with a JSON array of objects with 'title' and 'body' fields. If no reminders are needed, return an empty array [].", messages=[{"role": "user", "content": f"User profile data:\n{memory_text}"}], ) try: text = response.content[0].text.strip() if "[" in text: json_str = text[text.index("["):text.rindex("]") + 1] reminders = json.loads(json_str) else: return except (json.JSONDecodeError, ValueError): return for reminder in reminders[:5]: if "title" in reminder and "body" in reminder: notif = await create_notification( db, user.id, title=reminder["title"], body=reminder["body"], type="ai_generated", ) await db.commit() from app.workers.notification_sender import _serialize_notification await manager.send_to_user(user.id, { "type": "new_notification", "notification": _serialize_notification(notif), })