@hotmeshio/long-tail 0.4.12 → 0.4.13
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 +76 -100
- package/build/api/index.d.ts +2 -1
- package/build/api/index.js +3 -2
- package/build/api/{mcp-runs.d.ts → pipelines.d.ts} +18 -0
- package/build/api/{mcp-runs.js → pipelines.js} +36 -4
- package/build/api/workflows/discovery.js +1 -1
- package/build/routes/index.js +3 -2
- package/build/routes/{mcp-runs.js → pipelines.js} +17 -4
- package/build/sdk/index.d.ts +11 -4
- package/build/sdk/index.js +12 -5
- package/build/services/{mcp-runs → pipelines}/sql.js +1 -1
- package/build/start/adapters.js +3 -6
- package/build/start/server.js +5 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/startup.d.ts +3 -3
- package/dashboard/dist/assets/{AdminDashboard-B7AFFt4L.js → AdminDashboard-Jwr3Fsaz.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-B7AFFt4L.js.map → AdminDashboard-Jwr3Fsaz.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CjuCbr5J.js → AgentConfigPage-DbqbFXEq.js} +4 -4
- package/dashboard/dist/assets/{AgentConfigPage-CjuCbr5J.js.map → AgentConfigPage-DbqbFXEq.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-DnHaUCS5.js → AgentDetailPage-Cw7foCHd.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-DnHaUCS5.js.map → AgentDetailPage-Cw7foCHd.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-BR2-PdTq.js → AgentsPage-DzpWsTFO.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-BR2-PdTq.js.map → AgentsPage-DzpWsTFO.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-CEkeo_N4.js → AvailableEscalationsPage-D2cxvpAK.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-CEkeo_N4.js.map → AvailableEscalationsPage-D2cxvpAK.js.map} +1 -1
- package/dashboard/dist/assets/BotPicker-Ddu4V0uf.js +2 -0
- package/dashboard/dist/assets/{BotPicker-CAowL3ib.js.map → BotPicker-Ddu4V0uf.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-BTd-uYTM.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-CSUKBvEN.js.map → CapabilitiesPage-BTd-uYTM.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-Bv6ixURp.js → CollapsibleSection-DM-75khr.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-Bv6ixURp.js.map → CollapsibleSection-DM-75khr.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-CdPKxRBj.js → CredentialsPage-BQNraRZu.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CdPKxRBj.js.map → CredentialsPage-BQNraRZu.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-BtdXRDqs.js → CronLabel-CPuMNBua.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-BtdXRDqs.js.map → CronLabel-CPuMNBua.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-Mq3SLUuv.js → CustomDurationPicker-CLq8B89Y.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-Mq3SLUuv.js.map → CustomDurationPicker-CLq8B89Y.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-lw2wmqty.js → DropZone-BkfRoUcm.js} +2 -2
- package/dashboard/dist/assets/{DropZone-lw2wmqty.js.map → DropZone-BkfRoUcm.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-DOTqB4ZX.js → ElapsedCell-8lk94nZt.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-DOTqB4ZX.js.map → ElapsedCell-8lk94nZt.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DSM8Mnb-.js → EscalationsOverview-BfSrQ7A5.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DSM8Mnb-.js.map → EscalationsOverview-BfSrQ7A5.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-C-HagWbs.js → EventTable-D3IOLoxv.js} +2 -2
- package/dashboard/dist/assets/{EventTable-C-HagWbs.js.map → EventTable-D3IOLoxv.js.map} +1 -1
- package/dashboard/dist/assets/{EventTopicPill-RaASGdZz.js → EventTopicPill-CCWCs07y.js} +2 -2
- package/dashboard/dist/assets/{EventTopicPill-RaASGdZz.js.map → EventTopicPill-CCWCs07y.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-RO3qbF38.js +2 -0
- package/dashboard/dist/assets/HomePage-RO3qbF38.js.map +1 -0
- package/dashboard/dist/assets/ListToolbar-4lObXT3_.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-o8xSCSVv.js.map → ListToolbar-4lObXT3_.js.map} +1 -1
- package/dashboard/dist/assets/McpOverview-BdLivZv8.js +2 -0
- package/dashboard/dist/assets/McpOverview-BdLivZv8.js.map +1 -0
- package/dashboard/dist/assets/{McpQueryDetailPage-UR0bySPJ.js → McpQueryDetailPage-DKFkH1qa.js} +2 -2
- package/dashboard/dist/assets/McpQueryDetailPage-DKFkH1qa.js.map +1 -0
- package/dashboard/dist/assets/{McpQueryPage-C-mzOcGH.js → McpQueryPage-AFV_QPwm.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-C-mzOcGH.js.map → McpQueryPage-AFV_QPwm.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-DQJ41oKW.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-DQJ41oKW.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-CzVS7zcc.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-CzVS7zcc.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-DLpqyLle.js → OperatorDashboard-B_QmNzLw.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DLpqyLle.js.map → OperatorDashboard-B_QmNzLw.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-B4w-LDUF.js → PageHeader-CR6TpJG_.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-B4w-LDUF.js.map → PageHeader-CR6TpJG_.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-DQmNXYcG.js → PageHeaderWithStats-CRcQEAO1.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-DQmNXYcG.js.map → PageHeaderWithStats-CRcQEAO1.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-8cJEBC_E.js → ProcessDetailPage-qibro3Dm.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-8cJEBC_E.js.map → ProcessDetailPage-qibro3Dm.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CiprI5Wj.js → ProcessesListPage-CPgiDbdS.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CiprI5Wj.js.map → ProcessesListPage-CPgiDbdS.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-Dk-YUxCm.js → RolePill-BC54Vn-U.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Dk-YUxCm.js.map → RolePill-BC54Vn-U.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-xo6AgPym.js → RolesPage-BAj88I_Y.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-xo6AgPym.js.map → RolesPage-BAj88I_Y.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-DPXWgduq.js → RunAsSelector-IdZ-qOfl.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-DPXWgduq.js.map → RunAsSelector-IdZ-qOfl.js.map} +1 -1
- package/dashboard/dist/assets/{ServerName-A6Wlv3vZ.js → ServerName-Q6okiv4f.js} +2 -2
- package/dashboard/dist/assets/{ServerName-A6Wlv3vZ.js.map → ServerName-Q6okiv4f.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BzG8QxYs.js → SwimlaneTimeline-WQ6VMuqg.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BzG8QxYs.js.map → SwimlaneTimeline-WQ6VMuqg.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-CYh3PFNq.js → TagInput-D6l1SPWd.js} +2 -2
- package/dashboard/dist/assets/{TagInput-CYh3PFNq.js.map → TagInput-D6l1SPWd.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-Ck_0-iO2.js → TaskDetailPage-buNgjwiz.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-Ck_0-iO2.js.map → TaskDetailPage-buNgjwiz.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BSFLiBcf.js → TaskQueuePill-iDBVCEQQ.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BSFLiBcf.js.map → TaskQueuePill-iDBVCEQQ.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DtR4F0ho.js → TasksListPage-BQjjNjRC.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DtR4F0ho.js.map → TasksListPage-BQjjNjRC.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BLNstYO1.js → TimeAgo-Dvkw4shy.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BLNstYO1.js.map → TimeAgo-Dvkw4shy.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DxIz3l1J.js → TimestampCell-DGEGdbOW.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DxIz3l1J.js.map → TimestampCell-DGEGdbOW.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-CcKNnnrK.js → ToolPill-HcRTggHo.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-CcKNnnrK.js.map → ToolPill-HcRTggHo.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-AVDlqGQI.js → ToolTestPanel-GY3n1V12.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-AVDlqGQI.js.map → ToolTestPanel-GY3n1V12.js.map} +1 -1
- package/dashboard/dist/assets/TopicDetailPage-CGim5yi0.js +9 -0
- package/dashboard/dist/assets/TopicDetailPage-CGim5yi0.js.map +1 -0
- package/dashboard/dist/assets/{TopicsPage-BdnJ7E_S.js → TopicsPage-DLyRlo0A.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BdnJ7E_S.js.map → TopicsPage-DLyRlo0A.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-Bk-pzKYb.js → UserName-B8dGlxj9.js} +2 -2
- package/dashboard/dist/assets/{UserName-Bk-pzKYb.js.map → UserName-B8dGlxj9.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-BQbIIdIA.js +2 -0
- package/dashboard/dist/assets/WorkflowExecutionPage-BQbIIdIA.js.map +1 -0
- package/dashboard/dist/assets/WorkflowPill-54px0YiY.js +2 -0
- package/dashboard/dist/assets/WorkflowPill-54px0YiY.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-nXLTR0OO.js → WorkflowsDashboard-DL6oRbka.js} +2 -2
- package/dashboard/dist/assets/WorkflowsDashboard-DL6oRbka.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-BdSHBzzd.js → WorkflowsOverview-Reab_xHT.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-BdSHBzzd.js.map → WorkflowsOverview-Reab_xHT.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-BoFstOcp.js +2 -0
- package/dashboard/dist/assets/{YamlWorkflowsPage-BsO4L_SW.js.map → YamlWorkflowsPage-BoFstOcp.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CtF0uBav.js → agents-CQsJU21y.js} +2 -2
- package/dashboard/dist/assets/{agents-CtF0uBav.js.map → agents-CQsJU21y.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DOP_eck8.js → bots-t1FPESbm.js} +2 -2
- package/dashboard/dist/assets/{bots-DOP_eck8.js.map → bots-t1FPESbm.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DvxG02aF.js → capabilities-D1Y3hVvf.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DvxG02aF.js.map → capabilities-D1Y3hVvf.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Dmq81vAY.js → controlplane-CV-y8cfH.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Dmq81vAY.js.map → controlplane-CV-y8cfH.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-BP3UWfIe.js → escalation-Bf_SO_75.js} +2 -2
- package/dashboard/dist/assets/{escalation-BP3UWfIe.js.map → escalation-Bf_SO_75.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BayccZzU.js → escalation-columns-DgY8c1hM.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BayccZzU.js.map → escalation-columns-DgY8c1hM.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-B_PYr0pL.js → helpers-nWSTagzD.js} +2 -2
- package/dashboard/dist/assets/{helpers-B_PYr0pL.js.map → helpers-nWSTagzD.js.map} +1 -1
- package/dashboard/dist/assets/{index-DzQBDt3K.js → index-0i5oHs_4.js} +2 -2
- package/dashboard/dist/assets/{index-DzQBDt3K.js.map → index-0i5oHs_4.js.map} +1 -1
- package/dashboard/dist/assets/index-B77P0ssX.js +2 -0
- package/dashboard/dist/assets/{index-Bb1ycul8.js.map → index-B77P0ssX.js.map} +1 -1
- package/dashboard/dist/assets/index-BRYCB_g0.js +2 -0
- package/dashboard/dist/assets/index-BRYCB_g0.js.map +1 -0
- package/dashboard/dist/assets/{index-B80zLZVl.js → index-BVXXvXlF.js} +2 -2
- package/dashboard/dist/assets/{index-B80zLZVl.js.map → index-BVXXvXlF.js.map} +1 -1
- package/dashboard/dist/assets/{index-BnB7G5bA.js → index-BZu5zewH.js} +23 -23
- package/dashboard/dist/assets/index-BZu5zewH.js.map +1 -0
- package/dashboard/dist/assets/index-C42ACUTi.js +2 -0
- package/dashboard/dist/assets/index-C42ACUTi.js.map +1 -0
- package/dashboard/dist/assets/{index-DQs-LMoa.js → index-CHBiEYmf.js} +2 -2
- package/dashboard/dist/assets/{index-DQs-LMoa.js.map → index-CHBiEYmf.js.map} +1 -1
- package/dashboard/dist/assets/index-CdUj8mKq.js +15 -0
- package/dashboard/dist/assets/index-CdUj8mKq.js.map +1 -0
- package/dashboard/dist/assets/{index-Bv0eLXZq.js → index-DAQvhgrL.js} +4 -4
- package/dashboard/dist/assets/{index-Bv0eLXZq.js.map → index-DAQvhgrL.js.map} +1 -1
- package/dashboard/dist/assets/{index-CkcPZdQm.js → index-DUaF8VYe.js} +2 -2
- package/dashboard/dist/assets/{index-CkcPZdQm.js.map → index-DUaF8VYe.js.map} +1 -1
- package/dashboard/dist/assets/{index-Do1x4kN0.js → index-Dp8iH4i2.js} +2 -2
- package/dashboard/dist/assets/{index-Do1x4kN0.js.map → index-Dp8iH4i2.js.map} +1 -1
- package/dashboard/dist/assets/index-MO0YnTPi.js +2 -0
- package/dashboard/dist/assets/{index-EqKHsaVz.js.map → index-MO0YnTPi.js.map} +1 -1
- package/dashboard/dist/assets/index-ib-nDwd6.css +1 -0
- package/dashboard/dist/assets/{index-B3wGNZN2.js → index-wlL3EZ14.js} +2 -2
- package/dashboard/dist/assets/{index-B3wGNZN2.js.map → index-wlL3EZ14.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge--SApApck.js → knowledge-DJhm5z0p.js} +2 -2
- package/dashboard/dist/assets/{knowledge--SApApck.js.map → knowledge-DJhm5z0p.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-dn9iPrzm.js → mcp-DMYXb9fv.js} +2 -2
- package/dashboard/dist/assets/{mcp-dn9iPrzm.js.map → mcp-DMYXb9fv.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CgiU2UR6.js → mcp-query-DE-oPOvi.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CgiU2UR6.js.map → mcp-query-DE-oPOvi.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-D93H3wFO.js → namespaces-Bjjm4EG1.js} +2 -2
- package/dashboard/dist/assets/{namespaces-D93H3wFO.js.map → namespaces-Bjjm4EG1.js.map} +1 -1
- package/dashboard/dist/assets/pipelines-C8aRprVr.js +2 -0
- package/dashboard/dist/assets/pipelines-C8aRprVr.js.map +1 -0
- package/dashboard/dist/assets/{roles-DuOWZTpx.js → roles-CQsPYJXe.js} +2 -2
- package/dashboard/dist/assets/{roles-DuOWZTpx.js.map → roles-CQsPYJXe.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-DoCbLKz4.js → tasks-BQ1c7trT.js} +2 -2
- package/dashboard/dist/assets/{tasks-DoCbLKz4.js.map → tasks-BQ1c7trT.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CS7Sxf_-.js → topics-DIziCjqg.js} +2 -2
- package/dashboard/dist/assets/{topics-CS7Sxf_-.js.map → topics-DIziCjqg.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-CrIe_Ulh.js → useEventHooks-CPxcH6zx.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CrIe_Ulh.js.map → useEventHooks-CPxcH6zx.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-JzvzGsUR.js → useYamlActivityEvents-DnPywDgy.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-JzvzGsUR.js.map → useYamlActivityEvents-DnPywDgy.js.map} +1 -1
- package/dashboard/dist/assets/{users-DnxSh2dX.js → users-CMGaVe_B.js} +2 -2
- package/dashboard/dist/assets/{users-DnxSh2dX.js.map → users-CMGaVe_B.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-5gSix3t2.js → vendor-icons-CrrAvF2g.js} +131 -111
- package/dashboard/dist/assets/vendor-icons-CrrAvF2g.js.map +1 -0
- package/dashboard/dist/assets/{workflows-zFmmxc08.js → workflows-CD7-d5w8.js} +2 -2
- package/dashboard/dist/assets/{workflows-zFmmxc08.js.map → workflows-CD7-d5w8.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-VSax0tKa.js → yaml-workflows-CIeymjZr.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-VSax0tKa.js.map → yaml-workflows-CIeymjZr.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/{mcp-runs.md → pipelines.md} +39 -25
- package/docs/dashboard.md +1 -1
- package/docs/sdk.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/BotPicker-CAowL3ib.js +0 -2
- package/dashboard/dist/assets/CapabilitiesPage-CSUKBvEN.js +0 -2
- package/dashboard/dist/assets/HomePage-BkMEYnRK.js +0 -2
- package/dashboard/dist/assets/HomePage-BkMEYnRK.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-o8xSCSVv.js +0 -2
- package/dashboard/dist/assets/McpOverview-C4man2br.js +0 -2
- package/dashboard/dist/assets/McpOverview-C4man2br.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-UR0bySPJ.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-bJl08JSG.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-bJl08JSG.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-i2FGJ6yf.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-i2FGJ6yf.js.map +0 -1
- package/dashboard/dist/assets/TopicDetailPage-DQkoAlsj.js +0 -9
- package/dashboard/dist/assets/TopicDetailPage-DQkoAlsj.js.map +0 -1
- package/dashboard/dist/assets/WorkflowExecutionPage-B6mBqWq6.js +0 -2
- package/dashboard/dist/assets/WorkflowExecutionPage-B6mBqWq6.js.map +0 -1
- package/dashboard/dist/assets/WorkflowPill-BkfIn8N3.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-BkfIn8N3.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-nXLTR0OO.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-BsO4L_SW.js +0 -2
- package/dashboard/dist/assets/index-Bb1ycul8.js +0 -2
- package/dashboard/dist/assets/index-BnB7G5bA.js.map +0 -1
- package/dashboard/dist/assets/index-BnVnJcXw.js +0 -2
- package/dashboard/dist/assets/index-BnVnJcXw.js.map +0 -1
- package/dashboard/dist/assets/index-CsagXf3M.js +0 -2
- package/dashboard/dist/assets/index-CsagXf3M.js.map +0 -1
- package/dashboard/dist/assets/index-DZI2L4ag.css +0 -1
- package/dashboard/dist/assets/index-EqKHsaVz.js +0 -2
- package/dashboard/dist/assets/index-ox042ec_.js +0 -15
- package/dashboard/dist/assets/index-ox042ec_.js.map +0 -1
- package/dashboard/dist/assets/mcp-runs-BN5MrKai.js +0 -2
- package/dashboard/dist/assets/mcp-runs-BN5MrKai.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-5gSix3t2.js.map +0 -1
- /package/build/routes/{mcp-runs.d.ts → pipelines.d.ts} +0 -0
- /package/build/services/{mcp-runs → pipelines}/enrichment.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/enrichment.js +0 -0
- /package/build/services/{mcp-runs → pipelines}/events.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/events.js +0 -0
- /package/build/services/{mcp-runs → pipelines}/execution-builder.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/execution-builder.js +0 -0
- /package/build/services/{mcp-runs → pipelines}/index.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/index.js +0 -0
- /package/build/services/{mcp-runs → pipelines}/queries.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/queries.js +0 -0
- /package/build/services/{mcp-runs → pipelines}/sql.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/types.d.ts +0 -0
- /package/build/services/{mcp-runs → pipelines}/types.js +0 -0
- /package/docs/api/sdk/{mcp-runs.md → pipelines.md} +0 -0
package/README.md
CHANGED
|
@@ -1,41 +1,14 @@
|
|
|
1
1
|
# Long Tail
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Write durable workflows in TypeScript. When they need a human, they escalate. When they need AI, they orchestrate. When a pattern repeats, they compile it away. Postgres is the engine.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install @hotmeshio/long-tail
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## How it works
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
- **Identity everywhere** — Workflows know who started them, whose credentials govern their execution, and what permissions are in play. IAM is not bolted on — it's woven into every activity call.
|
|
13
|
-
- **Human-in-the-loop** — When confidence is low, the workflow escalates. RBAC-scoped escalation chains route work to the right reviewer. Approval workflows, content review, document verification — the pattern is the same.
|
|
14
|
-
- **AI triage** — When human-in-the-loop teams can't resolve a request, AI takes over. Its tool calls are checkpointed. And when the fix works, it compiles into a deterministic pipeline for next time.
|
|
15
|
-
- **MCP tool orchestration** — Describe what you need. If you've registered the tools, the Pipeline Designer builds the workflow. Every compiled pipeline deploys as a reusable MCP tool.
|
|
16
|
-
|
|
17
|
-
A dashboard, REST API, and live event stream ship with the package. Use what you need.
|
|
18
|
-
|
|
19
|
-
## Start
|
|
20
|
-
|
|
21
|
-
Point at Postgres. Everything else is optional.
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
import { start } from '@hotmeshio/long-tail';
|
|
25
|
-
import * as myWorkflow from './workflows/my-workflow';
|
|
26
|
-
|
|
27
|
-
const lt = await start({
|
|
28
|
-
database: { host: 'localhost', port: 5432, user: 'postgres', password: 'password', database: 'mydb' },
|
|
29
|
-
workers: [{ taskQueue: 'default', workflow: myWorkflow.reviewContent }],
|
|
30
|
-
auth: { secret: process.env.JWT_SECRET },
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Dashboard at [http://localhost:3000](http://localhost:3000). The [boilerplate](https://github.com/hotmeshio/long-tail-boilerplate) has a working project with custom MCP servers, MinIO, and example workflows.
|
|
35
|
-
|
|
36
|
-
## Write a Durable Workflow
|
|
37
|
-
|
|
38
|
-
A workflow receives an envelope and returns a result. Each activity call checkpoints — no work is lost, no step runs twice.
|
|
11
|
+
You write a workflow function. Each activity call checkpoints to Postgres — if the process crashes, it resumes from the last completed step.
|
|
39
12
|
|
|
40
13
|
```typescript
|
|
41
14
|
import { Durable } from '@hotmeshio/hotmesh';
|
|
@@ -51,6 +24,7 @@ export async function reviewContent(envelope: LTEnvelope) {
|
|
|
51
24
|
return { type: 'return' as const, data: { approved: true, analysis } };
|
|
52
25
|
}
|
|
53
26
|
|
|
27
|
+
// Low confidence — escalate to a human reviewer
|
|
54
28
|
return {
|
|
55
29
|
type: 'escalation' as const,
|
|
56
30
|
role: 'reviewer',
|
|
@@ -60,32 +34,39 @@ export async function reviewContent(envelope: LTEnvelope) {
|
|
|
60
34
|
}
|
|
61
35
|
```
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
That's a complete workflow. It runs, checkpoints, and when confidence is low, it hands off to a human. The human resolves it through the dashboard or API, and the workflow completes. No separate queue system, no webhook callbacks — the escalation is part of the execution.
|
|
38
|
+
|
|
39
|
+
Activities are plain functions:
|
|
64
40
|
|
|
65
41
|
```typescript
|
|
66
|
-
// activities.ts
|
|
67
42
|
export async function analyzeContent(content: string) {
|
|
68
43
|
const result = await llm.classify(content);
|
|
69
44
|
return { confidence: result.confidence, flags: result.flags };
|
|
70
45
|
}
|
|
71
46
|
```
|
|
72
47
|
|
|
73
|
-
##
|
|
48
|
+
## Start
|
|
74
49
|
|
|
75
|
-
|
|
50
|
+
Point at Postgres. Everything else is optional.
|
|
76
51
|
|
|
77
|
-
```
|
|
78
|
-
|
|
52
|
+
```typescript
|
|
53
|
+
import { start } from '@hotmeshio/long-tail';
|
|
79
54
|
|
|
80
|
-
|
|
81
|
-
|
|
55
|
+
const lt = await start({
|
|
56
|
+
database: { host: 'localhost', port: 5432, user: 'postgres', password: 'password', database: 'mydb' },
|
|
57
|
+
workers: [{ taskQueue: 'default', workflow: reviewContent }],
|
|
58
|
+
});
|
|
82
59
|
```
|
|
83
60
|
|
|
84
|
-
|
|
61
|
+
Dashboard at [http://localhost:3000](http://localhost:3000). The [boilerplate](https://github.com/hotmeshio/long-tail-boilerplate) has a working project with workflows, MCP servers, and MinIO.
|
|
62
|
+
|
|
63
|
+
## The pattern
|
|
85
64
|
|
|
86
|
-
|
|
65
|
+
Most systems start with a durable workflow and stop there. Long Tail keeps going.
|
|
87
66
|
|
|
88
|
-
|
|
67
|
+
**Step 1 — Author a durable workflow.** Your function checkpoints to Postgres. It can sleep, branch, call child workflows, wait for signals. Standard durable execution.
|
|
68
|
+
|
|
69
|
+
**Step 2 — Certify it.** Promotion to certified adds interceptor guarantees: failures escalate instead of throwing, escalation chains route through RBAC-scoped roles, and every error is either handled or surfaced. It cannot silently fail.
|
|
89
70
|
|
|
90
71
|
```bash
|
|
91
72
|
curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
|
|
@@ -93,13 +74,17 @@ curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
|
|
|
93
74
|
-d '{ "invocable": true, "task_queue": "default", "default_role": "reviewer" }'
|
|
94
75
|
```
|
|
95
76
|
|
|
96
|
-
|
|
77
|
+
**Step 3 — React to events.** Workflows publish topics. Agents subscribe. When `activity.failed` fires, an automation can re-run the step, notify a team, or trigger a different workflow. The choreography is dynamic — add subscribers through the dashboard without changing code.
|
|
78
|
+
|
|
79
|
+
**Step 4 — Compile what repeats.** The Pipeline Designer takes a working execution and compiles it into a deterministic YAML DAG. No LLM at runtime, no replay overhead, typed inputs and outputs. It deploys as a reusable tool that any workflow or API call can invoke.
|
|
80
|
+
|
|
81
|
+
Over time, the system accumulates compiled tools. Problems that once required a human, then required AI reasoning, eventually require neither.
|
|
97
82
|
|
|
98
|
-
## Register MCP
|
|
83
|
+
## Register MCP tools
|
|
99
84
|
|
|
100
|
-
Long Tail connects to any MCP server
|
|
85
|
+
Long Tail connects to any MCP server. Registered tools become durable activities and are available to the Pipeline Designer.
|
|
101
86
|
|
|
102
|
-
**
|
|
87
|
+
**Existing package — no code:**
|
|
103
88
|
|
|
104
89
|
```bash
|
|
105
90
|
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
@@ -113,21 +98,14 @@ curl -X POST http://localhost:3000/api/mcp/servers \
|
|
|
113
98
|
}'
|
|
114
99
|
```
|
|
115
100
|
|
|
116
|
-
**
|
|
101
|
+
**Remote server — point at a URL:**
|
|
117
102
|
|
|
118
103
|
```bash
|
|
119
104
|
curl -X POST http://localhost:3000/api/mcp/servers \
|
|
120
|
-
-
|
|
121
|
-
-d '{
|
|
122
|
-
"name": "my-python-server",
|
|
123
|
-
"transport_type": "sse",
|
|
124
|
-
"transport_config": { "url": "http://python-service:8000/mcp" },
|
|
125
|
-
"tags": ["ml", "classification"],
|
|
126
|
-
"compile_hints": "Returns confidence scores. Use threshold 0.85 for auto-approve."
|
|
127
|
-
}'
|
|
105
|
+
-d '{ "name": "my-python-server", "transport_type": "sse", "transport_config": { "url": "http://python-service:8000/mcp" } }'
|
|
128
106
|
```
|
|
129
107
|
|
|
130
|
-
**
|
|
108
|
+
**In-process — write your own:**
|
|
131
109
|
|
|
132
110
|
```typescript
|
|
133
111
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
@@ -139,8 +117,8 @@ export function createImageToolsServer(): McpServer {
|
|
|
139
117
|
|
|
140
118
|
registerMcpTool(server, 'resize_image', 'Resize an image.', {
|
|
141
119
|
path: z.string().describe('Path to the image'),
|
|
142
|
-
width: z.number().optional()
|
|
143
|
-
height: z.number().optional()
|
|
120
|
+
width: z.number().optional(),
|
|
121
|
+
height: z.number().optional(),
|
|
144
122
|
}, async (args: any) => ({
|
|
145
123
|
content: [{ type: 'text', text: JSON.stringify(await resize(args)) }],
|
|
146
124
|
}));
|
|
@@ -152,36 +130,33 @@ export function createImageToolsServer(): McpServer {
|
|
|
152
130
|
```typescript
|
|
153
131
|
const lt = await start({
|
|
154
132
|
// ...
|
|
155
|
-
mcp: {
|
|
156
|
-
serverFactories: { 'image-tools': createImageToolsServer },
|
|
157
|
-
},
|
|
133
|
+
mcp: { serverFactories: { 'image-tools': createImageToolsServer } },
|
|
158
134
|
});
|
|
159
135
|
```
|
|
160
136
|
|
|
161
|
-
All three paths produce the same outcome: tools callable as durable activities.
|
|
137
|
+
All three paths produce the same outcome: tools callable as durable activities. See the [MCP guide](docs/mcp.md).
|
|
162
138
|
|
|
163
|
-
##
|
|
139
|
+
## Compile workflows
|
|
164
140
|
|
|
165
|
-
|
|
141
|
+
The `ltc` compiler scans TypeScript workflow files and compiles them to YAML DAGs — like `tsc` for workflows.
|
|
166
142
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
143
|
+
```bash
|
|
144
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
145
|
+
npx ltc compile workflows/
|
|
146
|
+
```
|
|
170
147
|
|
|
171
|
-
The
|
|
148
|
+
The source is the spec. The compiled YAML is the optimized execution. Both live in the repo. See the [Compiler Guide](docs/compiler.md).
|
|
172
149
|
|
|
173
|
-
## Full
|
|
150
|
+
## Full configuration
|
|
174
151
|
|
|
175
152
|
```typescript
|
|
176
153
|
const lt = await start({
|
|
177
154
|
database: { connectionString: process.env.DATABASE_URL },
|
|
178
|
-
workers: [{ taskQueue: 'default', workflow:
|
|
155
|
+
workers: [{ taskQueue: 'default', workflow: reviewContent }],
|
|
179
156
|
|
|
180
157
|
// Everything below is optional
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
serverFactories: { 'my-tools': createMyToolsServer },
|
|
184
|
-
},
|
|
158
|
+
seed: { admin: { externalId: 'admin', password: process.env.ADMIN_PASSWORD } },
|
|
159
|
+
mcp: { server: { enabled: true }, serverFactories: { 'my-tools': createMyToolsServer } },
|
|
185
160
|
escalation: { strategy: 'mcp' },
|
|
186
161
|
auth: { secret: process.env.JWT_SECRET },
|
|
187
162
|
telemetry: { honeycomb: { apiKey: process.env.HNY } },
|
|
@@ -190,56 +165,57 @@ const lt = await start({
|
|
|
190
165
|
});
|
|
191
166
|
```
|
|
192
167
|
|
|
193
|
-
##
|
|
168
|
+
## Embed in an existing app
|
|
194
169
|
|
|
195
|
-
Long Tail
|
|
170
|
+
Long Tail runs as an embedded package inside NestJS, Express, or any Node.js application. No extra HTTP server, no extra ports.
|
|
196
171
|
|
|
197
172
|
```typescript
|
|
198
173
|
import { start, createClient } from '@hotmeshio/long-tail';
|
|
199
174
|
|
|
200
|
-
await start({
|
|
175
|
+
const lt = await start({
|
|
201
176
|
database: { connectionString: process.env.DATABASE_URL },
|
|
202
177
|
server: { enabled: false },
|
|
203
|
-
|
|
178
|
+
seed: { admin: { externalId: 'system' } },
|
|
179
|
+
workers: [{ taskQueue: 'default', workflow: reviewContent }],
|
|
204
180
|
});
|
|
205
181
|
|
|
206
|
-
const
|
|
182
|
+
const client = createClient({ auth: { userId: lt.adminUserId } });
|
|
207
183
|
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
const result = await lt.escalations.claim({ id: 'esc_123', durationMinutes: 30 });
|
|
184
|
+
const tasks = await client.tasks.list({ status: 'completed', limit: 10 });
|
|
185
|
+
const result = await client.escalations.claim({ id: 'esc_123', durationMinutes: 30 });
|
|
211
186
|
```
|
|
212
187
|
|
|
213
|
-
|
|
188
|
+
Mount the dashboard at a subpath:
|
|
214
189
|
|
|
215
190
|
```typescript
|
|
216
|
-
|
|
217
|
-
console.log('done:', event.workflowId);
|
|
218
|
-
});
|
|
191
|
+
import { LTExpressAdapter } from '@hotmeshio/long-tail';
|
|
219
192
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
193
|
+
const adapter = new LTExpressAdapter();
|
|
194
|
+
adapter.setBasePath('/admin/longtail');
|
|
195
|
+
app.use('/admin/longtail', adapter.getRouter());
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Subscribe to events with callbacks:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
client.events.on('task.completed', (event) => console.log('done:', event.workflowId));
|
|
202
|
+
client.events.on('escalation.*', (event) => notifyTeam(event));
|
|
223
203
|
```
|
|
224
204
|
|
|
225
|
-
Every SDK call returns an `LTApiResult` — same status codes, same validation, same RBAC.
|
|
205
|
+
Every SDK call returns an `LTApiResult` — same status codes, same validation, same RBAC. See the [SDK guide](docs/sdk.md).
|
|
226
206
|
|
|
227
207
|
## Deployment
|
|
228
208
|
|
|
229
209
|
Three modes from the same codebase:
|
|
230
210
|
|
|
231
211
|
```typescript
|
|
232
|
-
//
|
|
212
|
+
// Standalone — dashboard + API + workers
|
|
233
213
|
await start({ database: { connectionString: process.env.DATABASE_URL } });
|
|
234
214
|
|
|
235
|
-
//
|
|
236
|
-
await start({
|
|
237
|
-
database: { connectionString: process.env.DATABASE_URL },
|
|
238
|
-
server: { enabled: false },
|
|
239
|
-
workers: [{ taskQueue: 'default', workflow: reviewContent.reviewContent }],
|
|
240
|
-
});
|
|
215
|
+
// Worker-only — no HTTP server
|
|
216
|
+
await start({ database: { connectionString: process.env.DATABASE_URL }, server: { enabled: false }, workers: [...] });
|
|
241
217
|
|
|
242
|
-
//
|
|
218
|
+
// Embedded — inside your app, SDK calls only
|
|
243
219
|
await start({ database: { connectionString: process.env.DATABASE_URL }, server: { enabled: false } });
|
|
244
220
|
const lt = createClient({ auth: { userId: 'service' } });
|
|
245
221
|
```
|
|
@@ -250,12 +226,12 @@ All modes share PostgreSQL and scale independently. See [Cloud Deployment](docs/
|
|
|
250
226
|
|
|
251
227
|
| Guide | What it covers |
|
|
252
228
|
|-------|---------------|
|
|
253
|
-
| [The Long Tail Story](docs/story.md) | Why this exists, what accumulates over time
|
|
229
|
+
| [The Long Tail Story](docs/story.md) | Why this exists, what accumulates over time |
|
|
254
230
|
| [Workflows](docs/workflows.md) | Activities, interceptor, escalation lifecycle, composition |
|
|
255
231
|
| [IAM](docs/iam.md) | Identity propagation, service accounts, credential exchange |
|
|
256
232
|
| [Dashboard](docs/dashboard.md) | Navigation, key pages, event feed |
|
|
257
233
|
| [MCP](docs/mcp.md) | Server registration, tool calls, human queue |
|
|
258
|
-
| [Compilation](docs/compilation.md) | Dynamic
|
|
234
|
+
| [Compilation](docs/compilation.md) | Dynamic to deterministic pipeline wizard |
|
|
259
235
|
| [Compiler](docs/compiler.md) | `ltc compile` — durable TypeScript to YAML DAGs |
|
|
260
236
|
| [CLI](docs/cli.md) | `ltc` — terminal access to workflows, escalations, knowledge, MCP |
|
|
261
237
|
| [Escalation Strategies](docs/escalation-strategies.md) | Default, MCP triage, custom handlers |
|
|
@@ -266,7 +242,7 @@ All modes share PostgreSQL and scale independently. See [Cloud Deployment](docs/
|
|
|
266
242
|
|
|
267
243
|
**Adapters:** [Auth](docs/auth.md) · [Events](docs/events.md) · [Telemetry](docs/telemetry.md) · [Logging](docs/logging.md) · [Maintenance](docs/maintenance.md) · [OAuth](docs/oauth-and-delegation.md)
|
|
268
244
|
|
|
269
|
-
**HTTP API:** [Workflows](docs/api/http/workflows.md) · [Tasks](docs/api/http/tasks.md) · [Escalations](docs/api/http/escalations.md) · [YAML Workflows](docs/api/http/yaml-workflows.md) · [Users](docs/api/http/users.md) · [Roles](docs/api/http/roles.md) · [Service Accounts](docs/api/http/service-accounts.md) · [MCP Servers](docs/api/http/mcp-servers.md) · [
|
|
245
|
+
**HTTP API:** [Workflows](docs/api/http/workflows.md) · [Tasks](docs/api/http/tasks.md) · [Escalations](docs/api/http/escalations.md) · [YAML Workflows](docs/api/http/yaml-workflows.md) · [Users](docs/api/http/users.md) · [Roles](docs/api/http/roles.md) · [Service Accounts](docs/api/http/service-accounts.md) · [MCP Servers](docs/api/http/mcp-servers.md) · [Pipelines](docs/api/http/pipelines.md) · [Exports](docs/api/http/exports.md)
|
|
270
246
|
|
|
271
247
|
**SDK:** [Overview](docs/sdk.md) · [Workflows](docs/api/sdk/workflows.md) · [Tasks](docs/api/sdk/tasks.md) · [Escalations](docs/api/sdk/escalations.md) · [YAML Workflows](docs/api/sdk/yaml-workflows.md) · [MCP](docs/api/sdk/mcp.md) · [Events](docs/api/sdk/events.md)
|
|
272
248
|
|
package/build/api/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export * as users from './users';
|
|
|
6
6
|
export * as roles from './roles';
|
|
7
7
|
export * as auth from './auth';
|
|
8
8
|
export * as mcp from './mcp';
|
|
9
|
-
export * as
|
|
9
|
+
export * as pipelines from './pipelines';
|
|
10
|
+
export * as mcpRuns from './pipelines';
|
|
10
11
|
export * as insight from './insight';
|
|
11
12
|
export * as settings from './settings';
|
|
12
13
|
export * as exports from './exports';
|
package/build/api/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.maintenance = exports.namespaces = exports.dba = exports.workflowSets = exports.botAccounts = exports.controlplane = exports.exports = exports.settings = exports.insight = exports.mcpRuns = exports.mcp = exports.auth = exports.roles = exports.users = exports.yamlWorkflows = exports.workflows = exports.escalations = exports.tasks = void 0;
|
|
36
|
+
exports.maintenance = exports.namespaces = exports.dba = exports.workflowSets = exports.botAccounts = exports.controlplane = exports.exports = exports.settings = exports.insight = exports.mcpRuns = exports.pipelines = exports.mcp = exports.auth = exports.roles = exports.users = exports.yamlWorkflows = exports.workflows = exports.escalations = exports.tasks = void 0;
|
|
37
37
|
exports.tasks = __importStar(require("./tasks"));
|
|
38
38
|
exports.escalations = __importStar(require("./escalations"));
|
|
39
39
|
exports.workflows = __importStar(require("./workflows"));
|
|
@@ -42,7 +42,8 @@ exports.users = __importStar(require("./users"));
|
|
|
42
42
|
exports.roles = __importStar(require("./roles"));
|
|
43
43
|
exports.auth = __importStar(require("./auth"));
|
|
44
44
|
exports.mcp = __importStar(require("./mcp"));
|
|
45
|
-
exports.
|
|
45
|
+
exports.pipelines = __importStar(require("./pipelines"));
|
|
46
|
+
exports.mcpRuns = __importStar(require("./pipelines")); // backward-compat alias
|
|
46
47
|
exports.insight = __importStar(require("./insight"));
|
|
47
48
|
exports.settings = __importStar(require("./settings"));
|
|
48
49
|
exports.exports = __importStar(require("./exports"));
|
|
@@ -43,3 +43,21 @@ export declare function getJobExecution(input: {
|
|
|
43
43
|
jobId: string;
|
|
44
44
|
app_id: string;
|
|
45
45
|
}): Promise<LTApiResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Interrupt a running pipeline job via HotMesh.interrupt().
|
|
48
|
+
*
|
|
49
|
+
* This is the pipeline equivalent of the durable terminate endpoint.
|
|
50
|
+
* Pipelines run as raw HotMesh YAML DAGs, not through the Durable
|
|
51
|
+
* abstraction, so they require the app_id (namespace) and topic
|
|
52
|
+
* to locate the correct engine instance.
|
|
53
|
+
*
|
|
54
|
+
* @param input.jobId — HotMesh job ID (workflow_id)
|
|
55
|
+
* @param input.topic — workflow entity/topic name
|
|
56
|
+
* @param input.app_id — HotMesh namespace (e.g. "hmsh", "longtail")
|
|
57
|
+
* @returns `{ status: 200, data: { interrupted: true } }` or error
|
|
58
|
+
*/
|
|
59
|
+
export declare function interruptJob(input: {
|
|
60
|
+
jobId: string;
|
|
61
|
+
topic: string;
|
|
62
|
+
app_id: string;
|
|
63
|
+
}): Promise<LTApiResult>;
|
|
@@ -3,8 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.listEntities = listEntities;
|
|
4
4
|
exports.listJobs = listJobs;
|
|
5
5
|
exports.getJobExecution = getJobExecution;
|
|
6
|
+
exports.interruptJob = interruptJob;
|
|
6
7
|
const hotmesh_utils_1 = require("../services/hotmesh-utils");
|
|
7
|
-
const
|
|
8
|
+
const pipelines_1 = require("../services/pipelines");
|
|
9
|
+
const controlplane_1 = require("../services/controlplane");
|
|
8
10
|
/**
|
|
9
11
|
* List distinct entity types for an app (HotMesh namespace).
|
|
10
12
|
*
|
|
@@ -16,7 +18,7 @@ async function listEntities(input) {
|
|
|
16
18
|
if (!input.app_id) {
|
|
17
19
|
return { status: 400, error: 'app_id query parameter is required' };
|
|
18
20
|
}
|
|
19
|
-
const entities = await (0,
|
|
21
|
+
const entities = await (0, pipelines_1.listEntities)(input.app_id);
|
|
20
22
|
return { status: 200, data: { entities } };
|
|
21
23
|
}
|
|
22
24
|
catch (err) {
|
|
@@ -42,7 +44,7 @@ async function listJobs(input) {
|
|
|
42
44
|
if (!input.app_id) {
|
|
43
45
|
return { status: 400, error: 'app_id query parameter is required' };
|
|
44
46
|
}
|
|
45
|
-
const result = await (0,
|
|
47
|
+
const result = await (0, pipelines_1.listJobs)({
|
|
46
48
|
rawAppId: input.app_id,
|
|
47
49
|
limit: input.limit,
|
|
48
50
|
offset: input.offset,
|
|
@@ -78,7 +80,7 @@ async function getJobExecution(input) {
|
|
|
78
80
|
}
|
|
79
81
|
const appId = (0, hotmesh_utils_1.sanitizeAppId)(input.app_id);
|
|
80
82
|
const schema = (0, hotmesh_utils_1.quoteSchema)(appId);
|
|
81
|
-
const execution = await (0,
|
|
83
|
+
const execution = await (0, pipelines_1.buildExecution)(input.jobId, appId, schema);
|
|
82
84
|
return { status: 200, data: execution };
|
|
83
85
|
}
|
|
84
86
|
catch (err) {
|
|
@@ -89,3 +91,33 @@ async function getJobExecution(input) {
|
|
|
89
91
|
return { status: 500, error: msg };
|
|
90
92
|
}
|
|
91
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Interrupt a running pipeline job via HotMesh.interrupt().
|
|
96
|
+
*
|
|
97
|
+
* This is the pipeline equivalent of the durable terminate endpoint.
|
|
98
|
+
* Pipelines run as raw HotMesh YAML DAGs, not through the Durable
|
|
99
|
+
* abstraction, so they require the app_id (namespace) and topic
|
|
100
|
+
* to locate the correct engine instance.
|
|
101
|
+
*
|
|
102
|
+
* @param input.jobId — HotMesh job ID (workflow_id)
|
|
103
|
+
* @param input.topic — workflow entity/topic name
|
|
104
|
+
* @param input.app_id — HotMesh namespace (e.g. "hmsh", "longtail")
|
|
105
|
+
* @returns `{ status: 200, data: { interrupted: true } }` or error
|
|
106
|
+
*/
|
|
107
|
+
async function interruptJob(input) {
|
|
108
|
+
try {
|
|
109
|
+
if (!input.app_id) {
|
|
110
|
+
return { status: 400, error: 'app_id is required' };
|
|
111
|
+
}
|
|
112
|
+
if (!input.topic) {
|
|
113
|
+
return { status: 400, error: 'topic is required' };
|
|
114
|
+
}
|
|
115
|
+
const appId = (0, hotmesh_utils_1.sanitizeAppId)(input.app_id);
|
|
116
|
+
const engine = await (0, controlplane_1.getEngine)(appId);
|
|
117
|
+
await engine.interrupt(input.topic, input.jobId);
|
|
118
|
+
return { status: 200, data: { interrupted: true, jobId: input.jobId } };
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
return { status: 500, error: err.message };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -40,7 +40,7 @@ const configService = __importStar(require("../../services/config"));
|
|
|
40
40
|
const cron_1 = require("../../services/cron");
|
|
41
41
|
const db_1 = require("../../lib/db");
|
|
42
42
|
const registry_1 = require("../../services/workers/registry");
|
|
43
|
-
const sql_1 = require("../../services/
|
|
43
|
+
const sql_1 = require("../../services/pipelines/sql");
|
|
44
44
|
/**
|
|
45
45
|
* List active workflow workers with their registration status.
|
|
46
46
|
*
|
package/build/routes/index.js
CHANGED
|
@@ -20,7 +20,7 @@ const mcp_1 = __importDefault(require("./mcp"));
|
|
|
20
20
|
const insight_1 = __importDefault(require("./insight"));
|
|
21
21
|
const yaml_workflows_1 = __importDefault(require("./yaml-workflows"));
|
|
22
22
|
const settings_1 = __importDefault(require("./settings"));
|
|
23
|
-
const
|
|
23
|
+
const pipelines_1 = __importDefault(require("./pipelines"));
|
|
24
24
|
const namespaces_1 = __importDefault(require("./namespaces"));
|
|
25
25
|
const files_1 = __importDefault(require("./files"));
|
|
26
26
|
const file_browser_1 = __importDefault(require("./file-browser"));
|
|
@@ -54,7 +54,8 @@ router.use('/dba', dba_1.default);
|
|
|
54
54
|
router.use('/mcp', mcp_1.default);
|
|
55
55
|
router.use('/insight', insight_1.default);
|
|
56
56
|
router.use('/yaml-workflows', yaml_workflows_1.default);
|
|
57
|
-
router.use('/
|
|
57
|
+
router.use('/pipelines', pipelines_1.default);
|
|
58
|
+
router.use('/mcp-runs', pipelines_1.default); // backward-compat alias
|
|
58
59
|
router.use('/namespaces', namespaces_1.default);
|
|
59
60
|
router.use('/file-browser', file_browser_1.default);
|
|
60
61
|
router.use('/controlplane', controlplane_1.default);
|
|
@@ -34,11 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const express_1 = require("express");
|
|
37
|
-
const api = __importStar(require("../api/
|
|
37
|
+
const api = __importStar(require("../api/pipelines"));
|
|
38
38
|
const router = (0, express_1.Router)();
|
|
39
39
|
// ── Routes ───────────────────────────────────────────────────────────────────
|
|
40
40
|
/**
|
|
41
|
-
* GET /api/
|
|
41
|
+
* GET /api/pipelines/entities
|
|
42
42
|
* Return distinct entity (tool) names from {appId}.jobs,
|
|
43
43
|
* supplemented with graph_topics from yaml_workflows for this app_id.
|
|
44
44
|
*/
|
|
@@ -49,7 +49,7 @@ router.get('/entities', async (req, res) => {
|
|
|
49
49
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
50
50
|
});
|
|
51
51
|
/**
|
|
52
|
-
* GET /api/
|
|
52
|
+
* GET /api/pipelines
|
|
53
53
|
* List jobs from {appId}.jobs for a given app_id.
|
|
54
54
|
*/
|
|
55
55
|
router.get('/', async (req, res) => {
|
|
@@ -66,7 +66,7 @@ router.get('/', async (req, res) => {
|
|
|
66
66
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
67
67
|
});
|
|
68
68
|
/**
|
|
69
|
-
* GET /api/
|
|
69
|
+
* GET /api/pipelines/:jobId/execution
|
|
70
70
|
* Export execution details for a specific HotMesh pipeline job.
|
|
71
71
|
*/
|
|
72
72
|
router.get('/:jobId/execution', async (req, res) => {
|
|
@@ -76,4 +76,17 @@ router.get('/:jobId/execution', async (req, res) => {
|
|
|
76
76
|
});
|
|
77
77
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
78
78
|
});
|
|
79
|
+
/**
|
|
80
|
+
* POST /api/pipelines/:jobId/interrupt
|
|
81
|
+
* Interrupt a running pipeline job via HotMesh.interrupt().
|
|
82
|
+
* Body: { topic, app_id }
|
|
83
|
+
*/
|
|
84
|
+
router.post('/:jobId/interrupt', async (req, res) => {
|
|
85
|
+
const result = await api.interruptJob({
|
|
86
|
+
jobId: req.params.jobId,
|
|
87
|
+
topic: req.body.topic,
|
|
88
|
+
app_id: req.body.app_id,
|
|
89
|
+
});
|
|
90
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
91
|
+
});
|
|
79
92
|
exports.default = router;
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as usersApi from '../api/users';
|
|
|
6
6
|
import * as rolesApi from '../api/roles';
|
|
7
7
|
import * as authApi from '../api/auth';
|
|
8
8
|
import * as mcpApi from '../api/mcp';
|
|
9
|
-
import * as
|
|
9
|
+
import * as pipelinesApi from '../api/pipelines';
|
|
10
10
|
import * as insightApi from '../api/insight';
|
|
11
11
|
import * as settingsApi from '../api/settings';
|
|
12
12
|
import * as exportsApi from '../api/exports';
|
|
@@ -241,10 +241,17 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
241
241
|
execute_as?: string;
|
|
242
242
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
243
243
|
};
|
|
244
|
+
pipelines: {
|
|
245
|
+
listEntities: typeof pipelinesApi.listEntities;
|
|
246
|
+
listJobs: typeof pipelinesApi.listJobs;
|
|
247
|
+
getExecution: typeof pipelinesApi.getJobExecution;
|
|
248
|
+
interrupt: typeof pipelinesApi.interruptJob;
|
|
249
|
+
};
|
|
250
|
+
/** @deprecated Use `pipelines` */
|
|
244
251
|
mcpRuns: {
|
|
245
|
-
listEntities: typeof
|
|
246
|
-
listJobs: typeof
|
|
247
|
-
getExecution: typeof
|
|
252
|
+
listEntities: typeof pipelinesApi.listEntities;
|
|
253
|
+
listJobs: typeof pipelinesApi.listJobs;
|
|
254
|
+
getExecution: typeof pipelinesApi.getJobExecution;
|
|
248
255
|
};
|
|
249
256
|
insight: {
|
|
250
257
|
mcpQuery: (input: {
|
package/build/sdk/index.js
CHANGED
|
@@ -42,7 +42,7 @@ const usersApi = __importStar(require("../api/users"));
|
|
|
42
42
|
const rolesApi = __importStar(require("../api/roles"));
|
|
43
43
|
const authApi = __importStar(require("../api/auth"));
|
|
44
44
|
const mcpApi = __importStar(require("../api/mcp"));
|
|
45
|
-
const
|
|
45
|
+
const pipelinesApi = __importStar(require("../api/pipelines"));
|
|
46
46
|
const insightApi = __importStar(require("../api/insight"));
|
|
47
47
|
const settingsApi = __importStar(require("../api/settings"));
|
|
48
48
|
const exportsApi = __importStar(require("../api/exports"));
|
|
@@ -208,11 +208,18 @@ function createClient(options = {}) {
|
|
|
208
208
|
listTools: mcpApi.listMcpServerTools,
|
|
209
209
|
callTool: bindOptionalAuth(mcpApi.callMcpTool, auth),
|
|
210
210
|
},
|
|
211
|
-
// ──
|
|
211
|
+
// ── Pipelines ──────────────────────────────────────────────────────────
|
|
212
|
+
pipelines: {
|
|
213
|
+
listEntities: pipelinesApi.listEntities,
|
|
214
|
+
listJobs: pipelinesApi.listJobs,
|
|
215
|
+
getExecution: pipelinesApi.getJobExecution,
|
|
216
|
+
interrupt: pipelinesApi.interruptJob,
|
|
217
|
+
},
|
|
218
|
+
/** @deprecated Use `pipelines` */
|
|
212
219
|
mcpRuns: {
|
|
213
|
-
listEntities:
|
|
214
|
-
listJobs:
|
|
215
|
-
getExecution:
|
|
220
|
+
listEntities: pipelinesApi.listEntities,
|
|
221
|
+
listJobs: pipelinesApi.listJobs,
|
|
222
|
+
getExecution: pipelinesApi.getJobExecution,
|
|
216
223
|
},
|
|
217
224
|
// ── Insight ────────────────────────────────────────────────────────────
|
|
218
225
|
insight: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// SQL templates for
|
|
2
|
+
// SQL templates for pipeline queries.
|
|
3
3
|
// Schema placeholders (${schema}) are interpolated at call time
|
|
4
4
|
// because Postgres does not support parameterized schema names.
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
package/build/start/adapters.js
CHANGED
|
@@ -56,14 +56,11 @@ function registerAdapters(startConfig) {
|
|
|
56
56
|
// CallbackEventAdapter is registered later in start/workers.ts
|
|
57
57
|
// so it can be wired to the NATS bridge before connect().
|
|
58
58
|
// Do NOT register a duplicate here.
|
|
59
|
-
// Maintenance
|
|
60
|
-
if (startConfig.maintenance ===
|
|
61
|
-
// Disabled
|
|
62
|
-
}
|
|
63
|
-
else if (startConfig.maintenance === true || startConfig.maintenance === undefined) {
|
|
59
|
+
// Maintenance — opt-in only. Pass `true` for defaults or a config object.
|
|
60
|
+
if (startConfig.maintenance === true) {
|
|
64
61
|
maintenance_1.maintenanceRegistry.register(maintenance_2.defaultMaintenanceConfig);
|
|
65
62
|
}
|
|
66
|
-
else {
|
|
63
|
+
else if (startConfig.maintenance) {
|
|
67
64
|
maintenance_1.maintenanceRegistry.register(startConfig.maintenance);
|
|
68
65
|
}
|
|
69
66
|
// Escalation strategy
|
package/build/start/server.js
CHANGED
|
@@ -31,9 +31,12 @@ function startServer() {
|
|
|
31
31
|
const dashboardDist = (0, fs_1.existsSync)(devDist) ? devDist : prodDist;
|
|
32
32
|
if ((0, fs_1.existsSync)(dashboardDist)) {
|
|
33
33
|
app.use(express_1.default.static(dashboardDist));
|
|
34
|
-
// SPA fallback —
|
|
34
|
+
// SPA fallback — inject <base href="/"> so relative asset paths
|
|
35
|
+
// resolve from root regardless of route depth (e.g. /admin/users).
|
|
36
|
+
const rawHtml = (0, fs_1.readFileSync)(path_1.default.join(dashboardDist, 'index.html'), 'utf-8');
|
|
37
|
+
const indexHtml = rawHtml.replace('<head>', '<head><base href="/">');
|
|
35
38
|
app.get('/{*splat}', (_req, res) => {
|
|
36
|
-
res.
|
|
39
|
+
res.type('html').send(indexHtml);
|
|
37
40
|
});
|
|
38
41
|
logger_1.loggerRegistry.info(`[long-tail] Dashboard: http://localhost:${config_1.config.PORT}/`);
|
|
39
42
|
}
|