Spaces:
Sleeping
Sleeping
File size: 4,721 Bytes
663eb30 c822aba 663eb30 158ad95 663eb30 c278c76 663eb30 c278c76 158ad95 c278c76 663eb30 2c09dae c278c76 158ad95 7aecefc |
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 |
import json, random
from collections import deque
import numpy as np
import faiss, gradio as gr
from sentence_transformers import SentenceTransformer
from huggingface_hub import hf_hub_download
REPO_ID = "Elevi7/actionmatch-microactions-en"
index_path = hf_hub_download(repo_id=REPO_ID, filename="index/index.faiss", repo_type="dataset")
actions_path = hf_hub_download(repo_id=REPO_ID, filename="actions.jsonl", repo_type="dataset")
with open(actions_path, "r", encoding="utf-8") as f:
actions = [json.loads(l) for l in f]
index = faiss.read_index(index_path)
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
recent = deque(maxlen=120)
def render(a):
ctx = ", ".join(a["context"]) if isinstance(a.get("context"), list) else (a.get("context") or "")
return f"**{a['title']}** \n{a['instruction']} \nGoal: {a['goal']} • Duration: {a['duration_min']} min • Energy: {a['energy']} • Context: {ctx}"
def pick_unique(idxs, goal, energy, max_minutes, ignore_goal=False, ignore_energy=False, ignore_minutes=False, need=3, used=None):
if used is None:
used = set()
out = []
for i in idxs:
a = actions[i]
if a["title"] in used or a["title"] in recent:
continue
if not ignore_goal and goal and a["goal"] != goal:
continue
if not ignore_energy and energy and a["energy"] != energy:
continue
if not ignore_minutes and max_minutes and a["duration_min"] > int(max_minutes):
continue
used.add(a["title"])
out.append(a)
if len(out) == need:
break
return out, used
def fill_random(need, used, goal, energy, max_minutes):
pool = [a for a in actions if a["title"] not in used and a["title"] not in recent and (not goal or a["goal"]==goal) and (not energy or a["energy"]==energy) and (not max_minutes or a["duration_min"]<=int(max_minutes))]
if len(pool) < need:
pool = [a for a in actions if a["title"] not in used and a["title"] not in recent]
random.shuffle(pool)
return pool[:need]
def search(query, goal, energy, max_minutes):
try:
q = (query or "").strip()
qx = f"{q} Goal:{goal or 'any'} Energy:{energy or 'any'} Max:{int(max_minutes) if max_minutes else ''} minutes"
v = model.encode([qx], normalize_embeddings=True)
D, I = index.search(np.asarray(v, dtype="float32"), 800)
idxs = list(I[0]); random.shuffle(idxs)
res, used = [], set()
step, used = pick_unique(idxs, goal, energy, max_minutes, False, False, False, 3, used); res += step
if len(res) < 3:
step, used = pick_unique(idxs, goal, energy, max_minutes, False, True, False, 3-len(res), used); res += step
if len(res) < 3:
step, used = pick_unique(idxs, goal, energy, max_minutes, False, True, True, 3-len(res), used); res += step
if len(res) < 3:
step, used = pick_unique(idxs, goal, energy, max_minutes, True, True, True, 3-len(res), used); res += step
if len(res) < 3:
res += fill_random(3-len(res), used, goal, energy, max_minutes)
recent.extend([a["title"] for a in res[:3]])
return "\n\n---\n\n".join(render(a) for a in res[:3])
except Exception:
pool = [a for a in actions if (not goal or a["goal"]==goal) and (not energy or a["energy"]==energy) and (not max_minutes or a["duration_min"]<=int(max_minutes))]
if len(pool) < 3:
pool = actions[:]
random.shuffle(pool)
return "\n\n---\n\n".join(render(a) for a in pool[:3])
goals = ["","calm","focus","productivity","wellbeing"]
energies = ["","low","medium","high"]
with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo", neutral_hue="slate")) as demo:
gr.Markdown("# ActionMatch\nTop-3 micro-actions based on your situation, goal, energy and time.")
with gr.Row():
with gr.Column(scale=3):
q = gr.Textbox(lines=2, label="Your situation", placeholder="e.g., Stressed before exam")
btn = gr.Button("Recommend")
with gr.Column(scale=2):
g = gr.Dropdown(goals, label="Goal")
e = gr.Radio(energies, label="Energy")
m = gr.Slider(1, 15, step=1, value=5, label="Max minutes")
out = gr.Markdown()
btn.click(search, [q, g, e, m], out)
gr.Examples(
[["Stressed before exam","calm","low",5],
["No energy but need to start studying","focus","low",7],
["Keep switching tabs while writing essay","focus","medium",10]],
inputs=[q, g, e, m],
outputs=out,
fn=search,
label="One-click examples",
cache_examples=False
)
demo.queue()
demo.launch() |