Skip to content

feat(ui): add scheduled task management#354

Open
jromualdez-scale wants to merge 17 commits into
mainfrom
jerome/scheduled-tasks-ui
Open

feat(ui): add scheduled task management#354
jromualdez-scale wants to merge 17 commits into
mainfrom
jerome/scheduled-tasks-ui

Conversation

@jromualdez-scale

@jromualdez-scale jromualdez-scale commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add a Scheduled Tasks experience with direct creation, a consolidated cadence editor, active/paused controls, edit flows, irreversible-delete confirmation, and a disabled “Snooze — coming soon” affordance.
  • Add an occurrence-focused Upcoming timeline with current/all-agent scope, synchronized task-sidebar filtering, balanced previews for frequent schedules, run-now flows, and exact skip/unskip actions.
  • Use the generated TypeScript schedule SDK, label scheduled runs consistently in the task sidebar, and keep scheduled task titles stable without appending occurrence timestamps.

UX details

  • Create schedules immediately without a confirmation step; show animated pending/success feedback with Edit and auto-dismiss.
  • Group upcoming runs into Today, Tomorrow, and Later; show 10 by default with at most 3 per schedule, then allow expansion to the 10 occurrences returned per schedule.
  • Keep occurrence actions scoped to Skip/Unskip and Edit schedule; keep Pause/Resume, Delete, Run now, and Skip next run in the Schedules view.
  • Keep schedule names consistent with agent naming semantics: auto-generated kebab-case names are displayed and copied to scheduled task metadata.

Test plan

  • npm --prefix agentex-ui run typecheck
  • npm --prefix agentex-ui run lint
  • npm --prefix agentex-ui run test:run -- hooks/use-safe-search-params.test.tsx lib/agent-run-schedules.test.ts lib/schedule-utils.test.ts
  • Local smoke test with two registered agents, cross-agent schedule scope, upcoming schedule details, and schedule actions
  • Pre-commit Agentex UI lint hooks
Screen.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.

  • Adds 10 new components and hooks under scheduled-tasks/ and hooks/, backed by the generated TypeScript schedule SDK, with TanStack Query for caching and invalidation.
  • Removes _format_fire_time from the Python activity layer, replacing the "Scheduled Message: name · timestamp" display name with a stable schedule.name; a LEGACY_SCHEDULED_MESSAGE_PREFIX strip in task-utils.ts handles pre-migration tasks.
  • Feature-gates the entire experience behind ENABLE_AGENT_RUN_SCHEDULES, now parsed safely via a new parseBooleanEnv utility that warns and defaults to false for 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

Filename Overview
agentex-ui/lib/schedule-utils.ts Core cadence utilities: cron/interval conversion, name generation, and description helpers. describeCadence comment claims a raw-expression fallback for complex crons that isn't implemented — misleading labels possible if external schedules are introduced.
agentex-ui/components/scheduled-tasks/all-schedules-list.tsx Schedules list UI with toggle and overflow menu. Both the toggle button and the overflow menu create independent pause/resume mutation instances, allowing concurrent conflicting API calls if both are triggered rapidly.
agentex-ui/components/scheduled-tasks/schedule-composer.tsx Schedule creation composer with animated pending/success feedback and auto-dismiss. Minor: inline 10000 ms magic number should be a named constant.
agentex-ui/components/scheduled-tasks/scheduled-tasks-page.tsx Top-level page orchestrating scope selector, view tabs, and schedule/upcoming lists. Data flow and loading/error states are handled cleanly.
agentex-ui/components/scheduled-tasks/upcoming-schedule-list.tsx Upcoming runs timeline with Today/Tomorrow/Later grouping, default capped view, and Run-now modal. Sequential trigger+skip flow correctly relies on mutation onError toasts rather than IIFE error propagation.
agentex-ui/hooks/use-agent-run-schedules.ts TanStack Query hooks for schedule CRUD and actions. Limit is now SCHEDULE_LIST_LIMIT = 50, consistent with UI copy. Cache invalidation and optimistic seeding of detail queries look correct.
agentex-ui/lib/agent-run-schedules.ts Schedule type definitions and normalization adapter. Correctly defaults optional API fields and normalizes initial_input shape.
agentex-ui/lib/env-utils.ts Added parseBooleanEnv that safely defaults unrecognized values to false with a console.warn, avoiding the previous throwing behavior noted in review history.
agentex-ui/components/scheduled-tasks/schedule-helpers.ts Shared helpers for grouping, formatting, sorting, and outside-click detection. getUpcomingRuns deduplication by ISO key correctly handles overlap between next_action_times and skipped_action_times.
agentex/src/temporal/activities/scheduled_agent_run_activities.py Removes timestamp-appended display names in favor of stable schedule.name. _format_fire_time removed; metadata ordering preserved so caller-supplied task_metadata.display_name still overrides.
agentex-ui/lib/task-utils.ts Adds isScheduledTask helper and strips the legacy 'Scheduled Message: ' prefix for backward-compatible display of pre-migration tasks.
agentex-ui/components/scheduled-tasks/cadence-picker.tsx Cadence picker with daily/weekly/monthly/interval tabs, time selector, and timezone dropdown. TimezoneSelect correctly uses replaceAll for underscore-to-space formatting.
agentex-ui/hooks/use-safe-search-params.ts Adds view and scheduleScope URL params with validated enum parsing. New params correctly included in the memoization dependency array.

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
Loading
%%{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 queries
Loading

Reviews (7): Last reviewed commit: "fix(ui): fail closed on invalid feature ..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

✱ Stainless preview builds

This PR will update the agentex-sdk SDKs with the following commit messages.

openapi

feat(api): add skip/unskip/by-name methods, response fields to schedules

python

feat: Add scheduled tasks UI polish

typescript

feat(api): add num_tasks_created and skipped_action_times fields to schedules

Edit this comment to update them. They will appear in their respective SDK's changelogs.

agentex-sdk-openapi studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ❗

New diagnostics (2 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/skip`
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/unskip`
agentex-sdk-typescript studio · code · diff

Your SDK build had at least one new note diagnostic, which is a regression from the base state.
generate ❗build ✅lint ✅test ✅

npm install https://pkg.stainless.com/s/agentex-sdk-typescript/8cb79bd084af03a986befc8095d4a943d2c5301f/dist.tar.gz
New diagnostics (2 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/skip`
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/unskip`
agentex-sdk-python studio · conflict

Your SDK build had at least one new note diagnostic, which is a regression from the base state.

New diagnostics (2 note)
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/skip`
💡 Endpoint/NotConfigured: Skipped endpoint because it's not in your Stainless config: `post /agents/{agent_id}/schedules/{schedule_id}/unskip`

This comment is auto-generated by GitHub Actions and is automatically kept up to date as you push.
If you push custom code to the preview branch, re-run this workflow to update the comment.
Last updated: 2026-07-09 17:13:15 UTC

@jromualdez-scale jromualdez-scale force-pushed the jerome/scheduled-tasks-ui branch 2 times, most recently from 8445f04 to 0673c3d Compare July 9, 2026 17:05
jromualdez-scale and others added 6 commits July 10, 2026 13:00
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>
@jromualdez-scale jromualdez-scale force-pushed the jerome/scheduled-tasks-ui branch from 0673c3d to e36d4cd Compare July 10, 2026 17:40
Co-authored-by: Cursor <cursoragent@cursor.com>
@socket-security

socket-security Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​agentex@​0.1.0-alpha.9 ⏵ 0.1.0-alpha.2078 -110099 +196 +5100

View full report

@jromualdez-scale jromualdez-scale changed the title Add scheduled tasks UI polish feat(ui): add scheduled task management Jul 13, 2026
@jromualdez-scale jromualdez-scale marked this pull request as ready for review July 13, 2026 15:37
@jromualdez-scale jromualdez-scale requested a review from a team as a code owner July 13, 2026 15:37
@jromualdez-scale jromualdez-scale marked this pull request as draft July 13, 2026 15:38
Comment thread agentex-ui/components/scheduled-tasks/scheduled-tasks-page.tsx Outdated
Comment thread agentex-ui/hooks/use-agent-run-schedules.ts
Co-authored-by: Cursor <cursoragent@cursor.com>
@jromualdez-scale jromualdez-scale marked this pull request as ready for review July 13, 2026 17:29
@jromualdez-scale jromualdez-scale marked this pull request as draft July 13, 2026 17:31
jromualdez-scale and others added 2 commits July 13, 2026 14:09
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@jromualdez-scale jromualdez-scale marked this pull request as ready for review July 13, 2026 18:23
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>
Comment thread agentex-ui/components/task-sidebar/task-sidebar-header.tsx Outdated
Comment thread agentex-ui/hooks/use-agent-run-schedules.ts
Comment thread agentex-ui/lib/schedule-utils.ts
Comment thread agentex-ui/components/scheduled-tasks/scheduled-tasks-page.tsx Outdated
Comment thread agentex-ui/components/scheduled-tasks/scheduled-tasks-page.tsx Outdated
Comment thread agentex-ui/components/scheduled-tasks/scheduled-tasks-page.tsx

@declan-scale declan-scale left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran locally, looks good, just some organization / small ui improvements I'd suggest

jromualdez-scale and others added 2 commits July 14, 2026 21:59
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@jromualdez-scale

Copy link
Copy Markdown
Contributor Author

Ran locally, looks good, just some organization / small ui improvements I'd suggest

Thanks for the great comments @declan-scale I addressed them all

Comment thread agentex-ui/app/page.tsx
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.

2 participants