feat(ui): add scheduled task management#354
Conversation
✱ Stainless preview buildsThis PR will update the openapi python typescript Edit this comment to update them. They will appear in their respective SDK's changelogs. ✅ agentex-sdk-openapi studio · code · diff
✅ agentex-sdk-typescript studio · code · diff
✅ agentex-sdk-python studio · conflict
This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push. |
8445f04 to
0673c3d
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
Expose task-backed run counts and exact skip/unskip operations so schedule clients can reason about individual future occurrences. Co-authored-by: Cursor <cursoragent@cursor.com>
Add agent scoping, upcoming occurrence timelines, active toggles, run-now confirmation, and skipped occurrence controls to the scheduled tasks page. Co-authored-by: Cursor <cursoragent@cursor.com>
Use schedule metadata for scheduled-run task labels and add a calendar indicator so recurring runs are easier to recognize. Co-authored-by: Cursor <cursoragent@cursor.com>
Use the schedule name as the task display label and keep occurrence timing in metadata for views that need it. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
0673c3d to
e36d4cd
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Hide the scheduled tasks UI unless the schedules API is enabled so users do not navigate to endpoints that are absent at runtime. Co-authored-by: Cursor <cursoragent@cursor.com>
declan-scale
left a comment
There was a problem hiding this comment.
Ran locally, looks good, just some organization / small ui improvements I'd suggest
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Thanks for the great comments @declan-scale I addressed them all |
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
UX details
Test plan
npm --prefix agentex-ui run typechecknpm --prefix agentex-ui run lintnpm --prefix agentex-ui run test:run -- hooks/use-safe-search-params.test.tsx lib/agent-run-schedules.test.ts lib/schedule-utils.test.tsScreen.Recording.2026-07-13.at.2.25.20.PM.mov
Greptile Summary
This PR introduces a full Scheduled Tasks experience: a creation composer, an Upcoming timeline grouped by Today/Tomorrow/Later, and a Schedules management view with pause/resume, edit, delete, skip/unskip, and run-now flows. It also stabilizes scheduled-run display names (removing the per-occurrence timestamp suffix) with a backward-compatible legacy-prefix strip in the task sidebar.
scheduled-tasks/andhooks/, backed by the generated TypeScript schedule SDK, with TanStack Query for caching and invalidation._format_fire_timefrom the Python activity layer, replacing the"Scheduled Message: name · timestamp"display name with a stableschedule.name; aLEGACY_SCHEDULED_MESSAGE_PREFIXstrip intask-utils.tshandles pre-migration tasks.ENABLE_AGENT_RUN_SCHEDULES, now parsed safely via a newparseBooleanEnvutility that warns and defaults tofalsefor unrecognized values.Confidence Score: 5/5
Safe to merge; all changes are additive and feature-gated behind ENABLE_AGENT_RUN_SCHEDULES.
The new scheduled-tasks surface is entirely opt-in via an env flag, the Python activity change is a straightforward display-name simplification with a backward-compatible strip for legacy tasks, and no existing flows are broken. The two flagged items are a misleading code comment and a duplicate-mutation-instance pattern that could cause redundant API calls but not data corruption.
agentex-ui/lib/schedule-utils.ts (describeCadence fallback comment) and agentex-ui/components/scheduled-tasks/all-schedules-list.tsx (duplicate pause/resume hooks).
Important Files Changed
Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User participant ScheduleComposer participant useCreateAgentRunSchedule participant AgentexSDK participant QueryClient participant ScheduledTasksPage User->>ScheduleComposer: Enter prompt + cadence, click Schedule ScheduleComposer->>ScheduleComposer: generateScheduleName(prompt, existingSchedules) ScheduleComposer->>ScheduleComposer: cadenceToPayload(cadence) → cron/interval ScheduleComposer->>useCreateAgentRunSchedule: mutateAsync(payload) useCreateAgentRunSchedule->>AgentexSDK: agents.schedules.create(agentId, payload) AgentexSDK-->>useCreateAgentRunSchedule: AgentRunScheduleResponse useCreateAgentRunSchedule->>QueryClient: invalidateQueries(byAgentId) + setQueryData(detail) useCreateAgentRunSchedule-->>ScheduleComposer: AgentRunSchedule (normalized) ScheduleComposer->>ScheduleComposer: Show success feedback (auto-dismiss 10s) User->>ScheduledTasksPage: Click Upcoming tab ScheduledTasksPage->>ScheduledTasksPage: collectUpcomingRuns(items) → sort by runTime ScheduledTasksPage->>ScheduledTasksPage: getDefaultUpcomingRuns (≤10 total, ≤3/schedule) ScheduledTasksPage->>ScheduledTasksPage: groupUpcomingRuns → Today/Tomorrow/Later User->>ScheduledTasksPage: Run now (upcoming row) ScheduledTasksPage->>AgentexSDK: schedules.trigger(scheduleId) AgentexSDK-->>ScheduledTasksPage: success QueryClient->>QueryClient: invalidate detail + list queries%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant User participant ScheduleComposer participant useCreateAgentRunSchedule participant AgentexSDK participant QueryClient participant ScheduledTasksPage User->>ScheduleComposer: Enter prompt + cadence, click Schedule ScheduleComposer->>ScheduleComposer: generateScheduleName(prompt, existingSchedules) ScheduleComposer->>ScheduleComposer: cadenceToPayload(cadence) → cron/interval ScheduleComposer->>useCreateAgentRunSchedule: mutateAsync(payload) useCreateAgentRunSchedule->>AgentexSDK: agents.schedules.create(agentId, payload) AgentexSDK-->>useCreateAgentRunSchedule: AgentRunScheduleResponse useCreateAgentRunSchedule->>QueryClient: invalidateQueries(byAgentId) + setQueryData(detail) useCreateAgentRunSchedule-->>ScheduleComposer: AgentRunSchedule (normalized) ScheduleComposer->>ScheduleComposer: Show success feedback (auto-dismiss 10s) User->>ScheduledTasksPage: Click Upcoming tab ScheduledTasksPage->>ScheduledTasksPage: collectUpcomingRuns(items) → sort by runTime ScheduledTasksPage->>ScheduledTasksPage: getDefaultUpcomingRuns (≤10 total, ≤3/schedule) ScheduledTasksPage->>ScheduledTasksPage: groupUpcomingRuns → Today/Tomorrow/Later User->>ScheduledTasksPage: Run now (upcoming row) ScheduledTasksPage->>AgentexSDK: schedules.trigger(scheduleId) AgentexSDK-->>ScheduledTasksPage: success QueryClient->>QueryClient: invalidate detail + list queriesReviews (7): Last reviewed commit: "fix(ui): fail closed on invalid feature ..." | Re-trigger Greptile