@xopcai/xopc 0.0.105 → 0.0.107
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/dashscope/xopc.extension.json +7 -2
- package/dist/extensions/fal/xopc.extension.json +7 -2
- package/dist/extensions/feishu/src/adapters/gateway-setup.js +22 -26
- package/dist/extensions/feishu/src/adapters/gateway-setup.js.map +1 -1
- package/dist/extensions/feishu/src/directory/directory-adapter.js +1 -1
- package/dist/extensions/feishu/src/directory/directory-adapter.js.map +1 -1
- package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js +4 -3
- package/dist/extensions/feishu/src/outbound/outbound-adapter.js.map +1 -1
- package/dist/extensions/feishu/src/plugin.d.ts +6 -3
- package/dist/extensions/feishu/src/plugin.js +59 -40
- package/dist/extensions/feishu/src/plugin.js.map +1 -1
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js +20 -16
- package/dist/extensions/feishu/src/streaming/streaming-adapter.js.map +1 -1
- package/dist/extensions/feishu/src/transport/socket-mode/monitor.js +1 -1
- package/dist/extensions/feishu/src/transport/webhook/monitor.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.d.ts +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +3 -3
- package/dist/extensions/feishu/src/workflow-progress.js.map +1 -1
- package/dist/extensions/feishu/xopc.extension.json +458 -26
- package/dist/extensions/google/xopc.extension.json +7 -2
- package/dist/extensions/minimax/xopc.extension.json +8 -2
- package/dist/extensions/openai/xopc.extension.json +7 -2
- package/dist/extensions/telegram/src/adapters/gateway-setup.js +8 -6
- package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -1
- package/dist/extensions/telegram/src/adapters/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/command-handler.d.ts +1 -1
- package/dist/extensions/telegram/src/command-handler.js +11 -9
- package/dist/extensions/telegram/src/command-handler.js.map +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +2 -3
- package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
- package/dist/extensions/telegram/src/plugin.d.ts +1 -0
- package/dist/extensions/telegram/src/plugin.js +7 -7
- package/dist/extensions/telegram/src/plugin.js.map +1 -1
- package/dist/extensions/telegram/src/routing-integration.js +2 -2
- package/dist/extensions/telegram/src/update-offset-store.js +1 -1
- package/dist/extensions/telegram/src/workflow-progress.d.ts +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js +1 -1
- package/dist/extensions/telegram/src/workflow-progress.js.map +1 -1
- package/dist/extensions/telegram/xopc.extension.json +10 -2
- package/dist/extensions/weixin/src/api/api.js +2 -2
- package/dist/extensions/weixin/src/auth/accounts.js +1 -1
- package/dist/extensions/weixin/src/cdn/upload.js +1 -1
- package/dist/extensions/weixin/src/cli/gateway-qr-login.d.ts +4 -0
- package/dist/extensions/weixin/src/cli/gateway-qr-login.js +34 -5
- package/dist/extensions/weixin/src/cli/gateway-qr-login.js.map +1 -1
- package/dist/extensions/weixin/src/cli/qr-login.js +4 -3
- package/dist/extensions/weixin/src/cli/qr-login.js.map +1 -1
- package/dist/extensions/weixin/src/media/data-url.js +1 -1
- package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
- package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
- package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
- package/dist/extensions/weixin/src/plugin.d.ts +1 -0
- package/dist/extensions/weixin/src/plugin.js +8 -7
- package/dist/extensions/weixin/src/plugin.js.map +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
- package/dist/extensions/weixin/xopc.extension.json +57 -14
- package/dist/gateway/static/root/apple-touch-icon.png +0 -0
- package/dist/gateway/static/root/assets/agents-BXg2_mE4.js +78 -0
- package/dist/gateway/static/root/assets/apps-page-CJqQ-7Ss.js +1 -0
- package/dist/gateway/static/root/assets/channels-settings-DvMZ6NAd.js +1 -0
- package/dist/gateway/static/root/assets/cron-page-BPBlvSl5.js +1 -0
- package/dist/gateway/static/root/assets/{dist-DJDkNhu5.js → dist-CZh0c-s8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DI1XJTJi.js → extension-debug-page-DyJQR0SR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-SuafGTT_.js → extension-page-CDTuUr9B.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-cKmGax9v.js → extension-settings-page-DszZ8zHD.js} +1 -1
- package/dist/gateway/static/root/assets/{fetch-CkvRO30i.js → fetch-CFdKBnE6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BkKyRDrF.js → gateway-startup-retry-DdngdObI.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-config-api-CRiDcxtt.js → heartbeat-config-api-U10wnPdc.js} +1 -1
- package/dist/gateway/static/root/assets/index-DBc-bVOQ.js +4845 -0
- package/dist/gateway/static/root/assets/index-DI5_GsZt.css +1 -0
- package/dist/gateway/static/root/assets/{logs-page-DM8o5-Bm.js → logs-page-B6js8Bfi.js} +2 -2
- package/dist/gateway/static/root/assets/{note-detail-page-j53jtvq9.js → note-detail-page-DFzAXR35.js} +4 -4
- package/dist/gateway/static/root/assets/{note-time-Ck2H2Qpw.js → note-time-DOiSU-10.js} +1 -1
- package/dist/gateway/static/root/assets/notes-page-DAuZJMT8.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-BvmGNxiJ.js → schema-form-zM36dvbY.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-CAsV03BY.js +1 -0
- package/dist/gateway/static/root/assets/{settings-advanced-gate-DRdayl8P.js → settings-advanced-gate-BCvObK1y.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-BlIYg2gZ.js → settings-form-section-Bvl-RInc.js} +1 -1
- package/dist/gateway/static/root/assets/settings-page-DuCJDd74.js +3 -0
- package/dist/gateway/static/root/assets/{share-preview-page-BlT6Akvk.js → share-preview-page-rpL4DDTO.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page--BioR9J4.js +2 -0
- package/dist/gateway/static/root/assets/{theme-store-DYgVdRB4.js → theme-store-BZozwAeK.js} +1 -1
- package/dist/gateway/static/root/assets/url-DQRqHuL-.js +3 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-D2RJaoj_.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-page.utils-_sjXCMvi.js → workflow-page.utils-BxacHYen.js} +1 -1
- package/dist/gateway/static/root/assets/workflows-page-B1B-est-.js +18 -0
- package/dist/gateway/static/root/favicon-16.png +0 -0
- package/dist/gateway/static/root/favicon-32.png +0 -0
- package/dist/gateway/static/root/favicon.ico +0 -0
- package/dist/gateway/static/root/favicon.svg +18 -0
- package/dist/gateway/static/root/index.html +11 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +7 -7
- package/dist/src/agent/agent-scope.js +1 -1
- package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
- package/dist/src/agent/context/workspace-seed.js +2 -2
- package/dist/src/agent/context/workspace-state.js +1 -1
- package/dist/src/agent/goals/goal-run-store.js +4 -4
- package/dist/src/agent/goals/persistent-goal-service.js +1 -1
- package/dist/src/agent/goals/post-turn.js +2 -2
- package/dist/src/agent/image/load-image-media.js +2 -2
- package/dist/src/agent/ipc/bus.js +1 -1
- package/dist/src/agent/ipc/inbox.js +2 -2
- package/dist/src/agent/ipc/socket.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-config.js +16 -8
- package/dist/src/agent/mcp/bundle-mcp-config.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-policy.js +2 -2
- package/dist/src/agent/mcp/bundle-mcp-policy.js.map +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -2
- package/dist/src/agent/mcp/mcp-http.js +1 -1
- package/dist/src/agent/mcp/mcp-http.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +3 -7
- package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
- package/dist/src/agent/mcp/mcp-transport.js +1 -1
- package/dist/src/agent/memory/builtin-memory-store.js +1 -1
- package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
- package/dist/src/agent/memory/dreaming/events.js +1 -1
- package/dist/src/agent/memory/dreaming/last-run.js +1 -1
- package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
- package/dist/src/agent/memory/dreaming/preview.js +1 -1
- package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
- package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
- package/dist/src/agent/memory/dreaming/utils.js +1 -1
- package/dist/src/agent/memory/memory-flush.js +1 -1
- package/dist/src/agent/memory/plugin-discovery.js +1 -1
- package/dist/src/agent/models/manager.js +1 -1
- package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
- package/dist/src/agent/reply/post-compaction-context.js +1 -1
- package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
- package/dist/src/agent/sandbox/path-policy.js +2 -2
- package/dist/src/agent/service.js +4 -4
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/config.js +1 -1
- package/dist/src/agent/skills/hub-hash.js +2 -2
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/skills/hub-pull.js +2 -2
- package/dist/src/agent/skills/index.js +1 -1
- package/dist/src/agent/skills/managed-store.js +1 -1
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +4 -0
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +4 -2
- package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js.map +1 -1
- package/dist/src/agent/skills/scanner.js +1 -1
- package/dist/src/agent/skills/skill-manage-ops.js +1 -1
- package/dist/src/agent/skills/skill-manager.js +1 -1
- package/dist/src/agent/starter-agents.d.ts +19 -0
- package/dist/src/agent/starter-agents.js +190 -0
- package/dist/src/agent/starter-agents.js.map +1 -0
- package/dist/src/agent/tools/dreaming-tool.js +1 -1
- package/dist/src/agent/tools/factory.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +1 -1
- package/dist/src/agent/tools/send-media.js +1 -1
- package/dist/src/agent/tools/skill-manage-tool.js +1 -1
- package/dist/src/agent/tools/workflow-tool.js +1 -1
- package/dist/src/agent/tools/write.js +1 -1
- package/dist/src/agent/workflow/catalog.js +1 -1
- package/dist/src/agent/workflow/index.js +2 -1
- package/dist/src/agent/workflow/runtime.d.ts +2 -2
- package/dist/src/agent/workflow/runtime.js +50 -29
- package/dist/src/agent/workflow/runtime.js.map +1 -1
- package/dist/src/agent/workflow/snapshot-empty.d.ts +2 -0
- package/dist/src/agent/workflow/snapshot-empty.js +19 -0
- package/dist/src/agent/workflow/snapshot-empty.js.map +1 -0
- package/dist/src/agent/workflow/snapshot.js +1 -1
- package/dist/src/agent/workflow/snapshot.js.map +1 -1
- package/dist/src/agent/workflow/types.d.ts +11 -0
- package/dist/src/auth/credentials.js +3 -3
- package/dist/src/auth/profiles/store.js +2 -2
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/browser/cache-dir-policy.js +1 -1
- package/dist/src/browser/cdp-local-launcher.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +3 -3
- package/dist/src/browser/providers/cloakbrowser.js +4 -4
- package/dist/src/browser/providers/playwright-doctor.js +1 -1
- package/dist/src/browser/stealth.js +1 -1
- package/dist/src/channels/catalog/channel-catalog-service.js +13 -0
- package/dist/src/channels/catalog/channel-catalog-service.js.map +1 -1
- package/dist/src/channels/outbound/persist-store.js +1 -1
- package/dist/src/channels/pairing/allow-from-file.js +1 -1
- package/dist/src/channels/pairing/pairing-store.js +2 -2
- package/dist/src/channels/plugins/types.adapters.d.ts +2 -0
- package/dist/src/chat-commands/agent-edit.js +2 -2
- package/dist/src/chat-commands/builtins/config.js +2 -2
- package/dist/src/chat-commands/context.js +1 -1
- package/dist/src/cli/commands/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
- package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
- package/dist/src/cli/commands/extension-create.d.ts +2 -0
- package/dist/src/cli/commands/extension-create.js +165 -0
- package/dist/src/cli/commands/extension-create.js.map +1 -0
- package/dist/src/cli/commands/extension-dev.js +1 -3
- package/dist/src/cli/commands/extension-dev.js.map +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +105 -81
- package/dist/src/cli/commands/extension-marketplace.js.map +1 -1
- package/dist/src/cli/commands/extension-pack.d.ts +13 -0
- package/dist/src/cli/commands/extension-pack.js +159 -91
- package/dist/src/cli/commands/extension-pack.js.map +1 -1
- package/dist/src/cli/commands/extension.d.ts +2 -0
- package/dist/src/cli/commands/extension.js +375 -3
- package/dist/src/cli/commands/extension.js.map +1 -1
- package/dist/src/cli/commands/gateway/logs.js +1 -1
- package/dist/src/cli/commands/gateway/run-foreground.js +1 -2
- package/dist/src/cli/commands/gateway/run-foreground.js.map +1 -1
- package/dist/src/cli/commands/image.js +1 -1
- package/dist/src/cli/commands/init.js +3 -3
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +2 -2
- package/dist/src/cli/commands/onboard.js +0 -2
- package/dist/src/cli/commands/onboard.js.map +1 -1
- package/dist/src/cli/commands/setup.js +0 -2
- package/dist/src/cli/commands/setup.js.map +1 -1
- package/dist/src/cli/utils/init-workspace-core.js +10 -7
- package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/agent-typed-models.js +1 -1
- package/dist/src/config/gateway-bind.js +1 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +2 -2
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/paths-state.js +1 -1
- package/dist/src/config/paths.d.ts +2 -2
- package/dist/src/config/paths.js +6 -5
- package/dist/src/config/paths.js.map +1 -1
- package/dist/src/config/profile.js +2 -2
- package/dist/src/config/schema.d.ts +2 -0
- package/dist/src/config/schema.js +3 -1
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/config/workspace-path.js +1 -1
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/connectors/install.js +1 -1
- package/dist/src/cron/executor.js +2 -2
- package/dist/src/cron/persistence.js +1 -1
- package/dist/src/daemon/constants.js +1 -1
- package/dist/src/daemon/install-plan.js +2 -2
- package/dist/src/daemon/launchd.js +2 -2
- package/dist/src/daemon/schtasks.js +2 -2
- package/dist/src/daemon/systemd.js +2 -2
- package/dist/src/extensions/api.d.ts +4 -2
- package/dist/src/extensions/api.js +31 -12
- package/dist/src/extensions/api.js.map +1 -1
- package/dist/src/extensions/bundle-mcp.js +1 -1
- package/dist/src/extensions/discover-extensions.js +2 -1
- package/dist/src/extensions/discover-extensions.js.map +1 -1
- package/dist/src/extensions/health.js +1 -1
- package/dist/src/extensions/install.d.ts +1 -0
- package/dist/src/extensions/install.js +51 -8
- package/dist/src/extensions/install.js.map +1 -1
- package/dist/src/extensions/loader.d.ts +0 -4
- package/dist/src/extensions/loader.js +55 -88
- package/dist/src/extensions/loader.js.map +1 -1
- package/dist/src/extensions/lockfile.d.ts +9 -1
- package/dist/src/extensions/lockfile.js +2 -2
- package/dist/src/extensions/lockfile.js.map +1 -1
- package/dist/src/extensions/normalize-manifest.js +20 -4
- package/dist/src/extensions/normalize-manifest.js.map +1 -1
- package/dist/src/extensions/package-contract.d.ts +12 -0
- package/dist/src/extensions/package-contract.js +59 -0
- package/dist/src/extensions/package-contract.js.map +1 -0
- package/dist/src/extensions/sdk/core.d.ts +1 -1
- package/dist/src/extensions/sdk/index.d.ts +1 -1
- package/dist/src/extensions/sdk/index.js.map +1 -1
- package/dist/src/extensions/types/manifest.d.ts +15 -0
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.d.ts +0 -8
- package/dist/src/gateway/agents-admin.js +3 -28
- package/dist/src/gateway/agents-admin.js.map +1 -1
- package/dist/src/gateway/file-path-classifier.js +2 -2
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/lib/extension-store.js +2 -2
- package/dist/src/gateway/hono/lib/static-ui.js +2 -2
- package/dist/src/gateway/hono/oauth-async.js +1 -1
- package/dist/src/gateway/hono/oauth.js +1 -1
- package/dist/src/gateway/hono/routes/agents.js +2 -56
- package/dist/src/gateway/hono/routes/agents.js.map +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/channels.js +10 -1
- package/dist/src/gateway/hono/routes/channels.js.map +1 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/dreaming.js +1 -1
- package/dist/src/gateway/hono/routes/host-fs.js +2 -2
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/shares.js +1 -1
- package/dist/src/gateway/hono/routes/workflows.js +130 -0
- package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
- package/dist/src/gateway/hono/routes/workspace.js +2 -2
- package/dist/src/gateway/lock.js +3 -3
- package/dist/src/gateway/ports.js +1 -1
- package/dist/src/gateway/service/agent-runner.js +2 -2
- package/dist/src/gateway/service/marketplace-service.js +2 -2
- package/dist/src/gateway/service.d.ts +2 -0
- package/dist/src/gateway/service.js +45 -1
- package/dist/src/gateway/service.js.map +1 -1
- package/dist/src/gateway/workspace-fs-file-list.js +1 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/brew.js +1 -1
- package/dist/src/infra/package-json.js +1 -1
- package/dist/src/infra/package-update-steps.js +1 -1
- package/dist/src/infra/path-env.js +2 -2
- package/dist/src/infra/restart.js +2 -2
- package/dist/src/infra/stable-node-path.js +1 -1
- package/dist/src/infra/update-check.js +1 -1
- package/dist/src/infra/update-global.js +1 -1
- package/dist/src/infra/update-lock.js +3 -3
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/infra/update-startup.js +2 -2
- package/dist/src/infra/write-file-atomic.js +2 -2
- package/dist/src/media/store.js +1 -1
- package/dist/src/notes/agent-context.d.ts +12 -4
- package/dist/src/notes/agent-context.js +1 -1
- package/dist/src/notes/agent-context.js.map +1 -1
- package/dist/src/notes/store.js +2 -2
- package/dist/src/project-trust/trust-store.js +2 -2
- package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/session/init-session-turn.js +2 -2
- package/dist/src/session/resolve-session.js +3 -3
- package/dist/src/session/session-title.js +2 -2
- package/dist/src/session/store.js +2 -2
- package/dist/src/share/share-auto.js +2 -2
- package/dist/src/share/share-store.js +3 -3
- package/dist/src/share/share-thumbnail.js +2 -2
- package/dist/src/share/share-zip.js +1 -1
- package/dist/src/share/site-share-store.js +3 -3
- package/dist/src/share/site-static-serve.js +1 -1
- package/dist/src/storage/sqlite/connection.js +2 -2
- package/dist/src/storage/sqlite/memory-index-repository.js +2 -2
- package/dist/src/storage/sqlite/migrations/discover.js +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tui/backends/embedded-backend.js +1 -8
- package/dist/src/tui/backends/embedded-backend.js.map +1 -1
- package/dist/src/tui/backends/gateway-sse-backend.js +0 -7
- package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
- package/dist/src/tui/clipboard-image.js +3 -3
- package/dist/src/tui/theme-manager.js +1 -1
- package/dist/src/tui/tui-backend.d.ts +0 -1
- package/dist/src/tui/tui-command-formatters.js +3 -3
- package/dist/src/tui/tui-commands.js +3 -3
- package/dist/src/tui/tui-commands.js.map +1 -1
- package/dist/src/tui/tui-keybindings-file.js +1 -1
- package/dist/src/tui/tui-picker-overlay.js +1 -1
- package/dist/src/tui/tui-picker-overlay.js.map +1 -1
- package/dist/src/tui/tui-scoped-models.js +2 -2
- package/dist/src/tui/tui-settings.js +1 -1
- package/dist/src/tui/tui-startup-resources.js +2 -2
- package/dist/src/tui/tui.js +5 -5
- package/dist/src/tunnel/frpc-binary.js +3 -3
- package/dist/src/tunnel/frpc-config.js +1 -1
- package/dist/src/tunnel/frpc-extract.js +1 -1
- package/dist/src/tunnel/tunnel-state.js +1 -1
- package/dist/src/utils/logger/audit.js +1 -1
- package/dist/src/utils/logger/log-store.js +1 -1
- package/dist/src/utils/logger/rotation.js +1 -1
- package/dist/src/voice/stt/availability.d.ts +6 -0
- package/dist/src/voice/stt/availability.js +14 -6
- package/dist/src/voice/stt/availability.js.map +1 -1
- package/dist/src/voice/stt/index.js +2 -1
- package/dist/src/voice/stt/index.js.map +1 -1
- package/dist/src/voice/stt/mention.d.ts +2 -0
- package/dist/src/voice/stt/mention.js +20 -0
- package/dist/src/voice/stt/mention.js.map +1 -0
- package/dist/src/voice/stt/preflight.d.ts +1 -4
- package/dist/src/voice/stt/preflight.js +1 -18
- package/dist/src/voice/stt/preflight.js.map +1 -1
- package/dist/src/voice/tts/audio.js +1 -1
- package/dist/src/voice/tts/providers/edge-speech.js +2 -2
- package/dist/src/workflows/domain/definition-utils.d.ts +1 -0
- package/dist/src/workflows/domain/definition-utils.js +32 -2
- package/dist/src/workflows/domain/definition-utils.js.map +1 -1
- package/dist/src/workflows/domain/definition.d.ts +2 -0
- package/dist/src/workflows/domain/event.d.ts +2 -1
- package/dist/src/workflows/domain/index.d.ts +1 -0
- package/dist/src/workflows/domain/index.js +3 -2
- package/dist/src/workflows/domain/run.d.ts +27 -1
- package/dist/src/workflows/domain/run.js.map +1 -1
- package/dist/src/workflows/domain/schema-validation.d.ts +8 -0
- package/dist/src/workflows/domain/schema-validation.js +28 -0
- package/dist/src/workflows/domain/schema-validation.js.map +1 -0
- package/dist/src/workflows/draft/index.d.ts +3 -0
- package/dist/src/workflows/draft/index.js +3 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.d.ts +23 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.js +98 -0
- package/dist/src/workflows/draft/workflow-draft-prompt.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft-service.d.ts +12 -0
- package/dist/src/workflows/draft/workflow-draft-service.js +131 -0
- package/dist/src/workflows/draft/workflow-draft-service.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft-validator.d.ts +4 -0
- package/dist/src/workflows/draft/workflow-draft-validator.js +133 -0
- package/dist/src/workflows/draft/workflow-draft-validator.js.map +1 -0
- package/dist/src/workflows/draft/workflow-draft.types.d.ts +44 -0
- package/dist/src/workflows/draft/workflow-draft.types.js +1 -0
- package/dist/src/workflows/engine/projector.js +1 -0
- package/dist/src/workflows/engine/projector.js.map +1 -1
- package/dist/src/workflows/engine/workflow-engine.d.ts +18 -0
- package/dist/src/workflows/engine/workflow-engine.js +320 -11
- package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
- package/dist/src/workflows/index.js +4 -3
- package/dist/src/workflows/service/workflow-run-service.d.ts +14 -3
- package/dist/src/workflows/service/workflow-run-service.js +227 -6
- package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
- package/dist/src/workflows/service/workflow-run-service.types.d.ts +7 -2
- package/dist/src/workflows/store/event-store.js +1 -1
- package/dist/src/workflows/store/run-store.js +1 -1
- package/package.json +5 -3
- package/dist/gateway/static/root/assets/agents-XzgIVKcI.js +0 -396
- package/dist/gateway/static/root/assets/apps-page-B7Us3RMl.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BgeV6fzw.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-DKGHEeAU.js +0 -1
- package/dist/gateway/static/root/assets/index-50FVtgXU.js +0 -4845
- package/dist/gateway/static/root/assets/index-BPYKW7FB.css +0 -1
- package/dist/gateway/static/root/assets/notes-page-CsWIw35Q.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-CLPsbyOW.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-CRGHT_bm.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-Ce-RIH2y.js +0 -2
- package/dist/gateway/static/root/assets/url-DPEStU4M.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-CJGTidqc.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-o63aaARK.js +0 -27
- package/dist/src/agent/builtin-agent-ids.d.ts +0 -2
- package/dist/src/agent/builtin-agent-ids.js +0 -17
- package/dist/src/agent/builtin-agent-ids.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-draft-validator.js","names":[],"sources":["../../../../src/workflows/draft/workflow-draft-validator.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport { validateWorkflowDefinitionInput } from '../domain/validation.js';\nimport type { WorkflowDefinitionManifest } from '../domain/definition.js';\n\nimport type {\n GeneratedWorkflowDraft,\n WorkflowDraftConstraints,\n WorkflowDraftLintIssue,\n WorkflowDraftResponse,\n} from './workflow-draft.types.js';\n\nexport function parseGeneratedWorkflowDraft(raw: string): GeneratedWorkflowDraft {\n const json = extractJsonObject(raw);\n const parsed = JSON.parse(json) as Partial<GeneratedWorkflowDraft>;\n const name = normalizeWorkflowName(String(parsed.name ?? 'custom_workflow'));\n const script = String(parsed.script ?? '').trim();\n const manifest = normalizeManifest(parsed.manifest);\n return {\n name,\n script,\n manifest,\n explanation: String(parsed.explanation ?? ''),\n assumptions: stringArray(parsed.assumptions),\n risks: stringArray(parsed.risks),\n };\n}\n\nexport function buildWorkflowDraftResponse(\n draft: GeneratedWorkflowDraft,\n constraints?: WorkflowDraftConstraints,\n): WorkflowDraftResponse {\n const validation = validateWorkflowDefinitionInput({ name: draft.name, script: draft.script });\n const lint = lintWorkflowDraft(draft, constraints);\n return {\n draftId: randomUUID(),\n repairAttempts: 0,\n ...draft,\n permissionsSummary: summarizePermissions(draft.manifest),\n validation,\n lint,\n suggestedInputs: suggestedInputsFromManifest(draft.manifest),\n };\n}\n\nexport function lintWorkflowDraft(\n draft: GeneratedWorkflowDraft,\n constraints?: WorkflowDraftConstraints,\n): WorkflowDraftLintIssue[] {\n const issues: WorkflowDraftLintIssue[] = [];\n const { manifest, script } = draft;\n if (!manifest.inputSchema) {\n issues.push({ severity: 'warning', code: 'missing_input_schema', message: 'Draft does not define an input schema.' });\n }\n if (!manifest.outputSchema) {\n issues.push({ severity: 'warning', code: 'missing_output_schema', message: 'Draft does not define an output schema.' });\n }\n if (manifest.permissions?.network && constraints?.allowNetwork === false) {\n issues.push({ severity: 'error', code: 'unsafe_permission', message: 'Draft requests network access, but network is disabled by constraints.' });\n }\n if (manifest.permissions?.fileSystem === 'write' && constraints?.fileSystem !== 'write') {\n issues.push({ severity: 'warning', code: 'unsafe_permission', message: 'Draft requests filesystem write access.' });\n }\n const phaseCount = (script.match(/\\bphase\\s*\\(/g) ?? []).length;\n if (constraints?.maxPhases && phaseCount > constraints.maxPhases) {\n issues.push({ severity: 'warning', code: 'too_many_agents', message: `Draft has ${phaseCount} phases, above requested ${constraints.maxPhases}.` });\n }\n const agentCount = (script.match(/\\bagent\\s*\\(/g) ?? []).length;\n if (constraints?.maxSubagents && agentCount > constraints.maxSubagents) {\n issues.push({ severity: 'warning', code: 'too_many_agents', message: `Draft starts ${agentCount} agents, above requested ${constraints.maxSubagents}.` });\n }\n if (/parallel\\s*\\([^[]/.test(script)) {\n issues.push({ severity: 'warning', code: 'unbounded_parallelism', message: 'parallel() should receive a bounded array of thunks.' });\n }\n if (constraints?.allowedTools?.length) {\n const unknown = collectToolsetNames(script).filter((tool) => !constraints.allowedTools!.includes(tool));\n for (const tool of [...new Set(unknown)]) {\n issues.push({ severity: 'warning', code: 'unknown_tool', message: `Tool '${tool}' is outside the requested allowlist.` });\n }\n }\n return issues;\n}\n\nfunction extractJsonObject(raw: string): string {\n const trimmed = raw.trim();\n if (trimmed.startsWith('{') && trimmed.endsWith('}')) return trimmed;\n const fenced = trimmed.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)?.[1]?.trim();\n if (fenced?.startsWith('{')) return fenced;\n const start = trimmed.indexOf('{');\n const end = trimmed.lastIndexOf('}');\n if (start >= 0 && end > start) return trimmed.slice(start, end + 1);\n throw new Error('Model did not return a JSON object.');\n}\n\nfunction normalizeManifest(value: unknown): WorkflowDefinitionManifest {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n return value as WorkflowDefinitionManifest;\n}\n\nfunction stringArray(value: unknown): string[] {\n return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];\n}\n\nfunction normalizeWorkflowName(value: string): string {\n const normalized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '_')\n .replace(/^_+|_+$/g, '');\n return /^[a-z]/.test(normalized) ? normalized : `workflow_${normalized || 'draft'}`;\n}\n\nfunction summarizePermissions(manifest: WorkflowDefinitionManifest): string[] {\n const permissions = manifest.permissions;\n if (!permissions) return ['No explicit permissions requested.'];\n const out: string[] = [];\n if (permissions.tools?.length) out.push(`Tools: ${permissions.tools.join(', ')}`);\n if (permissions.network != null) out.push(`Network: ${permissions.network ? 'enabled' : 'disabled'}`);\n if (permissions.fileSystem) out.push(`Filesystem: ${permissions.fileSystem}`);\n if (permissions.approvalRequired) out.push('Approval required');\n return out.length > 0 ? out : ['No explicit permissions requested.'];\n}\n\nfunction suggestedInputsFromManifest(manifest: WorkflowDefinitionManifest): WorkflowDraftResponse['suggestedInputs'] {\n const properties = manifest.inputSchema?.properties;\n if (!properties) return undefined;\n return Object.entries(properties).slice(0, 8).map(([key, schema]) => ({\n key,\n label: typeof schema.title === 'string' ? schema.title : key,\n example: typeof schema.default === 'string' ? schema.default : schema.description ?? '',\n }));\n}\n\nfunction collectToolsetNames(script: string): string[] {\n const out: string[] = [];\n const re = /toolset\\s*:\\s*\\[([^\\]]*)\\]/g;\n for (const match of script.matchAll(re)) {\n const body = match[1] ?? '';\n for (const item of body.matchAll(/['\"]([^'\"]+)['\"]/g)) {\n out.push(item[1] ?? '');\n }\n }\n return out.filter(Boolean);\n}\n"],"mappings":";;;AAYA,SAAgB,4BAA4B,KAAqC;CAC/E,MAAM,OAAO,kBAAkB,IAAI;CACnC,MAAM,SAAS,KAAK,MAAM,KAAK;AAI/B,QAAO;EACL,MAJW,sBAAsB,OAAO,OAAO,QAAQ,kBAAkB,CAIrE;EACJ,QAJa,OAAO,OAAO,UAAU,GAAG,CAAC,MAInC;EACN,UAJe,kBAAkB,OAAO,SAIhC;EACR,aAAa,OAAO,OAAO,eAAe,GAAG;EAC7C,aAAa,YAAY,OAAO,YAAY;EAC5C,OAAO,YAAY,OAAO,MAAM;EACjC;;AAGH,SAAgB,2BACd,OACA,aACuB;CACvB,MAAM,aAAa,gCAAgC;EAAE,MAAM,MAAM;EAAM,QAAQ,MAAM;EAAQ,CAAC;CAC9F,MAAM,OAAO,kBAAkB,OAAO,YAAY;AAClD,QAAO;EACL,SAAS,YAAY;EACrB,gBAAgB;EAChB,GAAG;EACH,oBAAoB,qBAAqB,MAAM,SAAS;EACxD;EACA;EACA,iBAAiB,4BAA4B,MAAM,SAAS;EAC7D;;AAGH,SAAgB,kBACd,OACA,aAC0B;CAC1B,MAAM,SAAmC,EAAE;CAC3C,MAAM,EAAE,UAAU,WAAW;AAC7B,KAAI,CAAC,SAAS,YACZ,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAwB,SAAS;EAA0C,CAAC;AAEvH,KAAI,CAAC,SAAS,aACZ,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAyB,SAAS;EAA2C,CAAC;AAEzH,KAAI,SAAS,aAAa,WAAW,aAAa,iBAAiB,MACjE,QAAO,KAAK;EAAE,UAAU;EAAS,MAAM;EAAqB,SAAS;EAA0E,CAAC;AAElJ,KAAI,SAAS,aAAa,eAAe,WAAW,aAAa,eAAe,QAC9E,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAqB,SAAS;EAA2C,CAAC;CAErH,MAAM,cAAc,OAAO,MAAM,gBAAgB,IAAI,EAAE,EAAE;AACzD,KAAI,aAAa,aAAa,aAAa,YAAY,UACrD,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAmB,SAAS,aAAa,WAAW,2BAA2B,YAAY,UAAU;EAAI,CAAC;CAErJ,MAAM,cAAc,OAAO,MAAM,gBAAgB,IAAI,EAAE,EAAE;AACzD,KAAI,aAAa,gBAAgB,aAAa,YAAY,aACxD,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAmB,SAAS,gBAAgB,WAAW,2BAA2B,YAAY,aAAa;EAAI,CAAC;AAE3J,KAAI,oBAAoB,KAAK,OAAO,CAClC,QAAO,KAAK;EAAE,UAAU;EAAW,MAAM;EAAyB,SAAS;EAAwD,CAAC;AAEtI,KAAI,aAAa,cAAc,QAAQ;EACrC,MAAM,UAAU,oBAAoB,OAAO,CAAC,QAAQ,SAAS,CAAC,YAAY,aAAc,SAAS,KAAK,CAAC;AACvG,OAAK,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,CACtC,QAAO,KAAK;GAAE,UAAU;GAAW,MAAM;GAAgB,SAAS,SAAS,KAAK;GAAwC,CAAC;;AAG7H,QAAO;;AAGT,SAAS,kBAAkB,KAAqB;CAC9C,MAAM,UAAU,IAAI,MAAM;AAC1B,KAAI,QAAQ,WAAW,IAAI,IAAI,QAAQ,SAAS,IAAI,CAAE,QAAO;CAC7D,MAAM,SAAS,QAAQ,MAAM,gCAAgC,GAAG,IAAI,MAAM;AAC1E,KAAI,QAAQ,WAAW,IAAI,CAAE,QAAO;CACpC,MAAM,QAAQ,QAAQ,QAAQ,IAAI;CAClC,MAAM,MAAM,QAAQ,YAAY,IAAI;AACpC,KAAI,SAAS,KAAK,MAAM,MAAO,QAAO,QAAQ,MAAM,OAAO,MAAM,EAAE;AACnE,OAAM,IAAI,MAAM,sCAAsC;;AAGxD,SAAS,kBAAkB,OAA4C;AACrE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAAE,QAAO,EAAE;AAC1E,QAAO;;AAGT,SAAS,YAAY,OAA0B;AAC7C,QAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,SAAS,OAAO,KAAK,CAAC,CAAC,OAAO,QAAQ,GAAG,EAAE;;AAGtF,SAAS,sBAAsB,OAAuB;CACpD,MAAM,aAAa,MAChB,MAAM,CACN,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,YAAY,GAAG;AAC1B,QAAO,SAAS,KAAK,WAAW,GAAG,aAAa,YAAY,cAAc;;AAG5E,SAAS,qBAAqB,UAAgD;CAC5E,MAAM,cAAc,SAAS;AAC7B,KAAI,CAAC,YAAa,QAAO,CAAC,qCAAqC;CAC/D,MAAM,MAAgB,EAAE;AACxB,KAAI,YAAY,OAAO,OAAQ,KAAI,KAAK,UAAU,YAAY,MAAM,KAAK,KAAK,GAAG;AACjF,KAAI,YAAY,WAAW,KAAM,KAAI,KAAK,YAAY,YAAY,UAAU,YAAY,aAAa;AACrG,KAAI,YAAY,WAAY,KAAI,KAAK,eAAe,YAAY,aAAa;AAC7E,KAAI,YAAY,iBAAkB,KAAI,KAAK,oBAAoB;AAC/D,QAAO,IAAI,SAAS,IAAI,MAAM,CAAC,qCAAqC;;AAGtE,SAAS,4BAA4B,UAAgF;CACnH,MAAM,aAAa,SAAS,aAAa;AACzC,KAAI,CAAC,WAAY,QAAO,KAAA;AACxB,QAAO,OAAO,QAAQ,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,aAAa;EACpE;EACA,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;EACzD,SAAS,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,OAAO,eAAe;EACtF,EAAE;;AAGL,SAAS,oBAAoB,QAA0B;CACrD,MAAM,MAAgB,EAAE;AAExB,MAAK,MAAM,SAAS,OAAO,SAAS,8BAAG,EAAE;EACvC,MAAM,OAAO,MAAM,MAAM;AACzB,OAAK,MAAM,QAAQ,KAAK,SAAS,oBAAoB,CACnD,KAAI,KAAK,KAAK,MAAM,GAAG;;AAG3B,QAAO,IAAI,OAAO,QAAQ"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { WorkflowDefinitionManifest } from '../domain/definition.js';
|
|
2
|
+
import type { WorkflowDefinitionValidationResult } from '../domain/validation.js';
|
|
3
|
+
export type WorkflowDraftMode = 'create' | 'improve';
|
|
4
|
+
export interface WorkflowDraftConstraints {
|
|
5
|
+
allowedTools?: string[];
|
|
6
|
+
allowNetwork?: boolean;
|
|
7
|
+
fileSystem?: 'none' | 'read' | 'write';
|
|
8
|
+
maxPhases?: number;
|
|
9
|
+
maxSubagents?: number;
|
|
10
|
+
outputFormat?: 'report' | 'json' | 'actions';
|
|
11
|
+
}
|
|
12
|
+
export interface CreateWorkflowDraftRequest {
|
|
13
|
+
prompt: string;
|
|
14
|
+
agentId: string;
|
|
15
|
+
language?: 'en' | 'zh';
|
|
16
|
+
mode?: WorkflowDraftMode;
|
|
17
|
+
existingScript?: string;
|
|
18
|
+
constraints?: WorkflowDraftConstraints;
|
|
19
|
+
}
|
|
20
|
+
export interface WorkflowDraftLintIssue {
|
|
21
|
+
severity: 'error' | 'warning';
|
|
22
|
+
code: 'missing_input_schema' | 'missing_output_schema' | 'unsafe_permission' | 'too_many_agents' | 'unknown_tool' | 'weak_phase_names' | 'unbounded_parallelism';
|
|
23
|
+
message: string;
|
|
24
|
+
}
|
|
25
|
+
export interface GeneratedWorkflowDraft {
|
|
26
|
+
name: string;
|
|
27
|
+
script: string;
|
|
28
|
+
manifest: WorkflowDefinitionManifest;
|
|
29
|
+
explanation: string;
|
|
30
|
+
assumptions: string[];
|
|
31
|
+
risks: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface WorkflowDraftResponse extends GeneratedWorkflowDraft {
|
|
34
|
+
draftId: string;
|
|
35
|
+
repairAttempts: number;
|
|
36
|
+
permissionsSummary: string[];
|
|
37
|
+
validation: WorkflowDefinitionValidationResult;
|
|
38
|
+
lint: WorkflowDraftLintIssue[];
|
|
39
|
+
suggestedInputs?: Array<{
|
|
40
|
+
key: string;
|
|
41
|
+
label: string;
|
|
42
|
+
example: string;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projector.js","names":[],"sources":["../../../../src/workflows/engine/projector.ts"],"sourcesContent":["import type { WorkflowEventEnvelope } from '../domain/event.js';\nimport type {\n WorkflowAgentStatus,\n WorkflowAgentView,\n WorkflowLogEntry,\n WorkflowPhaseStatus,\n WorkflowPhaseView,\n WorkflowRun,\n WorkflowRunView,\n WorkflowTimelineItem,\n} from '../domain/run.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/run.js';\nimport type { WorkflowArtifactRef } from '../domain/result.js';\n\nfunction terminalRunStatus(status: WorkflowRun['status']): boolean {\n return isTerminalWorkflowRunStatus(status);\n}\n\nfunction phaseStatusAfterAgentStatus(agentStatuses: WorkflowAgentStatus[]): WorkflowPhaseStatus {\n if (agentStatuses.some((status) => status === 'running')) {\n return 'running';\n }\n if (agentStatuses.some((status) => status === 'error')) {\n return 'failed';\n }\n if (agentStatuses.length > 0 && agentStatuses.every((status) => status === 'done' || status === 'skipped')) {\n return 'completed';\n }\n return 'pending';\n}\n\nfunction buildTimelineItem(event: WorkflowEventEnvelope): WorkflowTimelineItem {\n return {\n sequence: event.sequence,\n type: event.type,\n title: event.type.replaceAll('_', ' '),\n createdAtMs: event.createdAtMs,\n };\n}\n\nexport function projectWorkflowRunView(events: WorkflowEventEnvelope[]): WorkflowRunView | null {\n if (events.length === 0) {\n return null;\n }\n\n const orderedEvents = [...events].sort((left, right) => left.sequence - right.sequence);\n const firstEvent = orderedEvents[0];\n if (firstEvent.type !== 'run_queued') {\n return null;\n }\n\n const firstPayload = firstEvent.payload as { run?: WorkflowRun };\n if (!firstPayload.run) {\n return null;\n }\n\n const run: WorkflowRun = {\n ...firstPayload.run,\n metrics: { ...firstPayload.run.metrics },\n };\n const phaseIdToPhase = new Map<string, WorkflowPhaseView>();\n const agentIdToAgent = new Map<string, WorkflowAgentView>();\n const logs: WorkflowLogEntry[] = [];\n const artifacts: WorkflowArtifactRef[] = [];\n const timeline: WorkflowTimelineItem[] = [];\n\n for (const event of orderedEvents) {\n timeline.push(buildTimelineItem(event));\n\n switch (event.type) {\n case 'run_started': {\n const payload = event.payload as { startedAtMs: number };\n run.status = 'running';\n run.startedAtMs = payload.startedAtMs;\n break;\n }\n case 'phase_started': {\n const payload = event.payload as { phaseId: string; title: string };\n phaseIdToPhase.set(payload.phaseId, {\n id: payload.phaseId,\n title: payload.title,\n status: 'running',\n startedAtMs: event.createdAtMs,\n agentIds: phaseIdToPhase.get(payload.phaseId)?.agentIds ?? [],\n });\n break;\n }\n case 'phase_completed': {\n const payload = event.payload as { phaseId: string };\n const existing = phaseIdToPhase.get(payload.phaseId);\n if (existing) {\n phaseIdToPhase.set(payload.phaseId, {\n ...existing,\n status: 'completed',\n completedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'agent_queued': {\n const payload = event.payload as { agentId: string; label: string; phaseId?: string; prompt?: string; sessionKey: string };\n agentIdToAgent.set(payload.agentId, {\n id: payload.agentId,\n label: payload.label,\n phaseId: payload.phaseId,\n status: 'queued',\n prompt: payload.prompt,\n sessionKey: payload.sessionKey,\n transcriptMessageCount: 0,\n steps: [],\n });\n if (payload.phaseId) {\n const existingPhase = phaseIdToPhase.get(payload.phaseId);\n if (existingPhase && !existingPhase.agentIds.includes(payload.agentId)) {\n phaseIdToPhase.set(payload.phaseId, {\n ...existingPhase,\n agentIds: [...existingPhase.agentIds, payload.agentId],\n });\n }\n }\n break;\n }\n case 'agent_started': {\n const payload = event.payload as { agentId: string };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n status: 'running',\n startedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'agent_step_started': {\n const payload = event.payload as {\n agentId: string;\n stepId: string;\n label: string;\n kind: 'tool' | 'llm' | 'thinking';\n toolName?: string;\n detail?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n currentStep: payload.label,\n transcriptMessageCount: existing.transcriptMessageCount + 1,\n steps: [\n ...existing.steps,\n {\n id: payload.stepId,\n label: payload.label,\n kind: payload.kind,\n toolName: payload.toolName,\n detail: payload.detail,\n status: 'running',\n startedAtMs: event.createdAtMs,\n },\n ],\n });\n }\n break;\n }\n case 'agent_step_completed': {\n const payload = event.payload as {\n agentId: string;\n stepId: string;\n status: 'done' | 'error';\n resultPreview?: string;\n error?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n steps: existing.steps.map((step) =>\n step.id === payload.stepId\n ? {\n ...step,\n status: payload.status,\n resultPreview: payload.resultPreview,\n error: payload.error,\n completedAtMs: event.createdAtMs,\n }\n : step,\n ),\n });\n }\n break;\n }\n case 'agent_completed': {\n const payload = event.payload as {\n agentId: string;\n status: WorkflowAgentStatus;\n resultPreview?: string;\n error?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n status: payload.status,\n currentStep: undefined,\n resultPreview: payload.resultPreview,\n error: payload.error,\n transcriptMessageCount: existing.transcriptMessageCount + 1,\n completedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'log_appended': {\n const payload = event.payload as { message: string };\n logs.push({ sequence: event.sequence, message: payload.message, createdAtMs: event.createdAtMs });\n break;\n }\n case 'artifact_created': {\n const payload = event.payload as { artifact: WorkflowArtifactRef };\n artifacts.push(payload.artifact);\n run.metrics.artifactCount = artifacts.length;\n break;\n }\n case 'run_completed': {\n const payload = event.payload as { result: WorkflowRun['result'] };\n run.status = 'succeeded';\n run.result = payload.result;\n run.completedAtMs = event.createdAtMs;\n break;\n }\n case 'run_failed': {\n const payload = event.payload as { error: WorkflowRun['error'] };\n run.status = payload.error?.code === 'timeout' ? 'timeout' : 'failed';\n run.error = payload.error;\n run.completedAtMs = event.createdAtMs;\n break;\n }\n case 'run_cancelled': {\n run.status = 'cancelled';\n run.completedAtMs = event.createdAtMs;\n for (const [agentId, agent] of agentIdToAgent) {\n if (agent.status !== 'queued' && agent.status !== 'running') {\n continue;\n }\n agentIdToAgent.set(agentId, {\n ...agent,\n status: 'skipped',\n currentStep: undefined,\n completedAtMs: event.createdAtMs,\n steps: agent.steps.map((step) =>\n step.status === 'running'\n ? { ...step, status: 'error', completedAtMs: event.createdAtMs }\n : step,\n ),\n });\n }\n break;\n }\n case 'run_queued':\n default:\n break;\n }\n }\n\n const agents = [...agentIdToAgent.values()];\n run.metrics.agentCount = agents.length;\n run.metrics.doneAgentCount = agents.filter((agent) => agent.status === 'done').length;\n run.metrics.errorAgentCount = agents.filter((agent) => agent.status === 'error').length;\n run.metrics.skippedAgentCount = agents.filter((agent) => agent.status === 'skipped').length;\n run.metrics.artifactCount = artifacts.length;\n if (run.startedAtMs && run.completedAtMs) {\n run.metrics.durationMs = run.completedAtMs - run.startedAtMs;\n }\n\n const phases = [...phaseIdToPhase.values()].map((phase) => {\n if (phase.status === 'completed' || phase.status === 'failed') {\n return phase;\n }\n const phaseAgents = phase.agentIds\n .map((agentId) => agentIdToAgent.get(agentId)?.status)\n .filter((status): status is WorkflowAgentStatus => Boolean(status));\n return { ...phase, status: phaseStatusAfterAgentStatus(phaseAgents) };\n });\n\n return {\n run,\n phases,\n agents,\n logs,\n artifacts,\n timeline,\n controls: {\n canCancel: !terminalRunStatus(run.status),\n canRetry: terminalRunStatus(run.status),\n canArchive: terminalRunStatus(run.status),\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"projector.js","names":[],"sources":["../../../../src/workflows/engine/projector.ts"],"sourcesContent":["import type { WorkflowEventEnvelope } from '../domain/event.js';\nimport type {\n WorkflowAgentStatus,\n WorkflowAgentView,\n WorkflowLogEntry,\n WorkflowPhaseStatus,\n WorkflowPhaseView,\n WorkflowRun,\n WorkflowRunView,\n WorkflowTimelineItem,\n} from '../domain/run.js';\nimport { isTerminalWorkflowRunStatus } from '../domain/run.js';\nimport type { WorkflowArtifactRef } from '../domain/result.js';\n\nfunction terminalRunStatus(status: WorkflowRun['status']): boolean {\n return isTerminalWorkflowRunStatus(status);\n}\n\nfunction phaseStatusAfterAgentStatus(agentStatuses: WorkflowAgentStatus[]): WorkflowPhaseStatus {\n if (agentStatuses.some((status) => status === 'running')) {\n return 'running';\n }\n if (agentStatuses.some((status) => status === 'error')) {\n return 'failed';\n }\n if (agentStatuses.length > 0 && agentStatuses.every((status) => status === 'done' || status === 'skipped')) {\n return 'completed';\n }\n return 'pending';\n}\n\nfunction buildTimelineItem(event: WorkflowEventEnvelope): WorkflowTimelineItem {\n return {\n sequence: event.sequence,\n type: event.type,\n title: event.type.replaceAll('_', ' '),\n createdAtMs: event.createdAtMs,\n };\n}\n\nexport function projectWorkflowRunView(events: WorkflowEventEnvelope[]): WorkflowRunView | null {\n if (events.length === 0) {\n return null;\n }\n\n const orderedEvents = [...events].sort((left, right) => left.sequence - right.sequence);\n const firstEvent = orderedEvents[0];\n if (firstEvent.type !== 'run_queued') {\n return null;\n }\n\n const firstPayload = firstEvent.payload as { run?: WorkflowRun };\n if (!firstPayload.run) {\n return null;\n }\n\n const run: WorkflowRun = {\n ...firstPayload.run,\n metrics: { ...firstPayload.run.metrics },\n };\n const phaseIdToPhase = new Map<string, WorkflowPhaseView>();\n const agentIdToAgent = new Map<string, WorkflowAgentView>();\n const logs: WorkflowLogEntry[] = [];\n const artifacts: WorkflowArtifactRef[] = [];\n const timeline: WorkflowTimelineItem[] = [];\n\n for (const event of orderedEvents) {\n timeline.push(buildTimelineItem(event));\n\n switch (event.type) {\n case 'run_started': {\n const payload = event.payload as { startedAtMs: number };\n run.status = 'running';\n run.startedAtMs = payload.startedAtMs;\n break;\n }\n case 'phase_started': {\n const payload = event.payload as { phaseId: string; title: string };\n phaseIdToPhase.set(payload.phaseId, {\n id: payload.phaseId,\n title: payload.title,\n status: 'running',\n startedAtMs: event.createdAtMs,\n agentIds: phaseIdToPhase.get(payload.phaseId)?.agentIds ?? [],\n });\n break;\n }\n case 'phase_completed': {\n const payload = event.payload as { phaseId: string };\n const existing = phaseIdToPhase.get(payload.phaseId);\n if (existing) {\n phaseIdToPhase.set(payload.phaseId, {\n ...existing,\n status: 'completed',\n completedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'agent_queued': {\n const payload = event.payload as {\n agentId: string;\n label: string;\n phaseId?: string;\n prompt?: string;\n sessionKey: string;\n invocation?: WorkflowAgentView['invocation'];\n };\n agentIdToAgent.set(payload.agentId, {\n id: payload.agentId,\n label: payload.label,\n phaseId: payload.phaseId,\n status: 'queued',\n prompt: payload.prompt,\n invocation: payload.invocation,\n sessionKey: payload.sessionKey,\n transcriptMessageCount: 0,\n steps: [],\n });\n if (payload.phaseId) {\n const existingPhase = phaseIdToPhase.get(payload.phaseId);\n if (existingPhase && !existingPhase.agentIds.includes(payload.agentId)) {\n phaseIdToPhase.set(payload.phaseId, {\n ...existingPhase,\n agentIds: [...existingPhase.agentIds, payload.agentId],\n });\n }\n }\n break;\n }\n case 'agent_started': {\n const payload = event.payload as { agentId: string };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n status: 'running',\n startedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'agent_step_started': {\n const payload = event.payload as {\n agentId: string;\n stepId: string;\n label: string;\n kind: 'tool' | 'llm' | 'thinking';\n toolName?: string;\n detail?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n currentStep: payload.label,\n transcriptMessageCount: existing.transcriptMessageCount + 1,\n steps: [\n ...existing.steps,\n {\n id: payload.stepId,\n label: payload.label,\n kind: payload.kind,\n toolName: payload.toolName,\n detail: payload.detail,\n status: 'running',\n startedAtMs: event.createdAtMs,\n },\n ],\n });\n }\n break;\n }\n case 'agent_step_completed': {\n const payload = event.payload as {\n agentId: string;\n stepId: string;\n status: 'done' | 'error';\n resultPreview?: string;\n error?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n steps: existing.steps.map((step) =>\n step.id === payload.stepId\n ? {\n ...step,\n status: payload.status,\n resultPreview: payload.resultPreview,\n error: payload.error,\n completedAtMs: event.createdAtMs,\n }\n : step,\n ),\n });\n }\n break;\n }\n case 'agent_completed': {\n const payload = event.payload as {\n agentId: string;\n status: WorkflowAgentStatus;\n resultPreview?: string;\n error?: string;\n };\n const existing = agentIdToAgent.get(payload.agentId);\n if (existing) {\n agentIdToAgent.set(payload.agentId, {\n ...existing,\n status: payload.status,\n currentStep: undefined,\n resultPreview: payload.resultPreview,\n error: payload.error,\n transcriptMessageCount: existing.transcriptMessageCount + 1,\n completedAtMs: event.createdAtMs,\n });\n }\n break;\n }\n case 'log_appended': {\n const payload = event.payload as { message: string };\n logs.push({ sequence: event.sequence, message: payload.message, createdAtMs: event.createdAtMs });\n break;\n }\n case 'artifact_created': {\n const payload = event.payload as { artifact: WorkflowArtifactRef };\n artifacts.push(payload.artifact);\n run.metrics.artifactCount = artifacts.length;\n break;\n }\n case 'run_completed': {\n const payload = event.payload as { result: WorkflowRun['result'] };\n run.status = 'succeeded';\n run.result = payload.result;\n run.completedAtMs = event.createdAtMs;\n break;\n }\n case 'run_failed': {\n const payload = event.payload as { error: WorkflowRun['error'] };\n run.status = payload.error?.code === 'timeout' ? 'timeout' : 'failed';\n run.error = payload.error;\n run.completedAtMs = event.createdAtMs;\n break;\n }\n case 'run_cancelled': {\n run.status = 'cancelled';\n run.completedAtMs = event.createdAtMs;\n for (const [agentId, agent] of agentIdToAgent) {\n if (agent.status !== 'queued' && agent.status !== 'running') {\n continue;\n }\n agentIdToAgent.set(agentId, {\n ...agent,\n status: 'skipped',\n currentStep: undefined,\n completedAtMs: event.createdAtMs,\n steps: agent.steps.map((step) =>\n step.status === 'running'\n ? { ...step, status: 'error', completedAtMs: event.createdAtMs }\n : step,\n ),\n });\n }\n break;\n }\n case 'run_queued':\n default:\n break;\n }\n }\n\n const agents = [...agentIdToAgent.values()];\n run.metrics.agentCount = agents.length;\n run.metrics.doneAgentCount = agents.filter((agent) => agent.status === 'done').length;\n run.metrics.errorAgentCount = agents.filter((agent) => agent.status === 'error').length;\n run.metrics.skippedAgentCount = agents.filter((agent) => agent.status === 'skipped').length;\n run.metrics.artifactCount = artifacts.length;\n if (run.startedAtMs && run.completedAtMs) {\n run.metrics.durationMs = run.completedAtMs - run.startedAtMs;\n }\n\n const phases = [...phaseIdToPhase.values()].map((phase) => {\n if (phase.status === 'completed' || phase.status === 'failed') {\n return phase;\n }\n const phaseAgents = phase.agentIds\n .map((agentId) => agentIdToAgent.get(agentId)?.status)\n .filter((status): status is WorkflowAgentStatus => Boolean(status));\n return { ...phase, status: phaseStatusAfterAgentStatus(phaseAgents) };\n });\n\n return {\n run,\n phases,\n agents,\n logs,\n artifacts,\n timeline,\n controls: {\n canCancel: !terminalRunStatus(run.status),\n canRetry: terminalRunStatus(run.status),\n canArchive: terminalRunStatus(run.status),\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { WorkflowRunStore } from '../store/run-store.js';
|
|
|
6
6
|
import type { WorkflowRuntime } from '../runtime/workflow-runtime-port.js';
|
|
7
7
|
import type { Api, Model } from '@earendil-works/pi-ai';
|
|
8
8
|
import type { WorkflowScriptSubagentRunner } from '../runtime/script-runtime.js';
|
|
9
|
+
import type { WorkflowAgentInvocationSnapshot } from '../domain/index.js';
|
|
9
10
|
export interface WorkflowEngineOptions {
|
|
10
11
|
cwd: string;
|
|
11
12
|
eventStore: WorkflowEventStore;
|
|
@@ -59,10 +60,27 @@ export interface StartWorkflowRunOptions {
|
|
|
59
60
|
concurrency?: number;
|
|
60
61
|
maxSubagents?: number;
|
|
61
62
|
tokenBudget?: number | null;
|
|
63
|
+
timeoutSec?: number;
|
|
64
|
+
}
|
|
65
|
+
export interface WorkflowReplayAgentTarget {
|
|
66
|
+
agentId: string;
|
|
67
|
+
label: string;
|
|
68
|
+
phaseId?: string;
|
|
69
|
+
phaseTitle?: string;
|
|
70
|
+
prompt: string;
|
|
71
|
+
invocation?: WorkflowAgentInvocationSnapshot;
|
|
72
|
+
}
|
|
73
|
+
export interface StartWorkflowReplayRunOptions extends StartWorkflowRunOptions {
|
|
74
|
+
sourceRunId: string;
|
|
75
|
+
replayScope: 'failed_agents' | 'failed_phases';
|
|
76
|
+
targets: WorkflowReplayAgentTarget[];
|
|
62
77
|
}
|
|
63
78
|
export declare class WorkflowEngine {
|
|
64
79
|
private readonly options;
|
|
65
80
|
constructor(options: WorkflowEngineOptions);
|
|
66
81
|
startRun(definition: WorkflowDefinition, options: StartWorkflowRunOptions): Promise<WorkflowRunView>;
|
|
82
|
+
startReplayRun(definition: WorkflowDefinition, options: StartWorkflowReplayRunOptions): Promise<WorkflowRunView>;
|
|
83
|
+
private runReplayTargets;
|
|
84
|
+
private runReplayTarget;
|
|
67
85
|
private callHooks;
|
|
68
86
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { workflowStepLabel } from "../../agent/workflow/step-labels.js";
|
|
2
|
+
import { validateWorkflowJsonSchema } from "../domain/schema-validation.js";
|
|
2
3
|
import { createScriptWorkflowRuntime } from "../runtime/script-workflow-runtime.js";
|
|
3
4
|
import { randomUUID } from "node:crypto";
|
|
4
5
|
//#region src/workflows/engine/workflow-engine.ts
|
|
@@ -53,7 +54,7 @@ var WorkflowEngine = class {
|
|
|
53
54
|
}));
|
|
54
55
|
await appendEvent("run_started", { startedAtMs: Date.now() });
|
|
55
56
|
try {
|
|
56
|
-
const runtimeResult = await (this.options.runtime ?? createScriptWorkflowRuntime()).run(definition.runtime.source, {
|
|
57
|
+
const runtimeResult = await withWorkflowTimeout((this.options.runtime ?? createScriptWorkflowRuntime()).run(definition.runtime.source, {
|
|
57
58
|
runner: this.options.runner,
|
|
58
59
|
resolveModelId: this.options.resolveModelId
|
|
59
60
|
}, {
|
|
@@ -95,7 +96,8 @@ var WorkflowEngine = class {
|
|
|
95
96
|
label: event.label,
|
|
96
97
|
phaseId,
|
|
97
98
|
prompt: event.prompt,
|
|
98
|
-
sessionKey: subagentSessionKey
|
|
99
|
+
sessionKey: subagentSessionKey,
|
|
100
|
+
invocation: event.invocation
|
|
99
101
|
});
|
|
100
102
|
},
|
|
101
103
|
onAgentStart: (event) => {
|
|
@@ -143,9 +145,10 @@ var WorkflowEngine = class {
|
|
|
143
145
|
onProgress: (event) => recorder.onProgress(event)
|
|
144
146
|
};
|
|
145
147
|
}
|
|
146
|
-
});
|
|
148
|
+
}), options.timeoutSec ?? definition.defaults.timeoutSec);
|
|
147
149
|
await eventQueue;
|
|
148
150
|
if (currentPhaseId) await appendEvent("phase_completed", { phaseId: currentPhaseId });
|
|
151
|
+
assertWorkflowOutput(definition, runtimeResult.result);
|
|
149
152
|
await appendEvent("run_completed", { result: toWorkflowResultEnvelope(runtimeResult.result) });
|
|
150
153
|
await this.callHooks((hook) => hook.afterRun?.({
|
|
151
154
|
runId,
|
|
@@ -153,7 +156,7 @@ var WorkflowEngine = class {
|
|
|
153
156
|
}));
|
|
154
157
|
} catch (err) {
|
|
155
158
|
await eventQueue;
|
|
156
|
-
const error = toWorkflowRunError(err, options.signal?.aborted === true);
|
|
159
|
+
const error = toWorkflowRunError(err, options.signal?.aborted === true, options.signal?.reason);
|
|
157
160
|
if (error.code === "cancelled") {
|
|
158
161
|
await appendEvent("run_cancelled", { reason: error.message });
|
|
159
162
|
await this.callHooks((hook) => hook.afterRun?.({
|
|
@@ -172,12 +175,233 @@ var WorkflowEngine = class {
|
|
|
172
175
|
if (!view) throw new Error(`workflow run view was not created for ${runId}`);
|
|
173
176
|
return view;
|
|
174
177
|
}
|
|
178
|
+
async startReplayRun(definition, options) {
|
|
179
|
+
const runId = options.runId ?? randomUUID();
|
|
180
|
+
const createdAtMs = Date.now();
|
|
181
|
+
let eventQueue = Promise.resolve();
|
|
182
|
+
const progressRecorders = /* @__PURE__ */ new Map();
|
|
183
|
+
const run = {
|
|
184
|
+
id: runId,
|
|
185
|
+
definitionId: definition.id,
|
|
186
|
+
definitionVersion: definition.version,
|
|
187
|
+
title: `${definition.title} replay`,
|
|
188
|
+
goal: options.goal ?? definition.description,
|
|
189
|
+
input: options.input ?? {},
|
|
190
|
+
status: "queued",
|
|
191
|
+
source: options.source,
|
|
192
|
+
metadata: options.metadata,
|
|
193
|
+
metrics: {
|
|
194
|
+
agentCount: 0,
|
|
195
|
+
doneAgentCount: 0,
|
|
196
|
+
errorAgentCount: 0,
|
|
197
|
+
skippedAgentCount: 0,
|
|
198
|
+
artifactCount: 0
|
|
199
|
+
},
|
|
200
|
+
createdAtMs
|
|
201
|
+
};
|
|
202
|
+
const appendEvent = (type, payload, createdAtMsOverride) => {
|
|
203
|
+
eventQueue = eventQueue.then(() => this.options.eventStore.append({
|
|
204
|
+
runId,
|
|
205
|
+
type,
|
|
206
|
+
payload,
|
|
207
|
+
createdAtMs: createdAtMsOverride
|
|
208
|
+
})).then(async (event) => {
|
|
209
|
+
this.options.onEventAppended?.(event);
|
|
210
|
+
const view = await this.options.runStore.rebuildRunView(runId);
|
|
211
|
+
if (view) this.options.onRunViewUpdated?.(view);
|
|
212
|
+
});
|
|
213
|
+
return eventQueue;
|
|
214
|
+
};
|
|
215
|
+
await appendEvent("run_queued", { run }, createdAtMs);
|
|
216
|
+
await this.callHooks((hook) => hook.beforeRun?.({
|
|
217
|
+
definition,
|
|
218
|
+
run
|
|
219
|
+
}));
|
|
220
|
+
await appendEvent("run_started", { startedAtMs: Date.now() });
|
|
221
|
+
try {
|
|
222
|
+
const result = await withWorkflowTimeout(this.runReplayTargets({
|
|
223
|
+
definition,
|
|
224
|
+
runId,
|
|
225
|
+
targets: options.targets,
|
|
226
|
+
signal: options.signal,
|
|
227
|
+
appendEvent,
|
|
228
|
+
progressRecorders
|
|
229
|
+
}), options.timeoutSec ?? definition.defaults.timeoutSec);
|
|
230
|
+
await eventQueue;
|
|
231
|
+
if (result.errors.length > 0) {
|
|
232
|
+
await appendEvent("run_failed", { error: {
|
|
233
|
+
code: "runtime_error",
|
|
234
|
+
message: `Replay completed with ${result.errors.length} failed target${result.errors.length === 1 ? "" : "s"}.`,
|
|
235
|
+
detail: result.errors.join("\n"),
|
|
236
|
+
recoverable: true
|
|
237
|
+
} });
|
|
238
|
+
await this.callHooks((hook) => hook.afterRun?.({
|
|
239
|
+
runId,
|
|
240
|
+
status: "failed"
|
|
241
|
+
}));
|
|
242
|
+
} else {
|
|
243
|
+
await appendEvent("run_completed", { result: buildReplayResultEnvelope(options, result.results) });
|
|
244
|
+
await this.callHooks((hook) => hook.afterRun?.({
|
|
245
|
+
runId,
|
|
246
|
+
status: "succeeded"
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
} catch (err) {
|
|
250
|
+
await eventQueue;
|
|
251
|
+
const error = toWorkflowRunError(err, options.signal?.aborted === true, options.signal?.reason);
|
|
252
|
+
if (error.code === "cancelled") {
|
|
253
|
+
await appendEvent("run_cancelled", { reason: error.message });
|
|
254
|
+
await this.callHooks((hook) => hook.afterRun?.({
|
|
255
|
+
runId,
|
|
256
|
+
status: "cancelled"
|
|
257
|
+
}));
|
|
258
|
+
} else {
|
|
259
|
+
await appendEvent("run_failed", { error });
|
|
260
|
+
await this.callHooks((hook) => hook.afterRun?.({
|
|
261
|
+
runId,
|
|
262
|
+
status: "failed"
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const view = await this.options.runStore.readRunView(runId);
|
|
267
|
+
if (!view) throw new Error(`workflow replay run view was not created for ${runId}`);
|
|
268
|
+
return view;
|
|
269
|
+
}
|
|
270
|
+
async runReplayTargets(params) {
|
|
271
|
+
const results = [];
|
|
272
|
+
const errors = [];
|
|
273
|
+
const targetsByPhase = groupReplayTargetsByPhase(params.targets);
|
|
274
|
+
for (const group of targetsByPhase) {
|
|
275
|
+
throwIfSignalAborted(params.signal);
|
|
276
|
+
if (group.phaseId && group.phaseTitle) await params.appendEvent("phase_started", {
|
|
277
|
+
phaseId: group.phaseId,
|
|
278
|
+
title: group.phaseTitle
|
|
279
|
+
});
|
|
280
|
+
const phaseResults = await Promise.all(group.targets.map((target) => this.runReplayTarget({
|
|
281
|
+
...params,
|
|
282
|
+
target
|
|
283
|
+
})));
|
|
284
|
+
results.push(...phaseResults);
|
|
285
|
+
errors.push(...phaseResults.filter((item) => item.status === "error").map((item) => `${item.label}: ${item.error ?? "failed"}`));
|
|
286
|
+
if (group.phaseId && phaseResults.every((item) => item.status === "done")) await params.appendEvent("phase_completed", { phaseId: group.phaseId });
|
|
287
|
+
}
|
|
288
|
+
return {
|
|
289
|
+
results,
|
|
290
|
+
errors
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
async runReplayTarget(params) {
|
|
294
|
+
const { target } = params;
|
|
295
|
+
const invocation = normalizeReplayInvocation(target);
|
|
296
|
+
const sessionKey = this.options.subagentSessionKeyFactory?.({
|
|
297
|
+
runId: params.runId,
|
|
298
|
+
agentId: target.agentId
|
|
299
|
+
}) ?? defaultSubagentSessionKey(params.runId, target.agentId);
|
|
300
|
+
await this.callHooks((hook) => hook.beforeAgent?.({
|
|
301
|
+
runId: params.runId,
|
|
302
|
+
agentId: target.agentId,
|
|
303
|
+
label: invocation.label,
|
|
304
|
+
phaseId: target.phaseId,
|
|
305
|
+
prompt: invocation.prompt
|
|
306
|
+
}));
|
|
307
|
+
await params.appendEvent("agent_queued", {
|
|
308
|
+
agentId: target.agentId,
|
|
309
|
+
label: invocation.label,
|
|
310
|
+
phaseId: target.phaseId,
|
|
311
|
+
prompt: invocation.prompt,
|
|
312
|
+
sessionKey,
|
|
313
|
+
invocation
|
|
314
|
+
});
|
|
315
|
+
await params.appendEvent("agent_started", { agentId: target.agentId });
|
|
316
|
+
const recorder = new AgentProgressRecorder({
|
|
317
|
+
agentId: target.agentId,
|
|
318
|
+
appendEvent: params.appendEvent
|
|
319
|
+
});
|
|
320
|
+
params.progressRecorders.set(target.agentId, recorder);
|
|
321
|
+
try {
|
|
322
|
+
throwIfSignalAborted(params.signal);
|
|
323
|
+
const model = resolveReplayModel(invocation, this.options.resolveModelId);
|
|
324
|
+
const result = await this.options.runner.run(invocation.prompt, {
|
|
325
|
+
label: invocation.label,
|
|
326
|
+
schema: invocation.schema,
|
|
327
|
+
allowedToolNames: invocation.toolset,
|
|
328
|
+
maxIterations: invocation.maxIterations,
|
|
329
|
+
phase: invocation.phase ?? target.phaseTitle,
|
|
330
|
+
signal: params.signal,
|
|
331
|
+
model,
|
|
332
|
+
sessionKey,
|
|
333
|
+
sessionMetadata: {
|
|
334
|
+
parentSessionKey: this.options.parentSessionKey,
|
|
335
|
+
workflowRunId: params.runId,
|
|
336
|
+
workflowDefinitionId: params.definition.id,
|
|
337
|
+
workflowAgentId: target.agentId,
|
|
338
|
+
workflowAgentLabel: invocation.label
|
|
339
|
+
},
|
|
340
|
+
onProgress: (event) => recorder.onProgress(event)
|
|
341
|
+
});
|
|
342
|
+
throwIfSignalAborted(params.signal);
|
|
343
|
+
const status = result === null ? "error" : "done";
|
|
344
|
+
const resultPreview = previewWorkflowValue(result);
|
|
345
|
+
recorder.completeOpenSteps(status === "done" ? "done" : "error");
|
|
346
|
+
await params.appendEvent("agent_completed", {
|
|
347
|
+
agentId: target.agentId,
|
|
348
|
+
status,
|
|
349
|
+
resultPreview,
|
|
350
|
+
error: status === "error" ? "Replay target failed" : void 0
|
|
351
|
+
});
|
|
352
|
+
await this.callHooks((hook) => hook.afterAgent?.({
|
|
353
|
+
runId: params.runId,
|
|
354
|
+
agentId: target.agentId,
|
|
355
|
+
status,
|
|
356
|
+
resultPreview
|
|
357
|
+
}));
|
|
358
|
+
return {
|
|
359
|
+
agentId: target.agentId,
|
|
360
|
+
label: invocation.label,
|
|
361
|
+
phaseId: target.phaseId,
|
|
362
|
+
status,
|
|
363
|
+
resultPreview
|
|
364
|
+
};
|
|
365
|
+
} catch (err) {
|
|
366
|
+
if (params.signal?.aborted) throw err;
|
|
367
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
368
|
+
recorder.completeOpenSteps("error");
|
|
369
|
+
await params.appendEvent("agent_completed", {
|
|
370
|
+
agentId: target.agentId,
|
|
371
|
+
status: "error",
|
|
372
|
+
error: message
|
|
373
|
+
});
|
|
374
|
+
await this.callHooks((hook) => hook.afterAgent?.({
|
|
375
|
+
runId: params.runId,
|
|
376
|
+
agentId: target.agentId,
|
|
377
|
+
status: "error"
|
|
378
|
+
}));
|
|
379
|
+
return {
|
|
380
|
+
agentId: target.agentId,
|
|
381
|
+
label: invocation.label,
|
|
382
|
+
phaseId: target.phaseId,
|
|
383
|
+
status: "error",
|
|
384
|
+
error: message
|
|
385
|
+
};
|
|
386
|
+
} finally {
|
|
387
|
+
params.progressRecorders.delete(target.agentId);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
175
390
|
async callHooks(call) {
|
|
176
391
|
for (const hook of this.options.hooks ?? []) try {
|
|
177
392
|
await call(hook);
|
|
178
393
|
} catch {}
|
|
179
394
|
}
|
|
180
395
|
};
|
|
396
|
+
var WorkflowEngineRunError = class extends Error {
|
|
397
|
+
constructor(code, message, recoverable, detail) {
|
|
398
|
+
super(message);
|
|
399
|
+
this.code = code;
|
|
400
|
+
this.recoverable = recoverable;
|
|
401
|
+
this.detail = detail;
|
|
402
|
+
this.name = "WorkflowEngineRunError";
|
|
403
|
+
}
|
|
404
|
+
};
|
|
181
405
|
var AgentProgressRecorder = class {
|
|
182
406
|
activeToolStepIds = /* @__PURE__ */ new Map();
|
|
183
407
|
activeIterationStepId = null;
|
|
@@ -301,6 +525,80 @@ function buildPhaseTitleToId(definition) {
|
|
|
301
525
|
function normalizePhaseId(title) {
|
|
302
526
|
return title.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "phase";
|
|
303
527
|
}
|
|
528
|
+
function withWorkflowTimeout(promise, timeoutSec) {
|
|
529
|
+
if (typeof timeoutSec !== "number" || !Number.isFinite(timeoutSec) || timeoutSec <= 0) return promise;
|
|
530
|
+
let timeout;
|
|
531
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
532
|
+
timeout = setTimeout(() => {
|
|
533
|
+
reject(/* @__PURE__ */ new Error(`workflow timed out after ${timeoutSec}s`));
|
|
534
|
+
}, timeoutSec * 1e3);
|
|
535
|
+
});
|
|
536
|
+
return Promise.race([promise, timeoutPromise]).finally(() => {
|
|
537
|
+
if (timeout) clearTimeout(timeout);
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
function throwIfSignalAborted(signal) {
|
|
541
|
+
if (!signal?.aborted) return;
|
|
542
|
+
const reason = signal.reason;
|
|
543
|
+
if (reason instanceof Error) throw reason;
|
|
544
|
+
if (reason) throw new Error(String(reason));
|
|
545
|
+
throw new Error("workflow aborted");
|
|
546
|
+
}
|
|
547
|
+
function groupReplayTargetsByPhase(targets) {
|
|
548
|
+
const groups = [];
|
|
549
|
+
for (const target of targets) {
|
|
550
|
+
const key = target.phaseId ?? "";
|
|
551
|
+
let group = groups.find((item) => item.key === key);
|
|
552
|
+
if (!group) {
|
|
553
|
+
group = {
|
|
554
|
+
key,
|
|
555
|
+
phaseId: target.phaseId,
|
|
556
|
+
phaseTitle: target.phaseTitle,
|
|
557
|
+
targets: []
|
|
558
|
+
};
|
|
559
|
+
groups.push(group);
|
|
560
|
+
}
|
|
561
|
+
group.targets.push(target);
|
|
562
|
+
}
|
|
563
|
+
return groups.map(({ key: _key, ...group }) => group);
|
|
564
|
+
}
|
|
565
|
+
function buildReplayResultEnvelope(options, results) {
|
|
566
|
+
return {
|
|
567
|
+
summary: `Replay completed for ${results.filter((item) => item.status === "done").length}/${results.length} target${results.length === 1 ? "" : "s"}.`,
|
|
568
|
+
sections: [{
|
|
569
|
+
kind: "json",
|
|
570
|
+
title: "Replay targets",
|
|
571
|
+
value: {
|
|
572
|
+
sourceRunId: options.sourceRunId,
|
|
573
|
+
scope: options.replayScope,
|
|
574
|
+
targets: results
|
|
575
|
+
}
|
|
576
|
+
}],
|
|
577
|
+
structuredOutput: { replay: {
|
|
578
|
+
sourceRunId: options.sourceRunId,
|
|
579
|
+
scope: options.replayScope,
|
|
580
|
+
targets: results
|
|
581
|
+
} }
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
function normalizeReplayInvocation(target) {
|
|
585
|
+
return {
|
|
586
|
+
prompt: target.invocation?.prompt ?? target.prompt,
|
|
587
|
+
label: target.invocation?.label ?? target.label,
|
|
588
|
+
phase: target.invocation?.phase ?? target.phaseTitle,
|
|
589
|
+
modelRef: target.invocation?.modelRef,
|
|
590
|
+
resolvedModelRef: target.invocation?.resolvedModelRef,
|
|
591
|
+
schema: target.invocation?.schema,
|
|
592
|
+
toolset: target.invocation?.toolset ? [...target.invocation.toolset] : void 0,
|
|
593
|
+
maxIterations: target.invocation?.maxIterations
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function resolveReplayModel(invocation, resolveModelId) {
|
|
597
|
+
const modelRef = invocation.resolvedModelRef ?? invocation.modelRef;
|
|
598
|
+
if (!modelRef) return void 0;
|
|
599
|
+
if (!resolveModelId) throw new Error(`workflow replay missing resolveModelId; cannot resolve model '${modelRef}'`);
|
|
600
|
+
return resolveModelId(modelRef);
|
|
601
|
+
}
|
|
304
602
|
function formatRuntimeAgentId(id) {
|
|
305
603
|
return `agent-${id}`;
|
|
306
604
|
}
|
|
@@ -346,23 +644,34 @@ function toWorkflowResultEnvelope(value) {
|
|
|
346
644
|
raw: value
|
|
347
645
|
};
|
|
348
646
|
}
|
|
647
|
+
function assertWorkflowOutput(definition, value) {
|
|
648
|
+
const validation = validateWorkflowJsonSchema(definition.outputSchema, value);
|
|
649
|
+
if (validation.ok) return;
|
|
650
|
+
throw new WorkflowEngineRunError("result_validation_failed", validation.message ?? "Workflow result did not match output schema", false, JSON.stringify(validation.errors ?? []));
|
|
651
|
+
}
|
|
349
652
|
function isWorkflowResultEnvelope(value) {
|
|
350
653
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
351
654
|
const record = value;
|
|
352
655
|
return typeof record.summary === "string" && Array.isArray(record.sections);
|
|
353
656
|
}
|
|
354
|
-
function toWorkflowRunError(err, wasAborted) {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
recoverable:
|
|
657
|
+
function toWorkflowRunError(err, wasAborted, abortReason) {
|
|
658
|
+
if (err instanceof WorkflowEngineRunError) return {
|
|
659
|
+
code: err.code,
|
|
660
|
+
message: err.message,
|
|
661
|
+
detail: err.detail,
|
|
662
|
+
recoverable: err.recoverable
|
|
360
663
|
};
|
|
361
|
-
|
|
664
|
+
const message = (abortReason instanceof Error ? abortReason.message : abortReason ? String(abortReason) : "") || (err instanceof Error ? err.message : String(err));
|
|
665
|
+
if (/timeout|timed out/i.test(message)) return {
|
|
362
666
|
code: "timeout",
|
|
363
667
|
message,
|
|
364
668
|
recoverable: true
|
|
365
669
|
};
|
|
670
|
+
if (wasAborted || /aborted|cancelled/i.test(message)) return {
|
|
671
|
+
code: "cancelled",
|
|
672
|
+
message: message || "Workflow run cancelled",
|
|
673
|
+
recoverable: true
|
|
674
|
+
};
|
|
366
675
|
if (/quota/i.test(message)) return {
|
|
367
676
|
code: "agent_quota_exceeded",
|
|
368
677
|
message,
|