@xopcai/xopc 0.0.106 → 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/outbound/media-load.js +1 -1
- package/dist/extensions/feishu/src/workflow-progress.js +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/streaming-adapter.js +1 -1
- package/dist/extensions/telegram/src/inbound-processor.js +1 -1
- package/dist/extensions/telegram/src/plugin.js +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.js +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/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.js +1 -1
- package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
- package/dist/extensions/weixin/src/workflow-progress.js +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-OM9qGfm5.js → dist-CZh0c-s8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-D-WHrr_w.js → extension-debug-page-DyJQR0SR.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-CCgjSoKn.js → extension-page-CDTuUr9B.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-BJH5a-Gn.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-CVyP6pFj.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-R6Vv_Ja6.js → logs-page-B6js8Bfi.js} +2 -2
- package/dist/gateway/static/root/assets/{note-detail-page-BUDarLhh.js → note-detail-page-DFzAXR35.js} +4 -4
- package/dist/gateway/static/root/assets/{note-time-Cc2-T21g.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-CrlOmEZt.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-BBAQxxew.js → settings-advanced-gate-BCvObK1y.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-form-section-DjPD-ErC.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-BjvPht3V.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-D4sqR0yX.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-materialize.js +1 -1
- package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
- package/dist/src/agent/mcp/mcp-transport-config.js +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/runtime.js +49 -15
- package/dist/src/agent/workflow/runtime.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/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/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 +1 -1
- 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/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 +4 -2
- package/dist/gateway/static/root/assets/agents-3eP0vqFO.js +0 -396
- package/dist/gateway/static/root/assets/apps-page-CZ2ZKrko.js +0 -1
- package/dist/gateway/static/root/assets/channels-settings-BbETa93K.js +0 -1
- package/dist/gateway/static/root/assets/cron-page-DCtUkHMu.js +0 -1
- package/dist/gateway/static/root/assets/index-BPYKW7FB.css +0 -1
- package/dist/gateway/static/root/assets/index-CEZxETzw.js +0 -4845
- package/dist/gateway/static/root/assets/notes-page-EAHl16bq.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-Ce_xuuSB.js +0 -1
- package/dist/gateway/static/root/assets/settings-page-KhQ9QgH0.js +0 -3
- package/dist/gateway/static/root/assets/skills-page-C0laq7l1.js +0 -2
- package/dist/gateway/static/root/assets/url-DPEStU4M.js +0 -3
- package/dist/gateway/static/root/assets/voice-api-key-field-DeGckWkl.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DFjM95g5.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,3 @@
|
|
|
1
|
+
import { buildWorkflowDraftResponse, lintWorkflowDraft, parseGeneratedWorkflowDraft } from "./workflow-draft-validator.js";
|
|
2
|
+
import { WorkflowDraftService, resolveDraftModelRef } from "./workflow-draft-service.js";
|
|
3
|
+
export { WorkflowDraftService, buildWorkflowDraftResponse, lintWorkflowDraft, parseGeneratedWorkflowDraft, resolveDraftModelRef };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WorkflowDraftConstraints, WorkflowDraftMode } from './workflow-draft.types.js';
|
|
2
|
+
export interface WorkflowDraftRepairIssue {
|
|
3
|
+
source: 'parse' | 'validation' | 'lint';
|
|
4
|
+
severity: 'error' | 'warning';
|
|
5
|
+
code: string;
|
|
6
|
+
message: string;
|
|
7
|
+
line?: number;
|
|
8
|
+
column?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildWorkflowDraftPrompt(params: {
|
|
11
|
+
prompt: string;
|
|
12
|
+
language?: 'en' | 'zh';
|
|
13
|
+
mode: WorkflowDraftMode;
|
|
14
|
+
existingScript?: string;
|
|
15
|
+
constraints?: WorkflowDraftConstraints;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare function buildWorkflowDraftRepairPrompt(params: {
|
|
18
|
+
prompt: string;
|
|
19
|
+
language?: 'en' | 'zh';
|
|
20
|
+
constraints?: WorkflowDraftConstraints;
|
|
21
|
+
previousOutput: string;
|
|
22
|
+
issues: WorkflowDraftRepairIssue[];
|
|
23
|
+
}): string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
//#region src/workflows/draft/workflow-draft-prompt.ts
|
|
2
|
+
function buildWorkflowDraftPrompt(params) {
|
|
3
|
+
return `You generate xopc workflow drafts. Return ONLY a JSON object, no markdown.
|
|
4
|
+
|
|
5
|
+
JSON shape:
|
|
6
|
+
{
|
|
7
|
+
"name": "lowercase_snake_case",
|
|
8
|
+
"script": "workflow JavaScript DSL",
|
|
9
|
+
"manifest": {
|
|
10
|
+
"title": "Human title",
|
|
11
|
+
"description": "What it does",
|
|
12
|
+
"version": "1.0.0",
|
|
13
|
+
"inputSchema": { "type": "object", "properties": {}, "required": [] },
|
|
14
|
+
"outputSchema": { "type": "object", "properties": { "summary": { "type": "string" } }, "required": ["summary"] },
|
|
15
|
+
"defaults": { "concurrency": 2, "timeoutSec": 1800, "maxSubagents": 8 },
|
|
16
|
+
"permissions": { "network": false, "fileSystem": "read", "approvalRequired": false },
|
|
17
|
+
"tags": ["custom"],
|
|
18
|
+
"whenToUse": "When to use this workflow"
|
|
19
|
+
},
|
|
20
|
+
"explanation": "Short explanation",
|
|
21
|
+
"assumptions": ["..."],
|
|
22
|
+
"risks": ["..."]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
DSL rules:
|
|
26
|
+
- script MUST start with: export const meta = { name, description, phases, tags, estimatedAgents }
|
|
27
|
+
- The top-level JSON "name" MUST exactly equal script meta.name.
|
|
28
|
+
- Use only these globals: phase(title), agent(prompt, opts), parallel([() => agent(...)]), pipeline(items, ...stages), log(message), budget, args.
|
|
29
|
+
- Read user inputs from args, e.g. args.goal, args.branch, args.audience.
|
|
30
|
+
- Each agent needs a clear label.
|
|
31
|
+
- Keep concurrency conservative; prefer 2-4.
|
|
32
|
+
- Return a WorkflowResultEnvelope-like object: { summary, sections, followUps?, structuredOutput? }.
|
|
33
|
+
- Do not use import, require, eval, Function, process.env, fs, http, fetch.
|
|
34
|
+
- If network/write/destructive behavior is requested, mark manifest.permissions.approvalRequired = true.
|
|
35
|
+
- Keep script self-contained and valid JavaScript.
|
|
36
|
+
|
|
37
|
+
Mode: ${params.mode}
|
|
38
|
+
Language for user-facing copy: ${params.language ?? "en"}
|
|
39
|
+
Constraints:
|
|
40
|
+
${JSON.stringify(params.constraints ?? {}, null, 2)}
|
|
41
|
+
|
|
42
|
+
${params.existingScript ? `Existing script to improve:\n${params.existingScript.slice(0, 12e3)}\n` : ""}
|
|
43
|
+
|
|
44
|
+
User request:
|
|
45
|
+
${params.prompt.slice(0, 8e3)}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
function buildWorkflowDraftRepairPrompt(params) {
|
|
49
|
+
return `You must repair an xopc workflow draft so it passes validation. Return ONLY a corrected JSON object, no markdown.
|
|
50
|
+
|
|
51
|
+
Required JSON shape is unchanged:
|
|
52
|
+
{
|
|
53
|
+
"name": "lowercase_snake_case",
|
|
54
|
+
"script": "workflow JavaScript DSL",
|
|
55
|
+
"manifest": {
|
|
56
|
+
"title": "Human title",
|
|
57
|
+
"description": "What it does",
|
|
58
|
+
"version": "1.0.0",
|
|
59
|
+
"inputSchema": { "type": "object", "properties": {}, "required": [] },
|
|
60
|
+
"outputSchema": { "type": "object", "properties": { "summary": { "type": "string" } }, "required": ["summary"] },
|
|
61
|
+
"defaults": { "concurrency": 2, "timeoutSec": 1800, "maxSubagents": 8 },
|
|
62
|
+
"permissions": { "network": false, "fileSystem": "read", "approvalRequired": false },
|
|
63
|
+
"tags": ["custom"],
|
|
64
|
+
"whenToUse": "When to use this workflow"
|
|
65
|
+
},
|
|
66
|
+
"explanation": "Short explanation",
|
|
67
|
+
"assumptions": ["..."],
|
|
68
|
+
"risks": ["..."]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
Hard requirements:
|
|
72
|
+
- The output MUST be valid JSON.
|
|
73
|
+
- JSON name MUST be lowercase snake_case and MUST exactly equal script meta.name.
|
|
74
|
+
- script MUST be valid JavaScript for the xopc workflow DSL.
|
|
75
|
+
- script MUST start with export const meta = { ... } and include phases, tags, estimatedAgents.
|
|
76
|
+
- Use only these globals: phase(title), agent(prompt, opts), parallel([() => agent(...)]), pipeline(items, ...stages), log(message), budget, args.
|
|
77
|
+
- Do not use import, require, eval, Function, process.env, fs, http, fetch.
|
|
78
|
+
- Respect the constraints exactly. If network is disabled, manifest.permissions.network must be false.
|
|
79
|
+
- Preserve the user's intent while making the smallest change needed to pass validation.
|
|
80
|
+
|
|
81
|
+
Language for user-facing copy: ${params.language ?? "en"}
|
|
82
|
+
Constraints:
|
|
83
|
+
${JSON.stringify(params.constraints ?? {}, null, 2)}
|
|
84
|
+
|
|
85
|
+
Validation and lint issues to fix:
|
|
86
|
+
${JSON.stringify(params.issues, null, 2)}
|
|
87
|
+
|
|
88
|
+
Original user request:
|
|
89
|
+
${params.prompt.slice(0, 8e3)}
|
|
90
|
+
|
|
91
|
+
Previous model output:
|
|
92
|
+
${params.previousOutput.slice(0, 12e3)}
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { buildWorkflowDraftPrompt, buildWorkflowDraftRepairPrompt };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=workflow-draft-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-draft-prompt.js","names":[],"sources":["../../../../src/workflows/draft/workflow-draft-prompt.ts"],"sourcesContent":["import type { WorkflowDraftConstraints, WorkflowDraftMode } from './workflow-draft.types.js';\n\nexport interface WorkflowDraftRepairIssue {\n source: 'parse' | 'validation' | 'lint';\n severity: 'error' | 'warning';\n code: string;\n message: string;\n line?: number;\n column?: number;\n}\n\nexport function buildWorkflowDraftPrompt(params: {\n prompt: string;\n language?: 'en' | 'zh';\n mode: WorkflowDraftMode;\n existingScript?: string;\n constraints?: WorkflowDraftConstraints;\n}): string {\n return `You generate xopc workflow drafts. Return ONLY a JSON object, no markdown.\n\nJSON shape:\n{\n \"name\": \"lowercase_snake_case\",\n \"script\": \"workflow JavaScript DSL\",\n \"manifest\": {\n \"title\": \"Human title\",\n \"description\": \"What it does\",\n \"version\": \"1.0.0\",\n \"inputSchema\": { \"type\": \"object\", \"properties\": {}, \"required\": [] },\n \"outputSchema\": { \"type\": \"object\", \"properties\": { \"summary\": { \"type\": \"string\" } }, \"required\": [\"summary\"] },\n \"defaults\": { \"concurrency\": 2, \"timeoutSec\": 1800, \"maxSubagents\": 8 },\n \"permissions\": { \"network\": false, \"fileSystem\": \"read\", \"approvalRequired\": false },\n \"tags\": [\"custom\"],\n \"whenToUse\": \"When to use this workflow\"\n },\n \"explanation\": \"Short explanation\",\n \"assumptions\": [\"...\"],\n \"risks\": [\"...\"]\n}\n\nDSL rules:\n- script MUST start with: export const meta = { name, description, phases, tags, estimatedAgents }\n- The top-level JSON \"name\" MUST exactly equal script meta.name.\n- Use only these globals: phase(title), agent(prompt, opts), parallel([() => agent(...)]), pipeline(items, ...stages), log(message), budget, args.\n- Read user inputs from args, e.g. args.goal, args.branch, args.audience.\n- Each agent needs a clear label.\n- Keep concurrency conservative; prefer 2-4.\n- Return a WorkflowResultEnvelope-like object: { summary, sections, followUps?, structuredOutput? }.\n- Do not use import, require, eval, Function, process.env, fs, http, fetch.\n- If network/write/destructive behavior is requested, mark manifest.permissions.approvalRequired = true.\n- Keep script self-contained and valid JavaScript.\n\nMode: ${params.mode}\nLanguage for user-facing copy: ${params.language ?? 'en'}\nConstraints:\n${JSON.stringify(params.constraints ?? {}, null, 2)}\n\n${params.existingScript ? `Existing script to improve:\\n${params.existingScript.slice(0, 12000)}\\n` : ''}\n\nUser request:\n${params.prompt.slice(0, 8000)}\n`;\n}\n\nexport function buildWorkflowDraftRepairPrompt(params: {\n prompt: string;\n language?: 'en' | 'zh';\n constraints?: WorkflowDraftConstraints;\n previousOutput: string;\n issues: WorkflowDraftRepairIssue[];\n}): string {\n return `You must repair an xopc workflow draft so it passes validation. Return ONLY a corrected JSON object, no markdown.\n\nRequired JSON shape is unchanged:\n{\n \"name\": \"lowercase_snake_case\",\n \"script\": \"workflow JavaScript DSL\",\n \"manifest\": {\n \"title\": \"Human title\",\n \"description\": \"What it does\",\n \"version\": \"1.0.0\",\n \"inputSchema\": { \"type\": \"object\", \"properties\": {}, \"required\": [] },\n \"outputSchema\": { \"type\": \"object\", \"properties\": { \"summary\": { \"type\": \"string\" } }, \"required\": [\"summary\"] },\n \"defaults\": { \"concurrency\": 2, \"timeoutSec\": 1800, \"maxSubagents\": 8 },\n \"permissions\": { \"network\": false, \"fileSystem\": \"read\", \"approvalRequired\": false },\n \"tags\": [\"custom\"],\n \"whenToUse\": \"When to use this workflow\"\n },\n \"explanation\": \"Short explanation\",\n \"assumptions\": [\"...\"],\n \"risks\": [\"...\"]\n}\n\nHard requirements:\n- The output MUST be valid JSON.\n- JSON name MUST be lowercase snake_case and MUST exactly equal script meta.name.\n- script MUST be valid JavaScript for the xopc workflow DSL.\n- script MUST start with export const meta = { ... } and include phases, tags, estimatedAgents.\n- Use only these globals: phase(title), agent(prompt, opts), parallel([() => agent(...)]), pipeline(items, ...stages), log(message), budget, args.\n- Do not use import, require, eval, Function, process.env, fs, http, fetch.\n- Respect the constraints exactly. If network is disabled, manifest.permissions.network must be false.\n- Preserve the user's intent while making the smallest change needed to pass validation.\n\nLanguage for user-facing copy: ${params.language ?? 'en'}\nConstraints:\n${JSON.stringify(params.constraints ?? {}, null, 2)}\n\nValidation and lint issues to fix:\n${JSON.stringify(params.issues, null, 2)}\n\nOriginal user request:\n${params.prompt.slice(0, 8000)}\n\nPrevious model output:\n${params.previousOutput.slice(0, 12000)}\n`;\n}\n"],"mappings":";AAWA,SAAgB,yBAAyB,QAM9B;AACT,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkCD,OAAO,KAAK;iCACa,OAAO,YAAY,KAAK;;EAEvD,KAAK,UAAU,OAAO,eAAe,EAAE,EAAE,MAAM,EAAE,CAAC;;EAElD,OAAO,iBAAiB,gCAAgC,OAAO,eAAe,MAAM,GAAG,KAAM,CAAC,MAAM,GAAG;;;EAGvG,OAAO,OAAO,MAAM,GAAG,IAAK,CAAC;;;AAI/B,SAAgB,+BAA+B,QAMpC;AACT,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAgCwB,OAAO,YAAY,KAAK;;EAEvD,KAAK,UAAU,OAAO,eAAe,EAAE,EAAE,MAAM,EAAE,CAAC;;;EAGlD,KAAK,UAAU,OAAO,QAAQ,MAAM,EAAE,CAAC;;;EAGvC,OAAO,OAAO,MAAM,GAAG,IAAK,CAAC;;;EAG7B,OAAO,eAAe,MAAM,GAAG,KAAM,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Config } from '../../config/schema.js';
|
|
2
|
+
import type { CreateWorkflowDraftRequest, WorkflowDraftResponse } from './workflow-draft.types.js';
|
|
3
|
+
export interface WorkflowDraftServiceOptions {
|
|
4
|
+
config: Config;
|
|
5
|
+
maxRepairAttempts?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class WorkflowDraftService {
|
|
8
|
+
private readonly options;
|
|
9
|
+
constructor(options: WorkflowDraftServiceOptions);
|
|
10
|
+
createDraft(request: CreateWorkflowDraftRequest, signal?: AbortSignal): Promise<WorkflowDraftResponse>;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveDraftModelRef(config: Config, agentId: string): string;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
2
|
+
import { createLogger } from "../../utils/logger/index.js";
|
|
3
|
+
import { init_logger } from "../../utils/logger.js";
|
|
4
|
+
import { getDefaultModelSync, init_providers, resolveModel } from "../../providers/index.js";
|
|
5
|
+
import { resolveModelRef } from "../../config/agent-typed-models.js";
|
|
6
|
+
import { buildWorkflowDraftPrompt, buildWorkflowDraftRepairPrompt } from "./workflow-draft-prompt.js";
|
|
7
|
+
import { buildWorkflowDraftResponse, parseGeneratedWorkflowDraft } from "./workflow-draft-validator.js";
|
|
8
|
+
import { complete } from "@earendil-works/pi-ai";
|
|
9
|
+
//#region src/workflows/draft/workflow-draft-service.ts
|
|
10
|
+
init_schema();
|
|
11
|
+
init_providers();
|
|
12
|
+
init_logger();
|
|
13
|
+
const log = createLogger("WorkflowDraft");
|
|
14
|
+
const DEFAULT_MAX_REPAIR_ATTEMPTS = 2;
|
|
15
|
+
var WorkflowDraftService = class {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
async createDraft(request, signal) {
|
|
20
|
+
const prompt = request.prompt.trim();
|
|
21
|
+
if (!prompt) throw new Error("prompt is required");
|
|
22
|
+
const modelRef = resolveDraftModelRef(this.options.config, request.agentId);
|
|
23
|
+
const model = resolveModel(modelRef);
|
|
24
|
+
const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;
|
|
25
|
+
let messageContent = buildWorkflowDraftPrompt({
|
|
26
|
+
prompt,
|
|
27
|
+
language: request.language,
|
|
28
|
+
mode: request.mode ?? (request.existingScript ? "improve" : "create"),
|
|
29
|
+
existingScript: request.existingScript,
|
|
30
|
+
constraints: request.constraints
|
|
31
|
+
});
|
|
32
|
+
let lastIssues = [];
|
|
33
|
+
let lastText = "";
|
|
34
|
+
for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {
|
|
35
|
+
lastText = extractText(await complete(model, { messages: [{
|
|
36
|
+
role: "user",
|
|
37
|
+
content: messageContent,
|
|
38
|
+
timestamp: Date.now()
|
|
39
|
+
}] }, {
|
|
40
|
+
maxTokens: 4096,
|
|
41
|
+
temperature: attempt === 0 ? .25 : .1,
|
|
42
|
+
signal
|
|
43
|
+
}));
|
|
44
|
+
try {
|
|
45
|
+
const response = buildWorkflowDraftResponse(parseGeneratedWorkflowDraft(lastText), request.constraints);
|
|
46
|
+
const blockingIssues = getBlockingDraftIssues(response);
|
|
47
|
+
if (blockingIssues.length === 0) return {
|
|
48
|
+
...response,
|
|
49
|
+
repairAttempts: attempt
|
|
50
|
+
};
|
|
51
|
+
lastIssues = blockingIssues;
|
|
52
|
+
} catch (err) {
|
|
53
|
+
lastIssues = [{
|
|
54
|
+
source: "parse",
|
|
55
|
+
severity: "error",
|
|
56
|
+
code: "invalid_model_output",
|
|
57
|
+
message: err instanceof Error ? err.message : String(err)
|
|
58
|
+
}];
|
|
59
|
+
}
|
|
60
|
+
if (attempt >= maxRepairAttempts) break;
|
|
61
|
+
log.warn({
|
|
62
|
+
modelRef,
|
|
63
|
+
attempt: attempt + 1,
|
|
64
|
+
issueCount: lastIssues.length,
|
|
65
|
+
preview: lastText.slice(0, 500)
|
|
66
|
+
}, "Workflow draft validation failed; asking model to repair");
|
|
67
|
+
messageContent = buildWorkflowDraftRepairPrompt({
|
|
68
|
+
prompt,
|
|
69
|
+
language: request.language,
|
|
70
|
+
constraints: request.constraints,
|
|
71
|
+
previousOutput: lastText,
|
|
72
|
+
issues: lastIssues
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const message = `Unable to generate a valid workflow draft after ${maxRepairAttempts + 1} attempts: ${formatRepairIssues(lastIssues)}`;
|
|
76
|
+
log.warn({
|
|
77
|
+
modelRef,
|
|
78
|
+
issues: lastIssues,
|
|
79
|
+
preview: lastText.slice(0, 500)
|
|
80
|
+
}, message);
|
|
81
|
+
throw new Error(message);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
function resolveDraftModelRef(config, agentId) {
|
|
85
|
+
try {
|
|
86
|
+
return resolveModelRef(config, agentId, "large");
|
|
87
|
+
} catch {
|
|
88
|
+
return getAgentDefaultModelRef(config) ?? getDefaultModelSync(config);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function extractText(result) {
|
|
92
|
+
const content = result.content;
|
|
93
|
+
if (typeof content === "string") return content;
|
|
94
|
+
if (Array.isArray(content)) return content.map((item) => {
|
|
95
|
+
if (item && typeof item === "object" && item.type === "text") return String(item.text ?? "");
|
|
96
|
+
return "";
|
|
97
|
+
}).join("");
|
|
98
|
+
return "";
|
|
99
|
+
}
|
|
100
|
+
function getBlockingDraftIssues(response) {
|
|
101
|
+
const validationIssues = [...response.validation.errors.map((issue) => ({
|
|
102
|
+
source: "validation",
|
|
103
|
+
severity: "error",
|
|
104
|
+
code: issue.code,
|
|
105
|
+
message: issue.message,
|
|
106
|
+
line: issue.line,
|
|
107
|
+
column: issue.column
|
|
108
|
+
})), ...response.validation.warnings.map((issue) => ({
|
|
109
|
+
source: "validation",
|
|
110
|
+
severity: "warning",
|
|
111
|
+
code: issue.code,
|
|
112
|
+
message: issue.message,
|
|
113
|
+
line: issue.line,
|
|
114
|
+
column: issue.column
|
|
115
|
+
}))];
|
|
116
|
+
const lintIssues = response.lint.filter((issue) => issue.severity === "error").map((issue) => ({
|
|
117
|
+
source: "lint",
|
|
118
|
+
severity: issue.severity,
|
|
119
|
+
code: issue.code,
|
|
120
|
+
message: issue.message
|
|
121
|
+
}));
|
|
122
|
+
return [...validationIssues, ...lintIssues];
|
|
123
|
+
}
|
|
124
|
+
function formatRepairIssues(issues) {
|
|
125
|
+
if (issues.length === 0) return "unknown validation failure";
|
|
126
|
+
return issues.slice(0, 5).map((issue) => `${issue.source}:${issue.code}: ${issue.message}`).join("; ");
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
export { WorkflowDraftService, resolveDraftModelRef };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=workflow-draft-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-draft-service.js","names":[],"sources":["../../../../src/workflows/draft/workflow-draft-service.ts"],"sourcesContent":["import { complete, type UserMessage } from '@earendil-works/pi-ai';\n\nimport { resolveModelRef } from '../../config/agent-typed-models.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport type { Config } from '../../config/schema.js';\nimport { getDefaultModelSync, resolveModel } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\n\nimport {\n buildWorkflowDraftPrompt,\n buildWorkflowDraftRepairPrompt,\n type WorkflowDraftRepairIssue,\n} from './workflow-draft-prompt.js';\nimport type { CreateWorkflowDraftRequest, WorkflowDraftResponse } from './workflow-draft.types.js';\nimport { buildWorkflowDraftResponse, parseGeneratedWorkflowDraft } from './workflow-draft-validator.js';\n\nconst log = createLogger('WorkflowDraft');\nconst DEFAULT_MAX_REPAIR_ATTEMPTS = 2;\n\nexport interface WorkflowDraftServiceOptions {\n config: Config;\n maxRepairAttempts?: number;\n}\n\nexport class WorkflowDraftService {\n constructor(private readonly options: WorkflowDraftServiceOptions) {}\n\n async createDraft(request: CreateWorkflowDraftRequest, signal?: AbortSignal): Promise<WorkflowDraftResponse> {\n const prompt = request.prompt.trim();\n if (!prompt) throw new Error('prompt is required');\n const modelRef = resolveDraftModelRef(this.options.config, request.agentId);\n const model = resolveModel(modelRef);\n const maxRepairAttempts = this.options.maxRepairAttempts ?? DEFAULT_MAX_REPAIR_ATTEMPTS;\n let messageContent = buildWorkflowDraftPrompt({\n prompt,\n language: request.language,\n mode: request.mode ?? (request.existingScript ? 'improve' : 'create'),\n existingScript: request.existingScript,\n constraints: request.constraints,\n });\n let lastIssues: WorkflowDraftRepairIssue[] = [];\n let lastText = '';\n\n for (let attempt = 0; attempt <= maxRepairAttempts; attempt += 1) {\n const userMsg: UserMessage = {\n role: 'user',\n content: messageContent,\n timestamp: Date.now(),\n };\n const result = await complete(\n model,\n { messages: [userMsg] },\n { maxTokens: 4096, temperature: attempt === 0 ? 0.25 : 0.1, signal: signal as AbortSignal },\n );\n lastText = extractText(result);\n try {\n const draft = parseGeneratedWorkflowDraft(lastText);\n const response = buildWorkflowDraftResponse(draft, request.constraints);\n const blockingIssues = getBlockingDraftIssues(response);\n if (blockingIssues.length === 0) {\n return { ...response, repairAttempts: attempt };\n }\n lastIssues = blockingIssues;\n } catch (err) {\n lastIssues = [{\n source: 'parse',\n severity: 'error',\n code: 'invalid_model_output',\n message: err instanceof Error ? err.message : String(err),\n }];\n }\n\n if (attempt >= maxRepairAttempts) break;\n log.warn(\n { modelRef, attempt: attempt + 1, issueCount: lastIssues.length, preview: lastText.slice(0, 500) },\n 'Workflow draft validation failed; asking model to repair',\n );\n messageContent = buildWorkflowDraftRepairPrompt({\n prompt,\n language: request.language,\n constraints: request.constraints,\n previousOutput: lastText,\n issues: lastIssues,\n });\n }\n\n const message = `Unable to generate a valid workflow draft after ${maxRepairAttempts + 1} attempts: ${formatRepairIssues(lastIssues)}`;\n log.warn({ modelRef, issues: lastIssues, preview: lastText.slice(0, 500) }, message);\n throw new Error(message);\n }\n}\n\nexport function resolveDraftModelRef(config: Config, agentId: string): string {\n try {\n return resolveModelRef(config, agentId, 'large');\n } catch {\n return getAgentDefaultModelRef(config) ?? getDefaultModelSync(config);\n }\n}\n\nfunction extractText(result: unknown): string {\n const content = (result as { content?: unknown }).content;\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content.map((item) => {\n if (item && typeof item === 'object' && (item as { type?: string }).type === 'text') {\n return String((item as { text?: string }).text ?? '');\n }\n return '';\n }).join('');\n }\n return '';\n}\n\nfunction getBlockingDraftIssues(response: WorkflowDraftResponse): WorkflowDraftRepairIssue[] {\n const validationIssues: WorkflowDraftRepairIssue[] = [\n ...response.validation.errors.map((issue) => ({\n source: 'validation' as const,\n severity: 'error' as const,\n code: issue.code,\n message: issue.message,\n line: issue.line,\n column: issue.column,\n })),\n ...response.validation.warnings.map((issue) => ({\n source: 'validation' as const,\n severity: 'warning' as const,\n code: issue.code,\n message: issue.message,\n line: issue.line,\n column: issue.column,\n })),\n ];\n const lintIssues = response.lint\n .filter((issue) => issue.severity === 'error')\n .map((issue) => ({\n source: 'lint' as const,\n severity: issue.severity,\n code: issue.code,\n message: issue.message,\n }));\n return [...validationIssues, ...lintIssues];\n}\n\nfunction formatRepairIssues(issues: WorkflowDraftRepairIssue[]): string {\n if (issues.length === 0) return 'unknown validation failure';\n return issues.slice(0, 5).map((issue) => `${issue.source}:${issue.code}: ${issue.message}`).join('; ');\n}\n"],"mappings":";;;;;;;;;aAGiE;gBAEY;aACxB;AAUrD,MAAM,MAAM,aAAa,gBAAgB;AACzC,MAAM,8BAA8B;AAOpC,IAAa,uBAAb,MAAkC;CAChC,YAAY,SAAuD;AAAtC,OAAA,UAAA;;CAE7B,MAAM,YAAY,SAAqC,QAAsD;EAC3G,MAAM,SAAS,QAAQ,OAAO,MAAM;AACpC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,qBAAqB;EAClD,MAAM,WAAW,qBAAqB,KAAK,QAAQ,QAAQ,QAAQ,QAAQ;EAC3E,MAAM,QAAQ,aAAa,SAAS;EACpC,MAAM,oBAAoB,KAAK,QAAQ,qBAAqB;EAC5D,IAAI,iBAAiB,yBAAyB;GAC5C;GACA,UAAU,QAAQ;GAClB,MAAM,QAAQ,SAAS,QAAQ,iBAAiB,YAAY;GAC5D,gBAAgB,QAAQ;GACxB,aAAa,QAAQ;GACtB,CAAC;EACF,IAAI,aAAyC,EAAE;EAC/C,IAAI,WAAW;AAEf,OAAK,IAAI,UAAU,GAAG,WAAW,mBAAmB,WAAW,GAAG;AAWhE,cAAW,YAAY,MALF,SACnB,OACA,EAAE,UAAU,CAAC;IANb,MAAM;IACN,SAAS;IACT,WAAW,KAAK,KAAK;IAID,CAAC,EAAE,EACvB;IAAE,WAAW;IAAM,aAAa,YAAY,IAAI,MAAO;IAAa;IAAuB,CAC5F,CAC6B;AAC9B,OAAI;IAEF,MAAM,WAAW,2BADH,4BAA4B,SACO,EAAE,QAAQ,YAAY;IACvE,MAAM,iBAAiB,uBAAuB,SAAS;AACvD,QAAI,eAAe,WAAW,EAC5B,QAAO;KAAE,GAAG;KAAU,gBAAgB;KAAS;AAEjD,iBAAa;YACN,KAAK;AACZ,iBAAa,CAAC;KACZ,QAAQ;KACR,UAAU;KACV,MAAM;KACN,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;KAC1D,CAAC;;AAGJ,OAAI,WAAW,kBAAmB;AAClC,OAAI,KACF;IAAE;IAAU,SAAS,UAAU;IAAG,YAAY,WAAW;IAAQ,SAAS,SAAS,MAAM,GAAG,IAAI;IAAE,EAClG,2DACD;AACD,oBAAiB,+BAA+B;IAC9C;IACA,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACrB,gBAAgB;IAChB,QAAQ;IACT,CAAC;;EAGJ,MAAM,UAAU,mDAAmD,oBAAoB,EAAE,aAAa,mBAAmB,WAAW;AACpI,MAAI,KAAK;GAAE;GAAU,QAAQ;GAAY,SAAS,SAAS,MAAM,GAAG,IAAI;GAAE,EAAE,QAAQ;AACpF,QAAM,IAAI,MAAM,QAAQ;;;AAI5B,SAAgB,qBAAqB,QAAgB,SAAyB;AAC5E,KAAI;AACF,SAAO,gBAAgB,QAAQ,SAAS,QAAQ;SAC1C;AACN,SAAO,wBAAwB,OAAO,IAAI,oBAAoB,OAAO;;;AAIzE,SAAS,YAAY,QAAyB;CAC5C,MAAM,UAAW,OAAiC;AAClD,KAAI,OAAO,YAAY,SAAU,QAAO;AACxC,KAAI,MAAM,QAAQ,QAAQ,CACxB,QAAO,QAAQ,KAAK,SAAS;AAC3B,MAAI,QAAQ,OAAO,SAAS,YAAa,KAA2B,SAAS,OAC3E,QAAO,OAAQ,KAA2B,QAAQ,GAAG;AAEvD,SAAO;GACP,CAAC,KAAK,GAAG;AAEb,QAAO;;AAGT,SAAS,uBAAuB,UAA6D;CAC3F,MAAM,mBAA+C,CACnD,GAAG,SAAS,WAAW,OAAO,KAAK,WAAW;EAC5C,QAAQ;EACR,UAAU;EACV,MAAM,MAAM;EACZ,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,QAAQ,MAAM;EACf,EAAE,EACH,GAAG,SAAS,WAAW,SAAS,KAAK,WAAW;EAC9C,QAAQ;EACR,UAAU;EACV,MAAM,MAAM;EACZ,SAAS,MAAM;EACf,MAAM,MAAM;EACZ,QAAQ,MAAM;EACf,EAAE,CACJ;CACD,MAAM,aAAa,SAAS,KACzB,QAAQ,UAAU,MAAM,aAAa,QAAQ,CAC7C,KAAK,WAAW;EACf,QAAQ;EACR,UAAU,MAAM;EAChB,MAAM,MAAM;EACZ,SAAS,MAAM;EAChB,EAAE;AACL,QAAO,CAAC,GAAG,kBAAkB,GAAG,WAAW;;AAG7C,SAAS,mBAAmB,QAA4C;AACtE,KAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAO,OAAO,MAAM,GAAG,EAAE,CAAC,KAAK,UAAU,GAAG,MAAM,OAAO,GAAG,MAAM,KAAK,IAAI,MAAM,UAAU,CAAC,KAAK,KAAK"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GeneratedWorkflowDraft, WorkflowDraftConstraints, WorkflowDraftLintIssue, WorkflowDraftResponse } from './workflow-draft.types.js';
|
|
2
|
+
export declare function parseGeneratedWorkflowDraft(raw: string): GeneratedWorkflowDraft;
|
|
3
|
+
export declare function buildWorkflowDraftResponse(draft: GeneratedWorkflowDraft, constraints?: WorkflowDraftConstraints): WorkflowDraftResponse;
|
|
4
|
+
export declare function lintWorkflowDraft(draft: GeneratedWorkflowDraft, constraints?: WorkflowDraftConstraints): WorkflowDraftLintIssue[];
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { validateWorkflowDefinitionInput } from "../domain/validation.js";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/workflows/draft/workflow-draft-validator.ts
|
|
4
|
+
function parseGeneratedWorkflowDraft(raw) {
|
|
5
|
+
const json = extractJsonObject(raw);
|
|
6
|
+
const parsed = JSON.parse(json);
|
|
7
|
+
return {
|
|
8
|
+
name: normalizeWorkflowName(String(parsed.name ?? "custom_workflow")),
|
|
9
|
+
script: String(parsed.script ?? "").trim(),
|
|
10
|
+
manifest: normalizeManifest(parsed.manifest),
|
|
11
|
+
explanation: String(parsed.explanation ?? ""),
|
|
12
|
+
assumptions: stringArray(parsed.assumptions),
|
|
13
|
+
risks: stringArray(parsed.risks)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function buildWorkflowDraftResponse(draft, constraints) {
|
|
17
|
+
const validation = validateWorkflowDefinitionInput({
|
|
18
|
+
name: draft.name,
|
|
19
|
+
script: draft.script
|
|
20
|
+
});
|
|
21
|
+
const lint = lintWorkflowDraft(draft, constraints);
|
|
22
|
+
return {
|
|
23
|
+
draftId: randomUUID(),
|
|
24
|
+
repairAttempts: 0,
|
|
25
|
+
...draft,
|
|
26
|
+
permissionsSummary: summarizePermissions(draft.manifest),
|
|
27
|
+
validation,
|
|
28
|
+
lint,
|
|
29
|
+
suggestedInputs: suggestedInputsFromManifest(draft.manifest)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function lintWorkflowDraft(draft, constraints) {
|
|
33
|
+
const issues = [];
|
|
34
|
+
const { manifest, script } = draft;
|
|
35
|
+
if (!manifest.inputSchema) issues.push({
|
|
36
|
+
severity: "warning",
|
|
37
|
+
code: "missing_input_schema",
|
|
38
|
+
message: "Draft does not define an input schema."
|
|
39
|
+
});
|
|
40
|
+
if (!manifest.outputSchema) issues.push({
|
|
41
|
+
severity: "warning",
|
|
42
|
+
code: "missing_output_schema",
|
|
43
|
+
message: "Draft does not define an output schema."
|
|
44
|
+
});
|
|
45
|
+
if (manifest.permissions?.network && constraints?.allowNetwork === false) issues.push({
|
|
46
|
+
severity: "error",
|
|
47
|
+
code: "unsafe_permission",
|
|
48
|
+
message: "Draft requests network access, but network is disabled by constraints."
|
|
49
|
+
});
|
|
50
|
+
if (manifest.permissions?.fileSystem === "write" && constraints?.fileSystem !== "write") issues.push({
|
|
51
|
+
severity: "warning",
|
|
52
|
+
code: "unsafe_permission",
|
|
53
|
+
message: "Draft requests filesystem write access."
|
|
54
|
+
});
|
|
55
|
+
const phaseCount = (script.match(/\bphase\s*\(/g) ?? []).length;
|
|
56
|
+
if (constraints?.maxPhases && phaseCount > constraints.maxPhases) issues.push({
|
|
57
|
+
severity: "warning",
|
|
58
|
+
code: "too_many_agents",
|
|
59
|
+
message: `Draft has ${phaseCount} phases, above requested ${constraints.maxPhases}.`
|
|
60
|
+
});
|
|
61
|
+
const agentCount = (script.match(/\bagent\s*\(/g) ?? []).length;
|
|
62
|
+
if (constraints?.maxSubagents && agentCount > constraints.maxSubagents) issues.push({
|
|
63
|
+
severity: "warning",
|
|
64
|
+
code: "too_many_agents",
|
|
65
|
+
message: `Draft starts ${agentCount} agents, above requested ${constraints.maxSubagents}.`
|
|
66
|
+
});
|
|
67
|
+
if (/parallel\s*\([^[]/.test(script)) issues.push({
|
|
68
|
+
severity: "warning",
|
|
69
|
+
code: "unbounded_parallelism",
|
|
70
|
+
message: "parallel() should receive a bounded array of thunks."
|
|
71
|
+
});
|
|
72
|
+
if (constraints?.allowedTools?.length) {
|
|
73
|
+
const unknown = collectToolsetNames(script).filter((tool) => !constraints.allowedTools.includes(tool));
|
|
74
|
+
for (const tool of [...new Set(unknown)]) issues.push({
|
|
75
|
+
severity: "warning",
|
|
76
|
+
code: "unknown_tool",
|
|
77
|
+
message: `Tool '${tool}' is outside the requested allowlist.`
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return issues;
|
|
81
|
+
}
|
|
82
|
+
function extractJsonObject(raw) {
|
|
83
|
+
const trimmed = raw.trim();
|
|
84
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) return trimmed;
|
|
85
|
+
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
|
|
86
|
+
if (fenced?.startsWith("{")) return fenced;
|
|
87
|
+
const start = trimmed.indexOf("{");
|
|
88
|
+
const end = trimmed.lastIndexOf("}");
|
|
89
|
+
if (start >= 0 && end > start) return trimmed.slice(start, end + 1);
|
|
90
|
+
throw new Error("Model did not return a JSON object.");
|
|
91
|
+
}
|
|
92
|
+
function normalizeManifest(value) {
|
|
93
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
function stringArray(value) {
|
|
97
|
+
return Array.isArray(value) ? value.map((item) => String(item)).filter(Boolean) : [];
|
|
98
|
+
}
|
|
99
|
+
function normalizeWorkflowName(value) {
|
|
100
|
+
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
101
|
+
return /^[a-z]/.test(normalized) ? normalized : `workflow_${normalized || "draft"}`;
|
|
102
|
+
}
|
|
103
|
+
function summarizePermissions(manifest) {
|
|
104
|
+
const permissions = manifest.permissions;
|
|
105
|
+
if (!permissions) return ["No explicit permissions requested."];
|
|
106
|
+
const out = [];
|
|
107
|
+
if (permissions.tools?.length) out.push(`Tools: ${permissions.tools.join(", ")}`);
|
|
108
|
+
if (permissions.network != null) out.push(`Network: ${permissions.network ? "enabled" : "disabled"}`);
|
|
109
|
+
if (permissions.fileSystem) out.push(`Filesystem: ${permissions.fileSystem}`);
|
|
110
|
+
if (permissions.approvalRequired) out.push("Approval required");
|
|
111
|
+
return out.length > 0 ? out : ["No explicit permissions requested."];
|
|
112
|
+
}
|
|
113
|
+
function suggestedInputsFromManifest(manifest) {
|
|
114
|
+
const properties = manifest.inputSchema?.properties;
|
|
115
|
+
if (!properties) return void 0;
|
|
116
|
+
return Object.entries(properties).slice(0, 8).map(([key, schema]) => ({
|
|
117
|
+
key,
|
|
118
|
+
label: typeof schema.title === "string" ? schema.title : key,
|
|
119
|
+
example: typeof schema.default === "string" ? schema.default : schema.description ?? ""
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
function collectToolsetNames(script) {
|
|
123
|
+
const out = [];
|
|
124
|
+
for (const match of script.matchAll(/toolset\s*:\s*\[([^\]]*)\]/g)) {
|
|
125
|
+
const body = match[1] ?? "";
|
|
126
|
+
for (const item of body.matchAll(/['"]([^'"]+)['"]/g)) out.push(item[1] ?? "");
|
|
127
|
+
}
|
|
128
|
+
return out.filter(Boolean);
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { buildWorkflowDraftResponse, lintWorkflowDraft, parseGeneratedWorkflowDraft };
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=workflow-draft-validator.js.map
|
|
@@ -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":"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"}
|
|
@@ -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
|
}
|