@xopcai/xopc 0.0.332 → 0.0.334
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/dist/browser-ext/dist/assets/{auth-DocRzRlS.js → auth-Cjj5SuoT.js} +49 -39
- package/dist/browser-ext/dist/background.js +1 -1
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +240 -36
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-C2wg3xC_.js → agent-avatar-dicebear-B73q7mlz.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-B9L2YIXz.js +1 -0
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BeNnu1Ts.js → agent-plugin-dialog-COOjsvea.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CCj1JnLu.js +70 -0
- package/dist/gateway/static/root/assets/agents-admin-api-Cuqi5xZn.js +2 -0
- package/dist/gateway/static/root/assets/{app-link-C6gA5Nck.js → app-link-DRL0YnPs.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-etFSkfzl.js → app-management-settings-panel-CckioKud.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DKmU2VAP.js → appearance-settings-DDiPIr_Q.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-Azqy8vfo.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-D0z_Fr2G.js → archive-plugin-Dtyr0RhX.js} +1 -1
- package/dist/gateway/static/root/assets/attachment-load-qjPpQzYY.js +1 -0
- package/dist/gateway/static/root/assets/attachment-utils-core-BIOUBrpT.js +1 -0
- package/dist/gateway/static/root/assets/{automations-page-B7_C-p66.js → automations-page-g3SrFkTC.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-B0nW2nZD.js +7 -0
- package/dist/gateway/static/root/assets/binary-plugins-BwKQVxsU.js +2 -0
- package/dist/gateway/static/root/assets/{block-editor-ChWW8Z9L.js → block-editor-DD9d5pCt.js} +29 -29
- package/dist/gateway/static/root/assets/{browser-automation-inputs-C5s1yHOu.js → browser-automation-inputs-D2gNdS3e.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-BV00BXRb.js → browser-automations-page-BKqqJR7P.js} +2 -2
- package/dist/gateway/static/root/assets/{browser-settings-page-xwTmuZjS.js → browser-settings-page-BZH9bZbk.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-CHk4RZl4.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-page-CfWaVH-6.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C5FcWsSe.js +8 -0
- package/dist/gateway/static/root/assets/capability-header-actions-Bd66yEOa.js +1 -0
- package/dist/gateway/static/root/assets/channels-DIU5Gq4o.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-C41mXCAi.js → chat-terminal-dock-B0nPDJyj.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-BJkqok2G.js → computer-settings-page-D7PxxaoG.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-BKCZMmwm.js → connector-service-page-BZH4SeQg.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-BC81R_fz.js +2 -0
- package/dist/gateway/static/root/assets/{turn-outcome-D0SnyZ3Z.js → constants-Co2_smKQ.js} +1 -1
- package/dist/gateway/static/root/assets/date-picker-CDEVYjXI.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-CqADAHZp.js → dependency-picker-AInmpSwC.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Bab-iWED.js → desktop-pet-Sjgnlq8M.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BqgzLOdi.js → desktop-pet-settings-BWn0rrhr.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-DFg7FDPf.js → device-pairing-wizard-BtW837_d.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-hqJ9sFCR.js → directory-picker-path-field-2CpmDx_D.js} +1 -1
- package/dist/gateway/static/root/assets/dist-CKkafhaS.js +1 -0
- package/dist/gateway/static/root/assets/dist-io9jFpN72.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-DX3PFhRE.js → extension-debug-page-WWJFj9Z5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DkREdHLs.js → extension-page-DL00dFRr.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-wF-HNTM-.js → extension-settings-page-CN-agjPk.js} +1 -1
- package/dist/gateway/static/root/assets/{files-BK6enEvD.js → files-Bw4SBGdM.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-cR-tz7-Q.js → gateway-config-swr-CgIjCxM8.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-Ciq4c7KT.js +1 -0
- package/dist/gateway/static/root/assets/gateway-realtime-store-BHeHN26R.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-4oD6fhAm.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-6jLRcQsu.js → gateway-startup-retry-i-1lTrwY.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-nEpyJUBY.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-CSSkwsyC.js → image-generation-api-gilc-u7M.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-B80Cv043.js → imports-page-BivdeiQ5.js} +1 -1
- package/dist/gateway/static/root/assets/index-BioG1pRD.js +106 -0
- package/dist/gateway/static/root/assets/index-DbLEkdNg.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BgoFaTwv.js → keyboard-shortcuts-settings-B_8AJTFr.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-CRtZQrmz.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-HO6OQlQT.js → local-apps-page-DclxpoqR.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-Bpja8nC6.js → local-apps-yys1VChX.js} +1 -1
- package/dist/gateway/static/root/assets/local-session-drafts-DkolHmyp.js +1 -0
- package/dist/gateway/static/root/assets/{locale-store-wNXWkWu5.js → locale-store-BY30D6tg.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DX8TxkRl.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-5WFufZ4g.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DlT9KqwF.js → markdown-view-DYJnwlDr.js} +1 -1
- package/dist/gateway/static/root/assets/media-plugins-DlJDvwLK.js +1 -0
- package/dist/gateway/static/root/assets/messages-_6IXbP2u.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-GF5Q9Fqy.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-E8o4_Ty9.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-CiCmfRTw.js +1 -0
- package/dist/gateway/static/root/assets/{page-tabs-vqI30Yrg.js → page-tabs-Cwp3fGVM.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-0p9PIHRy.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-B-mwPBJW.js → preview-open-alternatives-DJ5xqGeu.js} +1 -1
- package/dist/gateway/static/root/assets/{product-delivery-bv3z8Xkh.js → product-delivery-BAks11S4.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-D--sj_uN.js → product-open-page-CcGwNePw.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-6hhRBkmC.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-DUOzRaFI.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-BIpltJ47.js → registry-api-BvVx0G1o.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BWpWUXiE.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CAnb0PNY.js → runtime-tools-settings-panel-C6eDCNHz.js} +2 -2
- package/dist/gateway/static/root/assets/scenes-page-pF7Lmqnk.js +2 -0
- package/dist/gateway/static/root/assets/{schema-form-BKj6wIMb.js → schema-form-D8W8q_ez.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-88fK3zzl.js → schemas-CObaziC7.js} +3 -3
- package/dist/gateway/static/root/assets/session-api-BAyUr97V.js +1 -0
- package/dist/gateway/static/root/assets/session-manager-BAy2sR2Q.js +16 -0
- package/dist/gateway/static/root/assets/sessions-page-BDKDqqf9.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-C9cJWlAq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-78ycUHfv.js → settings-form-section-B0cAj0nq.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BOdxIVzo.js → settings-page-DZVVTFxs.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-DZCPVx9c.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-BkPNyV8c.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-Bqlv5JBi.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-CiBGQ0Jg.js → skill-api-C0dufzQC.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-3JF2OTBz.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-DB4lR4om.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-CyJUeREH.js → system-settings-panel-xjrlhdUz.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-CB6M7wSs.js +1 -0
- package/dist/gateway/static/root/assets/{tasks-CDR_RVbQ.js → tasks-QQJXsiER.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-Day9zhKi.js → tunnel-api--68MQEWM.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-OLZ00eqD.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-Bj9hC6ML.js → use-autosave-DsnHYpTv.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-CoePFpHD.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-fWRD6B8r.js → voice-api-key-field-CvIXutQp.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-ujEySjyc.js → voice-config-api-Bwy3Al3J.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CnxdvIk8.js → work-discovery-overlay-By5_7MLR.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DlWNN1VA.js → workflow-run-setup-panel-HSMDxDXV.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DElQ47Da.js +6 -0
- package/dist/gateway/static/root/index.html +27 -21
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/automations.js +44 -14
- package/dist/packages/gateway-contract/src/capabilities.js +120 -10
- package/dist/packages/gateway-contract/src/index.js +8 -2
- package/dist/packages/gateway-contract/src/scenes.js +7 -6
- package/dist/packages/gateway-contract/src/session-command-rejection.js +19 -0
- package/dist/packages/gateway-contract/src/session-input-command.js +109 -0
- package/dist/packages/gateway-contract/src/sessions.js +2 -7
- package/dist/packages/gateway-contract/src/usage.js +6 -0
- package/dist/src/agent/agent-manager.js +15 -9
- package/dist/src/agent/background-review/run-background-review.js +8 -3
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/embedded/run-turn.js +7 -1
- package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
- package/dist/src/agent/external-tools/gateway-tools.d.ts +2 -1
- package/dist/src/agent/external-tools/gateway-tools.js +45 -11
- package/dist/src/agent/external-tools/index.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +2 -2
- package/dist/src/agent/image/understanding/pi-ai-provider.js +1 -1
- package/dist/src/agent/memory/compaction.js +4 -0
- package/dist/src/agent/service/btw-query.js +8 -2
- package/dist/src/agent/service/process-direct-streaming.js +4 -2
- package/dist/src/agent/service.js +5 -5
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/filesystem-watcher.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +7 -3
- package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
- package/dist/src/agent/tool-manuals/xopc-use.js +5 -4
- package/dist/src/agent/tools/automation-tool.d.ts +4 -1
- package/dist/src/agent/tools/automation-tool.js +42 -4
- package/dist/src/agent/tools/session-search-tool.js +1 -1
- package/dist/src/agent/tools/web-extract.js +1 -1
- package/dist/src/agent/tools/xopc-use-tool.js +50 -9
- package/dist/src/agent-catalog/capabilities.js +2 -2
- package/dist/src/ai-assist/text-assist.js +6 -2
- package/dist/src/auth/credentials.js +1 -1
- package/dist/src/auth/oauth-provider-lock.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/automations/api/routes.js +65 -0
- package/dist/src/automations/capabilities/drafts.js +1 -1
- package/dist/src/automations/capabilities/read.js +24 -0
- package/dist/src/automations/capabilities/write.d.ts +52 -14
- package/dist/src/automations/capabilities/write.js +52 -3
- package/dist/src/automations/delivery/delivery-router.d.ts +50 -0
- package/dist/src/automations/delivery/delivery-router.js +318 -0
- package/dist/src/automations/delivery/index.d.ts +1 -0
- package/dist/src/automations/delivery/index.js +2 -0
- package/dist/src/automations/domain/defaults.d.ts +0 -1
- package/dist/src/automations/domain/defaults.js +1 -1
- package/dist/src/automations/domain/index.js +2 -2
- package/dist/src/automations/domain/types.d.ts +158 -7
- package/dist/src/automations/domain/validation.d.ts +104 -22
- package/dist/src/automations/domain/validation.js +66 -13
- package/dist/src/automations/draft/automation-draft-prompt.js +3 -4
- package/dist/src/automations/draft/automation-draft-service.js +6 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +22 -3
- package/dist/src/automations/draft/automation-draft-validator.js +4 -4
- package/dist/src/automations/events/event-catalog.d.ts +14 -0
- package/dist/src/automations/events/event-catalog.js +117 -0
- package/dist/src/automations/events/event-dispatcher.d.ts +27 -0
- package/dist/src/automations/events/event-dispatcher.js +140 -0
- package/dist/src/automations/events/event-repository.d.ts +59 -0
- package/dist/src/automations/events/event-repository.js +361 -0
- package/dist/src/automations/events/index.d.ts +3 -0
- package/dist/src/automations/events/index.js +4 -0
- package/dist/src/automations/index.d.ts +3 -1
- package/dist/src/automations/index.js +9 -3
- package/dist/src/automations/service/action-executor.d.ts +20 -1
- package/dist/src/automations/service/action-executor.js +80 -40
- package/dist/src/automations/service/automation-service.d.ts +21 -4
- package/dist/src/automations/service/automation-service.js +150 -100
- package/dist/src/automations/storage/automation-repository.js +4 -5
- package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
- package/dist/src/automations/storage/automation-run-repository.js +26 -1
- package/dist/src/automations/storage/index.js +2 -2
- package/dist/src/automations/webhook-secrets.d.ts +1 -0
- package/dist/src/automations/webhook-secrets.js +16 -0
- package/dist/src/bootstrap/application-state.js +1 -1
- package/dist/src/capabilities/runtime/dispatcher.js +1 -1
- package/dist/src/capabilities/runtime/product.js +1 -1
- package/dist/src/capabilities/store-connector.d.ts +17 -1
- package/dist/src/capabilities/store-connector.js +69 -3
- package/dist/src/channels/attachments/voice-stt-webchat.js +1 -1
- package/dist/src/chat-commands/agent-edit.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/cli/commands/agent.js +1 -1
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/connectors.js +4 -3
- package/dist/src/cli/commands/doctor/checks/automation-integrity.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/automation-integrity.js +55 -0
- package/dist/src/cli/commands/doctor/checks/database-relations.d.ts +2 -0
- package/dist/src/cli/commands/doctor/checks/database-relations.js +81 -0
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +2 -2
- package/dist/src/cli/commands/doctor/flow.js +5 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +2 -2
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +1 -1
- package/dist/src/computer/runtime.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/approval-resume.js +1 -1
- package/dist/src/connectors/cli/authorization.d.ts +1 -1
- package/dist/src/connectors/cli/store.d.ts +1 -1
- package/dist/src/connectors/cli/store.js +1 -1
- package/dist/src/connectors/composio-backends.js +14 -4
- package/dist/src/connectors/composio-managed-events.d.ts +5 -2
- package/dist/src/connectors/composio-managed-events.js +4 -1
- package/dist/src/connectors/connection-candidates.js +53 -15
- package/dist/src/connectors/connection-capabilities.js +5 -1
- package/dist/src/connectors/connection-recovery-service.d.ts +2 -1
- package/dist/src/connectors/connection-recovery-service.js +89 -4
- package/dist/src/discussions/analyzer.js +4 -4
- package/dist/src/execution-environments/local-worktree-manager.js +10 -1
- package/dist/src/execution-environments/session-environment-service.d.ts +3 -0
- package/dist/src/execution-environments/session-environment-service.js +28 -4
- package/dist/src/extensions/agent-plugins/validation.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/agents-admin.js +2 -2
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/home-intelligence-automation-reconciler.js +4 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -2
- package/dist/src/gateway/hono/routes/browser-session.js +4 -2
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/commands-skills.js +9 -2
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connection-waits.js +3 -2
- package/dist/src/gateway/hono/routes/files.js +3 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
- package/dist/src/gateway/hono/routes/models.js +17 -1
- package/dist/src/gateway/hono/routes/notes.js +2 -4
- package/dist/src/gateway/hono/routes/projects.js +2 -2
- package/dist/src/gateway/hono/routes/public-gateway.js +93 -3
- package/dist/src/gateway/hono/routes/scenes.js +57 -41
- package/dist/src/gateway/hono/routes/session-command-handler.d.ts +5 -0
- package/dist/src/gateway/hono/routes/session-command-handler.js +189 -0
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +14 -2
- package/dist/src/gateway/hono/routes/session-input-handler.js +2 -2
- package/dist/src/gateway/hono/routes/sessions.js +15 -168
- package/dist/src/gateway/hono/routes/tasks.js +1 -1
- package/dist/src/gateway/hono/routes/tui.js +2 -1
- package/dist/src/gateway/hono/routes/usage.d.ts +3 -0
- package/dist/src/gateway/hono/routes/usage.js +61 -0
- package/dist/src/gateway/hono/routes/voice.js +10 -1
- package/dist/src/gateway/image-generation-setup.js +2 -2
- package/dist/src/gateway/lock.js +1 -1
- package/dist/src/gateway/memory-maintenance-automation-reconciler.js +5 -2
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.js +2 -2
- package/dist/src/gateway/scenes/host.js +27 -14
- package/dist/src/gateway/scenes/slackThreadSource.d.ts +2 -2
- package/dist/src/gateway/security/gateway-scopes.js +1 -0
- package/dist/src/gateway/service/active-execution.d.ts +19 -0
- package/dist/src/gateway/service/active-execution.js +16 -0
- package/dist/src/gateway/service/agent-runner.d.ts +4 -0
- package/dist/src/gateway/service/agent-runner.js +19 -1
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.d.ts +2 -0
- package/dist/src/gateway/service/run-gateway-agent.js +10 -2
- package/dist/src/gateway/service/session-command-service.d.ts +34 -0
- package/dist/src/gateway/service/session-command-service.js +81 -0
- package/dist/src/gateway/service/session-input-coordinator.d.ts +21 -0
- package/dist/src/gateway/service/session-input-coordinator.js +41 -0
- package/dist/src/gateway/service/session-preparation-worker.d.ts +15 -0
- package/dist/src/gateway/service/session-preparation-worker.js +125 -0
- package/dist/src/gateway/service/sessions-api.d.ts +13 -0
- package/dist/src/gateway/service/sessions-api.js +23 -0
- package/dist/src/gateway/service.d.ts +30 -3
- package/dist/src/gateway/service.js +89 -79
- package/dist/src/gateway/side-chat/promotion-service.js +0 -1
- package/dist/src/gateway/side-chat/run-service.js +10 -7
- package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
- package/dist/src/home-intelligence/generator.js +5 -2
- package/dist/src/infra/domain-outbox-dispatcher.d.ts +0 -3
- package/dist/src/infra/domain-outbox-dispatcher.js +15 -7
- package/dist/src/local-apps/service.js +2 -2
- package/dist/src/mcp/channel-bridge.js +12 -2
- package/dist/src/notes/capabilities/read.js +2 -2
- package/dist/src/notes/service.d.ts +4 -1
- package/dist/src/notes/service.js +13 -11
- package/dist/src/projects/project-service.js +1 -2
- package/dist/src/projects/project-skill-service.js +2 -2
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-call.d.ts +3 -2
- package/dist/src/providers/model-call.js +30 -5
- package/dist/src/providers/model-catalog-persistence.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/scenes/activationAdapter.d.ts +19 -0
- package/dist/src/scenes/activationAdapter.js +1 -0
- package/dist/src/scenes/agentExecutor.js +3 -10
- package/dist/src/scenes/contracts.d.ts +3 -9
- package/dist/src/scenes/contracts.js +1 -0
- package/dist/src/scenes/execution.d.ts +9 -3
- package/dist/src/scenes/execution.js +12 -11
- package/dist/src/scenes/httpServices.d.ts +5 -2
- package/dist/src/scenes/mailContext.d.ts +4 -0
- package/dist/src/scenes/mailContext.js +9 -0
- package/dist/src/scenes/maintenance.js +1 -5
- package/dist/src/scenes/metrics.d.ts +0 -6
- package/dist/src/scenes/metrics.js +0 -11
- package/dist/src/scenes/registry.d.ts +11 -0
- package/dist/src/scenes/registry.js +28 -0
- package/dist/src/scenes/repository.d.ts +6 -3
- package/dist/src/scenes/repository.js +43 -5
- package/dist/src/scenes/service.d.ts +2 -1
- package/dist/src/scenes/service.js +9 -7
- package/dist/src/scenes/taskFollowUp/contracts.d.ts +37 -7
- package/dist/src/scenes/taskFollowUp/contracts.js +36 -17
- package/dist/src/scenes/taskFollowUp/service.d.ts +35 -7
- package/dist/src/scenes/taskFollowUp/service.js +86 -28
- package/dist/src/scenes/templates.d.ts +2 -2
- package/dist/src/scenes/userNotes.d.ts +3 -0
- package/dist/src/scenes/userNotes.js +6 -0
- package/dist/src/session/client-history.d.ts +3 -0
- package/dist/src/session/client-history.js +10 -5
- package/dist/src/session/manager.d.ts +1 -0
- package/dist/src/session/resolve-session.js +4 -3
- package/dist/src/session/session-title.js +1 -1
- package/dist/src/session/store.d.ts +1 -0
- package/dist/src/session/store.js +3 -3
- package/dist/src/storage/sqlite/ai-usage-repository.d.ts +137 -0
- package/dist/src/storage/sqlite/ai-usage-repository.js +175 -0
- package/dist/src/storage/sqlite/connector-account-repository.js +7 -5
- package/dist/src/storage/sqlite/connector-repository.js +36 -34
- package/dist/src/storage/sqlite/index.d.ts +2 -2
- package/dist/src/storage/sqlite/index.js +3 -3
- package/dist/src/storage/sqlite/migrations/209_automation_event_hub.sql +48 -0
- package/dist/src/storage/sqlite/migrations/210_remove_legacy_automation_timeout.sql +14 -0
- package/dist/src/storage/sqlite/migrations/211_automation_result_deliveries.sql +16 -0
- package/dist/src/storage/sqlite/migrations/212_automation_delivery_policy.sql +30 -0
- package/dist/src/storage/sqlite/migrations/213_automation_reliability_contract.sql +188 -0
- package/dist/src/storage/sqlite/migrations/214_ai_usage_ledger.sql +41 -0
- package/dist/src/storage/sqlite/migrations/215_scene_execution_adapters.sql +6 -0
- package/dist/src/storage/sqlite/migrations/216_remove_scene_model_usage.sql +1 -0
- package/dist/src/storage/sqlite/migrations/217_remove_legacy_memory_tables.sql +4 -0
- package/dist/src/storage/sqlite/migrations/218_core_relation_indexes.sql +26 -0
- package/dist/src/storage/sqlite/migrations/219_json_contracts.sql +123 -0
- package/dist/src/storage/sqlite/migrations/220_normalize_timestamps.sql +339 -0
- package/dist/src/storage/sqlite/migrations/221_ai_usage_retention_index.sql +2 -0
- package/dist/src/storage/sqlite/migrations/222_session_config_authority.sql +13 -0
- package/dist/src/storage/sqlite/migrations/223_session_creation_receipts.sql +59 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- package/dist/src/storage/sqlite/row-mappers.d.ts +3 -7
- package/dist/src/storage/sqlite/row-mappers.js +6 -6
- package/dist/src/storage/sqlite/scenes-schema.d.ts +1 -1
- package/dist/src/storage/sqlite/scenes-schema.js +0 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +0 -52
- package/dist/src/storage/sqlite/schemas/scenes.sql +0 -7
- package/dist/src/storage/sqlite/session-creation-repository.d.ts +50 -0
- package/dist/src/storage/sqlite/session-creation-repository.js +166 -0
- package/dist/src/storage/sqlite/session-input-repository.d.ts +12 -2
- package/dist/src/storage/sqlite/session-input-repository.js +25 -2
- package/dist/src/storage/sqlite/session-read-repository.d.ts +1 -1
- package/dist/src/storage/sqlite/session-read-repository.js +0 -1
- package/dist/src/storage/sqlite/session-repository.d.ts +0 -4
- package/dist/src/storage/sqlite/session-repository.js +8 -18
- package/dist/src/storage/sqlite/timestamps.d.ts +4 -0
- package/dist/src/storage/sqlite/timestamps.js +20 -0
- package/dist/src/storage/sqlite/transcript-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/transcript-repository.js +23 -15
- package/dist/src/storage/sqlite/user-trust-repository.js +4 -2
- package/dist/src/tasks/capabilities/read.js +2 -2
- package/dist/src/tasks/capabilities/write.d.ts +1 -1
- package/dist/src/tasks/home-query-service.js +3 -3
- package/dist/src/tasks/task-contract-planner.js +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +5 -0
- package/dist/src/tui/backends/embedded-backend.js +266 -20
- package/dist/src/tui/backends/embedded-drafts.d.ts +22 -0
- package/dist/src/tui/backends/embedded-drafts.js +53 -0
- package/dist/src/tui/backends/gateway-realtime-backend.d.ts +10 -0
- package/dist/src/tui/backends/gateway-realtime-backend.js +214 -33
- package/dist/src/tui/tui-backend.d.ts +1 -1
- package/dist/src/tui/tui-chat-input-state.d.ts +1 -0
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/tui/tui-session-format.js +0 -1
- package/dist/src/tui/tui-startup-resources.d.ts +1 -0
- package/dist/src/tui/tui-startup-resources.js +2 -2
- package/dist/src/tui/tui-types.d.ts +0 -1
- package/dist/src/tui/tui.js +69 -29
- package/dist/src/usage/cost.d.ts +4 -0
- package/dist/src/usage/cost.js +28 -0
- package/dist/src/usage/recorder.d.ts +13 -0
- package/dist/src/usage/recorder.js +117 -0
- package/dist/src/usage/scenario-registry.d.ts +8 -0
- package/dist/src/usage/scenario-registry.js +117 -0
- package/dist/src/usage/types.d.ts +55 -0
- package/dist/src/usage/types.js +1 -0
- package/dist/src/voice/realtime/persona-context.js +1 -1
- package/dist/src/voice/tts/summarize.js +1 -1
- package/dist/src/work-discovery/analyzer.js +2 -2
- package/dist/src/work-discovery/investigator.js +1 -1
- package/dist/src/work-discovery/service.js +3 -6
- package/dist/src/workflows/service/workflow-run-service.js +16 -3
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Se1Z72VG.js +0 -1
- package/dist/gateway/static/root/assets/agents-udIitwV8.js +0 -70
- package/dist/gateway/static/root/assets/apps-page-DVNySL58.js +0 -1
- package/dist/gateway/static/root/assets/attachment-load-DNCDbeOX.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BMgJvdcv.js +0 -7
- package/dist/gateway/static/root/assets/binary-plugins-BYn2hScX.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-CHA-sTAZ.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-page-v0WkhV5o.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DefBGjhV.js +0 -8
- package/dist/gateway/static/root/assets/capability-header-actions-vmx35sbu.js +0 -1
- package/dist/gateway/static/root/assets/channels-Eo4ONF5X.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DZYgogQw.js +0 -2
- package/dist/gateway/static/root/assets/conversation-identity-Cw0n9uzK.js +0 -1
- package/dist/gateway/static/root/assets/date-picker-CrOV4Ynd.js +0 -1
- package/dist/gateway/static/root/assets/dist-3h6cXXhT.js +0 -1
- package/dist/gateway/static/root/assets/dist-Che_jiQF.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-Du-Dos9O.js +0 -1
- package/dist/gateway/static/root/assets/home-page-D7YoMHq4.js +0 -1
- package/dist/gateway/static/root/assets/index-BEw0xrde.css +0 -1
- package/dist/gateway/static/root/assets/index-DalslRUx.js +0 -121
- package/dist/gateway/static/root/assets/local-app-workbench-page-BKL5UZAj.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-CjzR9Rpj.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-Dk_gTJb9.js +0 -1
- package/dist/gateway/static/root/assets/media-plugins-Dlj6TD3M.js +0 -1
- package/dist/gateway/static/root/assets/messages-fmf0dnr4.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BebJPjjk.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-CmS_hvz8.js +0 -8
- package/dist/gateway/static/root/assets/page-context-capture-button-BArPtqp5.js +0 -1
- package/dist/gateway/static/root/assets/popover-select-DcsFzD_i.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-BFUdtWXF.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-DBsBwAQ6.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BurdDY0m.js +0 -1
- package/dist/gateway/static/root/assets/scenes-page-Cj8xtr5t.js +0 -2
- package/dist/gateway/static/root/assets/sessions-page-BCsjgkCs.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BLL7csOJ.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CbKHBjrU.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-DyLfktib.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-BzvSNouj.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-BHnru0F5.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-C35VKjhb.js +0 -2
- package/dist/gateway/static/root/assets/task-detail-page-Bd1_Fguk.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-DuYzuR1T.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-B45YDiEw.js +0 -6
- package/dist/src/automations/product-events.d.ts +0 -5
- package/dist/src/automations/product-events.js +0 -19
- package/dist/src/tui/tui-empty-session-cleanup.d.ts +0 -9
- package/dist/src/tui/tui-empty-session-cleanup.js +0 -19
- /package/dist/gateway/static/root/assets/{dist-CI_fqRk-.js → dist-CI_fqRk-2.js} +0 -0
|
@@ -70,6 +70,36 @@ async function executeWithDeadline(operation, timeoutMs, parentSignal, deadlineA
|
|
|
70
70
|
}
|
|
71
71
|
var AutomationActionExecutor = class {
|
|
72
72
|
deps = {};
|
|
73
|
+
handlers = /* @__PURE__ */ new Map();
|
|
74
|
+
constructor() {
|
|
75
|
+
this.register("agent", { mode: "never" }, (input, action) => this.executeAgent(input.automation, action, input.run, input.signal, input.hooks, input.deadlineAtMs, input.context));
|
|
76
|
+
this.register("workflow", {
|
|
77
|
+
mode: "idempotent",
|
|
78
|
+
key: "run_id"
|
|
79
|
+
}, (input, action) => this.executeWorkflow(input.automation, action, input.run, input.signal, input.hooks, input.context));
|
|
80
|
+
this.register("browser_automation", { mode: "never" }, (input, action) => this.executeBrowserAutomation(input.automation, action, input.signal, input.hooks, input.context));
|
|
81
|
+
this.register("task_command", {
|
|
82
|
+
mode: "idempotent",
|
|
83
|
+
key: "run_id"
|
|
84
|
+
}, (input, action) => this.executeTaskCommand(input, action));
|
|
85
|
+
this.register("system", {
|
|
86
|
+
mode: "transient_only",
|
|
87
|
+
classify: (error) => /temporar|timeout|timed out|unavailable|busy|rate limit|econn|network/i.test(String(error))
|
|
88
|
+
}, (input, action) => this.executeSystemAction(input, action));
|
|
89
|
+
}
|
|
90
|
+
register(kind, retrySafety, handler) {
|
|
91
|
+
if (this.handlers.has(kind)) throw new Error(`Automation executor already registered: ${kind}`);
|
|
92
|
+
this.handlers.set(kind, {
|
|
93
|
+
retrySafety,
|
|
94
|
+
handler: (input) => handler(input, input.automation.action)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
canRetry(kind, error) {
|
|
98
|
+
const retrySafety = this.handlers.get(kind)?.retrySafety ?? { mode: "never" };
|
|
99
|
+
if (retrySafety.mode === "never") return false;
|
|
100
|
+
if (retrySafety.mode === "idempotent") return true;
|
|
101
|
+
return retrySafety.classify(error);
|
|
102
|
+
}
|
|
73
103
|
setDeps(deps) {
|
|
74
104
|
this.deps = {
|
|
75
105
|
...this.deps,
|
|
@@ -105,46 +135,56 @@ var AutomationActionExecutor = class {
|
|
|
105
135
|
status: "cancelled",
|
|
106
136
|
error: "Automation run was cancelled"
|
|
107
137
|
};
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
const registration = this.handlers.get(automation.action.kind);
|
|
139
|
+
if (!registration) return {
|
|
140
|
+
status: "failed",
|
|
141
|
+
error: `Automation executor is unavailable: ${automation.action.kind}`
|
|
142
|
+
};
|
|
143
|
+
return registration.handler({
|
|
144
|
+
automation,
|
|
145
|
+
run,
|
|
146
|
+
signal,
|
|
147
|
+
hooks,
|
|
148
|
+
deadlineAtMs,
|
|
149
|
+
context
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
async executeTaskCommand(input, action) {
|
|
153
|
+
await input.hooks.onRunPatch?.({ currentPhase: "action" });
|
|
154
|
+
const execute = this.deps.executeTaskCommand;
|
|
155
|
+
if (!execute) return {
|
|
156
|
+
status: "failed",
|
|
157
|
+
error: "Task command executor is unavailable"
|
|
158
|
+
};
|
|
159
|
+
const result = execute({
|
|
160
|
+
taskId: action.taskId,
|
|
161
|
+
idempotencyKey: `automation:${input.automation.id}:${input.run.id}`,
|
|
162
|
+
command: action.command,
|
|
163
|
+
...input.context.triggerEvent ? { triggerEvent: input.context.triggerEvent } : {}
|
|
164
|
+
});
|
|
165
|
+
return result.ok ? {
|
|
166
|
+
status: "succeeded",
|
|
167
|
+
summary: result.runId ? `TaskRun ${result.runId} queued` : "Task command applied"
|
|
168
|
+
} : {
|
|
169
|
+
status: "failed",
|
|
170
|
+
error: result.reason ?? "Task command failed"
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
async executeSystemAction(input, action) {
|
|
174
|
+
await input.hooks.onRunPatch?.({ currentPhase: "action" });
|
|
175
|
+
const execute = this.deps.executeSystemAction;
|
|
176
|
+
if (!execute) return {
|
|
177
|
+
status: "failed",
|
|
178
|
+
error: "System action executor is unavailable"
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
status: "succeeded",
|
|
182
|
+
summary: (await execute({
|
|
183
|
+
capability: action.capability,
|
|
184
|
+
automationId: input.automation.id,
|
|
185
|
+
runId: input.run.id
|
|
186
|
+
})).summary ?? "System action completed"
|
|
187
|
+
};
|
|
148
188
|
}
|
|
149
189
|
async executeBrowserAutomation(automation, action, signal, hooks, context) {
|
|
150
190
|
await hooks.onRunPatch?.({ currentPhase: "action" });
|
|
@@ -11,12 +11,15 @@ export declare class AutomationAlreadyExistsError extends Error {
|
|
|
11
11
|
}
|
|
12
12
|
export declare class AutomationService {
|
|
13
13
|
private readonly executor;
|
|
14
|
+
private readonly eventDispatcher;
|
|
15
|
+
private readonly deliveryRouter;
|
|
14
16
|
private timer;
|
|
15
17
|
private stopped;
|
|
16
18
|
private runningScheduler;
|
|
17
19
|
private deps;
|
|
18
20
|
private maxConcurrentRuns;
|
|
19
21
|
private readonly activeRuns;
|
|
22
|
+
private readonly activeRunTasks;
|
|
20
23
|
private readonly heartbeatTimers;
|
|
21
24
|
private readonly leaseOwner;
|
|
22
25
|
setDeps(deps: AutomationDeps): void;
|
|
@@ -49,14 +52,30 @@ export declare class AutomationService {
|
|
|
49
52
|
resume(id: string): Promise<Automation | null>;
|
|
50
53
|
runNow(id: string): Promise<AutomationRun>;
|
|
51
54
|
rerunFromRun(runId: string): Promise<AutomationRun>;
|
|
52
|
-
|
|
55
|
+
ingestEvent(event: AutomationEvent, targetAutomationIds?: string[]): import("../index.js").AutomationEventIngestResult;
|
|
56
|
+
dispatchEvents(): Promise<number>;
|
|
57
|
+
replayEventAtomically(eventId: string): boolean;
|
|
58
|
+
retryResultDeliveryAtomically(runId: string, destinationKey: string): boolean;
|
|
59
|
+
dispatchRecoveryWork(): void;
|
|
60
|
+
listEventRecords(input?: {
|
|
61
|
+
type?: string;
|
|
62
|
+
source?: string;
|
|
63
|
+
limit?: number;
|
|
64
|
+
}): import("../index.js").AutomationEventRecord[];
|
|
65
|
+
listResultDeliveries(input?: {
|
|
66
|
+
runId?: string;
|
|
67
|
+
status?: 'pending' | 'delivering' | 'retrying' | 'delivered' | 'dead_letter';
|
|
68
|
+
limit?: number;
|
|
69
|
+
}): import("../index.js").AutomationResultDeliveryRecord[];
|
|
70
|
+
private ingestTargetedTrigger;
|
|
71
|
+
queueTriggerAtomically(automationId: string, input: AutomationEvent, executionEvent?: AutomationEvent): AutomationRun;
|
|
53
72
|
queueRunAtomically(id: string, opts?: {
|
|
54
73
|
manual: boolean;
|
|
55
74
|
event?: AutomationEvent;
|
|
56
75
|
}): AutomationRun;
|
|
57
76
|
/** Claim before invoking external work; replays never restart running or completed runs. */
|
|
58
77
|
dispatchQueuedRun(runId: string): void;
|
|
59
|
-
|
|
78
|
+
availableRunSlots(): number;
|
|
60
79
|
listRuns(options?: {
|
|
61
80
|
automationId?: string;
|
|
62
81
|
projectId?: string;
|
|
@@ -85,12 +104,10 @@ export declare class AutomationService {
|
|
|
85
104
|
private recomputeNextRuns;
|
|
86
105
|
private armTimer;
|
|
87
106
|
private onTimer;
|
|
88
|
-
private startRun;
|
|
89
107
|
private persistQueuedRun;
|
|
90
108
|
private executeRun;
|
|
91
109
|
private recoverInterruptedRuns;
|
|
92
110
|
private waitForRetry;
|
|
93
111
|
private appendRunEvent;
|
|
94
112
|
private finishAutomationRun;
|
|
95
|
-
private postCompletionWebhook;
|
|
96
113
|
}
|
|
@@ -3,10 +3,15 @@ import { init_logger } from "../../utils/logger.js";
|
|
|
3
3
|
import { init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
4
4
|
import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
|
|
5
5
|
import { deleteAutomation, getAutomation, getDeletedAutomationRevision, listAutomations, saveAutomation, saveAutomations } from "../storage/automation-repository.js";
|
|
6
|
-
import { appendAutomationRunEvent, getAutomationRun, getAutomationRunRequest, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listUnfinishedAutomationRuns, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, saveAutomationRunRequest, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
6
|
+
import { appendAutomationRunEvent, getAutomationRun, getAutomationRunRequest, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listUnfinishedAutomationRuns, markAllAutomationRunsRead, markAutomationRunRead, pruneAutomationHistory, saveAutomationRun, saveAutomationRunRequest, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
7
7
|
import "../storage/index.js";
|
|
8
|
+
import { getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, ingestAutomationEvent, listAutomationEventRecords, markAutomationEventDeliveryQueued, replayAutomationEvent } from "../events/event-repository.js";
|
|
8
9
|
import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedule.js";
|
|
9
10
|
import { AutomationActionExecutor } from "./action-executor.js";
|
|
11
|
+
import { AutomationEventDispatcher } from "../events/event-dispatcher.js";
|
|
12
|
+
import "../events/index.js";
|
|
13
|
+
import { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery } from "../delivery/delivery-router.js";
|
|
14
|
+
import "../delivery/index.js";
|
|
10
15
|
import { randomUUID } from "node:crypto";
|
|
11
16
|
//#region src/automations/service/automation-service.ts
|
|
12
17
|
init_logger();
|
|
@@ -17,12 +22,6 @@ const MISSED_RUN_STAGGER_MS = 5e3;
|
|
|
17
22
|
const RUN_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
18
23
|
const RUN_LEASE_DURATION_MS = 3e4;
|
|
19
24
|
const RETRY_BASE_DELAY_MS = 1e3;
|
|
20
|
-
var AutomationDeadlineExceededError = class extends Error {
|
|
21
|
-
constructor() {
|
|
22
|
-
super("Automation deadline exceeded while calling the completion webhook");
|
|
23
|
-
this.name = "AutomationDeadlineExceededError";
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
25
|
var AutomationAlreadyRunningError = class extends Error {
|
|
27
26
|
constructor(automationId, runningRunId) {
|
|
28
27
|
super(`Automation is already running: ${automationId}`);
|
|
@@ -40,12 +39,21 @@ var AutomationAlreadyExistsError = class extends Error {
|
|
|
40
39
|
};
|
|
41
40
|
var AutomationService = class {
|
|
42
41
|
executor = new AutomationActionExecutor();
|
|
42
|
+
eventDispatcher = new AutomationEventDispatcher(this, {
|
|
43
|
+
onEvent: (event, signal) => this.deps.onEvent?.(event, signal),
|
|
44
|
+
onDeadLetter: (input) => this.deps.onReliabilityAttention?.(input)
|
|
45
|
+
});
|
|
46
|
+
deliveryRouter = new AutomationDeliveryRouter({
|
|
47
|
+
deliverGatewayEvent: (run, context) => this.deps.onRunCompleted?.(run, context),
|
|
48
|
+
onDeadLetter: (input) => this.deps.onReliabilityAttention?.(input)
|
|
49
|
+
});
|
|
43
50
|
timer = null;
|
|
44
51
|
stopped = true;
|
|
45
52
|
runningScheduler = false;
|
|
46
53
|
deps = {};
|
|
47
54
|
maxConcurrentRuns = DEFAULT_MAX_CONCURRENT_RUNS;
|
|
48
55
|
activeRuns = /* @__PURE__ */ new Map();
|
|
56
|
+
activeRunTasks = /* @__PURE__ */ new Map();
|
|
49
57
|
heartbeatTimers = /* @__PURE__ */ new Map();
|
|
50
58
|
leaseOwner = `automation-service:${process.pid}:${randomUUID()}`;
|
|
51
59
|
setDeps(deps) {
|
|
@@ -59,8 +67,11 @@ var AutomationService = class {
|
|
|
59
67
|
this.maxConcurrentRuns = Math.max(1, Math.floor(options?.maxConcurrentRuns ?? DEFAULT_MAX_CONCURRENT_RUNS));
|
|
60
68
|
this.stopped = false;
|
|
61
69
|
await this.recoverInterruptedRuns();
|
|
70
|
+
pruneAutomationHistory();
|
|
62
71
|
await this.recomputeNextRuns({ catchUp: true });
|
|
63
72
|
this.armTimer();
|
|
73
|
+
this.eventDispatcher.start();
|
|
74
|
+
this.deliveryRouter.start();
|
|
64
75
|
log.info("Automation service initialized");
|
|
65
76
|
}
|
|
66
77
|
async stop() {
|
|
@@ -69,9 +80,10 @@ var AutomationService = class {
|
|
|
69
80
|
clearTimeout(this.timer);
|
|
70
81
|
this.timer = null;
|
|
71
82
|
}
|
|
72
|
-
|
|
73
|
-
for (const
|
|
74
|
-
this.
|
|
83
|
+
await this.eventDispatcher.stop();
|
|
84
|
+
for (const controller of this.activeRuns.values()) controller.abort(/* @__PURE__ */ new Error("Automation service stopped"));
|
|
85
|
+
await Promise.allSettled(this.activeRunTasks.values());
|
|
86
|
+
await this.deliveryRouter.stop();
|
|
75
87
|
log.info("Automation service stopped");
|
|
76
88
|
}
|
|
77
89
|
async create(input) {
|
|
@@ -92,7 +104,13 @@ var AutomationService = class {
|
|
|
92
104
|
enabled: parsed.enabled ?? true,
|
|
93
105
|
safety: parsed.safety ?? { mode: "auto_apply" },
|
|
94
106
|
conversationMode: parsed.conversationMode ?? "new_session",
|
|
95
|
-
|
|
107
|
+
delivery: parsed.delivery ?? {
|
|
108
|
+
notificationPolicy: "attention",
|
|
109
|
+
destinations: [{
|
|
110
|
+
key: "gateway_event",
|
|
111
|
+
kind: "gateway_event"
|
|
112
|
+
}]
|
|
113
|
+
},
|
|
96
114
|
state: parsed.state ?? {},
|
|
97
115
|
createdAtMs: now,
|
|
98
116
|
updatedAtMs: now
|
|
@@ -188,24 +206,80 @@ var AutomationService = class {
|
|
|
188
206
|
return this.update(id, { enabled: true });
|
|
189
207
|
}
|
|
190
208
|
async runNow(id) {
|
|
191
|
-
|
|
209
|
+
return this.ingestTargetedTrigger(id, {
|
|
210
|
+
type: "automation.manual.requested",
|
|
211
|
+
source: "user",
|
|
212
|
+
trust: "user",
|
|
213
|
+
payload: { automationId: id }
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async rerunFromRun(runId) {
|
|
217
|
+
const previous = getAutomationRun(runId);
|
|
218
|
+
if (!previous) throw new Error(`Automation run not found: ${runId}`);
|
|
219
|
+
const request = {
|
|
220
|
+
type: "automation.rerun.requested",
|
|
221
|
+
source: "user",
|
|
222
|
+
trust: "user",
|
|
223
|
+
payload: {
|
|
224
|
+
automationId: previous.automationId,
|
|
225
|
+
previousRunId: runId
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const run = this.queueTriggerAtomically(previous.automationId, request, getAutomationEventForRun(runId) ?? request);
|
|
192
229
|
this.dispatchQueuedRun(run.id);
|
|
193
230
|
return run;
|
|
194
231
|
}
|
|
195
|
-
|
|
196
|
-
const
|
|
232
|
+
ingestEvent(event, targetAutomationIds) {
|
|
233
|
+
const result = ingestAutomationEvent(event, targetAutomationIds ? { targetAutomationIds } : void 0);
|
|
234
|
+
this.eventDispatcher.dispatch();
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
dispatchEvents() {
|
|
238
|
+
return this.eventDispatcher.dispatch();
|
|
239
|
+
}
|
|
240
|
+
replayEventAtomically(eventId) {
|
|
241
|
+
return replayAutomationEvent(eventId);
|
|
242
|
+
}
|
|
243
|
+
retryResultDeliveryAtomically(runId, destinationKey) {
|
|
244
|
+
return retryAutomationResultDelivery(runId, destinationKey);
|
|
245
|
+
}
|
|
246
|
+
dispatchRecoveryWork() {
|
|
247
|
+
this.eventDispatcher.dispatch();
|
|
248
|
+
this.deliveryRouter.dispatch();
|
|
249
|
+
}
|
|
250
|
+
listEventRecords(input) {
|
|
251
|
+
return listAutomationEventRecords(input);
|
|
252
|
+
}
|
|
253
|
+
listResultDeliveries(input) {
|
|
254
|
+
return listAutomationResultDeliveries(input);
|
|
255
|
+
}
|
|
256
|
+
async ingestTargetedTrigger(automationId, event) {
|
|
257
|
+
const run = this.queueTriggerAtomically(automationId, event);
|
|
197
258
|
this.dispatchQueuedRun(run.id);
|
|
198
259
|
return run;
|
|
199
260
|
}
|
|
200
|
-
|
|
261
|
+
queueTriggerAtomically(automationId, input, executionEvent = input) {
|
|
201
262
|
return runSqliteWriteTransaction(() => {
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
263
|
+
const eventId = input.id?.trim() || randomUUID();
|
|
264
|
+
const result = ingestAutomationEvent({
|
|
265
|
+
...input,
|
|
266
|
+
id: eventId,
|
|
267
|
+
subject: input.subject ?? {
|
|
268
|
+
kind: "automation",
|
|
269
|
+
id: automationId
|
|
270
|
+
},
|
|
271
|
+
correlationId: input.correlationId ?? eventId
|
|
272
|
+
}, { targetAutomationIds: [automationId] });
|
|
273
|
+
const existingRunId = getAutomationEventDeliveryRunId(result.event.id, automationId);
|
|
274
|
+
const existingRun = existingRunId ? getAutomationRun(existingRunId) : null;
|
|
275
|
+
if (existingRun) return existingRun;
|
|
276
|
+
const manual = result.event.type === "automation.manual.requested" || result.event.type === "automation.rerun.requested";
|
|
277
|
+
const run = this.queueRunAtomically(automationId, {
|
|
278
|
+
manual,
|
|
279
|
+
event: executionEvent
|
|
280
|
+
});
|
|
281
|
+
markAutomationEventDeliveryQueued(result.event.id, automationId, run.id);
|
|
282
|
+
return run;
|
|
209
283
|
});
|
|
210
284
|
}
|
|
211
285
|
queueRunAtomically(id, opts = { manual: true }) {
|
|
@@ -242,26 +316,18 @@ var AutomationService = class {
|
|
|
242
316
|
};
|
|
243
317
|
});
|
|
244
318
|
if (!claimed) return;
|
|
245
|
-
this.executeRun(claimed.automation, claimed.run).catch((err) => {
|
|
319
|
+
const task = this.executeRun(claimed.automation, claimed.run).catch((err) => {
|
|
246
320
|
log.error({
|
|
247
321
|
err,
|
|
248
322
|
runId
|
|
249
323
|
}, "Queued automation run failed");
|
|
324
|
+
}).finally(() => {
|
|
325
|
+
this.activeRunTasks.delete(runId);
|
|
250
326
|
});
|
|
327
|
+
this.activeRunTasks.set(runId, task);
|
|
251
328
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
...event,
|
|
255
|
-
occurredAtMs: event.occurredAtMs ?? Date.now()
|
|
256
|
-
};
|
|
257
|
-
const automations = listAutomations().filter((automation) => automation.enabled && automation.trigger.kind === "event" && !automation.state.runningRunId && matchesAutomationEvent(automation.trigger, normalized));
|
|
258
|
-
const availableSlots = Math.max(0, this.maxConcurrentRuns - this.activeRuns.size);
|
|
259
|
-
const started = [];
|
|
260
|
-
for (const automation of automations.slice(0, availableSlots)) started.push(await this.startRun(automation, {
|
|
261
|
-
manual: false,
|
|
262
|
-
event: normalized
|
|
263
|
-
}));
|
|
264
|
-
return started;
|
|
329
|
+
availableRunSlots() {
|
|
330
|
+
return Math.max(0, this.maxConcurrentRuns - this.activeRuns.size);
|
|
265
331
|
}
|
|
266
332
|
async listRuns(options) {
|
|
267
333
|
return listAutomationRuns(options);
|
|
@@ -288,6 +354,8 @@ var AutomationService = class {
|
|
|
288
354
|
}
|
|
289
355
|
dispatchCancellation(runId) {
|
|
290
356
|
this.activeRuns.get(runId)?.abort(/* @__PURE__ */ new Error("Automation run was cancelled by the user"));
|
|
357
|
+
const run = getAutomationRun(runId);
|
|
358
|
+
if (run?.status === "cancelled") this.eventDispatcher.runCompleted(run);
|
|
291
359
|
this.refreshSchedule();
|
|
292
360
|
}
|
|
293
361
|
cancelRunAtomically(runId) {
|
|
@@ -336,6 +404,8 @@ var AutomationService = class {
|
|
|
336
404
|
this.appendRunEvent(cancelled, "run.cancel_confirmed", "Queued automation cancelled before execution");
|
|
337
405
|
this.appendRunEvent(cancelled, "run.completed", "Automation run cancelled", { status: "cancelled" });
|
|
338
406
|
this.finishAutomationRun(current.automationId, runId, "cancelled", void 0, now);
|
|
407
|
+
const automation = getAutomation(current.automationId);
|
|
408
|
+
if (automation) this.deliveryRouter.enqueue(cancelled, automation);
|
|
339
409
|
return {
|
|
340
410
|
cancelled: true,
|
|
341
411
|
confirmed: true
|
|
@@ -347,6 +417,8 @@ var AutomationService = class {
|
|
|
347
417
|
const enabled = automations.filter((automation) => automation.enabled);
|
|
348
418
|
const next = enabled.filter((automation) => automation.state.nextRunAtMs != null).toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];
|
|
349
419
|
const oneHourAgo = Date.now() - 60 * 6e4;
|
|
420
|
+
const eventMetrics = getAutomationEventQueueMetrics();
|
|
421
|
+
const deliveryMetrics = getAutomationResultDeliveryMetrics();
|
|
350
422
|
return {
|
|
351
423
|
totalAutomations: automations.length,
|
|
352
424
|
enabledAutomations: enabled.length,
|
|
@@ -356,7 +428,16 @@ var AutomationService = class {
|
|
|
356
428
|
automationId: next.id,
|
|
357
429
|
name: next.name,
|
|
358
430
|
runAtMs: next.state.nextRunAtMs
|
|
359
|
-
} : void 0
|
|
431
|
+
} : void 0,
|
|
432
|
+
pendingEvents: eventMetrics.pending,
|
|
433
|
+
oldestPendingEventAgeMs: eventMetrics.oldestPendingAgeMs,
|
|
434
|
+
projectionDeadLetters: eventMetrics.projectionDeadLetters,
|
|
435
|
+
pendingRunDeliveries: eventMetrics.pendingDeliveries,
|
|
436
|
+
runDeliveryDeadLetters: eventMetrics.deliveryDeadLetters,
|
|
437
|
+
pendingResultDeliveries: deliveryMetrics.pending,
|
|
438
|
+
resultDeliveryDeadLetters: deliveryMetrics.deadLetters,
|
|
439
|
+
activeExecutions: this.activeRuns.size,
|
|
440
|
+
activeDeliveryLeases: eventMetrics.activeLeases + deliveryMetrics.activeLeases
|
|
360
441
|
};
|
|
361
442
|
}
|
|
362
443
|
async recomputeNextRuns(options) {
|
|
@@ -400,17 +481,28 @@ var AutomationService = class {
|
|
|
400
481
|
try {
|
|
401
482
|
const now = Date.now();
|
|
402
483
|
const due = listAutomations().filter((automation) => automation.enabled && automation.trigger.kind === "schedule" && automation.state.nextRunAtMs != null && automation.state.nextRunAtMs <= now && !automation.state.runningRunId).slice(0, this.maxConcurrentRuns);
|
|
403
|
-
await Promise.all(due.map((automation) => this.
|
|
484
|
+
await Promise.all(due.map((automation) => this.ingestTargetedTrigger(automation.id, {
|
|
485
|
+
id: `schedule:${automation.id}:${automation.state.nextRunAtMs}`,
|
|
486
|
+
type: "automation.schedule.due",
|
|
487
|
+
source: "scheduler",
|
|
488
|
+
subject: {
|
|
489
|
+
kind: "automation",
|
|
490
|
+
id: automation.id
|
|
491
|
+
},
|
|
492
|
+
correlationId: `schedule:${automation.id}:${automation.state.nextRunAtMs}`,
|
|
493
|
+
dedupeKey: `${automation.id}:${automation.state.nextRunAtMs}`,
|
|
494
|
+
trust: "system",
|
|
495
|
+
payload: {
|
|
496
|
+
automationId: automation.id,
|
|
497
|
+
dueAtMs: automation.state.nextRunAtMs
|
|
498
|
+
},
|
|
499
|
+
occurredAtMs: automation.state.nextRunAtMs
|
|
500
|
+
})));
|
|
404
501
|
} finally {
|
|
405
502
|
this.runningScheduler = false;
|
|
406
503
|
this.armTimer();
|
|
407
504
|
}
|
|
408
505
|
}
|
|
409
|
-
async startRun(automation, opts) {
|
|
410
|
-
const run = this.queueRunAtomically(automation.id, opts);
|
|
411
|
-
this.dispatchQueuedRun(run.id);
|
|
412
|
-
return run;
|
|
413
|
-
}
|
|
414
506
|
persistQueuedRun(automation, opts) {
|
|
415
507
|
const now = Date.now();
|
|
416
508
|
const run = {
|
|
@@ -420,7 +512,7 @@ var AutomationService = class {
|
|
|
420
512
|
status: "queued",
|
|
421
513
|
triggerSnapshot: automation.trigger,
|
|
422
514
|
actionSnapshot: automation.action,
|
|
423
|
-
manual: opts.manual,
|
|
515
|
+
manual: opts.manual || opts.event?.type === "automation.manual.requested" || opts.event?.type === "automation.rerun.requested",
|
|
424
516
|
createdAtMs: now,
|
|
425
517
|
attemptNumber: 1
|
|
426
518
|
};
|
|
@@ -465,7 +557,7 @@ var AutomationService = class {
|
|
|
465
557
|
this.heartbeatTimers.set(run.id, heartbeat);
|
|
466
558
|
let status = "failed";
|
|
467
559
|
let error;
|
|
468
|
-
let
|
|
560
|
+
let artifacts;
|
|
469
561
|
const triggerEvent = listAutomationRunEvents(run.id).map(readAutomationEventFromRunEvent).find((item) => item !== null);
|
|
470
562
|
try {
|
|
471
563
|
const maxAttempts = Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
|
|
@@ -494,7 +586,7 @@ var AutomationService = class {
|
|
|
494
586
|
timeoutMs: patch.deadlineAtMs - startedAtMs
|
|
495
587
|
});
|
|
496
588
|
} }, { triggerEvent });
|
|
497
|
-
if (!(task.status === "failed") || attempt >= maxAttempts || controller.signal.aborted) break;
|
|
589
|
+
if (!(task.status === "failed" && this.executor.canRetry(automation.action.kind, task.error)) || attempt >= maxAttempts || controller.signal.aborted) break;
|
|
498
590
|
const delayMs = Math.min(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1), 3e4);
|
|
499
591
|
this.appendRunEvent(run, "action.retry_scheduled", "Automation action retry scheduled", {
|
|
500
592
|
attempt,
|
|
@@ -506,8 +598,10 @@ var AutomationService = class {
|
|
|
506
598
|
});
|
|
507
599
|
await this.waitForRetry(delayMs, controller.signal);
|
|
508
600
|
}
|
|
601
|
+
this.deliveryRouter.validateArtifacts(task.artifacts ?? []);
|
|
509
602
|
status = task.status;
|
|
510
603
|
error = task.error;
|
|
604
|
+
artifacts = task.artifacts;
|
|
511
605
|
const persistedRun = getAutomationRun(run.id);
|
|
512
606
|
if (persistedRun) run = {
|
|
513
607
|
...run,
|
|
@@ -547,18 +641,6 @@ var AutomationService = class {
|
|
|
547
641
|
};
|
|
548
642
|
this.appendRunEvent(run, task.termination.cancellationConfirmed ? "run.cancel_confirmed" : "run.cancellation_unconfirmed", task.termination.cancellationConfirmed ? "Automation cancellation confirmed" : "Automation cancellation was not confirmed within the cleanup grace period", { termination: task.termination });
|
|
549
643
|
}
|
|
550
|
-
if (controller.signal.aborted || status === "timeout" || status === "cancelled") {} else if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.completionWebhookUrl) this.appendRunEvent(run, "completion_hook.completed", "Completion webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
|
|
551
|
-
else if (automation.completionWebhookUrl) {
|
|
552
|
-
activePhase = "completion_hook";
|
|
553
|
-
run = {
|
|
554
|
-
...run,
|
|
555
|
-
currentPhase: "completion_hook"
|
|
556
|
-
};
|
|
557
|
-
saveAutomationRun(run);
|
|
558
|
-
this.appendRunEvent(run, "completion_hook.started", "Calling completion webhook", { url: automation.completionWebhookUrl });
|
|
559
|
-
await this.postCompletionWebhook(automation.completionWebhookUrl, run, controller.signal);
|
|
560
|
-
this.appendRunEvent(run, "completion_hook.completed", "Completion webhook completed");
|
|
561
|
-
}
|
|
562
644
|
} catch (err) {
|
|
563
645
|
const persistedRun = getAutomationRun(run.id);
|
|
564
646
|
if (persistedRun) run = {
|
|
@@ -566,16 +648,16 @@ var AutomationService = class {
|
|
|
566
648
|
...persistedRun
|
|
567
649
|
};
|
|
568
650
|
error = err instanceof Error ? err.message : String(err);
|
|
569
|
-
const deadlineExceeded =
|
|
651
|
+
const deadlineExceeded = run.deadlineAtMs !== void 0 && Date.now() >= run.deadlineAtMs;
|
|
570
652
|
status = controller.signal.aborted ? "cancelled" : deadlineExceeded ? "timeout" : "failed";
|
|
571
|
-
this.appendRunEvent(run,
|
|
653
|
+
this.appendRunEvent(run, "action.failed", `Automation run ${status}`, { error });
|
|
572
654
|
run = {
|
|
573
655
|
...run,
|
|
574
656
|
status,
|
|
575
657
|
error,
|
|
576
658
|
termination: {
|
|
577
659
|
reason: status === "cancelled" ? "user_cancelled" : status === "timeout" ? "deadline_exceeded" : "failed",
|
|
578
|
-
component:
|
|
660
|
+
component: run.termination?.component,
|
|
579
661
|
cancellationConfirmed: status !== "cancelled" || controller.signal.aborted
|
|
580
662
|
}
|
|
581
663
|
};
|
|
@@ -606,17 +688,11 @@ var AutomationService = class {
|
|
|
606
688
|
error
|
|
607
689
|
});
|
|
608
690
|
this.finishAutomationRun(automation.id, run.id, status, error, endedAtMs);
|
|
691
|
+
this.deliveryRouter.enqueue(run, automation, artifacts);
|
|
609
692
|
});
|
|
610
693
|
this.refreshSchedule();
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
} catch (err) {
|
|
614
|
-
log.warn({
|
|
615
|
-
err,
|
|
616
|
-
automationId: automation.id,
|
|
617
|
-
runId: run.id
|
|
618
|
-
}, "Automation completion hook failed");
|
|
619
|
-
}
|
|
694
|
+
this.eventDispatcher.runCompleted(run);
|
|
695
|
+
this.deliveryRouter.dispatch();
|
|
620
696
|
}
|
|
621
697
|
}
|
|
622
698
|
async recoverInterruptedRuns() {
|
|
@@ -656,7 +732,10 @@ var AutomationService = class {
|
|
|
656
732
|
status,
|
|
657
733
|
error
|
|
658
734
|
});
|
|
659
|
-
if (automation)
|
|
735
|
+
if (automation) {
|
|
736
|
+
this.finishAutomationRun(automation.id, run.id, status, error, now);
|
|
737
|
+
this.deliveryRouter.enqueue(recovered, automation);
|
|
738
|
+
}
|
|
660
739
|
}
|
|
661
740
|
}
|
|
662
741
|
waitForRetry(delayMs, signal) {
|
|
@@ -706,36 +785,7 @@ var AutomationService = class {
|
|
|
706
785
|
next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, finishedAtMs);
|
|
707
786
|
saveAutomation(next);
|
|
708
787
|
}
|
|
709
|
-
async postCompletionWebhook(url, run, signal) {
|
|
710
|
-
const remainingMs = run.deadlineAtMs === void 0 ? 3e4 : Math.max(1, run.deadlineAtMs - Date.now());
|
|
711
|
-
const deadlineSignal = AbortSignal.timeout(remainingMs);
|
|
712
|
-
const requestSignal = AbortSignal.any([signal, deadlineSignal]);
|
|
713
|
-
let response;
|
|
714
|
-
try {
|
|
715
|
-
response = await fetch(url, {
|
|
716
|
-
method: "POST",
|
|
717
|
-
headers: { "content-type": "application/json" },
|
|
718
|
-
body: JSON.stringify({ run }),
|
|
719
|
-
signal: requestSignal
|
|
720
|
-
});
|
|
721
|
-
} catch (err) {
|
|
722
|
-
if (!signal.aborted && deadlineSignal.aborted) throw new AutomationDeadlineExceededError();
|
|
723
|
-
throw err;
|
|
724
|
-
}
|
|
725
|
-
if (!response.ok) {
|
|
726
|
-
const text = await response.text().catch(() => "");
|
|
727
|
-
throw new Error(`Automation webhook failed: HTTP ${response.status}${text ? ` ${text.slice(0, 200)}` : ""}`);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
788
|
};
|
|
731
|
-
function matchesAutomationEvent(trigger, event) {
|
|
732
|
-
if (trigger.eventType !== event.type) return false;
|
|
733
|
-
if (trigger.source && trigger.source !== event.source) return false;
|
|
734
|
-
const payloadMatch = trigger.payloadMatch;
|
|
735
|
-
if (!payloadMatch) return true;
|
|
736
|
-
const payload = event.payload ?? {};
|
|
737
|
-
return Object.entries(payloadMatch).every(([key, expected]) => Object.is(payload[key], expected));
|
|
738
|
-
}
|
|
739
789
|
function readAutomationEventFromRunEvent(event) {
|
|
740
790
|
if (!event.data || typeof event.data !== "object" || Array.isArray(event.data)) return null;
|
|
741
791
|
const raw = event.data.event;
|
|
@@ -20,8 +20,7 @@ function rowToAutomation(row) {
|
|
|
20
20
|
action: parseJson(row.action_json),
|
|
21
21
|
safety: parseJson(row.safety_json) ?? { mode: "auto_apply" },
|
|
22
22
|
conversationMode: row.conversation_mode,
|
|
23
|
-
|
|
24
|
-
completionWebhookUrl: row.completion_webhook_url ?? void 0,
|
|
23
|
+
delivery: parseJson(row.delivery_json),
|
|
25
24
|
reliability: parseJson(row.reliability_json),
|
|
26
25
|
management: parseJson(row.management_json),
|
|
27
26
|
state: parseJson(row.state_json) ?? {},
|
|
@@ -32,13 +31,13 @@ function rowToAutomation(row) {
|
|
|
32
31
|
function upsertAutomation(db, automation) {
|
|
33
32
|
db.prepare(`INSERT OR REPLACE INTO automations (
|
|
34
33
|
automation_id, name, description, project_id, enabled, trigger_json, action_json,
|
|
35
|
-
safety_json, conversation_mode,
|
|
34
|
+
safety_json, conversation_mode, delivery_json,
|
|
36
35
|
reliability_json, management_json, state_json, created_at_ms, updated_at_ms
|
|
37
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
|
36
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(automation.id, automation.name, automation.description ?? null, automation.projectId ?? null, automation.enabled ? 1 : 0, JSON.stringify(automation.trigger), JSON.stringify(automation.action), bindJson(automation.safety ?? { mode: "auto_apply" }), automation.conversationMode, bindJson(automation.delivery), bindJson(automation.reliability), bindJson(automation.management), JSON.stringify(automation.state ?? {}), automation.createdAtMs, automation.updatedAtMs);
|
|
38
37
|
}
|
|
39
38
|
const AUTOMATION_SELECT = `
|
|
40
39
|
SELECT automation_id, name, description, project_id, enabled, trigger_json, action_json,
|
|
41
|
-
safety_json, conversation_mode,
|
|
40
|
+
safety_json, conversation_mode, delivery_json,
|
|
42
41
|
reliability_json, management_json, state_json, created_at_ms, updated_at_ms
|
|
43
42
|
FROM automations
|
|
44
43
|
`;
|
|
@@ -20,6 +20,7 @@ export declare function listAutomationRunsForProductEvent(options: {
|
|
|
20
20
|
limit?: number;
|
|
21
21
|
}): AutomationProductEventRun[];
|
|
22
22
|
export declare function deleteAutomationRunsForAutomation(automationId: string): void;
|
|
23
|
+
export declare function pruneAutomationHistory(cutoffMs?: number): number;
|
|
23
24
|
export declare function markAutomationRunRead(runId: string, readAtMs?: number): boolean;
|
|
24
25
|
export declare function markAllAutomationRunsRead(options?: {
|
|
25
26
|
projectId?: string;
|