Repository navigation
feat(bot): Tasks view, Bot pause and Bot reset (#1007) - #1022
Merged
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Spec #1007, the Tasks view and whole-Bot pause/reset (build item 2 of 14 on #962), from the Wayfinder #974.
bots.tasks, and refreshes live from change-log hints. (The Tasks view: a "Tasks N" popover with the existing controls #1009)triggers.skip. The Trigger never reaches a Turn, and Done shows it as skipped. (Skip a waiting Routine, webhook or Check-in Trigger #1010)routines.edit(the edit is its own Approval, the Routine keeps its state, and the edit applies from the next run) andcheckIns.edit, in inline forms. (The user edits a Routine or a Check-in #1011)bots.pauseandbots.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)bots.resetbehind 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)bot.paused_at, Triggerskipped_at+skip_reason, theresetmessage role, and a partial index for skipped Triggers. All in one migration.docs/974-tasks-view).Closes #1007
How it was tested
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.bot-tasks,bot-task-edits,bot-pause,bot-reset.VERIFY OK, 2564 tests passed (34 skipped). Full e2e: 58/58.Decisions I made
resetBot(botId, userId, context)hook ondefineFeature, run by a durablebot.resetjob enqueued in the reset transaction. Memory implements it. ADR 0029 is amended.bot_trigger_skipped_idxis folded into the spec's unreleased migration20261029163647_tasks_view. A local database that applied the earlier version needs recreating.message_rolevalue,reset.botchange kind carries Bot-row changes (text column, no migration).pausedAtis on the Bot type,bots.get/listand the user export.>on the mark's timestamp. A row in the mark's own millisecond is treated as before it.bots.tasks,bots.pause,bots.resume,bots.reset,triggers.skip,routines.edit,checkIns.edit.Risk
bots.resetdeletes a Bot's Routines, Check-ins, Helpers with their transcripts, and its Memory files. The lab repo is never deployed.🤖 Generated with Claude Code