@xopcai/xopc 0.0.113 → 0.0.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CBlklyNr.js → agent-avatar-dicebear-Fp-p7bP1.js} +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-CWh7trjd.js +6 -0
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-kC8OuLoj.js +1 -0
- package/dist/gateway/static/root/assets/agents-DJWG26Si.js +71 -0
- package/dist/gateway/static/root/assets/{app-management-settings-panel-28E_WfMe.js → app-management-settings-panel-v24i25Oj.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Do1z0XgJ.js → appearance-settings-ycbdJRuZ.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-0V3DXZ7J.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BAFlsov_.js → archive-plugin-CJzSADJo.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-V3qGPC3x.js → attachment-load-BTAB4zGS.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DT8NvA6W.js → binary-plugins-DXR1-mct.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CdLMEcHd.js → block-editor-CzQri9h2.js} +44 -44
- package/dist/gateway/static/root/assets/channels-settings-CIKOkYdO.js +1 -0
- package/dist/gateway/static/root/assets/{config-api-Bf5mjpu7.js → config-api-DRqjEvAx.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-settings-ClrDS5jH.js +2 -0
- package/dist/gateway/static/root/assets/{cron-api--pAB_rps.js → cron-api-BXaZXv1o.js} +1 -1
- package/dist/gateway/static/root/assets/cron-page-Chi_4u4P.js +3 -0
- package/dist/gateway/static/root/assets/dreaming-settings-B0_rs2tj.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-BGhE7msg.js → extension-debug-page-DSkqMYo7.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CvpI45WG.js → extension-page-h2dGDbMN.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DAmR5FUe.js → extension-settings-page-hN99RhOi.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-NZmjSXLl.js → fetch-D9QqUtzZ.js} +1 -1
- package/dist/gateway/static/root/assets/{format-interval-label-qhth3BMV.js → format-interval-label-D6E687rG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-CaXBt-9R.js → gateway-config-api-CLt_SKTC.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DphpbLBc.js → gateway-settings-1PDi4lI0.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-Be1omjh3.js → gateway-startup-retry-N7Z_sz7p.js} +1 -1
- package/dist/gateway/static/root/assets/goal-detail-page-D_wwXL-t.js +1 -0
- package/dist/gateway/static/root/assets/goals-page-DZ2toZ8y.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-ceEBjnfc.js → goals-settings-LFlwtIKE.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-BzO6G4fD.js → heartbeat-config-api-DGPadTw-.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-DCST9-du.js → heartbeat-settings-BHHAs8ZX.js} +1 -1
- package/dist/gateway/static/root/assets/index-DefIdW9q.js +122 -0
- package/dist/gateway/static/root/assets/index-DzmWBkq-.css +1 -0
- package/dist/gateway/static/root/assets/{interval-presets-DJmshV8n.js → interval-presets-CEklPQ_r.js} +1 -1
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-9AUUlQ5Q.js → keyboard-shortcuts-settings-Ce_aQ8Iv.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-j_D2QTuQ.js +2 -0
- package/dist/gateway/static/root/assets/{markdown-split-CYYELqAr.js → markdown-split-BMz3xPXO.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-BEcMR2M8.js → media-plugins-BalOSoz9.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BN_WiUg0.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-panel-CMH_TmZz.js +2 -0
- package/dist/gateway/static/root/assets/note-detail-page-O18BrQPq.js +2 -0
- package/dist/gateway/static/root/assets/{note-image-lightbox-DNAoPcmm.js → note-image-lightbox-C5D1Q5mY.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-B_ZYCmY9.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BPLz0AIv.js → preview-open-alternatives-CYFR5U9l.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-CwKgWixY.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-CrWwWRVK.js → save-bar-controls-BQ79Z5IP.js} +1 -1
- package/dist/gateway/static/root/assets/{schedule-field-CF2sadvN.js → schedule-field-Bgk6Emue.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Di5cKjYE.js → schema-form-DzS36TMa.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-C4fcD-7B.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Ad2OJ86w.js +1 -0
- package/dist/gateway/static/root/assets/{settings-collapsible-section-Chh282jW.js → settings-collapsible-section-CdjFnSAy.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-Dq-83cQd.js → settings-form-section-DZLy_exu.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-D2BMY5wo.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-aWwxl_E1.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-0FXYnSUA.js → share-preview-page-_qRDr4g_.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-DUE83uIf.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-mWKJcrog.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-0Sx1Q58n.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-W1pTcojB.js → system-settings-panel-hqaBF5aG.js} +1 -1
- package/dist/gateway/static/root/assets/{use-agent-defaults-form-BVRvkK7m.js → use-agent-defaults-form-zbVIQLOA.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CgJibfMM.js → use-channel-catalog-CbXq97rT.js} +1 -1
- package/dist/gateway/static/root/assets/{use-settings-tab-guard-Bw_qkRQE.js → use-settings-tab-guard-DwS3drWK.js} +1 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-D6HR0hR2.js +1 -0
- package/dist/gateway/static/root/assets/{voice-player-store-C7lziaAx.js → voice-player-store-DSuOd9zy.js} +1 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-C0Uq3xyq.js +1 -0
- package/dist/gateway/static/root/assets/workflows-page-DW0fmWhQ.js +18 -0
- package/dist/gateway/static/root/index.html +5 -5
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.d.ts +8 -0
- package/dist/src/agent/agent-manager.js +57 -22
- package/dist/src/agent/agent-manager.js.map +1 -1
- package/dist/src/agent/bootstrap/project-agents-context.d.ts +2 -0
- package/dist/src/agent/bootstrap/project-agents-context.js +32 -0
- package/dist/src/agent/bootstrap/project-agents-context.js.map +1 -0
- package/dist/src/agent/goals/persistent-goal-service.js +2 -4
- package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
- package/dist/src/agent/inbound/inbound-loop.js +5 -1
- package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
- package/dist/src/agent/inbound/turn-dispatcher.d.ts +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js +2 -2
- package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.d.ts +27 -0
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +49 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +78 -3
- package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-types.d.ts +19 -0
- package/dist/src/agent/service/btw-query.js +11 -3
- package/dist/src/agent/service/btw-query.js.map +1 -1
- package/dist/src/agent/service/parse-outbound-session-key.js +13 -8
- package/dist/src/agent/service/parse-outbound-session-key.js.map +1 -1
- package/dist/src/agent/service/process-direct-one-shot.d.ts +2 -2
- package/dist/src/agent/service/process-direct-one-shot.js +1 -1
- package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
- package/dist/src/agent/service/process-direct-streaming.d.ts +2 -2
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
- package/dist/src/agent/service.d.ts +1 -1
- package/dist/src/agent/service.js +9 -5
- package/dist/src/agent/service.js.map +1 -1
- package/dist/src/agent/service.types.d.ts +5 -0
- package/dist/src/agent/skills/filesystem-watcher.js +4 -3
- package/dist/src/agent/skills/filesystem-watcher.js.map +1 -1
- package/dist/src/agent/skills/index.js +2 -1
- package/dist/src/agent/skills/index.js.map +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +2 -1
- package/dist/src/agent/skills/skill-manage-ops.js.map +1 -1
- package/dist/src/agent/skills/types.d.ts +1 -1
- package/dist/src/agent/skills/watcher.js +2 -5
- package/dist/src/agent/skills/watcher.js.map +1 -1
- package/dist/src/agent/skills/workspace-skills-dir.d.ts +1 -0
- package/dist/src/agent/skills/workspace-skills-dir.js +11 -0
- package/dist/src/agent/skills/workspace-skills-dir.js.map +1 -0
- package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
- package/dist/src/agent/tool-manuals/browser.js +62 -3
- package/dist/src/agent/tool-manuals/browser.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -1
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js +13 -4
- package/dist/src/agent/tools/browser/tool/browser-use-tool.js.map +1 -1
- package/dist/src/agent/tools/browser/tool/schemas.d.ts +0 -2
- package/dist/src/agent/tools/browser/tool/schemas.js +1 -2
- package/dist/src/agent/tools/browser/tool/schemas.js.map +1 -1
- package/dist/src/agent/tools/factory.js +1 -10
- package/dist/src/agent/tools/factory.js.map +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js.map +1 -1
- package/dist/src/agent/workflow/subagent-runner.js +18 -1
- package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
- package/dist/src/browser/actions/extension-registry-bridge.js +91 -7
- package/dist/src/browser/actions/extension-registry-bridge.js.map +1 -1
- package/dist/src/browser/actions/registry.js +383 -7
- package/dist/src/browser/actions/registry.js.map +1 -1
- package/dist/src/browser/actions/types.d.ts +11 -3
- package/dist/src/browser/index.js +2 -2
- package/dist/src/browser/pipeline/output.d.ts +18 -16
- package/dist/src/browser/pipeline/output.js +28 -20
- package/dist/src/browser/pipeline/output.js.map +1 -1
- package/dist/src/browser/pipeline/runner.d.ts +7 -14
- package/dist/src/browser/pipeline/runner.js +349 -102
- package/dist/src/browser/pipeline/runner.js.map +1 -1
- package/dist/src/browser/pipeline/schema.d.ts +1 -0
- package/dist/src/browser/pipeline/schema.js +35 -58
- package/dist/src/browser/pipeline/schema.js.map +1 -1
- package/dist/src/browser/pipeline/source.d.ts +2 -0
- package/dist/src/browser/pipeline/source.js +10 -1
- package/dist/src/browser/pipeline/source.js.map +1 -1
- package/dist/src/browser/pipeline/template.d.ts +10 -2
- package/dist/src/browser/pipeline/template.js +50 -8
- package/dist/src/browser/pipeline/template.js.map +1 -1
- package/dist/src/chat-commands/builtins/config.js +3 -5
- package/dist/src/chat-commands/builtins/config.js.map +1 -1
- package/dist/src/chat-commands/context.d.ts +5 -0
- package/dist/src/chat-commands/context.js +18 -9
- package/dist/src/chat-commands/context.js.map +1 -1
- package/dist/src/chat-commands/index.d.ts +1 -1
- package/dist/src/chat-commands/index.js +2 -2
- package/dist/src/chat-commands/index.js.map +1 -1
- package/dist/src/chat-commands/processor.js +22 -21
- package/dist/src/chat-commands/processor.js.map +1 -1
- package/dist/src/chat-commands/session-key.d.ts +3 -15
- package/dist/src/chat-commands/session-key.js +3 -49
- package/dist/src/chat-commands/session-key.js.map +1 -1
- package/dist/src/chat-commands/types.d.ts +4 -0
- package/dist/src/cli/commands/browser-cli-helpers.js +11 -5
- package/dist/src/cli/commands/browser-cli-helpers.js.map +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/session-integrity.js +8 -8
- package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
- package/dist/src/config/rules.js +5 -0
- package/dist/src/config/rules.js.map +1 -1
- package/dist/src/connectors/builtin-catalog.js +180 -1
- package/dist/src/connectors/builtin-catalog.js.map +1 -1
- package/dist/src/connectors/health.js +18 -9
- package/dist/src/connectors/health.js.map +1 -1
- package/dist/src/connectors/types.d.ts +19 -0
- package/dist/src/connectors/usage.js +12 -4
- package/dist/src/connectors/usage.js.map +1 -1
- package/dist/src/extensions/types/tui.d.ts +2 -0
- package/dist/src/gateway/heartbeat/service.js +13 -1
- package/dist/src/gateway/heartbeat/service.js.map +1 -1
- package/dist/src/gateway/hono/app.js +13 -4
- package/dist/src/gateway/hono/app.js.map +1 -1
- package/dist/src/gateway/hono/oauth-async.js +1 -1
- package/dist/src/gateway/hono/routes/agent-stream.js +6 -6
- package/dist/src/gateway/hono/routes/agent-stream.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.d.ts +1 -1
- package/dist/src/gateway/hono/routes/config-patch/gateway.js +6 -0
- package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
- package/dist/src/gateway/hono/routes/goals.js +16 -3
- package/dist/src/gateway/hono/routes/goals.js.map +1 -1
- package/dist/src/gateway/hono/routes/logs.js +1 -0
- package/dist/src/gateway/hono/routes/logs.js.map +1 -1
- package/dist/src/gateway/hono/routes/mcp.js +27 -8
- package/dist/src/gateway/hono/routes/mcp.js.map +1 -1
- package/dist/src/gateway/hono/routes/notes.js +14 -2
- package/dist/src/gateway/hono/routes/notes.js.map +1 -1
- package/dist/src/gateway/hono/routes/sessions.js +62 -4
- package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +3 -66
- package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
- package/dist/src/gateway/hono/sse.d.ts +2 -2
- package/dist/src/gateway/hono/sse.js +7 -15
- package/dist/src/gateway/hono/sse.js.map +1 -1
- package/dist/src/gateway/resolve-webchat-session-key.d.ts +2 -6
- package/dist/src/gateway/resolve-webchat-session-key.js +5 -31
- package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -1
- package/dist/src/gateway/service/agent-runner.d.ts +2 -3
- package/dist/src/gateway/service/agent-runner.js +9 -22
- package/dist/src/gateway/service/agent-runner.js.map +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +9 -7
- package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
- package/dist/src/gateway/service/sessions-api.d.ts +9 -0
- package/dist/src/gateway/service/sessions-api.js +11 -0
- package/dist/src/gateway/service/sessions-api.js.map +1 -1
- package/dist/src/gateway/service.d.ts +1 -1
- package/dist/src/gateway/service.js +19 -5
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-file-search.d.ts +9 -0
- package/dist/src/gateway/workspace-file-search.js +76 -0
- package/dist/src/gateway/workspace-file-search.js.map +1 -0
- package/dist/src/goals/goal-notifications.d.ts +2 -0
- package/dist/src/goals/goal-notifications.js +16 -11
- package/dist/src/goals/goal-notifications.js.map +1 -1
- package/dist/src/goals/goal-service.js +1 -6
- package/dist/src/goals/goal-service.js.map +1 -1
- package/dist/src/project-trust/trust-store.js +2 -0
- package/dist/src/project-trust/trust-store.js.map +1 -1
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +2 -2
- package/dist/src/session/init-session-turn.js +6 -9
- package/dist/src/session/init-session-turn.js.map +1 -1
- package/dist/src/session/manager.d.ts +5 -1
- package/dist/src/session/manager.js +5 -2
- package/dist/src/session/manager.js.map +1 -1
- package/dist/src/session/reset-type.d.ts +0 -2
- package/dist/src/session/reset-type.js +3 -9
- package/dist/src/session/reset-type.js.map +1 -1
- package/dist/src/session/resolve-session.js +9 -20
- package/dist/src/session/resolve-session.js.map +1 -1
- package/dist/src/session/store.d.ts +11 -3
- package/dist/src/session/store.js +29 -13
- package/dist/src/session/store.js.map +1 -1
- package/dist/src/session/types.d.ts +2 -4
- package/dist/src/session/types.js.map +1 -1
- package/dist/src/storage/sqlite/index.d.ts +2 -2
- package/dist/src/storage/sqlite/index.js +3 -3
- package/dist/src/storage/sqlite/migrations/010_session_id_identity.sql +30 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +2 -2
- package/dist/src/storage/sqlite/migrations/runner.js +4 -4
- package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
- package/dist/src/storage/sqlite/migrations/runner.ts +2 -2
- package/dist/src/storage/sqlite/row-mappers.d.ts +4 -4
- package/dist/src/storage/sqlite/row-mappers.js +11 -14
- package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
- package/dist/src/storage/sqlite/schema.js +3 -3
- package/dist/src/storage/sqlite/schema.js.map +1 -1
- package/dist/src/storage/sqlite/schema.sql +37 -10
- package/dist/src/storage/sqlite/session-metadata.d.ts +2 -7
- package/dist/src/storage/sqlite/session-metadata.js +18 -72
- package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
- package/dist/src/storage/sqlite/session-repository.d.ts +6 -5
- package/dist/src/storage/sqlite/session-repository.js +34 -40
- package/dist/src/storage/sqlite/session-repository.js.map +1 -1
- package/dist/src/storage/sqlite/transcript-repository.d.ts +2 -2
- package/dist/src/storage/sqlite/transcript-repository.js +52 -52
- package/dist/src/storage/sqlite/transcript-repository.js.map +1 -1
- package/dist/src/tui/backends/embedded-backend.d.ts +11 -4
- package/dist/src/tui/backends/embedded-backend.js +27 -1
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.d.ts +4 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +21 -2
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/extension-host/autocomplete.js +13 -10
- package/dist/src/tui/extension-host/autocomplete.js.map +1 -1
- package/dist/src/tui/extension-host/runtime.d.ts +7 -0
- package/dist/src/tui/extension-host/runtime.js +6 -4
- package/dist/src/tui/extension-host/runtime.js.map +1 -1
- package/dist/src/tui/tui-backend.d.ts +9 -0
- package/dist/src/tui/tui-commands.js +85 -6
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-file-autocomplete.d.ts +5 -0
- package/dist/src/tui/tui-file-autocomplete.js +26 -0
- package/dist/src/tui/tui-file-autocomplete.js.map +1 -0
- package/dist/src/tui/tui-picker-overlay.js +1 -1
- package/dist/src/tui/tui.js +29 -11
- package/dist/src/tui/tui.js.map +1 -1
- package/dist/src/utils/logger/context.d.ts +2 -2
- package/dist/src/utils/logger/context.js +2 -1
- package/dist/src/utils/logger/context.js.map +1 -1
- package/dist/src/utils/logger/log-store.js +1 -0
- package/dist/src/utils/logger/log-store.js.map +1 -1
- package/dist/src/utils/logger/pino-record.js +3 -0
- package/dist/src/utils/logger/pino-record.js.map +1 -1
- package/dist/src/utils/logger/types.d.ts +5 -0
- package/dist/src/utils/logger/types.js.map +1 -1
- package/dist/src/workflows/service/workflow-session-bridge.js +13 -1
- package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
- package/package.json +1 -1
- package/dist/gateway/static/root/assets/agent-browser-settings-page-rGbKc2Hh.js +0 -6
- package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-CtwVbjOA.js +0 -1
- package/dist/gateway/static/root/assets/agents-CCBmGcwc.js +0 -71
- package/dist/gateway/static/root/assets/apps-page-xwCsJS15.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-C044DcYk.js +0 -1
- package/dist/gateway/static/root/assets/connectors-settings-8VEWUOTj.js +0 -2
- package/dist/gateway/static/root/assets/cron-page-DqmNGNOy.js +0 -3
- package/dist/gateway/static/root/assets/dreaming-settings-6UZE1FSK.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-bv0VRDaf.js +0 -1
- package/dist/gateway/static/root/assets/goals-page-1Ywnt4Cb.js +0 -2
- package/dist/gateway/static/root/assets/index-Cxm6xsps.js +0 -122
- package/dist/gateway/static/root/assets/index-b_R4tKqt.css +0 -1
- package/dist/gateway/static/root/assets/logs-page-B_wrxhee.js +0 -2
- package/dist/gateway/static/root/assets/messages-CkT-lcgP.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-panel-D0JDSbNu.js +0 -2
- package/dist/gateway/static/root/assets/note-detail-page-DpFV-EO6.js +0 -2
- package/dist/gateway/static/root/assets/notes-page-CdkjTch8.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DSYVAi96.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CenkcVjF.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D9sva86V.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-DL35U0x0.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Ctwbp9Er.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-DIM3JNsr.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DAlNaNzL.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-CLrHVzAt.js +0 -2
- package/dist/gateway/static/root/assets/voice-api-key-field-vYAO71Gn.js +0 -1
- package/dist/gateway/static/root/assets/workflow-page.utils-sgHjOXOm.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DYyOTmFx.js +0 -18
|
@@ -1,87 +1,345 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { isTruthyValue, resolveTemplateDeep } from "./template.js";
|
|
3
4
|
import { parseBrowserPipeline } from "./schema.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { loadBrowserPipelineSource, resolvePipelineIncludeLocation } from "./source.js";
|
|
6
|
+
import { addStepTrace, createPipelineOutput, formatPipelineResult } from "./output.js";
|
|
7
|
+
import { setTimeout } from "node:timers/promises";
|
|
6
8
|
//#region src/browser/pipeline/runner.ts
|
|
7
|
-
init_logger();
|
|
8
|
-
const log = createLogger("PipelineRunner");
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Pipeline runner: deterministic browser automation DSL execution.
|
|
11
11
|
*/
|
|
12
|
+
init_logger();
|
|
13
|
+
const log = createLogger("PipelineRunner");
|
|
14
|
+
const CONTROL_ACTIONS = new Set([
|
|
15
|
+
"if",
|
|
16
|
+
"retry",
|
|
17
|
+
"sleep",
|
|
18
|
+
"set_var"
|
|
19
|
+
]);
|
|
12
20
|
function validateBrowserPipeline(yamlSource, registry) {
|
|
13
21
|
const parseResult = parseBrowserPipeline(yamlSource);
|
|
14
22
|
if (!parseResult.ok || !parseResult.document) return {
|
|
15
23
|
ok: false,
|
|
16
24
|
errors: parseResult.errors
|
|
17
25
|
};
|
|
18
|
-
const doc = parseResult.document;
|
|
19
26
|
const errors = [];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!registry.has(step.action)) errors.push({
|
|
24
|
-
path: `pipeline[${i}]`,
|
|
25
|
-
message: `Unknown action: "${step.action}"`
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
if (doc.onError) for (let i = 0; i < doc.onError.length; i++) {
|
|
29
|
-
const step = doc.onError[i];
|
|
30
|
-
if (!registry.has(step.action)) errors.push({
|
|
31
|
-
path: `on_error[${i}]`,
|
|
32
|
-
message: `Unknown action: "${step.action}"`
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
if (errors.length > 0) return {
|
|
27
|
+
validateSteps(parseResult.document.pipeline, "pipeline", registry, errors);
|
|
28
|
+
validateSteps(parseResult.document.onError ?? [], "on_error", registry, errors);
|
|
29
|
+
return errors.length > 0 ? {
|
|
37
30
|
ok: false,
|
|
38
|
-
document:
|
|
31
|
+
document: parseResult.document,
|
|
39
32
|
errors
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
33
|
+
} : {
|
|
42
34
|
ok: true,
|
|
43
|
-
document:
|
|
35
|
+
document: parseResult.document,
|
|
44
36
|
errors: []
|
|
45
37
|
};
|
|
46
38
|
}
|
|
39
|
+
async function validateBrowserPipelineSource(yamlSource, registry, sourceLocation) {
|
|
40
|
+
try {
|
|
41
|
+
const doc = await expandPipelineDocument(yamlSource, sourceLocation);
|
|
42
|
+
const errors = [];
|
|
43
|
+
validateSteps(doc.pipeline, "pipeline", registry, errors);
|
|
44
|
+
validateSteps(doc.onError ?? [], "on_error", registry, errors);
|
|
45
|
+
return errors.length > 0 ? {
|
|
46
|
+
ok: false,
|
|
47
|
+
document: doc,
|
|
48
|
+
errors
|
|
49
|
+
} : {
|
|
50
|
+
ok: true,
|
|
51
|
+
document: doc,
|
|
52
|
+
errors: []
|
|
53
|
+
};
|
|
54
|
+
} catch (e) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
errors: [{
|
|
58
|
+
path: "",
|
|
59
|
+
message: e instanceof Error ? e.message : String(e)
|
|
60
|
+
}]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function validateSteps(steps, path, registry, errors) {
|
|
65
|
+
if (!registry) return;
|
|
66
|
+
for (let i = 0; i < steps.length; i++) {
|
|
67
|
+
const step = steps[i];
|
|
68
|
+
if (!CONTROL_ACTIONS.has(step.action) && !registry.has(step.action)) errors.push({
|
|
69
|
+
path: `${path}[${i}]`,
|
|
70
|
+
message: `Unknown action: "${step.action}"`
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function expandPipelineDocument(yamlSource, sourceLocation, visiting = /* @__PURE__ */ new Set()) {
|
|
75
|
+
const parsed = parseBrowserPipeline(yamlSource);
|
|
76
|
+
if (!parsed.ok || !parsed.document) {
|
|
77
|
+
const message = parsed.errors.map((e) => `${e.path}: ${e.message}`).join("\n");
|
|
78
|
+
throw new Error(message);
|
|
79
|
+
}
|
|
80
|
+
const doc = parsed.document;
|
|
81
|
+
const key = sourceLocation ?? `inline:${doc.name}`;
|
|
82
|
+
if (visiting.has(key)) throw new Error(`Circular pipeline include detected: ${key}`);
|
|
83
|
+
visiting.add(key);
|
|
84
|
+
let merged = {
|
|
85
|
+
name: doc.name,
|
|
86
|
+
description: doc.description,
|
|
87
|
+
provider: doc.provider,
|
|
88
|
+
include: [],
|
|
89
|
+
timeoutSeconds: doc.timeoutSeconds,
|
|
90
|
+
args: {},
|
|
91
|
+
pipeline: [],
|
|
92
|
+
onError: []
|
|
93
|
+
};
|
|
94
|
+
for (const includePath of doc.include ?? []) {
|
|
95
|
+
const includeSource = await loadBrowserPipelineSource(resolvePipelineIncludeLocation(includePath, sourceLocation));
|
|
96
|
+
const includeDoc = await expandPipelineDocument(includeSource.source, includeSource.location, visiting);
|
|
97
|
+
merged = mergePipelineDocuments(merged, includeDoc);
|
|
98
|
+
}
|
|
99
|
+
merged = mergePipelineDocuments(merged, doc);
|
|
100
|
+
visiting.delete(key);
|
|
101
|
+
return merged;
|
|
102
|
+
}
|
|
103
|
+
function mergePipelineDocuments(target, source) {
|
|
104
|
+
return {
|
|
105
|
+
name: source.name || target.name,
|
|
106
|
+
description: source.description ?? target.description,
|
|
107
|
+
provider: source.provider ?? target.provider,
|
|
108
|
+
include: [...target.include ?? [], ...source.include ?? []],
|
|
109
|
+
timeoutSeconds: source.timeoutSeconds ?? target.timeoutSeconds,
|
|
110
|
+
args: {
|
|
111
|
+
...target.args,
|
|
112
|
+
...source.args
|
|
113
|
+
},
|
|
114
|
+
pipeline: [...target.pipeline, ...source.pipeline],
|
|
115
|
+
onError: [...target.onError ?? [], ...source.onError ?? []]
|
|
116
|
+
};
|
|
117
|
+
}
|
|
47
118
|
function resolveArgs(doc, overrides) {
|
|
48
119
|
const resolved = {};
|
|
49
|
-
for (const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
120
|
+
for (const key of Object.keys(overrides)) if (!(key in doc.args)) throw new Error(`Unknown pipeline arg: ${key}`);
|
|
121
|
+
for (const [key, def] of Object.entries(doc.args)) {
|
|
122
|
+
const value = key in overrides ? overrides[key] : def.default;
|
|
123
|
+
if (value === void 0) {
|
|
124
|
+
if (def.required) throw new Error(`Missing required arg: ${key}`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (def.choices && !def.choices.some((choice) => Object.is(choice, value))) throw new Error(`Invalid value for arg ${key}: expected one of ${def.choices.map(String).join(", ")}`);
|
|
128
|
+
resolved[key] = value;
|
|
129
|
+
}
|
|
53
130
|
return resolved;
|
|
54
131
|
}
|
|
55
|
-
|
|
56
|
-
|
|
132
|
+
function templateContext(runtime) {
|
|
133
|
+
return {
|
|
134
|
+
args: runtime.args,
|
|
135
|
+
last: runtime.last,
|
|
136
|
+
outputs: runtime.outputs,
|
|
137
|
+
vars: runtime.vars,
|
|
138
|
+
error: runtime.error
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function actionArgs(step, runtime) {
|
|
57
142
|
if (typeof step.args === "string") {
|
|
58
|
-
const resolved = resolveTemplateDeep(step.args,
|
|
59
|
-
if (step.action === "evaluate" || step.action === "eval" || step.action === "console")
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return
|
|
143
|
+
const resolved = resolveTemplateDeep(step.args, templateContext(runtime));
|
|
144
|
+
if (step.action === "evaluate" || step.action === "eval" || step.action === "console") return { javascript: String(resolved ?? "") };
|
|
145
|
+
return { value: resolved };
|
|
146
|
+
}
|
|
147
|
+
return resolveTemplateDeep(step.args, templateContext(runtime));
|
|
63
148
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
149
|
+
async function executePipeline(steps, scope, runtime, actionCtx, registry, output) {
|
|
150
|
+
for (let i = 0; i < steps.length; i++) {
|
|
151
|
+
if (actionCtx.signal?.aborted) throw actionError("ABORTED", "Pipeline aborted");
|
|
152
|
+
await executeStep(steps[i], i, scope, runtime, actionCtx, registry, output);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function executeStep(step, index, scope, runtime, actionCtx, registry, output) {
|
|
156
|
+
const started = Date.now();
|
|
157
|
+
let result;
|
|
158
|
+
try {
|
|
159
|
+
result = await executeStepOnce(step, index, scope, runtime, actionCtx, registry, output);
|
|
160
|
+
} catch (e) {
|
|
161
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
162
|
+
result = {
|
|
163
|
+
ok: false,
|
|
164
|
+
action: step.action,
|
|
165
|
+
error: {
|
|
166
|
+
code: error.code ?? "STEP_FAILED",
|
|
167
|
+
message: error.message
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
addStepTrace(output, {
|
|
172
|
+
index,
|
|
173
|
+
scope,
|
|
174
|
+
action: step.action,
|
|
175
|
+
ok: result.ok,
|
|
176
|
+
elapsedMs: Date.now() - started,
|
|
177
|
+
text: result.text?.slice(0, 500),
|
|
178
|
+
data: result.data,
|
|
179
|
+
error: result.error
|
|
180
|
+
}, result);
|
|
181
|
+
if (!result.ok) {
|
|
182
|
+
runtime.error = result.error;
|
|
183
|
+
throw actionError(result.error?.code ?? "STEP_FAILED", result.error?.message ?? "Step failed");
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function executeStepOnce(step, index, scope, runtime, actionCtx, registry, output) {
|
|
187
|
+
switch (step.action) {
|
|
188
|
+
case "sleep": {
|
|
189
|
+
const args = actionArgs(step, runtime);
|
|
190
|
+
const ms = Number(args.ms ?? args.delay_ms ?? args.delayMs ?? 1e3);
|
|
191
|
+
await setTimeout(Number.isFinite(ms) ? ms : 1e3, void 0, { signal: actionCtx.signal });
|
|
192
|
+
runtime.last = null;
|
|
193
|
+
return {
|
|
194
|
+
ok: true,
|
|
195
|
+
action: "sleep",
|
|
196
|
+
text: `Slept ${ms}ms.`,
|
|
197
|
+
data: null
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
case "set_var": {
|
|
201
|
+
const args = actionArgs(step, runtime);
|
|
202
|
+
const name = String(args.name ?? "");
|
|
203
|
+
if (!name) return {
|
|
204
|
+
ok: false,
|
|
205
|
+
action: "set_var",
|
|
206
|
+
error: {
|
|
207
|
+
code: "INVALID_ARGS",
|
|
208
|
+
message: "name is required"
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
runtime.vars[name] = args.value;
|
|
212
|
+
runtime.last = args.value;
|
|
213
|
+
return {
|
|
214
|
+
ok: true,
|
|
215
|
+
action: "set_var",
|
|
216
|
+
text: `Set var: ${name}`,
|
|
217
|
+
data: args.value
|
|
218
|
+
};
|
|
81
219
|
}
|
|
220
|
+
case "if": {
|
|
221
|
+
const args = actionArgs(step, runtime);
|
|
222
|
+
await executePipeline(normalizeNestedPipeline(isTruthyValue(args.condition) ? args.then : args.else, `${scope}.${index}.if`), `${scope}.${index}.if`, runtime, actionCtx, registry, output);
|
|
223
|
+
return {
|
|
224
|
+
ok: true,
|
|
225
|
+
action: "if",
|
|
226
|
+
text: "Conditional branch completed.",
|
|
227
|
+
data: runtime.last
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
case "retry": {
|
|
231
|
+
const args = actionArgs(step, runtime);
|
|
232
|
+
const times = Math.max(1, Number(args.times ?? 3));
|
|
233
|
+
const delayMs = Math.max(0, Number(args.delay_ms ?? args.delayMs ?? 250));
|
|
234
|
+
const retrySteps = normalizeNestedPipeline(args.pipeline ?? args.step, `${scope}.${index}.retry`);
|
|
235
|
+
let lastError;
|
|
236
|
+
for (let attempt = 1; attempt <= times; attempt++) try {
|
|
237
|
+
await executePipeline(retrySteps, `${scope}.${index}.retry.${attempt}`, runtime, actionCtx, registry, output);
|
|
238
|
+
output.ok = true;
|
|
239
|
+
output.error = void 0;
|
|
240
|
+
return {
|
|
241
|
+
ok: true,
|
|
242
|
+
action: "retry",
|
|
243
|
+
text: `Retry block completed on attempt ${attempt}.`,
|
|
244
|
+
data: runtime.last
|
|
245
|
+
};
|
|
246
|
+
} catch (e) {
|
|
247
|
+
lastError = e;
|
|
248
|
+
output.ok = true;
|
|
249
|
+
output.error = void 0;
|
|
250
|
+
if (attempt < times) await setTimeout(delayMs, void 0, { signal: actionCtx.signal });
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
ok: false,
|
|
254
|
+
action: "retry",
|
|
255
|
+
error: {
|
|
256
|
+
code: "RETRY_FAILED",
|
|
257
|
+
message: lastError instanceof Error ? lastError.message : String(lastError)
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
default: return executeBrowserAction(step, runtime, actionCtx, registry);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async function executeBrowserAction(step, runtime, actionCtx, registry) {
|
|
265
|
+
const args = actionArgs(step, runtime);
|
|
266
|
+
actionCtx.pipeline = {
|
|
267
|
+
args: runtime.args,
|
|
268
|
+
last: runtime.last,
|
|
269
|
+
outputs: runtime.outputs,
|
|
270
|
+
vars: runtime.vars,
|
|
271
|
+
error: runtime.error
|
|
82
272
|
};
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
273
|
+
const result = await registry.execute(step.action, actionCtx, args);
|
|
274
|
+
if (result.ok) {
|
|
275
|
+
if (step.action === "output") runtime.outputs.push(result.data);
|
|
276
|
+
if (result.data !== void 0) runtime.last = result.data;
|
|
277
|
+
}
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
function normalizeNestedPipeline(value, path) {
|
|
281
|
+
return (Array.isArray(value) ? value : value ? [value] : []).map((rawStep, index) => {
|
|
282
|
+
if (!rawStep || typeof rawStep !== "object" || Array.isArray(rawStep)) throw new Error(`${path}[${index}] must be a YAML object`);
|
|
283
|
+
const obj = rawStep;
|
|
284
|
+
const keys = Object.keys(obj);
|
|
285
|
+
if (keys.length !== 1) throw new Error(`${path}[${index}] must contain exactly one action`);
|
|
286
|
+
const action = keys[0];
|
|
287
|
+
const args = obj[action];
|
|
288
|
+
if (typeof args === "string") return {
|
|
289
|
+
action,
|
|
290
|
+
args
|
|
291
|
+
};
|
|
292
|
+
if (args && typeof args === "object" && !Array.isArray(args)) return {
|
|
293
|
+
action,
|
|
294
|
+
args
|
|
295
|
+
};
|
|
296
|
+
if (args === void 0 || args === null) return {
|
|
297
|
+
action,
|
|
298
|
+
args: {}
|
|
299
|
+
};
|
|
300
|
+
return {
|
|
301
|
+
action,
|
|
302
|
+
args: { value: args }
|
|
303
|
+
};
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
function actionError(code, message) {
|
|
307
|
+
const error = new Error(message);
|
|
308
|
+
error.code = code;
|
|
309
|
+
return error;
|
|
310
|
+
}
|
|
311
|
+
async function runBrowserPipeline(yamlSource, argOverrides, ctx, registry, options = {}) {
|
|
312
|
+
let doc;
|
|
313
|
+
try {
|
|
314
|
+
doc = await expandPipelineDocument(yamlSource, options.sourceLocation);
|
|
315
|
+
} catch (e) {
|
|
316
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
317
|
+
return {
|
|
318
|
+
ok: false,
|
|
319
|
+
action: "pipeline",
|
|
320
|
+
error: {
|
|
321
|
+
code: "VALIDATION_FAILED",
|
|
322
|
+
message: msg
|
|
323
|
+
},
|
|
324
|
+
text: msg
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
const validationErrors = [];
|
|
328
|
+
validateSteps(doc.pipeline, "pipeline", registry, validationErrors);
|
|
329
|
+
validateSteps(doc.onError ?? [], "on_error", registry, validationErrors);
|
|
330
|
+
if (validationErrors.length > 0) {
|
|
331
|
+
const msg = validationErrors.map((e) => `${e.path}: ${e.message}`).join("\n");
|
|
332
|
+
return {
|
|
333
|
+
ok: false,
|
|
334
|
+
action: "pipeline",
|
|
335
|
+
error: {
|
|
336
|
+
code: "VALIDATION_FAILED",
|
|
337
|
+
message: msg
|
|
338
|
+
},
|
|
339
|
+
text: msg
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
if (options.dryRun) return {
|
|
85
343
|
ok: true,
|
|
86
344
|
action: "pipeline",
|
|
87
345
|
text: `Pipeline "${doc.name}" validated successfully (${doc.pipeline.length} steps).`,
|
|
@@ -91,72 +349,61 @@ async function runBrowserPipeline(yamlSource, argOverrides, ctx, registry, dryRu
|
|
|
91
349
|
args: Object.keys(doc.args)
|
|
92
350
|
}
|
|
93
351
|
};
|
|
94
|
-
let
|
|
352
|
+
let args;
|
|
95
353
|
try {
|
|
96
|
-
|
|
354
|
+
args = resolveArgs(doc, argOverrides);
|
|
97
355
|
} catch (e) {
|
|
356
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
98
357
|
return {
|
|
99
358
|
ok: false,
|
|
100
359
|
action: "pipeline",
|
|
101
360
|
error: {
|
|
102
361
|
code: "ARG_RESOLUTION_FAILED",
|
|
103
|
-
message:
|
|
104
|
-
}
|
|
362
|
+
message: msg
|
|
363
|
+
},
|
|
364
|
+
text: msg
|
|
105
365
|
};
|
|
106
366
|
}
|
|
107
367
|
const output = createPipelineOutput(doc.name);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
args
|
|
111
|
-
|
|
368
|
+
const runtime = {
|
|
369
|
+
doc,
|
|
370
|
+
args,
|
|
371
|
+
last: void 0,
|
|
372
|
+
outputs: [],
|
|
373
|
+
vars: {}
|
|
112
374
|
};
|
|
113
|
-
ctx.pipelineData = void 0;
|
|
114
375
|
log.info({
|
|
115
376
|
pipeline: doc.name,
|
|
116
377
|
steps: doc.pipeline.length
|
|
117
378
|
}, `Running pipeline: ${doc.name}`);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (result.ok && result.data !== void 0) {
|
|
133
|
-
data = result.data;
|
|
134
|
-
templateCtx.data = data;
|
|
135
|
-
ctx.pipelineData = data;
|
|
136
|
-
}
|
|
137
|
-
if (step.action === "output" && result.ok && result.data !== void 0) output.data = result.data;
|
|
138
|
-
if (!result.ok) {
|
|
139
|
-
templateCtx.error = result.error ? {
|
|
140
|
-
code: result.error.code,
|
|
141
|
-
message: result.error.message
|
|
142
|
-
} : void 0;
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
379
|
+
try {
|
|
380
|
+
const run = executePipeline(doc.pipeline, "pipeline", runtime, ctx, registry, output);
|
|
381
|
+
if (doc.timeoutSeconds && doc.timeoutSeconds > 0) await Promise.race([run, setTimeout(doc.timeoutSeconds * 1e3, void 0, { signal: ctx.signal }).then(() => {
|
|
382
|
+
throw actionError("PIPELINE_TIMEOUT", `Pipeline timed out after ${doc.timeoutSeconds} seconds`);
|
|
383
|
+
})]);
|
|
384
|
+
else await run;
|
|
385
|
+
} catch {
|
|
386
|
+
output.ok = false;
|
|
387
|
+
output.error ??= {
|
|
388
|
+
step: output.trace.length,
|
|
389
|
+
action: "pipeline",
|
|
390
|
+
code: "PIPELINE_FAILED",
|
|
391
|
+
message: runtime.error?.message ?? "Pipeline failed"
|
|
392
|
+
};
|
|
145
393
|
}
|
|
146
|
-
|
|
394
|
+
output.last = runtime.last;
|
|
395
|
+
output.outputs = runtime.outputs;
|
|
147
396
|
if (!output.ok && doc.onError && doc.onError.length > 0) {
|
|
148
397
|
log.info({ pipeline: doc.name }, "Running on_error diagnostics");
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
} catch {}
|
|
155
|
-
}
|
|
398
|
+
try {
|
|
399
|
+
await executePipeline(doc.onError, "on_error", runtime, ctx, registry, output);
|
|
400
|
+
} catch {}
|
|
401
|
+
output.last = runtime.last;
|
|
402
|
+
output.outputs = runtime.outputs;
|
|
156
403
|
}
|
|
157
404
|
return formatPipelineResult(output);
|
|
158
405
|
}
|
|
159
406
|
//#endregion
|
|
160
|
-
export { runBrowserPipeline, validateBrowserPipeline };
|
|
407
|
+
export { runBrowserPipeline, validateBrowserPipeline, validateBrowserPipelineSource };
|
|
161
408
|
|
|
162
409
|
//# sourceMappingURL=runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","names":[],"sources":["../../../../src/browser/pipeline/runner.ts"],"sourcesContent":["/**\n * Pipeline runner — validate and execute brocli-style YAML browser pipelines.\n */\n\nimport { createLogger } from '../../utils/logger.js';\nimport type { BrowserActionContext, BrowserActionRegistry, BrowserActionResult } from '../actions/types.js';\nimport { parseBrowserPipeline, type PipelineDocument, type PipelineStep } from './schema.js';\nimport { resolveTemplateDeep, type TemplateContext } from './template.js';\nimport { addStepResult, createPipelineOutput, formatPipelineResult } from './output.js';\n\nconst log = createLogger('PipelineRunner');\n\n// ─── Validate ───────────────────────────────────────────────────────────────\n\nexport interface ValidateResult {\n ok: boolean;\n document?: PipelineDocument;\n errors: { path: string; message: string }[];\n}\n\n/**\n * Parse and validate a pipeline YAML without executing it.\n */\nexport function validateBrowserPipeline(yamlSource: string, registry?: BrowserActionRegistry): ValidateResult {\n const parseResult = parseBrowserPipeline(yamlSource);\n if (!parseResult.ok || !parseResult.document) {\n return { ok: false, errors: parseResult.errors };\n }\n\n const doc = parseResult.document;\n const errors: { path: string; message: string }[] = [];\n\n // Validate actions exist in registry\n if (registry) {\n for (let i = 0; i < doc.pipeline.length; i++) {\n const step = doc.pipeline[i];\n if (!registry.has(step.action)) {\n errors.push({ path: `pipeline[${i}]`, message: `Unknown action: \"${step.action}\"` });\n }\n }\n if (doc.onError) {\n for (let i = 0; i < doc.onError.length; i++) {\n const step = doc.onError[i];\n if (!registry.has(step.action)) {\n errors.push({ path: `on_error[${i}]`, message: `Unknown action: \"${step.action}\"` });\n }\n }\n }\n }\n\n if (errors.length > 0) {\n return { ok: false, document: doc, errors };\n }\n\n return { ok: true, document: doc, errors: [] };\n}\n\n// ─── Resolve args ───────────────────────────────────────────────────────────\n\nfunction resolveArgs(doc: PipelineDocument, overrides: Record<string, unknown>): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n for (const [key, def] of Object.entries(doc.args)) {\n if (key in overrides) {\n resolved[key] = overrides[key];\n } else if (def.default !== undefined) {\n resolved[key] = def.default;\n } else if (def.required) {\n throw new Error(`Missing required arg: ${key}`);\n }\n }\n // Pass through any extra overrides not in schema\n for (const [key, val] of Object.entries(overrides)) {\n if (!(key in resolved)) resolved[key] = val;\n }\n return resolved;\n}\n\n// ─── Execute step ───────────────────────────────────────────────────────────\n\nasync function executeStep(\n step: PipelineStep,\n templateCtx: TemplateContext,\n actionCtx: BrowserActionContext,\n registry: BrowserActionRegistry,\n): Promise<BrowserActionResult> {\n // Resolve templates in step args\n let resolvedArgs: Record<string, unknown>;\n if (typeof step.args === 'string') {\n // Shorthand: e.g. `evaluate: |` — the string IS the expression/code\n const resolved = resolveTemplateDeep(step.args, templateCtx) as string;\n // For evaluate/console, pass as `javascript`; for others, as `value`\n if (step.action === 'evaluate' || step.action === 'eval' || step.action === 'console') {\n resolvedArgs = { javascript: resolved };\n } else {\n resolvedArgs = { value: resolved };\n }\n } else {\n resolvedArgs = resolveTemplateDeep(step.args, templateCtx) as Record<string, unknown>;\n }\n\n return registry.execute(step.action, actionCtx, resolvedArgs);\n}\n\n// ─── Run ────────────────────────────────────────────────────────────────────\n\n/**\n * Run a browser pipeline from YAML source.\n *\n * @param yamlSource - Raw YAML text.\n * @param argOverrides - Runtime argument overrides.\n * @param ctx - Browser action context (page, manager, config, etc.).\n * @param registry - Action registry.\n * @param dryRun - When true, only validate without executing.\n */\nexport async function runBrowserPipeline(\n yamlSource: string,\n argOverrides: Record<string, unknown>,\n ctx: BrowserActionContext,\n registry: BrowserActionRegistry,\n dryRun = false,\n): Promise<BrowserActionResult> {\n // Parse & validate\n const validation = validateBrowserPipeline(yamlSource, registry);\n if (!validation.ok || !validation.document) {\n const errMsg = validation.errors.map((e) => `${e.path}: ${e.message}`).join('\\n');\n return {\n ok: false,\n action: 'pipeline',\n error: { code: 'VALIDATION_FAILED', message: errMsg },\n };\n }\n\n const doc = validation.document;\n\n // Dry run: just return validation success\n if (dryRun) {\n return {\n ok: true,\n action: 'pipeline',\n text: `Pipeline \"${doc.name}\" validated successfully (${doc.pipeline.length} steps).`,\n data: { name: doc.name, steps: doc.pipeline.length, args: Object.keys(doc.args) },\n };\n }\n\n // Resolve args\n let resolvedArgs: Record<string, unknown>;\n try {\n resolvedArgs = resolveArgs(doc, argOverrides);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return {\n ok: false,\n action: 'pipeline',\n error: { code: 'ARG_RESOLUTION_FAILED', message: msg },\n };\n }\n\n const output = createPipelineOutput(doc.name);\n let data: unknown = undefined;\n\n const templateCtx: TemplateContext = {\n args: resolvedArgs,\n data: undefined,\n };\n\n // Inject pipeline data into action context\n ctx.pipelineData = undefined;\n\n log.info({ pipeline: doc.name, steps: doc.pipeline.length }, `Running pipeline: ${doc.name}`);\n\n // Execute main pipeline\n for (let i = 0; i < doc.pipeline.length; i++) {\n if (ctx.signal?.aborted) {\n output.ok = false;\n output.error = { step: i, action: 'abort', code: 'ABORTED', message: 'Pipeline aborted' };\n break;\n }\n\n const step = doc.pipeline[i];\n const result = await executeStep(step, templateCtx, ctx, registry);\n addStepResult(output, i, result);\n\n // Update data accumulator\n if (result.ok && result.data !== undefined) {\n data = result.data;\n templateCtx.data = data;\n ctx.pipelineData = data;\n }\n\n // If output action, capture as final data\n if (step.action === 'output' && result.ok && result.data !== undefined) {\n output.data = result.data;\n }\n\n // Stop on failure\n if (!result.ok) {\n templateCtx.error = result.error ? { code: result.error.code, message: result.error.message } : undefined;\n break;\n }\n }\n\n // If pipeline succeeded but no explicit output, use last data\n if (output.ok && output.data === undefined) {\n output.data = data;\n }\n\n // Run on_error if pipeline failed\n if (!output.ok && doc.onError && doc.onError.length > 0) {\n log.info({ pipeline: doc.name }, 'Running on_error diagnostics');\n for (const step of doc.onError) {\n if (ctx.signal?.aborted) break;\n try {\n const result = await executeStep(step, templateCtx, ctx, registry);\n // Collect artifacts from error handlers (screenshots, etc.)\n if (result.artifacts) output.artifacts.push(...result.artifacts);\n } catch {\n // on_error steps should not throw\n }\n }\n }\n\n return formatPipelineResult(output);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","names":["sleep"],"sources":["../../../../src/browser/pipeline/runner.ts"],"sourcesContent":["/**\n * Pipeline runner: deterministic browser automation DSL execution.\n */\n\nimport { setTimeout as sleep } from 'node:timers/promises';\n\nimport { createLogger } from '../../utils/logger.js';\nimport type { BrowserActionContext, BrowserActionRegistry, BrowserActionResult } from '../actions/types.js';\nimport { loadBrowserPipelineSource, resolvePipelineIncludeLocation } from './source.js';\nimport { parseBrowserPipeline, type PipelineDocument, type PipelineStep } from './schema.js';\nimport { isTruthyValue, resolveTemplateDeep, type TemplateContext } from './template.js';\nimport { addStepTrace, createPipelineOutput, formatPipelineResult, type PipelineOutput } from './output.js';\n\nconst log = createLogger('PipelineRunner');\n\nconst CONTROL_ACTIONS = new Set(['if', 'retry', 'sleep', 'set_var']);\n\nexport interface ValidateResult {\n ok: boolean;\n document?: PipelineDocument;\n errors: { path: string; message: string }[];\n}\n\nexport interface RunBrowserPipelineOptions {\n dryRun?: boolean;\n sourceLocation?: string;\n}\n\ninterface PipelineRuntime {\n doc: PipelineDocument;\n args: Record<string, unknown>;\n last: unknown;\n outputs: unknown[];\n vars: Record<string, unknown>;\n error?: { code?: string; message?: string };\n}\n\nexport function validateBrowserPipeline(yamlSource: string, registry?: BrowserActionRegistry): ValidateResult {\n const parseResult = parseBrowserPipeline(yamlSource);\n if (!parseResult.ok || !parseResult.document) {\n return { ok: false, errors: parseResult.errors };\n }\n\n const errors: { path: string; message: string }[] = [];\n validateSteps(parseResult.document.pipeline, 'pipeline', registry, errors);\n validateSteps(parseResult.document.onError ?? [], 'on_error', registry, errors);\n return errors.length > 0\n ? { ok: false, document: parseResult.document, errors }\n : { ok: true, document: parseResult.document, errors: [] };\n}\n\nexport async function validateBrowserPipelineSource(\n yamlSource: string,\n registry?: BrowserActionRegistry,\n sourceLocation?: string,\n): Promise<ValidateResult> {\n try {\n const doc = await expandPipelineDocument(yamlSource, sourceLocation);\n const errors: { path: string; message: string }[] = [];\n validateSteps(doc.pipeline, 'pipeline', registry, errors);\n validateSteps(doc.onError ?? [], 'on_error', registry, errors);\n return errors.length > 0 ? { ok: false, document: doc, errors } : { ok: true, document: doc, errors: [] };\n } catch (e) {\n return { ok: false, errors: [{ path: '', message: e instanceof Error ? e.message : String(e) }] };\n }\n}\n\nfunction validateSteps(\n steps: PipelineStep[],\n path: string,\n registry: BrowserActionRegistry | undefined,\n errors: { path: string; message: string }[],\n): void {\n if (!registry) return;\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n if (!CONTROL_ACTIONS.has(step.action) && !registry.has(step.action)) {\n errors.push({ path: `${path}[${i}]`, message: `Unknown action: \"${step.action}\"` });\n }\n }\n}\n\nasync function expandPipelineDocument(\n yamlSource: string,\n sourceLocation: string | undefined,\n visiting = new Set<string>(),\n): Promise<PipelineDocument> {\n const parsed = parseBrowserPipeline(yamlSource);\n if (!parsed.ok || !parsed.document) {\n const message = parsed.errors.map((e) => `${e.path}: ${e.message}`).join('\\n');\n throw new Error(message);\n }\n\n const doc = parsed.document;\n const key = sourceLocation ?? `inline:${doc.name}`;\n if (visiting.has(key)) {\n throw new Error(`Circular pipeline include detected: ${key}`);\n }\n\n visiting.add(key);\n let merged: PipelineDocument = {\n name: doc.name,\n description: doc.description,\n provider: doc.provider,\n include: [],\n timeoutSeconds: doc.timeoutSeconds,\n args: {},\n pipeline: [],\n onError: [],\n };\n\n for (const includePath of doc.include ?? []) {\n const includeLocation = resolvePipelineIncludeLocation(includePath, sourceLocation);\n const includeSource = await loadBrowserPipelineSource(includeLocation);\n const includeDoc = await expandPipelineDocument(includeSource.source, includeSource.location, visiting);\n merged = mergePipelineDocuments(merged, includeDoc);\n }\n\n merged = mergePipelineDocuments(merged, doc);\n visiting.delete(key);\n return merged;\n}\n\nfunction mergePipelineDocuments(target: PipelineDocument, source: PipelineDocument): PipelineDocument {\n return {\n name: source.name || target.name,\n description: source.description ?? target.description,\n provider: source.provider ?? target.provider,\n include: [...(target.include ?? []), ...(source.include ?? [])],\n timeoutSeconds: source.timeoutSeconds ?? target.timeoutSeconds,\n args: { ...target.args, ...source.args },\n pipeline: [...target.pipeline, ...source.pipeline],\n onError: [...(target.onError ?? []), ...(source.onError ?? [])],\n };\n}\n\nfunction resolveArgs(doc: PipelineDocument, overrides: Record<string, unknown>): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n for (const key of Object.keys(overrides)) {\n if (!(key in doc.args)) {\n throw new Error(`Unknown pipeline arg: ${key}`);\n }\n }\n for (const [key, def] of Object.entries(doc.args)) {\n const value = key in overrides ? overrides[key] : def.default;\n if (value === undefined) {\n if (def.required) throw new Error(`Missing required arg: ${key}`);\n continue;\n }\n if (def.choices && !def.choices.some((choice) => Object.is(choice, value))) {\n throw new Error(`Invalid value for arg ${key}: expected one of ${def.choices.map(String).join(', ')}`);\n }\n resolved[key] = value;\n }\n return resolved;\n}\n\nfunction templateContext(runtime: PipelineRuntime): TemplateContext {\n return {\n args: runtime.args,\n last: runtime.last,\n outputs: runtime.outputs,\n vars: runtime.vars,\n error: runtime.error,\n };\n}\n\nfunction actionArgs(step: PipelineStep, runtime: PipelineRuntime): Record<string, unknown> {\n if (typeof step.args === 'string') {\n const resolved = resolveTemplateDeep(step.args, templateContext(runtime));\n if (step.action === 'evaluate' || step.action === 'eval' || step.action === 'console') {\n return { javascript: String(resolved ?? '') };\n }\n return { value: resolved };\n }\n return resolveTemplateDeep(step.args, templateContext(runtime)) as Record<string, unknown>;\n}\n\nasync function executePipeline(\n steps: PipelineStep[],\n scope: string,\n runtime: PipelineRuntime,\n actionCtx: BrowserActionContext,\n registry: BrowserActionRegistry,\n output: PipelineOutput,\n): Promise<void> {\n for (let i = 0; i < steps.length; i++) {\n if (actionCtx.signal?.aborted) {\n throw actionError('ABORTED', 'Pipeline aborted');\n }\n await executeStep(steps[i], i, scope, runtime, actionCtx, registry, output);\n }\n}\n\nasync function executeStep(\n step: PipelineStep,\n index: number,\n scope: string,\n runtime: PipelineRuntime,\n actionCtx: BrowserActionContext,\n registry: BrowserActionRegistry,\n output: PipelineOutput,\n): Promise<void> {\n const started = Date.now();\n let result: BrowserActionResult;\n try {\n result = await executeStepOnce(step, index, scope, runtime, actionCtx, registry, output);\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n result = {\n ok: false,\n action: step.action,\n error: { code: (error as Error & { code?: string }).code ?? 'STEP_FAILED', message: error.message },\n };\n }\n\n addStepTrace(output, {\n index,\n scope,\n action: step.action,\n ok: result.ok,\n elapsedMs: Date.now() - started,\n text: result.text?.slice(0, 500),\n data: result.data,\n error: result.error,\n }, result);\n\n if (!result.ok) {\n runtime.error = result.error;\n throw actionError(result.error?.code ?? 'STEP_FAILED', result.error?.message ?? 'Step failed');\n }\n}\n\nasync function executeStepOnce(\n step: PipelineStep,\n index: number,\n scope: string,\n runtime: PipelineRuntime,\n actionCtx: BrowserActionContext,\n registry: BrowserActionRegistry,\n output: PipelineOutput,\n): Promise<BrowserActionResult> {\n switch (step.action) {\n case 'sleep': {\n const args = actionArgs(step, runtime);\n const ms = Number(args.ms ?? args.delay_ms ?? args.delayMs ?? 1000);\n await sleep(Number.isFinite(ms) ? ms : 1000, undefined, { signal: actionCtx.signal });\n runtime.last = null;\n return { ok: true, action: 'sleep', text: `Slept ${ms}ms.`, data: null };\n }\n case 'set_var': {\n const args = actionArgs(step, runtime);\n const name = String(args.name ?? '');\n if (!name) return { ok: false, action: 'set_var', error: { code: 'INVALID_ARGS', message: 'name is required' } };\n runtime.vars[name] = args.value;\n runtime.last = args.value;\n return { ok: true, action: 'set_var', text: `Set var: ${name}`, data: args.value };\n }\n case 'if': {\n const args = actionArgs(step, runtime);\n const branch = isTruthyValue(args.condition) ? args.then : args.else;\n const branchSteps = normalizeNestedPipeline(branch, `${scope}.${index}.if`);\n await executePipeline(branchSteps, `${scope}.${index}.if`, runtime, actionCtx, registry, output);\n return { ok: true, action: 'if', text: 'Conditional branch completed.', data: runtime.last };\n }\n case 'retry': {\n const args = actionArgs(step, runtime);\n const times = Math.max(1, Number(args.times ?? 3));\n const delayMs = Math.max(0, Number(args.delay_ms ?? args.delayMs ?? 250));\n const retrySteps = normalizeNestedPipeline(args.pipeline ?? args.step, `${scope}.${index}.retry`);\n let lastError: unknown;\n for (let attempt = 1; attempt <= times; attempt++) {\n try {\n await executePipeline(retrySteps, `${scope}.${index}.retry.${attempt}`, runtime, actionCtx, registry, output);\n output.ok = true;\n output.error = undefined;\n return { ok: true, action: 'retry', text: `Retry block completed on attempt ${attempt}.`, data: runtime.last };\n } catch (e) {\n lastError = e;\n output.ok = true;\n output.error = undefined;\n if (attempt < times) await sleep(delayMs, undefined, { signal: actionCtx.signal });\n }\n }\n const message = lastError instanceof Error ? lastError.message : String(lastError);\n return { ok: false, action: 'retry', error: { code: 'RETRY_FAILED', message } };\n }\n default:\n return executeBrowserAction(step, runtime, actionCtx, registry);\n }\n}\n\nasync function executeBrowserAction(\n step: PipelineStep,\n runtime: PipelineRuntime,\n actionCtx: BrowserActionContext,\n registry: BrowserActionRegistry,\n): Promise<BrowserActionResult> {\n const args = actionArgs(step, runtime);\n actionCtx.pipeline = {\n args: runtime.args,\n last: runtime.last,\n outputs: runtime.outputs,\n vars: runtime.vars,\n error: runtime.error,\n };\n const result = await registry.execute(step.action, actionCtx, args);\n if (result.ok) {\n if (step.action === 'output') {\n runtime.outputs.push(result.data);\n }\n if (result.data !== undefined) {\n runtime.last = result.data;\n }\n }\n return result;\n}\n\nfunction normalizeNestedPipeline(value: unknown, path: string): PipelineStep[] {\n const rawSteps = Array.isArray(value) ? value : value ? [value] : [];\n return rawSteps.map((rawStep, index) => {\n if (!rawStep || typeof rawStep !== 'object' || Array.isArray(rawStep)) {\n throw new Error(`${path}[${index}] must be a YAML object`);\n }\n const obj = rawStep as Record<string, unknown>;\n const keys = Object.keys(obj);\n if (keys.length !== 1) {\n throw new Error(`${path}[${index}] must contain exactly one action`);\n }\n const action = keys[0];\n const args = obj[action];\n if (typeof args === 'string') return { action, args };\n if (args && typeof args === 'object' && !Array.isArray(args)) return { action, args: args as Record<string, unknown> };\n if (args === undefined || args === null) return { action, args: {} };\n return { action, args: { value: args } };\n });\n}\n\nfunction actionError(code: string, message: string): Error {\n const error = new Error(message) as Error & { code?: string };\n error.code = code;\n return error;\n}\n\nexport async function runBrowserPipeline(\n yamlSource: string,\n argOverrides: Record<string, unknown>,\n ctx: BrowserActionContext,\n registry: BrowserActionRegistry,\n options: RunBrowserPipelineOptions = {},\n): Promise<BrowserActionResult> {\n let doc: PipelineDocument;\n try {\n doc = await expandPipelineDocument(yamlSource, options.sourceLocation);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, action: 'pipeline', error: { code: 'VALIDATION_FAILED', message: msg }, text: msg };\n }\n\n const validationErrors: { path: string; message: string }[] = [];\n validateSteps(doc.pipeline, 'pipeline', registry, validationErrors);\n validateSteps(doc.onError ?? [], 'on_error', registry, validationErrors);\n if (validationErrors.length > 0) {\n const msg = validationErrors.map((e) => `${e.path}: ${e.message}`).join('\\n');\n return { ok: false, action: 'pipeline', error: { code: 'VALIDATION_FAILED', message: msg }, text: msg };\n }\n\n if (options.dryRun) {\n return {\n ok: true,\n action: 'pipeline',\n text: `Pipeline \"${doc.name}\" validated successfully (${doc.pipeline.length} steps).`,\n data: { name: doc.name, steps: doc.pipeline.length, args: Object.keys(doc.args) },\n };\n }\n\n let args: Record<string, unknown>;\n try {\n args = resolveArgs(doc, argOverrides);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, action: 'pipeline', error: { code: 'ARG_RESOLUTION_FAILED', message: msg }, text: msg };\n }\n\n const output = createPipelineOutput(doc.name);\n const runtime: PipelineRuntime = { doc, args, last: undefined, outputs: [], vars: {} };\n\n log.info({ pipeline: doc.name, steps: doc.pipeline.length }, `Running pipeline: ${doc.name}`);\n\n try {\n const run = executePipeline(doc.pipeline, 'pipeline', runtime, ctx, registry, output);\n if (doc.timeoutSeconds && doc.timeoutSeconds > 0) {\n await Promise.race([\n run,\n sleep(doc.timeoutSeconds * 1000, undefined, { signal: ctx.signal }).then(() => {\n throw actionError('PIPELINE_TIMEOUT', `Pipeline timed out after ${doc.timeoutSeconds} seconds`);\n }),\n ]);\n } else {\n await run;\n }\n } catch {\n output.ok = false;\n output.error ??= { step: output.trace.length, action: 'pipeline', code: 'PIPELINE_FAILED', message: runtime.error?.message ?? 'Pipeline failed' };\n }\n\n output.last = runtime.last;\n output.outputs = runtime.outputs;\n\n if (!output.ok && doc.onError && doc.onError.length > 0) {\n log.info({ pipeline: doc.name }, 'Running on_error diagnostics');\n try {\n await executePipeline(doc.onError, 'on_error', runtime, ctx, registry, output);\n } catch {\n // Main pipeline error remains authoritative.\n }\n output.last = runtime.last;\n output.outputs = runtime.outputs;\n }\n\n return formatPipelineResult(output);\n}\n"],"mappings":"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"}
|