Medication Reminder

A medicine or supplement schedule with this week at a glance and today's doses to log.

Experience · Shares patterns with Checklist, Insight Card

≈ 1,510 tokens per use (tool 1,093 · guidance 331 · typical payload 86)How token costs are estimated

Example: Medication Reminder

Remind me to take vitamin D three times a week

  • Vitamin D3

    1000 IU

    3 times per week

    1. Sunday, not scheduled
    2. Monday, scheduled, taken at 8:05 AM
    3. Tuesday, not scheduled
    4. Wednesday, scheduled, taken at 8:12 AM
    5. Thursday, not scheduled
    6. Friday, not scheduled
    7. Saturday, today, scheduled, not taken yet

    Today

    • 8:00 AMDue

Follow your prescription.

Reminders

When to use

  • The user wants to track or be reminded about medicines or supplements they already take: "remind me to take vitamin D three times a week", "did I take my antibiotics today?", "set up reminders for my prescription".
  • You have the schedule from the user's own words or their prescription data.

When not to use

  • The user asks what to take, how much, or when. Don't answer with a schedule; suggest they ask their pharmacist or clinician.
  • You'd have to guess any part of the schedule. Ask the user instead.
  • The question is about side effects, interactions or symptoms. This is a log, not advice.

How the agent should use it

  • Use only the schedule the user or their prescription gave. Never suggest or fill in doses, times, strengths or medicines. Every schedule field is data-bound.
  • Copy strength and instructions exactly as written on the label, and leave them out when unknown. The card shows nothing else about dosing, and always ends with "Follow your prescription."
  • Never put dosing advice or a diagnosis in the props. The card only renders the listed fields.
  • log comes from stored history. Never invent past doses.
  • Set reminders only when your host can actually send them.
  • Lifecycle: none of expiresAt, fetchedAt or supersede is needed: the card is a daily tool that stays usable, and it works out "today" from the clock. When the agent shows an updated schedule (a new prescription), supersede the old card so two schedules don't disagree.

Interaction

  • Week strip: seven day pills in the user's week order, each with the weekday, the date and one mark per dose. Taken days are tinted green, missed days (past only) red, scheduled and skipped days grey, and unscheduled days have no fill. Marks: a filled dot for taken, a hollow dot for due, a dash for skipped, an ✕ for missed. Today is filled solid.
  • Today: each of today's doses has Mark taken and Skip. A logged dose shows "Taken at 8:05 AM" with Undo for 5 minutes.
  • Course and supply: one quiet line, such as "Ends Oct 16, 6 days left · 40 pills left · refill by Oct 15", from endDate and refill. With refill, a warning appears when the supply lasts 7 days or less at this schedule (unless the course ends first), with a Request refill button.
  • Never locks. It's used every day, so it stays live after every result.

Accessibility

  • Each day has a full screen-reader label, such as "Monday, scheduled, taken at 8:05 AM", and today carries aria-current="date". State is never shown by color alone: taken, missed, skipped, today and scheduled each have an icon or ring too.
  • Dose buttons name the dose and the medication ("Mark 2:00 PM dose of Amoxicillin taken").
  • Marks, undos, refill requests and the reminders switch are announced in a polite live region.

Two kinds of history

Like the Checklist, the card is used over a day, so there are two ways to restore it:

PropBehavior
Saved dose logonProgress → progressCalled on every mark, skip and undo with { medId, scheduledFor, at, status }[]. Pass it back to restore. Nothing is sent to the agent
The latest resultresultRestores what that result describes (logged doses, the reminders switch, a refill request). The card stays live
<MedicationReminder
  {...part.input}
  progress={savedDoses}
  onProgress={(changes) => saveDoses(part.toolCallId, changes)}
  result={part.state === "output-available" ? part.output : undefined}
/>

Installation

npx shadcn@latest add https://your-site.com/r/medication-reminder.json

Usage

app/api/chat/route.ts
import { tool } from "ai"
import { medicationReminderTool } from "@/components/genui/medication-reminder.schema"

const tools = {
  [medicationReminderTool.name]: tool({
    description: medicationReminderTool.description,
    inputSchema: medicationReminderTool.inputSchema,
  }),
}

The agent receives one of:

// 1 s after the last mark, skip or undo: every dose logged in this card so far
{ action: "log", entries: [{ medId: "amoxicillin", scheduledFor: "2026-10-10T18:00:00.000Z", status: "taken", at: "2026-10-10T18:04:12.000Z" }] }
// The reminders switch (only with `reminders`)
{ action: "reminders", enabled: true }
// Hand off to the pharmacy flow; don't order anything yourself
{ action: "refill", medId: "iron" }

Treat each log result as the full set for this card: store new entries and remove ones that dropped out (an undo).

With LangGraph

Push it from a graph node with ui.push({ name: "show_medication_schedule", props: { toolCallId, ...args } }, { message }), and render the thread's UI messages with the Renderer.

Schema

PropTypeNotes
medicationsMedication[]1–6
timeZonestringIANA zone the times apply in, e.g. "America/New_York"
weekStart0 | 10 = Sunday (default), 1 = Monday
remindersboolean?Adds a "Reminders" switch. Only when the host can send them
localestring?BCP 47 locale for times, dates and weekday names

Medication

FieldTypeNotes
idstringReturned in results
namestringData-bound. e.g. "Vitamin D3"
strengthstring?Data-bound. As written on the label, e.g. "1000 IU"
instructionsstring?Data-bound. From the label, e.g. "With food"
schedule{ frequency, timesPerDay?, times?, daysOfWeek?, everyNDays?, startDate?, endDate? }Data-bound. frequency is daily, weekly (with daysOfWeek, 0 = Sunday), every-n-days (with everyNDays, counted from startDate) or as-needed. times are 24-hour local times like "08:00"
log{ at, status, scheduledFor? }[]?Data-bound. status is taken or skipped. Without scheduledFor, an entry is matched to the nearest dose that day
refill{ remaining, unit?, refillBy? }?Data-bound. unit is doses (default) or pills

Host props: status (streaming or ready), now, onResult, onProgress, progress, result and className. now fixes the moment "today" is measured from; it still advances while the card is open.

Source

On this page