@xopcai/xopc 0.0.332 → 0.0.333
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/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-DiI2O7lC.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CVp3J969.js +1 -0
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BeNnu1Ts.js → agent-plugin-dialog-CacyndrS.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DXYZSuUV.js +70 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-etFSkfzl.js → app-management-settings-panel-BcszTlqr.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DKmU2VAP.js → appearance-settings-B1XPe8qz.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DVNySL58.js → apps-page-ZqANbUZv.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-D0z_Fr2G.js → archive-plugin-MjUsJcNb.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DNCDbeOX.js → attachment-load-DHa-BI9a.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-B7_C-p66.js → automations-page-Dsjivdxs.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-B37vs5tk.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BYn2hScX.js → binary-plugins-DQYcuBHP.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-ChWW8Z9L.js → block-editor-Bx0uXbJP.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-C5s1yHOu.js → browser-automation-inputs-1ZIPGDeq.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-BV00BXRb.js → browser-automations-page-CCjYipHc.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-CSv4rvmx.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-BnO9LV7U.js +1 -0
- package/dist/gateway/static/root/assets/{capabilities-page-v0WkhV5o.js → capabilities-page-BfvDvIY1.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CoW7-ESq.js +8 -0
- package/dist/gateway/static/root/assets/{capability-header-actions-vmx35sbu.js → capability-header-actions-D_hbWRRF.js} +1 -1
- package/dist/gateway/static/root/assets/channels-BhMaRh1x.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-C41mXCAi.js → chat-terminal-dock-Fnum_IEm.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-BJkqok2G.js → computer-settings-page-DI1zfCTA.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-BKCZMmwm.js → connector-service-page-CiGDAubm.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-Ono0Pha1.js +2 -0
- package/dist/gateway/static/root/assets/{date-picker-CrOV4Ynd.js → date-picker-D-JhzZyW.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CqADAHZp.js → dependency-picker-DpD3xaEB.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Bab-iWED.js → desktop-pet-CCoDxKqh.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BqgzLOdi.js → desktop-pet-settings-GxndKfCx.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-DFg7FDPf.js → device-pairing-wizard-B71w3ptm.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-hqJ9sFCR.js → directory-picker-path-field-CUzjJvjs.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DX3PFhRE.js → extension-debug-page-BtDY8ntX.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DkREdHLs.js → extension-page-D9_XF-XC.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-wF-HNTM-.js → extension-settings-page-CjhUFAaC.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-settings-Du-Dos9O.js → gateway-settings-BWaCnwT1.js} +1 -1
- 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-BTjGLngn.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-BEtq5BRU.js} +1 -1
- package/dist/gateway/static/root/assets/index-DHL16aYZ.js +121 -0
- package/dist/gateway/static/root/assets/index-N1e6PDwx.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BgoFaTwv.js → keyboard-shortcuts-settings-JUYY_18v.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-uI7mtoVz.js +1 -0
- package/dist/gateway/static/root/assets/{local-apps-page-HO6OQlQT.js → local-apps-page-BlYESNqz.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-wNXWkWu5.js → locale-store-BY30D6tg.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-CjzR9Rpj.js → logs-page-BbLQreeN.js} +2 -2
- package/dist/gateway/static/root/assets/management-settings-c4krhYU7.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DlT9KqwF.js → markdown-view-BEeXMfDw.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Dlj6TD3M.js → media-plugins-DEFN1I73.js} +1 -1
- package/dist/gateway/static/root/assets/messages-_6IXbP2u.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel--09xGxyE.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-DsxcVBXF.js +8 -0
- package/dist/gateway/static/root/assets/{page-context-capture-button-BArPtqp5.js → page-context-capture-button-D43aVpCj.js} +1 -1
- package/dist/gateway/static/root/assets/{page-tabs-vqI30Yrg.js → page-tabs-BhYBCqls.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-B-mwPBJW.js → preview-open-alternatives-CP8agNlc.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-D--sj_uN.js → product-open-page-CU7fRhfT.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-U-EdDfAW.js +1 -0
- package/dist/gateway/static/root/assets/{projects-page-DBsBwAQ6.js → projects-page-DUOKZLt7.js} +1 -1
- 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-BurdDY0m.js → remote-access-hub-fVPQe5YS.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CAnb0PNY.js → runtime-tools-settings-panel-Czvzsuj_.js} +2 -2
- package/dist/gateway/static/root/assets/scenes-page-C0-WHOY3.js +2 -0
- package/dist/gateway/static/root/assets/{schema-form-BKj6wIMb.js → schema-form-B9Ni5O93.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-DdXvW09N.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BtF83fBY.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-78ycUHfv.js → settings-form-section-jquf1P7n.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-BOdxIVzo.js → settings-page-DPomsvba.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CbKHBjrU.js → setup-status-panel-BvVlqpHf.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DyLfktib.js → share-preview-page-b9DI0N1J.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-R_qwc4DN.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-CiBGQ0Jg.js → skill-api-Bu7-3w-L.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CNJAQ_e-.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-C35VKjhb.js → skills-page-D7XPEQu_.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-CyJUeREH.js → system-settings-panel-BwFR0Uci.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-PFjGW2g1.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-Day9zhKi.js → tunnel-api-PfucxMP3.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-t_zdQHcy.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-Bj9hC6ML.js → use-autosave-DLyy2wHz.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-OyfPVfB9.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-fWRD6B8r.js → voice-api-key-field-CQDY5EBK.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-CJzqJ47I.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DlWNN1VA.js → workflow-run-setup-panel-sCOk-esV.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DYBGjN7C.js +6 -0
- package/dist/gateway/static/root/index.html +9 -9
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/automations.js +44 -14
- package/dist/packages/gateway-contract/src/capabilities.js +106 -8
- package/dist/packages/gateway-contract/src/index.js +2 -0
- package/dist/packages/gateway-contract/src/scenes.js +7 -6
- package/dist/packages/gateway-contract/src/sessions.js +2 -1
- package/dist/packages/gateway-contract/src/usage.js +6 -0
- package/dist/src/agent/agent-manager.js +9 -3
- package/dist/src/agent/background-review/run-background-review.js +6 -1
- package/dist/src/agent/embedded/run-turn.js +7 -1
- package/dist/src/agent/external-tools/gateway-tools.d.ts +2 -1
- package/dist/src/agent/external-tools/gateway-tools.js +44 -11
- package/dist/src/agent/external-tools/index.js +1 -1
- 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.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 +4 -0
- 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 +49 -8
- package/dist/src/ai-assist/text-assist.js +5 -1
- package/dist/src/automations/api/routes.js +65 -0
- 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/capabilities/store-connector.d.ts +17 -1
- package/dist/src/capabilities/store-connector.js +69 -3
- 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/flow.js +5 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/skills.js +1 -1
- package/dist/src/connectors/approval-resume.js +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-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/extensions/update.js +1 -1
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/home-intelligence-automation-reconciler.js +4 -1
- package/dist/src/gateway/hono/routes/capabilities.js +1 -1
- package/dist/src/gateway/hono/routes/connection-waits.js +3 -2
- package/dist/src/gateway/hono/routes/lazy-bundles.js +14 -1
- 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/sessions.js +15 -0
- 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 +1 -1
- package/dist/src/gateway/memory-maintenance-automation-reconciler.js +5 -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 +9 -1
- 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 +6 -3
- package/dist/src/gateway/service.js +82 -85
- package/dist/src/gateway/side-chat/run-service.js +10 -7
- package/dist/src/home-intelligence/generator.js +4 -1
- package/dist/src/home-intelligence/host.js +1 -1
- 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 +1 -1
- package/dist/src/notes/service.js +2 -3
- package/dist/src/projects/project-service.js +1 -2
- package/dist/src/projects/project-skill-service.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/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 -2
- 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/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-input-repository.d.ts +8 -0
- package/dist/src/storage/sqlite/session-input-repository.js +18 -1
- 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/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/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/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/workflows/service/workflow-run-service.js +15 -2
- 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/automations-workspace-BMgJvdcv.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-xwTmuZjS.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-CHA-sTAZ.js +0 -1
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DefBGjhV.js +0 -8
- 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/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/management-settings-Dk_gTJb9.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/project-detail-page-BFUdtWXF.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/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/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
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
2
|
+
import { getAutomation, listAutomations } from "../storage/automation-repository.js";
|
|
3
|
+
import "../storage/index.js";
|
|
4
|
+
import { validateCatalogedBusinessEvent } from "./event-catalog.js";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
6
|
+
//#region src/automations/events/event-repository.ts
|
|
7
|
+
init_transaction();
|
|
8
|
+
const MAX_PAYLOAD_BYTES = 256 * 1024;
|
|
9
|
+
const MAX_ATTEMPTS = 5;
|
|
10
|
+
const RETRY_DELAYS_MS = [
|
|
11
|
+
1e3,
|
|
12
|
+
5e3,
|
|
13
|
+
3e4,
|
|
14
|
+
2 * 6e4,
|
|
15
|
+
10 * 6e4
|
|
16
|
+
];
|
|
17
|
+
function stableStringify(value) {
|
|
18
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
19
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
20
|
+
const record = value;
|
|
21
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
|
|
22
|
+
}
|
|
23
|
+
function sameEventIdentity(existing, candidate, input) {
|
|
24
|
+
return existing.id === candidate.id && existing.type === candidate.type && existing.source === candidate.source && existing.schemaVersion === candidate.schemaVersion && existing.subject?.kind === candidate.subject?.kind && existing.subject?.id === candidate.subject?.id && (input.occurredAtMs === void 0 || existing.occurredAtMs === candidate.occurredAtMs) && (input.correlationId === void 0 || existing.correlationId === candidate.correlationId) && (input.causationId === void 0 || existing.causationId === candidate.causationId) && (input.rootEventId === void 0 || existing.rootEventId === candidate.rootEventId) && (input.chainDepth === void 0 || existing.chainDepth === candidate.chainDepth) && existing.dedupeKey === candidate.dedupeKey && existing.trust === candidate.trust && stableStringify(existing.payload) === stableStringify(candidate.payload);
|
|
25
|
+
}
|
|
26
|
+
function matchesEvent(trigger, event) {
|
|
27
|
+
if (trigger.eventType !== event.type) return false;
|
|
28
|
+
if (trigger.source && trigger.source !== event.source) return false;
|
|
29
|
+
if (!trigger.payloadMatch) return true;
|
|
30
|
+
return Object.entries(trigger.payloadMatch).every(([key, expected]) => Object.is(event.payload[key], expected));
|
|
31
|
+
}
|
|
32
|
+
function rowToEvent(row) {
|
|
33
|
+
return {
|
|
34
|
+
id: row.event_id,
|
|
35
|
+
type: row.event_type,
|
|
36
|
+
schemaVersion: row.schema_version,
|
|
37
|
+
source: row.source,
|
|
38
|
+
...row.subject_kind && row.subject_id ? { subject: {
|
|
39
|
+
kind: row.subject_kind,
|
|
40
|
+
id: row.subject_id
|
|
41
|
+
} } : {},
|
|
42
|
+
occurredAtMs: row.occurred_at_ms,
|
|
43
|
+
ingestedAtMs: row.ingested_at_ms,
|
|
44
|
+
correlationId: row.correlation_id,
|
|
45
|
+
...row.causation_id ? { causationId: row.causation_id } : {},
|
|
46
|
+
rootEventId: row.root_event_id,
|
|
47
|
+
chainDepth: row.chain_depth,
|
|
48
|
+
...row.dedupe_key ? { dedupeKey: row.dedupe_key } : {},
|
|
49
|
+
trust: row.trust,
|
|
50
|
+
payload: JSON.parse(row.payload_json)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function readEventByIdentity(input) {
|
|
54
|
+
const db = getSqliteDatabase();
|
|
55
|
+
const row = input.dedupeKey ? db.prepare("SELECT * FROM automation_events WHERE event_id = ? OR (source = ? AND dedupe_key = ?) LIMIT 1").get(input.id, input.source, input.dedupeKey) : db.prepare("SELECT * FROM automation_events WHERE event_id = ?").get(input.id);
|
|
56
|
+
return row ? rowToEvent(row) : null;
|
|
57
|
+
}
|
|
58
|
+
function ingestAutomationEvent(input, options = {}) {
|
|
59
|
+
if (!input.type.trim()) throw new Error("Automation event type is required");
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
const id = input.id?.trim() || randomUUID();
|
|
62
|
+
const source = input.source?.trim() || "xopc";
|
|
63
|
+
const event = {
|
|
64
|
+
...input,
|
|
65
|
+
id,
|
|
66
|
+
type: input.type.trim(),
|
|
67
|
+
source,
|
|
68
|
+
schemaVersion: input.schemaVersion ?? 1,
|
|
69
|
+
occurredAtMs: input.occurredAtMs ?? now,
|
|
70
|
+
ingestedAtMs: now,
|
|
71
|
+
correlationId: input.correlationId?.trim() || id,
|
|
72
|
+
rootEventId: input.rootEventId?.trim() || id,
|
|
73
|
+
chainDepth: input.chainDepth ?? 0,
|
|
74
|
+
trust: input.trust ?? (source.startsWith("composio") ? "connector" : "system"),
|
|
75
|
+
payload: input.payload ?? {}
|
|
76
|
+
};
|
|
77
|
+
if (!Number.isInteger(event.schemaVersion) || event.schemaVersion < 1) throw new Error("Invalid event schema version");
|
|
78
|
+
if (!Number.isInteger(event.chainDepth) || event.chainDepth < 0 || event.chainDepth > 32) throw new Error("Invalid event chain depth");
|
|
79
|
+
const payloadJson = JSON.stringify(event.payload);
|
|
80
|
+
if (Buffer.byteLength(payloadJson) > MAX_PAYLOAD_BYTES) throw new Error(`Automation event payload exceeds ${MAX_PAYLOAD_BYTES} bytes`);
|
|
81
|
+
validateCatalogedBusinessEvent(event);
|
|
82
|
+
return runSqliteWriteTransaction((db) => {
|
|
83
|
+
if (!(db.prepare(`INSERT OR IGNORE INTO automation_events (
|
|
84
|
+
event_id, event_type, schema_version, source, subject_kind, subject_id,
|
|
85
|
+
occurred_at_ms, ingested_at_ms, correlation_id, causation_id, root_event_id,
|
|
86
|
+
chain_depth, dedupe_key, trust, payload_json, projection_next_attempt_at_ms
|
|
87
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(event.id, event.type, event.schemaVersion, event.source, event.subject?.kind ?? null, event.subject?.id ?? null, event.occurredAtMs, event.ingestedAtMs, event.correlationId, event.causationId ?? null, event.rootEventId, event.chainDepth, event.dedupeKey ?? null, event.trust, payloadJson, now).changes > 0)) {
|
|
88
|
+
const existing = readEventByIdentity({
|
|
89
|
+
id: event.id,
|
|
90
|
+
source: event.source,
|
|
91
|
+
dedupeKey: event.dedupeKey
|
|
92
|
+
});
|
|
93
|
+
if (!existing) throw new Error("Automation event identity conflict");
|
|
94
|
+
if (!sameEventIdentity(existing, event, input)) throw new Error("Automation event identity reused with different content");
|
|
95
|
+
return {
|
|
96
|
+
event: existing,
|
|
97
|
+
created: false,
|
|
98
|
+
deliveryCount: Number(db.prepare("SELECT count(*) AS count FROM automation_event_deliveries WHERE event_id = ?").get(existing.id)?.count ?? 0)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const automations = options.targetAutomationIds ? options.targetAutomationIds.map(getAutomation).filter((automation) => Boolean(automation?.enabled)) : listAutomations().filter((automation) => automation.enabled && automation.trigger.kind === "event" && matchesEvent(automation.trigger, event));
|
|
102
|
+
const insertDelivery = db.prepare(`INSERT INTO automation_event_deliveries (
|
|
103
|
+
event_id, automation_id, status, attempts, next_attempt_at_ms, created_at_ms, updated_at_ms
|
|
104
|
+
) VALUES (?, ?, 'pending', 0, ?, ?, ?)`);
|
|
105
|
+
for (const automation of automations) insertDelivery.run(event.id, automation.id, now, now, now);
|
|
106
|
+
return {
|
|
107
|
+
event,
|
|
108
|
+
created: true,
|
|
109
|
+
deliveryCount: automations.length
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
const automationEventPublisher = { publish: ingestAutomationEvent };
|
|
114
|
+
function listAutomationEvents(input = {}) {
|
|
115
|
+
const clauses = [];
|
|
116
|
+
const params = [];
|
|
117
|
+
if (input.type) {
|
|
118
|
+
clauses.push("event_type = ?");
|
|
119
|
+
params.push(input.type);
|
|
120
|
+
}
|
|
121
|
+
if (input.source) {
|
|
122
|
+
clauses.push("source = ?");
|
|
123
|
+
params.push(input.source);
|
|
124
|
+
}
|
|
125
|
+
if (input.subjectKind) {
|
|
126
|
+
clauses.push("subject_kind = ?");
|
|
127
|
+
params.push(input.subjectKind);
|
|
128
|
+
}
|
|
129
|
+
if (input.subjectId) {
|
|
130
|
+
clauses.push("subject_id = ?");
|
|
131
|
+
params.push(input.subjectId);
|
|
132
|
+
}
|
|
133
|
+
params.push(Math.max(1, Math.min(500, Math.floor(input.limit ?? 100))));
|
|
134
|
+
return getSqliteDatabase().prepare(`SELECT * FROM automation_events
|
|
135
|
+
${clauses.length ? `WHERE ${clauses.join(" AND ")}` : ""}
|
|
136
|
+
ORDER BY ingested_at_ms ${input.newestFirst ? "DESC" : "ASC"}, rowid ${input.newestFirst ? "DESC" : "ASC"} LIMIT ?`).all(...params).map(rowToEvent);
|
|
137
|
+
}
|
|
138
|
+
function listAutomationEventRecords(input = {}) {
|
|
139
|
+
const events = listAutomationEvents({
|
|
140
|
+
...input,
|
|
141
|
+
newestFirst: true
|
|
142
|
+
});
|
|
143
|
+
const db = getSqliteDatabase();
|
|
144
|
+
const readEventState = db.prepare(`SELECT projection_status, projection_attempts, projection_error
|
|
145
|
+
FROM automation_events WHERE event_id = ?`);
|
|
146
|
+
const readDeliveries = db.prepare(`SELECT automation_id, status, run_id, attempts, last_error
|
|
147
|
+
FROM automation_event_deliveries WHERE event_id = ? ORDER BY automation_id`);
|
|
148
|
+
return events.map((event) => {
|
|
149
|
+
const state = readEventState.get(event.id);
|
|
150
|
+
const deliveries = readDeliveries.all(event.id);
|
|
151
|
+
return {
|
|
152
|
+
event,
|
|
153
|
+
projectionStatus: state.projection_status,
|
|
154
|
+
projectionAttempts: state.projection_attempts,
|
|
155
|
+
projectionError: state.projection_error ?? void 0,
|
|
156
|
+
deliveries: deliveries.map((delivery) => ({
|
|
157
|
+
automationId: delivery.automation_id,
|
|
158
|
+
status: delivery.status,
|
|
159
|
+
runId: delivery.run_id ?? void 0,
|
|
160
|
+
attempts: delivery.attempts,
|
|
161
|
+
lastError: delivery.last_error ?? void 0
|
|
162
|
+
}))
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function claimAutomationEventsForProjection(owner, limit = 100, leaseMs = 3e4) {
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
return runSqliteWriteTransaction((db) => {
|
|
169
|
+
const candidates = db.prepare(`SELECT * FROM automation_events WHERE
|
|
170
|
+
(projection_status IN ('pending', 'retrying') AND projection_next_attempt_at_ms <= ?)
|
|
171
|
+
OR (projection_status = 'projecting' AND projection_lease_until_ms <= ?)
|
|
172
|
+
ORDER BY ingested_at_ms, event_id LIMIT ?`).all(now, now, Math.max(1, Math.min(500, limit)));
|
|
173
|
+
const claimed = [];
|
|
174
|
+
const statement = db.prepare(`UPDATE automation_events
|
|
175
|
+
SET projection_status = 'projecting', projection_attempts = projection_attempts + 1,
|
|
176
|
+
projection_owner = ?, projection_lease_until_ms = ?
|
|
177
|
+
WHERE event_id = ? AND (
|
|
178
|
+
(projection_status IN ('pending', 'retrying') AND projection_next_attempt_at_ms <= ?)
|
|
179
|
+
OR (projection_status = 'projecting' AND projection_lease_until_ms <= ?)
|
|
180
|
+
)`);
|
|
181
|
+
for (const candidate of candidates) if (statement.run(owner, now + leaseMs, candidate.event_id, now, now).changes === 1) claimed.push(rowToEvent(candidate));
|
|
182
|
+
return claimed;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function expireAutomationEventProjectionLeases() {
|
|
186
|
+
const now = Date.now();
|
|
187
|
+
return runSqliteWriteTransaction((db) => {
|
|
188
|
+
const candidates = db.prepare(`SELECT event_id FROM automation_events
|
|
189
|
+
WHERE projection_status = 'projecting' AND projection_lease_until_ms <= ? AND projection_attempts >= ?`).all(now, MAX_ATTEMPTS);
|
|
190
|
+
const expire = db.prepare(`UPDATE automation_events
|
|
191
|
+
SET projection_status = 'dead_letter', projection_error = 'Projection lease expired after maximum attempts',
|
|
192
|
+
projection_owner = NULL, projection_lease_until_ms = NULL
|
|
193
|
+
WHERE event_id = ? AND projection_status = 'projecting'
|
|
194
|
+
AND projection_lease_until_ms <= ? AND projection_attempts >= ?`);
|
|
195
|
+
const expired = [];
|
|
196
|
+
for (const candidate of candidates) if (expire.run(candidate.event_id, now, MAX_ATTEMPTS).changes === 1) expired.push({
|
|
197
|
+
eventId: candidate.event_id,
|
|
198
|
+
error: "Projection lease expired after maximum attempts"
|
|
199
|
+
});
|
|
200
|
+
return expired;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function completeAutomationEventProjection(eventId, owner) {
|
|
204
|
+
getSqliteDatabase().prepare(`UPDATE automation_events
|
|
205
|
+
SET projection_status = 'projected', projected_at_ms = ?, projection_error = NULL,
|
|
206
|
+
projection_owner = NULL, projection_lease_until_ms = NULL
|
|
207
|
+
WHERE event_id = ? AND projection_status = 'projecting' AND projection_owner = ?`).run(Date.now(), eventId, owner);
|
|
208
|
+
}
|
|
209
|
+
function releaseAutomationEventProjection(eventId, owner) {
|
|
210
|
+
getSqliteDatabase().prepare(`UPDATE automation_events
|
|
211
|
+
SET projection_status = 'retrying', projection_attempts = MAX(0, projection_attempts - 1),
|
|
212
|
+
projection_next_attempt_at_ms = ?, projection_owner = NULL, projection_lease_until_ms = NULL
|
|
213
|
+
WHERE event_id = ? AND projection_status = 'projecting' AND projection_owner = ?`).run(Date.now(), eventId, owner);
|
|
214
|
+
}
|
|
215
|
+
function failAutomationEventProjection(eventId, owner, error) {
|
|
216
|
+
const db = getSqliteDatabase();
|
|
217
|
+
const row = db.prepare("SELECT projection_attempts FROM automation_events WHERE event_id = ? AND projection_owner = ?").get(eventId, owner);
|
|
218
|
+
if (!row) return "retrying";
|
|
219
|
+
const status = row.projection_attempts >= MAX_ATTEMPTS ? "dead_letter" : "retrying";
|
|
220
|
+
const delay = RETRY_DELAYS_MS[Math.min(row.projection_attempts - 1, RETRY_DELAYS_MS.length - 1)];
|
|
221
|
+
db.prepare(`UPDATE automation_events SET projection_status = ?, projection_next_attempt_at_ms = ?,
|
|
222
|
+
projection_error = ?, projection_owner = NULL, projection_lease_until_ms = NULL
|
|
223
|
+
WHERE event_id = ? AND projection_status = 'projecting' AND projection_owner = ?`).run(status, Date.now() + delay, error instanceof Error ? error.message : String(error), eventId, owner);
|
|
224
|
+
return status;
|
|
225
|
+
}
|
|
226
|
+
function claimAutomationEventDeliveries(owner, limit, leaseMs = 3e4) {
|
|
227
|
+
if (limit <= 0) return [];
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
return runSqliteWriteTransaction((db) => {
|
|
230
|
+
const rows = db.prepare(`SELECT e.*, d.automation_id, d.attempts
|
|
231
|
+
FROM automation_event_deliveries d
|
|
232
|
+
JOIN automation_events e ON e.event_id = d.event_id
|
|
233
|
+
LEFT JOIN automations a ON a.automation_id = d.automation_id
|
|
234
|
+
WHERE d.status IN ('pending', 'retrying') AND d.next_attempt_at_ms <= ?
|
|
235
|
+
AND (d.lease_until_ms IS NULL OR d.lease_until_ms <= ?)
|
|
236
|
+
ORDER BY CASE
|
|
237
|
+
WHEN a.enabled = 1 AND json_extract(a.state_json, '$.runningRunId') IS NULL THEN 0
|
|
238
|
+
WHEN a.automation_id IS NULL OR a.enabled = 0 THEN 1
|
|
239
|
+
ELSE 2
|
|
240
|
+
END, d.created_at_ms, d.event_id, d.automation_id LIMIT ?`).all(now, now, Math.min(500, Math.floor(limit)));
|
|
241
|
+
const claimed = [];
|
|
242
|
+
const statement = db.prepare(`UPDATE automation_event_deliveries SET lease_owner = ?, lease_until_ms = ?, updated_at_ms = ?
|
|
243
|
+
WHERE event_id = ? AND automation_id = ? AND status IN ('pending', 'retrying')
|
|
244
|
+
AND (lease_until_ms IS NULL OR lease_until_ms <= ?)`);
|
|
245
|
+
for (const row of rows) if (statement.run(owner, now + leaseMs, now, row.event_id, row.automation_id, now).changes === 1) claimed.push({
|
|
246
|
+
event: rowToEvent(row),
|
|
247
|
+
automationId: row.automation_id,
|
|
248
|
+
attempts: row.attempts,
|
|
249
|
+
owner
|
|
250
|
+
});
|
|
251
|
+
return claimed;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function releaseAutomationEventDelivery(eventId, automationId, owner, delayMs = 1e3) {
|
|
255
|
+
const now = Date.now();
|
|
256
|
+
getSqliteDatabase().prepare(`UPDATE automation_event_deliveries SET next_attempt_at_ms = ?,
|
|
257
|
+
lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
|
|
258
|
+
WHERE event_id = ? AND automation_id = ? AND lease_owner = ? AND status IN ('pending', 'retrying')`).run(now + delayMs, now, eventId, automationId, owner);
|
|
259
|
+
}
|
|
260
|
+
function getAutomationEventDeliveryRunId(eventId, automationId) {
|
|
261
|
+
return getSqliteDatabase().prepare(`SELECT run_id FROM automation_event_deliveries
|
|
262
|
+
WHERE event_id = ? AND automation_id = ?`).get(eventId, automationId)?.run_id ?? null;
|
|
263
|
+
}
|
|
264
|
+
function getAutomationEventForRun(runId) {
|
|
265
|
+
const row = getSqliteDatabase().prepare(`SELECT e.* FROM automation_event_deliveries d
|
|
266
|
+
JOIN automation_events e ON e.event_id = d.event_id WHERE d.run_id = ? LIMIT 1`).get(runId);
|
|
267
|
+
return row ? rowToEvent(row) : null;
|
|
268
|
+
}
|
|
269
|
+
function markAutomationEventDeliveryQueued(eventId, automationId, runId, owner) {
|
|
270
|
+
const ownerClause = owner ? "AND lease_owner = ?" : "";
|
|
271
|
+
const params = owner ? [
|
|
272
|
+
runId,
|
|
273
|
+
Date.now(),
|
|
274
|
+
eventId,
|
|
275
|
+
automationId,
|
|
276
|
+
owner
|
|
277
|
+
] : [
|
|
278
|
+
runId,
|
|
279
|
+
Date.now(),
|
|
280
|
+
eventId,
|
|
281
|
+
automationId
|
|
282
|
+
];
|
|
283
|
+
if (getSqliteDatabase().prepare(`UPDATE automation_event_deliveries
|
|
284
|
+
SET status = 'queued', run_id = ?, attempts = attempts + 1, updated_at_ms = ?, last_error = NULL,
|
|
285
|
+
lease_owner = NULL, lease_until_ms = NULL
|
|
286
|
+
WHERE event_id = ? AND automation_id = ? AND status IN ('pending', 'retrying') ${ownerClause}`).run(...params).changes !== 1) throw new Error("Automation event delivery was already claimed");
|
|
287
|
+
}
|
|
288
|
+
function deferAutomationEventDelivery(eventId, automationId, owner, error) {
|
|
289
|
+
const db = getSqliteDatabase();
|
|
290
|
+
const row = db.prepare(`SELECT attempts FROM automation_event_deliveries
|
|
291
|
+
WHERE event_id = ? AND automation_id = ? AND lease_owner = ?`).get(eventId, automationId, owner);
|
|
292
|
+
if (!row) return "retrying";
|
|
293
|
+
const attempts = row.attempts + 1;
|
|
294
|
+
const status = attempts >= MAX_ATTEMPTS ? "dead_letter" : "retrying";
|
|
295
|
+
const delay = RETRY_DELAYS_MS[Math.min(attempts - 1, RETRY_DELAYS_MS.length - 1)];
|
|
296
|
+
db.prepare(`UPDATE automation_event_deliveries SET status = ?, attempts = ?, next_attempt_at_ms = ?,
|
|
297
|
+
last_error = ?, lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
|
|
298
|
+
WHERE event_id = ? AND automation_id = ? AND lease_owner = ?`).run(status, attempts, Date.now() + delay, error instanceof Error ? error.message : String(error), Date.now(), eventId, automationId, owner);
|
|
299
|
+
return status;
|
|
300
|
+
}
|
|
301
|
+
function skipAutomationEventDelivery(eventId, automationId, reason, owner) {
|
|
302
|
+
const ownerClause = owner ? "AND lease_owner = ?" : "";
|
|
303
|
+
getSqliteDatabase().prepare(`UPDATE automation_event_deliveries SET status = 'skipped',
|
|
304
|
+
last_error = ?, lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
|
|
305
|
+
WHERE event_id = ? AND automation_id = ? AND status IN ('pending', 'retrying') ${ownerClause}`).run(reason, Date.now(), eventId, automationId, ...owner ? [owner] : []);
|
|
306
|
+
}
|
|
307
|
+
function completeAutomationEventDelivery(runId, runStatus) {
|
|
308
|
+
const status = runStatus === "succeeded" ? "completed" : runStatus === "cancelled" ? "cancelled" : "failed";
|
|
309
|
+
getSqliteDatabase().prepare(`UPDATE automation_event_deliveries SET status = ?, updated_at_ms = ?
|
|
310
|
+
WHERE run_id = ? AND status = 'queued'`).run(status, Date.now(), runId);
|
|
311
|
+
}
|
|
312
|
+
function reconcileAutomationEventDeliveries() {
|
|
313
|
+
const result = getSqliteDatabase().prepare(`UPDATE automation_event_deliveries
|
|
314
|
+
SET status = CASE
|
|
315
|
+
WHEN (SELECT status FROM automation_runs WHERE run_id = automation_event_deliveries.run_id) = 'succeeded' THEN 'completed'
|
|
316
|
+
WHEN (SELECT status FROM automation_runs WHERE run_id = automation_event_deliveries.run_id) = 'cancelled' THEN 'cancelled'
|
|
317
|
+
ELSE 'failed'
|
|
318
|
+
END, updated_at_ms = ?
|
|
319
|
+
WHERE status = 'queued' AND run_id IN (
|
|
320
|
+
SELECT run_id FROM automation_runs WHERE status IN ('succeeded', 'failed', 'cancelled', 'timeout')
|
|
321
|
+
)`).run(Date.now());
|
|
322
|
+
return Number(result.changes);
|
|
323
|
+
}
|
|
324
|
+
function replayAutomationEvent(eventId) {
|
|
325
|
+
return runSqliteWriteTransaction((db) => {
|
|
326
|
+
const now = Date.now();
|
|
327
|
+
const projection = db.prepare(`UPDATE automation_events SET projection_status = 'retrying',
|
|
328
|
+
projection_attempts = 0, projection_next_attempt_at_ms = ?, projection_error = NULL,
|
|
329
|
+
projection_owner = NULL, projection_lease_until_ms = NULL
|
|
330
|
+
WHERE event_id = ? AND projection_status = 'dead_letter'`).run(now, eventId).changes;
|
|
331
|
+
const deliveries = db.prepare(`UPDATE automation_event_deliveries SET status = 'retrying', attempts = 0,
|
|
332
|
+
next_attempt_at_ms = ?, last_error = NULL, lease_owner = NULL, lease_until_ms = NULL, updated_at_ms = ?
|
|
333
|
+
WHERE event_id = ? AND status = 'dead_letter'`).run(now, now, eventId).changes;
|
|
334
|
+
return Number(projection) + Number(deliveries) > 0;
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
function getAutomationEventQueueMetrics() {
|
|
338
|
+
const now = Date.now();
|
|
339
|
+
const event = getSqliteDatabase().prepare(`SELECT
|
|
340
|
+
SUM(CASE WHEN projection_status IN ('pending', 'projecting', 'retrying') THEN 1 ELSE 0 END) AS pending,
|
|
341
|
+
MIN(CASE WHEN projection_status IN ('pending', 'projecting', 'retrying') THEN ingested_at_ms END) AS oldest,
|
|
342
|
+
SUM(CASE WHEN projection_status = 'dead_letter' THEN 1 ELSE 0 END) AS dead_letters
|
|
343
|
+
FROM automation_events`).get();
|
|
344
|
+
const delivery = getSqliteDatabase().prepare(`SELECT
|
|
345
|
+
SUM(CASE WHEN status IN ('pending', 'retrying', 'queued') THEN 1 ELSE 0 END) AS pending,
|
|
346
|
+
SUM(CASE WHEN status = 'dead_letter' THEN 1 ELSE 0 END) AS dead_letters,
|
|
347
|
+
SUM(CASE WHEN lease_until_ms > ? THEN 1 ELSE 0 END) AS active_leases
|
|
348
|
+
FROM automation_event_deliveries`).get(now);
|
|
349
|
+
const projectionLeases = getSqliteDatabase().prepare(`SELECT COUNT(*) AS count FROM automation_events
|
|
350
|
+
WHERE projection_status = 'projecting' AND projection_lease_until_ms > ?`).get(now);
|
|
351
|
+
return {
|
|
352
|
+
pending: event.pending ?? 0,
|
|
353
|
+
oldestPendingAgeMs: event.oldest == null ? 0 : Math.max(0, now - event.oldest),
|
|
354
|
+
projectionDeadLetters: event.dead_letters ?? 0,
|
|
355
|
+
pendingDeliveries: delivery.pending ?? 0,
|
|
356
|
+
deliveryDeadLetters: delivery.dead_letters ?? 0,
|
|
357
|
+
activeLeases: (delivery.active_leases ?? 0) + projectionLeases.count
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
//#endregion
|
|
361
|
+
export { automationEventPublisher, claimAutomationEventDeliveries, claimAutomationEventsForProjection, completeAutomationEventDelivery, completeAutomationEventProjection, deferAutomationEventDelivery, expireAutomationEventProjectionLeases, failAutomationEventProjection, getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, ingestAutomationEvent, listAutomationEventRecords, listAutomationEvents, markAutomationEventDeliveryQueued, reconcileAutomationEventDeliveries, releaseAutomationEventDelivery, releaseAutomationEventProjection, replayAutomationEvent, skipAutomationEventDelivery };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { listBusinessEventDefinitions, registerBusinessEvent, validateCatalogedBusinessEvent } from "./event-catalog.js";
|
|
2
|
+
import { automationEventPublisher, claimAutomationEventDeliveries, claimAutomationEventsForProjection, completeAutomationEventDelivery, completeAutomationEventProjection, deferAutomationEventDelivery, expireAutomationEventProjectionLeases, failAutomationEventProjection, getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, ingestAutomationEvent, listAutomationEventRecords, listAutomationEvents, markAutomationEventDeliveryQueued, reconcileAutomationEventDeliveries, releaseAutomationEventDelivery, releaseAutomationEventProjection, replayAutomationEvent, skipAutomationEventDelivery } from "./event-repository.js";
|
|
3
|
+
import { AutomationEventDispatcher } from "./event-dispatcher.js";
|
|
4
|
+
export { AutomationEventDispatcher, automationEventPublisher, claimAutomationEventDeliveries, claimAutomationEventsForProjection, completeAutomationEventDelivery, completeAutomationEventProjection, deferAutomationEventDelivery, expireAutomationEventProjectionLeases, failAutomationEventProjection, getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, ingestAutomationEvent, listAutomationEventRecords, listAutomationEvents, listBusinessEventDefinitions, markAutomationEventDeliveryQueued, reconcileAutomationEventDeliveries, registerBusinessEvent, releaseAutomationEventDelivery, releaseAutomationEventProjection, replayAutomationEvent, skipAutomationEventDelivery, validateCatalogedBusinessEvent };
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { AutomationActionSchema, AutomationDeliveryPolicySchema, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, UpdateAutomationSchema } from "./domain/validation.js";
|
|
2
|
+
import { listBusinessEventDefinitions, registerBusinessEvent, validateCatalogedBusinessEvent } from "./events/event-catalog.js";
|
|
3
|
+
import { automationEventPublisher, claimAutomationEventDeliveries, claimAutomationEventsForProjection, completeAutomationEventDelivery, completeAutomationEventProjection, deferAutomationEventDelivery, expireAutomationEventProjectionLeases, failAutomationEventProjection, getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, ingestAutomationEvent, listAutomationEventRecords, listAutomationEvents, markAutomationEventDeliveryQueued, reconcileAutomationEventDeliveries, releaseAutomationEventDelivery, releaseAutomationEventProjection, replayAutomationEvent, skipAutomationEventDelivery } from "./events/event-repository.js";
|
|
3
4
|
import { computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, timerDelayUntil } from "./domain/schedule.js";
|
|
4
5
|
import { DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, defaultAutomationTimeoutSeconds, resolveAutomationTimeoutSeconds } from "./domain/defaults.js";
|
|
5
6
|
import { AutomationActionExecutor } from "./service/action-executor.js";
|
|
7
|
+
import { AutomationEventDispatcher } from "./events/event-dispatcher.js";
|
|
8
|
+
import "./events/index.js";
|
|
9
|
+
import { resolveAutomationWebhookSecret } from "./webhook-secrets.js";
|
|
10
|
+
import { AutomationDeliveryRouter, getAutomationResultDeliveryMetrics, listAutomationResultDeliveries, retryAutomationResultDelivery } from "./delivery/delivery-router.js";
|
|
11
|
+
import "./delivery/index.js";
|
|
6
12
|
import { AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationService } from "./service/automation-service.js";
|
|
7
13
|
import "./domain/index.js";
|
|
8
14
|
import "./service/index.js";
|
|
9
|
-
export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds,
|
|
15
|
+
export { AutomationActionExecutor, AutomationActionSchema, AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationDeliveryPolicySchema, AutomationDeliveryRouter, AutomationEventDispatcher, AutomationManagementSchema, AutomationReliabilitySchema, AutomationSafetyPolicySchema, AutomationScheduleSchema, AutomationSchema, AutomationService, AutomationStateSchema, AutomationTriggerSchema, CreateAutomationSchema, DEFAULT_AUTOMATION_TIMEOUT_SECONDS, DEFAULT_BROWSER_AUTOMATION_TIMEOUT_SECONDS, UpdateAutomationSchema, automationEventPublisher, claimAutomationEventDeliveries, claimAutomationEventsForProjection, completeAutomationEventDelivery, completeAutomationEventProjection, computeNextAutomationRunAtMs, computeNextScheduleRunAtMs, defaultAutomationTimeoutSeconds, deferAutomationEventDelivery, expireAutomationEventProjectionLeases, failAutomationEventProjection, getAutomationEventDeliveryRunId, getAutomationEventForRun, getAutomationEventQueueMetrics, getAutomationResultDeliveryMetrics, ingestAutomationEvent, listAutomationEventRecords, listAutomationEvents, listAutomationResultDeliveries, listBusinessEventDefinitions, markAutomationEventDeliveryQueued, reconcileAutomationEventDeliveries, registerBusinessEvent, releaseAutomationEventDelivery, releaseAutomationEventProjection, replayAutomationEvent, resolveAutomationTimeoutSeconds, resolveAutomationWebhookSecret, retryAutomationResultDelivery, skipAutomationEventDelivery, timerDelayUntil, validateCatalogedBusinessEvent };
|
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
import type { Automation, AutomationActionExecutionContext, AutomationActionExecutionHooks, AutomationActionTask, AutomationDeps, AutomationRun } from '../domain/types.js';
|
|
1
|
+
import type { Automation, AutomationAction, AutomationActionExecutionContext, AutomationActionExecutionHooks, AutomationActionTask, AutomationDeps, AutomationRetrySafety, AutomationRun } from '../domain/types.js';
|
|
2
|
+
type AutomationActionKind = AutomationAction['kind'];
|
|
3
|
+
type AutomationActionOf<K extends AutomationActionKind> = Extract<AutomationAction, {
|
|
4
|
+
kind: K;
|
|
5
|
+
}>;
|
|
6
|
+
interface AutomationExecutorInput {
|
|
7
|
+
automation: Automation;
|
|
8
|
+
run: AutomationRun;
|
|
9
|
+
signal: AbortSignal;
|
|
10
|
+
hooks: AutomationActionExecutionHooks;
|
|
11
|
+
deadlineAtMs: number;
|
|
12
|
+
context: AutomationActionExecutionContext;
|
|
13
|
+
}
|
|
2
14
|
export declare class AutomationActionExecutor {
|
|
3
15
|
private deps;
|
|
16
|
+
private readonly handlers;
|
|
17
|
+
constructor();
|
|
18
|
+
register<K extends AutomationActionKind>(kind: K, retrySafety: AutomationRetrySafety, handler: (input: AutomationExecutorInput, action: AutomationActionOf<K>) => Promise<AutomationActionTask>): void;
|
|
19
|
+
canRetry(kind: AutomationActionKind, error: unknown): boolean;
|
|
4
20
|
setDeps(deps: AutomationDeps): void;
|
|
5
21
|
execute(automation: Automation, run: AutomationRun, signal: AbortSignal, hooks?: AutomationActionExecutionHooks, context?: AutomationActionExecutionContext): Promise<AutomationActionTask>;
|
|
6
22
|
private executeWithoutTimeout;
|
|
23
|
+
private executeTaskCommand;
|
|
24
|
+
private executeSystemAction;
|
|
7
25
|
private executeBrowserAutomation;
|
|
8
26
|
private executeAgent;
|
|
9
27
|
private executeWorkflow;
|
|
10
28
|
}
|
|
29
|
+
export {};
|
|
@@ -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
|
}
|