a9 commited on
Commit
02db71e
·
verified ·
1 Parent(s): 6012863

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +97 -0
app.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import PlainTextResponse
4
+ from pydantic import BaseModel
5
+ from typing import Optional, List
6
+ import os
7
+ from google import genai
8
+ from google.genai import types
9
+
10
+ Api_key = os.getenv('API_KEY')
11
+ client = genai.Client(api_key=Api_key)
12
+
13
+ app = FastAPI(title="Notes Task Manager API")
14
+
15
+ app.add_middleware(
16
+ CORSMiddleware,
17
+ allow_origins=["*"],
18
+ allow_credentials=True,
19
+ allow_methods=["*"],
20
+ allow_headers=["*"],
21
+ )
22
+
23
+ class Note(BaseModel):
24
+ project_name: Optional[str] = ""
25
+ details: Optional[str] = ""
26
+ type: str # "project" or "random"
27
+
28
+ class TaskRequest(BaseModel):
29
+ notes: list[Note]
30
+
31
+ class Task(BaseModel):
32
+ task_name: str
33
+ reason: str
34
+
35
+
36
+ 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.
37
+
38
+ **Your Goal:** Eliminate the user's decision fatigue. Do not give them a long list of options; give them a clear path forward.
39
+
40
+ **Input Data:
41
+ **1. **Projects:** The core goals and technical details of active work.
42
+ 2. **Random Notes:** Brain dumps, fleeting thoughts, anxieties, and unplanned ideas.
43
+
44
+ **Processing Logic:**
45
+ - **Analyze:** Cross-reference 'Random Notes' with 'Projects'. If a random thought is a task for a project, categorize it.
46
+ - **Prioritize:** Identify the 'Critical Path.' What needs to happen *now* to move the needle?
47
+ - **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.
48
+
49
+ **Output Format (Strictly follow this): **For each day, provide exactly **3 High-Impact Tasks**. No more, no less.
50
+
51
+ **Format:**📅 **Date: [Insert Date]**
52
+
53
+ 1. **[Task Name]** → (Briefly explain *why* this is a priority based on the notes).
54
+ 2. **[Task Name]** → (Briefly explain *why* this is a priority).
55
+ 3. **[Task Name]** → (Briefly explain *why* this is a priority).
56
+
57
+ **Closing Note:** Provide one sentence of encouragement or a 'Focus Tip' to help the user stay grounded and avoid distraction.
58
+
59
+ **Tone:** Professional, decisive, calm, and supportive. You are the anchor that keeps the user focused.'''
60
+
61
+
62
+ def call_gemini(history: List[types.Content]):
63
+ try:
64
+ response = client.models.generate_content(
65
+ model="gemma-4-31b-it",
66
+ contents=history,
67
+ config=types.GenerateContentConfig(
68
+ thinking_config=types.ThinkingConfig(thinking_level="MINIMAL")
69
+ ),
70
+ )
71
+ return response.text.rstrip()
72
+ except Exception as e:
73
+ print(f"GenAI Error: {e}")
74
+ raise HTTPException(status_code=500, detail="AI Generation Failed")
75
+
76
+
77
+ @app.post("/gen/task")
78
+ def generate_tasks(req: TaskRequest):
79
+ project_notes = [n for n in req.notes if n.type == "project"]
80
+ random_notes = [n for n in req.notes if n.type == "random"]
81
+
82
+ userPrompt = ""
83
+ for note in project_notes:
84
+ userPrompt = userPrompt + note.details
85
+
86
+ for note in random_notes:
87
+ userPrompt = userPrompt + note.details
88
+
89
+ history = [
90
+ types.Content(role="system", parts=[types.Part(text= sysPrompt)]),
91
+ types.Content(role="user", parts=[types.Part(text= userPrompt)])
92
+ ]
93
+
94
+ text = call_gemini(history)
95
+ if text:
96
+ return PlainTextResponse(text)
97
+ raise HTTPException(status_code=500, detail="AI returned empty response")