@agent-native/core 0.134.0 → 0.135.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +113 -0
- package/corpus/core/docs/content/template-content-developers.mdx +1 -1
- package/corpus/core/package.json +3 -2
- package/corpus/core/src/automations/service.ts +41 -4
- package/corpus/core/src/cli/mcp-config-writers.ts +27 -21
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/corpus/core/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/corpus/core/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/corpus/core/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/corpus/core/src/client/agent-page/use-jobs.ts +50 -10
- package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -0
- package/corpus/core/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/corpus/core/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/corpus/core/src/client/settings/SettingsRow.tsx +113 -0
- package/corpus/core/src/client/settings/agent-settings-search.ts +2 -1
- package/corpus/core/src/client/settings/index.ts +6 -0
- package/corpus/core/src/integrations/identity.ts +2 -12
- package/corpus/core/src/jobs/actions/list-automation-runs.ts +33 -0
- package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/corpus/core/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/corpus/core/src/jobs/background-automation-runner.ts +88 -0
- package/corpus/core/src/jobs/cron.ts +52 -6
- package/corpus/core/src/jobs/frontmatter.ts +20 -0
- package/corpus/core/src/jobs/run-history.ts +242 -0
- package/corpus/core/src/jobs/scheduler.ts +73 -18
- package/corpus/core/src/jobs/tools.ts +54 -6
- package/corpus/core/src/localization/actions/get-localization-preference.ts +2 -2
- package/corpus/core/src/localization/actions/set-localization-preference.ts +49 -11
- package/corpus/core/src/localization/default-messages.ts +27 -0
- package/corpus/core/src/localization/shared.ts +39 -6
- package/corpus/core/src/localization/user-timezone.ts +36 -0
- package/corpus/core/src/org/app-roles-handlers.ts +1 -9
- package/corpus/core/src/org/index.ts +2 -0
- package/corpus/core/src/org/membership.ts +18 -0
- package/corpus/core/src/review/actions/create-review-comment.ts +4 -1
- package/corpus/core/src/review/actions/reply-review-comment.ts +4 -1
- package/corpus/core/src/review/index.ts +5 -0
- package/corpus/core/src/review/notifications.ts +163 -0
- package/corpus/core/src/review/types.ts +7 -0
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/activity-notifications.ts +174 -0
- package/corpus/core/src/server/app-name.ts +31 -0
- package/corpus/core/src/server/better-auth-instance.ts +4 -4
- package/corpus/core/src/server/email-templates.ts +70 -14
- package/corpus/core/src/server/email.ts +66 -3
- package/corpus/core/src/server/index.ts +10 -0
- package/corpus/core/src/sharing/index.ts +5 -0
- package/corpus/core/src/sharing/recipients.ts +67 -0
- package/corpus/core/src/triggers/actions/list-automations.ts +27 -8
- package/corpus/core/src/triggers/actions/manage-automation.ts +17 -6
- package/corpus/core/src/triggers/actions.ts +16 -4
- package/corpus/core/src/triggers/dispatcher.ts +44 -30
- package/corpus/core/src/triggers/routes.ts +19 -6
- package/corpus/core/src/vitest-config.ts +68 -0
- package/corpus/core/vitest.config.ts +5 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +37 -53
- package/corpus/templates/analytics/changelog/2026-08-01-new-error-alerts-now-reach-you-by-email-and-a-scheduled-dash.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +43 -0
- package/corpus/templates/analytics/server/lib/error-capture.ts +5 -1
- package/corpus/templates/analytics/vitest.config.ts +16 -12
- package/corpus/templates/assets/actions/refresh-generation-run.ts +3 -0
- package/corpus/templates/assets/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/assets/app/hooks/use-assets-prefs.ts +55 -0
- package/corpus/templates/assets/app/i18n-data.ts +30 -0
- package/corpus/templates/assets/app/routes/settings.tsx +58 -55
- package/corpus/templates/assets/changelog/2026-08-01-get-an-email-when-a-generation-you-started-finishes-or-fails.md +6 -0
- package/corpus/templates/assets/server/lib/generation-run-notifications.ts +89 -0
- package/corpus/templates/assets/server/lib/video-runs.ts +8 -1
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.get.ts +17 -0
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.put.ts +36 -0
- package/corpus/templates/assets/shared/assets-user-prefs.ts +10 -0
- package/corpus/templates/assets/vitest.config.ts +16 -12
- package/corpus/templates/brain/app/routes/settings.tsx +15 -15
- package/corpus/templates/brain/vitest.config.ts +16 -12
- package/corpus/templates/calendar/app/pages/Settings.tsx +32 -40
- package/corpus/templates/calendar/changelog/2026-08-01-language-and-appearance-now-sit-together-in-one-preferences-.md +6 -0
- package/corpus/templates/calendar/vitest.config.ts +16 -12
- package/corpus/templates/chat/app/routes/settings.tsx +14 -22
- package/corpus/templates/chat/vitest.config.ts +9 -0
- package/corpus/templates/clips/.agents/skills/video-editing/SKILL.md +31 -0
- package/corpus/templates/clips/AGENTS.md +1 -0
- package/corpus/templates/clips/actions/add-comment.ts +12 -1
- package/corpus/templates/clips/actions/create-meeting.ts +2 -2
- package/corpus/templates/clips/actions/create-recording.ts +2 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +42 -6
- package/corpus/templates/clips/actions/generate-filmstrip.ts +154 -0
- package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
- package/corpus/templates/clips/actions/lib/ensure-recording-filmstrip.ts +258 -0
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +11 -3
- package/corpus/templates/clips/actions/react-to-comment.ts +13 -0
- package/corpus/templates/clips/actions/react-to-recording.ts +10 -1
- package/corpus/templates/clips/actions/reply-to-comment.ts +12 -1
- package/corpus/templates/clips/actions/stitch-recordings.ts +2 -2
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +152 -23
- package/corpus/templates/clips/app/components/editor/waveform.tsx +237 -75
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +23 -1
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +441 -0
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +329 -0
- package/corpus/templates/clips/app/components/settings/types.ts +14 -0
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +443 -0
- package/corpus/templates/clips/app/hooks/use-secret-status.ts +69 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +9 -1
- package/corpus/templates/clips/app/lib/video-filmstrip.ts +262 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +165 -1351
- package/corpus/templates/clips/changelog/2026-07-27-saved-clips-now-resume-from-the-last-uploaded-byte-after-an-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-29-meeting-notes-no-longer-transcribe-the-other-side-twice-when.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-editor-timeline-now-shows-video-frames-behind-the-waveform-g.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-email-notifications-now-go-out-when-someone-comments-on-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-you-can-now-set-a-default-visibility-for-new-recordings-in-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-01-email-notifications-for-comments-and-reactions-now-actually-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-03-the-desktop-app-now-opens-directly-beneath-its-tray-icon-on-.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +1 -0
- package/corpus/templates/clips/chrome-extension/vitest.config.ts +9 -0
- package/corpus/templates/clips/desktop/package.json +1 -0
- package/corpus/templates/clips/desktop/src/app.tsx +17 -1
- package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +37 -48
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +7 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +182 -106
- package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +43 -14
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/echo_guard.rs +443 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +815 -15
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +61 -11
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +125 -16
- package/corpus/templates/clips/desktop/vitest.config.ts +9 -0
- package/corpus/templates/clips/server/db/schema.ts +17 -0
- package/corpus/templates/clips/server/jobs/media-verification.ts +4 -0
- package/corpus/templates/clips/server/lib/activity-notifications.ts +185 -0
- package/corpus/templates/clips/server/lib/recording-media-cleanup.ts +2 -0
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +46 -9
- package/corpus/templates/clips/server/lib/recordings.ts +24 -0
- package/corpus/templates/clips/server/lib/resumable-session.ts +10 -4
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +109 -0
- package/corpus/templates/clips/server/lib/upload-interruption.ts +8 -0
- package/corpus/templates/clips/server/lib/upload-lease.ts +50 -4
- package/corpus/templates/clips/server/lib/video-filmstrip-sprite.ts +207 -0
- package/corpus/templates/clips/server/lib/video-remux.ts +13 -4
- package/corpus/templates/clips/server/plugins/db.ts +16 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +4 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +123 -36
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +159 -29
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +197 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +193 -39
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +191 -12
- package/corpus/templates/clips/shared/clips-ai-prefs.ts +6 -0
- package/corpus/templates/clips/shared/feature-flags.ts +12 -0
- package/corpus/templates/clips/shared/recording-core.ts +4 -0
- package/corpus/templates/clips/vitest.config.ts +23 -19
- package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -4
- package/corpus/templates/content/actions/_database-membership-lock.ts +25 -0
- package/corpus/templates/content/actions/_database-row-batch.ts +6 -2
- package/corpus/templates/content/actions/_database-source-utils.ts +289 -129
- package/corpus/templates/content/actions/_database-utils.ts +12 -3
- package/corpus/templates/content/actions/add-comment.ts +15 -1
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +39 -21
- package/corpus/templates/content/actions/attach-content-database-source.ts +4 -1
- package/corpus/templates/content/actions/change-content-database-source-role.ts +3 -5
- package/corpus/templates/content/actions/duplicate-document-property.ts +59 -46
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +77 -71
- package/corpus/templates/content/actions/list-documents.ts +1 -0
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +7 -0
- package/corpus/templates/content/actions/remove-database-items.ts +183 -0
- package/corpus/templates/content/actions/set-document-property.ts +57 -39
- package/corpus/templates/content/actions/sync-local-folder-source.ts +7 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +5 -2
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +50 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +471 -329
- package/corpus/templates/content/app/components/editor/database/row-access.ts +45 -0
- package/corpus/templates/content/app/components/editor/database/shared.tsx +141 -38
- package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +2 -2
- package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
- package/corpus/templates/content/app/i18n-data.ts +170 -0
- package/corpus/templates/content/app/routes/_app.settings.tsx +47 -18
- package/corpus/templates/content/changelog/2026-07-30-breadcrumb-menus-now-hide-internal-system-pages.md +6 -0
- package/corpus/templates/content/changelog/2026-07-30-database-rows-can-now-be-removed-without-deleting-their-page.md +6 -0
- package/corpus/templates/content/changelog/2026-08-01-get-an-email-when-someone-comments-on-replies-in-or-mentions.md +6 -0
- package/corpus/templates/content/parity/eval-scenarios.ts +2 -2
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +4 -5
- package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.get.ts +17 -0
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.put.ts +36 -0
- package/corpus/templates/content/shared/api.ts +4 -0
- package/corpus/templates/content/shared/content-user-prefs.ts +11 -0
- package/corpus/templates/content/vitest.config.ts +20 -16
- package/corpus/templates/crm/app/routes/settings.tsx +14 -22
- package/corpus/templates/crm/vitest.config.ts +8 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +26 -11
- package/corpus/templates/design/actions/take-design-screenshot.ts +7 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +11 -3
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +4 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +54 -17
- package/corpus/templates/design/app/components/design/design-canvas/local-runtime.ts +126 -0
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +2 -0
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- package/corpus/templates/design/app/pages/Present.tsx +2 -1
- package/corpus/templates/design/app/routes/settings.tsx +14 -22
- package/corpus/templates/design/changelog/2026-07-30-a-broken-inline-script-in-a-generated-screen-is-now-caught-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-design-html-is-now-validated-with-a-spec-grade-html-parser-i.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-now-load-their-tailwind-and-alpine-runtimes-from-the.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-with-a-broken-alpine-expression-are-now-caught-on-sa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-editing-a-design-no-longer-strips-its-styling-the-canvas-kep.md +6 -0
- package/corpus/templates/design/changelog/2026-08-01-review-comments-replies-and-mentions-now-send-an-email-to-th.md +6 -0
- package/corpus/templates/design/package.json +4 -0
- package/corpus/templates/design/shared/html-integrity.ts +802 -556
- package/corpus/templates/design/vitest.config.ts +18 -12
- package/corpus/templates/dispatch/app/routes/settings.tsx +26 -40
- package/corpus/templates/dispatch/vitest.config.ts +11 -7
- package/corpus/templates/factory/app/routes/settings.tsx +14 -22
- package/corpus/templates/factory/vitest.config.ts +9 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +14 -22
- package/corpus/templates/forms/vitest.config.ts +27 -23
- package/corpus/templates/macros/app/routes/settings.tsx +14 -22
- package/corpus/templates/macros/vitest.config.ts +16 -12
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +14 -16
- package/corpus/templates/mail/vitest.config.ts +16 -12
- package/corpus/templates/plan/app/routes/settings.tsx +30 -44
- package/corpus/templates/plan/vitest.config.ts +24 -20
- package/corpus/templates/slides/actions/add-slide-comment.ts +12 -1
- package/corpus/templates/slides/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/slides/app/hooks/use-slides-prefs.ts +55 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/routes/settings.tsx +45 -22
- package/corpus/templates/slides/changelog/2026-08-01-get-an-email-when-someone-comments-on-or-replies-in-your-dec.md +6 -0
- package/corpus/templates/slides/server/lib/comment-notifications.ts +182 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.get.ts +16 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.put.ts +36 -0
- package/corpus/templates/slides/shared/slides-user-prefs.ts +11 -0
- package/corpus/templates/slides/vitest.config.ts +17 -13
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +2 -0
- package/corpus/templates/tasks/app/routes/settings.tsx +14 -22
- package/corpus/templates/tasks/vitest.config.ts +17 -13
- package/corpus/toolkit/CHANGELOG.md +9 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/vitest.config.ts +3 -0
- package/dist/automations/service.d.ts +2 -0
- package/dist/automations/service.d.ts.map +1 -1
- package/dist/automations/service.js +29 -4
- package/dist/automations/service.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +24 -23
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +86 -29
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts +21 -0
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js +33 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts +15 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js +46 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts +17 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.js +107 -0
- package/dist/client/agent-page/TimezoneSelect.js.map +1 -0
- package/dist/client/agent-page/use-jobs.d.ts +20 -7
- package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/client/agent-page/use-jobs.js +24 -4
- package/dist/client/agent-page/use-jobs.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +8 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -1
- package/dist/client/settings/AccountSettingsCard.js +10 -9
- package/dist/client/settings/AccountSettingsCard.js.map +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +10 -0
- package/dist/client/settings/SchedulingTimezoneField.d.ts.map +1 -0
- package/dist/client/settings/SchedulingTimezoneField.js +30 -0
- package/dist/client/settings/SchedulingTimezoneField.js.map +1 -0
- package/dist/client/settings/SettingsRow.d.ts +36 -0
- package/dist/client/settings/SettingsRow.d.ts.map +1 -0
- package/dist/client/settings/SettingsRow.js +15 -0
- package/dist/client/settings/SettingsRow.js.map +1 -0
- package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
- package/dist/client/settings/agent-settings-search.js +1 -1
- package/dist/client/settings/agent-settings-search.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/identity.d.ts.map +1 -1
- package/dist/integrations/identity.js +2 -11
- package/dist/integrations/identity.js.map +1 -1
- package/dist/jobs/actions/list-automation-runs.d.ts +8 -0
- package/dist/jobs/actions/list-automation-runs.d.ts.map +1 -0
- package/dist/jobs/actions/list-automation-runs.js +29 -0
- package/dist/jobs/actions/list-automation-runs.js.map +1 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts +2 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
- package/dist/jobs/actions/list-recurring-jobs.js +20 -7
- package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
- package/dist/jobs/actions/manage-recurring-job.d.ts +2 -0
- package/dist/jobs/actions/manage-recurring-job.js +30 -9
- package/dist/jobs/actions/manage-recurring-job.js.map +1 -1
- package/dist/jobs/background-automation-runner.d.ts.map +1 -1
- package/dist/jobs/background-automation-runner.js +60 -0
- package/dist/jobs/background-automation-runner.js.map +1 -1
- package/dist/jobs/cron.d.ts +16 -2
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +43 -6
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/frontmatter.d.ts +12 -0
- package/dist/jobs/frontmatter.d.ts.map +1 -1
- package/dist/jobs/frontmatter.js +8 -0
- package/dist/jobs/frontmatter.js.map +1 -1
- package/dist/jobs/run-history.d.ts +56 -0
- package/dist/jobs/run-history.d.ts.map +1 -0
- package/dist/jobs/run-history.js +169 -0
- package/dist/jobs/run-history.js.map +1 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +51 -18
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +37 -6
- package/dist/jobs/tools.js.map +1 -1
- package/dist/localization/actions/get-localization-preference.d.ts +1 -2
- package/dist/localization/actions/get-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/get-localization-preference.js.map +1 -1
- package/dist/localization/actions/set-localization-preference.d.ts +3 -3
- package/dist/localization/actions/set-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/set-localization-preference.js +33 -8
- package/dist/localization/actions/set-localization-preference.js.map +1 -1
- package/dist/localization/default-messages.d.ts +25 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +25 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/localization/shared.d.ts +16 -1
- package/dist/localization/shared.d.ts.map +1 -1
- package/dist/localization/shared.js +22 -4
- package/dist/localization/shared.js.map +1 -1
- package/dist/localization/user-timezone.d.ts +11 -0
- package/dist/localization/user-timezone.d.ts.map +1 -0
- package/dist/localization/user-timezone.js +31 -0
- package/dist/localization/user-timezone.js.map +1 -0
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +1 -1
- package/dist/org/app-roles-handlers.d.ts.map +1 -1
- package/dist/org/app-roles-handlers.js +1 -8
- package/dist/org/app-roles-handlers.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/membership.d.ts +6 -0
- package/dist/org/membership.d.ts.map +1 -0
- package/dist/org/membership.js +16 -0
- package/dist/org/membership.js.map +1 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/review/actions/create-review-comment.d.ts +32 -1
- package/dist/review/actions/create-review-comment.d.ts.map +1 -1
- package/dist/review/actions/create-review-comment.js +3 -1
- package/dist/review/actions/create-review-comment.js.map +1 -1
- package/dist/review/actions/reply-review-comment.d.ts +32 -1
- package/dist/review/actions/reply-review-comment.d.ts.map +1 -1
- package/dist/review/actions/reply-review-comment.js +3 -1
- package/dist/review/actions/reply-review-comment.js.map +1 -1
- package/dist/review/index.d.ts +1 -0
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +1 -0
- package/dist/review/index.js.map +1 -1
- package/dist/review/notifications.d.ts +24 -0
- package/dist/review/notifications.d.ts.map +1 -0
- package/dist/review/notifications.js +123 -0
- package/dist/review/notifications.js.map +1 -0
- package/dist/review/types.d.ts +5 -0
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/activity-notifications.d.ts +61 -0
- package/dist/server/activity-notifications.d.ts.map +1 -0
- package/dist/server/activity-notifications.js +103 -0
- package/dist/server/activity-notifications.js.map +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/app-name.d.ts +18 -0
- package/dist/server/app-name.d.ts.map +1 -1
- package/dist/server/app-name.js +31 -0
- package/dist/server/app-name.js.map +1 -1
- package/dist/server/better-auth-instance.js +4 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/email-templates.d.ts +12 -0
- package/dist/server/email-templates.d.ts.map +1 -1
- package/dist/server/email-templates.js +57 -14
- package/dist/server/email-templates.js.map +1 -1
- package/dist/server/email.d.ts +12 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +52 -5
- package/dist/server/email.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/sharing/index.d.ts +1 -0
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +1 -0
- package/dist/sharing/index.js.map +1 -1
- package/dist/sharing/recipients.d.ts +31 -0
- package/dist/sharing/recipients.d.ts.map +1 -0
- package/dist/sharing/recipients.js +40 -0
- package/dist/sharing/recipients.js.map +1 -0
- package/dist/templates/chat/app/routes/settings.tsx +14 -22
- package/dist/templates/chat/vitest.config.ts +9 -0
- package/dist/triggers/actions/list-automations.d.ts +2 -0
- package/dist/triggers/actions/list-automations.d.ts.map +1 -1
- package/dist/triggers/actions/list-automations.js +19 -8
- package/dist/triggers/actions/list-automations.js.map +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +6 -0
- package/dist/triggers/actions/manage-automation.js +12 -6
- package/dist/triggers/actions/manage-automation.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +15 -4
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +19 -17
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/routes.d.ts.map +1 -1
- package/dist/triggers/routes.js +6 -6
- package/dist/triggers/routes.js.map +1 -1
- package/dist/vitest-config.d.ts +10 -0
- package/dist/vitest-config.d.ts.map +1 -0
- package/dist/vitest-config.js +55 -0
- package/dist/vitest-config.js.map +1 -0
- package/docs/content/template-content-developers.mdx +1 -1
- package/package.json +5 -4
- package/src/automations/service.ts +41 -4
- package/src/cli/mcp-config-writers.ts +27 -21
- package/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/src/client/agent-page/use-jobs.ts +50 -10
- package/src/client/org/OrgSwitcher.tsx +26 -0
- package/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/src/client/settings/SettingsRow.tsx +113 -0
- package/src/client/settings/agent-settings-search.ts +2 -1
- package/src/client/settings/index.ts +6 -0
- package/src/integrations/identity.ts +2 -12
- package/src/jobs/actions/list-automation-runs.ts +33 -0
- package/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/src/jobs/background-automation-runner.ts +88 -0
- package/src/jobs/cron.ts +52 -6
- package/src/jobs/frontmatter.ts +20 -0
- package/src/jobs/run-history.ts +242 -0
- package/src/jobs/scheduler.ts +73 -18
- package/src/jobs/tools.ts +54 -6
- package/src/localization/actions/get-localization-preference.ts +2 -2
- package/src/localization/actions/set-localization-preference.ts +49 -11
- package/src/localization/default-messages.ts +27 -0
- package/src/localization/shared.ts +39 -6
- package/src/localization/user-timezone.ts +36 -0
- package/src/org/app-roles-handlers.ts +1 -9
- package/src/org/index.ts +2 -0
- package/src/org/membership.ts +18 -0
- package/src/review/actions/create-review-comment.ts +4 -1
- package/src/review/actions/reply-review-comment.ts +4 -1
- package/src/review/index.ts +5 -0
- package/src/review/notifications.ts +163 -0
- package/src/review/types.ts +7 -0
- package/src/server/action-discovery.ts +4 -0
- package/src/server/activity-notifications.ts +174 -0
- package/src/server/app-name.ts +31 -0
- package/src/server/better-auth-instance.ts +4 -4
- package/src/server/email-templates.ts +70 -14
- package/src/server/email.ts +66 -3
- package/src/server/index.ts +10 -0
- package/src/sharing/index.ts +5 -0
- package/src/sharing/recipients.ts +67 -0
- package/src/templates/chat/app/routes/settings.tsx +14 -22
- package/src/templates/chat/vitest.config.ts +9 -0
- package/src/triggers/actions/list-automations.ts +27 -8
- package/src/triggers/actions/manage-automation.ts +17 -6
- package/src/triggers/actions.ts +16 -4
- package/src/triggers/dispatcher.ts +44 -30
- package/src/triggers/routes.ts +19 -6
- package/src/vitest-config.ts +68 -0
- package/corpus/templates/content/actions/delete-database-items.ts +0 -89
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-automations.d.ts","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"list-automations.d.ts","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"AAuCA,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,GAAG,cAAc,CAAC;IACnC,WAAW,EAAE,OAAO,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { defineAction } from "../../action.js";
|
|
3
3
|
import { listAutomationDefinitions, } from "../../automations/service.js";
|
|
4
|
-
import { describeCron, isValidCron, nextOccurrence } from "../../jobs/cron.js";
|
|
4
|
+
import { describeCron, effectiveTimezone, isValidCron, nextOccurrence, } from "../../jobs/cron.js";
|
|
5
5
|
const scopeSchema = z.enum(["personal", "organization"]);
|
|
6
6
|
function nextRun(meta) {
|
|
7
7
|
if (!meta.enabled)
|
|
8
8
|
return null;
|
|
9
|
-
|
|
10
|
-
return meta.nextRun;
|
|
11
|
-
if (meta.triggerType === "schedule" &&
|
|
9
|
+
const scheduled = Boolean(meta.triggerType === "schedule" &&
|
|
12
10
|
meta.schedule &&
|
|
13
|
-
isValidCron(meta.schedule))
|
|
14
|
-
|
|
11
|
+
isValidCron(meta.schedule));
|
|
12
|
+
// A stored `nextRun` in the past means the dispatcher kept declining to run
|
|
13
|
+
// this automation, not that it is overdue. Report the real next occurrence
|
|
14
|
+
// and let `lastError` carry the reason it keeps being passed over.
|
|
15
|
+
if (meta.nextRun) {
|
|
16
|
+
const stored = new Date(meta.nextRun).getTime();
|
|
17
|
+
if (!Number.isFinite(stored) || stored > Date.now() || !scheduled) {
|
|
18
|
+
return meta.nextRun;
|
|
19
|
+
}
|
|
15
20
|
}
|
|
16
|
-
return
|
|
21
|
+
return scheduled
|
|
22
|
+
? nextOccurrence(meta.schedule, undefined, meta.timezone).toISOString()
|
|
23
|
+
: null;
|
|
17
24
|
}
|
|
18
25
|
export default defineAction({
|
|
19
26
|
description: "List event-triggered and schedule-triggered automations in the selected personal or organization scope.",
|
|
@@ -37,11 +44,15 @@ export default defineAction({
|
|
|
37
44
|
triggerType: meta.triggerType,
|
|
38
45
|
event: meta.event ?? null,
|
|
39
46
|
schedule: meta.schedule || null,
|
|
40
|
-
|
|
47
|
+
timezone: meta.schedule ? effectiveTimezone(meta.timezone) : null,
|
|
48
|
+
scheduleDescription: meta.schedule
|
|
49
|
+
? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
|
|
50
|
+
: null,
|
|
41
51
|
condition: meta.condition ?? null,
|
|
42
52
|
body,
|
|
43
53
|
enabled: meta.enabled,
|
|
44
54
|
lastRun: meta.lastRun ?? null,
|
|
55
|
+
lastCheck: meta.lastCheck ?? null,
|
|
45
56
|
lastStatus: meta.lastStatus ?? null,
|
|
46
57
|
lastError: meta.lastError ?? null,
|
|
47
58
|
nextRun: nextRun(meta),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-automations.js","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,yBAAyB,GAE1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"list-automations.js","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n listAutomationDefinitions,\n type AutomationScope,\n} from \"../../automations/service.js\";\nimport {\n describeCron,\n effectiveTimezone,\n isValidCron,\n nextOccurrence,\n} from \"../../jobs/cron.js\";\n\nconst scopeSchema = z.enum([\"personal\", \"organization\"]);\n\nfunction nextRun(\n meta: Awaited<ReturnType<typeof listAutomationDefinitions>>[number][\"meta\"],\n): string | null {\n if (!meta.enabled) return null;\n const scheduled = Boolean(\n meta.triggerType === \"schedule\" &&\n meta.schedule &&\n isValidCron(meta.schedule),\n );\n // A stored `nextRun` in the past means the dispatcher kept declining to run\n // this automation, not that it is overdue. Report the real next occurrence\n // and let `lastError` carry the reason it keeps being passed over.\n if (meta.nextRun) {\n const stored = new Date(meta.nextRun).getTime();\n if (!Number.isFinite(stored) || stored > Date.now() || !scheduled) {\n return meta.nextRun;\n }\n }\n return scheduled\n ? nextOccurrence(meta.schedule!, undefined, meta.timezone).toISOString()\n : null;\n}\n\nexport interface AutomationActionItem {\n id: string;\n name: string;\n path: string;\n scope: \"personal\" | \"organization\";\n triggerType: \"event\" | \"schedule\";\n event: string | null;\n schedule: string | null;\n timezone: string | null;\n scheduleDescription: string | null;\n condition: string | null;\n body: string;\n enabled: boolean;\n lastRun: string | null;\n lastCheck: string | null;\n lastStatus: string | null;\n lastError: string | null;\n nextRun: string | null;\n createdBy: string | null;\n model: string | null;\n mcpTools: string[];\n originScopeId: string | null;\n deliveryPlatform: string | null;\n deliveryDestination: string | null;\n deliveryThreadRef: string | null;\n deliveryTenantId: string | null;\n canUpdate: boolean;\n}\n\nexport default defineAction({\n description:\n \"List event-triggered and schedule-triggered automations in the selected personal or organization scope.\",\n agentTool: false,\n schema: z.object({\n scope: scopeSchema.default(\"personal\"),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n parallelSafe: true,\n run: async ({ scope }, ctx): Promise<AutomationActionItem[]> => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const definitions = await listAutomationDefinitions(\n { userEmail, orgId: ctx?.orgId },\n scope as AutomationScope,\n );\n return definitions.map(({ resource, name, meta, body, canUpdate }) => ({\n id: resource.id,\n name,\n path: resource.path,\n scope: scope as AutomationScope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n timezone: meta.schedule ? effectiveTimezone(meta.timezone) : null,\n scheduleDescription: meta.schedule\n ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))\n : null,\n condition: meta.condition ?? null,\n body,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastCheck: meta.lastCheck ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: nextRun(meta),\n createdBy: meta.createdBy ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n canUpdate,\n }));\n },\n});\n"]}
|
|
@@ -3,15 +3,21 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
3
3
|
name: string;
|
|
4
4
|
scope?: "organization" | "personal";
|
|
5
5
|
enabled?: boolean;
|
|
6
|
+
schedule?: string;
|
|
7
|
+
timezone?: string;
|
|
6
8
|
}, {
|
|
7
9
|
deleted: boolean;
|
|
8
10
|
name: string;
|
|
9
11
|
enabled?: undefined;
|
|
12
|
+
schedule?: undefined;
|
|
13
|
+
timezone?: undefined;
|
|
10
14
|
nextRun?: undefined;
|
|
11
15
|
} | {
|
|
12
16
|
deleted?: undefined;
|
|
13
17
|
name: string;
|
|
14
18
|
enabled: boolean;
|
|
19
|
+
schedule: string;
|
|
20
|
+
timezone: string;
|
|
15
21
|
nextRun: string;
|
|
16
22
|
}>;
|
|
17
23
|
export default _default;
|
|
@@ -10,8 +10,10 @@ export default defineAction({
|
|
|
10
10
|
name: z.string().min(1),
|
|
11
11
|
scope: z.enum(["personal", "organization"]).default("personal"),
|
|
12
12
|
enabled: z.boolean().optional(),
|
|
13
|
+
schedule: z.string().min(1).optional(),
|
|
14
|
+
timezone: z.string().min(1).optional(),
|
|
13
15
|
}),
|
|
14
|
-
run: async ({ operation, name, scope, enabled }, ctx) => {
|
|
16
|
+
run: async ({ operation, name, scope, enabled, schedule, timezone }, ctx) => {
|
|
15
17
|
const userEmail = ctx?.userEmail;
|
|
16
18
|
if (!userEmail)
|
|
17
19
|
throw new Error("Not authenticated.");
|
|
@@ -21,20 +23,24 @@ export default defineAction({
|
|
|
21
23
|
await refreshEventSubscriptions();
|
|
22
24
|
return { deleted: true, name };
|
|
23
25
|
}
|
|
24
|
-
if (enabled === undefined
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
26
|
+
if (enabled === undefined &&
|
|
27
|
+
schedule === undefined &&
|
|
28
|
+
timezone === undefined) {
|
|
29
|
+
throw Object.assign(new Error("enabled, schedule, or timezone is required for update."), { statusCode: 400 });
|
|
28
30
|
}
|
|
29
31
|
const definition = await updateAutomation(actor, {
|
|
30
32
|
name,
|
|
31
33
|
scope,
|
|
32
|
-
enabled,
|
|
34
|
+
...(enabled === undefined ? {} : { enabled }),
|
|
35
|
+
...(schedule === undefined ? {} : { schedule }),
|
|
36
|
+
...(timezone === undefined ? {} : { timezone }),
|
|
33
37
|
});
|
|
34
38
|
await refreshEventSubscriptions();
|
|
35
39
|
return {
|
|
36
40
|
name,
|
|
37
41
|
enabled: definition.meta.enabled,
|
|
42
|
+
schedule: definition.meta.schedule || null,
|
|
43
|
+
timezone: definition.meta.timezone ?? null,
|
|
38
44
|
nextRun: definition.meta.nextRun ?? null,
|
|
39
45
|
};
|
|
40
46
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manage-automation.js","sourceRoot":"","sources":["../../../src/triggers/actions/manage-automation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,mGAAmG;IACrG,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"manage-automation.js","sourceRoot":"","sources":["../../../src/triggers/actions/manage-automation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,mGAAmG;IACrG,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;QACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;KACvC,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;QAC1E,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAE/C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3C,MAAM,yBAAyB,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QACD,IACE,OAAO,KAAK,SAAS;YACrB,QAAQ,KAAK,SAAS;YACtB,QAAQ,KAAK,SAAS,EACtB,CAAC;YACD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,wDAAwD,CAAC,EACnE,EAAE,UAAU,EAAE,GAAG,EAAE,CACpB,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE;YAC/C,IAAI;YACJ,KAAK;YACL,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,yBAAyB,EAAE,CAAC;QAClC,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO;YAChC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC1C,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC1C,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI;SACzC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n deleteAutomation,\n updateAutomation,\n} from \"../../automations/service.js\";\nimport { refreshEventSubscriptions } from \"../dispatcher.js\";\n\nexport default defineAction({\n description:\n \"Enable, disable, or delete a personal or organization automation from the Agent Automations page.\",\n agentTool: false,\n schema: z.object({\n operation: z.enum([\"update\", \"delete\"]),\n name: z.string().min(1),\n scope: z.enum([\"personal\", \"organization\"]).default(\"personal\"),\n enabled: z.boolean().optional(),\n schedule: z.string().min(1).optional(),\n timezone: z.string().min(1).optional(),\n }),\n run: async ({ operation, name, scope, enabled, schedule, timezone }, ctx) => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const actor = { userEmail, orgId: ctx?.orgId };\n\n if (operation === \"delete\") {\n await deleteAutomation(actor, scope, name);\n await refreshEventSubscriptions();\n return { deleted: true, name };\n }\n if (\n enabled === undefined &&\n schedule === undefined &&\n timezone === undefined\n ) {\n throw Object.assign(\n new Error(\"enabled, schedule, or timezone is required for update.\"),\n { statusCode: 400 },\n );\n }\n const definition = await updateAutomation(actor, {\n name,\n scope,\n ...(enabled === undefined ? {} : { enabled }),\n ...(schedule === undefined ? {} : { schedule }),\n ...(timezone === undefined ? {} : { timezone }),\n });\n await refreshEventSubscriptions();\n return {\n name,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n };\n },\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAqShE,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,MAAM,GAC3B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA0I7B"}
|
package/dist/triggers/actions.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { defineAutomation, deleteAutomation, listAutomationDefinitions, updateAutomation, } from "../automations/service.js";
|
|
12
12
|
import { listEvents } from "../event-bus/index.js";
|
|
13
|
-
import { describeCron } from "../jobs/cron.js";
|
|
13
|
+
import { describeCron, effectiveTimezone } from "../jobs/cron.js";
|
|
14
14
|
import { getIntegrationRequestContext, getRequestOrgId, } from "../server/request-context.js";
|
|
15
15
|
import { refreshEventSubscriptions } from "./dispatcher.js";
|
|
16
16
|
/* ------------------------------------------------------------------ */
|
|
@@ -52,7 +52,10 @@ async function handleList(args, getCurrentUser) {
|
|
|
52
52
|
triggerType: meta.triggerType,
|
|
53
53
|
event: meta.event ?? null,
|
|
54
54
|
schedule: meta.schedule || null,
|
|
55
|
-
|
|
55
|
+
timezone: meta.timezone ? effectiveTimezone(meta.timezone) : null,
|
|
56
|
+
scheduleDescription: meta.schedule
|
|
57
|
+
? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
|
|
58
|
+
: null,
|
|
56
59
|
condition: meta.condition ?? null,
|
|
57
60
|
mode: meta.mode,
|
|
58
61
|
domain: meta.domain ?? null,
|
|
@@ -101,6 +104,7 @@ async function handleDefine(args, getCurrentUser) {
|
|
|
101
104
|
triggerType: automationTriggerType(args.trigger_type),
|
|
102
105
|
body: typeof args.body === "string" ? args.body : "",
|
|
103
106
|
schedule: typeof args.schedule === "string" ? args.schedule : undefined,
|
|
107
|
+
timezone: typeof args.timezone === "string" ? args.timezone : undefined,
|
|
104
108
|
event: typeof args.event === "string" ? args.event : undefined,
|
|
105
109
|
condition: typeof args.condition === "string" ? args.condition : undefined,
|
|
106
110
|
domain: typeof args.domain === "string" ? args.domain : undefined,
|
|
@@ -132,6 +136,7 @@ async function handleDefine(args, getCurrentUser) {
|
|
|
132
136
|
triggerType: definition.meta.triggerType,
|
|
133
137
|
event: definition.meta.event ?? null,
|
|
134
138
|
schedule: definition.meta.schedule || null,
|
|
139
|
+
timezone: definition.meta.timezone ?? null,
|
|
135
140
|
nextRun: definition.meta.nextRun ?? null,
|
|
136
141
|
createdBy: definition.meta.createdBy,
|
|
137
142
|
runAs: definition.meta.runAs,
|
|
@@ -168,6 +173,7 @@ async function handleUpdate(args, getCurrentUser) {
|
|
|
168
173
|
: null,
|
|
169
174
|
body: typeof args.body === "string" ? args.body : undefined,
|
|
170
175
|
schedule: typeof args.schedule === "string" ? args.schedule : undefined,
|
|
176
|
+
timezone: typeof args.timezone === "string" ? args.timezone : undefined,
|
|
171
177
|
model: args.model === undefined
|
|
172
178
|
? undefined
|
|
173
179
|
: typeof args.model === "string"
|
|
@@ -183,6 +189,7 @@ async function handleUpdate(args, getCurrentUser) {
|
|
|
183
189
|
triggerType: definition.meta.triggerType,
|
|
184
190
|
enabled: definition.meta.enabled,
|
|
185
191
|
schedule: definition.meta.schedule || null,
|
|
192
|
+
timezone: definition.meta.timezone ?? null,
|
|
186
193
|
nextRun: definition.meta.nextRun ?? null,
|
|
187
194
|
createdBy: definition.meta.createdBy,
|
|
188
195
|
runAs: definition.meta.runAs,
|
|
@@ -247,8 +254,8 @@ export function createAutomationToolEntries(getCurrentUser) {
|
|
|
247
254
|
|
|
248
255
|
- **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.
|
|
249
256
|
- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.
|
|
250
|
-
- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, condition, mode, domain, delegated_policy_id, model, mcpTools.
|
|
251
|
-
- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.
|
|
257
|
+
- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, timezone, condition, mode, domain, delegated_policy_id, model, mcpTools.
|
|
258
|
+
- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, timezone, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.
|
|
252
259
|
- **delete**: Delete an automation. Always confirm with the user first. Required param: name.
|
|
253
260
|
- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,
|
|
254
261
|
parameters: {
|
|
@@ -277,6 +284,10 @@ export function createAutomationToolEntries(getCurrentUser) {
|
|
|
277
284
|
type: "string",
|
|
278
285
|
description: "For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.",
|
|
279
286
|
},
|
|
287
|
+
timezone: {
|
|
288
|
+
type: "string",
|
|
289
|
+
description: "IANA timezone the cron clock time is read in, e.g. 'America/New_York'. Optional; defaults to the user's saved scheduling timezone, then the caller's browser zone. Always pass this when the user names a time of day.",
|
|
290
|
+
},
|
|
280
291
|
schedule: {
|
|
281
292
|
type: "string",
|
|
282
293
|
description: 'For schedule triggers: cron expression. Example: "0 9 * * 1-5" (9am weekdays).',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Framework-level agent actions for the automations system.\n *\n * These are registered as native tools (not template actions) so they're\n * available in every template. The agent uses them to create, list, and\n * manage automations from chat.\n *\n * All six operations are consolidated into a single `manage-automations` tool\n * with an `action` discriminator to keep the tool registry compact.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport {\n defineAutomation,\n deleteAutomation,\n listAutomationDefinitions,\n updateAutomation,\n type AutomationScope,\n} from \"../automations/service.js\";\nimport { listEvents } from \"../event-bus/index.js\";\nimport { describeCron } from \"../jobs/cron.js\";\nimport {\n getIntegrationRequestContext,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { refreshEventSubscriptions } from \"./dispatcher.js\";\n\n/* ------------------------------------------------------------------ */\n/* Individual action handlers */\n/* ------------------------------------------------------------------ */\n\nasync function handleListEvents(): Promise<string> {\n const events = listEvents();\n if (events.length === 0) {\n return \"No events registered yet. Events are registered by integrations (mail, calendar, clips, etc.).\";\n }\n const lines = events.map((e) => {\n let schemaStr = \"\";\n try {\n const s = e.payloadSchema as any;\n if (s?._zod?.def?.shape) {\n const fields = Object.keys(s._zod.def.shape);\n schemaStr = ` Fields: ${fields.join(\", \")}`;\n }\n } catch {\n // ignore\n }\n const example = e.example\n ? `\\n Example: ${JSON.stringify(e.example)}`\n : \"\";\n return `- **${e.name}**: ${e.description}${schemaStr}${example}`;\n });\n return lines.join(\"\\n\");\n}\n\nasync function handleList(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const scope = automationScope(args.scope);\n const definitions = await listAutomationDefinitions(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n scope,\n );\n const automations = definitions\n .filter(({ meta }) => !args.domain || meta.domain === args.domain)\n .filter(({ meta }) => args.enabled_only !== \"true\" || meta.enabled)\n .map(({ name, meta, body, canUpdate }) => ({\n name,\n scope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n scheduleDescription: meta.schedule ? describeCron(meta.schedule) : null,\n condition: meta.condition ?? null,\n mode: meta.mode,\n domain: meta.domain ?? null,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: meta.nextRun ?? null,\n createdBy: meta.createdBy ?? null,\n runAs: meta.runAs ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n body,\n canUpdate,\n }));\n return JSON.stringify(automations, null, 2);\n}\n\nfunction automationScope(value: unknown): AutomationScope {\n if (value === undefined || value === null || value === \"\") return \"personal\";\n if (value === \"personal\" || value === \"organization\") return value;\n throw new Error('scope must be \"personal\" or \"organization\".');\n}\n\nfunction automationTriggerType(value: unknown): \"schedule\" | \"event\" {\n if (value === \"schedule\" || value === \"event\") return value;\n throw new Error('trigger_type must be \"schedule\" or \"event\".');\n}\n\nasync function handleDefine(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n if (args.mode === \"deterministic\") {\n return (\n \"Error: Deterministic mode was removed — it was never implemented and \" +\n \"automations that set it never fired. Create the automation without \" +\n \"mode (agentic), and describe the exact fixed steps in the automation body.\"\n );\n }\n const integration = getIntegrationRequestContext();\n try {\n const definition = await defineAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n triggerType: automationTriggerType(args.trigger_type),\n body: typeof args.body === \"string\" ? args.body : \"\",\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n event: typeof args.event === \"string\" ? args.event : undefined,\n condition:\n typeof args.condition === \"string\" ? args.condition : undefined,\n domain: typeof args.domain === \"string\" ? args.domain : undefined,\n delegatedPolicyId:\n typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n mcpTools: args.mcpTools,\n delivery: integration\n ? {\n originScopeId: integration.scopeId,\n platform: integration.incoming.platform,\n destination:\n typeof integration.incoming.platformContext.channelId ===\n \"string\"\n ? integration.incoming.platformContext.channelId\n : undefined,\n threadRef:\n typeof integration.incoming.threadRef === \"string\"\n ? integration.incoming.threadRef\n : undefined,\n tenantId: integration.incoming.tenantId,\n }\n : undefined,\n },\n );\n\n await refreshEventSubscriptions();\n return JSON.stringify({\n created: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n event: definition.meta.event ?? null,\n schedule: definition.meta.schedule || null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleUpdate(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n try {\n const definition = await updateAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n enabled:\n args.enabled === undefined\n ? undefined\n : args.enabled === true || args.enabled === \"true\",\n condition:\n args.condition === undefined\n ? undefined\n : typeof args.condition === \"string\"\n ? args.condition\n : null,\n delegatedPolicyId:\n args.delegated_policy_id === undefined\n ? undefined\n : typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : null,\n body: typeof args.body === \"string\" ? args.body : undefined,\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n model:\n args.model === undefined\n ? undefined\n : typeof args.model === \"string\"\n ? args.model\n : null,\n mcpTools: args.mcpTools,\n },\n );\n await refreshEventSubscriptions();\n return JSON.stringify({\n updated: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleDelete(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n try {\n await deleteAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n automationScope(args.scope),\n name,\n );\n await refreshEventSubscriptions();\n return JSON.stringify({ deleted: true, name });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleFireTest(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n // Dynamic import to avoid circular dependency at module load time\n const { emit } = await import(\"../event-bus/index.js\");\n\n let data: Record<string, unknown> = {};\n if (typeof args.data === \"string\" && args.data) {\n try {\n data = JSON.parse(args.data);\n } catch {\n return \"Error: invalid JSON in data parameter.\";\n }\n }\n\n // Scope the test event to the current user so only their automations fire,\n // not automations owned by other users in the same process.\n const owner = getCurrentUser();\n emit(\"test.event.fired\", { data }, { owner });\n return `Test event fired with payload: ${JSON.stringify({ data })}. Any automations subscribed to \"test.event.fired\" will be evaluated.`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Consolidated tool entry */\n/* ------------------------------------------------------------------ */\n\nconst VALID_ACTIONS = [\n \"list-events\",\n \"list\",\n \"define\",\n \"update\",\n \"delete\",\n \"fire-test\",\n] as const;\n\nexport function createAutomationToolEntries(\n getCurrentUser: () => string,\n): Record<string, ActionEntry> {\n return {\n \"manage-automations\": {\n tool: {\n description: `Manage automations (event-triggered and scheduled tasks). Use the \"action\" parameter to choose an operation:\n\n- **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.\n- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.\n- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, condition, mode, domain, delegated_policy_id, model, mcpTools.\n- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.\n- **delete**: Delete an automation. Always confirm with the user first. Required param: name.\n- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,\n parameters: {\n type: \"object\" as const,\n properties: {\n action: {\n type: \"string\",\n description:\n \"The operation to perform: list-events, list, define, update, delete, or fire-test.\",\n enum: [...VALID_ACTIONS],\n },\n name: {\n type: \"string\",\n description:\n \"Slug name for the automation (lowercase, hyphens). Used by define, update, and delete.\",\n },\n scope: {\n type: \"string\",\n description:\n \"Personal or organization scope. Organization automations are visible to the active organization but always execute as their creator.\",\n enum: [\"personal\", \"organization\"],\n },\n trigger_type: {\n type: \"string\",\n description: '\"event\" or \"schedule\". Required for define.',\n enum: [\"event\", \"schedule\"],\n },\n event: {\n type: \"string\",\n description:\n \"For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.\",\n },\n schedule: {\n type: \"string\",\n description:\n 'For schedule triggers: cron expression. Example: \"0 9 * * 1-5\" (9am weekdays).',\n },\n condition: {\n type: \"string\",\n description:\n 'Natural-language condition. Example: \"attendee email ends with @builder.io\". Leave empty for unconditional. Used by define and update.',\n },\n mode: {\n type: \"string\",\n description:\n '\"agentic\" (full agent loop, can use tools) — the only supported mode. Used by define.',\n enum: [\"agentic\"],\n },\n domain: {\n type: \"string\",\n description:\n \"Domain tag for grouping (mail, calendar, clips, etc.). Used by define and list.\",\n },\n model: {\n type: \"string\",\n description:\n \"Optional model id for this automation. The default model is used when omitted.\",\n },\n mcpTools: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n 'Optional explicit MCP capabilities. Use exact advertised tool names, for example [\"mcp__meeting-notes__list_meetings\"]. Credentials stay in the connector.',\n },\n delegated_policy_id: {\n type: \"string\",\n description:\n \"Optional app-owned stored policy id. It is passed by the trusted trigger runtime, never as action input. Only use an id documented by the app.\",\n },\n body: {\n type: \"string\",\n description:\n \"The natural-language instructions for what to do when the automation fires. This becomes the agent's prompt in agentic mode. Used by define and update.\",\n },\n enabled: {\n type: \"string\",\n description:\n '\"true\" or \"false\" to enable/disable. Used by update.',\n },\n enabled_only: {\n type: \"string\",\n description:\n '\"true\" to show only enabled automations. Used by list.',\n },\n data: {\n type: \"string\",\n description:\n 'JSON data to include as the test event payload. Used by fire-test. Example: \\'{\"email\": \"test@example.com\"}\\'.',\n },\n },\n required: [\"action\"],\n },\n },\n planMode: {\n effect: (args) =>\n args.action === \"list\" || args.action === \"list-events\"\n ? \"read\"\n : \"write\",\n allowedValues: { action: [\"list-events\", \"list\"] },\n description: \"Plan mode allows listing automations and event types.\",\n },\n run: async (args: Record<string, unknown>) => {\n const action = args.action;\n\n switch (action) {\n case \"list-events\":\n return handleListEvents();\n case \"list\":\n return handleList(args, getCurrentUser);\n case \"define\":\n return handleDefine(args, getCurrentUser);\n case \"update\":\n return handleUpdate(args, getCurrentUser);\n case \"delete\":\n return handleDelete(args, getCurrentUser);\n case \"fire-test\":\n return handleFireTest(args, getCurrentUser);\n default:\n return `Error: unknown action \"${action}\". Valid actions: ${VALID_ACTIONS.join(\", \")}.`;\n }\n },\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Framework-level agent actions for the automations system.\n *\n * These are registered as native tools (not template actions) so they're\n * available in every template. The agent uses them to create, list, and\n * manage automations from chat.\n *\n * All six operations are consolidated into a single `manage-automations` tool\n * with an `action` discriminator to keep the tool registry compact.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport {\n defineAutomation,\n deleteAutomation,\n listAutomationDefinitions,\n updateAutomation,\n type AutomationScope,\n} from \"../automations/service.js\";\nimport { listEvents } from \"../event-bus/index.js\";\nimport { describeCron, effectiveTimezone } from \"../jobs/cron.js\";\nimport {\n getIntegrationRequestContext,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { refreshEventSubscriptions } from \"./dispatcher.js\";\n\n/* ------------------------------------------------------------------ */\n/* Individual action handlers */\n/* ------------------------------------------------------------------ */\n\nasync function handleListEvents(): Promise<string> {\n const events = listEvents();\n if (events.length === 0) {\n return \"No events registered yet. Events are registered by integrations (mail, calendar, clips, etc.).\";\n }\n const lines = events.map((e) => {\n let schemaStr = \"\";\n try {\n const s = e.payloadSchema as any;\n if (s?._zod?.def?.shape) {\n const fields = Object.keys(s._zod.def.shape);\n schemaStr = ` Fields: ${fields.join(\", \")}`;\n }\n } catch {\n // ignore\n }\n const example = e.example\n ? `\\n Example: ${JSON.stringify(e.example)}`\n : \"\";\n return `- **${e.name}**: ${e.description}${schemaStr}${example}`;\n });\n return lines.join(\"\\n\");\n}\n\nasync function handleList(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const scope = automationScope(args.scope);\n const definitions = await listAutomationDefinitions(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n scope,\n );\n const automations = definitions\n .filter(({ meta }) => !args.domain || meta.domain === args.domain)\n .filter(({ meta }) => args.enabled_only !== \"true\" || meta.enabled)\n .map(({ name, meta, body, canUpdate }) => ({\n name,\n scope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n timezone: meta.timezone ? effectiveTimezone(meta.timezone) : null,\n scheduleDescription: meta.schedule\n ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))\n : null,\n condition: meta.condition ?? null,\n mode: meta.mode,\n domain: meta.domain ?? null,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: meta.nextRun ?? null,\n createdBy: meta.createdBy ?? null,\n runAs: meta.runAs ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n body,\n canUpdate,\n }));\n return JSON.stringify(automations, null, 2);\n}\n\nfunction automationScope(value: unknown): AutomationScope {\n if (value === undefined || value === null || value === \"\") return \"personal\";\n if (value === \"personal\" || value === \"organization\") return value;\n throw new Error('scope must be \"personal\" or \"organization\".');\n}\n\nfunction automationTriggerType(value: unknown): \"schedule\" | \"event\" {\n if (value === \"schedule\" || value === \"event\") return value;\n throw new Error('trigger_type must be \"schedule\" or \"event\".');\n}\n\nasync function handleDefine(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n if (args.mode === \"deterministic\") {\n return (\n \"Error: Deterministic mode was removed — it was never implemented and \" +\n \"automations that set it never fired. Create the automation without \" +\n \"mode (agentic), and describe the exact fixed steps in the automation body.\"\n );\n }\n const integration = getIntegrationRequestContext();\n try {\n const definition = await defineAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n triggerType: automationTriggerType(args.trigger_type),\n body: typeof args.body === \"string\" ? args.body : \"\",\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n timezone: typeof args.timezone === \"string\" ? args.timezone : undefined,\n event: typeof args.event === \"string\" ? args.event : undefined,\n condition:\n typeof args.condition === \"string\" ? args.condition : undefined,\n domain: typeof args.domain === \"string\" ? args.domain : undefined,\n delegatedPolicyId:\n typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n mcpTools: args.mcpTools,\n delivery: integration\n ? {\n originScopeId: integration.scopeId,\n platform: integration.incoming.platform,\n destination:\n typeof integration.incoming.platformContext.channelId ===\n \"string\"\n ? integration.incoming.platformContext.channelId\n : undefined,\n threadRef:\n typeof integration.incoming.threadRef === \"string\"\n ? integration.incoming.threadRef\n : undefined,\n tenantId: integration.incoming.tenantId,\n }\n : undefined,\n },\n );\n\n await refreshEventSubscriptions();\n return JSON.stringify({\n created: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n event: definition.meta.event ?? null,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleUpdate(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n try {\n const definition = await updateAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n enabled:\n args.enabled === undefined\n ? undefined\n : args.enabled === true || args.enabled === \"true\",\n condition:\n args.condition === undefined\n ? undefined\n : typeof args.condition === \"string\"\n ? args.condition\n : null,\n delegatedPolicyId:\n args.delegated_policy_id === undefined\n ? undefined\n : typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : null,\n body: typeof args.body === \"string\" ? args.body : undefined,\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n timezone: typeof args.timezone === \"string\" ? args.timezone : undefined,\n model:\n args.model === undefined\n ? undefined\n : typeof args.model === \"string\"\n ? args.model\n : null,\n mcpTools: args.mcpTools,\n },\n );\n await refreshEventSubscriptions();\n return JSON.stringify({\n updated: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleDelete(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n try {\n await deleteAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n automationScope(args.scope),\n name,\n );\n await refreshEventSubscriptions();\n return JSON.stringify({ deleted: true, name });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleFireTest(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n // Dynamic import to avoid circular dependency at module load time\n const { emit } = await import(\"../event-bus/index.js\");\n\n let data: Record<string, unknown> = {};\n if (typeof args.data === \"string\" && args.data) {\n try {\n data = JSON.parse(args.data);\n } catch {\n return \"Error: invalid JSON in data parameter.\";\n }\n }\n\n // Scope the test event to the current user so only their automations fire,\n // not automations owned by other users in the same process.\n const owner = getCurrentUser();\n emit(\"test.event.fired\", { data }, { owner });\n return `Test event fired with payload: ${JSON.stringify({ data })}. Any automations subscribed to \"test.event.fired\" will be evaluated.`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Consolidated tool entry */\n/* ------------------------------------------------------------------ */\n\nconst VALID_ACTIONS = [\n \"list-events\",\n \"list\",\n \"define\",\n \"update\",\n \"delete\",\n \"fire-test\",\n] as const;\n\nexport function createAutomationToolEntries(\n getCurrentUser: () => string,\n): Record<string, ActionEntry> {\n return {\n \"manage-automations\": {\n tool: {\n description: `Manage automations (event-triggered and scheduled tasks). Use the \"action\" parameter to choose an operation:\n\n- **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.\n- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.\n- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, timezone, condition, mode, domain, delegated_policy_id, model, mcpTools.\n- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, timezone, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.\n- **delete**: Delete an automation. Always confirm with the user first. Required param: name.\n- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,\n parameters: {\n type: \"object\" as const,\n properties: {\n action: {\n type: \"string\",\n description:\n \"The operation to perform: list-events, list, define, update, delete, or fire-test.\",\n enum: [...VALID_ACTIONS],\n },\n name: {\n type: \"string\",\n description:\n \"Slug name for the automation (lowercase, hyphens). Used by define, update, and delete.\",\n },\n scope: {\n type: \"string\",\n description:\n \"Personal or organization scope. Organization automations are visible to the active organization but always execute as their creator.\",\n enum: [\"personal\", \"organization\"],\n },\n trigger_type: {\n type: \"string\",\n description: '\"event\" or \"schedule\". Required for define.',\n enum: [\"event\", \"schedule\"],\n },\n event: {\n type: \"string\",\n description:\n \"For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.\",\n },\n timezone: {\n type: \"string\",\n description:\n \"IANA timezone the cron clock time is read in, e.g. 'America/New_York'. Optional; defaults to the user's saved scheduling timezone, then the caller's browser zone. Always pass this when the user names a time of day.\",\n },\n schedule: {\n type: \"string\",\n description:\n 'For schedule triggers: cron expression. Example: \"0 9 * * 1-5\" (9am weekdays).',\n },\n condition: {\n type: \"string\",\n description:\n 'Natural-language condition. Example: \"attendee email ends with @builder.io\". Leave empty for unconditional. Used by define and update.',\n },\n mode: {\n type: \"string\",\n description:\n '\"agentic\" (full agent loop, can use tools) — the only supported mode. Used by define.',\n enum: [\"agentic\"],\n },\n domain: {\n type: \"string\",\n description:\n \"Domain tag for grouping (mail, calendar, clips, etc.). Used by define and list.\",\n },\n model: {\n type: \"string\",\n description:\n \"Optional model id for this automation. The default model is used when omitted.\",\n },\n mcpTools: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n 'Optional explicit MCP capabilities. Use exact advertised tool names, for example [\"mcp__meeting-notes__list_meetings\"]. Credentials stay in the connector.',\n },\n delegated_policy_id: {\n type: \"string\",\n description:\n \"Optional app-owned stored policy id. It is passed by the trusted trigger runtime, never as action input. Only use an id documented by the app.\",\n },\n body: {\n type: \"string\",\n description:\n \"The natural-language instructions for what to do when the automation fires. This becomes the agent's prompt in agentic mode. Used by define and update.\",\n },\n enabled: {\n type: \"string\",\n description:\n '\"true\" or \"false\" to enable/disable. Used by update.',\n },\n enabled_only: {\n type: \"string\",\n description:\n '\"true\" to show only enabled automations. Used by list.',\n },\n data: {\n type: \"string\",\n description:\n 'JSON data to include as the test event payload. Used by fire-test. Example: \\'{\"email\": \"test@example.com\"}\\'.',\n },\n },\n required: [\"action\"],\n },\n },\n planMode: {\n effect: (args) =>\n args.action === \"list\" || args.action === \"list-events\"\n ? \"read\"\n : \"write\",\n allowedValues: { action: [\"list-events\", \"list\"] },\n description: \"Plan mode allows listing automations and event types.\",\n },\n run: async (args: Record<string, unknown>) => {\n const action = args.action;\n\n switch (action) {\n case \"list-events\":\n return handleListEvents();\n case \"list\":\n return handleList(args, getCurrentUser);\n case \"define\":\n return handleDefine(args, getCurrentUser);\n case \"update\":\n return handleUpdate(args, getCurrentUser);\n case \"delete\":\n return handleDelete(args, getCurrentUser);\n case \"fire-test\":\n return handleFireTest(args, getCurrentUser);\n default:\n return `Error: unknown action \"${action}\". Valid actions: ${VALID_ACTIONS.join(\", \")}.`;\n }\n },\n },\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,yCAAyC,CAAC;AAWjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAID,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CACpB,UAAU,CAAC,EAAE,2BAA2B,KACrC,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3B;
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,yCAAyC,CAAC;AAWjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAID,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CACpB,UAAU,CAAC,EAAE,2BAA2B,KACrC,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3B;AAyCD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgC/D"}
|
|
@@ -39,6 +39,21 @@ const _eventSubscriptions = new Map();
|
|
|
39
39
|
// deployments; multi-instance would need a conditional DB update.
|
|
40
40
|
const _dispatchingTriggers = new Set();
|
|
41
41
|
let _deps = null;
|
|
42
|
+
/**
|
|
43
|
+
* Record that a tick evaluated this trigger and declined to dispatch it.
|
|
44
|
+
* `lastRun` stays untouched — nothing ran — and an unchanged outcome is not
|
|
45
|
+
* re-persisted, so a permanently blocked trigger neither reports phantom runs
|
|
46
|
+
* nor rewrites its resource on every matching event.
|
|
47
|
+
*/
|
|
48
|
+
async function recordTriggerSkip(resource, meta, body, status, reason) {
|
|
49
|
+
const unchanged = meta.lastStatus === status && meta.lastError === reason;
|
|
50
|
+
meta.lastCheck = new Date().toISOString();
|
|
51
|
+
meta.lastStatus = status;
|
|
52
|
+
meta.lastError = reason;
|
|
53
|
+
if (unchanged)
|
|
54
|
+
return;
|
|
55
|
+
await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
|
|
56
|
+
}
|
|
42
57
|
/**
|
|
43
58
|
* Initialize the trigger dispatcher. Call once at server startup.
|
|
44
59
|
* Loads all event-triggered jobs and subscribes to their events.
|
|
@@ -116,18 +131,11 @@ async function handleEvent(eventName, payload, eventMeta) {
|
|
|
116
131
|
resolved = await resolveAutomationExecutionIdentity(resource.owner, meta);
|
|
117
132
|
}
|
|
118
133
|
catch {
|
|
119
|
-
meta
|
|
120
|
-
meta.lastStatus = "skipped";
|
|
121
|
-
meta.lastError =
|
|
122
|
-
"Could not verify the automation execution identity.";
|
|
123
|
-
await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
|
|
134
|
+
await recordTriggerSkip(resource, meta, body, "skipped", "Could not verify the automation execution identity.");
|
|
124
135
|
continue;
|
|
125
136
|
}
|
|
126
137
|
if (!resolved.ok) {
|
|
127
|
-
meta
|
|
128
|
-
meta.lastStatus = "skipped";
|
|
129
|
-
meta.lastError = resolved.reason;
|
|
130
|
-
await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
|
|
138
|
+
await recordTriggerSkip(resource, meta, body, "skipped", resolved.reason);
|
|
131
139
|
continue;
|
|
132
140
|
}
|
|
133
141
|
if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {
|
|
@@ -140,20 +148,14 @@ async function handleEvent(eventName, payload, eventMeta) {
|
|
|
140
148
|
const userApiKey = await getOwnerActiveApiKey(owner);
|
|
141
149
|
const apiKey = userApiKey || _deps.apiKey;
|
|
142
150
|
if (!apiKey) {
|
|
143
|
-
meta
|
|
144
|
-
meta.lastStatus = "error";
|
|
145
|
-
meta.lastError = "No API key is available for this automation";
|
|
146
|
-
await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
|
|
151
|
+
await recordTriggerSkip(resource, meta, body, "error", "No API key is available for this automation");
|
|
147
152
|
console.warn(`[triggers] ${meta.lastError}: "${resource.path}"`);
|
|
148
153
|
continue;
|
|
149
154
|
}
|
|
150
155
|
// Evaluate condition
|
|
151
156
|
const matches = await evaluateCondition(meta.condition, payload, apiKey);
|
|
152
157
|
if (!matches) {
|
|
153
|
-
meta
|
|
154
|
-
meta.lastStatus = "skipped";
|
|
155
|
-
meta.lastError = undefined;
|
|
156
|
-
await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
|
|
158
|
+
await recordTriggerSkip(resource, meta, body, "skipped", undefined);
|
|
157
159
|
continue;
|
|
158
160
|
}
|
|
159
161
|
// Dispatch. Guard against concurrent duplicate dispatch of the same
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Trigger dispatcher — bridges the event bus to the automation system.\n *\n * On startup, loads all event-triggered jobs from the resources store,\n * subscribes to their events, and dispatches them (condition eval → agent\n * loop) when matching events fire.\n */\n\nimport { getOwnerActiveApiKey } from \"../agent/production-agent.js\";\nimport {\n automationMatchesEventOwner,\n resolveAutomationExecutionIdentity,\n type AutomationExecutionIdentity,\n} from \"../automations/service.js\";\nimport { subscribe, unsubscribe } from \"../event-bus/index.js\";\nimport type { EventMeta } from \"../event-bus/types.js\";\nimport {\n isBackgroundAutomationRunActive,\n runBackgroundAutomation,\n type BackgroundAutomationContext,\n type BackgroundAutomationDeps,\n} from \"../jobs/background-automation-runner.js\";\nimport {\n buildJobResourceContent,\n parseJobResource,\n} from \"../jobs/frontmatter.js\";\nimport {\n resourceListAllOwners,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\nimport { evaluateCondition } from \"./condition-evaluator.js\";\nimport type { TriggerFrontmatter } from \"./types.js\";\n\nexport function parseTriggerFrontmatter(content: string): {\n meta: TriggerFrontmatter;\n body: string;\n} {\n const { meta, body } = parseJobResource(content);\n return {\n meta: {\n ...meta,\n triggerType: meta.triggerType ?? \"schedule\",\n mode: meta.mode ?? \"agentic\",\n },\n body,\n };\n}\n\nexport function buildTriggerContent(\n meta: TriggerFrontmatter,\n body: string,\n): string {\n return buildJobResourceContent(meta, body);\n}\n\n// ─── Dispatcher deps (same pattern as SchedulerDeps) ────────────────────────\n\nexport interface TriggerDispatcherDeps extends BackgroundAutomationDeps {\n /**\n * Tool names to expose on the FIRST engine request for a trigger run. See\n * `SchedulerDeps.getInitialToolNames` (`jobs/scheduler.ts`) — same\n * semantics. Omit to keep the full `getActions()` set visible up front\n * (current behavior).\n */\n getInitialToolNames?: (\n automation?: BackgroundAutomationContext,\n ) => string[] | undefined;\n}\n\n// Track active subscriptions (eventName -> subscription id) to avoid\n// double-subscribing AND so subscriptions for events that no longer have any\n// enabled trigger can be torn down — otherwise deleted/disabled triggers leave\n// phantom bus listeners that fire handleEvent forever.\nconst _eventSubscriptions = new Map<string, string>();\n// In-flight agentic dispatches keyed by `${owner}:${path}`. Guards against the\n// check-then-write TOCTOU window in handleEvent: two near-simultaneous fires of\n// the same event both pass the `lastStatus !== \"running\"` check (which has\n// several awaits before the DB is marked running) and would otherwise launch\n// two concurrent agent runs for one trigger. Sufficient for single-process\n// deployments; multi-instance would need a conditional DB update.\nconst _dispatchingTriggers = new Set<string>();\nlet _deps: TriggerDispatcherDeps | null = null;\n\n/**\n * Initialize the trigger dispatcher. Call once at server startup.\n * Loads all event-triggered jobs and subscribes to their events.\n */\nexport async function initTriggerDispatcher(\n deps: TriggerDispatcherDeps,\n): Promise<void> {\n _deps = deps;\n await refreshEventSubscriptions();\n}\n\n/**\n * Refresh event subscriptions from the resource store.\n * Call after creating/updating triggers.\n */\nexport async function refreshEventSubscriptions(): Promise<void> {\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const eventNames = new Set<string>();\n\n for (const resource of jobResources) {\n if (!resource.path.endsWith(\".md\")) continue;\n const { meta } = parseTriggerFrontmatter(resource.content);\n if (meta.triggerType === \"event\" && meta.event && meta.enabled) {\n eventNames.add(meta.event);\n }\n }\n\n // Tear down subscriptions whose event no longer has any enabled trigger.\n for (const [eventName, subId] of [..._eventSubscriptions]) {\n if (!eventNames.has(eventName)) {\n unsubscribe(subId);\n _eventSubscriptions.delete(eventName);\n }\n }\n\n for (const eventName of eventNames) {\n if (!_eventSubscriptions.has(eventName)) {\n const subId = subscribe(eventName, (payload, eventMeta) =>\n handleEvent(eventName, payload, eventMeta),\n );\n _eventSubscriptions.set(eventName, subId);\n }\n }\n } catch (err) {\n console.error(\"[triggers] Failed to refresh event subscriptions:\", err);\n }\n}\n\nasync function handleEvent(\n eventName: string,\n payload: unknown,\n eventMeta: EventMeta,\n): Promise<void> {\n if (!_deps) return;\n\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const matchingTriggers = jobResources.filter((r) => {\n if (!r.path.endsWith(\".md\")) return false;\n const { meta } = parseTriggerFrontmatter(r.content);\n return (\n meta.triggerType === \"event\" &&\n meta.event === eventName &&\n meta.enabled &&\n !isBackgroundAutomationRunActive(meta)\n );\n });\n\n for (const resource of matchingTriggers) {\n const { meta, body } = parseTriggerFrontmatter(resource.content);\n if (!body.trim()) continue;\n\n let identity: AutomationExecutionIdentity;\n if (resource.owner === \"__shared__\") {\n // Compatibility for old workspace-wide event resources. New personal\n // and organization automations always require an event owner.\n const userEmail = meta.createdBy || resource.owner;\n identity = {\n userEmail,\n orgId: meta.orgId,\n eventOwner: userEmail.toLowerCase(),\n };\n } else {\n let resolved;\n try {\n resolved = await resolveAutomationExecutionIdentity(\n resource.owner,\n meta,\n );\n } catch {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError =\n \"Could not verify the automation execution identity.\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n if (!resolved.ok) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError = resolved.reason;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {\n continue;\n }\n identity = resolved.identity;\n }\n\n // Resolve API key for condition evaluation\n const owner = identity.userEmail;\n const userApiKey = await getOwnerActiveApiKey(owner);\n const apiKey = userApiKey || _deps.apiKey;\n if (!apiKey) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"error\";\n meta.lastError = \"No API key is available for this automation\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.warn(`[triggers] ${meta.lastError}: \"${resource.path}\"`);\n continue;\n }\n\n // Evaluate condition\n const matches = await evaluateCondition(meta.condition, payload, apiKey);\n if (!matches) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n\n // Dispatch. Guard against concurrent duplicate dispatch of the same\n // trigger (TOCTOU on lastStatus) with an in-process lock keyed on the\n // trigger's identity.\n const dispatchKey = `${resource.owner}:${resource.path}`;\n if (_dispatchingTriggers.has(dispatchKey)) continue;\n if (meta.mode === \"agentic\") {\n _dispatchingTriggers.add(dispatchKey);\n try {\n await dispatchAgentic(\n resource,\n meta,\n body,\n payload,\n eventMeta,\n identity,\n );\n } finally {\n _dispatchingTriggers.delete(dispatchKey);\n }\n } else {\n console.warn(\n `[triggers] Deterministic mode not yet implemented for \"${resource.path}\" — skipping`,\n );\n }\n }\n } catch (err) {\n console.error(`[triggers] Error handling event \"${eventName}\":`, err);\n }\n}\n\nasync function dispatchAgentic(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n payload: unknown,\n eventMeta: EventMeta,\n identity: AutomationExecutionIdentity,\n): Promise<void> {\n if (!_deps) return;\n\n const triggerName = resource.path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n const now = new Date();\n\n const jobUserEmail = identity.userEmail;\n const jobOrgId = identity.orgId;\n\n // Mark as running\n meta.lastRun = now.toISOString();\n meta.lastStatus = \"running\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n\n let payloadStr: string;\n try {\n payloadStr = JSON.stringify(payload, null, 2);\n } catch {\n payloadStr = String(payload);\n }\n\n const automation: BackgroundAutomationContext = {\n name: triggerName,\n meta,\n body,\n resource,\n };\n const requestContext =\n meta.originScopeId && meta.deliveryPlatform && meta.deliveryDestination\n ? {\n isIntegrationCaller: true as const,\n integration: {\n taskId: `automation:${triggerName}:${eventMeta.eventId}`,\n scopeId: meta.originScopeId,\n principalType: \"service\" as const,\n incoming: {\n platform: meta.deliveryPlatform,\n externalThreadId: `${meta.deliveryTenantId || \"unknown\"}:${meta.deliveryDestination}:${meta.deliveryThreadRef || \"root\"}`,\n text: \"\",\n tenantId: meta.deliveryTenantId,\n integrationScopeId: meta.originScopeId,\n platformContext: {\n channelId: meta.deliveryDestination,\n threadTs: meta.deliveryThreadRef,\n teamId: meta.deliveryTenantId,\n },\n threadRef: meta.deliveryThreadRef,\n timestamp: now.getTime(),\n },\n },\n }\n : undefined;\n\n try {\n await runBackgroundAutomation(\n {\n automation,\n ownerEmail: jobUserEmail,\n orgId: jobOrgId,\n prompt: `[Automation Trigger: ${triggerName}]\nEvent: ${meta.event}\nEvent ID: ${eventMeta.eventId}\nFired at: ${eventMeta.emittedAt}\n\nEvent payload:\n${payloadStr}\n\nExecute the following automation instructions:\n\n${body}`,\n threadTitle: `Trigger: ${triggerName} — ${now.toLocaleDateString()}`,\n runIdPrefix: `automation-${triggerName}`,\n usageLabel: `automation:${triggerName}`,\n usageRefId: eventMeta.eventId,\n requestContext,\n actionCaller: \"automation\",\n actionAutomation: {\n triggerId: resource.id,\n triggerName,\n policyId: meta.delegatedPolicyId,\n },\n },\n _deps,\n );\n\n meta.lastStatus = \"success\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.log(`[triggers] \"${triggerName}\" completed successfully`);\n } catch (err) {\n meta.lastStatus = \"error\";\n meta.lastError =\n err instanceof Error ? err.message.slice(0, 200) : \"Unknown error\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.error(`[triggers] \"${triggerName}\" failed:`, meta.lastError);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Trigger dispatcher — bridges the event bus to the automation system.\n *\n * On startup, loads all event-triggered jobs from the resources store,\n * subscribes to their events, and dispatches them (condition eval → agent\n * loop) when matching events fire.\n */\n\nimport { getOwnerActiveApiKey } from \"../agent/production-agent.js\";\nimport {\n automationMatchesEventOwner,\n resolveAutomationExecutionIdentity,\n type AutomationExecutionIdentity,\n} from \"../automations/service.js\";\nimport { subscribe, unsubscribe } from \"../event-bus/index.js\";\nimport type { EventMeta } from \"../event-bus/types.js\";\nimport {\n isBackgroundAutomationRunActive,\n runBackgroundAutomation,\n type BackgroundAutomationContext,\n type BackgroundAutomationDeps,\n} from \"../jobs/background-automation-runner.js\";\nimport {\n buildJobResourceContent,\n parseJobResource,\n} from \"../jobs/frontmatter.js\";\nimport {\n resourceListAllOwners,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\nimport { evaluateCondition } from \"./condition-evaluator.js\";\nimport type { TriggerFrontmatter } from \"./types.js\";\n\nexport function parseTriggerFrontmatter(content: string): {\n meta: TriggerFrontmatter;\n body: string;\n} {\n const { meta, body } = parseJobResource(content);\n return {\n meta: {\n ...meta,\n triggerType: meta.triggerType ?? \"schedule\",\n mode: meta.mode ?? \"agentic\",\n },\n body,\n };\n}\n\nexport function buildTriggerContent(\n meta: TriggerFrontmatter,\n body: string,\n): string {\n return buildJobResourceContent(meta, body);\n}\n\n// ─── Dispatcher deps (same pattern as SchedulerDeps) ────────────────────────\n\nexport interface TriggerDispatcherDeps extends BackgroundAutomationDeps {\n /**\n * Tool names to expose on the FIRST engine request for a trigger run. See\n * `SchedulerDeps.getInitialToolNames` (`jobs/scheduler.ts`) — same\n * semantics. Omit to keep the full `getActions()` set visible up front\n * (current behavior).\n */\n getInitialToolNames?: (\n automation?: BackgroundAutomationContext,\n ) => string[] | undefined;\n}\n\n// Track active subscriptions (eventName -> subscription id) to avoid\n// double-subscribing AND so subscriptions for events that no longer have any\n// enabled trigger can be torn down — otherwise deleted/disabled triggers leave\n// phantom bus listeners that fire handleEvent forever.\nconst _eventSubscriptions = new Map<string, string>();\n// In-flight agentic dispatches keyed by `${owner}:${path}`. Guards against the\n// check-then-write TOCTOU window in handleEvent: two near-simultaneous fires of\n// the same event both pass the `lastStatus !== \"running\"` check (which has\n// several awaits before the DB is marked running) and would otherwise launch\n// two concurrent agent runs for one trigger. Sufficient for single-process\n// deployments; multi-instance would need a conditional DB update.\nconst _dispatchingTriggers = new Set<string>();\nlet _deps: TriggerDispatcherDeps | null = null;\n\n/**\n * Record that a tick evaluated this trigger and declined to dispatch it.\n * `lastRun` stays untouched — nothing ran — and an unchanged outcome is not\n * re-persisted, so a permanently blocked trigger neither reports phantom runs\n * nor rewrites its resource on every matching event.\n */\nasync function recordTriggerSkip(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n status: \"skipped\" | \"error\",\n reason: string | undefined,\n): Promise<void> {\n const unchanged = meta.lastStatus === status && meta.lastError === reason;\n meta.lastCheck = new Date().toISOString();\n meta.lastStatus = status;\n meta.lastError = reason;\n if (unchanged) return;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n}\n\n/**\n * Initialize the trigger dispatcher. Call once at server startup.\n * Loads all event-triggered jobs and subscribes to their events.\n */\nexport async function initTriggerDispatcher(\n deps: TriggerDispatcherDeps,\n): Promise<void> {\n _deps = deps;\n await refreshEventSubscriptions();\n}\n\n/**\n * Refresh event subscriptions from the resource store.\n * Call after creating/updating triggers.\n */\nexport async function refreshEventSubscriptions(): Promise<void> {\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const eventNames = new Set<string>();\n\n for (const resource of jobResources) {\n if (!resource.path.endsWith(\".md\")) continue;\n const { meta } = parseTriggerFrontmatter(resource.content);\n if (meta.triggerType === \"event\" && meta.event && meta.enabled) {\n eventNames.add(meta.event);\n }\n }\n\n // Tear down subscriptions whose event no longer has any enabled trigger.\n for (const [eventName, subId] of [..._eventSubscriptions]) {\n if (!eventNames.has(eventName)) {\n unsubscribe(subId);\n _eventSubscriptions.delete(eventName);\n }\n }\n\n for (const eventName of eventNames) {\n if (!_eventSubscriptions.has(eventName)) {\n const subId = subscribe(eventName, (payload, eventMeta) =>\n handleEvent(eventName, payload, eventMeta),\n );\n _eventSubscriptions.set(eventName, subId);\n }\n }\n } catch (err) {\n console.error(\"[triggers] Failed to refresh event subscriptions:\", err);\n }\n}\n\nasync function handleEvent(\n eventName: string,\n payload: unknown,\n eventMeta: EventMeta,\n): Promise<void> {\n if (!_deps) return;\n\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const matchingTriggers = jobResources.filter((r) => {\n if (!r.path.endsWith(\".md\")) return false;\n const { meta } = parseTriggerFrontmatter(r.content);\n return (\n meta.triggerType === \"event\" &&\n meta.event === eventName &&\n meta.enabled &&\n !isBackgroundAutomationRunActive(meta)\n );\n });\n\n for (const resource of matchingTriggers) {\n const { meta, body } = parseTriggerFrontmatter(resource.content);\n if (!body.trim()) continue;\n\n let identity: AutomationExecutionIdentity;\n if (resource.owner === \"__shared__\") {\n // Compatibility for old workspace-wide event resources. New personal\n // and organization automations always require an event owner.\n const userEmail = meta.createdBy || resource.owner;\n identity = {\n userEmail,\n orgId: meta.orgId,\n eventOwner: userEmail.toLowerCase(),\n };\n } else {\n let resolved;\n try {\n resolved = await resolveAutomationExecutionIdentity(\n resource.owner,\n meta,\n );\n } catch {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"skipped\",\n \"Could not verify the automation execution identity.\",\n );\n continue;\n }\n if (!resolved.ok) {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"skipped\",\n resolved.reason,\n );\n continue;\n }\n if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {\n continue;\n }\n identity = resolved.identity;\n }\n\n // Resolve API key for condition evaluation\n const owner = identity.userEmail;\n const userApiKey = await getOwnerActiveApiKey(owner);\n const apiKey = userApiKey || _deps.apiKey;\n if (!apiKey) {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"error\",\n \"No API key is available for this automation\",\n );\n console.warn(`[triggers] ${meta.lastError}: \"${resource.path}\"`);\n continue;\n }\n\n // Evaluate condition\n const matches = await evaluateCondition(meta.condition, payload, apiKey);\n if (!matches) {\n await recordTriggerSkip(resource, meta, body, \"skipped\", undefined);\n continue;\n }\n\n // Dispatch. Guard against concurrent duplicate dispatch of the same\n // trigger (TOCTOU on lastStatus) with an in-process lock keyed on the\n // trigger's identity.\n const dispatchKey = `${resource.owner}:${resource.path}`;\n if (_dispatchingTriggers.has(dispatchKey)) continue;\n if (meta.mode === \"agentic\") {\n _dispatchingTriggers.add(dispatchKey);\n try {\n await dispatchAgentic(\n resource,\n meta,\n body,\n payload,\n eventMeta,\n identity,\n );\n } finally {\n _dispatchingTriggers.delete(dispatchKey);\n }\n } else {\n console.warn(\n `[triggers] Deterministic mode not yet implemented for \"${resource.path}\" — skipping`,\n );\n }\n }\n } catch (err) {\n console.error(`[triggers] Error handling event \"${eventName}\":`, err);\n }\n}\n\nasync function dispatchAgentic(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n payload: unknown,\n eventMeta: EventMeta,\n identity: AutomationExecutionIdentity,\n): Promise<void> {\n if (!_deps) return;\n\n const triggerName = resource.path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n const now = new Date();\n\n const jobUserEmail = identity.userEmail;\n const jobOrgId = identity.orgId;\n\n // Mark as running\n meta.lastRun = now.toISOString();\n meta.lastStatus = \"running\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n\n let payloadStr: string;\n try {\n payloadStr = JSON.stringify(payload, null, 2);\n } catch {\n payloadStr = String(payload);\n }\n\n const automation: BackgroundAutomationContext = {\n name: triggerName,\n meta,\n body,\n resource,\n };\n const requestContext =\n meta.originScopeId && meta.deliveryPlatform && meta.deliveryDestination\n ? {\n isIntegrationCaller: true as const,\n integration: {\n taskId: `automation:${triggerName}:${eventMeta.eventId}`,\n scopeId: meta.originScopeId,\n principalType: \"service\" as const,\n incoming: {\n platform: meta.deliveryPlatform,\n externalThreadId: `${meta.deliveryTenantId || \"unknown\"}:${meta.deliveryDestination}:${meta.deliveryThreadRef || \"root\"}`,\n text: \"\",\n tenantId: meta.deliveryTenantId,\n integrationScopeId: meta.originScopeId,\n platformContext: {\n channelId: meta.deliveryDestination,\n threadTs: meta.deliveryThreadRef,\n teamId: meta.deliveryTenantId,\n },\n threadRef: meta.deliveryThreadRef,\n timestamp: now.getTime(),\n },\n },\n }\n : undefined;\n\n try {\n await runBackgroundAutomation(\n {\n automation,\n ownerEmail: jobUserEmail,\n orgId: jobOrgId,\n prompt: `[Automation Trigger: ${triggerName}]\nEvent: ${meta.event}\nEvent ID: ${eventMeta.eventId}\nFired at: ${eventMeta.emittedAt}\n\nEvent payload:\n${payloadStr}\n\nExecute the following automation instructions:\n\n${body}`,\n threadTitle: `Trigger: ${triggerName} — ${now.toLocaleDateString()}`,\n runIdPrefix: `automation-${triggerName}`,\n usageLabel: `automation:${triggerName}`,\n usageRefId: eventMeta.eventId,\n requestContext,\n actionCaller: \"automation\",\n actionAutomation: {\n triggerId: resource.id,\n triggerName,\n policyId: meta.delegatedPolicyId,\n },\n },\n _deps,\n );\n\n meta.lastStatus = \"success\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.log(`[triggers] \"${triggerName}\" completed successfully`);\n } catch (err) {\n meta.lastStatus = \"error\";\n meta.lastError =\n err instanceof Error ? err.message.slice(0, 200) : \"Unknown error\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.error(`[triggers] \"${triggerName}\" failed:`, meta.lastError);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/triggers/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/triggers/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AA4BZ,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,yBAAyB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6JD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA4BhC;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA8D9B;AAWD,wBAAgB,wBAAwB;;;;IA8DvC"}
|