@hotmeshio/long-tail 0.4.22 → 0.4.24
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/dba.d.ts +2 -1
- package/build/api/dba.js +3 -2
- package/build/api/exports.d.ts +1 -0
- package/build/api/exports.js +1 -1
- package/build/api/maintenance.d.ts +1 -0
- package/build/api/maintenance.js +3 -3
- package/build/api/overview.d.ts +4 -0
- package/build/api/overview.js +13 -0
- package/build/api/workflows/discovery.js +5 -2
- package/build/modules/maintenance.js +1 -0
- package/build/routes/controlplane.js +40 -29
- package/build/routes/dba.js +13 -2
- package/build/routes/exports.js +6 -0
- package/build/routes/index.js +2 -0
- package/build/routes/maintenance.js +1 -0
- package/build/routes/overview.d.ts +2 -0
- package/build/routes/overview.js +50 -0
- package/build/services/controlplane/index.js +7 -5
- package/build/services/dba.d.ts +3 -1
- package/build/services/dba.js +5 -4
- package/build/services/export/index.d.ts +2 -2
- package/build/services/export/index.js +16 -10
- package/build/services/maintenance/index.js +7 -4
- package/build/services/overview/index.d.ts +78 -0
- package/build/services/overview/index.js +105 -0
- package/build/services/overview/sql.d.ts +29 -0
- package/build/services/overview/sql.js +134 -0
- package/build/services/pipelines/queries.js +5 -2
- package/build/services/pipelines/sql.d.ts +0 -1
- package/build/services/pipelines/sql.js +1 -3
- package/build/system/mcp-servers/admin/controlplane.js +1 -1
- package/build/system/mcp-servers/admin/index.js +4 -2
- package/build/system/mcp-servers/admin/maintenance.js +1 -0
- package/build/system/mcp-servers/admin/overview.d.ts +13 -0
- package/build/system/mcp-servers/admin/overview.js +34 -0
- package/build/system/mcp-servers/admin/pipelines.js +4 -4
- package/build/system/mcp-servers/admin/schemas.d.ts +26 -20
- package/build/system/mcp-servers/admin/schemas.js +17 -15
- package/build/system/seed/tool-manifests-admin.d.ts +114 -0
- package/build/system/seed/tool-manifests-admin.js +2 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/maintenance.d.ts +2 -0
- package/dashboard/dist/assets/{AdminDashboard-BwUGcCxQ.js → AdminDashboard-CgJC8ZZF.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BwUGcCxQ.js.map → AdminDashboard-CgJC8ZZF.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-DgrYzLwq.js → AgentConfigPage-Bjl2Lsvo.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-DgrYzLwq.js.map → AgentConfigPage-Bjl2Lsvo.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-XJpl7wfJ.js → AgentDetailPage-D5dHrfaM.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-XJpl7wfJ.js.map → AgentDetailPage-D5dHrfaM.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-CGpVG6r8.js → AgentsPage-Mom3N1Av.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-CGpVG6r8.js.map → AgentsPage-Mom3N1Av.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-DR1e0TQZ.js → AvailableEscalationsPage-B2ZAb41C.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-DR1e0TQZ.js.map → AvailableEscalationsPage-B2ZAb41C.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-BKtjl6IL.js → BotPicker-dCvnjynP.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-BKtjl6IL.js.map → BotPicker-dCvnjynP.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-kCB8fyOj.js → CapabilitiesPage-CK2fJ9Sy.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-kCB8fyOj.js.map → CapabilitiesPage-CK2fJ9Sy.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-C3tU61hB.js → CollapsibleSection-bW0UZN9b.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-C3tU61hB.js.map → CollapsibleSection-bW0UZN9b.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-Dt4nJs_B.js → CredentialsPage-DVOK3aaR.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-Dt4nJs_B.js.map → CredentialsPage-DVOK3aaR.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-BdE6mHyA.js → CronLabel-Cv5em7OP.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-BdE6mHyA.js.map → CronLabel-Cv5em7OP.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-B_Yxfb-u.js → CustomDurationPicker-Dy4NBqhZ.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-B_Yxfb-u.js.map → CustomDurationPicker-Dy4NBqhZ.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-tcGx5PFI.js → ElapsedCell-TQqWaVRq.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-tcGx5PFI.js.map → ElapsedCell-TQqWaVRq.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-1KO5dXzk.js → EscalationsOverview-Cv5UvuHI.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-1KO5dXzk.js.map → EscalationsOverview-Cv5UvuHI.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DnpsQ6Ew.js → EventTable-Doky6fCO.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DnpsQ6Ew.js.map → EventTable-Doky6fCO.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-CzvVyTq4.js +2 -0
- package/dashboard/dist/assets/HomePage-CzvVyTq4.js.map +1 -0
- package/dashboard/dist/assets/{ListToolbar-jrVba7QN.js → ListToolbar-Cfec9gz_.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-jrVba7QN.js.map → ListToolbar-Cfec9gz_.js.map} +1 -1
- package/dashboard/dist/assets/McpOverview-BN4GsBGI.js +2 -0
- package/dashboard/dist/assets/McpOverview-BN4GsBGI.js.map +1 -0
- package/dashboard/dist/assets/McpQueryDetailPage-lCW668WQ.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-lCW668WQ.js.map +1 -0
- package/dashboard/dist/assets/{McpQueryPage-WZfTY43_.js → McpQueryPage-BK5L2PqJ.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-WZfTY43_.js.map → McpQueryPage-BK5L2PqJ.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-CQOeYqxa.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-CQOeYqxa.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-QsXid9Xe.js +2 -0
- package/dashboard/dist/assets/McpRunsPage-QsXid9Xe.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-Cy7ySMXj.js → OperatorDashboard-CZQSINho.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-Cy7ySMXj.js.map → OperatorDashboard-CZQSINho.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DYIfvWyc.js → ProcessDetailPage-DUCOOvOK.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DYIfvWyc.js.map → ProcessDetailPage-DUCOOvOK.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DR1RGaMl.js → ProcessesListPage-CXvSLTIM.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DR1RGaMl.js.map → ProcessesListPage-CXvSLTIM.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-DlQR0Iz_.js +2 -0
- package/dashboard/dist/assets/RolesPage-DlQR0Iz_.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-B-ksMoEj.js → RunAsSelector-DP-jxsv6.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-B-ksMoEj.js.map → RunAsSelector-DP-jxsv6.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-Cr_K5qpu.js → SwimlaneTimeline-BmASA0nN.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-Cr_K5qpu.js.map → SwimlaneTimeline-BmASA0nN.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-BO5p7AEe.js → TaskDetailPage-CRowpkeZ.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-BO5p7AEe.js.map → TaskDetailPage-CRowpkeZ.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BRg-uFtF.js → TasksListPage-uJ6z37J-.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BRg-uFtF.js.map → TasksListPage-uJ6z37J-.js.map} +1 -1
- package/dashboard/dist/assets/TimeAgo-BxwngK1D.js +2 -0
- package/dashboard/dist/assets/{TimeAgo-BSzN6rAH.js.map → TimeAgo-BxwngK1D.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DL6zMNEQ.js → TimestampCell-CDmichOM.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DL6zMNEQ.js.map → TimestampCell-CDmichOM.js.map} +1 -1
- package/dashboard/dist/assets/ToolTestPanel-xjTn8sU8.js +2 -0
- package/dashboard/dist/assets/ToolTestPanel-xjTn8sU8.js.map +1 -0
- package/dashboard/dist/assets/{TopicDetailPage-D7gCsPKB.js → TopicDetailPage-Dm0hDlS8.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-D7gCsPKB.js.map → TopicDetailPage-Dm0hDlS8.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-B3Aa8Haz.js → TopicsPage-letISGGD.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-B3Aa8Haz.js.map → TopicsPage-letISGGD.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BjHIJWgh.js → UserName-W6_Iz2Qb.js} +2 -2
- package/dashboard/dist/assets/{UserName-BjHIJWgh.js.map → UserName-W6_Iz2Qb.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQ7AYlQA.js → WorkflowExecutionPage-Cfx-xlRT.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQ7AYlQA.js.map → WorkflowExecutionPage-Cfx-xlRT.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-DC4XHMWt.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-DC4XHMWt.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-B4DUcVxs.js → WorkflowsOverview-GefO_yn0.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-B4DUcVxs.js.map → WorkflowsOverview-GefO_yn0.js.map} +1 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-CMsrFooO.js +2 -0
- package/dashboard/dist/assets/YamlWorkflowsPage-CMsrFooO.js.map +1 -0
- package/dashboard/dist/assets/{agents-CkvQDr9b.js → agents-BI5OeN84.js} +2 -2
- package/dashboard/dist/assets/{agents-CkvQDr9b.js.map → agents-BI5OeN84.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CzuMCVgU.js → bots-1UzUCsrR.js} +2 -2
- package/dashboard/dist/assets/{bots-CzuMCVgU.js.map → bots-1UzUCsrR.js.map} +1 -1
- package/dashboard/dist/assets/capabilities-BUbl-ojp.js +2 -0
- package/dashboard/dist/assets/{capabilities-CbGmS0ty.js.map → capabilities-BUbl-ojp.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-DGvwkuYx.js → controlplane-DTFrH_vN.js} +2 -2
- package/dashboard/dist/assets/{controlplane-DGvwkuYx.js.map → controlplane-DTFrH_vN.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-B7ysVToF.js → escalation-BQhCt4W0.js} +2 -2
- package/dashboard/dist/assets/{escalation-B7ysVToF.js.map → escalation-BQhCt4W0.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-CHQEJU1j.js → escalation-columns-J20k5CcY.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-CHQEJU1j.js.map → escalation-columns-J20k5CcY.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-BFOjXa4r.js → helpers-ge6Eu90Y.js} +2 -2
- package/dashboard/dist/assets/{helpers-BFOjXa4r.js.map → helpers-ge6Eu90Y.js.map} +1 -1
- package/dashboard/dist/assets/index-C-mbURj-.js +2 -0
- package/dashboard/dist/assets/index-C-mbURj-.js.map +1 -0
- package/dashboard/dist/assets/{index-BduDiGcw.js → index-C45DvtAZ.js} +2 -2
- package/dashboard/dist/assets/{index-BduDiGcw.js.map → index-C45DvtAZ.js.map} +1 -1
- package/dashboard/dist/assets/{index-B9_1AZaG.js → index-C9ClHiiW.js} +2 -2
- package/dashboard/dist/assets/{index-B9_1AZaG.js.map → index-C9ClHiiW.js.map} +1 -1
- package/dashboard/dist/assets/index-CLUYzdwz.js +2 -0
- package/dashboard/dist/assets/{index-DQHmfTPo.js.map → index-CLUYzdwz.js.map} +1 -1
- package/dashboard/dist/assets/{index-l_8R6U4r.js → index-CVGgSoda.js} +2 -2
- package/dashboard/dist/assets/{index-l_8R6U4r.js.map → index-CVGgSoda.js.map} +1 -1
- package/dashboard/dist/assets/{index-_BRA9uFL.js → index-CWEOhAiK.js} +3 -3
- package/dashboard/dist/assets/{index-_BRA9uFL.js.map → index-CWEOhAiK.js.map} +1 -1
- package/dashboard/dist/assets/{index-BFaDxPxA.js → index-CWlP6vHG.js} +2 -2
- package/dashboard/dist/assets/{index-BFaDxPxA.js.map → index-CWlP6vHG.js.map} +1 -1
- package/dashboard/dist/assets/index-DasoTRjT.js +2 -0
- package/dashboard/dist/assets/{index-BeLphL59.js.map → index-DasoTRjT.js.map} +1 -1
- package/dashboard/dist/assets/{index-CvOGgvzP.js → index-FhasoOjO.js} +2 -2
- package/dashboard/dist/assets/{index-CvOGgvzP.js.map → index-FhasoOjO.js.map} +1 -1
- package/dashboard/dist/assets/{index-a98qWLB-.js → index-WQQJ_cp7.js} +2 -2
- package/dashboard/dist/assets/{index-a98qWLB-.js.map → index-WQQJ_cp7.js.map} +1 -1
- package/dashboard/dist/assets/{index-CbrMW-gM.js → index-hAZiac0C.js} +2 -2
- package/dashboard/dist/assets/{index-CbrMW-gM.js.map → index-hAZiac0C.js.map} +1 -1
- package/dashboard/dist/assets/{index-v0OQpgXS.js → index-si70YcIP.js} +2 -2
- package/dashboard/dist/assets/{index-v0OQpgXS.js.map → index-si70YcIP.js.map} +1 -1
- package/dashboard/dist/assets/{index-CRiBkHPb.js → index-vgxjge70.js} +2 -2
- package/dashboard/dist/assets/{index-CRiBkHPb.js.map → index-vgxjge70.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-BlF8UMrk.js → knowledge-D9Tuh-o-.js} +2 -2
- package/dashboard/dist/assets/{knowledge-BlF8UMrk.js.map → knowledge-D9Tuh-o-.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-MtXuky8q.js → mcp-BO8QnWyk.js} +2 -2
- package/dashboard/dist/assets/{mcp-MtXuky8q.js.map → mcp-BO8QnWyk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DQ-J1Q0K.js → mcp-query-WLtQtr51.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DQ-J1Q0K.js.map → mcp-query-WLtQtr51.js.map} +1 -1
- package/dashboard/dist/assets/pipelines-BAVf9xud.js +2 -0
- package/dashboard/dist/assets/pipelines-BAVf9xud.js.map +1 -0
- package/dashboard/dist/assets/{roles-D-LhJ82d.js → roles-mGO2-2hA.js} +2 -2
- package/dashboard/dist/assets/{roles-D-LhJ82d.js.map → roles-mGO2-2hA.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BrP_8uEN.js → tasks-JVRVCx0f.js} +2 -2
- package/dashboard/dist/assets/{tasks-BrP_8uEN.js.map → tasks-JVRVCx0f.js.map} +1 -1
- package/dashboard/dist/assets/{topics-DUk-zX5D.js → topics-BLVnahd7.js} +2 -2
- package/dashboard/dist/assets/{topics-DUk-zX5D.js.map → topics-BLVnahd7.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-XNNzwADV.js → useEventHooks-BwjAi0Qq.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-XNNzwADV.js.map → useEventHooks-BwjAi0Qq.js.map} +1 -1
- package/dashboard/dist/assets/useNamespace-DkHmXddZ.js +2 -0
- package/dashboard/dist/assets/useNamespace-DkHmXddZ.js.map +1 -0
- package/dashboard/dist/assets/{useYamlActivityEvents-DANQ5jIY.js → useYamlActivityEvents-CsaR5dWj.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DANQ5jIY.js.map → useYamlActivityEvents-CsaR5dWj.js.map} +1 -1
- package/dashboard/dist/assets/{users-vj0JgOkA.js → users-BvizpAkV.js} +2 -2
- package/dashboard/dist/assets/{users-vj0JgOkA.js.map → users-BvizpAkV.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-CmqgGPzI.js → workflows-CyEYa01a.js} +2 -2
- package/dashboard/dist/assets/{workflows-CmqgGPzI.js.map → workflows-CyEYa01a.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DNFyjBXH.js → yaml-workflows-i3GzrEme.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DNFyjBXH.js.map → yaml-workflows-i3GzrEme.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/api/http/controlplane.md +6 -4
- package/docs/api/http/dba.md +1 -0
- package/docs/api/http/exports.md +26 -0
- package/docs/api/http/maintenance.md +1 -0
- package/docs/api/http/mcp-endpoint.md +68 -0
- package/docs/api/mcp/admin.md +7 -7
- package/docs/api/sdk/controlplane.md +4 -4
- package/package.json +1 -1
- package/dashboard/dist/assets/HomePage-B2Jgo1J1.js +0 -2
- package/dashboard/dist/assets/HomePage-B2Jgo1J1.js.map +0 -1
- package/dashboard/dist/assets/McpOverview-BzyxJyc9.js +0 -2
- package/dashboard/dist/assets/McpOverview-BzyxJyc9.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-DXNseeKl.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-DXNseeKl.js.map +0 -1
- package/dashboard/dist/assets/McpRunDetailPage-DKZp-p7S.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-DKZp-p7S.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-SXyiwc0d.js +0 -2
- package/dashboard/dist/assets/McpRunsPage-SXyiwc0d.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-pMERxj15.js +0 -2
- package/dashboard/dist/assets/RolesPage-pMERxj15.js.map +0 -1
- package/dashboard/dist/assets/TimeAgo-BSzN6rAH.js +0 -2
- package/dashboard/dist/assets/ToolTestPanel-fLzNp79U.js +0 -2
- package/dashboard/dist/assets/ToolTestPanel-fLzNp79U.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-D-G8Xudz.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-D-G8Xudz.js.map +0 -1
- package/dashboard/dist/assets/YamlWorkflowsPage-CnTNOku0.js +0 -2
- package/dashboard/dist/assets/YamlWorkflowsPage-CnTNOku0.js.map +0 -1
- package/dashboard/dist/assets/capabilities-CbGmS0ty.js +0 -2
- package/dashboard/dist/assets/index-BeLphL59.js +0 -2
- package/dashboard/dist/assets/index-DDlrQeTj.js +0 -2
- package/dashboard/dist/assets/index-DDlrQeTj.js.map +0 -1
- package/dashboard/dist/assets/index-DQHmfTPo.js +0 -2
- package/dashboard/dist/assets/namespaces-DtsT_GoV.js +0 -2
- package/dashboard/dist/assets/namespaces-DtsT_GoV.js.map +0 -1
- package/dashboard/dist/assets/pipelines-BjlCm9VH.js +0 -2
- package/dashboard/dist/assets/pipelines-BjlCm9VH.js.map +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System overview — one call, complete picture.
|
|
3
|
+
*
|
|
4
|
+
* Composes triage, throughput, trends, infrastructure, and process
|
|
5
|
+
* metrics from lt_* tables. All queries run in parallel. No HotMesh
|
|
6
|
+
* schema dependencies — safe regardless of engine initialization state.
|
|
7
|
+
*/
|
|
8
|
+
export interface SystemOverview {
|
|
9
|
+
period: string;
|
|
10
|
+
triage: {
|
|
11
|
+
pending: number;
|
|
12
|
+
claimed: number;
|
|
13
|
+
unclaimed: number;
|
|
14
|
+
aging_30m: number;
|
|
15
|
+
aging_1h: number;
|
|
16
|
+
aging_24h: number;
|
|
17
|
+
oldest_unclaimed_minutes: number;
|
|
18
|
+
created_period: number;
|
|
19
|
+
resolved_period: number;
|
|
20
|
+
resolution_rate_pct: number;
|
|
21
|
+
by_role: Array<{
|
|
22
|
+
role: string;
|
|
23
|
+
pending: number;
|
|
24
|
+
claimed: number;
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
throughput: {
|
|
28
|
+
tasks_pending: number;
|
|
29
|
+
tasks_in_progress: number;
|
|
30
|
+
tasks_failed: number;
|
|
31
|
+
tasks_created_1h: number;
|
|
32
|
+
tasks_completed_1h: number;
|
|
33
|
+
tasks_created_period: number;
|
|
34
|
+
tasks_completed_period: number;
|
|
35
|
+
tasks_failed_1h: number;
|
|
36
|
+
};
|
|
37
|
+
trends: {
|
|
38
|
+
escalation_creation: Array<{
|
|
39
|
+
hour: string;
|
|
40
|
+
created: number;
|
|
41
|
+
}>;
|
|
42
|
+
task_completion: Array<{
|
|
43
|
+
hour: string;
|
|
44
|
+
completed: number;
|
|
45
|
+
}>;
|
|
46
|
+
resolution_velocity: Array<{
|
|
47
|
+
hour: string;
|
|
48
|
+
created: number;
|
|
49
|
+
resolved: number;
|
|
50
|
+
}>;
|
|
51
|
+
};
|
|
52
|
+
infrastructure: {
|
|
53
|
+
mcp_servers: {
|
|
54
|
+
total: number;
|
|
55
|
+
connected: number;
|
|
56
|
+
total_tools: number;
|
|
57
|
+
};
|
|
58
|
+
compiled_workflows: {
|
|
59
|
+
total: number;
|
|
60
|
+
active: number;
|
|
61
|
+
};
|
|
62
|
+
agents: {
|
|
63
|
+
total: number;
|
|
64
|
+
active: number;
|
|
65
|
+
paused: number;
|
|
66
|
+
error: number;
|
|
67
|
+
stale: number;
|
|
68
|
+
};
|
|
69
|
+
workflow_configs: number;
|
|
70
|
+
};
|
|
71
|
+
processes: {
|
|
72
|
+
total: number;
|
|
73
|
+
active: number;
|
|
74
|
+
completed: number;
|
|
75
|
+
escalated: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export declare function getSystemOverview(period?: string): Promise<SystemOverview>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* System overview — one call, complete picture.
|
|
4
|
+
*
|
|
5
|
+
* Composes triage, throughput, trends, infrastructure, and process
|
|
6
|
+
* metrics from lt_* tables. All queries run in parallel. No HotMesh
|
|
7
|
+
* schema dependencies — safe regardless of engine initialization state.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.getSystemOverview = getSystemOverview;
|
|
11
|
+
const db_1 = require("../../lib/db");
|
|
12
|
+
const sql_1 = require("./sql");
|
|
13
|
+
const VALID_PERIODS = {
|
|
14
|
+
'1h': '1 hour',
|
|
15
|
+
'24h': '24 hours',
|
|
16
|
+
'7d': '7 days',
|
|
17
|
+
};
|
|
18
|
+
async function getSystemOverview(period = '24h') {
|
|
19
|
+
const interval = VALID_PERIODS[period] ?? VALID_PERIODS['24h'];
|
|
20
|
+
const pool = (0, db_1.getPool)();
|
|
21
|
+
// Every query is individually guarded — a single table failure
|
|
22
|
+
// (e.g., during migration) must not crash the entire overview.
|
|
23
|
+
const empty = { rows: [] };
|
|
24
|
+
const [escTriage, escByRole, taskThroughput, escTrends, taskTrends, resTrends, mcpInfra, compiledWf, agentHealth, wfConfigs, processSummary,] = await Promise.all([
|
|
25
|
+
pool.query(sql_1.OVERVIEW_ESCALATION_TRIAGE, [interval]).catch(() => empty),
|
|
26
|
+
pool.query(sql_1.OVERVIEW_ESCALATION_BY_ROLE).catch(() => empty),
|
|
27
|
+
pool.query(sql_1.OVERVIEW_TASK_THROUGHPUT, [interval]).catch(() => empty),
|
|
28
|
+
pool.query(sql_1.OVERVIEW_ESCALATION_TRENDS, [interval]).catch(() => empty),
|
|
29
|
+
pool.query(sql_1.OVERVIEW_TASK_TRENDS, [interval]).catch(() => empty),
|
|
30
|
+
pool.query(sql_1.OVERVIEW_RESOLUTION_TRENDS, [interval]).catch(() => empty),
|
|
31
|
+
pool.query(sql_1.OVERVIEW_MCP_INFRASTRUCTURE).catch(() => empty),
|
|
32
|
+
pool.query(sql_1.OVERVIEW_COMPILED_WORKFLOWS).catch(() => empty),
|
|
33
|
+
pool.query(sql_1.OVERVIEW_AGENT_HEALTH).catch(() => empty),
|
|
34
|
+
pool.query(sql_1.OVERVIEW_WORKFLOW_CONFIGS).catch(() => empty),
|
|
35
|
+
pool.query(sql_1.OVERVIEW_PROCESS_SUMMARY, [interval]).catch(() => empty),
|
|
36
|
+
]);
|
|
37
|
+
const ZEROS = { pending: 0, claimed: 0, unclaimed: 0, aging_30m: 0, aging_1h: 0, aging_24h: 0, oldest_unclaimed_minutes: 0, created_period: 0, resolved_period: 0, in_progress: 0, failed: 0, created_1h: 0, completed_1h: 0, created_period_t: 0, completed_period: 0, failed_1h: 0, total: 0, connected: 0, total_tools: 0, active: 0, paused: 0, error: 0, stale: 0, completed: 0, escalated: 0 };
|
|
38
|
+
const esc = escTriage.rows[0] ?? ZEROS;
|
|
39
|
+
const task = taskThroughput.rows[0] ?? ZEROS;
|
|
40
|
+
const mcp = mcpInfra.rows[0] ?? ZEROS;
|
|
41
|
+
const compiled = compiledWf.rows[0] ?? ZEROS;
|
|
42
|
+
const agents = agentHealth.rows[0] ?? ZEROS;
|
|
43
|
+
const configs = wfConfigs.rows[0] ?? ZEROS;
|
|
44
|
+
const procs = processSummary.rows[0] ?? ZEROS;
|
|
45
|
+
const createdPeriod = esc.created_period || 0;
|
|
46
|
+
const resolvedPeriod = esc.resolved_period || 0;
|
|
47
|
+
const resolutionRate = createdPeriod > 0
|
|
48
|
+
? Math.round((resolvedPeriod / createdPeriod) * 100)
|
|
49
|
+
: 0;
|
|
50
|
+
return {
|
|
51
|
+
period,
|
|
52
|
+
triage: {
|
|
53
|
+
pending: esc.pending,
|
|
54
|
+
claimed: esc.claimed,
|
|
55
|
+
unclaimed: esc.unclaimed,
|
|
56
|
+
aging_30m: esc.aging_30m,
|
|
57
|
+
aging_1h: esc.aging_1h,
|
|
58
|
+
aging_24h: esc.aging_24h,
|
|
59
|
+
oldest_unclaimed_minutes: esc.oldest_unclaimed_minutes,
|
|
60
|
+
created_period: createdPeriod,
|
|
61
|
+
resolved_period: resolvedPeriod,
|
|
62
|
+
resolution_rate_pct: resolutionRate,
|
|
63
|
+
by_role: escByRole.rows,
|
|
64
|
+
},
|
|
65
|
+
throughput: {
|
|
66
|
+
tasks_pending: task.pending,
|
|
67
|
+
tasks_in_progress: task.in_progress,
|
|
68
|
+
tasks_failed: task.failed,
|
|
69
|
+
tasks_created_1h: task.created_1h,
|
|
70
|
+
tasks_completed_1h: task.completed_1h,
|
|
71
|
+
tasks_created_period: task.created_period,
|
|
72
|
+
tasks_completed_period: task.completed_period,
|
|
73
|
+
tasks_failed_1h: task.failed_1h,
|
|
74
|
+
},
|
|
75
|
+
trends: {
|
|
76
|
+
escalation_creation: escTrends.rows.map((r) => ({
|
|
77
|
+
hour: r.hour, created: r.created,
|
|
78
|
+
})),
|
|
79
|
+
task_completion: taskTrends.rows.map((r) => ({
|
|
80
|
+
hour: r.hour, completed: r.completed,
|
|
81
|
+
})),
|
|
82
|
+
// Filter out zero-activity hours to keep MCP responses compact
|
|
83
|
+
resolution_velocity: resTrends.rows
|
|
84
|
+
.filter((r) => r.created > 0 || r.resolved > 0)
|
|
85
|
+
.map((r) => ({
|
|
86
|
+
hour: r.hour, created: r.created, resolved: r.resolved,
|
|
87
|
+
})),
|
|
88
|
+
},
|
|
89
|
+
infrastructure: {
|
|
90
|
+
mcp_servers: { total: mcp.total, connected: mcp.connected, total_tools: mcp.total_tools },
|
|
91
|
+
compiled_workflows: { total: compiled.total, active: compiled.active },
|
|
92
|
+
agents: {
|
|
93
|
+
total: agents.total, active: agents.active,
|
|
94
|
+
paused: agents.paused, error: agents.error, stale: agents.stale,
|
|
95
|
+
},
|
|
96
|
+
workflow_configs: configs.total,
|
|
97
|
+
},
|
|
98
|
+
processes: {
|
|
99
|
+
total: procs.total,
|
|
100
|
+
active: procs.active,
|
|
101
|
+
completed: procs.completed,
|
|
102
|
+
escalated: procs.escalated,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL for the system overview tool.
|
|
3
|
+
*
|
|
4
|
+
* All queries are SELECT-only, read-safe, and index-backed.
|
|
5
|
+
* They target only lt_* tables — no HotMesh schema dependencies.
|
|
6
|
+
* $1 is always the period interval (e.g., '24 hours').
|
|
7
|
+
*/
|
|
8
|
+
/** Escalation queue pressure — aging buckets, claim status, period counts. */
|
|
9
|
+
export declare const OVERVIEW_ESCALATION_TRIAGE = "\n SELECT\n COUNT(*) FILTER (WHERE status = 'pending')::int AS pending,\n COUNT(*) FILTER (WHERE status = 'pending'\n AND assigned_to IS NOT NULL AND assigned_until > NOW())::int AS claimed,\n COUNT(*) FILTER (WHERE status = 'pending'\n AND (assigned_to IS NULL OR assigned_until <= NOW()))::int AS unclaimed,\n COUNT(*) FILTER (WHERE status = 'pending'\n AND created_at < NOW() - INTERVAL '30 minutes')::int AS aging_30m,\n COUNT(*) FILTER (WHERE status = 'pending'\n AND created_at < NOW() - INTERVAL '1 hour')::int AS aging_1h,\n COUNT(*) FILTER (WHERE status = 'pending'\n AND created_at < NOW() - INTERVAL '24 hours')::int AS aging_24h,\n COALESCE(\n EXTRACT(EPOCH FROM (NOW() - MIN(created_at) FILTER (\n WHERE status = 'pending'\n AND (assigned_to IS NULL OR assigned_until <= NOW())\n )))::int / 60, 0\n ) AS oldest_unclaimed_minutes,\n COUNT(*) FILTER (WHERE created_at > NOW() - $1::interval)::int AS created_period,\n COUNT(*) FILTER (WHERE resolved_at > NOW() - $1::interval)::int AS resolved_period\n FROM lt_escalations";
|
|
10
|
+
/** Escalation breakdown by role (pending only). */
|
|
11
|
+
export declare const OVERVIEW_ESCALATION_BY_ROLE = "\n SELECT role,\n COUNT(*)::int AS pending,\n COUNT(*) FILTER (WHERE assigned_to IS NOT NULL AND assigned_until > NOW())::int AS claimed\n FROM lt_escalations\n WHERE status = 'pending'\n GROUP BY role\n ORDER BY COUNT(*) DESC\n LIMIT 10";
|
|
12
|
+
/** Task creation and completion counts for 1h and the configurable period. */
|
|
13
|
+
export declare const OVERVIEW_TASK_THROUGHPUT = "\n SELECT\n COUNT(*) FILTER (WHERE status = 'pending')::int AS pending,\n COUNT(*) FILTER (WHERE status = 'in_progress')::int AS in_progress,\n COUNT(*) FILTER (WHERE status = 'failed')::int AS failed,\n COUNT(*) FILTER (WHERE created_at > NOW() - INTERVAL '1 hour')::int AS created_1h,\n COUNT(*) FILTER (WHERE completed_at > NOW() - INTERVAL '1 hour')::int AS completed_1h,\n COUNT(*) FILTER (WHERE created_at > NOW() - $1::interval)::int AS created_period,\n COUNT(*) FILTER (WHERE completed_at > NOW() - $1::interval)::int AS completed_period,\n COUNT(*) FILTER (WHERE status = 'failed'\n AND created_at > NOW() - INTERVAL '1 hour')::int AS failed_1h\n FROM lt_tasks";
|
|
14
|
+
/** Hourly escalation creation within the period. */
|
|
15
|
+
export declare const OVERVIEW_ESCALATION_TRENDS = "\n SELECT date_trunc('hour', created_at) AS hour, COUNT(*)::int AS created\n FROM lt_escalations\n WHERE created_at > NOW() - $1::interval\n GROUP BY 1 ORDER BY 1";
|
|
16
|
+
/** Hourly task completion within the period. */
|
|
17
|
+
export declare const OVERVIEW_TASK_TRENDS = "\n SELECT date_trunc('hour', completed_at) AS hour, COUNT(*)::int AS completed\n FROM lt_tasks\n WHERE completed_at IS NOT NULL AND completed_at > NOW() - $1::interval\n GROUP BY 1 ORDER BY 1";
|
|
18
|
+
/** Hourly resolution velocity — created vs resolved. */
|
|
19
|
+
export declare const OVERVIEW_RESOLUTION_TRENDS = "\n SELECT\n gs AS hour,\n COALESCE(c.created, 0)::int AS created,\n COALESCE(r.resolved, 0)::int AS resolved\n FROM generate_series(\n date_trunc('hour', NOW() - $1::interval),\n date_trunc('hour', NOW()),\n INTERVAL '1 hour'\n ) AS gs\n LEFT JOIN (\n SELECT date_trunc('hour', created_at) AS h, COUNT(*)::int AS created\n FROM lt_escalations WHERE created_at > NOW() - $1::interval\n GROUP BY 1\n ) c ON c.h = gs\n LEFT JOIN (\n SELECT date_trunc('hour', resolved_at) AS h, COUNT(*)::int AS resolved\n FROM lt_escalations WHERE resolved_at > NOW() - $1::interval\n GROUP BY 1\n ) r ON r.h = gs\n ORDER BY gs";
|
|
20
|
+
/** MCP server and tool counts. */
|
|
21
|
+
export declare const OVERVIEW_MCP_INFRASTRUCTURE = "\n SELECT\n COUNT(*)::int AS total,\n COUNT(*) FILTER (WHERE status = 'connected')::int AS connected,\n COALESCE(SUM(jsonb_array_length(tool_manifest)) FILTER (WHERE tool_manifest IS NOT NULL), 0)::int AS total_tools\n FROM lt_mcp_servers";
|
|
22
|
+
/** Compiled workflow counts. */
|
|
23
|
+
export declare const OVERVIEW_COMPILED_WORKFLOWS = "\n SELECT\n COUNT(*)::int AS total,\n COUNT(*) FILTER (WHERE status = 'active')::int AS active\n FROM lt_yaml_workflows";
|
|
24
|
+
/** Agent health snapshot. */
|
|
25
|
+
export declare const OVERVIEW_AGENT_HEALTH = "\n SELECT\n COUNT(*)::int AS total,\n COUNT(*) FILTER (WHERE status = 'active')::int AS active,\n COUNT(*) FILTER (WHERE status = 'paused')::int AS paused,\n COUNT(*) FILTER (WHERE status = 'error')::int AS error,\n COUNT(*) FILTER (WHERE last_run_at IS NULL\n OR last_run_at < NOW() - INTERVAL '7 days')::int AS stale\n FROM lt_agents";
|
|
26
|
+
/** Registered workflow config count. */
|
|
27
|
+
export declare const OVERVIEW_WORKFLOW_CONFIGS = "\n SELECT COUNT(*)::int AS total FROM lt_config_workflows";
|
|
28
|
+
/** Process summary — grouped by origin_id within the period. */
|
|
29
|
+
export declare const OVERVIEW_PROCESS_SUMMARY = "\n SELECT\n COUNT(DISTINCT origin_id)::int AS total,\n COUNT(DISTINCT origin_id) FILTER (\n WHERE status IN ('pending', 'in_progress'))::int AS active,\n COUNT(DISTINCT origin_id) FILTER (\n WHERE status = 'completed')::int AS completed,\n COUNT(DISTINCT origin_id) FILTER (\n WHERE status = 'needs_intervention')::int AS escalated\n FROM lt_tasks\n WHERE origin_id IS NOT NULL\n AND created_at > NOW() - $1::interval";
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQL for the system overview tool.
|
|
4
|
+
*
|
|
5
|
+
* All queries are SELECT-only, read-safe, and index-backed.
|
|
6
|
+
* They target only lt_* tables — no HotMesh schema dependencies.
|
|
7
|
+
* $1 is always the period interval (e.g., '24 hours').
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.OVERVIEW_PROCESS_SUMMARY = exports.OVERVIEW_WORKFLOW_CONFIGS = exports.OVERVIEW_AGENT_HEALTH = exports.OVERVIEW_COMPILED_WORKFLOWS = exports.OVERVIEW_MCP_INFRASTRUCTURE = exports.OVERVIEW_RESOLUTION_TRENDS = exports.OVERVIEW_TASK_TRENDS = exports.OVERVIEW_ESCALATION_TRENDS = exports.OVERVIEW_TASK_THROUGHPUT = exports.OVERVIEW_ESCALATION_BY_ROLE = exports.OVERVIEW_ESCALATION_TRIAGE = void 0;
|
|
11
|
+
// ── Triage ──────────────────────────────────────────────────────────────────
|
|
12
|
+
/** Escalation queue pressure — aging buckets, claim status, period counts. */
|
|
13
|
+
exports.OVERVIEW_ESCALATION_TRIAGE = `
|
|
14
|
+
SELECT
|
|
15
|
+
COUNT(*) FILTER (WHERE status = 'pending')::int AS pending,
|
|
16
|
+
COUNT(*) FILTER (WHERE status = 'pending'
|
|
17
|
+
AND assigned_to IS NOT NULL AND assigned_until > NOW())::int AS claimed,
|
|
18
|
+
COUNT(*) FILTER (WHERE status = 'pending'
|
|
19
|
+
AND (assigned_to IS NULL OR assigned_until <= NOW()))::int AS unclaimed,
|
|
20
|
+
COUNT(*) FILTER (WHERE status = 'pending'
|
|
21
|
+
AND created_at < NOW() - INTERVAL '30 minutes')::int AS aging_30m,
|
|
22
|
+
COUNT(*) FILTER (WHERE status = 'pending'
|
|
23
|
+
AND created_at < NOW() - INTERVAL '1 hour')::int AS aging_1h,
|
|
24
|
+
COUNT(*) FILTER (WHERE status = 'pending'
|
|
25
|
+
AND created_at < NOW() - INTERVAL '24 hours')::int AS aging_24h,
|
|
26
|
+
COALESCE(
|
|
27
|
+
EXTRACT(EPOCH FROM (NOW() - MIN(created_at) FILTER (
|
|
28
|
+
WHERE status = 'pending'
|
|
29
|
+
AND (assigned_to IS NULL OR assigned_until <= NOW())
|
|
30
|
+
)))::int / 60, 0
|
|
31
|
+
) AS oldest_unclaimed_minutes,
|
|
32
|
+
COUNT(*) FILTER (WHERE created_at > NOW() - $1::interval)::int AS created_period,
|
|
33
|
+
COUNT(*) FILTER (WHERE resolved_at > NOW() - $1::interval)::int AS resolved_period
|
|
34
|
+
FROM lt_escalations`;
|
|
35
|
+
/** Escalation breakdown by role (pending only). */
|
|
36
|
+
exports.OVERVIEW_ESCALATION_BY_ROLE = `
|
|
37
|
+
SELECT role,
|
|
38
|
+
COUNT(*)::int AS pending,
|
|
39
|
+
COUNT(*) FILTER (WHERE assigned_to IS NOT NULL AND assigned_until > NOW())::int AS claimed
|
|
40
|
+
FROM lt_escalations
|
|
41
|
+
WHERE status = 'pending'
|
|
42
|
+
GROUP BY role
|
|
43
|
+
ORDER BY COUNT(*) DESC
|
|
44
|
+
LIMIT 10`;
|
|
45
|
+
// ── Throughput ───────────────────────────────────────────────────────────────
|
|
46
|
+
/** Task creation and completion counts for 1h and the configurable period. */
|
|
47
|
+
exports.OVERVIEW_TASK_THROUGHPUT = `
|
|
48
|
+
SELECT
|
|
49
|
+
COUNT(*) FILTER (WHERE status = 'pending')::int AS pending,
|
|
50
|
+
COUNT(*) FILTER (WHERE status = 'in_progress')::int AS in_progress,
|
|
51
|
+
COUNT(*) FILTER (WHERE status = 'failed')::int AS failed,
|
|
52
|
+
COUNT(*) FILTER (WHERE created_at > NOW() - INTERVAL '1 hour')::int AS created_1h,
|
|
53
|
+
COUNT(*) FILTER (WHERE completed_at > NOW() - INTERVAL '1 hour')::int AS completed_1h,
|
|
54
|
+
COUNT(*) FILTER (WHERE created_at > NOW() - $1::interval)::int AS created_period,
|
|
55
|
+
COUNT(*) FILTER (WHERE completed_at > NOW() - $1::interval)::int AS completed_period,
|
|
56
|
+
COUNT(*) FILTER (WHERE status = 'failed'
|
|
57
|
+
AND created_at > NOW() - INTERVAL '1 hour')::int AS failed_1h
|
|
58
|
+
FROM lt_tasks`;
|
|
59
|
+
// ── Trends ──────────────────────────────────────────────────────────────────
|
|
60
|
+
/** Hourly escalation creation within the period. */
|
|
61
|
+
exports.OVERVIEW_ESCALATION_TRENDS = `
|
|
62
|
+
SELECT date_trunc('hour', created_at) AS hour, COUNT(*)::int AS created
|
|
63
|
+
FROM lt_escalations
|
|
64
|
+
WHERE created_at > NOW() - $1::interval
|
|
65
|
+
GROUP BY 1 ORDER BY 1`;
|
|
66
|
+
/** Hourly task completion within the period. */
|
|
67
|
+
exports.OVERVIEW_TASK_TRENDS = `
|
|
68
|
+
SELECT date_trunc('hour', completed_at) AS hour, COUNT(*)::int AS completed
|
|
69
|
+
FROM lt_tasks
|
|
70
|
+
WHERE completed_at IS NOT NULL AND completed_at > NOW() - $1::interval
|
|
71
|
+
GROUP BY 1 ORDER BY 1`;
|
|
72
|
+
/** Hourly resolution velocity — created vs resolved. */
|
|
73
|
+
exports.OVERVIEW_RESOLUTION_TRENDS = `
|
|
74
|
+
SELECT
|
|
75
|
+
gs AS hour,
|
|
76
|
+
COALESCE(c.created, 0)::int AS created,
|
|
77
|
+
COALESCE(r.resolved, 0)::int AS resolved
|
|
78
|
+
FROM generate_series(
|
|
79
|
+
date_trunc('hour', NOW() - $1::interval),
|
|
80
|
+
date_trunc('hour', NOW()),
|
|
81
|
+
INTERVAL '1 hour'
|
|
82
|
+
) AS gs
|
|
83
|
+
LEFT JOIN (
|
|
84
|
+
SELECT date_trunc('hour', created_at) AS h, COUNT(*)::int AS created
|
|
85
|
+
FROM lt_escalations WHERE created_at > NOW() - $1::interval
|
|
86
|
+
GROUP BY 1
|
|
87
|
+
) c ON c.h = gs
|
|
88
|
+
LEFT JOIN (
|
|
89
|
+
SELECT date_trunc('hour', resolved_at) AS h, COUNT(*)::int AS resolved
|
|
90
|
+
FROM lt_escalations WHERE resolved_at > NOW() - $1::interval
|
|
91
|
+
GROUP BY 1
|
|
92
|
+
) r ON r.h = gs
|
|
93
|
+
ORDER BY gs`;
|
|
94
|
+
// ── Infrastructure ──────────────────────────────────────────────────────────
|
|
95
|
+
/** MCP server and tool counts. */
|
|
96
|
+
exports.OVERVIEW_MCP_INFRASTRUCTURE = `
|
|
97
|
+
SELECT
|
|
98
|
+
COUNT(*)::int AS total,
|
|
99
|
+
COUNT(*) FILTER (WHERE status = 'connected')::int AS connected,
|
|
100
|
+
COALESCE(SUM(jsonb_array_length(tool_manifest)) FILTER (WHERE tool_manifest IS NOT NULL), 0)::int AS total_tools
|
|
101
|
+
FROM lt_mcp_servers`;
|
|
102
|
+
/** Compiled workflow counts. */
|
|
103
|
+
exports.OVERVIEW_COMPILED_WORKFLOWS = `
|
|
104
|
+
SELECT
|
|
105
|
+
COUNT(*)::int AS total,
|
|
106
|
+
COUNT(*) FILTER (WHERE status = 'active')::int AS active
|
|
107
|
+
FROM lt_yaml_workflows`;
|
|
108
|
+
/** Agent health snapshot. */
|
|
109
|
+
exports.OVERVIEW_AGENT_HEALTH = `
|
|
110
|
+
SELECT
|
|
111
|
+
COUNT(*)::int AS total,
|
|
112
|
+
COUNT(*) FILTER (WHERE status = 'active')::int AS active,
|
|
113
|
+
COUNT(*) FILTER (WHERE status = 'paused')::int AS paused,
|
|
114
|
+
COUNT(*) FILTER (WHERE status = 'error')::int AS error,
|
|
115
|
+
COUNT(*) FILTER (WHERE last_run_at IS NULL
|
|
116
|
+
OR last_run_at < NOW() - INTERVAL '7 days')::int AS stale
|
|
117
|
+
FROM lt_agents`;
|
|
118
|
+
/** Registered workflow config count. */
|
|
119
|
+
exports.OVERVIEW_WORKFLOW_CONFIGS = `
|
|
120
|
+
SELECT COUNT(*)::int AS total FROM lt_config_workflows`;
|
|
121
|
+
// ── Processes ───────────────────────────────────────────────────────────────
|
|
122
|
+
/** Process summary — grouped by origin_id within the period. */
|
|
123
|
+
exports.OVERVIEW_PROCESS_SUMMARY = `
|
|
124
|
+
SELECT
|
|
125
|
+
COUNT(DISTINCT origin_id)::int AS total,
|
|
126
|
+
COUNT(DISTINCT origin_id) FILTER (
|
|
127
|
+
WHERE status IN ('pending', 'in_progress'))::int AS active,
|
|
128
|
+
COUNT(DISTINCT origin_id) FILTER (
|
|
129
|
+
WHERE status = 'completed')::int AS completed,
|
|
130
|
+
COUNT(DISTINCT origin_id) FILTER (
|
|
131
|
+
WHERE status = 'needs_intervention')::int AS escalated
|
|
132
|
+
FROM lt_tasks
|
|
133
|
+
WHERE origin_id IS NOT NULL
|
|
134
|
+
AND created_at > NOW() - $1::interval`;
|
|
@@ -65,9 +65,12 @@ async function listJobs(params) {
|
|
|
65
65
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
66
66
|
const keyPrefix = `hmsh:${appId}:j:`;
|
|
67
67
|
const orderBy = buildOrderBy(params.sort_by, params.order);
|
|
68
|
+
// Graceful degradation: HotMesh schema may not exist yet if no
|
|
69
|
+
// engine/worker has initialized. Return empty results, not 500.
|
|
70
|
+
const empty = { rows: [{ count: '0' }] };
|
|
68
71
|
const [countResult, dataResult] = await Promise.all([
|
|
69
|
-
pool.query((0, sql_1.COUNT_JOBS)(schema, where), values),
|
|
70
|
-
pool.query((0, sql_1.LIST_JOBS)(schema, appId, where, idx++, idx++, orderBy), [...values, limit, offset]),
|
|
72
|
+
pool.query((0, sql_1.COUNT_JOBS)(schema, where), values).catch(() => empty),
|
|
73
|
+
pool.query((0, sql_1.LIST_JOBS)(schema, appId, where, idx++, idx++, orderBy), [...values, limit, offset]).catch(() => ({ rows: [] })),
|
|
71
74
|
]);
|
|
72
75
|
const jobs = dataResult.rows.map((row) => ({
|
|
73
76
|
workflow_id: row.key.startsWith(keyPrefix) ? row.key.slice(keyPrefix.length) : row.key,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export declare const DISTINCT_ENTITIES_DURABLE = "\n SELECT DISTINCT entity FROM durable.jobs WHERE entity IS NOT NULL AND entity != '' ORDER BY entity";
|
|
2
1
|
export declare const DISTINCT_ENTITIES: (schema: string) => string;
|
|
3
2
|
export declare const ACTIVE_GRAPH_TOPICS = "SELECT DISTINCT graph_topic FROM lt_yaml_workflows WHERE app_id = $1 AND status IN ('active', 'deployed')";
|
|
4
3
|
export declare const COUNT_JOBS: (schema: string, where: string) => string;
|
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
// Schema placeholders (${schema}) are interpolated at call time
|
|
4
4
|
// because Postgres does not support parameterized schema names.
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LIST_JOBS = exports.GET_JOB_ATTRIBUTES = exports.GET_JOB = exports.COUNT_JOBS = exports.ACTIVE_GRAPH_TOPICS = exports.DISTINCT_ENTITIES =
|
|
7
|
-
exports.DISTINCT_ENTITIES_DURABLE = `
|
|
8
|
-
SELECT DISTINCT entity FROM durable.jobs WHERE entity IS NOT NULL AND entity != '' ORDER BY entity`;
|
|
6
|
+
exports.LIST_JOBS = exports.GET_JOB_ATTRIBUTES = exports.GET_JOB = exports.COUNT_JOBS = exports.ACTIVE_GRAPH_TOPICS = exports.DISTINCT_ENTITIES = void 0;
|
|
9
7
|
const DISTINCT_ENTITIES = (schema) => `SELECT DISTINCT entity FROM ${schema}.jobs WHERE entity IS NOT NULL AND entity != '' ORDER BY entity`;
|
|
10
8
|
exports.DISTINCT_ENTITIES = DISTINCT_ENTITIES;
|
|
11
9
|
exports.ACTIVE_GRAPH_TOPICS = `SELECT DISTINCT graph_topic FROM lt_yaml_workflows WHERE app_id = $1 AND status IN ('active', 'deployed')`;
|
|
@@ -57,7 +57,7 @@ function registerControlPlaneTools(server) {
|
|
|
57
57
|
inputSchema: schemas_1.rollCallSchema,
|
|
58
58
|
}, async (args) => {
|
|
59
59
|
const result = await api.rollCall({
|
|
60
|
-
appId: args.app_id
|
|
60
|
+
appId: args.app_id,
|
|
61
61
|
delay: args.delay,
|
|
62
62
|
});
|
|
63
63
|
if (result.error) {
|
|
@@ -53,7 +53,8 @@ const pipelines_1 = require("./pipelines");
|
|
|
53
53
|
const topics_1 = require("./topics");
|
|
54
54
|
const settings_1 = require("./settings");
|
|
55
55
|
const exports_1 = require("./exports");
|
|
56
|
-
const
|
|
56
|
+
const overview_1 = require("./overview");
|
|
57
|
+
const TOOL_COUNT = 72;
|
|
57
58
|
let server = null;
|
|
58
59
|
async function createAdminServer(options) {
|
|
59
60
|
if (server && !options?.fresh)
|
|
@@ -79,7 +80,8 @@ async function createAdminServer(options) {
|
|
|
79
80
|
(0, topics_1.registerTopicTools)(instance); // 5 tools
|
|
80
81
|
(0, settings_1.registerSettingsTools)(instance); // 1 tool
|
|
81
82
|
(0, exports_1.registerExportTools)(instance); // 4 tools
|
|
82
|
-
|
|
83
|
+
(0, overview_1.registerOverviewTools)(instance); // 1 tool
|
|
84
|
+
// Total: 72
|
|
83
85
|
logger_1.loggerRegistry.info(`[lt-mcp:admin] ${name} ready (${TOOL_COUNT} tools registered)`);
|
|
84
86
|
return instance;
|
|
85
87
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System overview tool — one call, complete picture.
|
|
3
|
+
*/
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export declare const systemOverviewSchema: z.ZodObject<{
|
|
7
|
+
period: z.ZodDefault<z.ZodOptional<z.ZodEnum<["1h", "24h", "7d"]>>>;
|
|
8
|
+
}, "strip", z.ZodTypeAny, {
|
|
9
|
+
period: "24h" | "1h" | "7d";
|
|
10
|
+
}, {
|
|
11
|
+
period?: "24h" | "1h" | "7d" | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function registerOverviewTools(server: McpServer): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.systemOverviewSchema = void 0;
|
|
4
|
+
exports.registerOverviewTools = registerOverviewTools;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const overview_1 = require("../../../services/overview");
|
|
7
|
+
exports.systemOverviewSchema = zod_1.z.object({
|
|
8
|
+
period: zod_1.z.enum(['1h', '24h', '7d']).optional().default('24h')
|
|
9
|
+
.describe('Time window for trends and throughput metrics'),
|
|
10
|
+
});
|
|
11
|
+
function registerOverviewTools(server) {
|
|
12
|
+
server.registerTool('get_system_overview', {
|
|
13
|
+
title: 'Get System Overview',
|
|
14
|
+
description: 'Triage-ready system dashboard in one call. Returns escalation queue pressure ' +
|
|
15
|
+
'(aging, unclaimed, by role), task throughput (created/completed/failed), ' +
|
|
16
|
+
'hourly trends (escalation creation, task completion, resolution velocity), ' +
|
|
17
|
+
'infrastructure status (MCP servers, agents, compiled workflows), and ' +
|
|
18
|
+
'business process summary. Use this as the first call to understand system state.',
|
|
19
|
+
inputSchema: exports.systemOverviewSchema,
|
|
20
|
+
}, async (args) => {
|
|
21
|
+
try {
|
|
22
|
+
const overview = await (0, overview_1.getSystemOverview)(args.period);
|
|
23
|
+
return {
|
|
24
|
+
content: [{ type: 'text', text: JSON.stringify(overview) }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{ type: 'text', text: JSON.stringify({ error: err.message }) }],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
@@ -44,7 +44,7 @@ function registerPipelineTools(server) {
|
|
|
44
44
|
'with graph topics from compiled YAML workflows.',
|
|
45
45
|
inputSchema: schemas_1.listPipelineEntitiesSchema,
|
|
46
46
|
}, async (args) => {
|
|
47
|
-
const result = await api.listEntities({ app_id: args.app_id
|
|
47
|
+
const result = await api.listEntities({ app_id: args.app_id });
|
|
48
48
|
if (result.error) {
|
|
49
49
|
return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
|
|
50
50
|
}
|
|
@@ -56,7 +56,7 @@ function registerPipelineTools(server) {
|
|
|
56
56
|
description: 'List pipeline jobs with optional entity, search, and status filters.',
|
|
57
57
|
inputSchema: schemas_1.listPipelineJobsSchema,
|
|
58
58
|
}, async (args) => {
|
|
59
|
-
const result = await api.listJobs({ ...args, app_id: args.app_id
|
|
59
|
+
const result = await api.listJobs({ ...args, app_id: args.app_id });
|
|
60
60
|
if (result.error) {
|
|
61
61
|
return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
|
|
62
62
|
}
|
|
@@ -70,7 +70,7 @@ function registerPipelineTools(server) {
|
|
|
70
70
|
}, async (args) => {
|
|
71
71
|
const result = await api.getJobExecution({
|
|
72
72
|
jobId: args.job_id,
|
|
73
|
-
app_id: args.app_id
|
|
73
|
+
app_id: args.app_id,
|
|
74
74
|
});
|
|
75
75
|
if (result.error) {
|
|
76
76
|
return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
|
|
@@ -86,7 +86,7 @@ function registerPipelineTools(server) {
|
|
|
86
86
|
const result = await api.interruptJob({
|
|
87
87
|
jobId: args.job_id,
|
|
88
88
|
topic: args.topic,
|
|
89
|
-
app_id: args.app_id
|
|
89
|
+
app_id: args.app_id,
|
|
90
90
|
});
|
|
91
91
|
if (result.error) {
|
|
92
92
|
return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
|