@xopcai/xopc 0.0.312 → 0.0.314
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-C3yV1y_l.js → auth-DKo-NMUY.js} +18 -1
- package/dist/browser-ext/dist/background.js +68 -2
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +1 -1
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +2 -2
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BVIJMP8w.js → agent-avatar-dicebear-BFkjfurL.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BdOZ6q8Z.js +1 -0
- package/dist/gateway/static/root/assets/{agents-D6g_SeWI.js → agents-CCcavsHq.js} +1 -1
- package/dist/gateway/static/root/assets/{api-_aHQA8bd.js → api-BYhRsTAc.js} +1 -1
- package/dist/gateway/static/root/assets/{app-link-CKueEVbT.js → app-link-nL8iPwEr.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-CLg_aXYG.js → app-management-settings-panel-B4kihr-A.js} +1 -1
- package/dist/gateway/static/root/assets/appearance-settings-N9sYmNOx.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-BMcy10_s.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-CHO3heHX.js → archive-plugin-k_SuYWyV.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BsmsBCI2.js → attachment-load-DRv5QWUK.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CftigJlf.js → automations-page-CkJV3DN0.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-BEa2doeR.js +7 -0
- package/dist/gateway/static/root/assets/{binary-plugins-CRCLWBo2.js → binary-plugins-Dg3h3TA7.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-D0LDiOTT.js → block-editor-DVhdHntT.js} +29 -29
- package/dist/gateway/static/root/assets/{browser-automation-inputs-C611KRBx.js → browser-automation-inputs-BMRYUW8_.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-Djyv3vy-.js → browser-automations-page-Byv6-FY2.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-DRCHGFpO.js +3 -0
- package/dist/gateway/static/root/assets/capabilities-D0S3DuAD.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-mxRP0gl0.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-DBt_6GsB.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CIsKqdET.js → chat-terminal-dock-D4AHa51o.js} +2 -2
- package/dist/gateway/static/root/assets/{computer-settings-page-C0YL9J7m.js → computer-settings-page-eXPe500D.js} +1 -1
- package/dist/gateway/static/root/assets/connector-service-page-BQTFlq_k.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-BKeBWwcI.js +2 -0
- package/dist/gateway/static/root/assets/conversation-identity-Cw0n9uzK.js +1 -0
- package/dist/gateway/static/root/assets/{date-picker-CDsfv8R0.js → date-picker-7MtovynY.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DvhPj3CZ.js → dependency-picker-Bj_xkXID.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-Cyg8XMpL.js → desktop-pet-CTmba9zH.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-DNM_BlWN.js +1 -0
- package/dist/gateway/static/root/assets/device-pairing-wizard-C2XE0QhT.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-D-AVJU3q.js → extension-debug-page-J_olaL7e.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DrFoQ9xt.js → extension-page-pK5RvqN8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DxWjESC1.js → extension-settings-page-BwroEN08.js} +1 -1
- package/dist/gateway/static/root/assets/files-BK6enEvD.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-DUDX42qY.js → gateway-config-swr-FuJTIg_a.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-CLLDp23J.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Cf8OxlvY.js → gateway-startup-retry-CKg_gu8_.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-B5Epb1PH.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-D2YorS--.js → image-generation-api-Bo6NZ7zb.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-BKucJlXI.js → imports-page-C8-hX8gS.js} +1 -1
- package/dist/gateway/static/root/assets/index-14F1yGJI.js +89 -0
- package/dist/gateway/static/root/assets/index-cB7rWIDY.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BxLXD-yU.js → keyboard-shortcuts-settings-BkBEjUZD.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-6jC3vQpY.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-BAsQJQKJ.js → local-apps-page-CrbKIixo.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DA0Z5jM_.js → locale-store-CvGwNbml.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-DBHlZts9.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DsUWLu5m.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-DYGPxPee.js → markdown-view-nXo5nrsv.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-CQtQzLyg.js → media-plugins-upxXJ-4l.js} +1 -1
- package/dist/gateway/static/root/assets/messages-B_AwRroN.js +3 -0
- package/dist/gateway/static/root/assets/note-detail-panel-0Q9TOtJG.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-D0NmcwNw.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-DUyA-K4L.js +1 -0
- package/dist/gateway/static/root/assets/{page-tabs-B6DjkyMM.js → page-tabs-Cl-NFPNr.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Dn57uLhr.js → preview-open-alternatives-DX81PwJ3.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-chCjIpvu.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-H2YMk8TY.js → product-open-page-CrfIGwm8.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BVfVrYmn.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-nM9a9XNS.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-C0DCx3wv.js → registry-api-CHxgohY0.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-C8b_k88G.js +1 -0
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-D3dLOW04.js +5 -0
- package/dist/gateway/static/root/assets/scenes-page-DEowreZV.js +2 -0
- package/dist/gateway/static/root/assets/{schema-form-CblI9WUA.js → schema-form-ZxuIvD2_.js} +1 -1
- package/dist/gateway/static/root/assets/schemas-88fK3zzl.js +64 -0
- package/dist/gateway/static/root/assets/sessions-page-B_nPhera.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BqhIOuus.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-BAaVyxJH.js → settings-form-section-TZRfg4yo.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-CKNPbm5q.js → settings-page-a8qcJpdZ.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DqNCGKxQ.js → settings-page-layout-BfvlRT9q.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CRj5Ruqn.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BzMfp_HM.js → share-preview-page-DCt1pTWB.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BNbXPk--.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-CNMCLbav.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-DIht92q6.js → skills-page-BIOcg44X.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-DLYRiEn3.js → skills-page.utils-CgZdzT4I.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-yYs4YgYk.js → system-settings-panel-_YaRncA6.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-CAcfAG-c.js +1 -0
- package/dist/gateway/static/root/assets/tasks-CDR_RVbQ.js +1 -0
- package/dist/gateway/static/root/assets/{tunnel-api-BasDYxvx.js → tunnel-api-uOupJOoS.js} +1 -1
- package/dist/gateway/static/root/assets/turn-outcome-D0SnyZ3Z.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-CWAUHhcb.js → use-autosave-BezzHBLE.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-BFFeneDq.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-Kc4UlxZs.js → voice-api-key-field-BmYifdwL.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-DTyMdGOR.js → voice-config-api-D_5Q2_A3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BPC_c9dO.js → work-discovery-overlay-4DmyEckJ.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DBTciOrq.js → workflow-run-setup-panel-DeZe8bTZ.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-Sv4hEc6W.js +6 -0
- package/dist/gateway/static/root/index.html +16 -16
- package/dist/package.js +1 -1
- package/dist/packages/computer-control-contract/src/index.js +10 -1
- package/dist/packages/gateway-contract/src/app-context.js +55 -0
- package/dist/packages/gateway-contract/src/automations.js +16 -17
- package/dist/packages/gateway-contract/src/capabilities.js +1078 -0
- package/dist/packages/gateway-contract/src/extension-capabilities.js +26 -0
- package/dist/packages/gateway-contract/src/home.js +3 -3
- package/dist/packages/gateway-contract/src/index.js +8 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +19 -4
- package/dist/packages/gateway-contract/src/scenes.js +199 -0
- package/dist/packages/gateway-contract/src/task-runs.js +8 -4
- package/dist/packages/gateway-contract/src/tasks.js +5 -4
- package/dist/packages/realtime-client/src/index.js +17 -4
- package/dist/src/agent/agent-manager.d.ts +1 -0
- package/dist/src/agent/agent-manager.js +1 -0
- package/dist/src/agent/child-agent-factory.d.ts +2 -0
- package/dist/src/agent/child-agent-factory.js +5 -0
- package/dist/src/agent/commands/approved-verification.d.ts +14 -0
- package/dist/src/agent/commands/approved-verification.js +48 -0
- package/dist/src/agent/context/execution-scope.js +2 -1
- package/dist/src/agent/context/project-context.js +2 -1
- package/dist/src/agent/external-tools/cliProvider.js +123 -75
- package/dist/src/agent/external-tools/composio-provider.d.ts +1 -1
- package/dist/src/agent/external-tools/composio-provider.js +70 -12
- package/dist/src/agent/external-tools/endpoint-provider.js +14 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -0
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -1
- package/dist/src/agent/memory/compaction-chunks.d.ts +6 -1
- package/dist/src/agent/memory/compaction-chunks.js +16 -3
- package/dist/src/agent/memory/compaction-ledger.d.ts +3 -1
- package/dist/src/agent/memory/compaction-ledger.js +31 -18
- package/dist/src/agent/memory/compaction-request.d.ts +2 -0
- package/dist/src/agent/memory/compaction-request.js +6 -1
- package/dist/src/agent/memory/compaction.d.ts +19 -1
- package/dist/src/agent/memory/compaction.js +112 -30
- package/dist/src/agent/service/process-direct-streaming.d.ts +3 -0
- package/dist/src/agent/service/process-direct-streaming.js +19 -10
- package/dist/src/agent/service.js +1 -0
- package/dist/src/agent/service.types.d.ts +1 -0
- package/dist/src/agent/skills/config.js +2 -0
- package/dist/src/agent/skills/format-skills-prompt.js +14 -1
- package/dist/src/agent/skills/index.js +16 -8
- package/dist/src/agent/skills/types.d.ts +1 -1
- package/dist/src/agent/source-context/app-context.d.ts +4 -0
- package/dist/src/agent/source-context/app-context.js +36 -0
- package/dist/src/agent/source-context/injector.js +1 -0
- package/dist/src/agent/source-context/types.d.ts +5 -1
- package/dist/src/agent/tasks/task-judge-service.js +2 -1
- package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
- package/dist/src/agent/tool-manuals/computer.js +1 -1
- package/dist/src/agent/tools/automation-tool.d.ts +12 -1
- package/dist/src/agent/tools/automation-tool.js +106 -32
- package/dist/src/agent/tools/factory.d.ts +1 -0
- package/dist/src/agent/tools/factory.js +6 -1
- package/dist/src/agent/tools/scoped-workspace-tools.d.ts +8 -0
- package/dist/src/agent/tools/scoped-workspace-tools.js +81 -0
- package/dist/src/agent/tools/xopc-use-tool.d.ts +6 -3
- package/dist/src/agent/tools/xopc-use-tool.js +997 -908
- package/dist/src/agent/workflow/subagent-runner.js +1 -0
- package/dist/src/agent-config/index.js +2 -2
- package/dist/src/agent-config/schema.d.ts +5 -0
- package/dist/src/agent-config/schema.js +14 -10
- package/dist/src/automations/api/routes.js +244 -164
- package/dist/src/automations/capabilities/drafts.d.ts +4 -0
- package/dist/src/automations/capabilities/drafts.js +95 -0
- package/dist/src/automations/capabilities/read.d.ts +4 -0
- package/dist/src/automations/capabilities/read.js +119 -0
- package/dist/src/automations/capabilities/write.d.ts +349 -0
- package/dist/src/automations/capabilities/write.js +172 -0
- package/dist/src/automations/domain/index.js +2 -2
- package/dist/src/automations/domain/validation.d.ts +77 -77
- package/dist/src/automations/domain/validation.js +9 -6
- package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -2
- package/dist/src/automations/index.js +6 -6
- package/dist/src/automations/service/automation-service.d.ts +31 -0
- package/dist/src/automations/service/automation-service.js +213 -75
- package/dist/src/automations/service/index.js +2 -2
- package/dist/src/automations/storage/automation-repository.d.ts +2 -0
- package/dist/src/automations/storage/automation-repository.js +9 -1
- package/dist/src/automations/storage/automation-run-repository.d.ts +4 -1
- package/dist/src/automations/storage/automation-run-repository.js +16 -3
- package/dist/src/automations/storage/index.js +3 -3
- package/dist/src/browser/automations/schema.d.ts +1 -1
- package/dist/src/browser/automations/service.d.ts +1 -1
- package/dist/src/browser/observation/format.js +4 -0
- package/dist/src/capabilities/adapters/http.d.ts +4 -0
- package/dist/src/capabilities/adapters/http.js +44 -0
- package/dist/src/capabilities/readiness/from-config.js +11 -7
- package/dist/src/capabilities/runtime/app-context.d.ts +3 -0
- package/dist/src/capabilities/runtime/app-context.js +72 -0
- package/dist/src/capabilities/runtime/atomic-operations.d.ts +11 -0
- package/dist/src/capabilities/runtime/atomic-operations.js +34 -0
- package/dist/src/capabilities/runtime/dispatcher.d.ts +67 -0
- package/dist/src/capabilities/runtime/dispatcher.js +170 -0
- package/dist/src/capabilities/runtime/errors.d.ts +6 -0
- package/dist/src/capabilities/runtime/errors.js +11 -0
- package/dist/src/capabilities/runtime/external-operations.d.ts +16 -0
- package/dist/src/capabilities/runtime/external-operations.js +92 -0
- package/dist/src/capabilities/runtime/product.d.ts +12 -0
- package/dist/src/capabilities/runtime/product.js +69 -0
- package/dist/src/capabilities/runtime/settings.d.ts +3 -0
- package/dist/src/capabilities/runtime/settings.js +27 -0
- package/dist/src/channels/index.js +2 -2
- package/dist/src/channels/manager.js +1 -1
- package/dist/src/cli/cli-log-level-preset.d.ts +2 -0
- package/dist/src/cli/cli-log-level-preset.js +4 -0
- package/dist/src/cli/command-catalog.js +4 -0
- package/dist/src/cli/command-loaders.js +1 -0
- package/dist/src/cli/command-manifest.js +4 -0
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/mcp.d.ts +1 -0
- package/dist/src/cli/commands/mcp.js +51 -0
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/project.js +1 -1
- package/dist/src/computer/broker.d.ts +0 -1
- package/dist/src/computer/broker.js +4 -6
- package/dist/src/computer/evaluation-harness.d.ts +45 -0
- package/dist/src/computer/evaluation-harness.js +108 -0
- package/dist/src/computer/model-adapter.d.ts +37 -2
- package/dist/src/computer/model-adapter.js +333 -42
- package/dist/src/computer/model-policy.d.ts +4 -1
- package/dist/src/computer/model-policy.js +11 -3
- package/dist/src/computer/release-gate.d.ts +22 -0
- package/dist/src/computer/release-gate.js +19 -0
- package/dist/src/computer/runtime.js +14 -10
- package/dist/src/computer/task-state.d.ts +1 -0
- package/dist/src/computer/task-state.js +1 -0
- package/dist/src/config/models-json.d.ts +14 -8
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +4 -0
- package/dist/src/config/schema.js +3 -9
- package/dist/src/connectors/composio-sessions.d.ts +4 -2
- package/dist/src/connectors/composio-sessions.js +10 -9
- package/dist/src/connectors/composio.js +10 -8
- package/dist/src/discussions/action-tasks.js +2 -1
- package/dist/src/discussions/recording.js +1 -1
- package/dist/src/execution-environments/local-worktree-manager.d.ts +1 -0
- package/dist/src/execution-environments/local-worktree-manager.js +13 -2
- package/dist/src/extensions/activation-context.js +3 -3
- package/dist/src/extensions/api.js +1 -1
- package/dist/src/extensions/normalize-manifest.js +6 -1
- package/dist/src/extensions/sdk/index.js +1 -1
- package/dist/src/extensions/sdk/media.js +1 -1
- package/dist/src/extensions/types/manifest.d.ts +3 -0
- package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/middleware/scopes.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +5 -2
- package/dist/src/gateway/hono/routes/capability-operations.d.ts +3 -0
- package/dist/src/gateway/hono/routes/capability-operations.js +52 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +16 -0
- package/dist/src/gateway/hono/routes/local-app-capabilities.d.ts +4 -0
- package/dist/src/gateway/hono/routes/local-app-capabilities.js +41 -0
- package/dist/src/gateway/hono/routes/local-apps.js +41 -9
- package/dist/src/gateway/hono/routes/models.js +2 -2
- package/dist/src/gateway/hono/routes/notes.js +215 -146
- package/dist/src/gateway/hono/routes/projects.js +217 -374
- package/dist/src/gateway/hono/routes/scenes.js +188 -75
- package/dist/src/gateway/hono/routes/session-input-handler.d.ts +60 -16
- package/dist/src/gateway/hono/routes/session-input-handler.js +43 -1
- package/dist/src/gateway/hono/routes/sessions.js +17 -0
- package/dist/src/gateway/hono/routes/status.js +1 -1
- package/dist/src/gateway/hono/routes/tasks.js +182 -326
- package/dist/src/gateway/hono/routes/user-model-refresh.js +1 -1
- package/dist/src/gateway/hono/routes/voice.js +4 -4
- package/dist/src/gateway/hono/routes/workflows.js +1 -1
- package/dist/src/gateway/media-access.js +2 -1
- package/dist/src/gateway/mobile-privacy.js +2 -2
- package/dist/src/gateway/scenes/host.js +14 -3
- package/dist/src/gateway/scenes/mailContext.js +1 -1
- package/dist/src/gateway/scenes/slackThreadSource.d.ts +41 -0
- package/dist/src/gateway/scenes/slackThreadSource.js +168 -0
- package/dist/src/gateway/security/gateway-scopes.d.ts +1 -1
- package/dist/src/gateway/security/gateway-scopes.js +5 -0
- package/dist/src/gateway/service/app-context-access.d.ts +11 -0
- package/dist/src/gateway/service/app-context-access.js +70 -0
- package/dist/src/gateway/service/run-gateway-agent.js +11 -2
- package/dist/src/gateway/service/session-input-coordinator.js +54 -15
- package/dist/src/gateway/service/sessions-api.d.ts +1 -0
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service/task-conversation-query-service.d.ts +3 -1
- package/dist/src/gateway/service/task-conversation-query-service.js +32 -3
- package/dist/src/gateway/service.d.ts +3 -0
- package/dist/src/gateway/service.js +69 -15
- package/dist/src/gateway/session-context-summary.js +2 -1
- package/dist/src/{tasks/task-outbox-dispatcher.d.ts → infra/domain-outbox-dispatcher.d.ts} +2 -2
- package/dist/src/{tasks/task-outbox-dispatcher.js → infra/domain-outbox-dispatcher.js} +10 -9
- package/dist/src/infra/operation-context.d.ts +2 -0
- package/dist/src/infra/operation-context.js +16 -0
- package/dist/src/local-apps/capabilities/contracts.d.ts +2 -0
- package/dist/src/local-apps/capabilities/contracts.js +32 -0
- package/dist/src/local-apps/capabilities/read.d.ts +3 -0
- package/dist/src/local-apps/capabilities/read.js +48 -0
- package/dist/src/local-apps/capabilities/runtime.d.ts +16 -0
- package/dist/src/local-apps/capabilities/runtime.js +66 -0
- package/dist/src/local-apps/capabilities/write.d.ts +3 -0
- package/dist/src/local-apps/capabilities/write.js +35 -0
- package/dist/src/local-apps/release-lock.d.ts +2 -0
- package/dist/src/local-apps/release-lock.js +20 -0
- package/dist/src/local-apps/runtime-entry.d.ts +0 -2
- package/dist/src/local-apps/runtime-entry.js +1 -14
- package/dist/src/local-apps/scaffold.js +4 -1
- package/dist/src/local-apps/service.d.ts +24 -1
- package/dist/src/local-apps/service.js +186 -43
- package/dist/src/local-apps/store.js +0 -2
- package/dist/src/mcp/capability-server.d.ts +4 -0
- package/dist/src/mcp/capability-server.js +96 -0
- package/dist/src/mcp/channel-bridge.js +1 -1
- package/dist/src/mcp/gateway-http-client.d.ts +7 -0
- package/dist/src/mcp/gateway-http-client.js +27 -5
- package/dist/src/media-understanding/openai-compatible-audio.js +1 -1
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/capabilities/read.d.ts +3 -0
- package/dist/src/notes/capabilities/read.js +96 -0
- package/dist/src/notes/capabilities/write.d.ts +7 -0
- package/dist/src/notes/capabilities/write.js +152 -0
- package/dist/src/notes/index.js +1 -1
- package/dist/src/notes/service.d.ts +12 -4
- package/dist/src/notes/service.js +188 -175
- package/dist/src/notes/store.d.ts +14 -9
- package/dist/src/notes/store.js +81 -21
- package/dist/src/notifications/service.d.ts +1 -0
- package/dist/src/notifications/service.js +5 -0
- package/dist/src/platform/client.d.ts +1 -1
- package/dist/src/platform/contracts.d.ts +1 -1
- package/dist/src/projects/capabilities/read.d.ts +3 -0
- package/dist/src/projects/capabilities/read.js +81 -0
- package/dist/src/projects/capabilities/write.d.ts +9 -0
- package/dist/src/projects/capabilities/write.js +260 -0
- package/dist/src/projects/index.js +2 -2
- package/dist/src/projects/project-change-events.d.ts +2 -0
- package/dist/src/projects/project-change-events.js +18 -0
- package/dist/src/projects/project-service.d.ts +11 -0
- package/dist/src/projects/project-service.js +121 -42
- package/dist/src/projects/project-store.js +12 -2
- package/dist/src/projects/project-workspace-creation.d.ts +3 -0
- package/dist/src/projects/project-workspace-creation.js +45 -0
- package/dist/src/projects/workspace-project.js +6 -0
- package/dist/src/providers/model-catalog-types.d.ts +2 -1
- package/dist/src/providers/model-reference-auditor.js +4 -4
- package/dist/src/providers/model-supplements.js +13 -3
- package/dist/src/providers/presentation.js +3 -3
- package/dist/src/providers/xopc-cloud-model-source.js +4 -2
- package/dist/src/realtime/runtime.js +4 -0
- package/dist/src/scenes/capabilities/read.d.ts +3 -0
- package/dist/src/scenes/capabilities/read.js +187 -0
- package/dist/src/scenes/capabilities/write.d.ts +3 -0
- package/dist/src/scenes/capabilities/write.js +151 -0
- package/dist/src/scenes/contracts.d.ts +2 -105
- package/dist/src/scenes/contracts.js +3 -88
- package/dist/src/scenes/execution.d.ts +1 -1
- package/dist/src/scenes/httpServices.d.ts +2 -0
- package/dist/src/scenes/inbox.d.ts +1 -0
- package/dist/src/scenes/inbox.js +7 -7
- package/dist/src/scenes/preferences.d.ts +3 -24
- package/dist/src/scenes/preferences.js +8 -30
- package/dist/src/scenes/repository.d.ts +1 -0
- package/dist/src/scenes/repository.js +7 -3
- package/dist/src/scenes/resultNotifications.js +2 -2
- package/dist/src/scenes/schedule.d.ts +1 -8
- package/dist/src/scenes/schedule.js +3 -15
- package/dist/src/scenes/service.d.ts +6 -0
- package/dist/src/scenes/service.js +29 -25
- package/dist/src/scenes/taskFollowUp/agentExecutor.d.ts +36 -0
- package/dist/src/scenes/taskFollowUp/agentExecutor.js +149 -0
- package/dist/src/scenes/taskFollowUp/branchInventory.d.ts +38 -0
- package/dist/src/scenes/taskFollowUp/branchInventory.js +70 -0
- package/dist/src/scenes/taskFollowUp/contracts.d.ts +91 -0
- package/dist/src/scenes/taskFollowUp/contracts.js +100 -0
- package/dist/src/scenes/taskFollowUp/resources.d.ts +19 -0
- package/dist/src/scenes/taskFollowUp/resources.js +97 -0
- package/dist/src/scenes/taskFollowUp/service.d.ts +810 -0
- package/dist/src/scenes/taskFollowUp/service.js +710 -0
- package/dist/src/scenes/taskFollowUp/workspaceFingerprint.d.ts +2 -0
- package/dist/src/scenes/taskFollowUp/workspaceFingerprint.js +46 -0
- package/dist/src/scenes/templates.d.ts +2 -2
- package/dist/src/scenes/templates.js +1 -1
- package/dist/src/session/session-find.d.ts +17 -0
- package/dist/src/session/session-find.js +56 -0
- package/dist/src/session/store.d.ts +4 -0
- package/dist/src/session/store.js +43 -7
- package/dist/src/share/note-share-revocation.d.ts +3 -0
- package/dist/src/share/note-share-revocation.js +26 -0
- package/dist/src/storage/sqlite/migrations/190_scene_development.sql +37 -0
- package/dist/src/storage/sqlite/migrations/191_scene_task_follow_up.sql +27 -0
- package/dist/src/storage/sqlite/migrations/192_capability_operations.sql +20 -0
- package/dist/src/storage/sqlite/migrations/193_note_file_cleanup.sql +8 -0
- package/dist/src/storage/sqlite/migrations/194_capability_external_outcomes.sql +11 -0
- package/dist/src/storage/sqlite/migrations/195_automation_deleted_revisions.sql +4 -0
- package/dist/src/storage/sqlite/migrations/196_automation_run_requests.sql +23 -0
- package/dist/src/storage/sqlite/migrations/197_note_deletion_cleanup.sql +8 -0
- package/dist/src/storage/sqlite/migrations/198_project_workspace_creation.sql +7 -0
- package/dist/src/storage/sqlite/migrations/199_scene_resource_events.sql +488 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +6 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/transaction.d.ts +5 -0
- package/dist/src/storage/sqlite/transaction.js +34 -3
- package/dist/src/tasks/capabilities/management.d.ts +195 -0
- package/dist/src/tasks/capabilities/management.js +111 -0
- package/dist/src/tasks/capabilities/read.d.ts +2 -0
- package/dist/src/tasks/capabilities/read.js +141 -0
- package/dist/src/tasks/capabilities/relations.d.ts +204 -0
- package/dist/src/tasks/capabilities/relations.js +140 -0
- package/dist/src/tasks/capabilities/runs.d.ts +2 -0
- package/dist/src/tasks/capabilities/runs.js +89 -0
- package/dist/src/tasks/capabilities/write.d.ts +207 -0
- package/dist/src/tasks/capabilities/write.js +107 -0
- package/dist/src/tasks/home-query-service.js +3 -2
- package/dist/src/tasks/index.d.ts +0 -1
- package/dist/src/tasks/index.js +9 -9
- package/dist/src/tasks/project-operating-view-service.js +2 -1
- package/dist/src/tasks/task-application-service.d.ts +1 -0
- package/dist/src/tasks/task-application-service.js +3 -2
- package/dist/src/tasks/task-change-events.js +5 -3
- package/dist/src/tasks/task-context-assembler.js +2 -1
- package/dist/src/tasks/task-deletion-service.js +2 -1
- package/dist/src/tasks/task-dependency-service.js +2 -1
- package/dist/src/tasks/task-handoff-service.js +2 -1
- package/dist/src/tasks/task-read-model-projector.js +2 -1
- package/dist/src/tasks/task-repository.d.ts +12 -7
- package/dist/src/tasks/task-repository.js +175 -154
- package/dist/src/tasks/task-run-coordinator.js +2 -1
- package/dist/src/tasks/task-run-dispatcher.js +2 -1
- package/dist/src/tasks/task-run-repository.d.ts +1 -0
- package/dist/src/tasks/task-run-repository.js +29 -14
- package/dist/src/tasks/task-signal-service.js +2 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/backends/gateway-realtime-backend.js +1 -1
- package/dist/src/tui/tui-commands.js +1 -1
- package/dist/src/user-context/config.d.ts +13 -0
- package/dist/src/user-context/config.js +2 -0
- package/dist/src/voice/platform-catalog.d.ts +1 -1
- package/dist/src/voice/realtime/runtime.js +3 -3
- package/dist/src/voice/stt/providers/alibaba-transcription.js +1 -1
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +1 -1
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +1 -1
- package/dist/src/work-discovery/incremental-repository.js +1 -1
- package/dist/src/work-discovery/index.js +1 -1
- package/dist/src/work-discovery/repository.d.ts +1 -1
- package/dist/src/work-discovery/repository.js +3 -2
- package/dist/src/work-discovery/service.d.ts +4 -0
- package/dist/src/work-discovery/service.js +36 -11
- package/dist/src/workflows/context/workflow-context.js +3 -2
- package/dist/src/workflows/service/workflow-run-service.js +2 -1
- package/package.json +6 -2
- package/skills/THIRD_PARTY_NOTICES.md +2 -2
- package/skills/documents/xlsx/SKILL.md +5 -0
- package/skills/engineering/build-xopc-local-app/SKILL.md +2 -0
- package/skills/tools/find-skills/SKILL.md +3 -0
- package/dist/gateway/static/root/assets/activity-store-DVUTs1fk.js +0 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-K3hTmu9d.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-CU52MfIT.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-ZpA1-6ad.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-IEAxKRME.js +0 -7
- package/dist/gateway/static/root/assets/browser-settings-page-CU4VWsmX.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-settings-panel-C9XQk3HL.js +0 -8
- package/dist/gateway/static/root/assets/channels-settings-Bqlhjooi.js +0 -1
- package/dist/gateway/static/root/assets/connector-service-page-BmH17JnO.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-zkx8Q-e6.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-settings-CE4GOlMM.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CdKJqnnw.js +0 -1
- package/dist/gateway/static/root/assets/files-Be5viEFY.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-CGOW0-b4.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-D4um_sV7.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-CgXp2zq4.js +0 -1
- package/dist/gateway/static/root/assets/home-page-D6Idk732.js +0 -1
- package/dist/gateway/static/root/assets/index-1wIKA-kM.css +0 -1
- package/dist/gateway/static/root/assets/index-PFQHPGgi.js +0 -79
- package/dist/gateway/static/root/assets/local-app-workbench-page-BmAqTRb4.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-ZjVYXXyM.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CSTkYVOZ.js +0 -1
- package/dist/gateway/static/root/assets/messages-4BtQKYlM.js +0 -3
- package/dist/gateway/static/root/assets/note-detail-panel-DuXCt-MM.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BjOgBVq5.js +0 -8
- package/dist/gateway/static/root/assets/product-delivery-CrAI8ZEa.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-0zi4-i9X.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-B18OxmJj.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-z-DxbuaE.js +0 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-DGsBTbo6.js +0 -5
- package/dist/gateway/static/root/assets/scenes-page-Bgba03B_.js +0 -1
- package/dist/gateway/static/root/assets/schemas-BaskVM5g.js +0 -64
- package/dist/gateway/static/root/assets/sessions-page-B1t3bMsm.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CBX0Ezhf.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Bw71C2X3.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-BoVDQolc.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DtTptpAt.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-vgkiGo-D.js +0 -1
- package/dist/gateway/static/root/assets/theme-store-CegIlB8d.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-CAGafNfP.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-CSxHVs1p.js +0 -6
- package/skills/creative/algorithmic-art/SKILL.md +0 -44
- package/skills/creative/algorithmic-art/templates/generator-template.js +0 -27
- package/skills/creative/algorithmic-art/templates/viewer.html +0 -27
|
@@ -5,6 +5,10 @@ export declare class AutomationAlreadyRunningError extends Error {
|
|
|
5
5
|
readonly runningRunId?: string;
|
|
6
6
|
constructor(automationId: string, runningRunId?: string);
|
|
7
7
|
}
|
|
8
|
+
export declare class AutomationAlreadyExistsError extends Error {
|
|
9
|
+
readonly automationId: string;
|
|
10
|
+
constructor(automationId: string);
|
|
11
|
+
}
|
|
8
12
|
export declare class AutomationService {
|
|
9
13
|
private readonly executor;
|
|
10
14
|
private timer;
|
|
@@ -21,16 +25,37 @@ export declare class AutomationService {
|
|
|
21
25
|
}): Promise<void>;
|
|
22
26
|
stop(): Promise<void>;
|
|
23
27
|
create(input: CreateAutomationInput): Promise<Automation>;
|
|
28
|
+
/** SQLite-only creation; scheduling starts after the caller commits. */
|
|
29
|
+
createAtomically(input: CreateAutomationInput): Automation;
|
|
30
|
+
private applyCreate;
|
|
24
31
|
list(options?: {
|
|
25
32
|
projectId?: string;
|
|
26
33
|
}): Promise<Automation[]>;
|
|
27
34
|
get(id: string): Promise<Automation | null>;
|
|
28
35
|
update(id: string, patch: UpdateAutomationInput): Promise<Automation | null>;
|
|
36
|
+
/** SQLite-only mutation; callers must refresh scheduling after their outer transaction commits. */
|
|
37
|
+
updateAtomically(id: string, patch: UpdateAutomationInput): Automation | null;
|
|
38
|
+
refreshSchedule(): void;
|
|
39
|
+
private applyUpdate;
|
|
29
40
|
remove(id: string): Promise<boolean>;
|
|
41
|
+
/** Persist deletion and cancellation intent together; never abort within a transaction. */
|
|
42
|
+
removeAtomically(id: string): {
|
|
43
|
+
removed: boolean;
|
|
44
|
+
automation?: Automation;
|
|
45
|
+
cancelRunId?: string;
|
|
46
|
+
};
|
|
47
|
+
finishRemoval(cancelRunId?: string): void;
|
|
30
48
|
pause(id: string): Promise<Automation | null>;
|
|
31
49
|
resume(id: string): Promise<Automation | null>;
|
|
32
50
|
runNow(id: string): Promise<AutomationRun>;
|
|
33
51
|
rerunFromRun(runId: string): Promise<AutomationRun>;
|
|
52
|
+
queueRerunAtomically(runId: string): AutomationRun;
|
|
53
|
+
queueRunAtomically(id: string, opts?: {
|
|
54
|
+
manual: boolean;
|
|
55
|
+
event?: AutomationEvent;
|
|
56
|
+
}): AutomationRun;
|
|
57
|
+
/** Claim before invoking external work; replays never restart running or completed runs. */
|
|
58
|
+
dispatchQueuedRun(runId: string): void;
|
|
34
59
|
triggerEvent(event: AutomationEvent): Promise<AutomationRun[]>;
|
|
35
60
|
listRuns(options?: {
|
|
36
61
|
automationId?: string;
|
|
@@ -51,11 +76,17 @@ export declare class AutomationService {
|
|
|
51
76
|
projectId?: string;
|
|
52
77
|
}): Promise<number>;
|
|
53
78
|
cancelRun(runId: string): Promise<boolean>;
|
|
79
|
+
dispatchCancellation(runId: string): void;
|
|
80
|
+
cancelRunAtomically(runId: string): {
|
|
81
|
+
cancelled: boolean;
|
|
82
|
+
confirmed: boolean;
|
|
83
|
+
};
|
|
54
84
|
getMetrics(): Promise<AutomationMetrics>;
|
|
55
85
|
private recomputeNextRuns;
|
|
56
86
|
private armTimer;
|
|
57
87
|
private onTimer;
|
|
58
88
|
private startRun;
|
|
89
|
+
private persistQueuedRun;
|
|
59
90
|
private executeRun;
|
|
60
91
|
private recoverInterruptedRuns;
|
|
61
92
|
private waitForRetry;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
4
|
-
import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedule.js";
|
|
5
4
|
import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
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";
|
|
9
7
|
import "../storage/index.js";
|
|
8
|
+
import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedule.js";
|
|
9
|
+
import { AutomationActionExecutor } from "./action-executor.js";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
//#region src/automations/service/automation-service.ts
|
|
12
12
|
init_logger();
|
|
@@ -31,6 +31,13 @@ var AutomationAlreadyRunningError = class extends Error {
|
|
|
31
31
|
this.name = "AutomationAlreadyRunningError";
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
+
var AutomationAlreadyExistsError = class extends Error {
|
|
35
|
+
constructor(automationId) {
|
|
36
|
+
super(`Automation already exists: ${automationId}`);
|
|
37
|
+
this.automationId = automationId;
|
|
38
|
+
this.name = "AutomationAlreadyExistsError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
34
41
|
var AutomationService = class {
|
|
35
42
|
executor = new AutomationActionExecutor();
|
|
36
43
|
timer = null;
|
|
@@ -68,6 +75,15 @@ var AutomationService = class {
|
|
|
68
75
|
log.info("Automation service stopped");
|
|
69
76
|
}
|
|
70
77
|
async create(input) {
|
|
78
|
+
const automation = this.createAtomically(input);
|
|
79
|
+
this.refreshSchedule();
|
|
80
|
+
return automation;
|
|
81
|
+
}
|
|
82
|
+
/** SQLite-only creation; scheduling starts after the caller commits. */
|
|
83
|
+
createAtomically(input) {
|
|
84
|
+
return runSqliteWriteTransaction(() => this.applyCreate(input));
|
|
85
|
+
}
|
|
86
|
+
applyCreate(input) {
|
|
71
87
|
const parsed = CreateAutomationSchema.parse(input);
|
|
72
88
|
const now = Date.now();
|
|
73
89
|
const automation = AutomationSchema.parse({
|
|
@@ -81,9 +97,10 @@ var AutomationService = class {
|
|
|
81
97
|
createdAtMs: now,
|
|
82
98
|
updatedAtMs: now
|
|
83
99
|
});
|
|
100
|
+
if (getAutomation(automation.id)) throw new AutomationAlreadyExistsError(automation.id);
|
|
101
|
+
automation.updatedAtMs = Math.max(automation.updatedAtMs, (getDeletedAutomationRevision(automation.id) ?? -1) + 1);
|
|
84
102
|
automation.state.nextRunAtMs = computeNextAutomationRunAtMs(automation, now);
|
|
85
103
|
saveAutomation(automation);
|
|
86
|
-
this.armTimer();
|
|
87
104
|
return automation;
|
|
88
105
|
}
|
|
89
106
|
async list(options) {
|
|
@@ -93,6 +110,18 @@ var AutomationService = class {
|
|
|
93
110
|
return getAutomation(id);
|
|
94
111
|
}
|
|
95
112
|
async update(id, patch) {
|
|
113
|
+
const automation = this.updateAtomically(id, patch);
|
|
114
|
+
this.refreshSchedule();
|
|
115
|
+
return automation;
|
|
116
|
+
}
|
|
117
|
+
/** SQLite-only mutation; callers must refresh scheduling after their outer transaction commits. */
|
|
118
|
+
updateAtomically(id, patch) {
|
|
119
|
+
return runSqliteWriteTransaction(() => this.applyUpdate(id, patch));
|
|
120
|
+
}
|
|
121
|
+
refreshSchedule() {
|
|
122
|
+
this.armTimer();
|
|
123
|
+
}
|
|
124
|
+
applyUpdate(id, patch) {
|
|
96
125
|
const parsed = UpdateAutomationSchema.parse(patch);
|
|
97
126
|
const current = getAutomation(id);
|
|
98
127
|
if (!current) return null;
|
|
@@ -102,7 +131,7 @@ var AutomationService = class {
|
|
|
102
131
|
...parsed,
|
|
103
132
|
id: current.id,
|
|
104
133
|
createdAtMs: current.createdAtMs,
|
|
105
|
-
updatedAtMs: now,
|
|
134
|
+
updatedAtMs: Math.max(now, current.updatedAtMs + 1),
|
|
106
135
|
state: {
|
|
107
136
|
...current.state,
|
|
108
137
|
...parsed.state ?? {}
|
|
@@ -110,15 +139,47 @@ var AutomationService = class {
|
|
|
110
139
|
});
|
|
111
140
|
if ("enabled" in parsed || "trigger" in parsed) next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, now);
|
|
112
141
|
saveAutomation(next);
|
|
113
|
-
this.armTimer();
|
|
114
142
|
return next;
|
|
115
143
|
}
|
|
116
144
|
async remove(id) {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const result = this.removeAtomically(id);
|
|
146
|
+
this.finishRemoval(result.cancelRunId);
|
|
147
|
+
return result.removed;
|
|
148
|
+
}
|
|
149
|
+
/** Persist deletion and cancellation intent together; never abort within a transaction. */
|
|
150
|
+
removeAtomically(id) {
|
|
151
|
+
return runSqliteWriteTransaction(() => {
|
|
152
|
+
const automation = getAutomation(id);
|
|
153
|
+
if (!automation) return { removed: false };
|
|
154
|
+
const run = automation.state.runningRunId ? getAutomationRun(automation.state.runningRunId) : null;
|
|
155
|
+
let cancelRunId;
|
|
156
|
+
if (run?.automationId === id && [
|
|
157
|
+
"queued",
|
|
158
|
+
"running",
|
|
159
|
+
"cancelling"
|
|
160
|
+
].includes(run.status)) {
|
|
161
|
+
cancelRunId = run.id;
|
|
162
|
+
if (run.status !== "cancelling") {
|
|
163
|
+
const cancelling = {
|
|
164
|
+
...run,
|
|
165
|
+
status: "cancelling",
|
|
166
|
+
currentPhase: "cancelling",
|
|
167
|
+
cancelRequestedAtMs: Date.now()
|
|
168
|
+
};
|
|
169
|
+
saveAutomationRun(cancelling);
|
|
170
|
+
this.appendRunEvent(cancelling, "run.cancel_requested", "Automation deletion requested cancellation", { reason: "automation_deleted" });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
removed: deleteAutomation(id),
|
|
175
|
+
automation,
|
|
176
|
+
cancelRunId
|
|
177
|
+
};
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
finishRemoval(cancelRunId) {
|
|
181
|
+
if (cancelRunId) this.activeRuns.get(cancelRunId)?.abort(/* @__PURE__ */ new Error("Automation was deleted by the user"));
|
|
182
|
+
this.refreshSchedule();
|
|
122
183
|
}
|
|
123
184
|
async pause(id) {
|
|
124
185
|
return this.update(id, { enabled: false });
|
|
@@ -127,22 +188,66 @@ var AutomationService = class {
|
|
|
127
188
|
return this.update(id, { enabled: true });
|
|
128
189
|
}
|
|
129
190
|
async runNow(id) {
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return this.startRun(automation, { manual: true });
|
|
191
|
+
const run = this.queueRunAtomically(id);
|
|
192
|
+
this.dispatchQueuedRun(run.id);
|
|
193
|
+
return run;
|
|
134
194
|
}
|
|
135
195
|
async rerunFromRun(runId) {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
event
|
|
145
|
-
|
|
196
|
+
const run = this.queueRerunAtomically(runId);
|
|
197
|
+
this.dispatchQueuedRun(run.id);
|
|
198
|
+
return run;
|
|
199
|
+
}
|
|
200
|
+
queueRerunAtomically(runId) {
|
|
201
|
+
return runSqliteWriteTransaction(() => {
|
|
202
|
+
const previous = getAutomationRun(runId);
|
|
203
|
+
if (!previous) throw new Error(`Automation run not found: ${runId}`);
|
|
204
|
+
const event = listAutomationRunEvents(runId).map(readAutomationEventFromRunEvent).find((item) => item !== null);
|
|
205
|
+
return this.queueRunAtomically(previous.automationId, event ? {
|
|
206
|
+
manual: false,
|
|
207
|
+
event
|
|
208
|
+
} : { manual: true });
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
queueRunAtomically(id, opts = { manual: true }) {
|
|
212
|
+
return runSqliteWriteTransaction(() => {
|
|
213
|
+
const automation = getAutomation(id);
|
|
214
|
+
if (!automation) throw new Error(`Automation not found: ${id}`);
|
|
215
|
+
if (automation.state.runningRunId) throw new AutomationAlreadyRunningError(id, automation.state.runningRunId);
|
|
216
|
+
return this.persistQueuedRun(automation, opts);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
/** Claim before invoking external work; replays never restart running or completed runs. */
|
|
220
|
+
dispatchQueuedRun(runId) {
|
|
221
|
+
const claimed = runSqliteWriteTransaction(() => {
|
|
222
|
+
const run = getAutomationRun(runId);
|
|
223
|
+
if (!run || run.status !== "queued") return null;
|
|
224
|
+
const current = getAutomation(run.automationId);
|
|
225
|
+
if (!current || current.state.runningRunId !== run.id) return null;
|
|
226
|
+
const automation = getAutomationRunRequest(run.id);
|
|
227
|
+
if (!automation) throw new Error(`Execution configuration is missing for run: ${run.id}`);
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
const next = {
|
|
230
|
+
...run,
|
|
231
|
+
status: "running",
|
|
232
|
+
startedAtMs: now,
|
|
233
|
+
currentPhase: "action",
|
|
234
|
+
heartbeatAtMs: now,
|
|
235
|
+
leaseOwner: this.leaseOwner,
|
|
236
|
+
leaseExpiresAtMs: now + RUN_LEASE_DURATION_MS
|
|
237
|
+
};
|
|
238
|
+
saveAutomationRun(next);
|
|
239
|
+
return {
|
|
240
|
+
automation,
|
|
241
|
+
run: next
|
|
242
|
+
};
|
|
243
|
+
});
|
|
244
|
+
if (!claimed) return;
|
|
245
|
+
this.executeRun(claimed.automation, claimed.run).catch((err) => {
|
|
246
|
+
log.error({
|
|
247
|
+
err,
|
|
248
|
+
runId
|
|
249
|
+
}, "Queued automation run failed");
|
|
250
|
+
});
|
|
146
251
|
}
|
|
147
252
|
async triggerEvent(event) {
|
|
148
253
|
const normalized = {
|
|
@@ -177,22 +282,65 @@ var AutomationService = class {
|
|
|
177
282
|
return markAllAutomationRunsRead(options);
|
|
178
283
|
}
|
|
179
284
|
async cancelRun(runId) {
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
285
|
+
const result = this.cancelRunAtomically(runId);
|
|
286
|
+
if (result.cancelled) this.dispatchCancellation(runId);
|
|
287
|
+
return result.cancelled;
|
|
288
|
+
}
|
|
289
|
+
dispatchCancellation(runId) {
|
|
290
|
+
this.activeRuns.get(runId)?.abort(/* @__PURE__ */ new Error("Automation run was cancelled by the user"));
|
|
291
|
+
this.refreshSchedule();
|
|
292
|
+
}
|
|
293
|
+
cancelRunAtomically(runId) {
|
|
294
|
+
return runSqliteWriteTransaction(() => {
|
|
295
|
+
const current = getAutomationRun(runId);
|
|
296
|
+
if (!current || ![
|
|
297
|
+
"queued",
|
|
298
|
+
"running",
|
|
299
|
+
"cancelling"
|
|
300
|
+
].includes(current.status)) return {
|
|
301
|
+
cancelled: false,
|
|
302
|
+
confirmed: false
|
|
303
|
+
};
|
|
304
|
+
const now = Date.now();
|
|
305
|
+
if (current.status !== "queued") {
|
|
306
|
+
if (current.status === "running") {
|
|
307
|
+
const cancelling = {
|
|
308
|
+
...current,
|
|
309
|
+
status: "cancelling",
|
|
310
|
+
currentPhase: "cancelling",
|
|
311
|
+
cancelRequestedAtMs: now
|
|
312
|
+
};
|
|
313
|
+
saveAutomationRun(cancelling);
|
|
314
|
+
this.appendRunEvent(cancelling, "run.cancel_requested", "Automation cancellation requested", { reason: "user_cancelled" });
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
cancelled: true,
|
|
318
|
+
confirmed: false
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
const cancelled = {
|
|
186
322
|
...current,
|
|
187
|
-
status: "
|
|
188
|
-
currentPhase: "
|
|
189
|
-
|
|
323
|
+
status: "cancelled",
|
|
324
|
+
currentPhase: "completed",
|
|
325
|
+
endedAtMs: now,
|
|
326
|
+
cancelRequestedAtMs: now,
|
|
327
|
+
cancelConfirmedAtMs: now,
|
|
328
|
+
termination: {
|
|
329
|
+
reason: "user_cancelled",
|
|
330
|
+
component: "automation",
|
|
331
|
+
cancellationConfirmed: true
|
|
332
|
+
}
|
|
190
333
|
};
|
|
191
|
-
saveAutomationRun(
|
|
192
|
-
this.appendRunEvent(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
334
|
+
saveAutomationRun(cancelled);
|
|
335
|
+
this.appendRunEvent(cancelled, "run.cancel_requested", "Queued automation cancellation requested");
|
|
336
|
+
this.appendRunEvent(cancelled, "run.cancel_confirmed", "Queued automation cancelled before execution");
|
|
337
|
+
this.appendRunEvent(cancelled, "run.completed", "Automation run cancelled", { status: "cancelled" });
|
|
338
|
+
this.finishAutomationRun(current.automationId, runId, "cancelled", void 0, now);
|
|
339
|
+
return {
|
|
340
|
+
cancelled: true,
|
|
341
|
+
confirmed: true
|
|
342
|
+
};
|
|
343
|
+
});
|
|
196
344
|
}
|
|
197
345
|
async getMetrics() {
|
|
198
346
|
const automations = listAutomations();
|
|
@@ -235,7 +383,7 @@ var AutomationService = class {
|
|
|
235
383
|
clearTimeout(this.timer);
|
|
236
384
|
this.timer = null;
|
|
237
385
|
}
|
|
238
|
-
const next = listAutomations().filter((automation) => automation.enabled && automation.state.nextRunAtMs != null).toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];
|
|
386
|
+
const next = listAutomations().filter((automation) => automation.enabled && automation.state.nextRunAtMs != null && !automation.state.runningRunId).toSorted((a, b) => (a.state.nextRunAtMs ?? 0) - (b.state.nextRunAtMs ?? 0))[0];
|
|
239
387
|
if (!next?.state.nextRunAtMs) return;
|
|
240
388
|
this.timer = setTimeout(() => {
|
|
241
389
|
this.onTimer();
|
|
@@ -259,6 +407,11 @@ var AutomationService = class {
|
|
|
259
407
|
}
|
|
260
408
|
}
|
|
261
409
|
async startRun(automation, opts) {
|
|
410
|
+
const run = this.queueRunAtomically(automation.id, opts);
|
|
411
|
+
this.dispatchQueuedRun(run.id);
|
|
412
|
+
return run;
|
|
413
|
+
}
|
|
414
|
+
persistQueuedRun(automation, opts) {
|
|
262
415
|
const now = Date.now();
|
|
263
416
|
const run = {
|
|
264
417
|
id: randomUUID(),
|
|
@@ -279,27 +432,20 @@ var AutomationService = class {
|
|
|
279
432
|
safety: automation.safety ?? { mode: "auto_apply" },
|
|
280
433
|
event: opts.event
|
|
281
434
|
});
|
|
282
|
-
|
|
435
|
+
saveAutomation({
|
|
283
436
|
...automation,
|
|
284
437
|
state: {
|
|
285
438
|
...automation.state,
|
|
286
439
|
runningRunId: run.id
|
|
287
440
|
}
|
|
288
|
-
};
|
|
289
|
-
saveAutomation(nextAutomation);
|
|
290
|
-
this.executeRun(nextAutomation, run).catch((err) => {
|
|
291
|
-
log.error({
|
|
292
|
-
err,
|
|
293
|
-
automationId: automation.id,
|
|
294
|
-
runId: run.id
|
|
295
|
-
}, `Automation run failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
296
441
|
});
|
|
442
|
+
saveAutomationRunRequest(run.id, automation);
|
|
297
443
|
return run;
|
|
298
444
|
}
|
|
299
445
|
async executeRun(automation, initialRun) {
|
|
300
446
|
const controller = new AbortController();
|
|
301
447
|
this.activeRuns.set(initialRun.id, controller);
|
|
302
|
-
const startedAtMs = Date.now();
|
|
448
|
+
const startedAtMs = initialRun.startedAtMs ?? Date.now();
|
|
303
449
|
let run = {
|
|
304
450
|
...initialRun,
|
|
305
451
|
status: "running",
|
|
@@ -400,7 +546,7 @@ var AutomationService = class {
|
|
|
400
546
|
};
|
|
401
547
|
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 });
|
|
402
548
|
}
|
|
403
|
-
if (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" } });
|
|
549
|
+
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" } });
|
|
404
550
|
else if (automation.completionWebhookUrl) {
|
|
405
551
|
activePhase = "completion_hook";
|
|
406
552
|
run = {
|
|
@@ -413,6 +559,11 @@ var AutomationService = class {
|
|
|
413
559
|
this.appendRunEvent(run, "completion_hook.completed", "Completion webhook completed");
|
|
414
560
|
}
|
|
415
561
|
} catch (err) {
|
|
562
|
+
const persistedRun = getAutomationRun(run.id);
|
|
563
|
+
if (persistedRun) run = {
|
|
564
|
+
...run,
|
|
565
|
+
...persistedRun
|
|
566
|
+
};
|
|
416
567
|
error = err instanceof Error ? err.message : String(err);
|
|
417
568
|
const deadlineExceeded = err instanceof AutomationDeadlineExceededError || run.deadlineAtMs !== void 0 && Date.now() >= run.deadlineAtMs;
|
|
418
569
|
status = controller.signal.aborted ? "cancelled" : deadlineExceeded ? "timeout" : "failed";
|
|
@@ -453,8 +604,9 @@ var AutomationService = class {
|
|
|
453
604
|
durationMs: run.durationMs,
|
|
454
605
|
error
|
|
455
606
|
});
|
|
456
|
-
this.finishAutomationRun(automation.id, status, error, endedAtMs);
|
|
607
|
+
this.finishAutomationRun(automation.id, run.id, status, error, endedAtMs);
|
|
457
608
|
});
|
|
609
|
+
this.refreshSchedule();
|
|
458
610
|
try {
|
|
459
611
|
this.deps.onRunCompleted?.(run);
|
|
460
612
|
} catch (err) {
|
|
@@ -467,25 +619,12 @@ var AutomationService = class {
|
|
|
467
619
|
}
|
|
468
620
|
}
|
|
469
621
|
async recoverInterruptedRuns() {
|
|
470
|
-
const recoverable =
|
|
622
|
+
const recoverable = listUnfinishedAutomationRuns();
|
|
471
623
|
for (const run of recoverable) {
|
|
472
624
|
const automation = getAutomation(run.automationId);
|
|
473
|
-
if (run.status === "queued" && automation) {
|
|
474
|
-
const claimed = {
|
|
475
|
-
...automation,
|
|
476
|
-
state: {
|
|
477
|
-
...automation.state,
|
|
478
|
-
runningRunId: run.id
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
saveAutomation(claimed);
|
|
625
|
+
if (run.status === "queued" && automation?.state.runningRunId === run.id && getAutomationRunRequest(run.id)) {
|
|
482
626
|
this.appendRunEvent(run, "run.recovered", "Queued automation run recovered after restart", { previousLeaseOwner: run.leaseOwner });
|
|
483
|
-
this.
|
|
484
|
-
log.error({
|
|
485
|
-
err,
|
|
486
|
-
runId: run.id
|
|
487
|
-
}, "Recovered automation run failed");
|
|
488
|
-
});
|
|
627
|
+
this.dispatchQueuedRun(run.id);
|
|
489
628
|
continue;
|
|
490
629
|
}
|
|
491
630
|
const now = Date.now();
|
|
@@ -516,7 +655,7 @@ var AutomationService = class {
|
|
|
516
655
|
status,
|
|
517
656
|
error
|
|
518
657
|
});
|
|
519
|
-
if (automation) this.finishAutomationRun(automation.id, status, error, now);
|
|
658
|
+
if (automation) this.finishAutomationRun(automation.id, run.id, status, error, now);
|
|
520
659
|
}
|
|
521
660
|
}
|
|
522
661
|
waitForRetry(delayMs, signal) {
|
|
@@ -544,9 +683,9 @@ var AutomationService = class {
|
|
|
544
683
|
createdAtMs: Date.now()
|
|
545
684
|
});
|
|
546
685
|
}
|
|
547
|
-
finishAutomationRun(automationId, status, error, finishedAtMs) {
|
|
686
|
+
finishAutomationRun(automationId, runId, status, error, finishedAtMs) {
|
|
548
687
|
const current = getAutomation(automationId);
|
|
549
|
-
if (!current) return;
|
|
688
|
+
if (!current || current.state.runningRunId !== runId) return;
|
|
550
689
|
const consecutiveFailures = status === "failed" || status === "timeout" ? (current.state.consecutiveFailures ?? 0) + 1 : 0;
|
|
551
690
|
const disableAfter = current.reliability?.disableAfterConsecutiveFailures;
|
|
552
691
|
const shouldDisable = disableAfter != null && consecutiveFailures >= disableAfter;
|
|
@@ -560,12 +699,11 @@ var AutomationService = class {
|
|
|
560
699
|
lastError: error,
|
|
561
700
|
consecutiveFailures
|
|
562
701
|
},
|
|
563
|
-
updatedAtMs: shouldDisable ? finishedAtMs : current.updatedAtMs
|
|
702
|
+
updatedAtMs: shouldDisable ? Math.max(finishedAtMs, current.updatedAtMs + 1) : current.updatedAtMs
|
|
564
703
|
};
|
|
565
704
|
delete next.state.runningRunId;
|
|
566
705
|
next.state.nextRunAtMs = computeNextAutomationRunAtMs(next, finishedAtMs);
|
|
567
706
|
saveAutomation(next);
|
|
568
|
-
this.armTimer();
|
|
569
707
|
}
|
|
570
708
|
async postCompletionWebhook(url, run, signal) {
|
|
571
709
|
const remainingMs = run.deadlineAtMs === void 0 ? 3e4 : Math.max(1, run.deadlineAtMs - Date.now());
|
|
@@ -611,4 +749,4 @@ function readAutomationEventFromRunEvent(event) {
|
|
|
611
749
|
};
|
|
612
750
|
}
|
|
613
751
|
//#endregion
|
|
614
|
-
export { AutomationAlreadyRunningError, AutomationService };
|
|
752
|
+
export { AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationService };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AutomationActionExecutor } from "./action-executor.js";
|
|
2
|
-
import { AutomationAlreadyRunningError, AutomationService } from "./automation-service.js";
|
|
3
|
-
export { AutomationActionExecutor, AutomationAlreadyRunningError, AutomationService };
|
|
2
|
+
import { AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationService } from "./automation-service.js";
|
|
3
|
+
export { AutomationActionExecutor, AutomationAlreadyExistsError, AutomationAlreadyRunningError, AutomationService };
|
|
@@ -6,3 +6,5 @@ export declare function getAutomation(automationId: string): Automation | null;
|
|
|
6
6
|
export declare function saveAutomation(automation: Automation): void;
|
|
7
7
|
export declare function saveAutomations(automations: Automation[]): void;
|
|
8
8
|
export declare function deleteAutomation(automationId: string): boolean;
|
|
9
|
+
/** Keep revisions distinct when a caller recreates a previously deleted identity. */
|
|
10
|
+
export declare function getDeletedAutomationRevision(automationId: string): number | undefined;
|
|
@@ -59,8 +59,16 @@ function saveAutomations(automations) {
|
|
|
59
59
|
}
|
|
60
60
|
function deleteAutomation(automationId) {
|
|
61
61
|
return runSqliteWriteTransaction((db) => {
|
|
62
|
+
db.prepare(`INSERT INTO automation_deleted_revisions (automation_id, revision)
|
|
63
|
+
SELECT automation_id, updated_at_ms FROM automations WHERE automation_id = ?
|
|
64
|
+
ON CONFLICT(automation_id) DO UPDATE SET revision = MAX(revision, excluded.revision)`).run(automationId);
|
|
62
65
|
return db.prepare(`DELETE FROM automations WHERE automation_id = ?`).run(automationId).changes > 0;
|
|
63
66
|
});
|
|
64
67
|
}
|
|
68
|
+
/** Keep revisions distinct when a caller recreates a previously deleted identity. */
|
|
69
|
+
function getDeletedAutomationRevision(automationId) {
|
|
70
|
+
const row = getSqliteDatabase().prepare("SELECT revision FROM automation_deleted_revisions WHERE automation_id = ?").get(automationId);
|
|
71
|
+
return row ? Number(row.revision) : void 0;
|
|
72
|
+
}
|
|
65
73
|
//#endregion
|
|
66
|
-
export { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations };
|
|
74
|
+
export { deleteAutomation, getAutomation, getDeletedAutomationRevision, listAutomations, saveAutomation, saveAutomations };
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { AutomationProductEventRun, AutomationRun, AutomationRunEvent } from '../domain/types.js';
|
|
1
|
+
import type { Automation, AutomationProductEventRun, AutomationRun, AutomationRunEvent } from '../domain/types.js';
|
|
2
|
+
export declare function saveAutomationRunRequest(runId: string, automation: Automation): void;
|
|
3
|
+
export declare function getAutomationRunRequest(runId: string): Automation | null;
|
|
4
|
+
export declare function listUnfinishedAutomationRuns(): AutomationRun[];
|
|
2
5
|
export declare function appendAutomationRunEvent(event: AutomationRunEvent): void;
|
|
3
6
|
export declare function saveAutomationRun(run: AutomationRun): void;
|
|
4
7
|
export declare function touchAutomationRunLease(runId: string, leaseOwner: string, heartbeatAtMs: number, leaseExpiresAtMs: number): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
|
|
2
|
+
import { AutomationSchema } from "../domain/validation.js";
|
|
2
3
|
//#region src/automations/storage/automation-run-repository.ts
|
|
3
4
|
init_transaction();
|
|
4
5
|
const MAX_RUNS_PER_AUTOMATION = 2e3;
|
|
@@ -48,13 +49,24 @@ function rowToEvent(row) {
|
|
|
48
49
|
function trimRuns(db, automationId) {
|
|
49
50
|
const countRow = db.prepare(`SELECT COUNT(*) AS count FROM automation_runs WHERE automation_id = ?`).get(automationId);
|
|
50
51
|
if (countRow.count <= MAX_RUNS_PER_AUTOMATION) return;
|
|
51
|
-
const staleRunIds = db.prepare(`SELECT run_id FROM automation_runs WHERE automation_id = ?
|
|
52
|
+
const staleRunIds = db.prepare(`SELECT run_id FROM automation_runs WHERE automation_id = ? AND status NOT IN ('queued', 'running', 'cancelling')
|
|
52
53
|
ORDER BY created_at_ms ASC LIMIT ?`).all(automationId, countRow.count - TRIM_TO_RUNS);
|
|
53
54
|
for (const { run_id: runId } of staleRunIds) {
|
|
55
|
+
db.prepare("DELETE FROM automation_run_requests WHERE run_id = ?").run(runId);
|
|
54
56
|
db.prepare(`DELETE FROM automation_run_events WHERE run_id = ?`).run(runId);
|
|
55
57
|
db.prepare(`DELETE FROM automation_runs WHERE run_id = ?`).run(runId);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
60
|
+
function saveAutomationRunRequest(runId, automation) {
|
|
61
|
+
getSqliteDatabase().prepare("INSERT INTO automation_run_requests (run_id, automation_json) VALUES (?, ?)").run(runId, JSON.stringify(automation));
|
|
62
|
+
}
|
|
63
|
+
function getAutomationRunRequest(runId) {
|
|
64
|
+
const row = getSqliteDatabase().prepare("SELECT automation_json FROM automation_run_requests WHERE run_id = ?").get(runId);
|
|
65
|
+
return row ? AutomationSchema.parse(JSON.parse(String(row.automation_json))) : null;
|
|
66
|
+
}
|
|
67
|
+
function listUnfinishedAutomationRuns() {
|
|
68
|
+
return getSqliteDatabase().prepare("SELECT * FROM automation_runs WHERE status IN ('queued', 'running', 'cancelling') ORDER BY created_at_ms ASC").all().map(rowToRun);
|
|
69
|
+
}
|
|
58
70
|
function appendAutomationRunEvent(event) {
|
|
59
71
|
runSqliteWriteTransaction((db) => {
|
|
60
72
|
db.prepare(`INSERT INTO automation_run_events (
|
|
@@ -163,12 +175,13 @@ function listAutomationRunsForProductEvent(options) {
|
|
|
163
175
|
}
|
|
164
176
|
function deleteAutomationRunsForAutomation(automationId) {
|
|
165
177
|
runSqliteWriteTransaction((db) => {
|
|
178
|
+
db.prepare("DELETE FROM automation_run_requests WHERE run_id IN (SELECT run_id FROM automation_runs WHERE automation_id = ?)").run(automationId);
|
|
166
179
|
db.prepare(`DELETE FROM automation_run_events WHERE automation_id = ?`).run(automationId);
|
|
167
180
|
db.prepare(`DELETE FROM automation_runs WHERE automation_id = ?`).run(automationId);
|
|
168
181
|
});
|
|
169
182
|
}
|
|
170
183
|
function markAutomationRunRead(runId, readAtMs = Date.now()) {
|
|
171
|
-
return getSqliteDatabase().prepare(`UPDATE automation_runs SET read_at_ms = ? WHERE run_id = ? AND ended_at_ms IS NOT NULL`).run(readAtMs, runId).changes > 0;
|
|
184
|
+
return getSqliteDatabase().prepare(`UPDATE automation_runs SET read_at_ms = COALESCE(read_at_ms, ?) WHERE run_id = ? AND ended_at_ms IS NOT NULL`).run(readAtMs, runId).changes > 0;
|
|
172
185
|
}
|
|
173
186
|
function markAllAutomationRunsRead(options) {
|
|
174
187
|
const projectId = options?.projectId?.trim();
|
|
@@ -183,4 +196,4 @@ function markAllAutomationRunsRead(options) {
|
|
|
183
196
|
return Number(result.changes);
|
|
184
197
|
}
|
|
185
198
|
//#endregion
|
|
186
|
-
export { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease };
|
|
199
|
+
export { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, getAutomationRunRequest, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listUnfinishedAutomationRuns, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, saveAutomationRunRequest, touchAutomationRunLease };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "./automation-repository.js";
|
|
2
|
-
import { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, touchAutomationRunLease } from "./automation-run-repository.js";
|
|
3
|
-
export { appendAutomationRunEvent, deleteAutomation, deleteAutomationRunsForAutomation, getAutomation, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listAutomations, markAllAutomationRunsRead, markAutomationRunRead, saveAutomation, saveAutomationRun, saveAutomations, touchAutomationRunLease };
|
|
1
|
+
import { deleteAutomation, getAutomation, getDeletedAutomationRevision, listAutomations, saveAutomation, saveAutomations } from "./automation-repository.js";
|
|
2
|
+
import { appendAutomationRunEvent, deleteAutomationRunsForAutomation, getAutomationRun, getAutomationRunRequest, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listUnfinishedAutomationRuns, markAllAutomationRunsRead, markAutomationRunRead, saveAutomationRun, saveAutomationRunRequest, touchAutomationRunLease } from "./automation-run-repository.js";
|
|
3
|
+
export { appendAutomationRunEvent, deleteAutomation, deleteAutomationRunsForAutomation, getAutomation, getAutomationRun, getAutomationRunRequest, getDeletedAutomationRevision, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, listAutomations, listUnfinishedAutomationRuns, markAllAutomationRunsRead, markAutomationRunRead, saveAutomation, saveAutomationRun, saveAutomationRunRequest, saveAutomations, touchAutomationRunLease };
|
|
@@ -7,8 +7,8 @@ export declare const BrowserAutomationDefinitionSchema: z.ZodObject<{
|
|
|
7
7
|
risk: z.ZodEnum<{
|
|
8
8
|
read: "read";
|
|
9
9
|
draft: "draft";
|
|
10
|
-
sensitive: "sensitive";
|
|
11
10
|
destructive: "destructive";
|
|
11
|
+
sensitive: "sensitive";
|
|
12
12
|
external_effect: "external_effect";
|
|
13
13
|
}>;
|
|
14
14
|
inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
@@ -25,7 +25,7 @@ export declare class BrowserAutomationService {
|
|
|
25
25
|
id: string;
|
|
26
26
|
name: string;
|
|
27
27
|
allowedDomains: string[];
|
|
28
|
-
risk: "read" | "draft" | "
|
|
28
|
+
risk: "read" | "draft" | "destructive" | "sensitive" | "external_effect";
|
|
29
29
|
inputs: Record<string, {
|
|
30
30
|
type: "string" | "number" | "boolean";
|
|
31
31
|
required?: boolean;
|
|
@@ -15,6 +15,10 @@ function formatBrowserObservation(observation) {
|
|
|
15
15
|
const { added, changed, removed } = observation.changes;
|
|
16
16
|
if (added.length || changed.length || removed.length) lines.push(`Changes: +${added.length} ~${changed.length} -${removed.length}`);
|
|
17
17
|
if (observation.visual) lines.push("Visual screenshot attached.");
|
|
18
|
+
if (observation.truncation) {
|
|
19
|
+
const omitted = observation.truncation.omittedNodeCount;
|
|
20
|
+
lines.push(`Transport note: observation was reduced for delivery${omitted ? `; ${omitted} interactive elements omitted` : ""}.`);
|
|
21
|
+
}
|
|
18
22
|
return lines.join("\n");
|
|
19
23
|
}
|
|
20
24
|
function formatNode(node) {
|