@hotmeshio/long-tail 0.1.13 → 0.1.14
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/build/api/files.d.ts +13 -0
- package/build/api/files.js +44 -0
- package/build/api/mcp-runs.d.ts +2 -0
- package/build/api/mcp-runs.js +2 -0
- package/build/api/workflow-sets.d.ts +11 -0
- package/build/api/workflow-sets.js +62 -0
- package/build/api/yaml-workflows.d.ts +9 -0
- package/build/api/yaml-workflows.js +40 -11
- package/build/lib/storage/local.d.ts +15 -0
- package/build/lib/storage/local.js +63 -0
- package/build/lib/storage/mime.d.ts +4 -0
- package/build/lib/storage/mime.js +31 -0
- package/build/lib/storage/s3.d.ts +16 -0
- package/build/lib/storage/s3.js +70 -0
- package/build/lib/storage/types.d.ts +18 -0
- package/build/modules/utils.d.ts +73 -0
- package/build/modules/utils.js +84 -0
- package/build/routes/file-browser.d.ts +2 -0
- package/build/routes/file-browser.js +112 -0
- package/build/routes/files.js +25 -17
- package/build/routes/index.js +2 -0
- package/build/routes/mcp-runs.js +2 -0
- package/build/routes/workflow-sets.js +9 -0
- package/build/routes/yaml-workflows/deployment.js +8 -0
- package/build/services/insight/index.d.ts +13 -0
- package/build/services/insight/index.js +4 -7
- package/build/services/insight/prompts.d.ts +1 -1
- package/build/services/insight/prompts.js +1 -1
- package/build/services/mcp-runs/queries.d.ts +2 -0
- package/build/services/mcp-runs/queries.js +11 -1
- package/build/services/mcp-runs/sql.d.ts +1 -1
- package/build/services/mcp-runs/sql.js +2 -2
- package/build/services/workflow-sets/db.d.ts +1 -0
- package/build/services/workflow-sets/db.js +6 -0
- package/build/services/workflow-sets/index.d.ts +1 -1
- package/build/services/workflow-sets/index.js +2 -1
- package/build/services/workflow-sets/sql.d.ts +1 -0
- package/build/services/workflow-sets/sql.js +6 -1
- package/build/services/yaml-workflow/db.d.ts +12 -0
- package/build/services/yaml-workflow/db.js +18 -0
- package/build/services/yaml-workflow/generator.js +4 -4
- package/build/services/yaml-workflow/pipeline/build/index.d.ts +2 -1
- package/build/services/yaml-workflow/pipeline/build/index.js +3 -2
- package/build/services/yaml-workflow/pipeline/build/utils.d.ts +0 -2
- package/build/services/yaml-workflow/pipeline/build/utils.js +0 -8
- package/build/services/yaml-workflow/sql.d.ts +2 -1
- package/build/services/yaml-workflow/sql.js +10 -3
- package/build/system/activities/schema-exchange.d.ts +50 -0
- package/build/system/activities/schema-exchange.js +210 -0
- package/build/system/activities/sql.d.ts +1 -1
- package/build/system/activities/sql.js +12 -1
- package/build/system/index.js +1 -0
- package/build/system/mcp-servers/knowledge.js +35 -6
- package/build/system/mcp-servers/schema-exchange.d.ts +4 -0
- package/build/system/mcp-servers/schema-exchange.js +93 -0
- package/build/system/seed/server-definitions.d.ts +112 -1
- package/build/system/seed/server-definitions.js +37 -0
- package/build/system/seed/tool-manifests-data.d.ts +87 -0
- package/build/system/seed/tool-manifests-data.js +37 -1
- package/build/system/seed/tool-manifests-knowledge.d.ts +9 -1
- package/build/system/seed/tool-manifests-knowledge.js +6 -5
- package/build/system/workflows/mcp-workflow-builder/prompts.d.ts +1 -1
- package/build/system/workflows/mcp-workflow-builder/prompts.js +21 -20
- package/build/system/workflows/mcp-workflow-planner/activities/persist.d.ts +1 -1
- package/build/system/workflows/mcp-workflow-planner/activities/persist.js +3 -3
- package/build/system/workflows/mcp-workflow-planner/index.js +39 -5
- package/build/system/workflows/mcp-workflow-planner/prompts.d.ts +1 -1
- package/build/system/workflows/mcp-workflow-planner/prompts.js +3 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/dashboard/dist/assets/{AdminDashboard-DUrSBQOl.js → AdminDashboard-Cngijp4Q.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DUrSBQOl.js.map → AdminDashboard-Cngijp4Q.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-Dbd1qUK_.js → AvailableEscalationsPage-CpBfGV1h.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-Dbd1qUK_.js.map → AvailableEscalationsPage-CpBfGV1h.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-Cg5iNEkm.js → BotPicker-B8Uvw9Si.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Cg5iNEkm.js.map → BotPicker-B8Uvw9Si.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-Kd9UIyeU.js → CollapsibleSection-DiFPuWOY.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-Kd9UIyeU.js.map → CollapsibleSection-DiFPuWOY.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-DZMgmlof.js → ConfirmDeleteModal-CpXG9uyu.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-DZMgmlof.js.map → ConfirmDeleteModal-CpXG9uyu.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-cPFTRm8q.js → CopyableId-DKsTR9lK.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-cPFTRm8q.js.map → CopyableId-DKsTR9lK.js.map} +1 -1
- package/dashboard/dist/assets/CredentialsPage-DlS7Kf40.js +2 -0
- package/dashboard/dist/assets/{CredentialsPage-DJablIbs.js.map → CredentialsPage-DlS7Kf40.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-NgIP6YDW.js → CustomDurationPicker-B-9eW3pm.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-NgIP6YDW.js.map → CustomDurationPicker-B-9eW3pm.js.map} +1 -1
- package/dashboard/dist/assets/{DataTable-CTRhTAfT.js → DataTable-DkOokbtL.js} +2 -2
- package/dashboard/dist/assets/{DataTable-CTRhTAfT.js.map → DataTable-DkOokbtL.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-HcSJ_MMs.js → ElapsedCell-DVtHqM-5.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-HcSJ_MMs.js.map → ElapsedCell-DVtHqM-5.js.map} +1 -1
- package/dashboard/dist/assets/{EmptyState-joNbd4gg.js → EmptyState-C7KIMIbE.js} +2 -2
- package/dashboard/dist/assets/{EmptyState-joNbd4gg.js.map → EmptyState-C7KIMIbE.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-DpXDnQux.js → EscalationsOverview-BMKBlkPx.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-DpXDnQux.js.map → EscalationsOverview-BMKBlkPx.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CYem3v8n.js → EventTable-BYZ5OVdQ.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CYem3v8n.js.map → EventTable-BYZ5OVdQ.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-BiO8SOzc.js → FilterBar-C5r3n6YO.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-BiO8SOzc.js.map → FilterBar-C5r3n6YO.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-6yRDh2e9.js → ListToolbar-BGUajIsW.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-6yRDh2e9.js.map → ListToolbar-BGUajIsW.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CUgSxkQe.js → McpOverview-B_kJYHea.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CUgSxkQe.js.map → McpOverview-B_kJYHea.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-Czsmovqw.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-Czsmovqw.js.map +1 -0
- package/dashboard/dist/assets/McpQueryPage-BgAq_bQg.js +2 -0
- package/dashboard/dist/assets/{McpQueryPage-lV6kfDG5.js.map → McpQueryPage-BgAq_bQg.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-B8c0OszR.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-B8c0OszR.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-BY8C6k78.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-BY8C6k78.js.map +1 -0
- package/dashboard/dist/assets/{Modal-BuTvD0pz.js → Modal-E1yRnCeW.js} +2 -2
- package/dashboard/dist/assets/{Modal-BuTvD0pz.js.map → Modal-E1yRnCeW.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-C8MSTzey.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-C9SSV96T.js.map → OperatorDashboard-C8MSTzey.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-BcTVF9ul.js → PageHeader-Cm5HBQF_.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-BcTVF9ul.js.map → PageHeader-Cm5HBQF_.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-BI7JG5x6.js → PageHeaderWithStats-CNmWJFSN.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-BI7JG5x6.js.map → PageHeaderWithStats-CNmWJFSN.js.map} +1 -1
- package/dashboard/dist/assets/{PriorityBadge-DqVaOU65.js → PriorityBadge-HSI4RVhs.js} +2 -2
- package/dashboard/dist/assets/{PriorityBadge-DqVaOU65.js.map → PriorityBadge-HSI4RVhs.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-hFMhf9qa.js → ProcessDetailPage-Dln8622H.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-hFMhf9qa.js.map → ProcessDetailPage-Dln8622H.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-ByVoBCQ3.js → ProcessesListPage-bIsd9N_h.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-ByVoBCQ3.js.map → ProcessesListPage-bIsd9N_h.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-D9ZIkYiu.js → RolePill-BVUp2bF0.js} +2 -2
- package/dashboard/dist/assets/{RolePill-D9ZIkYiu.js.map → RolePill-BVUp2bF0.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-kH-Njt25.js +2 -0
- package/dashboard/dist/assets/{RolesPage-SMedMuqa.js.map → RolesPage-kH-Njt25.js.map} +1 -1
- package/dashboard/dist/assets/{RowActions-yDhwwDbU.js → RowActions-DbUJPfaW.js} +2 -2
- package/dashboard/dist/assets/{RowActions-yDhwwDbU.js.map → RowActions-DbUJPfaW.js.map} +1 -1
- package/dashboard/dist/assets/{StatCard-BrBnQFxh.js → StatCard-Bs3JbyAz.js} +2 -2
- package/dashboard/dist/assets/{StatCard-BrBnQFxh.js.map → StatCard-Bs3JbyAz.js.map} +1 -1
- package/dashboard/dist/assets/{StatusBadge-xgb-lZku.js → StatusBadge-CakDdsCw.js} +2 -2
- package/dashboard/dist/assets/{StatusBadge-xgb-lZku.js.map → StatusBadge-CakDdsCw.js.map} +1 -1
- package/dashboard/dist/assets/{StepIndicator-B9ps2SvM.js → StepIndicator-Cd_SG_yA.js} +2 -2
- package/dashboard/dist/assets/{StepIndicator-B9ps2SvM.js.map → StepIndicator-Cd_SG_yA.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-DTIjBKN3.js → StickyPagination-Bz0C18nC.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-DTIjBKN3.js.map → StickyPagination-Bz0C18nC.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-RK4Yu66z.js → SwimlaneTimeline-Cfe-xQRX.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-RK4Yu66z.js.map → SwimlaneTimeline-Cfe-xQRX.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-CdNUuqk4.js → TagInput-ClFhXG-U.js} +2 -2
- package/dashboard/dist/assets/{TagInput-CdNUuqk4.js.map → TagInput-ClFhXG-U.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-C-nzaNea.js → TaskDetailPage-SuMBdARt.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-C-nzaNea.js.map → TaskDetailPage-SuMBdARt.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-Lvr2-NzS.js → TaskQueuePill-lJR1JW_W.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-Lvr2-NzS.js.map → TaskQueuePill-lJR1JW_W.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DSUmD84y.js → TasksListPage-Dkq1Vtbt.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DSUmD84y.js.map → TasksListPage-Dkq1Vtbt.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BZdLdrIh.js → TimeAgo-DgfDZ1pl.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BZdLdrIh.js.map → TimeAgo-DgfDZ1pl.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-QX_0i5FK.js → TimestampCell-MpHZ1hMD.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-QX_0i5FK.js.map → TimestampCell-MpHZ1hMD.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DyZMXcBm.js → UserName-DqsosA4B.js} +2 -2
- package/dashboard/dist/assets/{UserName-DyZMXcBm.js.map → UserName-DqsosA4B.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DjVxfZaF.js → WorkflowExecutionPage-CVlg38C3.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DjVxfZaF.js.map → WorkflowExecutionPage-CVlg38C3.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowPill-CRpZhjGR.js +2 -0
- package/dashboard/dist/assets/WorkflowPill-CRpZhjGR.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsDashboard-DZjuiFZ0.js → WorkflowsDashboard-Ugzbs8mV.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DZjuiFZ0.js.map → WorkflowsDashboard-Ugzbs8mV.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-CLnLRpOu.js → WorkflowsOverview-CIp_lTNl.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-CLnLRpOu.js.map → WorkflowsOverview-CIp_lTNl.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-BICF0fRO.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-BICF0fRO.js.map +1 -0
- package/dashboard/dist/assets/{bots-DIM6lBoY.js → bots-DPfUpVqI.js} +2 -2
- package/dashboard/dist/assets/{bots-DIM6lBoY.js.map → bots-DPfUpVqI.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-JOTuOqjq.js → escalation-RrCDbMC3.js} +2 -2
- package/dashboard/dist/assets/{escalation-JOTuOqjq.js.map → escalation-RrCDbMC3.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-CDGa9wsD.js +2 -0
- package/dashboard/dist/assets/{escalation-columns-Cyg58nkg.js.map → escalation-columns-CDGa9wsD.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-B1BDxBZd.js → helpers-ZSKqdkdS.js} +2 -2
- package/dashboard/dist/assets/{helpers-B1BDxBZd.js.map → helpers-ZSKqdkdS.js.map} +1 -1
- package/dashboard/dist/assets/helpers-rMEcLwKs.js +2 -0
- package/dashboard/dist/assets/helpers-rMEcLwKs.js.map +1 -0
- package/dashboard/dist/assets/{index-DDYFpi4l.js → index-ABcJHHlN.js} +2 -2
- package/dashboard/dist/assets/{index-DDYFpi4l.js.map → index-ABcJHHlN.js.map} +1 -1
- package/dashboard/dist/assets/{index-D1wVX50Z.js → index-B91h_jZ0.js} +2 -2
- package/dashboard/dist/assets/{index-D1wVX50Z.js.map → index-B91h_jZ0.js.map} +1 -1
- package/dashboard/dist/assets/{index-BcR6PfpY.js → index-BbI2dzhJ.js} +2 -2
- package/dashboard/dist/assets/{index-BcR6PfpY.js.map → index-BbI2dzhJ.js.map} +1 -1
- package/dashboard/dist/assets/{index-BizfauqT.js → index-BmVCyB6C.js} +4 -4
- package/dashboard/dist/assets/{index-BizfauqT.js.map → index-BmVCyB6C.js.map} +1 -1
- package/dashboard/dist/assets/index-C1E5GTs9.js +2 -0
- package/dashboard/dist/assets/index-C1E5GTs9.js.map +1 -0
- package/dashboard/dist/assets/{index-Cf60K3x9.js → index-C90ZPzXk.js} +2 -2
- package/dashboard/dist/assets/{index-Cf60K3x9.js.map → index-C90ZPzXk.js.map} +1 -1
- package/dashboard/dist/assets/{index-BYZX9tOb.js → index-Cmgrk7PQ.js} +58 -58
- package/dashboard/dist/assets/index-Cmgrk7PQ.js.map +1 -0
- package/dashboard/dist/assets/{index-Ds0JoXS2.js → index-DNytWfSZ.js} +2 -2
- package/dashboard/dist/assets/{index-Ds0JoXS2.js.map → index-DNytWfSZ.js.map} +1 -1
- package/dashboard/dist/assets/index-DX6zxr6t.js +2 -0
- package/dashboard/dist/assets/{index-Cg5nfiYX.js.map → index-DX6zxr6t.js.map} +1 -1
- package/dashboard/dist/assets/index-DeX-ezqf.css +1 -0
- package/dashboard/dist/assets/index-K40Qw1tk.js +2 -0
- package/dashboard/dist/assets/{index-Di12t56M.js.map → index-K40Qw1tk.js.map} +1 -1
- package/dashboard/dist/assets/{index-BUK3qR-1.js → index-lCyNr5Xk.js} +2 -2
- package/dashboard/dist/assets/{index-BUK3qR-1.js.map → index-lCyNr5Xk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-B_xbczAt.js → mcp-CNE44TSp.js} +2 -2
- package/dashboard/dist/assets/{mcp-B_xbczAt.js.map → mcp-CNE44TSp.js.map} +1 -1
- package/dashboard/dist/assets/mcp-query-RQX0uN-5.js +2 -0
- package/dashboard/dist/assets/mcp-query-RQX0uN-5.js.map +1 -0
- package/dashboard/dist/assets/mcp-runs-0w40bdz-.js +2 -0
- package/dashboard/dist/assets/mcp-runs-0w40bdz-.js.map +1 -0
- package/dashboard/dist/assets/{namespaces-C3WtdO_9.js → namespaces-BbmdXuPp.js} +2 -2
- package/dashboard/dist/assets/{namespaces-C3WtdO_9.js.map → namespaces-BbmdXuPp.js.map} +1 -1
- package/dashboard/dist/assets/{roles-BDAsPpZG.js → roles-DoHYlhWH.js} +2 -2
- package/dashboard/dist/assets/{roles-BDAsPpZG.js.map → roles-DoHYlhWH.js.map} +1 -1
- package/dashboard/dist/assets/{settings-Ife_UwAp.js → settings-BAiJiCHS.js} +2 -2
- package/dashboard/dist/assets/{settings-Ife_UwAp.js.map → settings-BAiJiCHS.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BquNDHDI.js → tasks-CvroqHtm.js} +2 -2
- package/dashboard/dist/assets/{tasks-BquNDHDI.js.map → tasks-CvroqHtm.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-anv_B2Yy.js → useEventHooks-BHMbzR_y.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-anv_B2Yy.js.map → useEventHooks-BHMbzR_y.js.map} +1 -1
- package/dashboard/dist/assets/useFilterParams-CGRYFw_A.js +2 -0
- package/dashboard/dist/assets/useFilterParams-CGRYFw_A.js.map +1 -0
- package/dashboard/dist/assets/useYamlActivityEvents-D56KV14X.js +2 -0
- package/dashboard/dist/assets/useYamlActivityEvents-D56KV14X.js.map +1 -0
- package/dashboard/dist/assets/{users-CFcxB4v6.js → users-CxIMy_xw.js} +2 -2
- package/dashboard/dist/assets/{users-CFcxB4v6.js.map → users-CxIMy_xw.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-T4r2DSPD.js → vendor-icons-AFGxSeQS.js} +132 -82
- package/dashboard/dist/assets/vendor-icons-AFGxSeQS.js.map +1 -0
- package/dashboard/dist/assets/{workflows-CeRci9z3.js → workflows-yR9yais7.js} +2 -2
- package/dashboard/dist/assets/{workflows-CeRci9z3.js.map → workflows-yR9yais7.js.map} +1 -1
- package/dashboard/dist/assets/yaml-workflows-QVF2MZ0l.js +2 -0
- package/dashboard/dist/assets/yaml-workflows-QVF2MZ0l.js.map +1 -0
- package/dashboard/dist/index.html +3 -3
- package/docs/schema-exchange.md +173 -0
- package/docs/self-test.md +106 -0
- package/package.json +3 -1
- package/dashboard/dist/assets/CredentialsPage-DJablIbs.js +0 -2
- package/dashboard/dist/assets/McpQueryDetailPage-BWbinTM_.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-BWbinTM_.js.map +0 -1
- package/dashboard/dist/assets/McpQueryPage-lV6kfDG5.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-D6gaxH3_.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-D6gaxH3_.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-DKvTklh9.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-DKvTklh9.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-C9SSV96T.js +0 -2
- package/dashboard/dist/assets/RolesPage-SMedMuqa.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-CZqGslD6.js +0 -2
- package/dashboard/dist/assets/WorkflowPill-CZqGslD6.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-VjdhnLmO.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-VjdhnLmO.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-Cyg58nkg.js +0 -2
- package/dashboard/dist/assets/helpers-BCix9c_m.js +0 -2
- package/dashboard/dist/assets/helpers-BCix9c_m.js.map +0 -1
- package/dashboard/dist/assets/index-BYZX9tOb.js.map +0 -1
- package/dashboard/dist/assets/index-Cg5nfiYX.js +0 -2
- package/dashboard/dist/assets/index-DcIKW-cZ.css +0 -1
- package/dashboard/dist/assets/index-Di12t56M.js +0 -2
- package/dashboard/dist/assets/mcp-query-B8-P_QoG.js +0 -2
- package/dashboard/dist/assets/mcp-query-B8-P_QoG.js.map +0 -1
- package/dashboard/dist/assets/mcp-runs-CWeZinoF.js +0 -2
- package/dashboard/dist/assets/mcp-runs-CWeZinoF.js.map +0 -1
- package/dashboard/dist/assets/useFilterParams-BUyLHcx_.js +0 -2
- package/dashboard/dist/assets/useFilterParams-BUyLHcx_.js.map +0 -1
- package/dashboard/dist/assets/useYamlActivityEvents-DN-PTgVx.js +0 -2
- package/dashboard/dist/assets/useYamlActivityEvents-DN-PTgVx.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-T4r2DSPD.js.map +0 -1
- package/dashboard/dist/assets/yaml-workflows-DLwd2BOX.js +0 -2
- package/dashboard/dist/assets/yaml-workflows-DLwd2BOX.js.map +0 -1
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sanitizeToolName = sanitizeToolName;
|
|
4
|
+
exports.sanitizeServerName = sanitizeServerName;
|
|
5
|
+
/**
|
|
6
|
+
* Sanitize a value for use as an MCP tool name or HotMesh graph topic
|
|
7
|
+
* (the `subscribes` field in a YAML DAG).
|
|
8
|
+
*
|
|
9
|
+
* ## Why snake_case
|
|
10
|
+
*
|
|
11
|
+
* MCP tool names become the `subscribes` topic in a HotMesh YAML DAG.
|
|
12
|
+
* That topic is how the system routes incoming messages to the correct
|
|
13
|
+
* workflow. The same value also appears in `worker` activity `topic`
|
|
14
|
+
* fields and in the `mcp_<server>_<tool>` activity type encoding.
|
|
15
|
+
*
|
|
16
|
+
* Because the activity type uses underscores to delimit server from tool
|
|
17
|
+
* (`mcp_longtail_take_screenshot`), both the server name (letters only)
|
|
18
|
+
* and the tool name (snake_case) must avoid dashes, dots, or other
|
|
19
|
+
* separators that would create ambiguity when parsing activity types.
|
|
20
|
+
*
|
|
21
|
+
* ## Risks if violated
|
|
22
|
+
*
|
|
23
|
+
* - Dashes in tool names cause `parseMcpActivityType()` to mis-split
|
|
24
|
+
* the server/tool boundary in activity type strings.
|
|
25
|
+
* - Dots or special chars can produce invalid HotMesh topic subscriptions
|
|
26
|
+
* that silently fail to route.
|
|
27
|
+
* - Mixed conventions across entry points (builder, planner, discovery)
|
|
28
|
+
* cause topic collisions or deployment failures when merging workflows
|
|
29
|
+
* into a single app namespace.
|
|
30
|
+
*
|
|
31
|
+
* ## Contract
|
|
32
|
+
*
|
|
33
|
+
* Input: any string (LLM output, user input, URL slug, etc.)
|
|
34
|
+
* Output: lowercase letters, digits, and underscores only.
|
|
35
|
+
* Runs of non-alphanumeric chars become a single underscore.
|
|
36
|
+
* No leading or trailing underscores.
|
|
37
|
+
*
|
|
38
|
+
* This is the ONE canonical backend implementation. The dashboard has an
|
|
39
|
+
* identical copy at `dashboard/src/lib/sanitize.ts`. No other file in
|
|
40
|
+
* the platform may inline this logic.
|
|
41
|
+
*/
|
|
42
|
+
function sanitizeToolName(value) {
|
|
43
|
+
return value
|
|
44
|
+
.toLowerCase()
|
|
45
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
46
|
+
.replace(/^_|_$/g, '');
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Sanitize a value for use as an MCP server name (the HotMesh `app.id`
|
|
50
|
+
* and Postgres schema name that isolates one server's workflows from another).
|
|
51
|
+
*
|
|
52
|
+
* ## Why lowercase alphanumeric, leading letter
|
|
53
|
+
*
|
|
54
|
+
* The server name becomes:
|
|
55
|
+
* 1. A Postgres schema name — must start with a letter; letters and digits
|
|
56
|
+
* are safe without quoting.
|
|
57
|
+
* 2. The first segment in the `mcp_<server>_<tool>` activity type encoding.
|
|
58
|
+
* Because underscores delimit server from tool, the server name itself
|
|
59
|
+
* must never contain underscores (or dashes, dots, etc.).
|
|
60
|
+
*
|
|
61
|
+
* ## Risks if violated
|
|
62
|
+
*
|
|
63
|
+
* - Underscores or dashes in the server name make `parseMcpActivityType()`
|
|
64
|
+
* split incorrectly — it uses the first `_` after `mcp_` as the boundary.
|
|
65
|
+
* - A leading digit produces an invalid Postgres schema name that requires
|
|
66
|
+
* quoting and breaks HotMesh's unquoted SQL paths.
|
|
67
|
+
* - Special characters can cause silent deployment failures or schema
|
|
68
|
+
* creation errors.
|
|
69
|
+
*
|
|
70
|
+
* ## Contract
|
|
71
|
+
*
|
|
72
|
+
* Input: any string (LLM suggestion, user input, etc.)
|
|
73
|
+
* Output: lowercase letters and digits only, guaranteed to start with a letter.
|
|
74
|
+
* All non-alphanumeric chars are stripped (not replaced).
|
|
75
|
+
* Leading digits are stripped so the result starts with a letter.
|
|
76
|
+
* Default: 'longtail' if the result is empty after sanitization.
|
|
77
|
+
*
|
|
78
|
+
* This is the ONE canonical backend implementation. The dashboard has an
|
|
79
|
+
* identical copy at `dashboard/src/lib/sanitize.ts`. No other file in
|
|
80
|
+
* the platform may inline this logic.
|
|
81
|
+
*/
|
|
82
|
+
function sanitizeServerName(value) {
|
|
83
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, '').replace(/^[0-9]+/, '');
|
|
84
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const express_1 = require("express");
|
|
40
|
+
const path_1 = __importDefault(require("path"));
|
|
41
|
+
const api = __importStar(require("../api/files"));
|
|
42
|
+
const storage_1 = require("../lib/storage");
|
|
43
|
+
const mime_1 = require("../lib/storage/mime");
|
|
44
|
+
const router = (0, express_1.Router)();
|
|
45
|
+
/**
|
|
46
|
+
* GET /api/file-browser/browse
|
|
47
|
+
* List files and directories at a given prefix.
|
|
48
|
+
* Query: ?prefix=screenshots/&pageSize=100&continuationToken=...
|
|
49
|
+
*/
|
|
50
|
+
router.get('/browse', async (req, res) => {
|
|
51
|
+
const result = await api.browseFiles({
|
|
52
|
+
prefix: req.query.prefix,
|
|
53
|
+
pageSize: req.query.pageSize ? parseInt(req.query.pageSize, 10) : undefined,
|
|
54
|
+
continuationToken: req.query.continuationToken,
|
|
55
|
+
});
|
|
56
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
57
|
+
});
|
|
58
|
+
/**
|
|
59
|
+
* GET /api/file-browser/metadata/*
|
|
60
|
+
* Get metadata for a single file.
|
|
61
|
+
*/
|
|
62
|
+
router.get('/metadata/{*filePath}', async (req, res) => {
|
|
63
|
+
const raw = req.params.filePath;
|
|
64
|
+
const filePath = Array.isArray(raw) ? raw.join('/') : raw;
|
|
65
|
+
if (!filePath) {
|
|
66
|
+
res.status(400).json({ error: 'File path required' });
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const result = await api.getFileMetadata({ filePath });
|
|
70
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* POST /api/file-browser/signed-url
|
|
74
|
+
* Generate a time-limited signed URL for sharing.
|
|
75
|
+
* Body: { path, expiresIn } — expiresIn in seconds (3600, 21600, 86400, 604800, 2592000)
|
|
76
|
+
*/
|
|
77
|
+
router.post('/signed-url', async (req, res) => {
|
|
78
|
+
const { path: filePath, expiresIn } = req.body;
|
|
79
|
+
if (!filePath || !expiresIn) {
|
|
80
|
+
res.status(400).json({ error: 'path and expiresIn are required' });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const result = await api.generateSignedUrl({
|
|
84
|
+
filePath,
|
|
85
|
+
expiresIn: typeof expiresIn === 'number' ? expiresIn : parseInt(expiresIn, 10),
|
|
86
|
+
});
|
|
87
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* GET /api/file-browser/download/*
|
|
91
|
+
* Download a file with Content-Disposition: attachment.
|
|
92
|
+
*/
|
|
93
|
+
router.get('/download/{*filePath}', async (req, res) => {
|
|
94
|
+
const raw = req.params.filePath;
|
|
95
|
+
const filePath = Array.isArray(raw) ? raw.join('/') : raw;
|
|
96
|
+
if (!filePath) {
|
|
97
|
+
res.status(400).json({ error: 'File path required' });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const stream = await (0, storage_1.getStorageBackend)().createReadStream(filePath);
|
|
102
|
+
const fileName = path_1.default.basename(filePath);
|
|
103
|
+
const contentType = (0, mime_1.mimeFromPath)(filePath);
|
|
104
|
+
res.setHeader('Content-Type', contentType);
|
|
105
|
+
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
|
|
106
|
+
stream.pipe(res);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
res.status(404).json({ error: 'File not found' });
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
exports.default = router;
|
package/build/routes/files.js
CHANGED
|
@@ -4,26 +4,15 @@ 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
|
|
7
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
8
8
|
const storage_1 = require("../lib/storage");
|
|
9
|
+
const mime_1 = require("../lib/storage/mime");
|
|
9
10
|
const router = (0, express_1.Router)();
|
|
10
|
-
const MIME_TYPES = {
|
|
11
|
-
'.png': 'image/png',
|
|
12
|
-
'.jpg': 'image/jpeg',
|
|
13
|
-
'.jpeg': 'image/jpeg',
|
|
14
|
-
'.gif': 'image/gif',
|
|
15
|
-
'.svg': 'image/svg+xml',
|
|
16
|
-
'.webp': 'image/webp',
|
|
17
|
-
'.pdf': 'application/pdf',
|
|
18
|
-
'.json': 'application/json',
|
|
19
|
-
'.txt': 'text/plain',
|
|
20
|
-
'.html': 'text/html',
|
|
21
|
-
'.csv': 'text/csv',
|
|
22
|
-
'.xml': 'application/xml',
|
|
23
|
-
};
|
|
24
11
|
/**
|
|
25
12
|
* GET /api/files/*
|
|
26
13
|
* Serve files from managed file storage.
|
|
14
|
+
* Supports optional signed token (?token=<jwt>) for authenticated access
|
|
15
|
+
* to locally-generated signed URLs.
|
|
27
16
|
*/
|
|
28
17
|
router.get('/{*filePath}', async (req, res) => {
|
|
29
18
|
const raw = req.params.filePath;
|
|
@@ -32,10 +21,29 @@ router.get('/{*filePath}', async (req, res) => {
|
|
|
32
21
|
res.status(400).json({ error: 'File path required' });
|
|
33
22
|
return;
|
|
34
23
|
}
|
|
24
|
+
// Validate signed token if provided
|
|
25
|
+
const token = req.query.token;
|
|
26
|
+
if (token) {
|
|
27
|
+
const secret = process.env.JWT_SECRET;
|
|
28
|
+
if (!secret) {
|
|
29
|
+
res.status(500).json({ error: 'Server not configured for signed URLs' });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const decoded = jsonwebtoken_1.default.verify(token, secret);
|
|
34
|
+
if (decoded.purpose !== 'file-download' || decoded.filePath !== filePath.replace(/^\/+/, '')) {
|
|
35
|
+
res.status(403).json({ error: 'Token does not match requested file' });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
res.status(403).json({ error: 'Invalid or expired token' });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
try {
|
|
36
45
|
const stream = await (0, storage_1.getStorageBackend)().createReadStream(filePath);
|
|
37
|
-
const
|
|
38
|
-
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
46
|
+
const contentType = (0, mime_1.mimeFromPath)(filePath);
|
|
39
47
|
res.setHeader('Content-Type', contentType);
|
|
40
48
|
res.setHeader('Cache-Control', 'public, max-age=300');
|
|
41
49
|
stream.pipe(res);
|
package/build/routes/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const settings_1 = __importDefault(require("./settings"));
|
|
|
23
23
|
const mcp_runs_1 = __importDefault(require("./mcp-runs"));
|
|
24
24
|
const namespaces_1 = __importDefault(require("./namespaces"));
|
|
25
25
|
const files_1 = __importDefault(require("./files"));
|
|
26
|
+
const file_browser_1 = __importDefault(require("./file-browser"));
|
|
26
27
|
const controlplane_1 = __importDefault(require("./controlplane"));
|
|
27
28
|
const bot_accounts_1 = __importDefault(require("./bot-accounts"));
|
|
28
29
|
const docs_1 = __importDefault(require("./docs"));
|
|
@@ -49,6 +50,7 @@ router.use('/insight', insight_1.default);
|
|
|
49
50
|
router.use('/yaml-workflows', yaml_workflows_1.default);
|
|
50
51
|
router.use('/mcp-runs', mcp_runs_1.default);
|
|
51
52
|
router.use('/namespaces', namespaces_1.default);
|
|
53
|
+
router.use('/file-browser', file_browser_1.default);
|
|
52
54
|
router.use('/controlplane', controlplane_1.default);
|
|
53
55
|
router.use('/bot-accounts', bot_accounts_1.default);
|
|
54
56
|
router.use('/docs', docs_1.default);
|
package/build/routes/mcp-runs.js
CHANGED
|
@@ -60,6 +60,8 @@ router.get('/', async (req, res) => {
|
|
|
60
60
|
entity: req.query.entity || undefined,
|
|
61
61
|
search: req.query.search || undefined,
|
|
62
62
|
status: req.query.status || undefined,
|
|
63
|
+
sort_by: req.query.sort_by || undefined,
|
|
64
|
+
order: req.query.order || undefined,
|
|
63
65
|
});
|
|
64
66
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
65
67
|
});
|
|
@@ -79,6 +79,15 @@ router.put('/:id/plan', async (req, res) => {
|
|
|
79
79
|
});
|
|
80
80
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
81
81
|
});
|
|
82
|
+
/**
|
|
83
|
+
* POST /api/workflow-sets/:id/add
|
|
84
|
+
* Add additional workflows to an existing set from a new specification.
|
|
85
|
+
*/
|
|
86
|
+
router.post('/:id/add', async (req, res) => {
|
|
87
|
+
const { specification } = req.body;
|
|
88
|
+
const result = await api.addToWorkflowSet({ id: req.params.id, specification }, req.auth ? { userId: req.auth.userId } : undefined);
|
|
89
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
90
|
+
});
|
|
82
91
|
/**
|
|
83
92
|
* POST /api/workflow-sets/:id/build
|
|
84
93
|
* Trigger the build phase (resume the planner workflow).
|
|
@@ -76,4 +76,12 @@ router.post('/:id/archive', async (req, res) => {
|
|
|
76
76
|
const result = await api.archiveYamlWorkflow({ id: req.params.id });
|
|
77
77
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
78
78
|
});
|
|
79
|
+
/**
|
|
80
|
+
* POST /api/yaml-workflows/:id/restore
|
|
81
|
+
* Restore an archived YAML workflow back to draft status for redeployment.
|
|
82
|
+
*/
|
|
83
|
+
router.post('/:id/restore', async (req, res) => {
|
|
84
|
+
const result = await api.restoreYamlWorkflow({ id: req.params.id });
|
|
85
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
86
|
+
});
|
|
79
87
|
exports.default = router;
|
|
@@ -44,6 +44,19 @@ export interface WorkflowPlannerInput {
|
|
|
44
44
|
setId: string;
|
|
45
45
|
wait?: boolean;
|
|
46
46
|
userId?: string;
|
|
47
|
+
/** When adding to an existing set, pass the current plan items so the planner avoids duplicates. */
|
|
48
|
+
existingPlan?: Array<{
|
|
49
|
+
name: string;
|
|
50
|
+
description: string;
|
|
51
|
+
namespace: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Sibling schemas from already-built workflows for composition context. */
|
|
54
|
+
existingSchemas?: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
input_schema: Record<string, unknown>;
|
|
57
|
+
output_schema: Record<string, unknown>;
|
|
58
|
+
graph_topic: string;
|
|
59
|
+
}>;
|
|
47
60
|
}
|
|
48
61
|
export declare function startWorkflowPlanner(input: WorkflowPlannerInput): Promise<McpQueryResult>;
|
|
49
62
|
export declare function describeWorkflow(input: DescribeInput): Promise<DescribeResult>;
|
|
@@ -11,6 +11,7 @@ exports.describeWorkflow = describeWorkflow;
|
|
|
11
11
|
const hotmesh_1 = require("@hotmeshio/hotmesh");
|
|
12
12
|
const db_1 = require("../../lib/db");
|
|
13
13
|
const defaults_1 = require("../../modules/defaults");
|
|
14
|
+
const utils_1 = require("../../modules/utils");
|
|
14
15
|
const llm_1 = require("../llm");
|
|
15
16
|
const prompts_1 = require("./prompts");
|
|
16
17
|
// ── MCP query invocation ─────────────────────────────────────────────────────
|
|
@@ -76,13 +77,13 @@ async function startWorkflowBuilder(input) {
|
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
79
|
async function startWorkflowPlanner(input) {
|
|
79
|
-
const { specification, setId, wait = true, userId } = input;
|
|
80
|
+
const { specification, setId, wait = true, userId, existingPlan, existingSchemas } = input;
|
|
80
81
|
const startTime = Date.now();
|
|
81
82
|
const client = new hotmesh_1.Durable.Client({ connection: (0, db_1.getConnection)() });
|
|
82
83
|
const workflowId = `wf-planner-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
83
84
|
const handle = await client.workflow.start({
|
|
84
85
|
args: [{
|
|
85
|
-
data: { specification, setId },
|
|
86
|
+
data: { specification, setId, existingPlan, existingSchemas },
|
|
86
87
|
metadata: { source: 'dashboard' },
|
|
87
88
|
lt: { userId },
|
|
88
89
|
}],
|
|
@@ -126,11 +127,7 @@ async function describeWorkflow(input) {
|
|
|
126
127
|
const raw = response.content || '{}';
|
|
127
128
|
const cleaned = raw.replace(/^```(?:json)?\s*/m, '').replace(/\s*```$/m, '').trim();
|
|
128
129
|
const parsed = JSON.parse(cleaned);
|
|
129
|
-
const toolName = (parsed.tool_name || '')
|
|
130
|
-
.toLowerCase()
|
|
131
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
132
|
-
.replace(/^-|-$/g, '')
|
|
133
|
-
.slice(0, 60);
|
|
130
|
+
const toolName = (0, utils_1.sanitizeToolName)(parsed.tool_name || '').slice(0, 60);
|
|
134
131
|
return {
|
|
135
132
|
tool_name: toolName || undefined,
|
|
136
133
|
description: parsed.description || prompt,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Externalized LLM prompt constants for the insight service.
|
|
3
3
|
*/
|
|
4
|
-
export declare const DESCRIBE_WORKFLOW_SYSTEM_PROMPT = "You generate concise workflow descriptions, tool names, and discovery tags.\n\nGiven a user's original query and the execution result, produce:\n1. A short, descriptive tool name
|
|
4
|
+
export declare const DESCRIBE_WORKFLOW_SYSTEM_PROMPT = "You generate concise workflow descriptions, tool names, and discovery tags.\n\nGiven a user's original query and the execution result, produce:\n1. A short, descriptive tool name in snake_case (e.g. \"screenshot_all_nav_pages\", \"fetch_order_status\", \"translate_content\"). Only lowercase letters, digits, and underscores. The name should describe what the workflow does, not be generic like \"query_complete\".\n2. A clear, reusable description of what this workflow does (not what the user asked, but what the workflow accomplishes as a reusable tool). Write it as if describing a tool in a catalog. 2-3 sentences max.\n3. Discovery tags \u2014 lowercase keywords that help find this workflow when similar future queries are made.\n\nReturn ONLY a JSON object:\n{ \"tool_name\": \"...\", \"description\": \"...\", \"tags\": [\"tag1\", \"tag2\", ...] }";
|
|
@@ -7,7 +7,7 @@ exports.DESCRIBE_WORKFLOW_SYSTEM_PROMPT = void 0;
|
|
|
7
7
|
exports.DESCRIBE_WORKFLOW_SYSTEM_PROMPT = `You generate concise workflow descriptions, tool names, and discovery tags.
|
|
8
8
|
|
|
9
9
|
Given a user's original query and the execution result, produce:
|
|
10
|
-
1. A short, descriptive tool name
|
|
10
|
+
1. A short, descriptive tool name in snake_case (e.g. "screenshot_all_nav_pages", "fetch_order_status", "translate_content"). Only lowercase letters, digits, and underscores. The name should describe what the workflow does, not be generic like "query_complete".
|
|
11
11
|
2. A clear, reusable description of what this workflow does (not what the user asked, but what the workflow accomplishes as a reusable tool). Write it as if describing a tool in a catalog. 2-3 sentences max.
|
|
12
12
|
3. Discovery tags — lowercase keywords that help find this workflow when similar future queries are made.
|
|
13
13
|
|
|
@@ -5,6 +5,15 @@ exports.listJobs = listJobs;
|
|
|
5
5
|
const db_1 = require("../../lib/db");
|
|
6
6
|
const hotmesh_utils_1 = require("../hotmesh-utils");
|
|
7
7
|
const sql_1 = require("./sql");
|
|
8
|
+
const SORTABLE_COLUMNS = new Set(['created_at', 'updated_at', 'entity', 'status']);
|
|
9
|
+
function buildOrderBy(sortBy, order) {
|
|
10
|
+
if (!sortBy || !SORTABLE_COLUMNS.has(sortBy)) {
|
|
11
|
+
return '(CASE WHEN j.status > 0 THEN 0 ELSE 1 END), j.created_at DESC';
|
|
12
|
+
}
|
|
13
|
+
const dir = order === 'asc' ? 'ASC' : 'DESC';
|
|
14
|
+
const col = sortBy === 'status' ? '(CASE WHEN j.status > 0 THEN 0 WHEN j.status = 0 THEN 1 ELSE 2 END)' : `j.${sortBy}`;
|
|
15
|
+
return `${col} ${dir}`;
|
|
16
|
+
}
|
|
8
17
|
/**
|
|
9
18
|
* Return distinct entity names from job runs + yaml workflow graph_topics.
|
|
10
19
|
*/
|
|
@@ -55,9 +64,10 @@ async function listJobs(params) {
|
|
|
55
64
|
}
|
|
56
65
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
57
66
|
const keyPrefix = `hmsh:${appId}:j:`;
|
|
67
|
+
const orderBy = buildOrderBy(params.sort_by, params.order);
|
|
58
68
|
const [countResult, dataResult] = await Promise.all([
|
|
59
69
|
pool.query((0, sql_1.COUNT_JOBS)(schema, where), values),
|
|
60
|
-
pool.query((0, sql_1.LIST_JOBS)(schema, appId, where, idx++, idx
|
|
70
|
+
pool.query((0, sql_1.LIST_JOBS)(schema, appId, where, idx++, idx++, orderBy), [...values, limit, offset]),
|
|
61
71
|
]);
|
|
62
72
|
const jobs = dataResult.rows.map((row) => ({
|
|
63
73
|
workflow_id: row.key.startsWith(keyPrefix) ? row.key.slice(keyPrefix.length) : row.key,
|
|
@@ -4,4 +4,4 @@ export declare const ACTIVE_GRAPH_TOPICS = "SELECT DISTINCT graph_topic FROM lt_
|
|
|
4
4
|
export declare const COUNT_JOBS: (schema: string, where: string) => string;
|
|
5
5
|
export declare const GET_JOB: (schema: string) => string;
|
|
6
6
|
export declare const GET_JOB_ATTRIBUTES: (schema: string) => string;
|
|
7
|
-
export declare const LIST_JOBS: (schema: string, appId: string, where: string, limitIdx: number, offsetIdx: number) => string;
|
|
7
|
+
export declare const LIST_JOBS: (schema: string, appId: string, where: string, limitIdx: number, offsetIdx: number, orderBy?: string) => string;
|
|
@@ -18,7 +18,7 @@ exports.GET_JOB = GET_JOB;
|
|
|
18
18
|
const GET_JOB_ATTRIBUTES = (schema) => `SELECT symbol, dimension, value FROM ${schema}.jobs_attributes WHERE job_id = $1 ORDER BY symbol, dimension`;
|
|
19
19
|
exports.GET_JOB_ATTRIBUTES = GET_JOB_ATTRIBUTES;
|
|
20
20
|
// ─── Queries (queries.ts) ───────────────────────────────────────────────────
|
|
21
|
-
const LIST_JOBS = (schema, appId, where, limitIdx, offsetIdx) => `WITH ju_symbols AS (
|
|
21
|
+
const LIST_JOBS = (schema, appId, where, limitIdx, offsetIdx, orderBy) => `WITH ju_symbols AS (
|
|
22
22
|
SELECT value FROM ${schema}.symbols
|
|
23
23
|
WHERE key LIKE 'keys:%' AND field = 'metadata/ju'
|
|
24
24
|
)
|
|
@@ -33,6 +33,6 @@ const LIST_JOBS = (schema, appId, where, limitIdx, offsetIdx) => `WITH ju_symbol
|
|
|
33
33
|
AND ju.symbol IN (SELECT value FROM ju_symbols)
|
|
34
34
|
AND (ju.dimension IS NULL OR ju.dimension = '')
|
|
35
35
|
${where}
|
|
36
|
-
ORDER BY (CASE WHEN j.status > 0 THEN 0 ELSE 1 END), j.created_at DESC
|
|
36
|
+
ORDER BY ${orderBy || '(CASE WHEN j.status > 0 THEN 0 ELSE 1 END), j.created_at DESC'}
|
|
37
37
|
LIMIT $${limitIdx} OFFSET $${offsetIdx}`;
|
|
38
38
|
exports.LIST_JOBS = LIST_JOBS;
|
|
@@ -2,6 +2,7 @@ import type { LTWorkflowSetRecord, LTWorkflowSetStatus, CreateWorkflowSetInput,
|
|
|
2
2
|
export declare function createWorkflowSet(input: CreateWorkflowSetInput): Promise<LTWorkflowSetRecord>;
|
|
3
3
|
export declare function getWorkflowSet(id: string): Promise<LTWorkflowSetRecord | null>;
|
|
4
4
|
export declare function updateWorkflowSetPlan(id: string, plan: PlanItem[], namespaces: string[]): Promise<LTWorkflowSetRecord | null>;
|
|
5
|
+
export declare function appendWorkflowSetSpecification(id: string, specification: string): Promise<LTWorkflowSetRecord | null>;
|
|
5
6
|
export declare function updateWorkflowSetStatus(id: string, status: LTWorkflowSetStatus): Promise<LTWorkflowSetRecord | null>;
|
|
6
7
|
export declare function updateWorkflowSetSourceWorkflow(id: string, sourceWorkflowId: string): Promise<void>;
|
|
7
8
|
export declare function deleteWorkflowSet(id: string): Promise<boolean>;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createWorkflowSet = createWorkflowSet;
|
|
4
4
|
exports.getWorkflowSet = getWorkflowSet;
|
|
5
5
|
exports.updateWorkflowSetPlan = updateWorkflowSetPlan;
|
|
6
|
+
exports.appendWorkflowSetSpecification = appendWorkflowSetSpecification;
|
|
6
7
|
exports.updateWorkflowSetStatus = updateWorkflowSetStatus;
|
|
7
8
|
exports.updateWorkflowSetSourceWorkflow = updateWorkflowSetSourceWorkflow;
|
|
8
9
|
exports.deleteWorkflowSet = deleteWorkflowSet;
|
|
@@ -36,6 +37,11 @@ async function updateWorkflowSetPlan(id, plan, namespaces) {
|
|
|
36
37
|
]);
|
|
37
38
|
return rows[0] || null;
|
|
38
39
|
}
|
|
40
|
+
async function appendWorkflowSetSpecification(id, specification) {
|
|
41
|
+
const pool = (0, db_1.getPool)();
|
|
42
|
+
const { rows } = await pool.query(sql_1.APPEND_WORKFLOW_SET_SPECIFICATION, [id, specification]);
|
|
43
|
+
return rows[0] || null;
|
|
44
|
+
}
|
|
39
45
|
async function updateWorkflowSetStatus(id, status) {
|
|
40
46
|
const pool = (0, db_1.getPool)();
|
|
41
47
|
const { rows } = await pool.query(sql_1.UPDATE_WORKFLOW_SET_STATUS, [id, status]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { createWorkflowSet, getWorkflowSet, updateWorkflowSetPlan, updateWorkflowSetStatus, updateWorkflowSetSourceWorkflow, deleteWorkflowSet, listWorkflowSets, } from './db';
|
|
1
|
+
export { createWorkflowSet, getWorkflowSet, updateWorkflowSetPlan, updateWorkflowSetStatus, updateWorkflowSetSourceWorkflow, appendWorkflowSetSpecification, deleteWorkflowSet, listWorkflowSets, } from './db';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.listWorkflowSets = exports.deleteWorkflowSet = exports.updateWorkflowSetSourceWorkflow = exports.updateWorkflowSetStatus = exports.updateWorkflowSetPlan = exports.getWorkflowSet = exports.createWorkflowSet = void 0;
|
|
3
|
+
exports.listWorkflowSets = exports.deleteWorkflowSet = exports.appendWorkflowSetSpecification = exports.updateWorkflowSetSourceWorkflow = exports.updateWorkflowSetStatus = exports.updateWorkflowSetPlan = exports.getWorkflowSet = exports.createWorkflowSet = void 0;
|
|
4
4
|
var db_1 = require("./db");
|
|
5
5
|
Object.defineProperty(exports, "createWorkflowSet", { enumerable: true, get: function () { return db_1.createWorkflowSet; } });
|
|
6
6
|
Object.defineProperty(exports, "getWorkflowSet", { enumerable: true, get: function () { return db_1.getWorkflowSet; } });
|
|
7
7
|
Object.defineProperty(exports, "updateWorkflowSetPlan", { enumerable: true, get: function () { return db_1.updateWorkflowSetPlan; } });
|
|
8
8
|
Object.defineProperty(exports, "updateWorkflowSetStatus", { enumerable: true, get: function () { return db_1.updateWorkflowSetStatus; } });
|
|
9
9
|
Object.defineProperty(exports, "updateWorkflowSetSourceWorkflow", { enumerable: true, get: function () { return db_1.updateWorkflowSetSourceWorkflow; } });
|
|
10
|
+
Object.defineProperty(exports, "appendWorkflowSetSpecification", { enumerable: true, get: function () { return db_1.appendWorkflowSetSpecification; } });
|
|
10
11
|
Object.defineProperty(exports, "deleteWorkflowSet", { enumerable: true, get: function () { return db_1.deleteWorkflowSet; } });
|
|
11
12
|
Object.defineProperty(exports, "listWorkflowSets", { enumerable: true, get: function () { return db_1.listWorkflowSets; } });
|
|
@@ -2,5 +2,6 @@ export declare const CREATE_WORKFLOW_SET = "\n INSERT INTO lt_workflow_sets (na
|
|
|
2
2
|
export declare const GET_WORKFLOW_SET = "\n SELECT * FROM lt_workflow_sets WHERE id = $1";
|
|
3
3
|
export declare const UPDATE_WORKFLOW_SET_PLAN = "\n UPDATE lt_workflow_sets\n SET plan = $2, namespaces = $3, status = 'planned', updated_at = NOW()\n WHERE id = $1\n RETURNING *";
|
|
4
4
|
export declare const UPDATE_WORKFLOW_SET_STATUS = "\n UPDATE lt_workflow_sets\n SET status = $2, updated_at = NOW()\n WHERE id = $1\n RETURNING *";
|
|
5
|
+
export declare const APPEND_WORKFLOW_SET_SPECIFICATION = "\n UPDATE lt_workflow_sets\n SET specification = specification || E'\\n\\n---\\n\\n' || $2, updated_at = NOW()\n WHERE id = $1\n RETURNING *";
|
|
5
6
|
export declare const DELETE_WORKFLOW_SET = "\n DELETE FROM lt_workflow_sets WHERE id = $1";
|
|
6
7
|
export declare const LIST_WORKFLOW_SETS_BASE = "\n SELECT * FROM lt_workflow_sets";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ─── Workflow set CRUD ──────────────────────────────────────────────────────
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.LIST_WORKFLOW_SETS_BASE = exports.DELETE_WORKFLOW_SET = exports.UPDATE_WORKFLOW_SET_STATUS = exports.UPDATE_WORKFLOW_SET_PLAN = exports.GET_WORKFLOW_SET = exports.CREATE_WORKFLOW_SET = void 0;
|
|
4
|
+
exports.LIST_WORKFLOW_SETS_BASE = exports.DELETE_WORKFLOW_SET = exports.APPEND_WORKFLOW_SET_SPECIFICATION = exports.UPDATE_WORKFLOW_SET_STATUS = exports.UPDATE_WORKFLOW_SET_PLAN = exports.GET_WORKFLOW_SET = exports.CREATE_WORKFLOW_SET = void 0;
|
|
5
5
|
exports.CREATE_WORKFLOW_SET = `
|
|
6
6
|
INSERT INTO lt_workflow_sets (name, description, specification, plan, namespaces, source_workflow_id)
|
|
7
7
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
@@ -18,6 +18,11 @@ exports.UPDATE_WORKFLOW_SET_STATUS = `
|
|
|
18
18
|
SET status = $2, updated_at = NOW()
|
|
19
19
|
WHERE id = $1
|
|
20
20
|
RETURNING *`;
|
|
21
|
+
exports.APPEND_WORKFLOW_SET_SPECIFICATION = `
|
|
22
|
+
UPDATE lt_workflow_sets
|
|
23
|
+
SET specification = specification || E'\\n\\n---\\n\\n' || $2, updated_at = NOW()
|
|
24
|
+
WHERE id = $1
|
|
25
|
+
RETURNING *`;
|
|
21
26
|
exports.DELETE_WORKFLOW_SET = `
|
|
22
27
|
DELETE FROM lt_workflow_sets WHERE id = $1`;
|
|
23
28
|
exports.LIST_WORKFLOW_SETS_BASE = `
|
|
@@ -21,6 +21,18 @@ export declare function discoverWorkflows(prompt: string, tags: string[], catego
|
|
|
21
21
|
})[]>;
|
|
22
22
|
export declare function getActiveYamlWorkflows(): Promise<LTYamlWorkflowRecord[]>;
|
|
23
23
|
export declare function listYamlWorkflowsByAppId(appId: string): Promise<LTYamlWorkflowRecord[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Return the next app-level version for a namespace.
|
|
26
|
+
*
|
|
27
|
+
* Each deploy of an app (namespace) must use a strictly increasing integer
|
|
28
|
+
* version. This queries the current max across all non-archived workflows
|
|
29
|
+
* in the namespace and returns max + 1.
|
|
30
|
+
*
|
|
31
|
+
* A new namespace with no workflows returns '1'.
|
|
32
|
+
* An existing namespace with one active tool at v1 returns '2' when a
|
|
33
|
+
* second tool is added — even though that second tool is "version 1" of itself.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getNextAppVersion(appId: string): Promise<string>;
|
|
24
36
|
export declare function getDistinctAppIds(): Promise<string[]>;
|
|
25
37
|
export declare function createVersionSnapshot(workflowId: string, version: number, yamlContent: string, activityManifest: ActivityManifestEntry[] | unknown, inputSchema: Record<string, unknown> | unknown, outputSchema: Record<string, unknown> | unknown, inputFieldMeta?: unknown, changeSummary?: string): Promise<LTYamlWorkflowVersionRecord>;
|
|
26
38
|
export declare function getVersionHistory(workflowId: string, limit?: number, offset?: number): Promise<{
|
|
@@ -11,6 +11,7 @@ exports.deleteYamlWorkflow = deleteYamlWorkflow;
|
|
|
11
11
|
exports.discoverWorkflows = discoverWorkflows;
|
|
12
12
|
exports.getActiveYamlWorkflows = getActiveYamlWorkflows;
|
|
13
13
|
exports.listYamlWorkflowsByAppId = listYamlWorkflowsByAppId;
|
|
14
|
+
exports.getNextAppVersion = getNextAppVersion;
|
|
14
15
|
exports.getDistinctAppIds = getDistinctAppIds;
|
|
15
16
|
exports.createVersionSnapshot = createVersionSnapshot;
|
|
16
17
|
exports.getVersionHistory = getVersionHistory;
|
|
@@ -172,6 +173,23 @@ async function listYamlWorkflowsByAppId(appId) {
|
|
|
172
173
|
const { rows } = await pool.query(sql_1.LIST_BY_APP_ID, [appId]);
|
|
173
174
|
return rows;
|
|
174
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Return the next app-level version for a namespace.
|
|
178
|
+
*
|
|
179
|
+
* Each deploy of an app (namespace) must use a strictly increasing integer
|
|
180
|
+
* version. This queries the current max across all non-archived workflows
|
|
181
|
+
* in the namespace and returns max + 1.
|
|
182
|
+
*
|
|
183
|
+
* A new namespace with no workflows returns '1'.
|
|
184
|
+
* An existing namespace with one active tool at v1 returns '2' when a
|
|
185
|
+
* second tool is added — even though that second tool is "version 1" of itself.
|
|
186
|
+
*/
|
|
187
|
+
async function getNextAppVersion(appId) {
|
|
188
|
+
const pool = (0, db_1.getPool)();
|
|
189
|
+
const { rows } = await pool.query(sql_1.GET_MAX_APP_VERSION, [appId]);
|
|
190
|
+
const max = parseInt(rows[0]?.max_version ?? '0', 10);
|
|
191
|
+
return String(max + 1);
|
|
192
|
+
}
|
|
175
193
|
async function getDistinctAppIds() {
|
|
176
194
|
const pool = (0, db_1.getPool)();
|
|
177
195
|
const { rows } = await pool.query(sql_1.GET_DISTINCT_APP_IDS);
|
|
@@ -50,10 +50,10 @@ const analyze_1 = require("./pipeline/analyze");
|
|
|
50
50
|
const compile_1 = require("./pipeline/compile");
|
|
51
51
|
const build_1 = require("./pipeline/build");
|
|
52
52
|
const validate_1 = require("./pipeline/validate");
|
|
53
|
-
const
|
|
53
|
+
const utils_1 = require("../../modules/utils");
|
|
54
54
|
// Re-exports for backward compatibility
|
|
55
|
-
var
|
|
56
|
-
Object.defineProperty(exports, "capToolArguments", { enumerable: true, get: function () { return
|
|
55
|
+
var build_2 = require("./pipeline/build");
|
|
56
|
+
Object.defineProperty(exports, "capToolArguments", { enumerable: true, get: function () { return build_2.capToolArguments; } });
|
|
57
57
|
/**
|
|
58
58
|
* Generate a HotMesh YAML workflow from a completed execution's tool call sequence.
|
|
59
59
|
*
|
|
@@ -63,7 +63,7 @@ Object.defineProperty(exports, "capToolArguments", { enumerable: true, get: func
|
|
|
63
63
|
*/
|
|
64
64
|
async function generateYamlFromExecution(options) {
|
|
65
65
|
const appId = options.appId || 'longtail';
|
|
66
|
-
const graphTopic =
|
|
66
|
+
const graphTopic = (0, utils_1.sanitizeToolName)(options.subscribes || options.name);
|
|
67
67
|
// 1. Export the execution to get events
|
|
68
68
|
const execution = await (0, index_1.exportWorkflowExecution)(options.workflowId, options.taskQueue, options.workflowName);
|
|
69
69
|
// 2. Initialize pipeline context
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* Falls back to mechanical heuristics when no plan is available.
|
|
7
7
|
*/
|
|
8
8
|
import type { PipelineContext } from '../../types';
|
|
9
|
-
export { capToolArguments
|
|
9
|
+
export { capToolArguments } from './utils';
|
|
10
|
+
export { sanitizeToolName } from '../../../../modules/utils';
|
|
10
11
|
/**
|
|
11
12
|
* Build pipeline stage: construct the HotMesh YAML DAG.
|
|
12
13
|
*
|