Skip to content

feat: schedule and webhook triggers#823

Open
a7m-1st wants to merge 98 commits intomainfrom
feat-trigger
Open

feat: schedule and webhook triggers#823
a7m-1st wants to merge 98 commits intomainfrom
feat-trigger

Conversation

@a7m-1st
Copy link
Collaborator

@a7m-1st a7m-1st commented Jan 12, 2026

Description

  • Depends on the sever side implementation
  • Introduced the Trigger feature
image

Highlights and upgrades

UX - Click twice to edit trigger (in addition to edit button)
UX - Added a webhook dialog after its creation
UX - Live notifications shows all the logs from all triggers (can be modified)
Logic - A single websocket (if trigger is available) per session for all projects
Server - Execution Event marked as missed if not acknowledged in 60 seconds

To dos

  • UI
  • Integrate CRUD into UI
  • Integrate Real time changes
  • Run the task in foreground project
  • Add concurrent tasks to queue
  • Run each trigger and project in the background (need to update handleSend logic)

Small issues

  • When clicking to Edit trigger it is not consistent (fields empty)
  • All time sent to client is utc based - need to convert to local time in client
  • Custom crons doesn't update next run at in UI.

What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

@a7m-1st a7m-1st self-assigned this Jan 12, 2026
@a7m-1st a7m-1st requested a review from Pakchoioioi January 12, 2026 12:36
@a7m-1st a7m-1st force-pushed the feat-trigger branch 3 times, most recently from 366b2b6 to e191f11 Compare February 4, 2026 16:47
@Pakchoioioi Pakchoioioi linked an issue Feb 17, 2026 that may be closed by this pull request
…hrough an exception

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@a7m-1st a7m-1st requested a review from Copilot February 17, 2026 11:27
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds the new Trigger feature (schedule + webhook) end-to-end, including UI/UX updates, real-time execution handling, and server-side scheduling/execution infrastructure.

Changes:

  • Introduces trigger CRUD + execution logs UI, plus trigger-driven task queueing/execution via WebSocket events.
  • Adds shared UI component upgrades (Tabs animation, Select/Popover/Input enhancements, new Table, Switch sizing, etc.) and i18n strings.
  • Adds server trigger models/migrations, Redis + Celery worker/beat in Docker, and scheduled polling/timeout checking tasks.

Reviewed changes

Copilot reviewed 115 out of 198 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
src/i18n/locales/ja/index.ts Registers new triggers locale namespace.
src/i18n/locales/ja/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/it/workforce.json Adds workforce advanced model config strings.
src/i18n/locales/it/index.ts Registers new triggers locale namespace.
src/i18n/locales/it/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/fr/workforce.json Adds workforce advanced model config strings.
src/i18n/locales/fr/index.ts Registers new triggers locale namespace.
src/i18n/locales/fr/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/es/workforce.json Adds workforce advanced model config strings.
src/i18n/locales/es/index.ts Registers new triggers locale namespace.
src/i18n/locales/es/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/en-us/index.ts Registers new triggers locale namespace.
src/i18n/locales/en-us/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/de/workforce.json Adds workforce advanced model config strings.
src/i18n/locales/de/index.ts Registers new triggers locale namespace.
src/i18n/locales/de/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/i18n/locales/ar/workforce.json Adds workforce advanced model config strings.
src/i18n/locales/ar/index.ts Registers new triggers locale namespace.
src/i18n/locales/ar/chat.json Adds chat UI strings for queued tasks / attachments / expand input.
src/hooks/useTriggerTaskExecutor.ts Queues and dispatches trigger-driven tasks into project message queues.
src/hooks/queries/useTriggerQueries.ts Adds React Query hooks for triggers list/config/count + cache invalidation.
src/components/ui/tooltip.tsx Extends TooltipSimple with delay + enable/disable behavior.
src/components/ui/toggle-group.tsx Adjusts toggle group item base styling.
src/components/ui/textarea.tsx Updates textarea styling and state visuals.
src/components/ui/tabs.tsx Adds variants + animated outline slider + animated content transitions.
src/components/ui/table.tsx Adds new Table UI primitives.
src/components/ui/switch.tsx Adds size variants to Switch.
src/components/ui/select.tsx Enhances Select trigger with tooltip + required marker + new focus/hover visuals.
src/components/ui/popover.tsx Major Popover UI expansion: trigger states, sizing, list items, viewport, scroll handling.
src/components/ui/input.tsx Adds optional display and updates hover/focus handling.
src/components/ui/dialog.tsx Improves dialog overlay/content styling and adds footer border-on-scroll behavior.
src/components/ui/card.tsx Simplifies card styling (border-only).
src/components/ui/accordion.tsx Changes accordion content padding.
src/components/WorkSpaceMenu/index.tsx Updates workspace menu UI and adds viewport nav buttons.
src/components/WorkFlow/index.tsx Hooks workflow viewport movement into a shared store for external controls.
src/components/Trigger/TriggerTaskInput.tsx Adds trigger task prompt textarea component.
src/components/Trigger/TriggerListItem.tsx Adds trigger list row UI with status/actions and auth-required states.
src/components/Trigger/ExecutionLogs.tsx Adds execution log viewer + real-time refresh via activity logs.
src/components/Trigger/ActivityLogItem.tsx Adds activity log row UI with expandable metadata.
src/components/TopBar/index.tsx Adjusts titlebar layout and end-project button styling.
src/components/TerminalAgentWrokSpace/index.tsx Updates layout sizing and background styles.
src/components/SideBar/index.tsx Reworks sidebar items + adds inbox red-dot based on new-file count.
src/components/MenuButton/MenuButton.tsx Adds variants/sizes and richer layout (rightElement/subIcon handling).
src/components/GroupedHistoryView/index.tsx Adds total_triggers, skeleton loading UI, and trims icon imports.
src/components/GroupedHistoryView/TaskItem.tsx Switches to shared datetime formatting helper.
src/components/GroupedHistoryView/ProjectGroup.tsx Adds trigger count display in list and grid views.
src/components/Folder/index.tsx Removes back button and adjusts title styling.
src/components/ChatBox/UserQueryGroup.tsx Adds task-completion CTA card.
src/components/ChatBox/ProjectChatContainer.tsx Forces always-visible scrollbar styling.
src/components/ChatBox/MessageItem/TaskCompletionCard.tsx Adds “task completed → add trigger” CTA and opens TriggerDialog.
src/components/ChatBox/HeaderBox/index.tsx Adds header with token count and replay button.
src/components/ChatBox/BottomBox/index.tsx Enables queued box and simplifies layout; removes BoxAction usage.
src/components/ChatBox/BottomBox/QueuedBox.tsx i18n-ifies queued tasks UI strings.
src/components/ChatBox/BottomBox/InputBox.tsx Adds trigger button + TriggerDialog, Cmd/Ctrl+P expanded input dialog infra.
src/components/ChatBox/BottomBox/ExpandedInputBox.tsx Adds expanded input modal layout including agent chips and worker add.
src/components/ChatBox/BottomBox/BoxHeader.tsx i18n-ifies Splitting/Confirm headers and tweaks spacing.
src/components/ChatBox/BottomBox/BoxAction.tsx Removes token/replay UI and leaves placeholder.
src/components/BrowserAgentWorkSpace/index.tsx Updates layout sizing and background styles.
src/components/BottomBar/index.tsx Passes chat panel toggle props into WorkSpaceMenu.
src/components/AddWorker/index.tsx Adds controlled open support + icon variant; adds loading fallback.
src/App.tsx Adds React Query provider + trigger execution subscription/executor wiring.
server/pyproject.toml Adds limiter/slack/celery deps and a git source override.
server/docker-compose.yml Adds Redis + Celery worker/beat, env wiring, healthchecks.
server/docker-compose.dev.yml Adds Redis service for dev.
server/celery/worker/start Adds Celery worker start script.
server/celery/beat/start Adds Celery beat start script.
server/app/type/trigger_types.py Adds trigger/execution enums.
server/app/service/trigger/init.py Exposes trigger services/handlers package API.
server/app/schedule/trigger_schedule_task.py Adds Celery tasks for schedule polling and timeout checking.
server/app/model/trigger/trigger_execution.py Adds trigger execution SQLModel + DTOs.
server/app/model/trigger/trigger.py Adds trigger SQLModel + DTOs/config schema out.
server/app/model/trigger/app_configs/webhook_config.py Adds webhook trigger config schema + filtering helpers.
server/app/model/trigger/app_configs/slack_config.py Adds Slack trigger config schema + credential requirements.
server/app/model/trigger/app_configs/schedule_config.py Adds schedule trigger config schema + expiration/date validators.
server/app/model/trigger/app_configs/config_registry.py Adds registry for config class lookup/validation/schema generation.
server/app/model/trigger/app_configs/base_config.py Adds base config model, activation requirements checks, regex validation.
server/app/model/trigger/app_configs/init.py Exports trigger config types and registry functions.
server/app/model/trigger/init.py Registers trigger models for import and Alembic auto-import.
server/app/model/chat/chat_history_grouped.py Adds total_triggers to ProjectGroup response model.
server/app/controller/trigger/slack_controller.py Adds endpoint to list Slack channels based on stored credentials.
server/app/controller/trigger/init.py Adds trigger controller package init.
server/app/controller/chat/history_controller.py Adds trigger counts per project + filters placeholder trigger-created tasks.
server/app/component/trigger_utils.py Adds trigger rate-limit helpers and scheduling constants.
server/app/component/service/trigger/init.py Adds a duplicate trigger service re-export package.
server/app/component/schedule/trigger_schedule_task.py Adds a duplicate schedule task module (appears duplicated from app/schedule).
server/app/component/celery.py Adds Celery app configuration + beat schedules.
server/app/init.py Adds FastAPI lifespan to init FastAPI-Limiter with Redis.
server/alembic/versions/2026_02_06_0440-9464b9d89de7_feat_trigger.py Adds trigger + trigger_execution tables migration.
server/alembic/env.py Registers trigger models and switches offline URL to env var.
server/Dockerfile Adds git/curl/build deps + Rust toolchain; chmod celery scripts.
server/.env.example Documents Redis/Celery and trigger poller/timeout env vars.
package.json Adds React Query, date-fns, and react-day-picker dependencies.
backend/app/utils/telemetry/init.py Adds telemetry package init stub.
Comments suppressed due to low confidence (1)

server/app/component/service/trigger/init.py:1

  • This module duplicates server/app/service/trigger/__init__.py (same re-exports under a different package path). Having two public entry-points for the same service APIs is confusing and can lead to inconsistent imports across the codebase. Consider removing the duplicate and standardizing imports on a single package path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to +62
return useQuery({
queryKey: queryKeys.triggers.list(projectId),
queryFn: async () => {
if (!projectId) {
return { items: [], total: 0 };
}
const response = await proxyFetchProjectTriggers(
projectId,
triggerType,
status,
page,
size
);
return response;
},
enabled: enabled && !!projectId,
});
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The queryKey only keys on projectId but the queryFn result also depends on triggerType, status, page, and size. This will cause cache collisions (e.g., paging/filters returning stale or incorrect data). Include all inputs that affect the result in the queryKey (or use a dedicated queryKeys helper that encodes those parameters).

Copilot uses AI. Check for mistakes.
Comment on lines +375 to +384
// Register moveViewport callbacks with the store
const { setMoveLeft, setMoveRight } = useWorkflowViewportStore();
useEffect(() => {
setMoveLeft(() => moveViewport(200));
setMoveRight(() => moveViewport(-200));
return () => {
setMoveLeft(null);
setMoveRight(null);
};
}, [setMoveLeft, setMoveRight, isAnimating, clampViewportX]);
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

moveViewport is not memoized and not included in the effect dependencies, so the callbacks stored in Zustand can capture a stale moveViewport closure (and stale isAnimating, clamp logic, etc.). Wrap moveViewport in useCallback and include it in the dependency array, or register callbacks using a stable wrapper that always calls the latest moveViewport via a ref.

Copilot uses AI. Check for mistakes.
className={cn(
// Base styles
'relative flex w-full items-center justify-between gap-2 rounded-lg border border-solid border-input-border-default px-3 text-text-body outline-none transition-colors',
'relative flex w-full items-center justify-between gap-2 rounded-lg border-solid px-3 text-text-body outline-none transition-all',
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The trigger base class removed the border class (border width), but state classes mostly only set border color/ring. This will likely result in no visible border in default/disabled/error states. Re-add border to the base styles (or ensure a border-width utility is applied in all relevant states).

Suggested change
'relative flex w-full items-center justify-between gap-2 rounded-lg border-solid px-3 text-text-body outline-none transition-all',
'relative flex w-full items-center justify-between gap-2 rounded-lg border border-solid px-3 text-text-body outline-none transition-all',

Copilot uses AI. Check for mistakes.
'focus-visible:ring-0 data-[state=open]:bg-input-bg-input',
'focus-within:border-input-border-focus',
],
!state && 'bg-input-bg-default',
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

The trigger base class removed the border class (border width), but state classes mostly only set border color/ring. This will likely result in no visible border in default/disabled/error states. Re-add border to the base styles (or ensure a border-width utility is applied in all relevant states).

Copilot uses AI. Check for mistakes.
This is a lightweight wrapper around TriggerScheduleService that handles
session management and delegates all business logic to the service layer.
"""
logger.info("Starting poll_trigger_schedules task")
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

logger is referenced but never defined in this module, which will raise NameError if this task module is imported/executed. Either define logger = logging.getLogger(...) (as done in app/schedule/trigger_schedule_task.py) or remove this duplicated module if it’s unintended.

Copilot uses AI. Check for mistakes.
className="rounded-lg h-fit"
>
<Plus className="w-4 h-4" />
Add trigger
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

This component hardcodes user-facing strings while also initializing useTranslation(). Please move these strings into i18n keys and use t(...) so the completion CTA is localized consistently with the rest of the UI.

Copilot uses AI. Check for mistakes.
</TooltipProvider>
);
}
);
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

TooltipSimple.displayName = 'TooltipSimple' was removed. Re-adding a displayName is helpful for React DevTools/debugging (especially for forwardRef components).

Suggested change
);
);
TooltipSimple.displayName = 'TooltipSimple';

Copilot uses AI. Check for mistakes.
const setDialogOpen = isControlled ? onOpenChange : setInternalOpen;
const { chatStore, projectStore } = useChatStoreAdapter();
if (!chatStore) {
return <div>Loading...</div>;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

This introduces a user-facing “Loading...” string that isn’t localized and may flash in layout-critical areas (e.g., menus/modals). Prefer returning null/a skeleton, or using an existing localized loading label via i18n.

Suggested change
return <div>Loading...</div>;
return null;

Copilot uses AI. Check for mistakes.
);
}
);
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

PopoverContent.displayName is assigned twice. Remove the duplicate assignment to reduce noise and prevent confusion during future edits.

Copilot uses AI. Check for mistakes.
selected?: boolean;
disabled?: boolean;
};
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

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

PopoverContent.displayName is assigned twice. Remove the duplicate assignment to reduce noise and prevent confusion during future edits.

Suggested change
PopoverContent.displayName = PopoverPrimitive.Content.displayName;

Copilot uses AI. Check for mistakes.
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.

[Feature Request] Test and Go-live with Trigger feature

3 participants