Space / app.py
a9's picture
Update app.py
6a97dd6 verified
Raw
History Blame Contribute Delete
4.31 kB
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")