@hotmeshio/long-tail 0.5.11 → 0.5.12
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/diagnostics.d.ts +5 -0
- package/build/api/diagnostics.js +5 -1
- package/build/api/escalations/list.d.ts +2 -0
- package/build/api/escalations/list.js +2 -0
- package/build/api/settings.d.ts +1 -1
- package/build/api/settings.js +3 -1
- package/build/api/workflows/invocation.d.ts +6 -0
- package/build/api/workflows/invocation.js +6 -2
- package/build/modules/features.d.ts +19 -0
- package/build/modules/features.js +16 -0
- package/build/routes/diagnostics.js +15 -2
- package/build/routes/escalations/list.js +2 -0
- package/build/routes/workflows/invocation.js +12 -4
- package/build/sdk/index.d.ts +2 -0
- package/build/services/diagnostics/index.d.ts +40 -6
- package/build/services/diagnostics/index.js +54 -5
- package/build/services/escalation/queries.d.ts +2 -0
- package/build/services/escalation/queries.js +84 -2
- package/build/services/escalation/sql.d.ts +7 -0
- package/build/services/escalation/sql.js +50 -1
- package/build/services/task/resolve.d.ts +5 -3
- package/build/services/task/resolve.js +9 -6
- package/build/services/task/sql.d.ts +6 -1
- package/build/services/task/sql.js +7 -1
- package/build/start/adapters.js +3 -0
- package/build/system/mcp-servers/admin/diagnostics.d.ts +5 -4
- package/build/system/mcp-servers/admin/diagnostics.js +12 -10
- package/build/system/mcp-servers/admin/escalations.d.ts +6 -0
- package/build/system/mcp-servers/admin/escalations.js +182 -54
- package/build/system/mcp-servers/admin/index.js +3 -3
- package/build/system/mcp-servers/admin/schemas.d.ts +92 -3
- package/build/system/mcp-servers/admin/schemas.js +39 -4
- package/build/system/mcp-servers/admin/workflows.js +23 -12
- package/build/system/seed/tool-manifests-admin.d.ts +1324 -562
- package/build/system/seed/tool-manifests-admin.js +10 -2
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/startup.d.ts +9 -0
- package/dashboard/dist/assets/{AdminDashboard-DZpduYdW.js → AdminDashboard-LTiYLuzq.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DZpduYdW.js.map → AdminDashboard-LTiYLuzq.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js → AgentConfigPage-nlOudfpZ.js} +7 -7
- package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js.map → AgentConfigPage-nlOudfpZ.js.map} +1 -1
- package/dashboard/dist/assets/AgentDetailPage-BSUnDvGp.js +4 -0
- package/dashboard/dist/assets/AgentDetailPage-BSUnDvGp.js.map +1 -0
- package/dashboard/dist/assets/AgentsPage-DpS0cCYe.js +2 -0
- package/dashboard/dist/assets/AgentsPage-DpS0cCYe.js.map +1 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BEylRqjP.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BEylRqjP.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js → BotPicker-BhKmq7M7.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js.map → BotPicker-BhKmq7M7.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-DLIleX2L.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-DTfKCzBQ.js.map → CapabilitiesPage-DLIleX2L.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js → CollapsibleSection-D7SVwNVk.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js.map → CollapsibleSection-D7SVwNVk.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js → CredentialsPage-fat5Z2U9.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js.map → CredentialsPage-fat5Z2U9.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js → CronLabel-OOP4P2mJ.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js.map → CronLabel-OOP4P2mJ.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js → CustomDurationPicker-COacSAXO.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js.map → CustomDurationPicker-COacSAXO.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-Dwpgbueb.js → DropZone-Bfw2YLVS.js} +2 -2
- package/dashboard/dist/assets/{DropZone-Dwpgbueb.js.map → DropZone-Bfw2YLVS.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js → ElapsedCell-CkfCD-m7.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js.map → ElapsedCell-CkfCD-m7.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js → EscalationsOverview-BmI8jxlh.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js.map → EscalationsOverview-BmI8jxlh.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-CwvX_L9t.js → EventTable-CeKfFk3m.js} +2 -2
- package/dashboard/dist/assets/{EventTable-CwvX_L9t.js.map → EventTable-CeKfFk3m.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js → GraphInvokePage-BZBPBCSq.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js.map → GraphInvokePage-BZBPBCSq.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-BS_-jcHr.js → HomePage-dM7U2tl6.js} +2 -2
- package/dashboard/dist/assets/{HomePage-BS_-jcHr.js.map → HomePage-dM7U2tl6.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js → ListToolbar-BJaCzAXS.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js.map → ListToolbar-BJaCzAXS.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js → McpOverview-CvnDG5OB.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js.map → McpOverview-CvnDG5OB.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js → McpQueryDetailPage-DwmSIcIL.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js.map → McpQueryDetailPage-DwmSIcIL.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryPage-CU6FMEEk.js +2 -0
- package/dashboard/dist/assets/McpQueryPage-CU6FMEEk.js.map +1 -0
- package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js → McpRunDetailPage-8a6lsehv.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js.map → McpRunDetailPage-8a6lsehv.js.map} +1 -1
- package/dashboard/dist/assets/McpRunsPage-CPMYWgm_.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-CPMYWgm_.js.map +1 -0
- package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js → NamespacePill-D6btr6e8.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js.map → NamespacePill-D6btr6e8.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-g9o7I925.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-g9o7I925.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-Bnt2iQQa.js → PageHeader-Dk2Pe44Q.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Bnt2iQQa.js.map → PageHeader-Dk2Pe44Q.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js → PageHeaderWithStats-DJQCZ0FR.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js.map → PageHeaderWithStats-DJQCZ0FR.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js → ProcessDetailPage-ByyWCs2A.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js.map → ProcessDetailPage-ByyWCs2A.js.map} +1 -1
- package/dashboard/dist/assets/ProcessesListPage-BTsXds4l.js +2 -0
- package/dashboard/dist/assets/ProcessesListPage-BTsXds4l.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-DQTT1s9v.js → RolePill-Du-aNnjR.js} +2 -2
- package/dashboard/dist/assets/{RolePill-DQTT1s9v.js.map → RolePill-Du-aNnjR.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js → RolesPage-B2Kdf-L9.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js.map → RolesPage-B2Kdf-L9.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js → RunAsSelector-BzkZXpSX.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js.map → RunAsSelector-BzkZXpSX.js.map} +1 -1
- package/dashboard/dist/assets/StreamMessageDetail-B6ch-6SY.js +2 -0
- package/dashboard/dist/assets/{StreamMessageDetail-BF0tM0cd.js.map → StreamMessageDetail-B6ch-6SY.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js → SwimlaneTimeline-CjvfUkls.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js.map → SwimlaneTimeline-CjvfUkls.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-B00uqhjX.js → TagInput-CZSeyesi.js} +2 -2
- package/dashboard/dist/assets/{TagInput-B00uqhjX.js.map → TagInput-CZSeyesi.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js → TaskDetailPage-BjHU6opi.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js.map → TaskDetailPage-BjHU6opi.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js → TaskQueuePill-CQrXrSxk.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js.map → TaskQueuePill-CQrXrSxk.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js → TasksListPage-Bem44zd0.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js.map → TasksListPage-Bem44zd0.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js → TimeAgo-CUIYqSt_.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js.map → TimeAgo-CUIYqSt_.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js → TimestampCell--tnreI1i.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js.map → TimestampCell--tnreI1i.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-DjvedZSn.js → ToolPill-O09jsTQM.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-DjvedZSn.js.map → ToolPill-O09jsTQM.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js → ToolTestPanel-OD99H7Pk.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js.map → ToolTestPanel-OD99H7Pk.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js → TopicDetailPage-rh_dsTJI.js} +3 -3
- package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js.map → TopicDetailPage-rh_dsTJI.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js → TopicsPage-CD_40_v-.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js.map → TopicsPage-CD_40_v-.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-xHAgkk8M.js → UserName-C__c8BN0.js} +2 -2
- package/dashboard/dist/assets/{UserName-xHAgkk8M.js.map → UserName-C__c8BN0.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js → WorkflowExecutionPage-Bw6QdtUO.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js.map → WorkflowExecutionPage-Bw6QdtUO.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js → WorkflowPill-CS-IsR0U.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js.map → WorkflowPill-CS-IsR0U.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-BgI-iOP6.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-BgI-iOP6.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js → WorkflowsOverview-BRc0QbA7.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js.map → WorkflowsOverview-BRc0QbA7.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js → YamlWorkflowDetailPage-DdzspNQR.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js.map → YamlWorkflowDetailPage-DdzspNQR.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js → YamlWorkflowsPage-Djw5ZbgQ.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js.map → YamlWorkflowsPage-Djw5ZbgQ.js.map} +1 -1
- package/dashboard/dist/assets/{agents-JE4aL07D.js → agents-xstNkF6c.js} +2 -2
- package/dashboard/dist/assets/{agents-JE4aL07D.js.map → agents-xstNkF6c.js.map} +1 -1
- package/dashboard/dist/assets/api-path-u2Jf9QXS.js +2 -0
- package/dashboard/dist/assets/api-path-u2Jf9QXS.js.map +1 -0
- package/dashboard/dist/assets/{bots-cAzKkDtQ.js → bots-BztAI0s_.js} +2 -2
- package/dashboard/dist/assets/{bots-cAzKkDtQ.js.map → bots-BztAI0s_.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-RBFXLAXF.js → capabilities-CEDwtxNL.js} +2 -2
- package/dashboard/dist/assets/{capabilities-RBFXLAXF.js.map → capabilities-CEDwtxNL.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DGhv3rwI.js → controlplane-BlGEsRKe.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DGhv3rwI.js.map → controlplane-BlGEsRKe.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-DqTkKbCv.js → escalation-columns-nVYVt7Gl.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-DqTkKbCv.js.map → escalation-columns-nVYVt7Gl.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-ne7dIaPa.js → escalation-iI4QKlP-.js} +2 -2
- package/dashboard/dist/assets/{escalation-ne7dIaPa.js.map → escalation-iI4QKlP-.js.map} +1 -1
- package/dashboard/dist/assets/{index-BbJuC9kg.js → index-B5qsp8lb.js} +2 -2
- package/dashboard/dist/assets/{index-BbJuC9kg.js.map → index-B5qsp8lb.js.map} +1 -1
- package/dashboard/dist/assets/{index-CgyucK0e.js → index-B7VC0vjf.js} +2 -2
- package/dashboard/dist/assets/{index-CgyucK0e.js.map → index-B7VC0vjf.js.map} +1 -1
- package/dashboard/dist/assets/{index-CQDn-bLr.js → index-BUmnJ4eT.js} +2 -2
- package/dashboard/dist/assets/{index-CQDn-bLr.js.map → index-BUmnJ4eT.js.map} +1 -1
- package/dashboard/dist/assets/{index-DgzgRTNg.js → index-CAqEy2Db.js} +2 -2
- package/dashboard/dist/assets/{index-DgzgRTNg.js.map → index-CAqEy2Db.js.map} +1 -1
- package/dashboard/dist/assets/{index-CByjpYlU.js → index-CMviPjXQ.js} +2 -2
- package/dashboard/dist/assets/{index-CByjpYlU.js.map → index-CMviPjXQ.js.map} +1 -1
- package/dashboard/dist/assets/index-CP0JEQhZ.js +6 -0
- package/dashboard/dist/assets/{index-CucXk58o.js.map → index-CP0JEQhZ.js.map} +1 -1
- package/dashboard/dist/assets/index-CUfgt3mV.js +2 -0
- package/dashboard/dist/assets/index-CUfgt3mV.js.map +1 -0
- package/dashboard/dist/assets/{index-DPJW96d2.js → index-D1xVY4JR.js} +26 -26
- package/dashboard/dist/assets/index-D1xVY4JR.js.map +1 -0
- package/dashboard/dist/assets/{index-CEpw_Fh8.js → index-DPLy-jwO.js} +2 -2
- package/dashboard/dist/assets/{index-CEpw_Fh8.js.map → index-DPLy-jwO.js.map} +1 -1
- package/dashboard/dist/assets/{index-BTqhAT6p.js → index-DjJ6VCuc.js} +2 -2
- package/dashboard/dist/assets/{index-BTqhAT6p.js.map → index-DjJ6VCuc.js.map} +1 -1
- package/dashboard/dist/assets/{index-QxAYCJ1S.js → index-Dsi5o7dx.js} +2 -2
- package/dashboard/dist/assets/{index-QxAYCJ1S.js.map → index-Dsi5o7dx.js.map} +1 -1
- package/dashboard/dist/assets/{index-C2l4GcZ7.js → index-DzVYjoex.js} +3 -3
- package/dashboard/dist/assets/{index-C2l4GcZ7.js.map → index-DzVYjoex.js.map} +1 -1
- package/dashboard/dist/assets/index-FuhiJuHL.js +2 -0
- package/dashboard/dist/assets/index-FuhiJuHL.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-DzRpsm3D.js → knowledge-BKg0cr39.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DzRpsm3D.js.map → knowledge-BKg0cr39.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-B1lc6nL4.js → mcp-CVdHpKlz.js} +2 -2
- package/dashboard/dist/assets/{mcp-B1lc6nL4.js.map → mcp-CVdHpKlz.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CXuweaN3.js → mcp-query-CYxZcbwQ.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CXuweaN3.js.map → mcp-query-CYxZcbwQ.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-D4VLWDvu.js → pipelines-BOEv7P6O.js} +2 -2
- package/dashboard/dist/assets/{pipelines-D4VLWDvu.js.map → pipelines-BOEv7P6O.js.map} +1 -1
- package/dashboard/dist/assets/{roles-CSpHRRu8.js → roles-c5cV2QYQ.js} +2 -2
- package/dashboard/dist/assets/{roles-CSpHRRu8.js.map → roles-c5cV2QYQ.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CWUsKhM4.js → tasks-JV3BjeEF.js} +2 -2
- package/dashboard/dist/assets/{tasks-CWUsKhM4.js.map → tasks-JV3BjeEF.js.map} +1 -1
- package/dashboard/dist/assets/{topics-BXwstrzB.js → topics-BDaPnhnQ.js} +2 -2
- package/dashboard/dist/assets/{topics-BXwstrzB.js.map → topics-BDaPnhnQ.js.map} +1 -1
- package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js +2 -0
- package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js.map +1 -0
- package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js → useEventHooks-a7Dnh8G4.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js.map → useEventHooks-a7Dnh8G4.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CsepDyR5.js → useNamespace-BSwEV0e9.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CsepDyR5.js.map → useNamespace-BSwEV0e9.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js → useYamlActivityEvents-BuqvL-cn.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js.map → useYamlActivityEvents-BuqvL-cn.js.map} +1 -1
- package/dashboard/dist/assets/{users-DvhHbR0R.js → users-Pn85K_3C.js} +2 -2
- package/dashboard/dist/assets/{users-DvhHbR0R.js.map → users-Pn85K_3C.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-Dj2F0Jrb.js → vendor-icons-D5ycKPA2.js} +114 -109
- package/dashboard/dist/assets/vendor-icons-D5ycKPA2.js.map +1 -0
- package/dashboard/dist/assets/{workflows-C7Cam2Ok.js → workflows-DF-9Voyi.js} +2 -2
- package/dashboard/dist/assets/{workflows-C7Cam2Ok.js.map → workflows-DF-9Voyi.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js → yaml-workflows-2roKaSSK.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js.map → yaml-workflows-2roKaSSK.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/mcp/admin.md +156 -12
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js +0 -4
- package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js.map +0 -1
- package/dashboard/dist/assets/AgentsPage-C3FztFd_.js +0 -2
- package/dashboard/dist/assets/AgentsPage-C3FztFd_.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-DTfKCzBQ.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js +0 -2
- package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js +0 -2
- package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js.map +0 -1
- package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js +0 -2
- package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js.map +0 -1
- package/dashboard/dist/assets/StreamMessageDetail-BF0tM0cd.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js.map +0 -1
- package/dashboard/dist/assets/index-CucXk58o.js +0 -6
- package/dashboard/dist/assets/index-DPJW96d2.js.map +0 -1
- package/dashboard/dist/assets/index-DeZhNCf5.js +0 -2
- package/dashboard/dist/assets/index-DeZhNCf5.js.map +0 -1
- package/dashboard/dist/assets/index-Do8Xp3pa.js +0 -2
- package/dashboard/dist/assets/index-Do8Xp3pa.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-Dj2F0Jrb.js.map +0 -1
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import type { DiagnoseSection, DiagnoseVerbosity } from '../services/diagnostics';
|
|
1
2
|
import type { LTApiResult } from '../types/sdk';
|
|
2
3
|
export declare function diagnose(input: {
|
|
3
4
|
workflowId: string;
|
|
4
5
|
appId?: string;
|
|
5
6
|
maxEvents?: number;
|
|
7
|
+
/** Heavy sections to include (events, streams). Default: verdict only. */
|
|
8
|
+
include?: DiagnoseSection[];
|
|
9
|
+
/** Shorthand: 'full' includes events + streams; 'summary' (default) includes neither. */
|
|
10
|
+
verbosity?: DiagnoseVerbosity;
|
|
6
11
|
}): Promise<LTApiResult>;
|
|
7
12
|
export declare function stalledJobs(input: {
|
|
8
13
|
appId?: string;
|
package/build/api/diagnostics.js
CHANGED
|
@@ -6,7 +6,11 @@ exports.orphanedSignals = orphanedSignals;
|
|
|
6
6
|
const diagnostics_1 = require("../services/diagnostics");
|
|
7
7
|
async function diagnose(input) {
|
|
8
8
|
try {
|
|
9
|
-
const diagnosis = await (0, diagnostics_1.diagnoseJob)(input.workflowId, input.appId, {
|
|
9
|
+
const diagnosis = await (0, diagnostics_1.diagnoseJob)(input.workflowId, input.appId, {
|
|
10
|
+
maxEvents: input.maxEvents,
|
|
11
|
+
include: input.include,
|
|
12
|
+
verbosity: input.verbosity,
|
|
13
|
+
});
|
|
10
14
|
return { status: 200, data: diagnosis };
|
|
11
15
|
}
|
|
12
16
|
catch (err) {
|
|
@@ -30,6 +30,7 @@ export declare function listEscalations(input: {
|
|
|
30
30
|
offset?: number;
|
|
31
31
|
sort_by?: string;
|
|
32
32
|
order?: string;
|
|
33
|
+
search?: string;
|
|
33
34
|
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
34
35
|
/**
|
|
35
36
|
* List escalations available for claim (pending and not actively claimed).
|
|
@@ -57,6 +58,7 @@ export declare function listAvailableEscalations(input: {
|
|
|
57
58
|
offset?: number;
|
|
58
59
|
sort_by?: string;
|
|
59
60
|
order?: string;
|
|
61
|
+
search?: string;
|
|
60
62
|
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
61
63
|
/**
|
|
62
64
|
* List all distinct escalation type values.
|
|
@@ -77,6 +77,7 @@ async function listEscalations(input, auth) {
|
|
|
77
77
|
offset: input.offset,
|
|
78
78
|
sort_by: input.sort_by,
|
|
79
79
|
order: input.order,
|
|
80
|
+
search: input.search,
|
|
80
81
|
visibleRoles,
|
|
81
82
|
});
|
|
82
83
|
return { status: 200, data: result };
|
|
@@ -117,6 +118,7 @@ async function listAvailableEscalations(input, auth) {
|
|
|
117
118
|
offset: input.offset,
|
|
118
119
|
sort_by: input.sort_by,
|
|
119
120
|
order: input.order,
|
|
121
|
+
search: input.search,
|
|
120
122
|
visibleRoles,
|
|
121
123
|
});
|
|
122
124
|
return { status: 200, data: result };
|
package/build/api/settings.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ import type { LTApiResult } from '../types/sdk';
|
|
|
8
8
|
* environment block (long-tail + HotMesh versions, Node env/version).
|
|
9
9
|
*
|
|
10
10
|
* @param req — the incoming HTTP request, used to derive NATS WS URL from headers when proxying
|
|
11
|
-
* @returns `{ status: 200, data: { telemetry, escalation, events, auth, ai, environment } }`
|
|
11
|
+
* @returns `{ status: 200, data: { telemetry, escalation, events, auth, ai, features, environment } }`
|
|
12
12
|
*/
|
|
13
13
|
export declare function getSettings(req?: IncomingMessage): Promise<LTApiResult>;
|
package/build/api/settings.js
CHANGED
|
@@ -7,6 +7,7 @@ const nats_1 = require("../lib/events/nats");
|
|
|
7
7
|
const socketio_1 = require("../lib/events/socketio");
|
|
8
8
|
const nats_ws_proxy_1 = require("../lib/events/nats-ws-proxy");
|
|
9
9
|
const config_1 = require("../modules/config");
|
|
10
|
+
const features_1 = require("../modules/features");
|
|
10
11
|
const version_1 = require("../modules/version");
|
|
11
12
|
const sso_1 = require("../modules/sso");
|
|
12
13
|
const defaults_1 = require("../modules/defaults");
|
|
@@ -38,7 +39,7 @@ function resolveNatsWsUrl(adapter, req) {
|
|
|
38
39
|
* environment block (long-tail + HotMesh versions, Node env/version).
|
|
39
40
|
*
|
|
40
41
|
* @param req — the incoming HTTP request, used to derive NATS WS URL from headers when proxying
|
|
41
|
-
* @returns `{ status: 200, data: { telemetry, escalation, events, auth, ai, environment } }`
|
|
42
|
+
* @returns `{ status: 200, data: { telemetry, escalation, events, auth, ai, features, environment } }`
|
|
42
43
|
*/
|
|
43
44
|
async function getSettings(req) {
|
|
44
45
|
try {
|
|
@@ -70,6 +71,7 @@ async function getSettings(req) {
|
|
|
70
71
|
ai: {
|
|
71
72
|
enabled: (0, llm_1.hasLLMApiKey)(),
|
|
72
73
|
},
|
|
74
|
+
features: (0, features_1.getFeatureFlags)(),
|
|
73
75
|
environment: {
|
|
74
76
|
longTailVersion: version_1.LONG_TAIL_VERSION,
|
|
75
77
|
hotmeshVersion: version_1.HOTMESH_VERSION,
|
|
@@ -23,12 +23,16 @@ export declare function invokeWorkflow(input: {
|
|
|
23
23
|
*
|
|
24
24
|
* Returns the HotMesh status code (0 = completed, 1 = running).
|
|
25
25
|
* Resolves the workflow handle via task record or worker registry.
|
|
26
|
+
* `appId` selects the namespace for the job-entity fallback so a child
|
|
27
|
+
* running in another app resolves instead of 404ing against `durable`.
|
|
26
28
|
*
|
|
27
29
|
* @param input.workflowId — HotMesh workflow ID
|
|
30
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
28
31
|
* @returns `{ status: 200, data: { workflowId, status } }` or 404
|
|
29
32
|
*/
|
|
30
33
|
export declare function getWorkflowStatus(input: {
|
|
31
34
|
workflowId: string;
|
|
35
|
+
appId?: string;
|
|
32
36
|
}): Promise<LTApiResult>;
|
|
33
37
|
/**
|
|
34
38
|
* Get the result of a completed workflow.
|
|
@@ -37,10 +41,12 @@ export declare function getWorkflowStatus(input: {
|
|
|
37
41
|
* payload when complete. Never blocks — always returns immediately.
|
|
38
42
|
*
|
|
39
43
|
* @param input.workflowId — HotMesh workflow ID
|
|
44
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
40
45
|
* @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
|
|
41
46
|
*/
|
|
42
47
|
export declare function getWorkflowResult(input: {
|
|
43
48
|
workflowId: string;
|
|
49
|
+
appId?: string;
|
|
44
50
|
}): Promise<LTApiResult>;
|
|
45
51
|
/**
|
|
46
52
|
* Terminate a running workflow.
|
|
@@ -87,13 +87,16 @@ async function invokeWorkflow(input, auth) {
|
|
|
87
87
|
*
|
|
88
88
|
* Returns the HotMesh status code (0 = completed, 1 = running).
|
|
89
89
|
* Resolves the workflow handle via task record or worker registry.
|
|
90
|
+
* `appId` selects the namespace for the job-entity fallback so a child
|
|
91
|
+
* running in another app resolves instead of 404ing against `durable`.
|
|
90
92
|
*
|
|
91
93
|
* @param input.workflowId — HotMesh workflow ID
|
|
94
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
92
95
|
* @returns `{ status: 200, data: { workflowId, status } }` or 404
|
|
93
96
|
*/
|
|
94
97
|
async function getWorkflowStatus(input) {
|
|
95
98
|
try {
|
|
96
|
-
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
|
|
99
|
+
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
|
|
97
100
|
const client = (0, workers_1.createClient)();
|
|
98
101
|
const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
|
|
99
102
|
const status = await handle.status();
|
|
@@ -115,11 +118,12 @@ async function getWorkflowStatus(input) {
|
|
|
115
118
|
* payload when complete. Never blocks — always returns immediately.
|
|
116
119
|
*
|
|
117
120
|
* @param input.workflowId — HotMesh workflow ID
|
|
121
|
+
* @param input.appId — HotMesh namespace for resolution (default: durable)
|
|
118
122
|
* @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
|
|
119
123
|
*/
|
|
120
124
|
async function getWorkflowResult(input) {
|
|
121
125
|
try {
|
|
122
|
-
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
|
|
126
|
+
const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
|
|
123
127
|
const client = (0, workers_1.createClient)();
|
|
124
128
|
const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
|
|
125
129
|
const status = await handle.status();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime feature flags surfaced to the dashboard via /api/settings.
|
|
3
|
+
*
|
|
4
|
+
* These gate UI affordances (nav entries, routes) that some deployments want to
|
|
5
|
+
* hide. Defaults are permissive (everything on); a deployment opts OUT through
|
|
6
|
+
* the `features` block of the `start()` config. The dashboard reads the resolved
|
|
7
|
+
* flags from `settings.features` and hides the corresponding nav item + route.
|
|
8
|
+
*/
|
|
9
|
+
export interface FeatureFlags {
|
|
10
|
+
/**
|
|
11
|
+
* Show the DB Maintenance admin page (nav entry + route).
|
|
12
|
+
* Default: true. Set `features.dbMaintenance: false` in start config to hide it.
|
|
13
|
+
*/
|
|
14
|
+
dbMaintenance: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
17
|
+
export declare function configureFeatureFlags(patch?: Partial<FeatureFlags>): void;
|
|
18
|
+
/** The resolved feature flags reported to the dashboard. */
|
|
19
|
+
export declare function getFeatureFlags(): FeatureFlags;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureFeatureFlags = configureFeatureFlags;
|
|
4
|
+
exports.getFeatureFlags = getFeatureFlags;
|
|
5
|
+
const DEFAULT_FLAGS = {
|
|
6
|
+
dbMaintenance: true,
|
|
7
|
+
};
|
|
8
|
+
let flags = { ...DEFAULT_FLAGS };
|
|
9
|
+
/** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
|
|
10
|
+
function configureFeatureFlags(patch) {
|
|
11
|
+
flags = { ...DEFAULT_FLAGS, ...(patch ?? {}) };
|
|
12
|
+
}
|
|
13
|
+
/** The resolved feature flags reported to the dashboard. */
|
|
14
|
+
function getFeatureFlags() {
|
|
15
|
+
return { ...flags };
|
|
16
|
+
}
|
|
@@ -37,19 +37,32 @@ const express_1 = require("express");
|
|
|
37
37
|
const api = __importStar(require("../api/diagnostics"));
|
|
38
38
|
const auth_1 = require("../modules/auth");
|
|
39
39
|
const router = (0, express_1.Router)();
|
|
40
|
+
const VALID_SECTIONS = new Set(['events', 'streams']);
|
|
41
|
+
/** Parse a comma-separated `include` query param into the recognized heavy sections. */
|
|
42
|
+
function parseInclude(raw) {
|
|
43
|
+
if (typeof raw !== 'string' || raw.trim() === '')
|
|
44
|
+
return undefined;
|
|
45
|
+
const sections = raw.split(',').map((s) => s.trim()).filter((s) => VALID_SECTIONS.has(s));
|
|
46
|
+
return sections.length > 0 ? sections : undefined;
|
|
47
|
+
}
|
|
40
48
|
/**
|
|
41
49
|
* GET /api/diagnostics/jobs/:workflowId
|
|
42
|
-
*
|
|
50
|
+
* Compact diagnosis for a single workflow job — the verdict only by default
|
|
51
|
+
* (status, idle time, stream counts, escalation, findings).
|
|
43
52
|
*
|
|
44
53
|
* Query params:
|
|
45
54
|
* app_id — HotMesh namespace (default: durable)
|
|
46
|
-
* max_events — cap on events returned (most recent kept; default: 500)
|
|
55
|
+
* max_events — cap on events returned when included (most recent kept; default: 500)
|
|
56
|
+
* include — comma-separated heavy sections to add: events, streams
|
|
57
|
+
* verbosity — 'summary' (default, verdict only) or 'full' (events + streams)
|
|
47
58
|
*/
|
|
48
59
|
router.get('/jobs/:workflowId', auth_1.requireAdmin, async (req, res) => {
|
|
49
60
|
const result = await api.diagnose({
|
|
50
61
|
workflowId: req.params.workflowId,
|
|
51
62
|
appId: typeof req.query.app_id === 'string' ? req.query.app_id : undefined,
|
|
52
63
|
maxEvents: req.query.max_events ? Number(req.query.max_events) : undefined,
|
|
64
|
+
include: parseInclude(req.query.include),
|
|
65
|
+
verbosity: req.query.verbosity === 'full' ? 'full' : undefined,
|
|
53
66
|
});
|
|
54
67
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
55
68
|
});
|
|
@@ -76,6 +76,7 @@ function registerListRoutes(router) {
|
|
|
76
76
|
offset: req.query.offset ? parseInt(req.query.offset, 10) : undefined,
|
|
77
77
|
sort_by: req.query.sort_by,
|
|
78
78
|
order: req.query.order,
|
|
79
|
+
search: req.query.search,
|
|
79
80
|
}, req.auth);
|
|
80
81
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
81
82
|
});
|
|
@@ -94,6 +95,7 @@ function registerListRoutes(router) {
|
|
|
94
95
|
offset: req.query.offset ? parseInt(req.query.offset, 10) : undefined,
|
|
95
96
|
sort_by: req.query.sort_by,
|
|
96
97
|
order: req.query.order,
|
|
98
|
+
search: req.query.search,
|
|
97
99
|
}, req.auth);
|
|
98
100
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
99
101
|
});
|
|
@@ -66,19 +66,27 @@ router.post('/:type/invoke', async (req, res) => {
|
|
|
66
66
|
// ── Workflow observation ────────────────────────────────────────────────────
|
|
67
67
|
/**
|
|
68
68
|
* GET /api/workflows/:workflowId/status
|
|
69
|
-
* Get the status of a workflow.
|
|
69
|
+
* Get the status of a workflow. Optional `app_id` query param selects the
|
|
70
|
+
* HotMesh namespace for resolution (default: durable).
|
|
70
71
|
*/
|
|
71
72
|
router.get('/:workflowId/status', async (req, res) => {
|
|
72
|
-
const result = await api.getWorkflowStatus({
|
|
73
|
+
const result = await api.getWorkflowStatus({
|
|
74
|
+
workflowId: req.params.workflowId,
|
|
75
|
+
appId: typeof req.query.app_id === 'string' ? req.query.app_id : undefined,
|
|
76
|
+
});
|
|
73
77
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
74
78
|
});
|
|
75
79
|
/**
|
|
76
80
|
* GET /api/workflows/:workflowId/result
|
|
77
81
|
* Return the workflow result if complete, or 202 if still running.
|
|
78
|
-
* Never blocks — always returns immediately.
|
|
82
|
+
* Never blocks — always returns immediately. Optional `app_id` query param
|
|
83
|
+
* selects the HotMesh namespace for resolution (default: durable).
|
|
79
84
|
*/
|
|
80
85
|
router.get('/:workflowId/result', async (req, res) => {
|
|
81
|
-
const result = await api.getWorkflowResult({
|
|
86
|
+
const result = await api.getWorkflowResult({
|
|
87
|
+
workflowId: req.params.workflowId,
|
|
88
|
+
appId: typeof req.query.app_id === 'string' ? req.query.app_id : undefined,
|
|
89
|
+
});
|
|
82
90
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
83
91
|
});
|
|
84
92
|
/**
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -95,6 +95,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
95
95
|
offset?: number;
|
|
96
96
|
sort_by?: string;
|
|
97
97
|
order?: string;
|
|
98
|
+
search?: string;
|
|
98
99
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
99
100
|
listAvailable: (input: {
|
|
100
101
|
role?: string;
|
|
@@ -105,6 +106,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
105
106
|
offset?: number;
|
|
106
107
|
sort_by?: string;
|
|
107
108
|
order?: string;
|
|
109
|
+
search?: string;
|
|
108
110
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
109
111
|
listTypes: typeof escalationsApi.listDistinctTypes;
|
|
110
112
|
getStats: (input: {
|
|
@@ -17,6 +17,21 @@ export interface StreamSummary {
|
|
|
17
17
|
pending: number;
|
|
18
18
|
in_flight: number;
|
|
19
19
|
}
|
|
20
|
+
/** A large string field replaced with a bounded summary instead of the full payload. */
|
|
21
|
+
export interface TruncatedString {
|
|
22
|
+
bytes: number;
|
|
23
|
+
preview: string;
|
|
24
|
+
truncated: true;
|
|
25
|
+
}
|
|
26
|
+
/** Pointer to the stream browser for the raw, untruncated message payloads. */
|
|
27
|
+
export interface RawMessagesHint {
|
|
28
|
+
hint: string;
|
|
29
|
+
jid: string;
|
|
30
|
+
}
|
|
31
|
+
/** A stream message whose large `message` payload may have been summarized. */
|
|
32
|
+
export type SummarizedStreamMessage = Omit<StreamMessage, 'message'> & {
|
|
33
|
+
message: string | TruncatedString;
|
|
34
|
+
};
|
|
20
35
|
export interface JobDiagnosis {
|
|
21
36
|
workflow_id: string;
|
|
22
37
|
app_id: string;
|
|
@@ -32,18 +47,37 @@ export interface JobDiagnosis {
|
|
|
32
47
|
stream_summary: StreamSummary;
|
|
33
48
|
escalation: EscalationSummary;
|
|
34
49
|
findings: Finding[];
|
|
35
|
-
execution_events: unknown[];
|
|
36
50
|
/** Total events before any cap was applied (execution_events may be truncated to the most recent `maxEvents`). */
|
|
37
51
|
total_events: number;
|
|
38
52
|
events_truncated: boolean;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Full event timeline — present only when `include` contains `'events'` (or
|
|
55
|
+
* `verbosity: 'full'`). Large string attributes are summarized to
|
|
56
|
+
* `{ bytes, preview, truncated }`. Omitted by default to keep the verdict compact.
|
|
57
|
+
*/
|
|
58
|
+
execution_events?: unknown[];
|
|
59
|
+
/**
|
|
60
|
+
* Raw engine + worker stream messages — present only when `include` contains
|
|
61
|
+
* `'streams'` (or `verbosity: 'full'`). Large `message` payloads are summarized.
|
|
62
|
+
* Omitted by default; see `raw_messages` for where to fetch the full payloads.
|
|
63
|
+
*/
|
|
64
|
+
stream_messages?: {
|
|
65
|
+
worker: SummarizedStreamMessage[];
|
|
66
|
+
engine: SummarizedStreamMessage[];
|
|
42
67
|
};
|
|
68
|
+
/** Pointer to `list_stream_messages` for the raw payloads (present when streams are omitted). */
|
|
69
|
+
raw_messages?: RawMessagesHint;
|
|
43
70
|
}
|
|
44
|
-
export
|
|
71
|
+
export type DiagnoseVerbosity = 'summary' | 'full';
|
|
72
|
+
export type DiagnoseSection = 'events' | 'streams';
|
|
73
|
+
export interface DiagnoseOptions {
|
|
45
74
|
maxEvents?: number;
|
|
46
|
-
|
|
75
|
+
/** Heavy sections to include in the response. Default: none (verdict only). */
|
|
76
|
+
include?: DiagnoseSection[];
|
|
77
|
+
/** Shorthand: `'full'` includes both events and streams; `'summary'` (default) includes neither. */
|
|
78
|
+
verbosity?: DiagnoseVerbosity;
|
|
79
|
+
}
|
|
80
|
+
export declare function diagnoseJob(workflowId: string, appId?: string, options?: DiagnoseOptions): Promise<JobDiagnosis>;
|
|
47
81
|
export declare function findStalledJobs(params: {
|
|
48
82
|
appId?: string;
|
|
49
83
|
idleMinutes?: number;
|
|
@@ -88,10 +88,39 @@ const ORPHANED_SIGNALS = (appId) => `
|
|
|
88
88
|
`;
|
|
89
89
|
/** Default cap on events returned in the payload — keeps a high-activity workflow from returning a huge response. */
|
|
90
90
|
const DEFAULT_MAX_EVENTS = 500;
|
|
91
|
+
/** Strings larger than this (UTF-8 bytes) are summarized rather than returned in full. */
|
|
92
|
+
const LARGE_STRING_BYTES = 1024;
|
|
93
|
+
/** How many leading characters of a summarized string to keep as a preview. */
|
|
94
|
+
const PREVIEW_CHARS = 200;
|
|
95
|
+
/** Recursion depth cap for summarizing nested event attributes. */
|
|
96
|
+
const SUMMARIZE_MAX_DEPTH = 6;
|
|
97
|
+
/** Replace an over-threshold string with a bounded summary; pass small strings through unchanged. */
|
|
98
|
+
function summarizeString(value) {
|
|
99
|
+
const bytes = Buffer.byteLength(value, 'utf8');
|
|
100
|
+
if (bytes <= LARGE_STRING_BYTES)
|
|
101
|
+
return value;
|
|
102
|
+
return { bytes, preview: value.slice(0, PREVIEW_CHARS), truncated: true };
|
|
103
|
+
}
|
|
104
|
+
/** Recursively summarize large string leaves in an event attribute tree (result/output/input/error payloads). */
|
|
105
|
+
function summarizeDeep(value, depth = 0) {
|
|
106
|
+
if (typeof value === 'string')
|
|
107
|
+
return summarizeString(value);
|
|
108
|
+
if (value === null || typeof value !== 'object' || depth >= SUMMARIZE_MAX_DEPTH)
|
|
109
|
+
return value;
|
|
110
|
+
if (Array.isArray(value))
|
|
111
|
+
return value.map((v) => summarizeDeep(v, depth + 1));
|
|
112
|
+
const out = {};
|
|
113
|
+
for (const [k, v] of Object.entries(value)) {
|
|
114
|
+
out[k] = summarizeDeep(v, depth + 1);
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
91
118
|
// ── diagnoseJob ──────────────────────────────────────────────────────────────
|
|
92
119
|
async function diagnoseJob(workflowId, appId = 'durable', options = {}) {
|
|
93
120
|
const pool = (0, db_1.getPool)();
|
|
94
121
|
const maxEvents = Math.max(options.maxEvents ?? DEFAULT_MAX_EVENTS, 1);
|
|
122
|
+
const includeEvents = options.verbosity === 'full' || !!options.include?.includes('events');
|
|
123
|
+
const includeStreams = options.verbosity === 'full' || !!options.include?.includes('streams');
|
|
95
124
|
let resolved;
|
|
96
125
|
try {
|
|
97
126
|
resolved = await (0, resolve_1.resolveWorkflowHandle)(workflowId);
|
|
@@ -135,7 +164,7 @@ async function diagnoseJob(workflowId, appId = 'durable', options = {}) {
|
|
|
135
164
|
const findings = execution
|
|
136
165
|
? (0, patterns_1.matchPatterns)(execution, workerMessages, engineMessages, escalationRow)
|
|
137
166
|
: [{ condition: 'export_unavailable', confidence: 0.9, severity: 'warning', evidence: ['Execution export unavailable — job may have expired or HotMesh engine is not running'], guidance: [] }];
|
|
138
|
-
|
|
167
|
+
const diagnosis = {
|
|
139
168
|
workflow_id: workflowId,
|
|
140
169
|
app_id: appId,
|
|
141
170
|
status,
|
|
@@ -153,11 +182,33 @@ async function diagnoseJob(workflowId, appId = 'durable', options = {}) {
|
|
|
153
182
|
created_at: escalationRow?.created_at ?? null,
|
|
154
183
|
},
|
|
155
184
|
findings,
|
|
156
|
-
execution_events: cappedEvents,
|
|
157
185
|
total_events: events.length,
|
|
158
186
|
events_truncated: eventsTruncated,
|
|
159
|
-
stream_messages: { worker: workerMessages, engine: engineMessages },
|
|
160
187
|
};
|
|
188
|
+
// Heavy sections are opt-in. Large string payloads are summarized either way
|
|
189
|
+
// so an included section can't reintroduce the 100–200KB blow-up.
|
|
190
|
+
if (includeEvents) {
|
|
191
|
+
diagnosis.execution_events = cappedEvents.map((e) => e && typeof e === 'object'
|
|
192
|
+
? { ...e, attributes: summarizeDeep(e.attributes) }
|
|
193
|
+
: e);
|
|
194
|
+
}
|
|
195
|
+
if (includeStreams) {
|
|
196
|
+
diagnosis.stream_messages = {
|
|
197
|
+
worker: summarizeMessages(workerMessages),
|
|
198
|
+
engine: summarizeMessages(engineMessages),
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
diagnosis.raw_messages = {
|
|
203
|
+
hint: 'Use list_stream_messages (Control Plane) filtered by jid (and aid/dad) for the full raw message payloads.',
|
|
204
|
+
jid: workflowId,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return diagnosis;
|
|
208
|
+
}
|
|
209
|
+
/** Summarize the large `message` payload of each stream message; everything else passes through. */
|
|
210
|
+
function summarizeMessages(messages) {
|
|
211
|
+
return messages.map((m) => ({ ...m, message: summarizeString(m.message) }));
|
|
161
212
|
}
|
|
162
213
|
// ── findStalledJobs ──────────────────────────────────────────────────────────
|
|
163
214
|
async function findStalledJobs(params) {
|
|
@@ -200,9 +251,7 @@ function notFound(workflowId, appId) {
|
|
|
200
251
|
stream_summary: { worker_total: 0, engine_total: 0, dead_lettered: 0, pending: 0, in_flight: 0 },
|
|
201
252
|
escalation: { exists: false, id: null, status: null, signal_key: null, role: null, type: null, created_at: null },
|
|
202
253
|
findings: [{ condition: 'not_found', confidence: 1, severity: 'critical', evidence: ['Workflow ID not found — no task record or job entity'], guidance: [] }],
|
|
203
|
-
execution_events: [],
|
|
204
254
|
total_events: 0,
|
|
205
255
|
events_truncated: false,
|
|
206
|
-
stream_messages: { worker: [], engine: [] },
|
|
207
256
|
};
|
|
208
257
|
}
|
|
@@ -15,6 +15,7 @@ export declare function listEscalations(filters: {
|
|
|
15
15
|
visibleRoles?: string[];
|
|
16
16
|
sort_by?: string;
|
|
17
17
|
order?: string;
|
|
18
|
+
search?: string;
|
|
18
19
|
}): Promise<{
|
|
19
20
|
escalations: LTEscalationRecord[];
|
|
20
21
|
total: number;
|
|
@@ -32,6 +33,7 @@ export declare function listAvailableEscalations(filters: {
|
|
|
32
33
|
visibleRoles?: string[];
|
|
33
34
|
sort_by?: string;
|
|
34
35
|
order?: string;
|
|
36
|
+
search?: string;
|
|
35
37
|
}): Promise<{
|
|
36
38
|
escalations: LTEscalationRecord[];
|
|
37
39
|
total: number;
|
|
@@ -4,9 +4,11 @@ exports.getEscalationStats = getEscalationStats;
|
|
|
4
4
|
exports.listDistinctTypes = listDistinctTypes;
|
|
5
5
|
exports.listEscalations = listEscalations;
|
|
6
6
|
exports.listAvailableEscalations = listAvailableEscalations;
|
|
7
|
+
const db_1 = require("../../lib/db");
|
|
7
8
|
const client_1 = require("./client");
|
|
8
9
|
const map_1 = require("./map");
|
|
9
10
|
const types_1 = require("./types");
|
|
11
|
+
const sql_1 = require("./sql");
|
|
10
12
|
/**
|
|
11
13
|
* Default sort is priority ASC, created_at ASC. A user-chosen `sort_by` maps to
|
|
12
14
|
* a single column (DESC unless `order='asc'`), matching the legacy behavior.
|
|
@@ -20,6 +22,50 @@ function buildOrderBy(sortBy, order) {
|
|
|
20
22
|
{ column: 'created_at', direction: 'asc' },
|
|
21
23
|
];
|
|
22
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* ORDER BY clause for the raw search query. `sortBy` is checked against the
|
|
27
|
+
* SORTABLE_COLUMNS whitelist before interpolation, so it is injection-safe.
|
|
28
|
+
*/
|
|
29
|
+
function buildSearchOrderBy(sortBy, order) {
|
|
30
|
+
const dir = order === 'asc' ? 'ASC' : 'DESC';
|
|
31
|
+
if (sortBy && types_1.SORTABLE_COLUMNS.has(sortBy)) {
|
|
32
|
+
return `${sortBy} ${dir}`;
|
|
33
|
+
}
|
|
34
|
+
return 'priority ASC, created_at ASC';
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Server-side free-text search over the `lt_escalations` view. Runs when a
|
|
38
|
+
* caller supplies a non-empty `search` term — the SDK `client.list()` cannot do
|
|
39
|
+
* free-text, so this is raw SQL on the shared table (see ./sql.ts). All other
|
|
40
|
+
* filters combine with the term (AND).
|
|
41
|
+
*/
|
|
42
|
+
async function searchEscalations(params) {
|
|
43
|
+
await (0, client_1.ensureEscalationCompatView)();
|
|
44
|
+
const pool = (0, db_1.getPool)();
|
|
45
|
+
// Coerce empty strings to NULL so an absent filter (e.g. assigned_to='') does
|
|
46
|
+
// not become `column = ''` and match zero rows. Mirrors the SDK path's
|
|
47
|
+
// `if (filters.x)` truthiness guards.
|
|
48
|
+
const filterArgs = [
|
|
49
|
+
params.status || null,
|
|
50
|
+
params.role || null,
|
|
51
|
+
params.roles && params.roles.length ? params.roles : null,
|
|
52
|
+
params.type || null,
|
|
53
|
+
params.subtype || null,
|
|
54
|
+
params.priority ?? null,
|
|
55
|
+
params.assigned_to || null,
|
|
56
|
+
params.available ?? null,
|
|
57
|
+
params.search,
|
|
58
|
+
];
|
|
59
|
+
const orderBy = buildSearchOrderBy(params.sort_by, params.order);
|
|
60
|
+
const [rows, countRows] = await Promise.all([
|
|
61
|
+
pool.query((0, sql_1.searchEscalationsQuery)(orderBy), [...filterArgs, params.limit, params.offset]),
|
|
62
|
+
pool.query(sql_1.COUNT_SEARCH_ESCALATIONS, filterArgs),
|
|
63
|
+
]);
|
|
64
|
+
return {
|
|
65
|
+
escalations: (0, map_1.toEscalationRecords)(rows.rows),
|
|
66
|
+
total: countRows.rows[0]?.total ?? 0,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
23
69
|
async function getEscalationStats(visibleRoles, period) {
|
|
24
70
|
const client = await (0, client_1.escalations)();
|
|
25
71
|
return client.stats({
|
|
@@ -32,6 +78,26 @@ async function listDistinctTypes() {
|
|
|
32
78
|
return client.listDistinctTypes();
|
|
33
79
|
}
|
|
34
80
|
async function listEscalations(filters) {
|
|
81
|
+
// Active claim semantics: assigned_to-active and `claimed` both mean "held now".
|
|
82
|
+
const heldNow = !!(filters.assigned_to || filters.claimed);
|
|
83
|
+
// Free-text search → server-side SQL path (the SDK list() has no free-text).
|
|
84
|
+
if (filters.search) {
|
|
85
|
+
return searchEscalations({
|
|
86
|
+
status: filters.status,
|
|
87
|
+
role: filters.role,
|
|
88
|
+
roles: filters.visibleRoles,
|
|
89
|
+
type: filters.type,
|
|
90
|
+
subtype: filters.subtype,
|
|
91
|
+
priority: filters.priority,
|
|
92
|
+
assigned_to: filters.assigned_to,
|
|
93
|
+
available: heldNow ? false : undefined,
|
|
94
|
+
search: filters.search,
|
|
95
|
+
limit: filters.limit ?? 50,
|
|
96
|
+
offset: filters.offset ?? 0,
|
|
97
|
+
sort_by: filters.sort_by,
|
|
98
|
+
order: filters.order,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
35
101
|
const client = await (0, client_1.escalations)();
|
|
36
102
|
// Shared filter — passed to both list() and count() so totals stay in sync.
|
|
37
103
|
const where = {
|
|
@@ -44,8 +110,7 @@ async function listEscalations(filters) {
|
|
|
44
110
|
};
|
|
45
111
|
if (filters.assigned_to)
|
|
46
112
|
where.assignedTo = filters.assigned_to;
|
|
47
|
-
|
|
48
|
-
if (filters.assigned_to || filters.claimed)
|
|
113
|
+
if (heldNow)
|
|
49
114
|
where.available = false;
|
|
50
115
|
const [rows, total] = await Promise.all([
|
|
51
116
|
client.list({
|
|
@@ -62,6 +127,23 @@ async function listEscalations(filters) {
|
|
|
62
127
|
* List available escalations: pending AND (unassigned OR expired claim).
|
|
63
128
|
*/
|
|
64
129
|
async function listAvailableEscalations(filters) {
|
|
130
|
+
// Free-text search → server-side SQL path (available = pending + no active claim).
|
|
131
|
+
if (filters.search) {
|
|
132
|
+
return searchEscalations({
|
|
133
|
+
status: 'pending',
|
|
134
|
+
role: filters.role,
|
|
135
|
+
roles: filters.visibleRoles,
|
|
136
|
+
type: filters.type,
|
|
137
|
+
subtype: filters.subtype,
|
|
138
|
+
priority: filters.priority,
|
|
139
|
+
available: true,
|
|
140
|
+
search: filters.search,
|
|
141
|
+
limit: filters.limit ?? 50,
|
|
142
|
+
offset: filters.offset ?? 0,
|
|
143
|
+
sort_by: filters.sort_by,
|
|
144
|
+
order: filters.order,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
65
147
|
const client = await (0, client_1.escalations)();
|
|
66
148
|
const where = {
|
|
67
149
|
status: 'pending',
|
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
* table. Clears both `assigned_until` and `claim_expires_at`.
|
|
9
9
|
*/
|
|
10
10
|
export declare const RELEASE_EXPIRED_CLAIMS = "UPDATE public.hmsh_escalations\nSET assigned_to = NULL,\n assigned_until = NULL,\n claimed_at = NULL,\n claim_expires_at = NULL,\n updated_at = NOW()\nWHERE status = 'pending'\n AND assigned_to IS NOT NULL\n AND assigned_until <= NOW()";
|
|
11
|
+
/** Count matching the search WHERE (params $1–$9). */
|
|
12
|
+
export declare const COUNT_SEARCH_ESCALATIONS = "SELECT COUNT(*)::int AS total\n FROM public.lt_escalations\n WHERE ($1::text IS NULL OR status = $1)\n AND ($2::text IS NULL OR role = $2)\n AND ($3::text[] IS NULL OR role = ANY($3))\n AND ($4::text IS NULL OR type = $4)\n AND ($5::text IS NULL OR subtype = $5)\n AND ($6::int IS NULL OR priority = $6)\n AND ($7::text IS NULL OR assigned_to = $7)\n AND ($8::boolean IS NULL OR available = $8)\n AND ($9::text IS NULL OR (\n description ILIKE '%' || $9 || '%'\n OR type ILIKE '%' || $9 || '%'\n OR subtype ILIKE '%' || $9 || '%'\n OR role ILIKE '%' || $9 || '%'\n OR workflow_id ILIKE '%' || $9 || '%'\n OR origin_id ILIKE '%' || $9 || '%'\n OR id::text ILIKE '%' || $9 || '%'\n OR metadata::text ILIKE '%' || $9 || '%'\n ))";
|
|
13
|
+
/**
|
|
14
|
+
* Build the search SELECT. `orderBy` is composed from a whitelist by the caller
|
|
15
|
+
* (never raw user input), so it is safe to interpolate; everything else is bound.
|
|
16
|
+
*/
|
|
17
|
+
export declare function searchEscalationsQuery(orderBy: string): string;
|
|
11
18
|
/**
|
|
12
19
|
* Atomic resolve by metadata with signal guard.
|
|
13
20
|
*
|