Spaces:
Sleeping
Sleeping
File size: 4,872 Bytes
c315e77 257b532 c315e77 257b532 c315e77 257b532 5f83ea5 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 257b532 c315e77 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | # app.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import os, re, json
from datetime import datetime, timedelta
from typing import Optional, Dict, Any
from groq import Groq
# Initialize Groq client using environment variable
GROQ_KEY = "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"
if not GROQ_KEY:
raise RuntimeError("Missing GROQ_API_KEY. Set it as an environment variable or in Hugging Face Secrets.")
client = Groq(api_key=GROQ_KEY)
app = FastAPI(title="Task Parsing API (Groq-powered)")
# -------------------- PROMPTS --------------------
llm_task_create_agent_system_prompt = f"""
You are a task creation agent. Extract the following from user input:
- Task Name (Text)
- Task Priority (High, Medium, Low)
- Task Deadline (STRICTLY 'YYYY-MM-DD HH:MM:SS')
- Task Status (Pending, Completed)
- Task Type (Work, Health, Personal)
- Date Created (If not given, use current time)
⚠️ ALL datetime values must follow 'YYYY-MM-DD HH:MM:SS'. NO natural language like 'tomorrow' or 'evening'.
Output JUST a JSON object. Example:
{{"Task Name": "Submit report", "Task Priority": "High", "Task Deadline": "2025-07-17 18:00:00", "Task Status": "Pending", "Task Type": "Work", "Date Created": "2025-07-01 12:00:00"}}
"""
# -------------------- HELPERS --------------------
def extract_json_from_response(text: str):
match = re.search(r"\{[\s\S]*\}", text)
if not match:
return None
try:
return json.loads(match.group())
except json.JSONDecodeError:
return None
DATETIME_REGEX = r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"
def validate_datetime_format(dt_str: str) -> bool:
if re.fullmatch(DATETIME_REGEX, dt_str):
try:
datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")
return True
except:
return False
return False
# -------------------- GROQ CALLER --------------------
def call_groq_system(system_prompt: str, user_message: str, model: str = "llama-3.3-70b-versatile"):
"""Generic wrapper to call Groq chat API."""
chat_completion = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message},
],
)
return chat_completion.choices[0].message.content.strip()
# -------------------- AGENTS --------------------
def run_task_creation_agent(nl_task: str):
reply = call_groq_system(llm_task_create_agent_system_prompt, nl_task)
parsed = extract_json_from_response(reply)
if not parsed:
raise ValueError(f"LLM did not return valid JSON. Raw:\n{reply}")
if not validate_datetime_format(parsed.get("Task Deadline", "")):
raise ValueError(f"Invalid 'Task Deadline': {parsed.get('Task Deadline')}")
if not validate_datetime_format(parsed.get("Date Created", "")):
parsed["Date Created"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
parsed.setdefault("Task Status", "Pending")
parsed.setdefault("Task Priority", "Medium")
parsed.setdefault("Task Type", "Work")
return parsed
def scheduler_agent(task_json: Dict[str, Any]) -> str:
"""Simplified scheduler — returns the deadline as the scheduled time."""
deadline = task_json.get("Task Deadline")
if not validate_datetime_format(deadline):
raise ValueError("Scheduler requires a valid Task Deadline.")
return deadline
def reminder_agent(task_json: Dict[str, Any], scheduled_time_str: str):
scheduled = datetime.strptime(scheduled_time_str, "%Y-%m-%d %H:%M:%S")
priority = (task_json.get("Task Priority") or "Medium").lower()
if priority == "high":
offsets = [timedelta(hours=24), timedelta(hours=1)]
elif priority == "low":
offsets = [timedelta(days=1), timedelta(days=3)]
else:
offsets = [timedelta(hours=12), timedelta(hours=1)]
reminders = []
for off in offsets:
r = scheduled - off
if r > datetime.now():
reminders.append(r.strftime("%Y-%m-%d %H:%M:%S"))
return reminders
# -------------------- MODELS --------------------
class ParseRequest(BaseModel):
text: str
class ParseResponse(BaseModel):
task_json: Dict[str, Any]
scheduled_time: str
reminders: list
# -------------------- ENDPOINTS --------------------
@app.post("/parse-task", response_model=ParseResponse)
def parse_task(req: ParseRequest):
try:
task_json = run_task_creation_agent(req.text)
scheduled_time = scheduler_agent(task_json)
reminders = reminder_agent(task_json, scheduled_time)
return ParseResponse(task_json=task_json, scheduled_time=scheduled_time, reminders=reminders)
except Exception as e:
raise HTTPException(status_code=400, detail=str(e))
@app.get("/health")
def health():
return {"status": "ok"}
|