Unified routing guide for reminders, schedules, notifications, and tasks. Prevents common misrouting.
assistant skills install time-based-actionsQuick-reference decision guide for choosing the right tool when users ask about time-triggered actions, recurring automation, notifications, or task tracking.
Does the request have a specific future time AND should fire only once?
reminder_createDoes the request have a recurring pattern?
schedule_create with mode: "notify" (for recurring reminders/alerts) or mode: "execute" (if the assistant should act autonomously each recurrence)mode: "notify" for recurring reminder-style requests. Use mode: "execute" only when each recurrence should trigger the assistant to perform a task (e.g. "every morning, check my email and summarize it").Does the request need an alert RIGHT NOW (no delay)?
assistant notifications send via bashIs the request about tracking work with no time trigger?
task_list_addassistant notifications send is IMMEDIATE-ONLYassistant notifications send fires instantly when called. It has NO delay, scheduling, or future-time capability. NEVER use it for:
reminder_createreminder_createreminder_createIf you use assistant notifications send for any of these, the notification fires immediately and the user misses their intended reminder.
task_list_add has NO time triggertask_list_add creates a work queue item. It does NOT fire at a specific time. NEVER use it as a workaround for delayed notifications. If the user wants a timed alert, use reminder_create.
Use the current_time: field from the injected <turn_context> block as the authoritative clock source. The format is:
current_time: 2026-04-02 (Wednesday) 14:30:00 -05:00 (America/Chicago)
It contains the date, weekday name, local time (HH:MM:SS), UTC offset, and IANA timezone name in parentheses.
Timezone confidence check: The timezone shown may be the assistant host's timezone rather than the user's actual timezone (this happens when the user hasn't configured Settings → Appearance → User timezone). If you have no prior confirmation of the user's timezone (from conversation history or memory) and the request is locale-specific (e.g. "at 3pm", "tomorrow morning", "tonight"), confirm the timezone once before scheduling. If the user confirms, suggest saving it in Settings → Appearance → User timezone so future requests resolve correctly without re-asking.
When the user says "in X minutes/hours", compute the ISO 8601 timestamp yourself:
current_time: field (e.g. 23:26:00 -05:00)2025-03-15T09:05:00-05:00reminder_create as fire_atPhrases like "at the 45 minute mark", "at the top of the hour", "on the half-hour", "at noon", "20 minutes in", or "when I hit an hour" are clock-position or anchored relative time expressions. Do NOT treat them as offsets from now.
Resolution rules (in priority order):
Conversation-anchored expressions - if the user mentioned a start time earlier in conversation ("I got here at 9", "meeting started at 2:10"), interpret offset-style phrases ("the 45 minute mark", "20 minutes in", "when I hit an hour") as start_time + offset. This takes precedence because the conversational anchor overrides any wall-clock interpretation.
Clock-position expressions - when no start time is in context, map directly to a wall-clock time:
Ask only if truly ambiguous - if neither rule 1 nor rule 2 resolves, ask: "Do you mean [clock time] or [X minutes from now]?" Never silently default to "from now."
Examples:
The word "remind" is ambiguous. Route based on whether a time is specified:
| User says | Time present? | Tool |
|---|---|---|
| "Remind me to buy milk" | No | task_list_add |
| "Remind me to buy milk at 5pm" | Yes | reminder_create |
| "Remind me in 10 minutes to check the oven" | Yes (relative) | reminder_create |
| "Remind me every morning to take vitamins" | Yes (recurring) | schedule_create |
reminder_create supports two modes:
notify (default) - shows a notification to the user when the reminder firesexecute - sends the reminder message to a background assistant conversation for autonomous handlingUse notify for simple alerts. Use execute when the reminder should trigger the assistant to do something (e.g., "in 30 minutes, check if the build passed").
reminder_create supports a routing_intent parameter that controls how the reminder is delivered at trigger time:
single_channel - deliver to one best channelmulti_channel - deliver to a subset of channelsall_channels (default) - deliver to every available channelYou can also pass routing_hints (a JSON object) to influence routing decisions (e.g. preferred channels, exclusions).
Use the following heuristics to pick routing_intent:
Default to all_channels for most reminders. Users setting reminders usually want to be notified wherever they are, and redundant notifications are less harmful than missed ones.
Use single_channel only when the user explicitly specifies a single channel (e.g. "remind me on Telegram") or the reminder is low-stakes and noise reduction matters.
Determine the originating channel for routing hints using this priority:
source_channel from <turn_context> — use directly if present. This is the authoritative channel name.interface fallback — if source_channel is absent (common for guardian/direct users), map the interface value to a channel name:
interface value | Channel name |
|---|---|
macos, ios | vellum |
telegram | telegram |
slack | slack |
cli | (omit — no routable channel) |
cli, omit preferred_channels.When a channel is determined, include it as a routing hint:
routing_hints: { preferred_channels: ["<resolved channel>"] }
routing_intent: "all_channels"
Never use single_channel as a passive default. If you haven't thought about which channel to use, use all_channels.
| Scenario | routing_intent | routing_hints |
|---|---|---|
source_channel: telegram in turn_context | all_channels | { preferred_channels: ["telegram"] } |
No source_channel, interface: macos | all_channels | { preferred_channels: ["vellum"] } |
No source_channel, interface: ios | all_channels | { preferred_channels: ["vellum"] } |
| User says "remind me on Telegram" | single_channel | { preferred_channels: ["telegram"] } |
No source_channel, interface: cli | all_channels | {} |
| No channel info available | all_channels | {} |
| Tool | Timing | Recurrence | Purpose |
|---|---|---|---|
reminder_create | Future time (one-shot) | No | Timed notification or timed autonomous action |
schedule_create | Recurring pattern | Yes (cron/RRULE) | Recurring automated jobs |
assistant notifications send | Immediate only | No | Alert the user right now |
task_list_add | No time trigger | No | Track work in the task queue |