Files
nanobot-runtime/skills/remind/SKILL.md
2026-07-22 12:32:02 +02:00

5.0 KiB
Raw Permalink Blame History

name, description
name description
remind Create, list, edit, enable, disable, and remove recurring or one-time reminders. Triggers on: "/remind", "remind me", "set a reminder".

/remind

Reminders are stored in SQLite (db/reminders.sqlite) and delivered by remind_send.py, which runs every minute from the nanobot user crontab, directly to Telegram, outside the agent. Reply to the user in their own language.

Natural language → command mapping

User says Command
"every day at 9" / "every weekday at 9:30" add --cron "0 9 * * *"
"on 2026-06-15 at 18:00" / "once at …" add --at "2026-06-15T18:00:00"
"randomly 2× between 08:00 and 20:00" add --random-times-per-day 2 --random-window 08:00-20:00
"randomly 2× a week between 08:00 and 20:00" add --random-times-per-week 2 --random-window 08:00-20:00
"every day at 8:00 and 20:00" add --cron "0 8 * * *" --cron "0 20 * * *"
"today at 18:00 and Tuesday at 7:00" add --at "2026-07-05T18:00:00" --at "2026-07-07T07:00:00"
"what reminders arrived today / since when" delivered [--since YYYY-MM-DD]
"what goes out today / tomorrow / this week" upcoming [--date YYYY-MM-DD | --days N]
list all reminders list

For the full flag reference of any command, run:

uv run skills/remind/scripts/remind_cli.py --help
uv run skills/remind/scripts/remind_cli.py <command> --help

Behavioral contract

One reminder text = one record. When the same message should fire at several times or days, put them all on a single add with repeated --at/--cron (both are repeatable) — never issue multiple adds with the same text. add and edit reject a duplicate active text with {"error": "duplicate text", ...}. To add a time to an existing reminder, edit --id <n> --replace-schedules with all the times it should keep.

Showing read results. list, upcoming, and delivered return text for the user — present it, never collapse to a count. For list, rewrite the raw output into a compact, readable form of your own: one reminder per line, schedules paraphrased to natural language (30 9 * * 1-5 → "9:30 on weekdays"). Show only enabled reminders — skip disabled ones; keep each shown reminder's #display-id exactly as the CLI printed it (so --id still matches — gaps from skipped disabled ones are fine). Don't print the [enabled] marker.

list returns readable text. Each reminder:

#<display-id>  text  [enabled|disabled]
    cron: 0 9 * * *
    at: 2026-06-15T18:00:00
    random: 2× daily 09:0021:00 (1-5) from 2026-06-01
    random: 2× weekly 08:0020:00

An empty store prints (no active reminders).

Display IDs (#1, #2, …) are sequential positions among active reminders, computed on the fly — never the internal DB id. They renumber after every remove, so always run list first when unsure. The internal DB id is never shown to the user; do not surface the id field from mutation JSON as #….

A weekly random schedule fires N times across the week (MonSun) on N distinct random days, one random time each inside the window. --random-days/--random-from/ --random-until narrow the eligible days; a partial week at a from/until edge squeezes the full weekly count into the days that remain (no proration).

Mutations (add, edit, remove, enable, disable) return JSON: {"added": …}, {"edited": …}, etc. Errors go to stderr with a non-zero exit code.

Selecting a reminder: edit, remove, enable, disable accept --keyword (case-insensitive substring) or --id (the display ID from list). An ambiguous keyword match returns {"error": "ambiguous", "matches": [{"display_id": n, "text": …}]} — retry with --id <display-id>. Run list to see current display IDs.

delivered reads the reminder_fires table (delivered rows only, Prague local time). Defaults to today; --since YYYY-MM-DD widens the window. The agent never sees deliveries happen — this is the only window into them.

upcoming returns readable text: each scheduled fire as YYYY-MM-DD HH:MM #display-id text (type), sorted by time. The #display-id matches the one in list. It shows the plan (computed from the schedules), not actual deliveries — use delivered for those. Defaults to the rest of today; --date shows one whole day, --days N the next N calendar days. An empty window prints (nothing scheduled in this window).

remove is a soft delete.

Editing reminders

To fix or change wording: use edit --id <display-id> --text "…" (get the display ID from list), or edit --keyword <kw> --text "…". NEVER remove + re-add a reminder just to change its text — that loses the delivery history and changes the id.

Use --replace-schedules (with at least one new --cron/--at/--random-*) only when you need to change the schedule, not the text.

Environment

  • REMIND_DB — override SQLite path (used in tests).
  • Scripts run via uv run (PEP 723 headers declare their dependencies).