@xopcai/xopc 0.0.178 → 0.0.180
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/{activity-store-BzGX__8I.js → activity-store-DFKtQDgE.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BzxntcaZ.js → agent-avatar-dicebear-CcTvB_4W.js} +1 -1
- package/dist/gateway/static/root/assets/agents-DgGj9bu6.js +2 -0
- package/dist/gateway/static/root/assets/{api-hi6f2Xtp.js → api-CUClAvuL.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-fTY1F7ac.js → app-management-settings-panel-Ib-cWKHM.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BZ-IxQfB.js → appearance-settings-CRSN8WuA.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-B5xahuT-.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-ZSLLG8wB.js → archive-plugin-BBF9zspN.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-D4YktqIF.js → attachment-load-D3QQfA7w.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-BUYrvMmD.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BIkPxfxj.js → binary-plugins-D78XOjJ3.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Q3v_YQom.js → block-editor-D_VVXlYX.js} +46 -46
- package/dist/gateway/static/root/assets/browser-settings-page-Cjw07q9h.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-M5lTEW1I.js → browser-workflow-inputs-_gu08MA4.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-B3T1KYk4.js → browser-workflows-page-58DBMXgG.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-D_dfVxHY.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-DE09c0VB.js → capability-presets-api-DhCn9rPv.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-LWWIYUT7.js +1 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-CFR5FBfS.js → channel-recipient-api-DYtoNV5A.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Cyj5OunL.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-TEFnV0IG.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-B1mD-3pM.js → connector-logo-CxIXnifA.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-0TobCpBB.js +2 -0
- package/dist/gateway/static/root/assets/desktop-pet-CwVSLL6N.js +1 -0
- package/dist/gateway/static/root/assets/desktop-pet-settings-BOIp4q0Z.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-BYQJ2XUS.js → directory-picker-path-field-C8_lsW6S.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-BXcb8fwx.js → dreaming-settings-Da9FeWQl.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-O1Xu1r4Q.js → extension-debug-page-CMNnSJP6.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C2Jraq8l.js → extension-page-t0pJqLvM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DcXQDTpG.js → extension-settings-page-aiR-tKnW.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DmPIZrvg.js → gateway-config-api-CkyQBD6r.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-BIZfAgfB.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BZEkOdPm.js → gateway-startup-retry-CSU7UvzG.js} +1 -1
- package/dist/gateway/static/root/assets/goals-settings-Dx9uTyWF.js +1 -0
- package/dist/gateway/static/root/assets/{heartbeat-settings-BtKu2NWT.js → heartbeat-settings-Cnr5ORXL.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-05Gg8wsU.js → image-generation-api-BR6Kb77X.js} +1 -1
- package/dist/gateway/static/root/assets/index-B0Tdge_q.css +1 -0
- package/dist/gateway/static/root/assets/index-BA56bQ68.js +224 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CfmDR9Sc.js → keyboard-shortcuts-settings-D76uYKeQ.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DSUNtLHg.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-Df8BW1A_.js → local-apps-page-BsLnojTh.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CTwSy7yW.js → locale-store-BNC8HUCI.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-yI8kpQtO.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-B3FvKbaP.js → markdown-split-D6smTQWD.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DsjrvvB6.js → media-plugins-D1TmMF0A.js} +1 -1
- package/dist/gateway/static/root/assets/messages-H_iJjnEM.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-tuzIwy3c.js → notes-page-Vt-diFf0.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-BD297EZt.js +4 -0
- package/dist/gateway/static/root/assets/outcome-detail-page-C5i_ZR9a.js +1 -0
- package/dist/gateway/static/root/assets/{page-tabs-ke9s4nYi.js → page-tabs-BnSzIjH0.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-Cp1eI4S9.js → preview-open-alternatives-CF12Eqi4.js} +1 -1
- package/dist/gateway/static/root/assets/product-delivery-BVG-eWQO.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-dXQCMAtH.js → product-open-page-Du0TE_CU.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-D1HGz7Dy.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CqP2TnW-.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BXdVJLS3.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-Bl30zjHc.js → save-bar-controls-B53UNtDM.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-DqhmXQKo.js → schedule-field-C3dIMN5q.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-DkUCy6vf.js → schema-form-BKvpxqof.js} +1 -1
- package/dist/gateway/static/root/assets/{schemas-DgQq6Z5S.js → schemas-C6onAggk.js} +2 -2
- package/dist/gateway/static/root/assets/sessions-page-CPAwDdl5.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-C-jGsoft.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-C6ZbNpdy.js → settings-form-section-kt6GIS32.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-Bk58_cr7.js → settings-loading-skeleton-85eUPcKz.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-k8iE_NdX.js → settings-page-Di5x6Xrc.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-DgFSya2e.js → settings-page-layout-CkkCee_x.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-B_KDlyZA.js → setup-status-panel-uxEE6gAB.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CV7nL_J9.js → share-preview-page-BtLEstaI.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-2mcsMWgn.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-ocDwsrEt.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-9_jfsFU5.js +2 -0
- package/dist/gateway/static/root/assets/{skills-page.utils-kahBIHg0.js → skills-page.utils-C2SHvq8V.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-JV3-MG5F.js → system-settings-panel-CIJ66cUy.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-DFLyzoLO.js → theme-store-ClDa_Bci.js} +1 -1
- package/dist/gateway/static/root/assets/time-picker-D0zAsHOo.js +1 -0
- package/dist/gateway/static/root/assets/{typed-models-lib-60Aqo-UJ.js → typed-models-lib-GsmwmB40.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CnTkHDnw.js → use-channel-catalog-BQz3K7xj.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-Bn4BLg4W.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-CNa8qUgS.js → voice-api-key-field-Blaxsbb3.js} +1 -1
- package/dist/gateway/static/root/assets/work-copy-Cwyan9Sn.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-iJ9RBSpu.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-CqTH7PQX.js +1 -0
- package/dist/gateway/static/root/assets/work-page-H3m99ccS.js +3 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-yV_x595t.js → workflow-run-setup-panel-CTG4RpRE.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BxZSKMfv.js +11 -0
- package/dist/gateway/static/root/index.html +9 -10
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/outcomes.js +137 -0
- package/dist/packages/gateway-contract/src/product-delivery.js +1 -0
- package/dist/packages/gateway-contract/src/work-intake.js +85 -0
- package/dist/src/activity/service.d.ts +1 -0
- package/dist/src/activity/service.js +4 -1
- package/dist/src/agent/agent-manager.d.ts +4 -1
- package/dist/src/agent/agent-manager.js +21 -7
- package/dist/src/agent/bootstrap/filter-bootstrap-files.js +1 -1
- package/dist/src/agent/code-intelligence/binary.js +1 -1
- package/dist/src/agent/context/execution-scope.d.ts +1 -1
- package/dist/src/agent/context/execution-scope.js +6 -4
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.d.ts +2 -0
- package/dist/src/agent/embedded/run-for-session.js +3 -1
- package/dist/src/agent/goals/post-turn.js +7 -6
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +6 -1
- package/dist/src/agent/inbound/turn-dispatcher.js +5 -2
- package/dist/src/agent/ipc/inbox.js +1 -1
- package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -0
- package/dist/src/agent/lifecycle/timeout-wrapper.js +39 -9
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -2
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +6 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +1 -1
- package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.d.ts +2 -0
- package/dist/src/agent/mcp/mcp-transport-config.js +10 -3
- package/dist/src/agent/mcp/mcp-transport.d.ts +1 -0
- package/dist/src/agent/mcp/mcp-transport.js +5 -2
- package/dist/src/agent/memory/dreaming/config.js +1 -1
- package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -0
- package/dist/src/agent/memory/user-context-coordinator.js +17 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.d.ts +1 -1
- package/dist/src/agent/orchestration/run-agent-turn-with-timeout.js +6 -2
- package/dist/src/agent/outcomes/{task-evaluation.d.ts → execution-evaluation.d.ts} +3 -3
- package/dist/src/agent/outcomes/{task-evaluation.js → execution-evaluation.js} +5 -5
- package/dist/src/agent/outcomes/execution-verifier.d.ts +29 -0
- package/dist/src/agent/outcomes/{task-verifier.js → execution-verifier.js} +4 -4
- package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -0
- package/dist/src/agent/service/direct-turn-helpers.js +1 -0
- package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -0
- package/dist/src/agent/service/process-direct-one-shot.js +4 -1
- package/dist/src/agent/service/process-direct-streaming.js +3 -1
- package/dist/src/agent/service.d.ts +1 -0
- package/dist/src/agent/service.js +5 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +6 -0
- package/dist/src/agent/skills/filesystem-watcher.d.ts +4 -0
- package/dist/src/agent/skills/filesystem-watcher.js +16 -7
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/index.d.ts +10 -7
- package/dist/src/agent/skills/index.js +56 -47
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.d.ts +5 -2
- package/dist/src/agent/skills/skill-manager.js +10 -5
- package/dist/src/agent/skills/skill-sources.d.ts +18 -0
- package/dist/src/agent/skills/skill-sources.js +143 -0
- package/dist/src/agent/skills/types.d.ts +25 -2
- package/dist/src/agent/tools/delegate-tool.js +2 -1
- package/dist/src/agent/tools/executor.d.ts +2 -0
- package/dist/src/agent/tools/executor.js +18 -11
- package/dist/src/agent/tools/factory.js +18 -1
- package/dist/src/agent/tools/goal-tool.js +5 -3
- package/dist/src/agent/tools/index.d.ts +1 -0
- package/dist/src/agent/tools/index.js +2 -1
- package/dist/src/agent/tools/managed-job-tool.d.ts +2 -0
- package/dist/src/agent/tools/managed-job-tool.js +160 -0
- package/dist/src/agent/tools/todo-tool.d.ts +5 -0
- package/dist/src/agent/tools/todo-tool.js +16 -4
- package/dist/src/agent/tools/update-plan-tool.d.ts +1 -0
- package/dist/src/agent/tools/update-plan-tool.js +6 -0
- package/dist/src/agent/workspace-runtime/registry.d.ts +3 -0
- package/dist/src/agent/workspace-runtime/registry.js +3 -1
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/runtime-profile.js +1 -1
- package/dist/src/auth/credentials.d.ts +9 -1
- package/dist/src/auth/credentials.js +112 -56
- package/dist/src/auth/model-credential-store.js +7 -22
- package/dist/src/auth/oauth-provider-lock.d.ts +5 -0
- package/dist/src/auth/oauth-provider-lock.js +91 -0
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/automations/domain/defaults.d.ts +8 -1
- package/dist/src/automations/domain/defaults.js +9 -2
- package/dist/src/automations/domain/index.js +2 -2
- package/dist/src/automations/domain/types.d.ts +33 -7
- package/dist/src/automations/domain/validation.d.ts +8 -0
- package/dist/src/automations/domain/validation.js +2 -0
- package/dist/src/automations/draft/automation-draft-validator.d.ts +2 -1
- package/dist/src/automations/index.js +2 -2
- package/dist/src/automations/service/action-executor.d.ts +2 -2
- package/dist/src/automations/service/action-executor.js +144 -34
- package/dist/src/automations/service/automation-service.d.ts +4 -0
- package/dist/src/automations/service/automation-service.js +197 -18
- package/dist/src/automations/storage/automation-run-repository.d.ts +1 -0
- package/dist/src/automations/storage/automation-run-repository.js +37 -7
- package/dist/src/automations/storage/index.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/browser/providers/cloakbrowser.js +2 -2
- package/dist/src/channels/attachments/voice-stt-webchat.d.ts +0 -3
- package/dist/src/channels/attachments/voice-stt-webchat.js +1 -24
- package/dist/src/chat-commands/builtins/goal.js +5 -4
- package/dist/src/cli/commands/agents.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/goal.js +6 -5
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/tunnel.js +3 -3
- package/dist/src/cli/utils/oauth-login.js +1 -7
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/config/schema.d.ts +3 -0
- package/dist/src/config/schema.js +2 -1
- package/dist/src/connectors/learning-coordinator.js +7 -1
- package/dist/src/connectors/source-change-publisher.d.ts +17 -0
- package/dist/src/connectors/source-change-publisher.js +148 -0
- package/dist/src/discussions/analyzer.d.ts +35 -0
- package/dist/src/discussions/analyzer.js +127 -0
- package/dist/src/discussions/index.d.ts +7 -0
- package/dist/src/discussions/index.js +7 -0
- package/dist/src/discussions/live-worker.d.ts +33 -0
- package/dist/src/discussions/live-worker.js +148 -0
- package/dist/src/discussions/pipeline.d.ts +33 -0
- package/dist/src/discussions/pipeline.js +205 -0
- package/dist/src/discussions/project-inference.d.ts +13 -0
- package/dist/src/discussions/project-inference.js +19 -0
- package/dist/src/discussions/repository.d.ts +29 -0
- package/dist/src/discussions/repository.js +255 -0
- package/dist/src/discussions/service.d.ts +51 -0
- package/dist/src/discussions/service.js +335 -0
- package/dist/src/discussions/transcript.d.ts +3 -0
- package/dist/src/discussions/transcript.js +15 -0
- package/dist/src/discussions/types.d.ts +116 -0
- package/dist/src/discussions/types.js +10 -0
- package/dist/src/discussions/worker.d.ts +18 -0
- package/dist/src/discussions/worker.js +74 -0
- package/dist/src/extensions/activation-context.js +2 -1
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/extensions/sdk/testing.js +1 -1
- package/dist/src/gateway/agents-admin.js +3 -3
- package/dist/src/gateway/chat-stream/mapper.js +53 -3
- package/dist/src/gateway/chat-stream/protocol.d.ts +17 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/hono/app.js +8 -3
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.js +2 -2
- package/dist/src/gateway/hono/middleware/logger.js +1 -1
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +1 -1
- package/dist/src/gateway/hono/oauth-async.js +1 -7
- package/dist/src/gateway/hono/oauth.js +1 -7
- package/dist/src/gateway/hono/routes/agents.js +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
- package/dist/src/gateway/hono/routes/connectors.js +79 -0
- package/dist/src/gateway/hono/routes/discussions.d.ts +3 -0
- package/dist/src/gateway/hono/routes/discussions.js +177 -0
- package/dist/src/gateway/hono/routes/execution-receipts.d.ts +3 -0
- package/dist/src/gateway/hono/routes/execution-receipts.js +163 -0
- package/dist/src/gateway/hono/routes/exposure.js +1 -1
- package/dist/src/gateway/hono/routes/goals.js +3 -288
- package/dist/src/gateway/hono/routes/home.d.ts +2 -102
- package/dist/src/gateway/hono/routes/home.js +8 -424
- package/dist/src/gateway/hono/routes/index.js +6 -2
- package/dist/src/gateway/hono/routes/memory.js +7 -7
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/notes.js +30 -0
- package/dist/src/gateway/hono/routes/projects.js +8 -152
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/status.js +2 -2
- package/dist/src/gateway/hono/routes/tunnel.js +3 -3
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/hono/routes/work.d.ts +3 -0
- package/dist/src/gateway/hono/routes/work.js +207 -0
- package/dist/src/gateway/hono/routes/you.js +13 -15
- package/dist/src/gateway/index.js +2 -2
- package/dist/src/gateway/runtime-config.js +2 -2
- package/dist/src/gateway/security/audit.js +2 -2
- package/dist/src/gateway/security/index.js +1 -1
- package/dist/src/gateway/service/config-coordinator.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +46 -51
- package/dist/src/gateway/service.d.ts +8 -1
- package/dist/src/gateway/service.js +142 -15
- package/dist/src/goals/goal-queue-store.d.ts +1 -0
- package/dist/src/goals/goal-queue-store.js +5 -1
- package/dist/src/goals/goal-queue-types.d.ts +11 -1
- package/dist/src/goals/goal-runner.js +10 -6
- package/dist/src/goals/goal-service.d.ts +2 -15
- package/dist/src/goals/goal-service.js +9 -42
- package/dist/src/goals/goal-store.d.ts +1 -18
- package/dist/src/goals/goal-store.js +25 -231
- package/dist/src/goals/goal-workflow-judge.js +1 -1
- package/dist/src/goals/index.d.ts +0 -4
- package/dist/src/goals/index.js +1 -3
- package/dist/src/goals/types.d.ts +4 -66
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/service.d.ts +1 -0
- package/dist/src/notes/service.js +10 -1
- package/dist/src/notes/types.d.ts +1 -0
- package/dist/src/proactive/events/product-event-bridge.d.ts +7 -0
- package/dist/src/proactive/events/product-event-bridge.js +84 -0
- package/dist/src/proactive/execution/context.d.ts +27 -11
- package/dist/src/proactive/execution/context.js +259 -25
- package/dist/src/proactive/execution/repository.js +18 -5
- package/dist/src/proactive/execution/types.d.ts +7 -1
- package/dist/src/proactive/execution/worker.js +7 -6
- package/dist/src/proactive/inbox/repository.js +8 -2
- package/dist/src/proactive/index.d.ts +4 -2
- package/dist/src/proactive/index.js +5 -3
- package/dist/src/proactive/temporal/worker.d.ts +16 -0
- package/dist/src/proactive/temporal/worker.js +110 -0
- package/dist/src/projects/project-loop.js +3 -3
- package/dist/src/providers/auth-runtime/oauth.js +12 -0
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-proxy.js +1 -1
- package/dist/src/storage/sqlite/activity-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/activity-repository.js +4 -1
- package/dist/src/storage/sqlite/connector-sync-policy-repository.d.ts +20 -0
- package/dist/src/storage/sqlite/connector-sync-policy-repository.js +50 -0
- package/dist/src/storage/sqlite/execution-receipt-repository.d.ts +146 -0
- package/dist/src/storage/sqlite/execution-receipt-repository.js +235 -0
- package/dist/src/storage/sqlite/index.d.ts +4 -2
- package/dist/src/storage/sqlite/index.js +6 -4
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +3 -0
- package/dist/src/storage/sqlite/knowledge-repository.js +9 -1
- package/dist/src/storage/sqlite/memory-records-repository.js +1 -1
- package/dist/src/storage/sqlite/migrations/075_connector_sync_policies.sql +13 -0
- package/dist/src/storage/sqlite/migrations/076_meeting_preparation_scenario.sql +29 -0
- package/dist/src/storage/sqlite/migrations/077_proactive_insight_fingerprints.sql +4 -0
- package/dist/src/storage/sqlite/migrations/078_discussion_captures.sql +64 -0
- package/dist/src/storage/sqlite/migrations/079_discussion_follow_up_scenario.sql +29 -0
- package/dist/src/storage/sqlite/migrations/080_task_outcome_context.sql +15 -0
- package/dist/src/storage/sqlite/migrations/081_project_monitoring_policies.sql +10 -0
- package/dist/src/storage/sqlite/migrations/082_one_click_live_discussions.sql +100 -0
- package/dist/src/storage/sqlite/migrations/083_session_task_plans.sql +9 -0
- package/dist/src/storage/sqlite/migrations/084_work_intake_lifecycle.sql +26 -0
- package/dist/src/storage/sqlite/migrations/085_task_outcome_projection.sql +19 -0
- package/dist/src/storage/sqlite/migrations/086_outcome_aggregates.sql +168 -0
- package/dist/src/storage/sqlite/migrations/087_context_snapshots.sql +21 -0
- package/dist/src/storage/sqlite/migrations/088_automation_execution_deadlines.sql +5 -0
- package/dist/src/storage/sqlite/migrations/089_automation_run_leases.sql +8 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/notes-repository.js +9 -0
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/schema.sql +89 -44
- package/dist/src/storage/sqlite/session-repository.js +1 -1
- package/dist/src/storage/sqlite/session-task-plan-repository.d.ts +20 -0
- package/dist/src/storage/sqlite/session-task-plan-repository.js +77 -0
- package/dist/src/tui/backends/embedded-backend.d.ts +2 -0
- package/dist/src/tui/backends/embedded-backend.js +12 -8
- package/dist/src/tui/tui-backend.d.ts +2 -0
- package/dist/src/tui/tui-oauth-login.js +1 -7
- package/dist/src/tui/tui-picker-overlay.js +1 -0
- package/dist/src/tui/tui-picker-services.d.ts +1 -0
- package/dist/src/tui/tui-skills-autocomplete.d.ts +6 -2
- package/dist/src/tui/tui-skills-autocomplete.js +10 -6
- package/dist/src/tui/tui-startup-resources.d.ts +3 -1
- package/dist/src/tui/tui-startup-resources.js +4 -3
- package/dist/src/tui/tui.js +4 -1
- package/dist/src/tunnel/frpc-binary.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/index.js +2 -2
- package/dist/src/user-context/context-compiler.d.ts +31 -0
- package/dist/src/user-context/context-compiler.js +51 -0
- package/dist/src/voice/local/model-files.js +1 -1
- package/dist/src/voice/stt/config.d.ts +4 -0
- package/dist/src/voice/stt/config.js +26 -0
- package/dist/src/voice/stt/index.d.ts +1 -0
- package/dist/src/voice/stt/index.js +2 -1
- package/dist/src/voice/stt/list-providers.js +1 -1
- package/dist/src/work/attention-governor.d.ts +20 -0
- package/dist/src/work/attention-governor.js +46 -0
- package/dist/src/work/execution-context.d.ts +16 -0
- package/dist/src/work/execution-context.js +66 -0
- package/dist/src/work/home-query-service.d.ts +147 -0
- package/dist/src/work/home-query-service.js +389 -0
- package/dist/src/work/index.d.ts +14 -0
- package/dist/src/work/index.js +15 -0
- package/dist/src/work/outcome-contract-definition.d.ts +8 -0
- package/dist/src/work/outcome-contract-definition.js +15 -0
- package/dist/src/work/outcome-execution-service.d.ts +27 -0
- package/dist/src/work/outcome-execution-service.js +60 -0
- package/dist/src/work/outcome-projection-service.d.ts +7 -0
- package/dist/src/work/outcome-projection-service.js +51 -0
- package/dist/src/work/outcome-receipt-service.d.ts +13 -0
- package/dist/src/work/outcome-receipt-service.js +55 -0
- package/dist/src/work/outcome-repository.d.ts +50 -0
- package/dist/src/work/outcome-repository.js +112 -0
- package/dist/src/work/outcome-run-coordinator.d.ts +25 -0
- package/dist/src/work/outcome-run-coordinator.js +117 -0
- package/dist/src/work/project-monitoring-service.d.ts +21 -0
- package/dist/src/work/project-monitoring-service.js +76 -0
- package/dist/src/work/project-operating-view-service.d.ts +10 -0
- package/dist/src/work/project-operating-view-service.js +46 -0
- package/dist/src/work/work-intake-repository.d.ts +49 -0
- package/dist/src/work/work-intake-repository.js +97 -0
- package/dist/src/work/work-intake-service.d.ts +26 -0
- package/dist/src/work/work-intake-service.js +171 -0
- package/dist/src/work/work-value-metrics-service.d.ts +4 -0
- package/dist/src/work/work-value-metrics-service.js +88 -0
- package/dist/src/work-items/work-item-service.d.ts +0 -2
- package/dist/src/work-items/work-item-service.js +0 -28
- package/dist/src/workflows/service/workflow-run-service.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +3 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +2 -2
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agents-DC9F12Kw.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-5bKr05Fa.js +0 -1
- package/dist/gateway/static/root/assets/automation-suggestion-card-B7mxFRtf.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-Dg6dmt5g.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-BHoo6Rpq.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BlsqN8Fu.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DJeT8_B4.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-C4VVjYEm.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-vdf8kB16.js +0 -1
- package/dist/gateway/static/root/assets/circle-alert-BEjgurr2.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-DNcrDThX.js +0 -2
- package/dist/gateway/static/root/assets/desktop-pet-B1urphOZ.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-DTL6J3EP.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-DmObBx9b.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-BRhmmBe9.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-C1k7_s_O.js +0 -4
- package/dist/gateway/static/root/assets/goals-config-api-Fwu1wjEP.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-hOu9uA3q.js +0 -2
- package/dist/gateway/static/root/assets/goals-settings-DY-JjvHz.js +0 -1
- package/dist/gateway/static/root/assets/index-C0CGebQ1.js +0 -212
- package/dist/gateway/static/root/assets/index-eqq25gvV.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-EjsNT7nJ.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-Dswjlraa.js +0 -7
- package/dist/gateway/static/root/assets/messages-DP6tPKk-.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-DSh3-hMY.js +0 -4
- package/dist/gateway/static/root/assets/product-delivery-BTRT9kCS.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-D0QPRHR_.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CI5Vz62F.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-S1jpzBS5.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CTm66k7h.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CU52AUVD.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DK6XK95e.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Bvv_u4ii.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BGHvVbay.js +0 -2
- package/dist/gateway/static/root/assets/time-picker-XwpxdZFr.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-DBCMk-Vn.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-C1UIdsCl.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-DEAQepB8.js +0 -1
- package/dist/gateway/static/root/assets/work-page-D5qYmCTq.js +0 -3
- package/dist/gateway/static/root/assets/workflows-page-yrK17ZZ5.js +0 -11
- package/dist/src/agent/outcomes/task-verifier.d.ts +0 -29
- package/dist/src/gateway/hono/routes/task-outcomes.d.ts +0 -3
- package/dist/src/gateway/hono/routes/task-outcomes.js +0 -109
- package/dist/src/goals/goal-contract-draft.d.ts +0 -15
- package/dist/src/goals/goal-contract-draft.js +0 -112
- package/dist/src/goals/goal-evidence-review.d.ts +0 -15
- package/dist/src/goals/goal-evidence-review.js +0 -89
- package/dist/src/storage/sqlite/task-outcome-repository.d.ts +0 -90
- package/dist/src/storage/sqlite/task-outcome-repository.js +0 -138
|
@@ -2,35 +2,71 @@ import { createLogger } from "../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { init_agent_scope, normalizeAgentId } from "../../agent/agent-scope.js";
|
|
4
4
|
import { buildSessionKey, init_session_key } from "../../routing/session-key.js";
|
|
5
|
-
import "../domain/defaults.js";
|
|
5
|
+
import { resolveAutomationTimeoutSeconds } from "../domain/defaults.js";
|
|
6
6
|
import crypto from "node:crypto";
|
|
7
7
|
//#region src/automations/service/action-executor.ts
|
|
8
8
|
init_agent_scope();
|
|
9
9
|
init_session_key();
|
|
10
10
|
init_logger();
|
|
11
11
|
const log = createLogger("Automation:ActionExecutor");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const CANCELLATION_GRACE_MS = 1e4;
|
|
13
|
+
var AutomationExecutionStoppedError = class extends Error {
|
|
14
|
+
constructor(status, cancellationConfirmed, deadlineAtMs, timeoutMs) {
|
|
15
|
+
super(status === "timeout" ? `Automation timed out after ${timeoutMs}ms` : "Automation run was cancelled");
|
|
16
|
+
this.status = status;
|
|
17
|
+
this.cancellationConfirmed = cancellationConfirmed;
|
|
18
|
+
this.deadlineAtMs = deadlineAtMs;
|
|
19
|
+
this.name = "AutomationExecutionStoppedError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
async function waitForCancellation(promise) {
|
|
23
|
+
let timer;
|
|
24
|
+
try {
|
|
25
|
+
return await Promise.race([promise.then(() => true, () => true), new Promise((resolve) => {
|
|
26
|
+
timer = setTimeout(() => resolve(false), CANCELLATION_GRACE_MS);
|
|
27
|
+
})]);
|
|
28
|
+
} finally {
|
|
29
|
+
if (timer) clearTimeout(timer);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function executeWithDeadline(operation, timeoutMs, parentSignal, deadlineAtMs) {
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
let stoppedAs;
|
|
35
|
+
const stop = (status, reason) => {
|
|
36
|
+
if (controller.signal.aborted) return;
|
|
37
|
+
stoppedAs = status;
|
|
38
|
+
controller.abort(reason);
|
|
39
|
+
};
|
|
40
|
+
const onParentAbort = () => stop("cancelled", parentSignal.reason);
|
|
41
|
+
parentSignal.addEventListener("abort", onParentAbort, { once: true });
|
|
42
|
+
if (parentSignal.aborted) onParentAbort();
|
|
43
|
+
const timer = setTimeout(() => stop("timeout", /* @__PURE__ */ new Error(`Automation timed out after ${timeoutMs}ms`)), Math.max(0, deadlineAtMs - Date.now()));
|
|
44
|
+
const operationPromise = operation(controller.signal);
|
|
45
|
+
const rejectForAbort = () => {
|
|
46
|
+
throw controller.signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled");
|
|
47
|
+
};
|
|
48
|
+
let removeDeadlineAbortListener;
|
|
49
|
+
const abortPromise = new Promise((_, reject) => {
|
|
50
|
+
const rejectPromise = () => reject(controller.signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled"));
|
|
51
|
+
if (controller.signal.aborted) rejectPromise();
|
|
52
|
+
else {
|
|
53
|
+
controller.signal.addEventListener("abort", rejectPromise, { once: true });
|
|
54
|
+
removeDeadlineAbortListener = () => controller.signal.removeEventListener("abort", rejectPromise);
|
|
17
55
|
}
|
|
18
|
-
const timer = setTimeout(() => reject(/* @__PURE__ */ new Error(`Automation timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
19
|
-
const onAbort = () => {
|
|
20
|
-
clearTimeout(timer);
|
|
21
|
-
reject(/* @__PURE__ */ new Error("Automation run was cancelled"));
|
|
22
|
-
};
|
|
23
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
24
|
-
promise.then((value) => {
|
|
25
|
-
clearTimeout(timer);
|
|
26
|
-
signal.removeEventListener("abort", onAbort);
|
|
27
|
-
resolve(value);
|
|
28
|
-
}, (err) => {
|
|
29
|
-
clearTimeout(timer);
|
|
30
|
-
signal.removeEventListener("abort", onAbort);
|
|
31
|
-
reject(err);
|
|
32
|
-
});
|
|
33
56
|
});
|
|
57
|
+
try {
|
|
58
|
+
const result = await Promise.race([operationPromise, abortPromise]);
|
|
59
|
+
if (stoppedAs) rejectForAbort();
|
|
60
|
+
return result;
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (!stoppedAs) throw err;
|
|
63
|
+
const cancellationConfirmed = await waitForCancellation(operationPromise);
|
|
64
|
+
throw new AutomationExecutionStoppedError(stoppedAs, cancellationConfirmed, deadlineAtMs, timeoutMs);
|
|
65
|
+
} finally {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
parentSignal.removeEventListener("abort", onParentAbort);
|
|
68
|
+
removeDeadlineAbortListener?.();
|
|
69
|
+
}
|
|
34
70
|
}
|
|
35
71
|
var AutomationActionExecutor = class {
|
|
36
72
|
deps = {};
|
|
@@ -40,26 +76,41 @@ var AutomationActionExecutor = class {
|
|
|
40
76
|
...deps
|
|
41
77
|
};
|
|
42
78
|
}
|
|
43
|
-
async execute(automation, run, signal) {
|
|
44
|
-
const
|
|
45
|
-
|
|
79
|
+
async execute(automation, run, signal, hooks = {}) {
|
|
80
|
+
const configuredTimeoutMs = resolveAutomationTimeoutSeconds(automation.action, automation.reliability) * 1e3;
|
|
81
|
+
const deadlineAtMs = run.deadlineAtMs ?? Date.now() + configuredTimeoutMs;
|
|
82
|
+
const timeoutMs = Math.max(1, deadlineAtMs - Date.now());
|
|
83
|
+
await hooks.onRunPatch?.({ deadlineAtMs });
|
|
84
|
+
return executeWithDeadline((deadlineSignal) => this.executeWithoutTimeout(automation, run, deadlineSignal, hooks, deadlineAtMs), timeoutMs, signal, deadlineAtMs).catch((err) => {
|
|
46
85
|
const message = err instanceof Error ? err.message : String(err);
|
|
86
|
+
if (err instanceof AutomationExecutionStoppedError) return {
|
|
87
|
+
status: err.status,
|
|
88
|
+
error: message,
|
|
89
|
+
deadlineAtMs: err.deadlineAtMs,
|
|
90
|
+
termination: {
|
|
91
|
+
reason: err.status === "timeout" ? "deadline_exceeded" : "user_cancelled",
|
|
92
|
+
component: "automation",
|
|
93
|
+
cancellationConfirmed: err.cancellationConfirmed
|
|
94
|
+
}
|
|
95
|
+
};
|
|
47
96
|
return {
|
|
48
97
|
status: message.toLowerCase().includes("cancelled") ? "cancelled" : message.toLowerCase().includes("timed out") ? "timeout" : "failed",
|
|
49
|
-
error: message
|
|
98
|
+
error: message,
|
|
99
|
+
deadlineAtMs
|
|
50
100
|
};
|
|
51
101
|
});
|
|
52
102
|
}
|
|
53
|
-
async executeWithoutTimeout(automation, run, signal) {
|
|
103
|
+
async executeWithoutTimeout(automation, run, signal, hooks, deadlineAtMs) {
|
|
54
104
|
if (signal.aborted) return {
|
|
55
105
|
status: "cancelled",
|
|
56
106
|
error: "Automation run was cancelled"
|
|
57
107
|
};
|
|
58
|
-
if (automation.action.kind === "workflow") return this.executeWorkflow(automation, automation.action, run);
|
|
59
|
-
if (automation.action.kind === "browser_recipe") return this.executeBrowserRecipe(automation, automation.action, signal);
|
|
60
|
-
return this.executeAgent(automation, automation.action);
|
|
108
|
+
if (automation.action.kind === "workflow") return this.executeWorkflow(automation, automation.action, run, signal, hooks);
|
|
109
|
+
if (automation.action.kind === "browser_recipe") return this.executeBrowserRecipe(automation, automation.action, signal, hooks);
|
|
110
|
+
return this.executeAgent(automation, automation.action, run, signal, hooks, deadlineAtMs);
|
|
61
111
|
}
|
|
62
|
-
async executeBrowserRecipe(automation, action, signal) {
|
|
112
|
+
async executeBrowserRecipe(automation, action, signal, hooks) {
|
|
113
|
+
await hooks.onRunPatch?.({ currentPhase: "action" });
|
|
63
114
|
const safetyMode = automation.safety?.mode ?? "auto_apply";
|
|
64
115
|
if (safetyMode !== "auto_apply") return {
|
|
65
116
|
status: "succeeded",
|
|
@@ -80,7 +131,7 @@ var AutomationActionExecutor = class {
|
|
|
80
131
|
error: run.error ?? `Browser automation ${action.recipeId} ${run.status}`
|
|
81
132
|
};
|
|
82
133
|
}
|
|
83
|
-
async executeAgent(automation, action) {
|
|
134
|
+
async executeAgent(automation, action, run, signal, hooks, deadlineAtMs) {
|
|
84
135
|
const agentService = this.deps.agentService;
|
|
85
136
|
if (!agentService?.turnDispatcher?.processDirect) return {
|
|
86
137
|
status: "failed",
|
|
@@ -94,6 +145,10 @@ var AutomationActionExecutor = class {
|
|
|
94
145
|
peerId: `${automation.id}-${crypto.randomUUID().slice(0, 8)}`
|
|
95
146
|
});
|
|
96
147
|
const effectiveWorkingDirectory = action.workingDirectory ?? (automation.projectId ? this.deps.getProjectWorkspaceRoot?.(automation.projectId) : void 0);
|
|
148
|
+
await hooks.onRunPatch?.({
|
|
149
|
+
sessionKey,
|
|
150
|
+
currentPhase: "action"
|
|
151
|
+
});
|
|
97
152
|
await agentService.sessionConfig?.applyAutomationWorkingDirectory?.(sessionKey, effectiveWorkingDirectory);
|
|
98
153
|
if (agentService.sessionConfig?.applyAutomationModelOverride) {
|
|
99
154
|
if (!await agentService.sessionConfig.applyAutomationModelOverride(sessionKey, action.model) && action.model) log.warn({
|
|
@@ -102,7 +157,11 @@ var AutomationActionExecutor = class {
|
|
|
102
157
|
model: action.model
|
|
103
158
|
}, "Automation model override invalid; using agent default");
|
|
104
159
|
}
|
|
105
|
-
const response = await agentService.turnDispatcher.processDirect(buildSafetyInstruction(automation, action.instruction), sessionKey
|
|
160
|
+
const response = await agentService.turnDispatcher.processDirect(buildSafetyInstruction(automation, action.instruction), sessionKey, void 0, void 0, {
|
|
161
|
+
signal,
|
|
162
|
+
runId: run.id,
|
|
163
|
+
deadlineAtMs
|
|
164
|
+
});
|
|
106
165
|
const model = agentService.getModelForSession?.(sessionKey);
|
|
107
166
|
return {
|
|
108
167
|
status: "succeeded",
|
|
@@ -111,7 +170,7 @@ var AutomationActionExecutor = class {
|
|
|
111
170
|
model
|
|
112
171
|
};
|
|
113
172
|
}
|
|
114
|
-
async executeWorkflow(automation, action, run) {
|
|
173
|
+
async executeWorkflow(automation, action, run, signal, hooks) {
|
|
115
174
|
const safetyMode = automation.safety?.mode ?? "auto_apply";
|
|
116
175
|
if (safetyMode === "suggest_only") return {
|
|
117
176
|
status: "succeeded",
|
|
@@ -148,14 +207,65 @@ var AutomationActionExecutor = class {
|
|
|
148
207
|
status: "failed",
|
|
149
208
|
error: result.message
|
|
150
209
|
};
|
|
151
|
-
|
|
210
|
+
await hooks.onRunPatch?.({
|
|
211
|
+
sessionKey: result.sessionKey,
|
|
212
|
+
workflowRunId: result.runId,
|
|
213
|
+
currentPhase: "action"
|
|
214
|
+
});
|
|
215
|
+
if (!workflowRunService.readWorkflowRunView) return {
|
|
152
216
|
status: "succeeded",
|
|
153
217
|
summary: `Started workflow run ${result.runId}`,
|
|
154
218
|
sessionKey: result.sessionKey,
|
|
155
219
|
workflowRunId: result.runId
|
|
156
220
|
};
|
|
221
|
+
while (!signal.aborted) {
|
|
222
|
+
const view = await workflowRunService.readWorkflowRunView(agentId, result.runId);
|
|
223
|
+
if (!view) return {
|
|
224
|
+
status: "failed",
|
|
225
|
+
error: `Workflow run ${result.runId} disappeared`
|
|
226
|
+
};
|
|
227
|
+
const workflowStatus = view.run.status;
|
|
228
|
+
if (workflowStatus === "succeeded") return {
|
|
229
|
+
status: "succeeded",
|
|
230
|
+
summary: `Workflow run ${result.runId} completed`,
|
|
231
|
+
sessionKey: result.sessionKey,
|
|
232
|
+
workflowRunId: result.runId
|
|
233
|
+
};
|
|
234
|
+
if (workflowStatus === "failed" || workflowStatus === "cancelled" || workflowStatus === "timeout") return {
|
|
235
|
+
status: workflowStatus,
|
|
236
|
+
error: view.run.error?.message ?? `Workflow run ${result.runId} ${workflowStatus}`,
|
|
237
|
+
sessionKey: result.sessionKey,
|
|
238
|
+
workflowRunId: result.runId
|
|
239
|
+
};
|
|
240
|
+
await waitForSignalOrDelay(signal, 500);
|
|
241
|
+
}
|
|
242
|
+
await workflowRunService.cancelWorkflowRun?.({
|
|
243
|
+
agentId,
|
|
244
|
+
runId: result.runId,
|
|
245
|
+
reason: "Parent automation was cancelled or reached its deadline"
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
status: "cancelled",
|
|
249
|
+
error: "Parent automation stopped while the workflow was running",
|
|
250
|
+
sessionKey: result.sessionKey,
|
|
251
|
+
workflowRunId: result.runId
|
|
252
|
+
};
|
|
157
253
|
}
|
|
158
254
|
};
|
|
255
|
+
function waitForSignalOrDelay(signal, delayMs) {
|
|
256
|
+
return new Promise((resolve) => {
|
|
257
|
+
const timer = setTimeout(() => {
|
|
258
|
+
signal.removeEventListener("abort", onAbort);
|
|
259
|
+
resolve();
|
|
260
|
+
}, delayMs);
|
|
261
|
+
const onAbort = () => {
|
|
262
|
+
clearTimeout(timer);
|
|
263
|
+
resolve();
|
|
264
|
+
};
|
|
265
|
+
if (signal.aborted) onAbort();
|
|
266
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
267
|
+
});
|
|
268
|
+
}
|
|
159
269
|
function buildSafetyInstruction(automation, instruction) {
|
|
160
270
|
const mode = automation.safety?.mode ?? "auto_apply";
|
|
161
271
|
if (mode === "suggest_only") return [
|
|
@@ -15,6 +15,8 @@ export declare class AutomationService {
|
|
|
15
15
|
private deps;
|
|
16
16
|
private maxConcurrentRuns;
|
|
17
17
|
private readonly activeRuns;
|
|
18
|
+
private readonly heartbeatTimers;
|
|
19
|
+
private readonly leaseOwner;
|
|
18
20
|
constructor(signals?: ProactiveSignalPublisher);
|
|
19
21
|
setDeps(deps: AutomationDeps): void;
|
|
20
22
|
initialize(options?: {
|
|
@@ -54,6 +56,8 @@ export declare class AutomationService {
|
|
|
54
56
|
private onTimer;
|
|
55
57
|
private startRun;
|
|
56
58
|
private executeRun;
|
|
59
|
+
private recoverInterruptedRuns;
|
|
60
|
+
private waitForRetry;
|
|
57
61
|
private appendRunEvent;
|
|
58
62
|
private finishAutomationRun;
|
|
59
63
|
private postAfterRunWebhook;
|
|
@@ -5,7 +5,7 @@ import { computeNextAutomationRunAtMs, timerDelayUntil } from "../domain/schedul
|
|
|
5
5
|
import { AutomationSchema, CreateAutomationSchema, UpdateAutomationSchema } from "../domain/validation.js";
|
|
6
6
|
import { AutomationActionExecutor } from "./action-executor.js";
|
|
7
7
|
import { deleteAutomation, getAutomation, listAutomations, saveAutomation, saveAutomations } from "../storage/automation-repository.js";
|
|
8
|
-
import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun } from "../storage/automation-run-repository.js";
|
|
8
|
+
import { appendAutomationRunEvent, getAutomationRun, listAutomationRunEvents, listAutomationRuns, listAutomationRunsForProductEvent, saveAutomationRun, touchAutomationRunLease } from "../storage/automation-run-repository.js";
|
|
9
9
|
import "../storage/index.js";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
//#region src/automations/service/automation-service.ts
|
|
@@ -13,6 +13,9 @@ init_logger();
|
|
|
13
13
|
const log = createLogger("AutomationService");
|
|
14
14
|
const DEFAULT_MAX_CONCURRENT_RUNS = 5;
|
|
15
15
|
const MISSED_RUN_STAGGER_MS = 5e3;
|
|
16
|
+
const RUN_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
17
|
+
const RUN_LEASE_DURATION_MS = 3e4;
|
|
18
|
+
const RETRY_BASE_DELAY_MS = 1e3;
|
|
16
19
|
var AutomationAlreadyRunningError = class extends Error {
|
|
17
20
|
constructor(automationId, runningRunId) {
|
|
18
21
|
super(`Automation is already running: ${automationId}`);
|
|
@@ -29,6 +32,8 @@ var AutomationService = class {
|
|
|
29
32
|
deps = {};
|
|
30
33
|
maxConcurrentRuns = DEFAULT_MAX_CONCURRENT_RUNS;
|
|
31
34
|
activeRuns = /* @__PURE__ */ new Map();
|
|
35
|
+
heartbeatTimers = /* @__PURE__ */ new Map();
|
|
36
|
+
leaseOwner = `automation-service:${process.pid}:${randomUUID()}`;
|
|
32
37
|
constructor(signals) {
|
|
33
38
|
this.signals = signals;
|
|
34
39
|
}
|
|
@@ -42,6 +47,7 @@ var AutomationService = class {
|
|
|
42
47
|
async initialize(options) {
|
|
43
48
|
this.maxConcurrentRuns = Math.max(1, Math.floor(options?.maxConcurrentRuns ?? DEFAULT_MAX_CONCURRENT_RUNS));
|
|
44
49
|
this.stopped = false;
|
|
50
|
+
await this.recoverInterruptedRuns();
|
|
45
51
|
await this.recomputeNextRuns({ catchUp: true });
|
|
46
52
|
this.armTimer();
|
|
47
53
|
log.info("Automation service initialized");
|
|
@@ -53,6 +59,8 @@ var AutomationService = class {
|
|
|
53
59
|
this.timer = null;
|
|
54
60
|
}
|
|
55
61
|
for (const controller of this.activeRuns.values()) controller.abort();
|
|
62
|
+
for (const timer of this.heartbeatTimers.values()) clearInterval(timer);
|
|
63
|
+
this.heartbeatTimers.clear();
|
|
56
64
|
log.info("Automation service stopped");
|
|
57
65
|
}
|
|
58
66
|
async create(input) {
|
|
@@ -160,7 +168,19 @@ var AutomationService = class {
|
|
|
160
168
|
async cancelRun(runId) {
|
|
161
169
|
const controller = this.activeRuns.get(runId);
|
|
162
170
|
if (!controller) return false;
|
|
163
|
-
|
|
171
|
+
const now = Date.now();
|
|
172
|
+
const current = getAutomationRun(runId);
|
|
173
|
+
if (current && current.status === "running") {
|
|
174
|
+
const cancelling = {
|
|
175
|
+
...current,
|
|
176
|
+
status: "cancelling",
|
|
177
|
+
currentPhase: "cancelling",
|
|
178
|
+
cancelRequestedAtMs: now
|
|
179
|
+
};
|
|
180
|
+
saveAutomationRun(cancelling);
|
|
181
|
+
this.appendRunEvent(cancelling, "run.cancel_requested", "Automation cancellation requested", { reason: "user_cancelled" });
|
|
182
|
+
}
|
|
183
|
+
controller.abort(/* @__PURE__ */ new Error("Automation run was cancelled by the user"));
|
|
164
184
|
return true;
|
|
165
185
|
}
|
|
166
186
|
async getMetrics() {
|
|
@@ -187,7 +207,7 @@ var AutomationService = class {
|
|
|
187
207
|
...automation,
|
|
188
208
|
state: { ...automation.state }
|
|
189
209
|
};
|
|
190
|
-
if (next.state.runningRunId) {
|
|
210
|
+
if (next.state.runningRunId && !this.activeRuns.has(next.state.runningRunId)) {
|
|
191
211
|
next.state.lastRunStatus = "failed";
|
|
192
212
|
next.state.lastError = "Interrupted by gateway restart";
|
|
193
213
|
next.state.consecutiveFailures = (next.state.consecutiveFailures ?? 0) + 1;
|
|
@@ -237,8 +257,10 @@ var AutomationService = class {
|
|
|
237
257
|
triggerSnapshot: automation.trigger,
|
|
238
258
|
actionSnapshot: automation.action,
|
|
239
259
|
manual: opts.manual,
|
|
240
|
-
createdAtMs: now
|
|
260
|
+
createdAtMs: now,
|
|
261
|
+
attemptNumber: 1
|
|
241
262
|
};
|
|
263
|
+
run.rootRunId = run.id;
|
|
242
264
|
saveAutomationRun(run);
|
|
243
265
|
this.appendRunEvent(run, "run.queued", opts.event ? `Event ${opts.event.type} queued automation` : opts.manual ? "Manual run queued" : "Scheduled run queued", {
|
|
244
266
|
trigger: automation.trigger,
|
|
@@ -270,21 +292,69 @@ var AutomationService = class {
|
|
|
270
292
|
let run = {
|
|
271
293
|
...initialRun,
|
|
272
294
|
status: "running",
|
|
273
|
-
startedAtMs
|
|
295
|
+
startedAtMs,
|
|
296
|
+
currentPhase: "action",
|
|
297
|
+
heartbeatAtMs: startedAtMs,
|
|
298
|
+
leaseOwner: this.leaseOwner,
|
|
299
|
+
leaseExpiresAtMs: startedAtMs + RUN_LEASE_DURATION_MS
|
|
274
300
|
};
|
|
275
301
|
saveAutomationRun(run);
|
|
276
302
|
this.appendRunEvent(run, "run.started", "Automation run started");
|
|
303
|
+
const heartbeat = setInterval(() => {
|
|
304
|
+
const now = Date.now();
|
|
305
|
+
touchAutomationRunLease(run.id, this.leaseOwner, now, now + RUN_LEASE_DURATION_MS);
|
|
306
|
+
}, RUN_HEARTBEAT_INTERVAL_MS);
|
|
307
|
+
heartbeat.unref?.();
|
|
308
|
+
this.heartbeatTimers.set(run.id, heartbeat);
|
|
277
309
|
let status = "failed";
|
|
278
310
|
let error;
|
|
279
311
|
let activePhase = "action";
|
|
280
312
|
try {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
313
|
+
const maxAttempts = Math.max(1, (automation.reliability?.retryCount ?? 0) + 1);
|
|
314
|
+
let outcome;
|
|
315
|
+
for (let attempt = 1;; attempt += 1) {
|
|
316
|
+
run = {
|
|
317
|
+
...run,
|
|
318
|
+
attemptNumber: attempt
|
|
319
|
+
};
|
|
320
|
+
saveAutomationRun(run);
|
|
321
|
+
this.appendRunEvent(run, "action.started", `Running ${automation.action.kind} action`, {
|
|
322
|
+
actionKind: automation.action.kind,
|
|
323
|
+
safety: automation.safety ?? { mode: "auto_apply" },
|
|
324
|
+
attempt,
|
|
325
|
+
maxAttempts
|
|
326
|
+
});
|
|
327
|
+
outcome = await this.executor.execute(automation, run, controller.signal, { onRunPatch: (patch) => {
|
|
328
|
+
const previousDeadline = run.deadlineAtMs;
|
|
329
|
+
run = {
|
|
330
|
+
...run,
|
|
331
|
+
...patch
|
|
332
|
+
};
|
|
333
|
+
saveAutomationRun(run);
|
|
334
|
+
if (patch.deadlineAtMs !== void 0 && patch.deadlineAtMs !== previousDeadline) this.appendRunEvent(run, "run.deadline_resolved", "Automation deadline resolved", {
|
|
335
|
+
deadlineAtMs: patch.deadlineAtMs,
|
|
336
|
+
timeoutMs: patch.deadlineAtMs - startedAtMs
|
|
337
|
+
});
|
|
338
|
+
} });
|
|
339
|
+
if (!(outcome.status === "failed") || attempt >= maxAttempts || controller.signal.aborted) break;
|
|
340
|
+
const delayMs = Math.min(RETRY_BASE_DELAY_MS * 2 ** (attempt - 1), 3e4);
|
|
341
|
+
this.appendRunEvent(run, "action.retry_scheduled", "Automation action retry scheduled", {
|
|
342
|
+
attempt,
|
|
343
|
+
nextAttempt: attempt + 1,
|
|
344
|
+
maxAttempts,
|
|
345
|
+
delayMs,
|
|
346
|
+
status: outcome.status,
|
|
347
|
+
error: outcome.error
|
|
348
|
+
});
|
|
349
|
+
await this.waitForRetry(delayMs, controller.signal);
|
|
350
|
+
}
|
|
286
351
|
status = outcome.status;
|
|
287
352
|
error = outcome.error;
|
|
353
|
+
const persistedRun = getAutomationRun(run.id);
|
|
354
|
+
if (persistedRun) run = {
|
|
355
|
+
...run,
|
|
356
|
+
...persistedRun
|
|
357
|
+
};
|
|
288
358
|
this.appendRunEvent(run, status === "succeeded" ? "action.completed" : "action.failed", status === "succeeded" ? `${automation.action.kind} action completed` : `${automation.action.kind} action ${status}`, {
|
|
289
359
|
summary: outcome.summary,
|
|
290
360
|
error: outcome.error,
|
|
@@ -299,23 +369,52 @@ var AutomationService = class {
|
|
|
299
369
|
error,
|
|
300
370
|
sessionKey: outcome.sessionKey,
|
|
301
371
|
workflowRunId: outcome.workflowRunId,
|
|
302
|
-
model: outcome.model
|
|
372
|
+
model: outcome.model,
|
|
373
|
+
deadlineAtMs: outcome.deadlineAtMs ?? run.deadlineAtMs,
|
|
374
|
+
termination: outcome.termination ?? (status === "succeeded" ? {
|
|
375
|
+
reason: "completed",
|
|
376
|
+
cancellationConfirmed: true
|
|
377
|
+
} : status === "failed" ? {
|
|
378
|
+
reason: "failed",
|
|
379
|
+
cancellationConfirmed: true
|
|
380
|
+
} : run.termination)
|
|
303
381
|
};
|
|
304
|
-
if (
|
|
382
|
+
if (outcome.termination) {
|
|
383
|
+
const now = Date.now();
|
|
384
|
+
run = {
|
|
385
|
+
...run,
|
|
386
|
+
currentPhase: "cancelling",
|
|
387
|
+
cancelRequestedAtMs: run.cancelRequestedAtMs ?? now,
|
|
388
|
+
cancelConfirmedAtMs: outcome.termination.cancellationConfirmed ? now : void 0
|
|
389
|
+
};
|
|
390
|
+
this.appendRunEvent(run, outcome.termination.cancellationConfirmed ? "run.cancel_confirmed" : "run.cancellation_unconfirmed", outcome.termination.cancellationConfirmed ? "Automation cancellation confirmed" : "Automation cancellation was not confirmed within the cleanup grace period", { termination: outcome.termination });
|
|
391
|
+
}
|
|
392
|
+
if (status === "timeout" || status === "cancelled") {} else if ((automation.safety?.mode ?? "auto_apply") !== "auto_apply" && automation.afterRun?.kind === "webhook") this.appendRunEvent(run, "after_run.completed", "After-run webhook skipped by safety mode", { safety: automation.safety ?? { mode: "auto_apply" } });
|
|
305
393
|
else if (automation.afterRun?.kind === "webhook") {
|
|
306
394
|
activePhase = "after_run";
|
|
395
|
+
run = {
|
|
396
|
+
...run,
|
|
397
|
+
currentPhase: "after_run"
|
|
398
|
+
};
|
|
399
|
+
saveAutomationRun(run);
|
|
307
400
|
this.appendRunEvent(run, "after_run.started", "Calling after-run webhook", { url: automation.afterRun.url });
|
|
308
|
-
await this.postAfterRunWebhook(automation.afterRun.url, run);
|
|
401
|
+
await this.postAfterRunWebhook(automation.afterRun.url, run, controller.signal);
|
|
309
402
|
this.appendRunEvent(run, "after_run.completed", "After-run webhook completed");
|
|
310
403
|
}
|
|
311
404
|
} catch (err) {
|
|
312
405
|
error = err instanceof Error ? err.message : String(err);
|
|
313
|
-
|
|
406
|
+
const deadlineExceeded = run.deadlineAtMs !== void 0 && Date.now() >= run.deadlineAtMs;
|
|
407
|
+
status = controller.signal.aborted ? "cancelled" : deadlineExceeded ? "timeout" : "failed";
|
|
314
408
|
this.appendRunEvent(run, activePhase === "after_run" ? "after_run.failed" : "action.failed", `Automation run ${status}`, { error });
|
|
315
409
|
run = {
|
|
316
410
|
...run,
|
|
317
411
|
status,
|
|
318
|
-
error
|
|
412
|
+
error,
|
|
413
|
+
termination: {
|
|
414
|
+
reason: status === "cancelled" ? "user_cancelled" : status === "timeout" ? "deadline_exceeded" : "failed",
|
|
415
|
+
component: activePhase === "after_run" ? "automation" : run.termination?.component,
|
|
416
|
+
cancellationConfirmed: status !== "cancelled" || controller.signal.aborted
|
|
417
|
+
}
|
|
319
418
|
};
|
|
320
419
|
} finally {
|
|
321
420
|
const endedAtMs = Date.now();
|
|
@@ -323,9 +422,19 @@ var AutomationService = class {
|
|
|
323
422
|
...run,
|
|
324
423
|
status,
|
|
325
424
|
endedAtMs,
|
|
326
|
-
durationMs: endedAtMs - startedAtMs
|
|
425
|
+
durationMs: endedAtMs - startedAtMs,
|
|
426
|
+
currentPhase: "completed"
|
|
327
427
|
};
|
|
328
428
|
this.activeRuns.delete(initialRun.id);
|
|
429
|
+
const heartbeatTimer = this.heartbeatTimers.get(initialRun.id);
|
|
430
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
431
|
+
this.heartbeatTimers.delete(initialRun.id);
|
|
432
|
+
run = {
|
|
433
|
+
...run,
|
|
434
|
+
heartbeatAtMs: endedAtMs,
|
|
435
|
+
leaseOwner: void 0,
|
|
436
|
+
leaseExpiresAtMs: void 0
|
|
437
|
+
};
|
|
329
438
|
runSqliteWriteTransaction(() => {
|
|
330
439
|
saveAutomationRun(run);
|
|
331
440
|
this.appendRunEvent(run, "run.completed", `Automation run ${status}`, {
|
|
@@ -370,6 +479,73 @@ var AutomationService = class {
|
|
|
370
479
|
}
|
|
371
480
|
}
|
|
372
481
|
}
|
|
482
|
+
async recoverInterruptedRuns() {
|
|
483
|
+
const recoverable = listAutomationRuns({ limit: 500 }).filter((run) => run.status === "queued" || run.status === "running" || run.status === "cancelling");
|
|
484
|
+
for (const run of recoverable) {
|
|
485
|
+
const automation = getAutomation(run.automationId);
|
|
486
|
+
if (run.status === "queued" && automation) {
|
|
487
|
+
const claimed = {
|
|
488
|
+
...automation,
|
|
489
|
+
state: {
|
|
490
|
+
...automation.state,
|
|
491
|
+
runningRunId: run.id
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
saveAutomation(claimed);
|
|
495
|
+
this.appendRunEvent(run, "run.recovered", "Queued automation run recovered after restart", { previousLeaseOwner: run.leaseOwner });
|
|
496
|
+
this.executeRun(claimed, run).catch((err) => {
|
|
497
|
+
log.error({
|
|
498
|
+
err,
|
|
499
|
+
runId: run.id
|
|
500
|
+
}, "Recovered automation run failed");
|
|
501
|
+
});
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
const now = Date.now();
|
|
505
|
+
const status = run.status === "cancelling" ? "cancelled" : "failed";
|
|
506
|
+
const error = run.status === "cancelling" ? "Cancellation interrupted by gateway restart" : "Automation execution interrupted by gateway restart";
|
|
507
|
+
const recovered = {
|
|
508
|
+
...run,
|
|
509
|
+
status,
|
|
510
|
+
error,
|
|
511
|
+
endedAtMs: now,
|
|
512
|
+
durationMs: run.startedAtMs ? now - run.startedAtMs : void 0,
|
|
513
|
+
currentPhase: "completed",
|
|
514
|
+
heartbeatAtMs: now,
|
|
515
|
+
leaseOwner: void 0,
|
|
516
|
+
leaseExpiresAtMs: void 0,
|
|
517
|
+
termination: {
|
|
518
|
+
reason: status === "cancelled" ? "user_cancelled" : "failed",
|
|
519
|
+
component: "automation",
|
|
520
|
+
cancellationConfirmed: false
|
|
521
|
+
}
|
|
522
|
+
};
|
|
523
|
+
saveAutomationRun(recovered);
|
|
524
|
+
this.appendRunEvent(recovered, "run.recovered", error, {
|
|
525
|
+
previousLeaseOwner: run.leaseOwner,
|
|
526
|
+
previousLeaseExpiresAtMs: run.leaseExpiresAtMs
|
|
527
|
+
});
|
|
528
|
+
this.appendRunEvent(recovered, "run.completed", `Automation run ${status}`, {
|
|
529
|
+
status,
|
|
530
|
+
error
|
|
531
|
+
});
|
|
532
|
+
if (automation) this.finishAutomationRun(automation.id, status, error, now);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
waitForRetry(delayMs, signal) {
|
|
536
|
+
return new Promise((resolve, reject) => {
|
|
537
|
+
const timer = setTimeout(() => {
|
|
538
|
+
signal.removeEventListener("abort", onAbort);
|
|
539
|
+
resolve();
|
|
540
|
+
}, delayMs);
|
|
541
|
+
const onAbort = () => {
|
|
542
|
+
clearTimeout(timer);
|
|
543
|
+
reject(signal.reason ?? /* @__PURE__ */ new Error("Automation run was cancelled"));
|
|
544
|
+
};
|
|
545
|
+
if (signal.aborted) onAbort();
|
|
546
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
547
|
+
});
|
|
548
|
+
}
|
|
373
549
|
appendRunEvent(run, type, message, data) {
|
|
374
550
|
appendAutomationRunEvent({
|
|
375
551
|
id: randomUUID(),
|
|
@@ -404,11 +580,14 @@ var AutomationService = class {
|
|
|
404
580
|
saveAutomation(next);
|
|
405
581
|
this.armTimer();
|
|
406
582
|
}
|
|
407
|
-
async postAfterRunWebhook(url, run) {
|
|
583
|
+
async postAfterRunWebhook(url, run, signal) {
|
|
584
|
+
const remainingMs = run.deadlineAtMs === void 0 ? 3e4 : Math.max(1, run.deadlineAtMs - Date.now());
|
|
585
|
+
const requestSignal = AbortSignal.any([signal, AbortSignal.timeout(remainingMs)]);
|
|
408
586
|
const response = await fetch(url, {
|
|
409
587
|
method: "POST",
|
|
410
588
|
headers: { "content-type": "application/json" },
|
|
411
|
-
body: JSON.stringify({ run })
|
|
589
|
+
body: JSON.stringify({ run }),
|
|
590
|
+
signal: requestSignal
|
|
412
591
|
});
|
|
413
592
|
if (!response.ok) {
|
|
414
593
|
const text = await response.text().catch(() => "");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AutomationProductEventRun, AutomationRun, AutomationRunEvent } from '../domain/types.js';
|
|
2
2
|
export declare function appendAutomationRunEvent(event: AutomationRunEvent): void;
|
|
3
3
|
export declare function saveAutomationRun(run: AutomationRun): void;
|
|
4
|
+
export declare function touchAutomationRunLease(runId: string, leaseOwner: string, heartbeatAtMs: number, leaseExpiresAtMs: number): void;
|
|
4
5
|
export declare function listAutomationRunEvents(runId: string): AutomationRunEvent[];
|
|
5
6
|
export declare function getAutomationRun(runId: string): AutomationRun | null;
|
|
6
7
|
export declare function listAutomationRuns(options?: {
|