@hotmeshio/long-tail 0.1.5 → 0.1.6
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/README.md +34 -4
- package/build/lib/db/migrate.js +3 -6
- package/{lib → build/lib}/db/schemas/001_schema.sql +3 -0
- package/{lib → build/lib}/db/schemas/011_system_workflow_configs.sql +7 -0
- package/build/lib/db/schemas/016_streamable_http.sql +7 -0
- package/build/routes/docs.js +25 -7
- package/build/routes/insight.js +63 -0
- package/build/routes/mcp.js +23 -1
- package/build/routes/yaml-workflows/cron.d.ts +2 -0
- package/build/routes/yaml-workflows/cron.js +117 -0
- package/build/routes/yaml-workflows/crud.js +38 -0
- package/build/routes/yaml-workflows/deployment.js +9 -34
- package/build/routes/yaml-workflows/index.js +4 -1
- package/build/services/cron/index.d.ts +17 -0
- package/build/services/cron/index.js +94 -1
- package/build/services/insight/index.d.ts +11 -0
- package/build/services/insight/index.js +30 -0
- package/build/services/mcp/client/connection.d.ts +9 -0
- package/build/services/mcp/client/connection.js +49 -1
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/services/mcp/db.d.ts +1 -1
- package/build/services/mcp/db.js +10 -0
- package/build/services/mcp/playwright-server/schemas.d.ts +4 -4
- package/build/services/mcp/sql.d.ts +1 -1
- package/build/services/mcp/sql.js +2 -2
- package/build/services/mcp/types.d.ts +3 -1
- package/build/services/yaml-workflow/db.d.ts +3 -0
- package/build/services/yaml-workflow/db.js +24 -0
- package/build/services/yaml-workflow/invoke.d.ts +19 -0
- package/build/services/yaml-workflow/invoke.js +80 -0
- package/build/services/yaml-workflow/pipeline/build/dag.js +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/build/wiring.js +89 -2
- package/build/services/yaml-workflow/pipeline/prompts.d.ts +1 -1
- package/build/services/yaml-workflow/pipeline/prompts.js +44 -1
- package/build/services/yaml-workflow/sql.d.ts +3 -0
- package/build/services/yaml-workflow/sql.js +16 -1
- package/build/services/yaml-workflow/types.d.ts +13 -1
- package/build/services/yaml-workflow/workers/callbacks.js +9 -1
- package/build/services/yaml-workflow/workers/register.js +29 -1
- package/build/system/index.js +6 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +12 -12
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/playwright/schemas.d.ts +18 -18
- package/build/system/mcp-servers/playwright-cli/schemas.d.ts +34 -34
- package/build/system/mcp-servers/playwright-cli/tools-capture.js +5 -1
- package/build/system/mcp-servers/vision.js +54 -17
- package/build/system/seed/server-definitions.d.ts +7 -0
- package/build/system/seed/server-definitions.js +5 -2
- package/build/system/seed/tool-manifests-workflows.d.ts +7 -0
- package/build/system/seed/tool-manifests-workflows.js +10 -3
- package/build/system/workflows/mcp-workflow-builder/activities/caches.d.ts +5 -0
- package/build/system/workflows/mcp-workflow-builder/activities/caches.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/index.js +7 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.d.ts +2 -0
- package/build/system/workflows/mcp-workflow-builder/activities/llm.js +25 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.d.ts +5 -0
- package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.js +8 -0
- package/build/system/workflows/mcp-workflow-builder/index.d.ts +16 -0
- package/build/system/workflows/mcp-workflow-builder/index.js +229 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.d.ts +8 -0
- package/build/system/workflows/mcp-workflow-builder/prompts.js +247 -0
- package/build/system/workflows/shared/tool-loader.js +3 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/mcp.d.ts +4 -3
- package/build/types/yaml-workflow.d.ts +6 -2
- package/dashboard/dist/assets/AdminDashboard-BXkKGkb5.js +2 -0
- package/dashboard/dist/assets/{AdminDashboard-CTyAMUJR.js.map → AdminDashboard-BXkKGkb5.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DcH592mc.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-DcH592mc.js.map +1 -0
- package/dashboard/dist/assets/BotPicker-A6LtzyuO.js +2 -0
- package/dashboard/dist/assets/{BotPicker-C51nKFEu.js.map → BotPicker-A6LtzyuO.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js → CollapsibleSection-C7nL2_mv.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BSyfd8uL.js.map → CollapsibleSection-C7nL2_mv.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js → ConfirmDeleteModal-CWFwJrSl.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-CBdhia5T.js.map → ConfirmDeleteModal-CWFwJrSl.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js → CopyableId-DbZ5c3jh.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-dGlewBCS.js.map → CopyableId-DbZ5c3jh.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-ClWkmLPu.js +2 -0
- package/dashboard/dist/assets/CredentialsPage-ClWkmLPu.js.map +1 -0
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js → CustomDurationPicker-CtH2hReF.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BataWFj8.js.map → CustomDurationPicker-CtH2hReF.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js → DataTable-CM5ZcpPi.js} +2 -2
- package/dashboard/dist/assets/{DataTable-B3uf5CCo.js.map → DataTable-CM5ZcpPi.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js → ElapsedCell-CwqavyeC.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-G5oSwTpT.js.map → ElapsedCell-CwqavyeC.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js → EmptyState-BBn78pmm.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-BChBJNGS.js.map → EmptyState-BBn78pmm.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js → EscalationsOverview-BcJ2E3X7.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CxUv8xjG.js.map → EscalationsOverview-BcJ2E3X7.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js → EventTable-C1en_KZ0.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CVt8B0BZ.js.map → EventTable-C1en_KZ0.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js → FilterBar-CZTlrLQT.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CShf0oe7.js.map → FilterBar-CZTlrLQT.js.map} +1 -1
- package/dashboard/dist/assets/ListToolbar-Cdbsapig.js +2 -0
- package/dashboard/dist/assets/ListToolbar-Cdbsapig.js.map +1 -0
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js → McpOverview-CSpEJxKa.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CbaZRnJl.js.map → McpOverview-CSpEJxKa.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-DhqEI180.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-DhqEI180.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-CIiVMlqo.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-CIiVMlqo.js.map +1 -0
- package/dashboard/dist/assets/McpRunDetailPage-9xdxgG4d.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-9xdxgG4d.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-wWLqHsd4.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-wWLqHsd4.js.map +1 -0
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js → Modal-kB_P7ZOr.js} +2 -2
- package/dashboard/dist/assets/{Modal-CI5RBPOQ.js.map → Modal-kB_P7ZOr.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-jc0vrgDI.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-jc0vrgDI.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js → PageHeader-NkOeBR05.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-SMD9qtOO.js.map → PageHeader-NkOeBR05.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js → PageHeaderWithStats-ywNhrmFK.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-TikLQsTp.js.map → PageHeaderWithStats-ywNhrmFK.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js → PriorityBadge-B2MQbSxy.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-CQ0EsLTA.js.map → PriorityBadge-B2MQbSxy.js.map} +1 -1
- package/dashboard/dist/assets/ProcessDetailPage-B7z7IdqE.js +2 -0
- package/dashboard/dist/assets/ProcessDetailPage-B7z7IdqE.js.map +1 -0
- package/dashboard/dist/assets/ProcessesListPage-C-uHadO6.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-C-uHadO6.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js → RolePill-C1dgC-fK.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Crj4TH5p.js.map → RolePill-C1dgC-fK.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js → RolesPage-BSxrD1vm.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-C_RInUwS.js.map → RolesPage-BSxrD1vm.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js → RowActions-lYaHGI-v.js} +2 -2
- package/dashboard/dist/assets/{RowActions-Cp5HyK_w.js.map → RowActions-lYaHGI-v.js.map} +1 -1
- package/dashboard/dist/assets/RunAsSelector-CJDnyp93.js +2 -0
- package/dashboard/dist/assets/RunAsSelector-CJDnyp93.js.map +1 -0
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js → StatCard-v2TiITVr.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BKZLSgNV.js.map → StatCard-v2TiITVr.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js → StatusBadge-DWlxevgG.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-BYNGGZK5.js.map → StatusBadge-DWlxevgG.js.map} +1 -1
- package/dashboard/dist/assets/StepIndicator-CRM4ft28.js +2 -0
- package/dashboard/dist/assets/StepIndicator-CRM4ft28.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js → StickyPagination-CF0EToEU.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-CTosgiU2.js.map → StickyPagination-CF0EToEU.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js → SwimlaneTimeline-CNlj7fgg.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-ylG5Ps1s.js.map → SwimlaneTimeline-CNlj7fgg.js.map} +1 -1
- package/dashboard/dist/assets/TagInput-CH8qMGhC.js +2 -0
- package/dashboard/dist/assets/TagInput-CH8qMGhC.js.map +1 -0
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js → TaskDetailPage-CdWo-6mu.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-C9pDGdD2.js.map → TaskDetailPage-CdWo-6mu.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js → TaskQueuePill-BPj4ogVG.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BtJbZTT0.js.map → TaskQueuePill-BPj4ogVG.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js → TasksListPage-CtRkMpKU.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DtFLUEhg.js.map → TasksListPage-CtRkMpKU.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js → TimeAgo-Di1a3X5P.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-WuM6xImZ.js.map → TimeAgo-Di1a3X5P.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js → TimestampCell-CqrXql-S.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-IVL_-Upy.js.map → TimestampCell-CqrXql-S.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DU9qeg13.js → UserName-BUFYCnRa.js} +2 -2
- package/dashboard/dist/assets/{UserName-DU9qeg13.js.map → UserName-BUFYCnRa.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-25iusMml.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-25iusMml.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowPill-Diw8iWBP.js → WorkflowPill-DPKOcbf4.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Diw8iWBP.js.map → WorkflowPill-DPKOcbf4.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BgxslssH.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-BgxslssH.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js → WorkflowsOverview-Doe5L-Re.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CPuvA4t3.js.map → WorkflowsOverview-Doe5L-Re.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-BliAckJ6.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-BliAckJ6.js.map +1 -0
- package/dashboard/dist/assets/{bots-BPiZXf2h.js → bots-Bi2_O1Ts.js} +2 -2
- package/dashboard/dist/assets/{bots-BPiZXf2h.js.map → bots-Bi2_O1Ts.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js → escalation-Ck1KlLkT.js} +2 -2
- package/dashboard/dist/assets/{escalation-DTY_OKRh.js.map → escalation-Ck1KlLkT.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js → escalation-columns-ohDsj2eJ.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-C91fHSkp.js.map → escalation-columns-ohDsj2eJ.js.map} +1 -1
- package/dashboard/dist/assets/helpers-BoD2SgUY.js +2 -0
- package/dashboard/dist/assets/helpers-BoD2SgUY.js.map +1 -0
- package/dashboard/dist/assets/{index-D_qEAYrg.js → index-BEtLIsML.js} +2 -2
- package/dashboard/dist/assets/{index-D_qEAYrg.js.map → index-BEtLIsML.js.map} +1 -1
- package/dashboard/dist/assets/index-Bn2xHDr8.js +5 -0
- package/dashboard/dist/assets/index-Bn2xHDr8.js.map +1 -0
- package/dashboard/dist/assets/index-BpT-6WgJ.js +2 -0
- package/dashboard/dist/assets/{index-BtOwLI0K.js.map → index-BpT-6WgJ.js.map} +1 -1
- package/dashboard/dist/assets/index-CZrJ09p-.js +2 -0
- package/dashboard/dist/assets/index-CZrJ09p-.js.map +1 -0
- package/dashboard/dist/assets/index-D3NyVADW.js +2 -0
- package/dashboard/dist/assets/index-D3NyVADW.js.map +1 -0
- package/dashboard/dist/assets/index-D7zYZOnH.js +2 -0
- package/dashboard/dist/assets/{index-CDWOfCmi.js.map → index-D7zYZOnH.js.map} +1 -1
- package/dashboard/dist/assets/index-DOkHXmyf.js +17 -0
- package/dashboard/dist/assets/index-DOkHXmyf.js.map +1 -0
- package/dashboard/dist/assets/{index-DSzSoku1.js → index-DYyLF-Qb.js} +91 -93
- package/dashboard/dist/assets/index-DYyLF-Qb.js.map +1 -0
- package/dashboard/dist/assets/index-Dk2Q51o0.js +2 -0
- package/dashboard/dist/assets/index-Dk2Q51o0.js.map +1 -0
- package/dashboard/dist/assets/index-FuohTtaM.js +6 -0
- package/dashboard/dist/assets/index-FuohTtaM.js.map +1 -0
- package/dashboard/dist/assets/index-PyCTS05D.css +1 -0
- package/dashboard/dist/assets/mcp-CJtYjA7A.js +2 -0
- package/dashboard/dist/assets/mcp-CJtYjA7A.js.map +1 -0
- package/dashboard/dist/assets/mcp-query-jQJQrs_7.js +2 -0
- package/dashboard/dist/assets/mcp-query-jQJQrs_7.js.map +1 -0
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js → mcp-runs-DUWm9Z4V.js} +2 -2
- package/dashboard/dist/assets/{mcp-runs-DmXYJD19.js.map → mcp-runs-DUWm9Z4V.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js → namespaces-BM5P2qmL.js} +2 -2
- package/dashboard/dist/assets/{namespaces-DoGa7jc7.js.map → namespaces-BM5P2qmL.js.map} +1 -1
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js → roles-lv0shpjJ.js} +2 -2
- package/dashboard/dist/assets/{roles-wCdQ2Z7k.js.map → roles-lv0shpjJ.js.map} +1 -1
- package/dashboard/dist/assets/{settings-DDe_L7JT.js → settings-Wlq92mRo.js} +2 -2
- package/dashboard/dist/assets/{settings-DDe_L7JT.js.map → settings-Wlq92mRo.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js → tasks-BFGm4PuE.js} +2 -2
- package/dashboard/dist/assets/{tasks-3Hih8Bt7.js.map → tasks-BFGm4PuE.js.map} +1 -1
- package/dashboard/dist/assets/useEventHooks-DIE6ue4x.js +2 -0
- package/dashboard/dist/assets/useEventHooks-DIE6ue4x.js.map +1 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js +2 -0
- package/dashboard/dist/assets/useExpandedRows-Cg9iq6Vy.js.map +1 -0
- package/dashboard/dist/assets/{useYamlActivityEvents-B5dHec6Y.js → useYamlActivityEvents-DCwSO73t.js} +2 -2
- package/dashboard/dist/assets/useYamlActivityEvents-DCwSO73t.js.map +1 -0
- package/dashboard/dist/assets/{users-BTagPmGW.js → users-tA5-K0wA.js} +2 -2
- package/dashboard/dist/assets/{users-BTagPmGW.js.map → users-tA5-K0wA.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-DCLlGYO9.js → vendor-icons-BiIug1SK.js} +121 -66
- package/dashboard/dist/assets/vendor-icons-BiIug1SK.js.map +1 -0
- package/dashboard/dist/assets/{workflows-B20dR3NE.js → workflows-CfLc15Wr.js} +2 -2
- package/dashboard/dist/assets/{workflows-B20dR3NE.js.map → workflows-CfLc15Wr.js.map} +1 -1
- package/dashboard/dist/assets/yaml-workflows-D7JXNqbM.js +2 -0
- package/dashboard/dist/assets/{yaml-workflows-CaLPMQha.js.map → yaml-workflows-D7JXNqbM.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/mcp-servers.md +60 -2
- package/docs/architecture.md +3 -3
- package/docs/dashboard.md +1 -1
- package/docs/escalation-strategies.md +2 -3
- package/docs/mcp.md +301 -31
- package/package.json +4 -4
- package/dashboard/dist/assets/AdminDashboard-CTyAMUJR.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-BMXV3Q4l.js.map +0 -1
- package/dashboard/dist/assets/BotPicker-C51nKFEu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js +0 -2
- package/dashboard/dist/assets/CredentialsPage-CoBNFSAu.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-CGoR9XK6.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-BjXoYQuU.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-DLkA5Aar.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-DCh9n11D.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-Dc80suXd.js.map +0 -1
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js +0 -2
- package/dashboard/dist/assets/ProcessDetailPage-B2GKuGzk.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CTjI3Wn6.js.map +0 -1
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js +0 -2
- package/dashboard/dist/assets/RefreshButton-BcQDObrv.js.map +0 -1
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js +0 -2
- package/dashboard/dist/assets/RunAsSelector-BhyWtofX.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-DOocX81f.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DDtUIrTy.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-DlwwkluN.js.map +0 -1
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js +0 -2
- package/dashboard/dist/assets/helpers-DBUZ9pnG.js.map +0 -1
- package/dashboard/dist/assets/index-BOeA-gfK.js +0 -17
- package/dashboard/dist/assets/index-BOeA-gfK.js.map +0 -1
- package/dashboard/dist/assets/index-BZ6K_kmL.js +0 -3
- package/dashboard/dist/assets/index-BZ6K_kmL.js.map +0 -1
- package/dashboard/dist/assets/index-Bpm0yeoi.js +0 -2
- package/dashboard/dist/assets/index-Bpm0yeoi.js.map +0 -1
- package/dashboard/dist/assets/index-BtOwLI0K.js +0 -2
- package/dashboard/dist/assets/index-CBF3ZvRZ.js +0 -6
- package/dashboard/dist/assets/index-CBF3ZvRZ.js.map +0 -1
- package/dashboard/dist/assets/index-CDWOfCmi.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js +0 -2
- package/dashboard/dist/assets/index-Ce6sL__n.js.map +0 -1
- package/dashboard/dist/assets/index-DSzSoku1.js.map +0 -1
- package/dashboard/dist/assets/index-gCy9XX3W.css +0 -1
- package/dashboard/dist/assets/mcp-BzVpaaKF.js +0 -2
- package/dashboard/dist/assets/mcp-BzVpaaKF.js.map +0 -1
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js +0 -2
- package/dashboard/dist/assets/mcp-query-wTuxTTCV.js.map +0 -1
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js +0 -2
- package/dashboard/dist/assets/useNatsEvents-DeGKHFTX.js.map +0 -1
- package/dashboard/dist/assets/useYamlActivityEvents-B5dHec6Y.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-DCLlGYO9.js.map +0 -1
- package/dashboard/dist/assets/yaml-workflows-CaLPMQha.js +0 -2
- package/lib/db/README.md +0 -8
- /package/{lib → build/lib}/db/schemas/002_seed.sql +0 -0
- /package/{lib → build/lib}/db/schemas/003_workflow_discovery.sql +0 -0
- /package/{lib → build/lib}/db/schemas/004_query_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/005_triage_router.sql +0 -0
- /package/{lib → build/lib}/db/schemas/006_oauth.sql +0 -0
- /package/{lib → build/lib}/db/schemas/007_security.sql +0 -0
- /package/{lib → build/lib}/db/schemas/008_bot_accounts.sql +0 -0
- /package/{lib → build/lib}/db/schemas/009_audit_trail.sql +0 -0
- /package/{lib → build/lib}/db/schemas/010_credential_providers.sql +0 -0
- /package/{lib → build/lib}/db/schemas/012_drop_modality.sql +0 -0
- /package/{lib → build/lib}/db/schemas/013_execute_as.sql +0 -0
- /package/{lib → build/lib}/db/schemas/014_ephemeral_credentials.sql +0 -0
- /package/{lib → build/lib}/db/schemas/015_knowledge.sql +0 -0
package/README.md
CHANGED
|
@@ -82,9 +82,39 @@ curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
|
|
|
82
82
|
|
|
83
83
|
De-certifying removes the interceptor. The workflow continues as a standard durable workflow — same code, different guarantees.
|
|
84
84
|
|
|
85
|
-
## Register
|
|
85
|
+
## Register MCP Servers
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
Long Tail connects to any MCP server — an npm package, a remote service, or one you write yourself. Registered tools become durable activities and are available to the Pipeline Designer.
|
|
88
|
+
|
|
89
|
+
**Use an existing package** — no code, just register:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
93
|
+
-H 'Content-Type: application/json' \
|
|
94
|
+
-d '{
|
|
95
|
+
"name": "filesystem",
|
|
96
|
+
"transport_type": "stdio",
|
|
97
|
+
"transport_config": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/data"] },
|
|
98
|
+
"tags": ["files", "storage"],
|
|
99
|
+
"auto_connect": true
|
|
100
|
+
}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Connect a remote server** — point at a URL:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
107
|
+
-H 'Content-Type: application/json' \
|
|
108
|
+
-d '{
|
|
109
|
+
"name": "my-python-server",
|
|
110
|
+
"transport_type": "sse",
|
|
111
|
+
"transport_config": { "url": "http://python-service:8000/mcp" },
|
|
112
|
+
"tags": ["ml", "classification"],
|
|
113
|
+
"compile_hints": "Returns confidence scores. Use threshold 0.85 for auto-approve."
|
|
114
|
+
}'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Write your own** and register it in-process:
|
|
88
118
|
|
|
89
119
|
```typescript
|
|
90
120
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
@@ -106,8 +136,6 @@ export function createImageToolsServer(): McpServer {
|
|
|
106
136
|
}
|
|
107
137
|
```
|
|
108
138
|
|
|
109
|
-
Register it at startup and it appears in the dashboard:
|
|
110
|
-
|
|
111
139
|
```typescript
|
|
112
140
|
const lt = await start({
|
|
113
141
|
// ...
|
|
@@ -117,6 +145,8 @@ const lt = await start({
|
|
|
117
145
|
});
|
|
118
146
|
```
|
|
119
147
|
|
|
148
|
+
All three paths produce the same outcome: tools callable as durable activities. Tags enable discovery. Compile hints guide the compiler when tools are compiled into deterministic pipelines. See the [MCP guide](docs/mcp.md) for the full registration lifecycle.
|
|
149
|
+
|
|
120
150
|
## Ask It Anything
|
|
121
151
|
|
|
122
152
|
Once your tools are registered, the Pipeline Designer orchestrates them. Describe what you need in plain language:
|
package/build/lib/db/migrate.js
CHANGED
|
@@ -38,12 +38,9 @@ const fs = __importStar(require("fs"));
|
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const index_1 = require("./index");
|
|
40
40
|
const logger_1 = require("../logger");
|
|
41
|
-
//
|
|
42
|
-
// In
|
|
43
|
-
const
|
|
44
|
-
const SCHEMAS_DIR = fs.existsSync(devPath)
|
|
45
|
-
? devPath
|
|
46
|
-
: path.join(__dirname, '..', '..', '..', 'services', 'db', 'schemas');
|
|
41
|
+
// Both dev (lib/db/) and build (build/lib/db/) have schemas/ as a sibling.
|
|
42
|
+
// In dev it exists naturally; in build it's copied by the build script.
|
|
43
|
+
const SCHEMAS_DIR = path.join(__dirname, 'schemas');
|
|
47
44
|
async function migrate() {
|
|
48
45
|
const pool = (0, index_1.getPool)();
|
|
49
46
|
// ensure migration tracking table
|
|
@@ -258,6 +258,9 @@ CREATE TABLE IF NOT EXISTS lt_yaml_workflows (
|
|
|
258
258
|
tags TEXT[] NOT NULL DEFAULT '{}',
|
|
259
259
|
input_field_meta JSONB NOT NULL DEFAULT '[]'::JSONB,
|
|
260
260
|
metadata JSONB,
|
|
261
|
+
cron_schedule TEXT,
|
|
262
|
+
cron_envelope JSONB,
|
|
263
|
+
execute_as TEXT,
|
|
261
264
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
262
265
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
263
266
|
);
|
|
@@ -10,6 +10,9 @@ VALUES
|
|
|
10
10
|
'{}'),
|
|
11
11
|
('mcpTriage', 'long-tail-system', 'engineer', false,
|
|
12
12
|
'Dynamic MCP triage — LLM agentic loop for escalation remediation',
|
|
13
|
+
'{}'),
|
|
14
|
+
('mcpWorkflowBuilder', 'long-tail-system', 'engineer', false,
|
|
15
|
+
'Direct pipeline builder — LLM constructs DAG from tool schemas',
|
|
13
16
|
'{}')
|
|
14
17
|
ON CONFLICT (workflow_type) DO NOTHING;
|
|
15
18
|
|
|
@@ -21,3 +24,7 @@ ON CONFLICT (workflow_type, role) DO NOTHING;
|
|
|
21
24
|
INSERT INTO lt_config_roles (workflow_type, role)
|
|
22
25
|
SELECT 'mcpTriage', unnest(ARRAY['reviewer', 'engineer', 'admin'])
|
|
23
26
|
ON CONFLICT (workflow_type, role) DO NOTHING;
|
|
27
|
+
|
|
28
|
+
INSERT INTO lt_config_roles (workflow_type, role)
|
|
29
|
+
SELECT 'mcpWorkflowBuilder', unnest(ARRAY['reviewer', 'engineer', 'admin'])
|
|
30
|
+
ON CONFLICT (workflow_type, role) DO NOTHING;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- Allow 'streamable-http' as a transport type for MCP servers
|
|
2
|
+
ALTER TABLE lt_mcp_servers
|
|
3
|
+
DROP CONSTRAINT IF EXISTS lt_mcp_servers_transport_type_check;
|
|
4
|
+
|
|
5
|
+
ALTER TABLE lt_mcp_servers
|
|
6
|
+
ADD CONSTRAINT lt_mcp_servers_transport_type_check
|
|
7
|
+
CHECK (transport_type IN ('stdio', 'sse', 'streamable-http'));
|
package/build/routes/docs.js
CHANGED
|
@@ -37,13 +37,13 @@ const express_1 = require("express");
|
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const router = (0, express_1.Router)();
|
|
40
|
-
function
|
|
40
|
+
function projectRoot() {
|
|
41
41
|
const candidates = [
|
|
42
|
-
path.join(__dirname, '..'
|
|
43
|
-
path.join(__dirname, '..', '..'
|
|
42
|
+
path.join(__dirname, '..'),
|
|
43
|
+
path.join(__dirname, '..', '..'),
|
|
44
44
|
];
|
|
45
45
|
for (const dir of candidates) {
|
|
46
|
-
if (fs.existsSync(dir))
|
|
46
|
+
if (fs.existsSync(path.join(dir, 'docs')))
|
|
47
47
|
return dir;
|
|
48
48
|
}
|
|
49
49
|
return candidates[0];
|
|
@@ -66,8 +66,26 @@ function listDocs(dir, prefix = '') {
|
|
|
66
66
|
}
|
|
67
67
|
return results;
|
|
68
68
|
}
|
|
69
|
+
function resolveDocPath(docPath) {
|
|
70
|
+
const root = projectRoot();
|
|
71
|
+
// README.md lives at project root, everything else under docs/
|
|
72
|
+
if (docPath === 'README.md') {
|
|
73
|
+
const fp = path.join(root, 'README.md');
|
|
74
|
+
return fs.existsSync(fp) ? fp : null;
|
|
75
|
+
}
|
|
76
|
+
const fp = path.join(root, 'docs', docPath);
|
|
77
|
+
return fs.existsSync(fp) ? fp : null;
|
|
78
|
+
}
|
|
69
79
|
router.get('/', (_req, res) => {
|
|
70
|
-
|
|
80
|
+
const root = projectRoot();
|
|
81
|
+
const docs = [];
|
|
82
|
+
// README first
|
|
83
|
+
const readmePath = path.join(root, 'README.md');
|
|
84
|
+
if (fs.existsSync(readmePath)) {
|
|
85
|
+
docs.push({ path: 'README.md', title: 'Long Tail' });
|
|
86
|
+
}
|
|
87
|
+
docs.push(...listDocs(path.join(root, 'docs')));
|
|
88
|
+
res.json({ docs });
|
|
71
89
|
});
|
|
72
90
|
// Use query param for doc path to avoid Express wildcard issues
|
|
73
91
|
router.get('/read', (req, res) => {
|
|
@@ -76,8 +94,8 @@ router.get('/read', (req, res) => {
|
|
|
76
94
|
res.status(400).json({ error: 'Invalid path' });
|
|
77
95
|
return;
|
|
78
96
|
}
|
|
79
|
-
const filePath =
|
|
80
|
-
if (!
|
|
97
|
+
const filePath = resolveDocPath(docPath);
|
|
98
|
+
if (!filePath) {
|
|
81
99
|
res.status(404).json({ error: 'Document not found' });
|
|
82
100
|
return;
|
|
83
101
|
}
|
package/build/routes/insight.js
CHANGED
|
@@ -37,6 +37,69 @@ router.post('/mcp-query', async (req, res) => {
|
|
|
37
37
|
res.status(500).json({ error: err.message });
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
|
+
/**
|
|
41
|
+
* POST /api/insight/build-workflow
|
|
42
|
+
* Build a HotMesh YAML DAG directly from a natural language description.
|
|
43
|
+
* The LLM reasons about tool schemas and constructs the YAML declaratively.
|
|
44
|
+
* Body: { prompt: string, tags?: string[], wait?: boolean, feedback?: string, prior_yaml?: string }
|
|
45
|
+
*/
|
|
46
|
+
router.post('/build-workflow', async (req, res) => {
|
|
47
|
+
try {
|
|
48
|
+
const { prompt, tags, wait, feedback, prior_yaml, answers, prior_questions } = req.body;
|
|
49
|
+
if (!prompt || typeof prompt !== 'string') {
|
|
50
|
+
res.status(400).json({ error: 'prompt is required' });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (!process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_API_KEY) {
|
|
54
|
+
res.status(503).json({ error: 'Workflow builder requires an LLM API key (OPENAI_API_KEY or ANTHROPIC_API_KEY)' });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const result = await (0, insight_1.startWorkflowBuilder)({
|
|
58
|
+
prompt,
|
|
59
|
+
tags,
|
|
60
|
+
wait,
|
|
61
|
+
feedback,
|
|
62
|
+
prior_yaml,
|
|
63
|
+
answers,
|
|
64
|
+
prior_questions,
|
|
65
|
+
userId: req.auth?.userId,
|
|
66
|
+
});
|
|
67
|
+
res.json(result);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err.message?.includes('timeout') || err.message?.includes('TIMEOUT')) {
|
|
71
|
+
res.status(504).json({ error: 'Workflow builder timed out. Try a simpler description.' });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
res.status(500).json({ error: err.message });
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
/**
|
|
78
|
+
* POST /api/insight/build-workflow/refine
|
|
79
|
+
* Refine a previously built workflow using execution feedback.
|
|
80
|
+
* Body: { prompt: string, prior_yaml: string, feedback: string, tags?: string[], wait?: boolean }
|
|
81
|
+
*/
|
|
82
|
+
router.post('/build-workflow/refine', async (req, res) => {
|
|
83
|
+
try {
|
|
84
|
+
const { prompt, prior_yaml, feedback, tags, wait } = req.body;
|
|
85
|
+
if (!prompt || !prior_yaml || !feedback) {
|
|
86
|
+
res.status(400).json({ error: 'prompt, prior_yaml, and feedback are required' });
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const result = await (0, insight_1.startWorkflowBuilder)({
|
|
90
|
+
prompt,
|
|
91
|
+
tags,
|
|
92
|
+
wait,
|
|
93
|
+
feedback,
|
|
94
|
+
prior_yaml,
|
|
95
|
+
userId: req.auth?.userId,
|
|
96
|
+
});
|
|
97
|
+
res.json(result);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
res.status(500).json({ error: err.message });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
40
103
|
/**
|
|
41
104
|
* POST /api/insight/mcp-query/describe
|
|
42
105
|
* Generate a workflow description and suggested tags from prompt and result.
|
package/build/routes/mcp.js
CHANGED
|
@@ -66,7 +66,7 @@ router.get('/servers', async (req, res) => {
|
|
|
66
66
|
*/
|
|
67
67
|
router.post('/servers', async (req, res) => {
|
|
68
68
|
try {
|
|
69
|
-
const { name, description, transport_type, transport_config, auto_connect, metadata } = req.body;
|
|
69
|
+
const { name, description, transport_type, transport_config, auto_connect, metadata, tags, compile_hints, credential_providers } = req.body;
|
|
70
70
|
if (!name || !transport_type || !transport_config) {
|
|
71
71
|
res.status(400).json({ error: 'name, transport_type, and transport_config are required' });
|
|
72
72
|
return;
|
|
@@ -78,6 +78,9 @@ router.post('/servers', async (req, res) => {
|
|
|
78
78
|
transport_config,
|
|
79
79
|
auto_connect,
|
|
80
80
|
metadata,
|
|
81
|
+
tags,
|
|
82
|
+
compile_hints,
|
|
83
|
+
credential_providers,
|
|
81
84
|
});
|
|
82
85
|
res.status(201).json(server);
|
|
83
86
|
}
|
|
@@ -89,6 +92,25 @@ router.post('/servers', async (req, res) => {
|
|
|
89
92
|
res.status(500).json({ error: err.message });
|
|
90
93
|
}
|
|
91
94
|
});
|
|
95
|
+
/**
|
|
96
|
+
* POST /api/mcp/servers/test-connection
|
|
97
|
+
* Test connectivity to an MCP server without persisting it.
|
|
98
|
+
*/
|
|
99
|
+
router.post('/servers/test-connection', async (req, res) => {
|
|
100
|
+
try {
|
|
101
|
+
const { transport_type, transport_config } = req.body;
|
|
102
|
+
if (!transport_type || !transport_config) {
|
|
103
|
+
res.status(400).json({ error: 'transport_type and transport_config are required' });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const { testConnection } = await Promise.resolve().then(() => __importStar(require('../services/mcp/client/connection')));
|
|
107
|
+
const result = await testConnection(transport_type, transport_config);
|
|
108
|
+
res.json(result);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
res.json({ success: false, error: err.message, tools: [] });
|
|
112
|
+
}
|
|
113
|
+
});
|
|
92
114
|
// ── Parameterized routes (must come after literal paths) ──────────────
|
|
93
115
|
/**
|
|
94
116
|
* GET /api/mcp/servers/:id
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const yamlDb = __importStar(require("../../services/yaml-workflow/db"));
|
|
38
|
+
const cron_1 = require("../../services/cron");
|
|
39
|
+
const helpers_1 = require("./helpers");
|
|
40
|
+
const router = (0, express_1.Router)();
|
|
41
|
+
/**
|
|
42
|
+
* PUT /api/yaml-workflows/:id/cron
|
|
43
|
+
* Set or update cron schedule + envelope + execute_as.
|
|
44
|
+
*/
|
|
45
|
+
router.put('/:id/cron', async (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const wf = await yamlDb.getYamlWorkflow(req.params.id);
|
|
48
|
+
if (!wf) {
|
|
49
|
+
res.status(404).json({ error: 'YAML workflow not found' });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const { cron_schedule, cron_envelope, execute_as } = req.body;
|
|
53
|
+
if (!cron_schedule || typeof cron_schedule !== 'string') {
|
|
54
|
+
res.status(400).json({ error: 'cron_schedule is required' });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const updated = await yamlDb.updateCronSchedule(wf.id, cron_schedule.trim(), cron_envelope ?? null, execute_as ?? null);
|
|
58
|
+
if (updated) {
|
|
59
|
+
await cron_1.cronRegistry.restartYamlCron(updated);
|
|
60
|
+
}
|
|
61
|
+
res.json(updated);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if ((0, helpers_1.isNotFoundError)(err)) {
|
|
65
|
+
res.status(404).json({ error: 'YAML workflow not found' });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
res.status(500).json({ error: err.message });
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* DELETE /api/yaml-workflows/:id/cron
|
|
73
|
+
* Clear cron schedule.
|
|
74
|
+
*/
|
|
75
|
+
router.delete('/:id/cron', async (req, res) => {
|
|
76
|
+
try {
|
|
77
|
+
const wf = await yamlDb.getYamlWorkflow(req.params.id);
|
|
78
|
+
if (!wf) {
|
|
79
|
+
res.status(404).json({ error: 'YAML workflow not found' });
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await cron_1.cronRegistry.stopYamlCron(wf.id);
|
|
83
|
+
const updated = await yamlDb.clearCronSchedule(wf.id);
|
|
84
|
+
res.json(updated);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if ((0, helpers_1.isNotFoundError)(err)) {
|
|
88
|
+
res.status(404).json({ error: 'YAML workflow not found' });
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
res.status(500).json({ error: err.message });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* GET /api/yaml-workflows/cron/status
|
|
96
|
+
* List all YAML workflows with active cron schedules.
|
|
97
|
+
*/
|
|
98
|
+
router.get('/cron/status', async (_req, res) => {
|
|
99
|
+
try {
|
|
100
|
+
const workflows = await yamlDb.getCronScheduledWorkflows();
|
|
101
|
+
const activeTypes = cron_1.cronRegistry.activeWorkflowTypes;
|
|
102
|
+
const schedules = workflows.map((wf) => ({
|
|
103
|
+
id: wf.id,
|
|
104
|
+
name: wf.name,
|
|
105
|
+
graph_topic: wf.graph_topic,
|
|
106
|
+
app_id: wf.app_id,
|
|
107
|
+
cron_schedule: wf.cron_schedule,
|
|
108
|
+
execute_as: wf.execute_as,
|
|
109
|
+
active: activeTypes.includes(`yaml:${wf.id}`),
|
|
110
|
+
}));
|
|
111
|
+
res.json({ schedules });
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
res.status(500).json({ error: err.message });
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
exports.default = router;
|
|
@@ -147,6 +147,44 @@ router.get('/app-ids', async (_req, res) => {
|
|
|
147
147
|
res.status(500).json({ error: err.message });
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
|
+
/**
|
|
151
|
+
* POST /api/yaml-workflows/direct
|
|
152
|
+
* Create a YAML workflow from raw YAML content (workflow builder output).
|
|
153
|
+
* Unlike POST /, this does not require a source execution — the YAML is provided directly.
|
|
154
|
+
* Body: { name, description?, yaml_content, input_schema?, activity_manifest?, tags?, app_id? }
|
|
155
|
+
*/
|
|
156
|
+
router.post('/direct', async (req, res) => {
|
|
157
|
+
try {
|
|
158
|
+
const { name, description, yaml_content, input_schema, activity_manifest, tags, app_id, graph_topic } = req.body;
|
|
159
|
+
if (!name || !yaml_content) {
|
|
160
|
+
res.status(400).json({ error: 'name and yaml_content are required' });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// Extract subscribes topic from YAML content, or fall back to name-derived slug
|
|
164
|
+
let graphTopic = graph_topic || name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
165
|
+
const subscribesMatch = yaml_content.match(/subscribes:\s*(.+)/);
|
|
166
|
+
if (subscribesMatch) {
|
|
167
|
+
graphTopic = subscribesMatch[1].trim().replace(/^['"]|['"]$/g, '');
|
|
168
|
+
}
|
|
169
|
+
const wf = await yamlDb.createYamlWorkflow({
|
|
170
|
+
name,
|
|
171
|
+
description,
|
|
172
|
+
app_id: app_id || 'longtail',
|
|
173
|
+
yaml_content,
|
|
174
|
+
graph_topic: graphTopic,
|
|
175
|
+
input_schema: input_schema || {},
|
|
176
|
+
output_schema: {},
|
|
177
|
+
activity_manifest: activity_manifest || [],
|
|
178
|
+
tags: tags || [],
|
|
179
|
+
original_prompt: description,
|
|
180
|
+
category: 'builder',
|
|
181
|
+
});
|
|
182
|
+
res.json(wf);
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
res.status(500).json({ error: err.message });
|
|
186
|
+
}
|
|
187
|
+
});
|
|
150
188
|
// -- Parameterized routes --
|
|
151
189
|
/**
|
|
152
190
|
* GET /api/yaml-workflows/:id
|
|
@@ -37,6 +37,7 @@ const express_1 = require("express");
|
|
|
37
37
|
const yamlDb = __importStar(require("../../services/yaml-workflow/db"));
|
|
38
38
|
const yamlDeployer = __importStar(require("../../services/yaml-workflow/deployer"));
|
|
39
39
|
const yamlWorkers = __importStar(require("../../services/yaml-workflow/workers"));
|
|
40
|
+
const invoke_1 = require("../../services/yaml-workflow/invoke");
|
|
40
41
|
const helpers_1 = require("./helpers");
|
|
41
42
|
const router = (0, express_1.Router)();
|
|
42
43
|
/**
|
|
@@ -133,40 +134,14 @@ router.post('/:id/invoke', async (req, res) => {
|
|
|
133
134
|
res.status(400).json({ error: 'Workflow must be active to invoke' });
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
resolvePrincipal(executeAs),
|
|
145
|
-
userId ? resolvePrincipal(userId) : Promise.resolve(null),
|
|
146
|
-
]);
|
|
147
|
-
if (botPrincipal) {
|
|
148
|
-
data._scope = {
|
|
149
|
-
principal: botPrincipal,
|
|
150
|
-
scopes: ['mcp:tool:call'],
|
|
151
|
-
...(invokerPrincipal ? { initiatedBy: userId, initiatingPrincipal: invokerPrincipal } : {}),
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
else if (userId) {
|
|
156
|
-
const principal = await resolvePrincipal(userId);
|
|
157
|
-
if (principal) {
|
|
158
|
-
data._scope = { principal, scopes: ['mcp:tool:call'] };
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (req.body.sync) {
|
|
163
|
-
const { job_id, result } = await yamlDeployer.invokeYamlWorkflowSync(wf.app_id, wf.graph_topic, data, req.body.timeout, wf.graph_topic);
|
|
164
|
-
res.json({ job_id, result });
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
const jobId = await yamlDeployer.invokeYamlWorkflow(wf.app_id, wf.graph_topic, data, wf.graph_topic);
|
|
168
|
-
res.json({ job_id: jobId });
|
|
169
|
-
}
|
|
137
|
+
const result = await (0, invoke_1.invokeYamlWorkflow)(wf, {
|
|
138
|
+
data: req.body.data,
|
|
139
|
+
sync: req.body.sync,
|
|
140
|
+
timeout: req.body.timeout,
|
|
141
|
+
execute_as: req.body.execute_as,
|
|
142
|
+
userId: req.auth?.userId,
|
|
143
|
+
});
|
|
144
|
+
res.json(result);
|
|
170
145
|
}
|
|
171
146
|
catch (err) {
|
|
172
147
|
if ((0, helpers_1.isNotFoundError)(err)) {
|
|
@@ -4,11 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const express_1 = require("express");
|
|
7
|
+
const cron_1 = __importDefault(require("./cron"));
|
|
7
8
|
const crud_1 = __importDefault(require("./crud"));
|
|
8
9
|
const deployment_1 = __importDefault(require("./deployment"));
|
|
9
10
|
const versions_1 = __importDefault(require("./versions"));
|
|
10
11
|
const router = (0, express_1.Router)();
|
|
11
|
-
//
|
|
12
|
+
// cron.ts handles: GET /cron/status, PUT /:id/cron, DELETE /:id/cron
|
|
13
|
+
// Mount before crud so /cron/status doesn't match /:id
|
|
14
|
+
router.use(cron_1.default);
|
|
12
15
|
// crud.ts handles: GET /, POST /, GET /app-ids, GET /:id, PUT /:id,
|
|
13
16
|
// POST /:id/regenerate, DELETE /:id
|
|
14
17
|
router.use(crud_1.default);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { LTWorkflowConfig } from '../../types';
|
|
2
|
+
import type { LTYamlWorkflowRecord } from '../../types/yaml-workflow';
|
|
2
3
|
/**
|
|
3
4
|
* Singleton registry for workflow cron schedules.
|
|
4
5
|
*
|
|
@@ -30,6 +31,22 @@ declare class LTCronRegistry {
|
|
|
30
31
|
* Stops the old cron (if any) and starts a new one if cron_schedule is set.
|
|
31
32
|
*/
|
|
32
33
|
restartCron(config: LTWorkflowConfig): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Load all YAML workflows with a cron_schedule and start Virtual.cron for each.
|
|
36
|
+
*/
|
|
37
|
+
connectYamlCrons(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Start a single Virtual.cron for a YAML workflow.
|
|
40
|
+
*/
|
|
41
|
+
startYamlCron(wf: LTYamlWorkflowRecord): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Stop a single YAML workflow cron.
|
|
44
|
+
*/
|
|
45
|
+
stopYamlCron(yamlWfId: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Restart a YAML workflow cron after config change.
|
|
48
|
+
*/
|
|
49
|
+
restartYamlCron(wf: LTYamlWorkflowRecord): Promise<void>;
|
|
33
50
|
/**
|
|
34
51
|
* Stop all active crons. Call during graceful shutdown.
|
|
35
52
|
*/
|