Inspiration

What it does

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for MeddyBuddyAI — the proactive AI medication companion

Inspiration

Meet Sarah, 67. She's on four medications for blood pressure, diabetes, and cholesterol. She forgets the evening doses. Her son worries from across the country and calls every Sunday to ask "did you take your meds?"

Existing apps are forms. Sarah won't fill out a form. They're trackers. Sarah won't open a tracker. They're reactive — they wait for her. We wanted an agent that starts the conversation, runs the routine, and quietly closes the loop with her family when something slips. That's MeddyBuddyAI.

What it does

A proactive AI medication companion built on Jac 2.0 + Claude Sonnet 4.6 — 25 walker endpoints, three distinct byLLM agents, native Jac end-to-end.

  • Conversational onboarding. A dedicated agent greets new users and walks them through adding meds in plain English. Say "Metformin 500mg twice a day, 8am and 8pm" → it parses name, dose, frequency, and BOTH clock times into the user's Jac graph.
  • A real agentic loop. The main agent picks from 7 tools per turn — log a dose, check an OpenFDA interaction, compute adherence, look up the current time — with multi-turn memory via Jac glob lists.
  • Digital Health Twin. A 0–100 score with trend vs prior week, proactive Alert nodes when adherence drops below 70%, and a byLLM-generated weekly digest narrative.
  • Proactive email layer (Brevo). Bell icon on each medication fires a real reminder email. Set a caregiver email in Settings → weekly digest goes to the family inbox. The family-care loop closes without surveillance.
  • Symptoms & Mood Analyzer. A second, isolated byLLM agent that asks 2–3 short check-in questions, then returns structured follow-up + medication + diet suggestions. Includes an OCR/vision panel — drop a PDF lab report or a skin photo, get a structured triage mapped onto 6 internal flags (acne, eczema_dermatitis, psoriasis, rosacea, skin_infection, rash_or_allergic).

How we built it

Stack:

  • Jac 2.0 (jaclang 0.10.2) — every node, edge, walker, ability, by llm function, and sem annotation is native Jac. 25 walker:pub endpoints, all auto-exposed as REST.
  • byLLM 0.4.20 + Claude Sonnet 4.6 via LiteLLM.
  • jac start for the FastAPI server + Bearer auth + per-user graph persistence.
  • OpenFDA for drug-interaction tool calls.
  • Brevo transactional email for reminders + caregiver digests.
  • pdfplumber for PDF text extraction; LiteLLM vision for skin-image triage.
  • Frontend: React 19, Vite 8, Tailwind v4, Framer Motion, react-markdown + remark-gfm, Lucide React.

Architecture:

  • Single main.jac: 10 node types, 25 walkers, three byLLM agents (meddy_onboarder, meddy_buddy, symptom_intake + analyze_symptoms), each with its own glob conversation history so they never interfere.
  • Per-user root graph: root → UserProfile → Medication → DoseLog, plus → Alert, → Reminder, → MedicalReport. Auto-persisted by jac start.
  • Tools read/write the graph directly (no walker-spawn-inside-walker), so the same data the agent touches is exposed via REST.

Challenges we ran into

The Jac docs we started from were aspirational for the 0.6+ API and didn't match installed jaclang 0.10.2. We documented eight real gotchas as we hit them:

  1. pip install jaseci pulls in legacy Jaseci 1.x which uses Linux-only signal.SIGALRM and breaks on Windows — install jaclang directly.
  2. jaclang 0.10.2 needs typing.overridePython 3.12+ only.
  3. can run with `root entry does NOT fire on spawn — typed entries only fire on explicit visit. Switched dispatcher abilities to plain can run with entry.
  4. Lowercase true/false compile but transpile to literal true/false in Python → NameError at runtime. Use True/False.
  5. [parent --> NodeType] doesn't actually filter by node type at runtime. We added isinstance guards across 19 graph traversals.
  6. walker:pub is required for REST exposure. Plain walker is private.
  7. Even public walkers need a Bearer token — register/login first.
  8. Windows cp1252 stdout chokes on emoji in LLM replies — PYTHONIOENCODING=utf-8 before jac start.

Multi-file imports for server walkers don't work via cl import (that's client-side). Tried, hit it, consolidated into single-file. The README has a "lessons learned" section covering all of this so the next jaclang 0.10.2 hackathon team doesn't lose hours to the same things.

Accomplishments that we're proud of

  • Three distinct byLLM agents coordinating through a shared per-user graph — not three copies of the same prompt.
  • Real proactive behavior: the agent emails the user AND emails the caregiver, with audit logging back to the graph as NotificationLog nodes.
  • The agent saves "Metformin 500mg twice a day at 8am and 8pm" with frequency=twice_daily, times=["08:00","20:00"] — not from a regex parser, just from sem-annotated tool calling.
  • A second isolated flow (Symptoms & Mood Analyzer with OCR + vision triage) that lives next to the main app without touching any existing code — proving the architecture composes.
  • A polished React frontend (landing page with how-it-works section, settings modal, weekly-report modal with markdown summary, per-medication reminder bell, full-screen symptoms analyzer) — not a Postman screenshot pretending to be a UI.
  • Engineering discipline: 25 atomic commits, comprehensive README, JAC_USAGE.md essay for the Best Use of Jac sub-track, SUBMISSION.md walking through the demo, .env.example with verified Brevo setup steps.

What we learned

  • Jac is a real language with real semantics. The productive moves are single-file main.jac, untyped dispatcher + typed visitor abilities, def fn(...) -> T by llm() for declarative AI, and sem blocks as the prompt contract.
  • byLLM tool calling is surprisingly tight. With a sharp sem annotation per tool, Claude reliably parses natural language into structured arguments — even lists — without us writing parsing logic.
  • The Agentic AI flagship track rewards loops, not single-shot calls. Adherence drops → Digital Twin generates an alert → caregiver email fires → graph logs the send. That loop is what makes this feel like an agent and not a chat wrapper.
  • Document gotchas as you find them. Our "lessons learned" section in the README will save the next jaclang 0.10.2 hackathon team hours.

What's next for MeddyBuddyAI — the proactive AI medication companion

  • Background scheduler that fires reminders by clock — the Brevo plumbing is already in place, adding a threading.Timer loop is a 30-line change.
  • Multimodal expansion: voice intake during onboarding; richer OCR (multi-page scanned PDFs, handwritten prescription scans).
  • Agent-to-agent coordination: the onboarding agent hands off to a "first-week coach" agent that nudges adherence for the first 7 days.
  • Phase 2 graph stubs already shipped: MoodEntry, SleepEntry, MedicalReport, ReportFinding — ready for the next set of specialized agents to plug in.
  • HIPAA-grade encryption pass for real deployment, and a caregiver-side dashboard so families can see trends without spamming the patient's phone.

Built With

  • anthropic
  • brevo
  • byllm
  • claude
  • claude-sonnet-4.6
  • fastapi
  • framer-motion
  • jac
  • jac-2.0
  • jaclang
  • javascript
  • litellm
  • lucide-react
  • node.js
  • openfda
  • pdfplumber
  • python
  • python-3.12
  • react
  • react-19
  • react-markdown
  • tailwind-css
  • tailwind-v4
  • vite
Share this project:

Updates