[feat] Automations on mobile, and one automation instead of two triggers - #6716
[feat] Automations on mobile, and one automation instead of two triggers#6716ashrafchowdury wants to merge 113 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 SummarySummary by CodeRabbit
WalkthroughThe change adds a shared automation UI package, new mobile automation routes and screens, unified automation drawers, removal of legacy trigger settings, and reusable filter-menu and input-group components. ChangesAutomation package
Mobile automation surfaces
Legacy trigger migration
Shared UI primitives
Priority: ➖ Normal Estimated code review effort: 5 (Critical) | ~120 minutes Severity of issue fixed: Medium Merge Risk: 🟡 Moderate · up to The unified automation migration can currently fail to build, bind an automation to the wrong connected account, and prevent users from reaching events in long picker lists. These issues should be resolved before merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 17
🧹 Nitpick comments (6)
web/packages/agenta-ui/src/filter-menu/GroupMenu.tsx (1)
111-111: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMerge
classNamewith the base popover classes instead of replacing them.
className ?? "w-[220px] p-0"dropsp-0whenever a consumer passes any class. The popover then falls back to its defaultp-1padding, and the option list adds its ownp-1, so the panel renders with double padding. Merge withcnso a consumer can override width without losing the layout reset.Note also that
classNametargets the popover surface here, butFilterMenuforwardsclassNametoFilterMenuPanel(FilterMenu.tsxline 105). Consider documenting that difference on the prop.♻️ Proposed fix
-import {Popover, PopoverContent} from "../components/ui/popover" +import {Popover, PopoverContent} from "../components/ui/popover" +import {cn} from "../components/ui/utils"- className={className ?? "w-[220px] p-0"} + className={cn("w-[220px] p-0", className)}web/storybook/stories/FilterMenu.stories.tsx (1)
128-130: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winImport
ComponentPropsinstead of referencing theReactnamespace.
web/storybook/tsconfig.jsonincludes story files, enablesstrict, and does not enableallowUmdGlobalAccess. TheReact.ComponentPropsreference therefore causes a TypeScript UMD-global error. ImportComponentPropsdirectly.♻️ Proposed fix
-import {useState} from "react" +import {useState, type ComponentProps} from "react"-}: {withGroup?: boolean; emptyAgents?: boolean} & Partial< - React.ComponentProps<typeof FilterMenu> ->) => { +}: {withGroup?: boolean; emptyAgents?: boolean} & Partial<ComponentProps<typeof FilterMenu>>) => {web/packages/agenta-automation-ui/src/states/AutomationStates.tsx (1)
19-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExport this grid template once and consume it in the list screen.
web/mobile/src/features/automations/AutomationListScreen.tsxlines 73-74 hold a byte-identical copy of this string. The skeleton must match the table cell for cell, so the two copies can drift without any test noticing. Export the constant from this package and import it in the screen.web/packages/agenta-automation-ui/src/AutomationAgentField.tsx (1)
18-29: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReduce the multi-line comment blocks to one short line each. The new package files carry multi-paragraph rationale comments. The coding guideline for
web/**/*.{ts,tsx}sets a hard limit of one short line per comment. Move the longer rationale to the package README or a design note.
web/packages/agenta-automation-ui/src/AutomationAgentField.tsx#L18-L29: reduce theAutomationAgentFielddocblock to one line; the same applies to the inline block at L54-56.web/packages/agenta-automation-ui/src/AutomationCreateBody.tsx#L11-L18: reduce theAutomationCreateBodydocblock to one line; the same applies to the inline block at L36-37.web/packages/agenta-automation-ui/src/AutomationField.tsx#L3-L9: reduce theAutomationFielddocblock to one line.web/packages/agenta-automation-ui/src/AutomationTitle.tsx#L8-L14: reduce theAutomationTitledocblock to one line; the same applies to the inline block at L81-82.As per coding guidelines: "Hard rule. At most ONE short line per comment."
Source: Coding guidelines
web/packages/agenta-automation-ui/package.json (1)
25-25: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winAlign the
lucide-reactrange with the other workspaces.
web/pnpm-lock.yamlresolves bothlucide-react@0.475.0andlucide-react@0.479.0. The consumingweb/ossandweb/mobileapplications import@agenta/automation-ui, whose source importslucide-react, so both versions can enter their bundles. Use the shared range and regenerate the lockfile.♻️ Proposed change
- "lucide-react": "^0.475.0" + "lucide-react": "^0.479.0"web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/ScheduleBuilderField.tsx (1)
291-298: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe next-run line now renders twice in
ScheduleBuilderField.The panel prints the "Next run …" footer.
ScheduleBuilderFieldstill prints the samenextLineunder the popover trigger at lines 345-349. While the popover is open, the user sees the sentence twice.
AutomationRunsWhenFieldrelies on the panel owning this line, so the footer belongs here. Remove the duplicate fromScheduleBuilderField.♻️ Proposed change in `ScheduleBuilderField`
</Popover> - - {nextLine ? ( - <span className="text-xs leading-snug text-[var(--ag-colorTextDescription)]"> - {nextLine} - </span> - ) : null} </div>Then drop
nextLinefrom the destructure at line 311.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Advanced
Run ID: 90a21abd-eedf-4181-94ff-3702370a1de3
⛔ Files ignored due to path filters (1)
web/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (139)
web/mobile/next.config.tsweb/mobile/package.jsonweb/mobile/src/components/StatusTag.tsxweb/mobile/src/components/ui/dialog.tsxweb/mobile/src/components/ui/input-group.tsxweb/mobile/src/features/automations/AutomationActionsMenu.tsxweb/mobile/src/features/automations/AutomationDetailScreen.tsxweb/mobile/src/features/automations/AutomationDraftScreen.tsxweb/mobile/src/features/automations/AutomationFilterMenu.tsxweb/mobile/src/features/automations/AutomationListScreen.tsxweb/mobile/src/features/automations/AutomationRunConversation.tsxweb/mobile/src/features/automations/AutomationTestRunButton.tsxweb/mobile/src/features/automations/useUnsavedGuard.tsweb/mobile/src/features/chat/ConfigPane.tsxweb/mobile/src/features/chat/useStartBlankSession.tsweb/mobile/src/features/nav/useMobileNavItems.tsxweb/mobile/src/features/sessions/SessionAutomationDrawers.tsxweb/mobile/src/features/settings/ConfirmModal.tsxweb/mobile/src/features/settings/ConfirmSheet.tsxweb/mobile/src/features/settings/LlmProvidersTab.tsxweb/mobile/src/features/settings/SecretsTab.tsxweb/mobile/src/features/settings/SettingsScreen.tsxweb/mobile/src/features/settings/WebhooksTab.tsxweb/mobile/src/features/settings/settingsTabs.tsweb/mobile/src/features/settings/useConfirmModal.tsxweb/mobile/src/pages/w/[workspace_id]/p/[project_id]/automations/[automation_id].tsxweb/mobile/src/pages/w/[workspace_id]/p/[project_id]/automations/index.tsxweb/mobile/src/pages/w/[workspace_id]/p/[project_id]/automations/new.tsxweb/mobile/src/styles/globals.cssweb/oss/next.config.tsweb/oss/package.jsonweb/oss/src/components/Playground/Components/PlaygroundVariantConfig/index.tsxweb/oss/src/components/pages/sessions/components/SessionAutomationDrawers.tsxweb/oss/src/components/pages/settings/README.mdweb/oss/src/components/pages/settings/Triggers/Triggers.tsxweb/oss/src/components/pages/settings/Triggers/components/GatewayTriggersSection.tsxweb/oss/src/components/pages/settings/Triggers/components/useAgentNameById.tsweb/oss/src/components/pages/settings/hooks/useSettingsAccess.tsweb/oss/src/pages/w/[workspace_id]/p/[project_id]/settings/index.tsxweb/oss/tailwind.config.tsweb/packages/agenta-automation-ui/eslint.config.mjsweb/packages/agenta-automation-ui/package.jsonweb/packages/agenta-automation-ui/src/AutomationAgentField.tsxweb/packages/agenta-automation-ui/src/AutomationBackLink.tsxweb/packages/agenta-automation-ui/src/AutomationCreateBody.tsxweb/packages/agenta-automation-ui/src/AutomationDetailBody.tsxweb/packages/agenta-automation-ui/src/AutomationDrawer.tsxweb/packages/agenta-automation-ui/src/AutomationFailureBanner.tsxweb/packages/agenta-automation-ui/src/AutomationField.tsxweb/packages/agenta-automation-ui/src/AutomationInstructionField.tsxweb/packages/agenta-automation-ui/src/AutomationMetaRow.tsxweb/packages/agenta-automation-ui/src/AutomationRunFilterMenu.tsxweb/packages/agenta-automation-ui/src/AutomationRunHistoryCard.tsxweb/packages/agenta-automation-ui/src/AutomationRunHistoryView.tsxweb/packages/agenta-automation-ui/src/AutomationRunList.tsxweb/packages/agenta-automation-ui/src/AutomationRunPane.tsxweb/packages/agenta-automation-ui/src/AutomationRunRow.tsxweb/packages/agenta-automation-ui/src/AutomationRunsWhenField.tsxweb/packages/agenta-automation-ui/src/AutomationSaveBar.tsxweb/packages/agenta-automation-ui/src/AutomationTemplateCard.tsxweb/packages/agenta-automation-ui/src/AutomationTitle.tsxweb/packages/agenta-automation-ui/src/AutomationTriggerDrawers.tsxweb/packages/agenta-automation-ui/src/automationEdit.tsweb/packages/agenta-automation-ui/src/automationListView.tsweb/packages/agenta-automation-ui/src/automationModel.tsweb/packages/agenta-automation-ui/src/index.tsweb/packages/agenta-automation-ui/src/lib/interactive.tsweb/packages/agenta-automation-ui/src/lib/useMediaQuery.tsweb/packages/agenta-automation-ui/src/lib/utils.tsweb/packages/agenta-automation-ui/src/pickers/AppIcon.tsxweb/packages/agenta-automation-ui/src/pickers/EventAppRail.tsxweb/packages/agenta-automation-ui/src/pickers/EventList.tsxweb/packages/agenta-automation-ui/src/pickers/EventPickerPanel.tsxweb/packages/agenta-automation-ui/src/pickers/EventRow.tsxweb/packages/agenta-automation-ui/src/pickers/EventSearchGroup.tsxweb/packages/agenta-automation-ui/src/pickers/EventSearchResults.tsxweb/packages/agenta-automation-ui/src/pickers/PickerOverlay.tsxweb/packages/agenta-automation-ui/src/pickers/connectedApps.tsweb/packages/agenta-automation-ui/src/runListView.tsweb/packages/agenta-automation-ui/src/runModel.tsweb/packages/agenta-automation-ui/src/states/AutomationRunStates.tsxweb/packages/agenta-automation-ui/src/states/AutomationStates.tsxweb/packages/agenta-automation-ui/src/templates.tsweb/packages/agenta-automation-ui/src/useAutomation.tsweb/packages/agenta-automation-ui/src/useAutomationCreate.tsweb/packages/agenta-automation-ui/src/useAutomationDraft.tsweb/packages/agenta-automation-ui/src/useAutomationEditor.tsweb/packages/agenta-automation-ui/src/useAutomationRuns.tsweb/packages/agenta-automation-ui/src/useAutomations.tsweb/packages/agenta-automation-ui/tsconfig.jsonweb/packages/agenta-entity-ui/src/DrillInView/SchemaControls/AgentOperationsSections.tsxweb/packages/agenta-entity-ui/src/DrillInView/SchemaControls/TriggerManagementSection.tsxweb/packages/agenta-entity-ui/src/drawers/shared/HelpTip.tsxweb/packages/agenta-entity-ui/src/gatewayTool/components/FormItem.tsxweb/packages/agenta-entity-ui/src/gatewayTool/components/SchemaForm.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/ScheduleBuilderField.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerEventsDrawer.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerSubscriptionDrawer.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleForm.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/constants.tsweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/AgentField.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/FormSkeleton.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/VersionField.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/normalizeJson.tsweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/useShapeChange.tsweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/EventFieldList.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/InputsMappingField.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/MappingSection.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/PillEditor.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceBrowsePage.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceField.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionForm.tsxweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/constants.tsweb/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/helpers.tsweb/packages/agenta-entity-ui/src/gatewayTrigger/index.tsweb/packages/agenta-playground-ui/src/components/AgentBuildPanel.tsxweb/packages/agenta-settings-ui/src/index.tsweb/packages/agenta-settings-ui/src/triggers/TriggerConnectionsSection.tsxweb/packages/agenta-settings-ui/src/triggers/TriggerSchedulesSection.tsxweb/packages/agenta-settings-ui/src/triggers/TriggerSubscriptionsSection.tsxweb/packages/agenta-settings/src/access.tsxweb/packages/agenta-settings/src/navigation.tsweb/packages/agenta-settings/src/sidebar.tsxweb/packages/agenta-settings/tests/unit/navigation.test.tsweb/packages/agenta-ui/package.jsonweb/packages/agenta-ui/src/filter-menu/FilterMenu.tsxweb/packages/agenta-ui/src/filter-menu/FilterMenuOptionList.tsxweb/packages/agenta-ui/src/filter-menu/FilterMenuPanel.tsxweb/packages/agenta-ui/src/filter-menu/FilterMenuRow.tsxweb/packages/agenta-ui/src/filter-menu/FilterMenuTrigger.tsxweb/packages/agenta-ui/src/filter-menu/GroupMenu.tsxweb/packages/agenta-ui/src/filter-menu/index.tsweb/packages/agenta-ui/src/filter-menu/types.tsweb/packages/agenta-ui/src/filter-menu/useFilterMenuView.tsweb/storybook/stories/FilterMenu.stories.tsxweb/storybook/stories/GroupMenu.stories.tsxweb/storybook/stories/entity-ui/TriggerManagementSection.stories.tsxweb/turbo.json
💤 Files with no reviewable changes (32)
- web/oss/src/components/pages/settings/Triggers/Triggers.tsx
- web/packages/agenta-settings-ui/src/index.ts
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/constants.ts
- web/oss/src/components/pages/settings/hooks/useSettingsAccess.ts
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/normalizeJson.ts
- web/packages/agenta-settings/src/sidebar.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/MappingSection.tsx
- web/oss/src/components/pages/settings/Triggers/components/GatewayTriggersSection.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/PillEditor.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SubscriptionForm.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerSubscriptionDrawer.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/AgentField.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/FormSkeleton.tsx
- web/oss/src/components/pages/settings/Triggers/components/useAgentNameById.ts
- web/packages/agenta-settings-ui/src/triggers/TriggerSchedulesSection.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceBrowsePage.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/VersionField.tsx
- web/mobile/src/features/settings/ConfirmSheet.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/shared/useShapeChange.ts
- web/packages/agenta-settings/src/navigation.ts
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/InputsMappingField.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/helpers.ts
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerScheduleDrawer.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/SourceField.tsx
- web/packages/agenta-settings-ui/src/triggers/TriggerConnectionsSection.tsx
- web/packages/agenta-settings/src/access.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/EventFieldList.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/TriggerEventsDrawer.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/subscription/constants.ts
- web/oss/src/pages/w/[workspace_id]/p/[project_id]/settings/index.tsx
- web/packages/agenta-entity-ui/src/gatewayTrigger/drawers/schedule/ScheduleForm.tsx
- web/packages/agenta-settings-ui/src/triggers/TriggerSubscriptionsSection.tsx
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/packages/agenta-ui/src/filter-menu/useFilterMenuView.ts (1)
50-50: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUpdate the
setViewdependencies. Thereact-hooks/exhaustive-depsrule is disabled forweb, so this is not a lint failure. Ifpersistchanges whilekeystays the same,setViewuses the stale key list and writes incorrect fields. Addpersistto thesetViewdependency array; keep the mount-only effect unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Advanced
Run ID: 51dfa6d6-f311-46fb-823a-ad38a6d9e3a6
📒 Files selected for processing (13)
web/mobile/src/features/automations/AutomationActionsMenu.tsxweb/mobile/src/features/automations/AutomationDetailScreen.tsxweb/mobile/src/features/automations/AutomationListScreen.tsxweb/mobile/src/features/chat/ConfigPane.tsxweb/mobile/src/features/settings/ConfirmModal.tsxweb/packages/agenta-automation-ui/src/AutomationRunHistoryView.tsxweb/packages/agenta-automation-ui/src/AutomationSaveBar.tsxweb/packages/agenta-automation-ui/src/runListView.tsweb/packages/agenta-automation-ui/src/states/AutomationStates.tsxweb/packages/agenta-settings/tests/unit/navigation.test.tsweb/packages/agenta-ui/src/components/ui/index.tsweb/packages/agenta-ui/src/components/ui/input-group.tsxweb/packages/agenta-ui/src/filter-menu/useFilterMenuView.ts
💤 Files with no reviewable changes (1)
- web/mobile/src/features/automations/AutomationDetailScreen.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
- web/packages/agenta-automation-ui/src/AutomationRunHistoryView.tsx
- web/packages/agenta-automation-ui/src/AutomationSaveBar.tsx
- web/packages/agenta-automation-ui/src/runListView.ts
- web/packages/agenta-settings/tests/unit/navigation.test.ts
- web/mobile/src/features/chat/ConfigPane.tsx
- web/packages/agenta-automation-ui/src/states/AutomationStates.tsx
Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.
Railway Preview Environment
|
There was a problem hiding this comment.
Actionable comments posted: 4
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Advanced
Run ID: e52fef5f-12ed-4cab-9dcf-c39329b1c7bd
📒 Files selected for processing (9)
web/mobile/src/features/automations/AutomationDraftScreen.tsxweb/packages/agenta-automation-ui/src/AutomationDrawer.tsxweb/packages/agenta-automation-ui/src/pickers/EventAppRail.tsxweb/packages/agenta-automation-ui/src/pickers/EventList.tsxweb/packages/agenta-automation-ui/src/pickers/EventPickerPanel.tsxweb/packages/agenta-automation-ui/src/states/EventPickerStates.tsxweb/packages/agenta-entity-ui/src/gatewayTool/components/FormItem.tsxweb/packages/agenta-entity-ui/src/gatewayTool/components/SchemaForm.tsxweb/packages/agenta-ui/src/components/ui/accordion.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- web/packages/agenta-entity-ui/src/gatewayTool/components/FormItem.tsx
- web/packages/agenta-entity-ui/src/gatewayTool/components/SchemaForm.tsx
Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 3
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Advanced
Run ID: 7be5260b-2a6a-4938-9b91-778ad73d31e5
📒 Files selected for processing (15)
web/mobile/src/components/FilterChip.tsxweb/mobile/src/components/ui/button.tsxweb/mobile/src/features/automations/AutomationFilterMenu.tsxweb/mobile/src/features/chat/ToolLine.tsxweb/mobile/src/features/chat/TurnRow.tsxweb/mobile/src/features/context/ContextResolver.tsxweb/mobile/src/features/nav/NavDrawer.tsxweb/packages/agenta-automation-ui/src/AutomationTitle.tsxweb/packages/agenta-automation-ui/src/pickers/EventAppRail.tsxweb/packages/agenta-automation-ui/src/pickers/EventList.tsxweb/packages/agenta-automation-ui/src/pickers/EventPickerPanel.tsxweb/packages/agenta-automation-ui/src/pickers/PickerOverlay.tsxweb/packages/agenta-entity-ui/src/agent/AgentOverviewSkeleton.tsxweb/packages/agenta-entity-ui/src/agent/NextTriggersSection.tsxweb/packages/agenta-entity-ui/src/gatewayTool/components/SchemaForm.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
- web/packages/agenta-automation-ui/src/AutomationTitle.tsx
- web/packages/agenta-entity-ui/src/gatewayTool/components/SchemaForm.tsx
- web/packages/agenta-automation-ui/src/pickers/EventPickerPanel.tsx
- web/packages/agenta-automation-ui/src/pickers/EventAppRail.tsx
Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.
Adds the model, hooks, route shells and nav entry the Automations screens build on. A cron schedule and an event subscription are separate rows on separate endpoints, but a reader sees one list of things that run an agent, so automationModel maps both onto a single Automation type and every screen reads that instead of branching per entity. Delivery outcomes read status.message rather than the shared deliveryStatusColor helper, which reads a status.type the backend never sets and so returns neutral for every row.
Renders both trigger kinds in one table — name, status, when it runs, and the agent it runs — over the shared DataTable the settings trigger sections already use, with search across name, description and agent. Gives StatusTag a failed tone so a broken automation reads red. attention maps to the accent, which asks for a look rather than reporting a fault, and the two must not collapse once run outcomes land. The empty state is plain markup rather than EmptyState: its image slot is sized for a 184x152 illustration, and opting a 48px tile out of that took more overrides than the markup it replaced.
Config lives on the automation's own page rather than in a drawer, so creating and editing one later share a single surface. The name renames in place, ActiveToggle owns start/stop, and the three fields reuse the shared controls: ScheduleBuilderField for the cadence and MessageComposer for the instruction. Both trigger endpoints take a full PUT, so buildAutomationEdit copies every stored field off the source row and overlays only what changed - a rename must not drop the cron, the message or the agent binding. Neither field repeats the helper line its shared control already prints, and an unbound automation reads Pick an agent rather than naming one that isn't there.
…ents Both screens were built on default control sizing, which left every heading, row and gap a few pixels off. Sizes, weights, letter-spacing, padding, radii and the table's column ratios now come from the design. The list drops DataTable for a plain CSS grid. The shared table lays out a real table with a fixed-pixel colgroup, so it cannot express the design's minmax()/fr columns without being fought at every cell; one GRID constant now feeds the header, the rows and the skeleton so they cannot drift. Status in a column of its own is a dot and a coloured word, not a pill - the pill exists to separate a status from a sentence, and there is no sentence here.
Both pickers open as a popover on a wide screen and a bottom sheet on a phone, sharing one overlay helper - an anchored popover is the wrong affordance at phone width, and the design was drawn wide. The event side composes the package's own SourceBrowsePage and SchemaForm rather than reimplementing a catalog browser and a filter form; the two symbols it needed are added to the export block already kept for hosts outside the drawer. Agent rebinding goes through buildTriggerReferences so a pick writes a resolvable reference rather than an artifact-only one. A binding whose id is missing from the agent roster now reads Unknown agent. It used to read as unbound, which both misreported the automation and offered a rebind that would have replaced something real.
New automation and the template cards routed to /automations/new, which had no route - the dynamic segment caught it, read "new" as an id, and rendered "This automation no longer exists". A static route wins over the dynamic one and now renders the draft. Create and edit are the same surface, as the design draws them: the draft is the detail screen minus what a draft has not earned - no meta row, no failure banner, no run history - plus a footer whose Create stays disabled until an agent is bound. The create payload sits beside buildAutomationEdit so both PUT and POST shapes are read in one place, and the blank draft seeds its weekday cron in the comma form: cronToBuilder parses a plain int list, so 1-5 comes back unrepresentable and the field would open on a raw expression.
…story card The meta row states whether an automation is on, so it takes a switch, which shows that at rest. ActiveToggle is a play/pause button - right in a row of actions, wrong in a status line - so the pending guard and the messages it owned move here with it. The run history card is drawn two lines tall, a title over a run count. It collapses to one row until that count is wired, because a box sized for two lines holding one reads as padding around nothing.
The design opens Runs when on a choice between a schedule and an app event. Without it a schedule can never become an event trigger, which is the point of that control. ScheduleBuilderField is split into useScheduleBuilder + ScheduleBuilderPanel so its panel can sit inside a different popover, with the field itself rebuilt on the same pair - one implementation, and the existing drawer keeps its behaviour. Kind stays switchable only on a draft: the two kinds are separate rows on separate endpoints, so converting a saved one is a create, a delete and a redirect, not a PUT. The agent field is a real Select rather than a hand-rolled list, so it closes on pick, matches the schedule control's height, and drops a heading the design never had. Both overlays open at their trigger's width. Unknown agent now waits for the roster to answer. Reading it mid-load flashed a resolvable binding as broken.
Every button this feature added had picked up its own size or weight - sm here, a font override there - so no two agreed. They all sit at the default size now, with the normal weight the design draws, and carry no per-call geometry of their own.
24px was loud for a name that sits under a back link and above a short field stack. The rename input moves with it so the swap does not resize.
The rename field was a shadcn Input overridden to imitate the heading it replaced, which only made the swap a resize. It is the stock input now. The heading's tap target drops the shared FOCUS_RING for the soft ring the inputs use: a hard 2px outline in the near-black ring colour reads as a border around the title rather than as focus.
The panel was rendering the subscription drawer's integration catalog - a marketplace of ninety apps with descriptions, categories and action counts. That answers how to connect an app, not which event should run this automation, so it is replaced by what the design asks for: the apps this workspace has already connected, that app's events, and a search across them. Connect another app... is now the only route to the catalog, and it opens the real drawer. Apps are named and marked from the integrations catalog rather than the connection: a connection is named for the account it authorises, so the rail was reading gmail-main where it meant Gmail. Every event in a list wears its app's mark, and a mark that has not loaded is a skeleton, not a letter tile that looks like a broken icon.
…vision
An automation created from the automations page failed on every run with 'No user message
to send (prompt/messages empty)'. The instruction was saved as {"message": "…"}; the runner
reads `prompt` or `messages` and never `message`.
The key came from the workflow molecule, which reads a CACHED entity and never fetches. The
create screen knows the agent only from the agents list, whose rows carry neither
`flags.is_chat` nor an input schema, so `executionMode` returned its "completion" default
and the composer fell through to the literal "message". The playground drawer wrote
`messages` for the same agent, because there the agent was already open.
The field now resolves the agent's latest revision and reads the flag and the schema off it,
and stays disabled until that lands rather than guessing. `remapMessageShape` is wired back
in — it existed and was tested but lost its only caller when the old drawers were deleted —
so a message typed before the revision arrives is migrated rather than left under a dead key.
References bind the latest revision's own variant instead of 'the agent happens to have
exactly one', so an automation runs the newest revision whatever the variant count.
Uppercased in the model, so the heading could not be restyled without changing the data.
Choosing an agent was about to be re-implemented per screen — a Select here, a list there — which is how the search, the glyphs and the create affordance drift apart. AgentPicker is the one answer, in @agenta/entity-ui because it fetches its own agents: a picker whose host hands it a list is a picker every host populates differently. The design's two densities are one component. 'relaxed' prints each agent's description under its name for a screen with room to explain; 'compact' prints the name alone for a toolbar. The trigger is a field or a pill. Nothing else differs, so a reader who learns one has learned both. A description that does not exist still takes its line, saying so, or the rows change height and a blank reads as one that failed to load. A Popover rather than a Select, for the reason @agenta/ui/filter-menu is: a select's typeahead competes with the search field for every keystroke. Search covers the description as well as the name — an agent is often easier to recall by what it does. Focus lands in the field on open, a frame late, because Radix focuses the content wrapper first. Every row wears a chip, the agent's own colour when it has one and a neutral tile when not: a column where some rows have one reads as a rendering fault. The bound row keeps a tint of its own so 'which one is this set to' survives the pointer moving down the list. The automations agent field is now this component in that screen's frame.
A centred line of grey said the same thing for two different facts. A project with no agents and a search that matched none of the ones it has now read differently: one offers to make an agent, the other quotes what was typed, says the search covers names AND descriptions, and clears itself. Same frame as the other pickers here — a glyph in a tile, the fact, what to do.
…mode `bg-muted` sits within a hair of the popover's own surface there, so the tiles for agents without an icon disappeared while the coloured ones stayed — the column read as half-drawn. `colorFillSecondary` is the fill the agent chrome already uses for an unpicked icon, and it composites a clear step above the surface in both themes.
The Agent column drew a bare glyph while the control that set it drew a tinted tile, so the same agent looked like two different things a click apart. AgentChip comes out of the picker for it. The tile is not the picker's — any list that names agents wants the same one, and a second implementation is how two columns of the same agents stop matching.
fd615db to
d8f6f94
Compare
Sessions wants the same table, so the frame moves to @agenta/ui/list-table where the filter menu lives: presentational, antd-free, and column-agnostic. It knows a list has columns of some width, that rows sit under headings that collapse, and that a row opens something. It never learns what the rows ARE — the columns and the cells are the consumer's, which is why renderRow is a prop and not a set of cell types. ListTableToolbar is the row above it: the search field, then a slot. Not a filter prop — this row does not know what narrows the list, only that something does. A CSS grid rather than a <table>. shadcn's table was tried and dropped: the columns are minmax()/fr, the rows carry no cell borders, and a group heading spans the full width between two runs of rows — none of which a table layout gives without fighting it, and it turns every cell into a <td> a consumer has to remember to wrap. The automations list is the first consumer; nothing about it looks different.
Loading is a state of the table, not a screen beside it, so the frame draws it: the real columns in the real row rhythm, so the list arrives into the shape it was already occupying instead of snapping a spinner into a table under the reader's cursor. Bar widths cycle down each column, or five identical pills read as a grid rather than as text. Uses SkeletonBlock, not Skeleton. Skeleton is antd's composite (avatar + title + paragraph) and paints nothing of its own — a bare one renders a transparent box, which is exactly what the first attempt drew. Replaces the automations list's own AutomationListSkeleton, which restated the columns a second time and would have drifted from them.
Every one of them drew a transparent box. `Skeleton` from @agenta/ui is antd's composite (avatar + title + paragraph) and paints nothing of its own; `SkeletonBlock active` is the bar. The agent surfaces in entity-ui already used it, so this brings the rest into line. Six files: the run history's rows and day headings, the automations list and detail, the event picker's app rail, its event list and its app icons, and the agent picker.
…state in the table Three example cards sat on the emptiest screen in the product, asking the reader to choose before they knew what they were choosing between. They were also the only thing that ever set ?template=, so the seed, the card, the catalog and the query param all go together. What is left says what an automation IS, which is the one thing that screen has to do, and sits UNDER the column header rather than replacing the table: the columns are still true, and a project with no automations is a table with no rows, not a different screen. No button of its own either — New automation is already in the page header, and the same action twice on one screen reads as two different ones. An empty list is not the same as a search that matched nothing: the query is narrowed server-side, so a term with no matches empties the list too and used to claim the project had none.
The kind glyph sat bare beside a tinted agent tile, so two marks on one row read as two different kinds of thing. It gets a tile now, and the two kinds take their own tint: down a column, colour separates 'when something happens' from 'on a schedule' faster than two small glyphs do. The agent's tile stays at 20px — it is the second mark on a row, not the first.
Each said more than it needed to, and the instruction's line changed shape with the agent — naming the input key on a completion agent, which is a detail of the wire format rather than anything the reader chose. All three now state the one fact the control cannot.
A permanent bar sat over the right edge of every row and clipped the times to "17:0". The app's own ag-scroll-quiet keeps it invisible until the pointer is in the column.
The triggers worker built its dispatcher without a dispatch_fn, so it invoked the workflow INLINE — a POST to the runner behind a 60s httpx timeout. Any agent run longer than a minute raised a timeout whose string is empty, and the dispatcher's except branch wrote the delivery as 500/failed with a blank error while the runner carried on and finished the job. Every scheduled run of a real agent read as a failure: 20 of 20 on the account I checked, including one that demonstrably sent its email. It now dispatches detached, exactly as the interactions worker already does, and the delivery settles at 202/dispatched. That is honest but incomplete, and the gap is worth naming: nothing writes the run's terminal outcome afterwards, so a delivery stays 'dispatched' for good. The UI already treats anything that is neither succeeded nor failed as in-flight, so it needs no new state — but the word is now Running rather than Pending, because the runner has the work rather than queuing it. Closing a delivery on completion needs a durable callback the API does not have yet.
Context
The mobile app had no automations at all. You could talk to an agent, but you could not see what ran it on a schedule or on an app event, let alone change it from a phone.
On desktop, one idea existed as two. A subscription (an app event runs an agent) and a schedule (a cron runs an agent) each had their own Settings section, their own drawer, and their own form, and the agent panel listed them in two more places. Someone who wanted "run this agent when a GitHub issue opens, and again every Monday" had to learn two screens that did the same job.
What this adds
One automation, two ways to start it. Subscriptions and schedules are now a single automation edited in a single drawer. A "Runs when" control switches the kind in place instead of sending you to a different form.
Before:
Settings → Triggerswith separate Subscriptions and Schedules sections, plusTriggerEventsDrawer,TriggerScheduleDrawerandTriggerSubscriptionDrawerbehind roughly 2,500 lines of form code.After: one
AutomationDrawer, one list, one editor. The Triggers settings page is gone and the old forms are deleted.Automations on mobile. A list, a detail screen, a draft screen for a new one, run history with each run's conversation, a test run, and delete. A test run now opens the session with its instruction sitting in the composer, unsent, so you can read and change it before committing to a run.
A shared package. The screens live in a new
@agenta/automation-uiso both apps render the same thing. Mobile cannot use antd, so the package is antd-free and presentational; data comes in through props and hooks the host owns.A shared filter menu.
@agenta/ui/filter-menuis one popover that carries filtering, sorting and grouping together, because they are the same kind of question about a list. Rows open their options on hover, the search field matches both row labels and option labels, reset is a row rather than a footnote, and under 640px the rows drill in instead of fanning a flyout out over the panel they came from. The automations list and the run history both use it, and the sessions rail now opens its filters from it too.Grouping is remembered in
localStorage; filters are not. A list that reopens already narrowed looks broken, because the rows are missing and the reason is a menu away.Tests
pnpm --filter @agenta/settings testcovers the navigation entry the Triggers page left behind.FilterMenuandGroupMenu.?view=runs, the no-match state, the table restyle, the save bar, grouping persistence, column spacing) is parse-checked but not yet checked in a browser. The dev server was down while they were written. Worth a look during QA.Demo
Outstanding. Captures to follow.
What to QA
/m/p/<project>/automations. The list matches the sessions list's frame: borderless rows, a search field on the table's own column, a filter button at the end of the header row.Settingsno longer lists Triggers, and nothing links to it.