Skip to content

feat(bot): Tasks view, Bot pause and Bot reset (#1007) - #1022

Merged
Daanish2003 merged 21 commits into
mainfrom
feature/tasks-view
Oct 29, 2026
Merged

Daanish2003 merged 21 commits into
mainfrom
feature/tasks-view

Conversation

@Daanish2003

Copy link
Copy Markdown
Owner

Summary

Spec #1007, the Tasks view and whole-Bot pause/reset (build item 2 of 14 on #962), from the Wayfinder #974.

  • Tasks view: a "Tasks N" header popover with In progress / Scheduled / Done tabs replaces the To-do and Routines · Check-ins popovers. It reads one RPC, bots.tasks, and refreshes live from change-log hints. (The Tasks view: a "Tasks N" popover with the existing controls #1009)
  • Skip a waiting Routine, webhook or Check-in Trigger with triggers.skip. The Trigger never reaches a Turn, and Done shows it as skipped. (Skip a waiting Routine, webhook or Check-in Trigger #1010)
  • User edits: routines.edit (the edit is its own Approval, the Routine keeps its state, and the edit applies from the next run) and checkIns.edit, in inline forms. (The user edits a Routine or a Check-in #1011)
  • Bot pause: bots.pause and bots.resume, a "⋯" Bot menu, a Paused badge, a composer banner, a disabled composer. While the Bot is paused, everything that comes due is recorded as skipped (reason paused). User Messages and Approval yeses are refused, and a webhook still answers 202. (Bot pause and resume #1012)
  • Bot reset: bots.reset behind a typed-name gate. It wipes the Bot's Routines, Check-ins, Helpers, pending Approvals and own Memory files, keeps everything else the spec lists, and appends a reset mark. The Bot sees nothing from before the mark. (Bot reset #1013)
  • Schema (Schema for the Tasks view, Bot pause and Bot reset #1008): bot.paused_at, Trigger skipped_at + skip_reason, the reset message role, and a partial index for skipped Triggers. All in one migration.
  • CONTEXT terms Tasks view, Bot pause and Bot reset (from docs/974-tasks-view).

Closes #1007

How it was tested

  • New integration suites at the RPC seam: bot-tasks, bot-trigger-skip, bot-pause, bot-reset, bot-memory-reset, plus cases added to the bot-send, Routine-fire and Check-in suites. Each new test was seen red before its implementation or fix.
  • New UI component tests: bot-tasks, bot-task-edits, bot-pause, bot-reset.
  • A high-effort branch review found 10 issues, all fixed in db7c9e8 and 13ae493. They include: pause now takes back allowed-but-unstarted calls; a pre-reset call's result never reaches the reset Bot; Memory deletion is a durable runner job; and attachments are no longer lost on a pause/resume race.
  • Full verify on 13ae493: VERIFY OK, 2564 tests passed (34 skipped). Full e2e: 58/58.

Decisions I made

  • Public API (owner-approved on Bot reset #1013, 2026-10-30): an optional resetBot(botId, userId, context) hook on defineFeature, run by a durable bot.reset job enqueued in the reset transaction. Memory implements it. ADR 0029 is amended.
  • Schema (owner-approved, 2026-10-30): the partial index bot_trigger_skipped_idx is folded into the spec's unreleased migration 20261029163647_tasks_view. A local database that applied the earlier version needs recreating.
  • The reset mark is a third message_role value, reset.
  • A user Message skipped by a pause stays visible but is left out of later Turns' input. Email to a paused Bot saves no Message.
  • While paused, only tool-call Approval yeses and Choice answers are refused. Routine and rule approvals are unchanged.
  • A new bot change kind carries Bot-row changes (text column, no migration). pausedAt is on the Bot type, bots.get/list and the user export.
  • Reset's history cut uses a strict > on the mark's timestamp. A row in the mark's own millisecond is treated as before it.
  • New public RPCs, all approved in the spec: bots.tasks, bots.pause, bots.resume, bots.reset, triggers.skip, routines.edit, checkIns.edit.

Risk

  • Schema: one new migration (approved). Irreversible by design: bots.reset deletes a Bot's Routines, Check-ins, Helpers with their transcripts, and its Memory files. The lab repo is never deployed.
  • Left as follow-ups: an approved call already started at pause time finishes, and its result is kept as skipped. The Tasks view's six reads are not snapshot-consistent; a change hint triggers a re-fetch.

🤖 Generated with Claude Code

Daanish2003 and others added 21 commits October 29, 2026 21:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One migration for spec #1007: the Bot's pause timestamp (paused_at),
a Trigger's skipped time and reason (cancelled, paused or reset), and
the reset mark as a new Message kind (message_role 'reset'). Waiting
now means not taken by a Turn and not skipped: the Router, the Turn's
batch take, Stop and the waiting index honour it, and a Routine that
stops keeps its skipped Triggers. A CHECK ties the reason to the time
and keeps a skipped Trigger untaken.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ls (#1009)

bots.tasks reads a Bot's In progress, Scheduled and Done in one call, and
the Tasks popover replaces the To-do and Routines · Check-ins popovers.
The change log's turn, helper, routine and check_in changes refresh it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…per read (#1009)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
triggers.skip marks a waiting Routine run, webhook call or Check-in fire
as skipped (reason cancelled), so no Turn takes it and it shows in Done.
User and Helper-report Triggers and ones a Turn took are refused;
another user's is not found. The Tasks popover's Scheduled tab gets a
Skip button on those rows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r id (#1010)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
routines.edit changes a Routine's prompt and schedule (a webhook Routine
takes the prompt only) without an Approval and keeps its state; an active
Routine's queued fire is moved to the new schedule. checkIns.edit moves a
pending Check-in's fire and changes its note, and refuses one that already
fired. The Tasks popover gets inline forms for both.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
# Conflicts:
#	packages/botsdk/bot/src/create-chat.ts
#	packages/botsdk/client/src/i18n/en/errors.ts
#	packages/botsdk/ui/src/bot/tasks-popover.tsx
…1011)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
bots.pause stops the running Turn the way Stop does, stops every Helper
and skips each waiting Trigger with reason paused; each Routine keeps its
state. While paused, the Router keeps every Trigger it receives as
skipped (paused), so a Routine slot, a Check-in fire, a webhook call or
an email starts no Turn: the next slot stays queued, the Check-in ends
fired, the webhook answers 202, and an email saves no Message. A user
Message and an Approval's yes are refused. bots.resume only clears the
pause. Both are idempotent and log a bot change.

A user Message whose Trigger was skipped never reaches a later Turn's
input. The header gets the "..." Bot menu, a Paused badge, and a banner
with Resume above the disabled composer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An email to a paused Bot answers 202, saves no Message and keeps a
skipped Trigger. The user export and the UI fixtures carry pausedAt, and
the conversation reads a missing pausedAt as not paused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A Choice answer is refused while paused, so the choice stays open.
- A yes to a closed Approval answers as closed even while paused.
- Pause also skips the Triggers of a Turn it stopped before that Turn
  took its input, so resume replays none of them.
- A skipped Message no longer sets the Turn's time zone.
- Mail to a paused Bot stores no attachments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bots.reset takes the Bot's name and, in one transaction, stops the Bot as
a pause does (skip reason "reset"), declines pending Approvals, deletes
its Routines and Check-ins (cancelling their jobs, so webhooks answer
404) and its Helpers with their transcripts, then appends the reset mark.
The Prompt start, history Turns, recent replies and reactions now drop
everything before the latest reset mark. The UI adds Reset Bot… to the
Bot menu, a name-gated dialog listing what is wiped and kept, and a
divider for the mark.

Deleting the Bot's own Memory files waits on an owner decision (#1013).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The name is checked against the Bot's row locked for update, reset
cancels an allowed call's queued job, an answer to a choice asked before
the reset is refused, and the reset-mark filter reads the latest mark once
per query. Doc comments no longer claim Memory is deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1013)

defineFeature takes an optional resetBot(botId, userId, context) hook,
which bots.reset calls for each enabled feature once the reset commits,
best-effort and logged. Memory implements it by deleting the Bot's memory
directory when the user has a Computer, and its pass writes nothing from
a Turn the Bot had before its latest reset. ADR 0029 is amended (owner
approved on #1013, 2026-10-30).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The newest input, the last-input Turn and the safety reviewer's user
Messages stop at the reset mark, and a reaction to a pre-reset Message
is refused like a choice answer. Memory's reset delete and its pass take
the same advisory lock, and the pass checks the reset mark under it with
noResetAfter. The change hint goes out before the features forget the
Bot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pause cancels an allowed call that hasn't started and reopens its Approval (R1)
- An approved call's result never wakes a Bot reset since the answer (R2)
- Reset forgets each feature's data in a retried runner job (R3)
- An email to a Bot resumed while its files are stored keeps them (R4)
- Partial index on bot_trigger (conversation_id, skipped_at) for skipped Triggers,
  folded into the unreleased tasks_view migration (R5, owner-approved)
- Tasks lists only shown Helpers and the newest 100 skipped Triggers (R5, R6)
- A Turn's left-out skipped Messages use an uncorrelated subquery (R7)
- The reset mark hides rows stamped in its own millisecond (R8)
- Trigger id and text formats live beside their writers (R9, R10)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pause also takes back an allowed call waiting out a retry, until its start marker
- Test that an away Summary queued after a reset writes nothing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Daanish2003
Daanish2003 merged commit 3585448 into main Oct 29, 2026
2 checks passed
@Daanish2003
Daanish2003 deleted the feature/tasks-view branch October 29, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spec: Tasks view and whole-Bot pause/reset

1 participant