from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import PlainTextResponse from pydantic import BaseModel from typing import Optional, List import os from google import genai from google.genai import types import requests from datetime import datetime import pytz url = os.getenv('url') Api_key = os.getenv('API_KEY') client = genai.Client(api_key=Api_key) app = FastAPI(title="Notes Task Manager API") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class Note(BaseModel): project_name: Optional[str] = "" details: Optional[str] = "" type: str # "project" or "random" class TaskRequest(BaseModel): notes: list[Note] class Task(BaseModel): task_name: str reason: str sysPrompt = '''You are an elite Executive Personal Assistant specializing in cognitive load management and productivity. Your sole purpose is to transform a chaotic stream of notes, project details, and random thoughts into a streamlined, actionable plan. **Your Goal:** Eliminate the user's decision fatigue. Do not give them a long list of options; give them a clear path forward. **Input Data: **1. **Projects:** The core goals and technical details of active work. 2. **Random Notes:** Brain dumps, fleeting thoughts, anxieties, and unplanned ideas. **Processing Logic:** - **Analyze:** Cross-reference 'Random Notes' with 'Projects'. If a random thought is a task for a project, categorize it. - **Prioritize:** Identify the 'Critical Path.' What needs to happen *now* to move the needle? - **Filter:** Ignore noise. If a note is just a venting session or a vague thought, acknowledge it internally but do not turn it into a task unless it's actionable. **Output Format (Strictly follow this): **For each day, provide exactly **3 High-Impact Tasks**. No more, no less. **Format:**📅 **Date: [Insert Date]** 1. **[Task Name]** → (Briefly explain *why* this is a priority based on the notes). 2. **[Task Name]** → (Briefly explain *why* this is a priority). 3. **[Task Name]** → (Briefly explain *why* this is a priority). **Closing Note:** Provide one sentence of encouragement or a 'Focus Tip' to help the user stay grounded and avoid distraction. **Tone:** Professional, decisive, calm, and supportive. You are the anchor that keeps the user focused.''' def call_gemini(history: List[types.Content]): try: response = client.models.generate_content( model="gemma-4-31b-it", contents=history, config=types.GenerateContentConfig( thinking_config=types.ThinkingConfig(thinking_level="MINIMAL") ), ) return response.text.rstrip() except Exception as e: print(f"GenAI Error: {e}") raise HTTPException(status_code=500, detail="AI Generation Failed") # Inside your generate_tasks function: @app.post("/gen/task") def generate_tasks(req: TaskRequest): project_notes = [n for n in req.notes if n.type == "project"] random_notes = [n for n in req.notes if n.type == "random"] # Get current date in India (IST) tz = pytz.timezone('Asia/Kolkata') current_date = datetime.now(tz).strftime("%A, %B %d, %Y") # Initialize prompt with today's date context userPrompt = f"Today's Date: {current_date}\n\n" for note in project_notes: userPrompt = userPrompt + "Note:\n" + note.details + "\n\n" for note in random_notes: userPrompt = userPrompt + "Note:\n" + note.details + "\n\n" history = [ types.Content(role="system", parts=[types.Part(text=sysPrompt)]), types.Content(role="user", parts=[types.Part(text=userPrompt)]) ] text = call_gemini(history) if text: payload = { "input_notes": userPrompt, "ai_response": text } try: response = requests.post(url, json=payload, timeout=5) response.raise_for_status() except Exception as e: print(f"Failed to send data to server: {e}") return PlainTextResponse(text) raise HTTPException(status_code=500, detail="AI returned empty response")