Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.nanoclaw.dev/llms.txt

Use this file to discover all available pages before exploring further.

Overview

v2 has no separate task scheduler. A scheduled task is a row in messages_in with a process_after timestamp (and optionally a recurrence cron expression). The host sweep runs every 60 seconds, finds rows whose time has come, wakes the session’s container, and the agent picks it up like any other inbound message. That means everything scheduled — daily briefings, weekly reports, per-hour polls, one-time reminders — goes through the same pipeline as a user message. You only learn one model.

Task types

Use cron expressions for complex recurring schedules:
0 9 * * *     — Daily at 9am
0 9 * * 1-5   — Weekdays at 9am
0 */6 * * *   — Every 6 hours
0 0 * * 0     — Sundays at midnight
0 8 1 * *     — First day of each month at 8am
Each occurrence creates a new row in the session database sharing a series_id.

Creating tasks

Tasks are created through natural language requests to the agent:
@Andy send me a summary of my calendar every weekday at 9am
@Andy check for new GitHub issues every hour and notify me
@Andy remind me to review the budget tomorrow at 2pm
@Andy compile AI news from Hacker News every Monday at 8am

How it works

When you request a scheduled task, the agent:
  1. Parses your request to extract the schedule and prompt
  2. Calls the schedule_task MCP tool (writes to outbound.db)
  3. The host’s delivery system creates the task in inbound.db
  4. The host sweep picks up the task when it’s due

Task execution

The host sweep runs every 60 seconds and:
  1. Finds tasks where process_after <= now
  2. Wakes the session’s container (or spawns a new one)
  3. The agent-runner’s poll loop picks up the task
  4. Agent executes the task prompt
  5. Host sweep syncs processing_ack and marks the task completed
  6. For recurring tasks, creates the next occurrence with updated process_after
Tasks share the container concurrency pool with interactive messages. If all container slots are busy (default: 5), tasks wait until a slot is available.

Timezone configuration

Tasks use the configured timezone for cron evaluation. The resolver checks:
  1. process.env.TZ
  2. .env file’s TZ value
  3. System locale
  4. Falls back to UTC
Each candidate is validated as a real IANA timezone identifier. To override:
export TZ="America/New_York"

Task management

Manage tasks through natural language:
@Andy list all scheduled tasks
@Andy pause the Monday briefing task
@Andy resume the calendar summary task
@Andy cancel the reminder about the meeting
@Andy update the PR monitor to check every 30 minutes instead

Available operations

OperationWhat it does
schedule_taskCreates a new task with process_after and optional recurrence
cancel_taskMarks all rows in the series as completed, nulls recurrence
pause_taskToggles task to paused (skipped by host sweep)
resume_taskToggles task back to pending
update_taskUpdates prompt, script, schedule, or recurrence in-place

Task scripts

For recurring tasks, add a script to minimize unnecessary agent wake-ups. The script runs first, and the agent is only invoked when the script determines action is needed.

How it works

  1. The script runs first (30-second timeout)
  2. It prints JSON to stdout: { "wakeAgent": true/false, "data": {...} }
  3. If wakeAgent is false — task completes silently, no agent invocation
  4. If wakeAgent is true — the agent wakes with the script’s data in its prompt

Example

@Andy every hour, check for new GitHub PRs needing my review. Use this script to check first:
curl -s https://api.github.com/repos/org/repo/pulls?state=open | jq '{wakeAgent: (length > 0), data: .}'

Always test your script first

Before scheduling, run the script in the sandbox:
bash -c 'curl -s https://api.github.com/repos/owner/repo/pulls?state=open | jq "{wakeAgent: (length > 0), data: .}"'

When NOT to use scripts

If a task requires agent judgment every time (daily briefings, reminders, reports), skip the script.

Frequent task guidance

If a task runs more than roughly twice a day and a script can’t reduce agent wake-ups:
  • Each wake-up uses API credits
  • Restructure with a script that checks conditions first
  • Find the minimum viable frequency
Scripts have a 30-second timeout and 1 MB output limit. If the script fails or produces no output, the agent is not invoked.

Recurring task series

Recurring tasks use a series model:
  • Each occurrence gets a new messages_in row sharing the same series_id
  • When an occurrence completes, the host creates the next one
  • cancel_task stops the entire series
  • update_task matches by series_id to hit the live next-occurrence row

Example use cases

Daily standup summary

@Andy every weekday at 9am, compile my calendar events for the day and send me a brief summary

GitHub PR monitor (with script)

@Andy check for PRs needing review every hour. Script: curl -s https://api.github.com/repos/org/repo/pulls?state=open | jq '{wakeAgent: (length > 0), data: .}'

Weekly report

@Andy every Friday at 5pm, review the git history for the past week and compile a summary

One-time reminder

@Andy remind me tomorrow at 2pm to review the budget proposal

Error handling

If a task fails:
  1. Processing is acknowledged with error state
  2. For recurring tasks, the next occurrence is still created
  3. For one-time tasks, the task is marked completed even if it failed
  4. Check container logs for error details
  • Messaging — the inbox/outbox pattern that scheduling rides on
  • Customization — sweep interval, timezone, and concurrency
Last modified on April 23, 2026