|
|
import gradio as gr |
|
|
from ai import ask_ai, parse_actions |
|
|
from db import init_db, add_task, get_dashboard_fig, list_tasks, export_tasks_csv |
|
|
import os |
|
|
|
|
|
init_db() |
|
|
|
|
|
DEFAULT_USER = "demo_user" |
|
|
|
|
|
def chat_and_handle(message, history, user=DEFAULT_USER): |
|
|
|
|
|
history = history or [] |
|
|
history.append((message, "")) |
|
|
|
|
|
|
|
|
reply = ask_ai(message, history) |
|
|
|
|
|
actions = parse_actions(reply) |
|
|
|
|
|
applied = [] |
|
|
suggestions = [] |
|
|
for act in actions: |
|
|
t = act.get("type") |
|
|
conf = act.get("confidence", 0) |
|
|
payload = act.get("payload", {}) |
|
|
if t == "create_task" and payload.get("title"): |
|
|
|
|
|
if conf >= 0.9: |
|
|
add_task(user, payload) |
|
|
applied.append(payload.get("title")) |
|
|
else: |
|
|
suggestions.append(payload) |
|
|
elif t == "create_project": |
|
|
|
|
|
if payload.get("name"): |
|
|
add_task(user, {"title": f"Project: {payload.get('name')}", "tags": ["project"]}) |
|
|
applied.append(f"Project: {payload.get('name')}") |
|
|
else: |
|
|
|
|
|
suggestions.append(act) |
|
|
|
|
|
final_reply_lines = [reply.strip()] |
|
|
if applied: |
|
|
final_reply_lines.append("\n\nApplied actions (auto):") |
|
|
for a in applied: |
|
|
final_reply_lines.append("- " + a) |
|
|
if suggestions: |
|
|
final_reply_lines.append("\n\nSuggested actions (please confirm manually):") |
|
|
for s in suggestions: |
|
|
final_reply_lines.append("- " + (s.get("title") if isinstance(s, dict) else str(s))) |
|
|
|
|
|
final_reply = "\n".join(final_reply_lines) |
|
|
|
|
|
|
|
|
history[-1] = (message, final_reply) |
|
|
|
|
|
|
|
|
fig = get_dashboard_fig(user) |
|
|
tasks = list_tasks(user) |
|
|
return history, final_reply, fig, tasks |
|
|
|
|
|
def export_csv(user=DEFAULT_USER): |
|
|
path = export_tasks_csv(user) |
|
|
return path |
|
|
|
|
|
with gr.Blocks(title="FullTrack AI β Hugging Face Space (MVP)") as demo: |
|
|
gr.Markdown("""# π FullTrack AI β Hugging Face Space (MVP) |
|
|
This Space demonstrates an AI-driven task/project tracker MVP. |
|
|
- Type instructions in the chat (e.g. "Create a project Website Redesign and 3 tasks due next week assigned to Raj.") |
|
|
- The assistant will reply and propose actions in JSON. High-confidence task creations are auto-applied. |
|
|
""") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=2): |
|
|
chatbot = gr.Chatbot([], elem_id="chatbot") |
|
|
msg = gr.Textbox(placeholder="Type a message and press Enter", lines=2) |
|
|
send_btn = gr.Button("Send") |
|
|
clear_btn = gr.Button("Clear chat") |
|
|
with gr.Column(scale=1): |
|
|
gr.Markdown("### Dashboard") |
|
|
dash_plot = gr.Plot() |
|
|
gr.Markdown("### Tasks (latest)") |
|
|
tasks_table = gr.Dataframe(headers=["id","title","status","created_at"], interactive=False) |
|
|
export_button = gr.Button("Export CSV") |
|
|
export_path = gr.Textbox(label="Export path", interactive=False) |
|
|
|
|
|
def on_send(message, history): |
|
|
return chat_and_handle(message, history) |
|
|
|
|
|
def on_clear(): |
|
|
return [], "", None, [] |
|
|
|
|
|
msg.submit(on_send, inputs=[msg, chatbot], outputs=[chatbot, gr.Textbox(), dash_plot, tasks_table]) |
|
|
send_btn.click(on_send, inputs=[msg, chatbot], outputs=[chatbot, gr.Textbox(), dash_plot, tasks_table]) |
|
|
clear_btn.click(on_clear, outputs=[chatbot, gr.Textbox(), dash_plot, tasks_table]) |
|
|
export_button.click(export_csv, outputs=[export_path]) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|