feat(scheduler): Add Slack scheduled tasks#368
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
8dfdc8b to
9dade87
Compare
Add a state-adapter backed scheduler for Slack-authored Junior tasks. Use active-context Slack tools, calendar recurrence, and an authenticated cron tick endpoint. Wrap scheduled runs in marker-delimited task prompts and deliver results back through Slack. Add integration and eval coverage for task management, recurrence, tick dispatch, and delivery. Refs #114 Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Require scheduled task edits and deletes to come from the creator so a thread member cannot change work that later runs with another user's credentials. Keep scheduler tick auth scoped to scheduler secrets and prune deleted tasks from scheduler scan indexes. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Use the inbound Slack workspace context when a message raw payload lacks team_id so schedule tools still receive the destination workspace. Prefer the workspace team over user_team for Slack Connect author payloads, and keep the shared context outside ingress-only modules. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Keep existing recurrence metadata when a schedule update only changes task content. This prevents unrelated edits from shifting bi-weekly or monthly anchors to the current next run. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Claim an active-run slot per scheduled task before creating a run so schedule edits cannot start a second due instant while the previous run is still active. Clear the slot only when that same run reaches a terminal state. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Return blocked instead of failed when scheduled Slack execution pauses for MCP or plugin authorization. This keeps recurring tasks from advancing past credential requirements. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Clear statusReason when Slack schedule updates move a task out of the blocked state. This prevents resumed active tasks from carrying old credential error text. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Release the per-slot scheduler claim when a blocked task is resumed as active for the same due instant. This lets credential-unblocked tasks retry immediately instead of waiting for claim TTL expiry. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Return a blocked scheduler result when a scheduled run needs new MCP or plugin authorization instead of starting an OAuth handoff. Scheduled tasks can still use existing creator credentials, but missing credentials now require an interactive Slack turn before the task can be resumed. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Let scheduler claims recover pending runs that never started after an aborted tick. Only transition pending runs to running so stale duplicate claims cannot restart a run another tick already completed. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Guard scheduled run transitions with claim and start ownership so stale workers cannot mutate reclaimed runs. Move post-run task updates behind the scheduler store lock, add persisted Slack delivery idempotency for completed runs, privately notify creators when scheduled auth is blocked, and require explicit confirmation before creating scheduled tasks. Co-Authored-By: GPT-5 Codex <codex@openai.com>
839383e to
2282725
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2282725. Configure here.
| ok: false, | ||
| error: | ||
| "Active scheduled tasks require next_run_at_iso when no next run is stored.", | ||
| }; |
There was a problem hiding this comment.
Blocked task resume rejected
Medium Severity
When a scheduled run finishes as blocked, the store clears nextRunAtMs. slackScheduleUpdateTask then rejects status: "active" unless the caller also supplies next_run_at_iso, even though the task still has lastRunAtMs from that blocked attempt. Users told to “resume” after fixing auth cannot re-enable the task through the Slack update tool alone.
Reviewed by Cursor Bugbot for commit 2282725. Configure here.


Add Slack-authored scheduled Junior tasks backed by the existing state adapter instead of SQL. Users can create, list, edit, pause/resume, and delete tasks from the active Slack thread, and the internal cron tick executes due runs back into Slack.
Calendar Scheduling
Scheduled tasks store an exact next-run instant plus a small calendar recurrence rule for daily, weekly, monthly, and yearly schedules. This keeps recurring tasks aligned to local wall-clock time across DST and skips unsupported exact dates instead of inventing business-day behavior.
Scheduled Execution
Due runs are claimed idempotently, wrapped in a marker-delimited scheduled-task prompt, executed as the creator, and delivered through the Slack Web API. The runner blocks tasks on auth-pending turns and preserves newer task edits/deletes made while a run is in flight.
Coverage
Adds integration coverage for Slack schedule tools, scheduler execution, cron auth, and the scheduled Slack runner's MSW-backed chat.postMessage path. Adds eval coverage for natural-language schedule creation and scheduled-task prompt execution.
Refs #114