@hotmeshio/long-tail 0.4.13 → 0.4.15
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/escalations/claim.js +1 -10
- package/build/api/escalations/create.js +1 -11
- package/build/api/escalations/helpers.d.ts +14 -0
- package/build/api/escalations/helpers.js +14 -0
- package/build/api/escalations/index.d.ts +1 -0
- package/build/api/escalations/index.js +5 -1
- package/build/api/escalations/metadata.d.ts +58 -0
- package/build/api/escalations/metadata.js +172 -0
- package/build/api/escalations/resolve.js +4 -23
- package/build/bin/ltc.js +19 -0
- package/build/lib/cli/commands/escalations.d.ts +11 -0
- package/build/lib/cli/commands/escalations.js +40 -0
- package/build/lib/db/schemas/010_metadata_gin.sql +5 -0
- package/build/lib/events/publish.js +2 -0
- package/build/routes/escalations/index.js +3 -0
- package/build/routes/escalations/metadata.d.ts +6 -0
- package/build/routes/escalations/metadata.js +88 -0
- package/build/sdk/index.d.ts +21 -0
- package/build/sdk/index.js +3 -0
- package/build/services/escalation/crud.d.ts +5 -0
- package/build/services/escalation/crud.js +80 -3
- package/build/services/escalation/sql.d.ts +5 -0
- package/build/services/escalation/sql.js +42 -1
- package/build/services/interceptor/activities/escalation.js +1 -0
- package/build/services/interceptor/activities/task.js +2 -23
- package/build/services/interceptor/completion.js +2 -22
- package/build/services/interceptor/escalation.js +5 -44
- package/build/services/interceptor/index.js +26 -2
- package/build/services/interceptor/lifecycle.d.ts +1 -1
- package/build/services/interceptor/lifecycle.js +18 -32
- package/build/services/task/crud.js +36 -2
- package/build/start/server.js +5 -4
- package/build/tsconfig.tsbuildinfo +1 -1
- package/dashboard/dist/assets/{AdminDashboard-Jwr3Fsaz.js → AdminDashboard-BuqyRY2r.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Jwr3Fsaz.js.map → AdminDashboard-BuqyRY2r.js.map} +1 -1
- package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js +16 -0
- package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-Cw7foCHd.js → AgentDetailPage-0Kq-tBF2.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-Cw7foCHd.js.map → AgentDetailPage-0Kq-tBF2.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DzpWsTFO.js → AgentsPage-B5gYDSOX.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DzpWsTFO.js.map → AgentsPage-B5gYDSOX.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-Ddu4V0uf.js → BotPicker-BQ336piW.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-Ddu4V0uf.js.map → BotPicker-BQ336piW.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BTd-uYTM.js → CapabilitiesPage-CkiJROX-.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BTd-uYTM.js.map → CapabilitiesPage-CkiJROX-.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DM-75khr.js → CollapsibleSection-SM8_UjNe.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DM-75khr.js.map → CollapsibleSection-SM8_UjNe.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-BQNraRZu.js → CredentialsPage-f6niro9_.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-BQNraRZu.js.map → CredentialsPage-f6niro9_.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CPuMNBua.js → CronLabel-DINmdqoe.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CPuMNBua.js.map → CronLabel-DINmdqoe.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-CLq8B89Y.js → CustomDurationPicker-BCUcYxfB.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-CLq8B89Y.js.map → CustomDurationPicker-BCUcYxfB.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-8lk94nZt.js → ElapsedCell-DPYZnXsX.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-8lk94nZt.js.map → ElapsedCell-DPYZnXsX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BfSrQ7A5.js → EscalationsOverview-CTB8AEBd.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BfSrQ7A5.js.map → EscalationsOverview-CTB8AEBd.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-D3IOLoxv.js → EventTable-8_r3Tg09.js} +2 -2
- package/dashboard/dist/assets/{EventTable-D3IOLoxv.js.map → EventTable-8_r3Tg09.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-RO3qbF38.js → HomePage-Bjxnjv6p.js} +2 -2
- package/dashboard/dist/assets/{HomePage-RO3qbF38.js.map → HomePage-Bjxnjv6p.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-4lObXT3_.js → ListToolbar-B60JrvJ9.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-4lObXT3_.js.map → ListToolbar-B60JrvJ9.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-BdLivZv8.js → McpOverview-whVRP_Nj.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-BdLivZv8.js.map → McpOverview-whVRP_Nj.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DKFkH1qa.js → McpQueryDetailPage-DPuujJkH.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DKFkH1qa.js.map → McpQueryDetailPage-DPuujJkH.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-AFV_QPwm.js → McpQueryPage-DciK6r7r.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-AFV_QPwm.js.map → McpQueryPage-DciK6r7r.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-DQJ41oKW.js → McpRunDetailPage-QEz8BCTu.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-DQJ41oKW.js.map → McpRunDetailPage-QEz8BCTu.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CzVS7zcc.js → McpRunsPage-BA6AVpi_.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CzVS7zcc.js.map → McpRunsPage-BA6AVpi_.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js.map +1 -0
- package/dashboard/dist/assets/{ProcessDetailPage-qibro3Dm.js → ProcessDetailPage-Dc5ASJpQ.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-qibro3Dm.js.map → ProcessDetailPage-Dc5ASJpQ.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CPgiDbdS.js → ProcessesListPage-Sa-bjC-g.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CPgiDbdS.js.map → ProcessesListPage-Sa-bjC-g.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-BAj88I_Y.js → RolesPage-DmO8Jlbw.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-BAj88I_Y.js.map → RolesPage-DmO8Jlbw.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-IdZ-qOfl.js → RunAsSelector-yWEwIZRe.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-IdZ-qOfl.js.map → RunAsSelector-yWEwIZRe.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-WQ6VMuqg.js → SwimlaneTimeline-CmzfFQ09.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-WQ6VMuqg.js.map → SwimlaneTimeline-CmzfFQ09.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-buNgjwiz.js → TaskDetailPage-CI4JTC62.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-buNgjwiz.js.map → TaskDetailPage-CI4JTC62.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BQjjNjRC.js → TasksListPage-xdNmQsNE.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BQjjNjRC.js.map → TasksListPage-xdNmQsNE.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-Dvkw4shy.js → TimeAgo-B_um9BWR.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-Dvkw4shy.js.map → TimeAgo-B_um9BWR.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DGEGdbOW.js → TimestampCell-BJ6trAqW.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DGEGdbOW.js.map → TimestampCell-BJ6trAqW.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-GY3n1V12.js → ToolTestPanel-DMQhLDES.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-GY3n1V12.js.map → ToolTestPanel-DMQhLDES.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-CGim5yi0.js → TopicDetailPage-YeGQA0vD.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-CGim5yi0.js.map → TopicDetailPage-YeGQA0vD.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DLyRlo0A.js → TopicsPage-B3QZNlWz.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DLyRlo0A.js.map → TopicsPage-B3QZNlWz.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-B8dGlxj9.js → UserName-MpSZ2_EH.js} +2 -2
- package/dashboard/dist/assets/{UserName-B8dGlxj9.js.map → UserName-MpSZ2_EH.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQbIIdIA.js → WorkflowExecutionPage-DqMqDb1h.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BQbIIdIA.js.map → WorkflowExecutionPage-DqMqDb1h.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DL6oRbka.js → WorkflowsDashboard-BF7FpMmk.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DL6oRbka.js.map → WorkflowsDashboard-BF7FpMmk.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Reab_xHT.js → WorkflowsOverview-YFc_KBMS.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Reab_xHT.js.map → WorkflowsOverview-YFc_KBMS.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BoFstOcp.js → YamlWorkflowsPage-BOLs5KTB.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BoFstOcp.js.map → YamlWorkflowsPage-BOLs5KTB.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CQsJU21y.js → agents-CPYVSCQ3.js} +2 -2
- package/dashboard/dist/assets/{agents-CQsJU21y.js.map → agents-CPYVSCQ3.js.map} +1 -1
- package/dashboard/dist/assets/{bots-t1FPESbm.js → bots-DCXjHjID.js} +2 -2
- package/dashboard/dist/assets/{bots-t1FPESbm.js.map → bots-DCXjHjID.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-D1Y3hVvf.js → capabilities-CreogBYU.js} +2 -2
- package/dashboard/dist/assets/{capabilities-D1Y3hVvf.js.map → capabilities-CreogBYU.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CV-y8cfH.js → controlplane-Cm_-Gb1x.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CV-y8cfH.js.map → controlplane-Cm_-Gb1x.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js +2 -0
- package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js.map +1 -0
- package/dashboard/dist/assets/{escalation-Bf_SO_75.js → escalation-ulsBFHVb.js} +2 -2
- package/dashboard/dist/assets/{escalation-Bf_SO_75.js.map → escalation-ulsBFHVb.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-nWSTagzD.js → helpers-etjHeZEI.js} +2 -2
- package/dashboard/dist/assets/{helpers-nWSTagzD.js.map → helpers-etjHeZEI.js.map} +1 -1
- package/dashboard/dist/assets/{index-BRYCB_g0.js → index-7Fbktqcl.js} +2 -2
- package/dashboard/dist/assets/{index-BRYCB_g0.js.map → index-7Fbktqcl.js.map} +1 -1
- package/dashboard/dist/assets/{index-CHBiEYmf.js → index-BkCkBW_D.js} +2 -2
- package/dashboard/dist/assets/{index-CHBiEYmf.js.map → index-BkCkBW_D.js.map} +1 -1
- package/dashboard/dist/assets/{index-B77P0ssX.js → index-BkOv2dQA.js} +2 -2
- package/dashboard/dist/assets/{index-B77P0ssX.js.map → index-BkOv2dQA.js.map} +1 -1
- package/dashboard/dist/assets/index-C37LMzJa.css +1 -0
- package/dashboard/dist/assets/{index-DUaF8VYe.js → index-CKDOaej4.js} +6 -6
- package/dashboard/dist/assets/index-CKDOaej4.js.map +1 -0
- package/dashboard/dist/assets/{index-Dp8iH4i2.js → index-CcvHiZW-.js} +2 -2
- package/dashboard/dist/assets/{index-Dp8iH4i2.js.map → index-CcvHiZW-.js.map} +1 -1
- package/dashboard/dist/assets/{index-BVXXvXlF.js → index-CihScSLF.js} +2 -2
- package/dashboard/dist/assets/{index-BVXXvXlF.js.map → index-CihScSLF.js.map} +1 -1
- package/dashboard/dist/assets/{index-wlL3EZ14.js → index-Cnpo94XG.js} +2 -2
- package/dashboard/dist/assets/{index-wlL3EZ14.js.map → index-Cnpo94XG.js.map} +1 -1
- package/dashboard/dist/assets/{index-CdUj8mKq.js → index-DFuHrLll.js} +2 -2
- package/dashboard/dist/assets/{index-CdUj8mKq.js.map → index-DFuHrLll.js.map} +1 -1
- package/dashboard/dist/assets/{index-0i5oHs_4.js → index-DGpIF_Td.js} +2 -2
- package/dashboard/dist/assets/{index-0i5oHs_4.js.map → index-DGpIF_Td.js.map} +1 -1
- package/dashboard/dist/assets/{index-C42ACUTi.js → index-DT0JeuiL.js} +2 -2
- package/dashboard/dist/assets/{index-C42ACUTi.js.map → index-DT0JeuiL.js.map} +1 -1
- package/dashboard/dist/assets/{index-MO0YnTPi.js → index-DT68ewTC.js} +2 -2
- package/dashboard/dist/assets/{index-MO0YnTPi.js.map → index-DT68ewTC.js.map} +1 -1
- package/dashboard/dist/assets/{index-DAQvhgrL.js → index-DVqtJBno.js} +2 -2
- package/dashboard/dist/assets/{index-DAQvhgrL.js.map → index-DVqtJBno.js.map} +1 -1
- package/dashboard/dist/assets/{index-BZu5zewH.js → index-DYmrNJ_H.js} +4 -4
- package/dashboard/dist/assets/index-DYmrNJ_H.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-DJhm5z0p.js → knowledge-CXA2DJwY.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DJhm5z0p.js.map → knowledge-CXA2DJwY.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DMYXb9fv.js → mcp-DeC-PpeL.js} +2 -2
- package/dashboard/dist/assets/{mcp-DMYXb9fv.js.map → mcp-DeC-PpeL.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DE-oPOvi.js → mcp-query-DldD_RPZ.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DE-oPOvi.js.map → mcp-query-DldD_RPZ.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-Bjjm4EG1.js → namespaces-BIGZ6exX.js} +2 -2
- package/dashboard/dist/assets/{namespaces-Bjjm4EG1.js.map → namespaces-BIGZ6exX.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-C8aRprVr.js → pipelines-BtihifKT.js} +2 -2
- package/dashboard/dist/assets/{pipelines-C8aRprVr.js.map → pipelines-BtihifKT.js.map} +1 -1
- package/dashboard/dist/assets/{roles-CQsPYJXe.js → roles-4DocbpKy.js} +2 -2
- package/dashboard/dist/assets/{roles-CQsPYJXe.js.map → roles-4DocbpKy.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BQ1c7trT.js → tasks-B9P_7SR_.js} +2 -2
- package/dashboard/dist/assets/{tasks-BQ1c7trT.js.map → tasks-B9P_7SR_.js.map} +1 -1
- package/dashboard/dist/assets/{topics-DIziCjqg.js → topics-CcLT-IrY.js} +2 -2
- package/dashboard/dist/assets/{topics-DIziCjqg.js.map → topics-CcLT-IrY.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-CPxcH6zx.js → useEventHooks-B9UOxef_.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CPxcH6zx.js.map → useEventHooks-B9UOxef_.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DnPywDgy.js → useYamlActivityEvents-V_MENSI5.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DnPywDgy.js.map → useYamlActivityEvents-V_MENSI5.js.map} +1 -1
- package/dashboard/dist/assets/{users-CMGaVe_B.js → users-BHF3YOU1.js} +2 -2
- package/dashboard/dist/assets/{users-CMGaVe_B.js.map → users-BHF3YOU1.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-CD7-d5w8.js → workflows-DorgmYSk.js} +2 -2
- package/dashboard/dist/assets/{workflows-CD7-d5w8.js.map → workflows-DorgmYSk.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CIeymjZr.js → yaml-workflows-DTGpqnEG.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CIeymjZr.js.map → yaml-workflows-DTGpqnEG.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +98 -0
- package/docs/api/sdk/escalations.md +86 -0
- package/docs/cli.md +8 -0
- package/docs/sdk.md +1 -1
- package/package.json +1 -1
- package/dashboard/dist/assets/AgentConfigPage-DbqbFXEq.js +0 -16
- package/dashboard/dist/assets/AgentConfigPage-DbqbFXEq.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-D2cxvpAK.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D2cxvpAK.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-B_QmNzLw.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-B_QmNzLw.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-DgY8c1hM.js +0 -2
- package/dashboard/dist/assets/escalation-columns-DgY8c1hM.js.map +0 -1
- package/dashboard/dist/assets/index-BZu5zewH.js.map +0 -1
- package/dashboard/dist/assets/index-DUaF8VYe.js.map +0 -1
- package/dashboard/dist/assets/index-ib-nDwd6.css +0 -1
package/build/sdk/index.d.ts
CHANGED
|
@@ -150,6 +150,27 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
150
150
|
ids: string[];
|
|
151
151
|
hint?: string;
|
|
152
152
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
153
|
+
findByMetadata: (input: {
|
|
154
|
+
key: string;
|
|
155
|
+
value: string;
|
|
156
|
+
status?: string;
|
|
157
|
+
limit?: number;
|
|
158
|
+
offset?: number;
|
|
159
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
160
|
+
claimByMetadata: (input: {
|
|
161
|
+
key: string;
|
|
162
|
+
value: string;
|
|
163
|
+
durationMinutes?: number;
|
|
164
|
+
assignee?: string;
|
|
165
|
+
metadata?: Record<string, any>;
|
|
166
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
167
|
+
resolveByMetadata: (input: {
|
|
168
|
+
key: string;
|
|
169
|
+
value: string;
|
|
170
|
+
resolverPayload: Record<string, any>;
|
|
171
|
+
assignee?: string;
|
|
172
|
+
metadata?: Record<string, any>;
|
|
173
|
+
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
153
174
|
};
|
|
154
175
|
workflows: {
|
|
155
176
|
invoke: (input: {
|
package/build/sdk/index.js
CHANGED
|
@@ -130,6 +130,9 @@ function createClient(options = {}) {
|
|
|
130
130
|
bulkAssign: bindAuth(escalationsApi.bulkAssign, auth),
|
|
131
131
|
bulkEscalate: bindAuth(escalationsApi.bulkEscalate, auth),
|
|
132
132
|
bulkTriage: bindAuth(escalationsApi.bulkTriage, auth),
|
|
133
|
+
findByMetadata: bindAuth(escalationsApi.findByMetadata, auth),
|
|
134
|
+
claimByMetadata: bindAuth(escalationsApi.claimByMetadata, auth),
|
|
135
|
+
resolveByMetadata: bindAuth(escalationsApi.resolveByMetadata, auth),
|
|
133
136
|
},
|
|
134
137
|
// ── Workflows ──────────────────────────────────────────────────────────
|
|
135
138
|
workflows: {
|
|
@@ -45,3 +45,8 @@ export declare function enrichEscalationRouting(id: string, metadataPatch: Recor
|
|
|
45
45
|
taskId?: string;
|
|
46
46
|
}): Promise<LTEscalationRecord | null>;
|
|
47
47
|
export declare function getEscalationsByOriginId(originId: string): Promise<LTEscalationRecord[]>;
|
|
48
|
+
export declare function findByMetadata(key: string, value: string, status?: string, limit?: number, offset?: number): Promise<{
|
|
49
|
+
escalations: LTEscalationRecord[];
|
|
50
|
+
total: number;
|
|
51
|
+
}>;
|
|
52
|
+
export declare function claimByMetadata(key: string, value: string, userId: string, durationMinutes?: number, metadata?: Record<string, any>): Promise<ClaimResult | null>;
|
|
@@ -14,9 +14,14 @@ exports.getEscalationsByWorkflowId = getEscalationsByWorkflowId;
|
|
|
14
14
|
exports.updateEscalationMetadata = updateEscalationMetadata;
|
|
15
15
|
exports.enrichEscalationRouting = enrichEscalationRouting;
|
|
16
16
|
exports.getEscalationsByOriginId = getEscalationsByOriginId;
|
|
17
|
+
exports.findByMetadata = findByMetadata;
|
|
18
|
+
exports.claimByMetadata = claimByMetadata;
|
|
17
19
|
const db_1 = require("../../lib/db");
|
|
20
|
+
const publish_1 = require("../../lib/events/publish");
|
|
21
|
+
const logger_1 = require("../../lib/logger");
|
|
18
22
|
const sql_1 = require("./sql");
|
|
19
23
|
async function createEscalation(input) {
|
|
24
|
+
logger_1.loggerRegistry.info(`[escalation-crud] createEscalation called for wf=${input.workflow_id} type=${input.type} caller=${new Error().stack?.split('\n')[2]?.trim()}`);
|
|
20
25
|
const pool = (0, db_1.getPool)();
|
|
21
26
|
// Ensure the role exists in lt_roles (FK constraint)
|
|
22
27
|
await pool.query(sql_1.ENSURE_ROLE_EXISTS, [input.role]);
|
|
@@ -38,7 +43,18 @@ async function createEscalation(input) {
|
|
|
38
43
|
input.trace_id || null,
|
|
39
44
|
input.span_id || null,
|
|
40
45
|
]);
|
|
41
|
-
|
|
46
|
+
const escalation = rows[0];
|
|
47
|
+
(0, publish_1.publishEscalationEvent)({
|
|
48
|
+
type: 'escalation.created',
|
|
49
|
+
source: 'service',
|
|
50
|
+
workflowId: escalation.workflow_id || '',
|
|
51
|
+
workflowName: escalation.workflow_type || '',
|
|
52
|
+
taskQueue: escalation.task_queue || '',
|
|
53
|
+
escalationId: escalation.id,
|
|
54
|
+
status: 'pending',
|
|
55
|
+
data: { type: input.type, role: input.role },
|
|
56
|
+
});
|
|
57
|
+
return escalation;
|
|
42
58
|
}
|
|
43
59
|
/**
|
|
44
60
|
* Atomic claim operation. Does NOT change status — "claimed" is implicit
|
|
@@ -56,15 +72,39 @@ async function claimEscalation(id, userId, durationMinutes = 30) {
|
|
|
56
72
|
if (rows.length === 0)
|
|
57
73
|
return null;
|
|
58
74
|
const row = rows[0];
|
|
75
|
+
const escalation = row;
|
|
76
|
+
(0, publish_1.publishEscalationEvent)({
|
|
77
|
+
type: 'escalation.claimed',
|
|
78
|
+
source: 'service',
|
|
79
|
+
workflowId: escalation.workflow_id || '',
|
|
80
|
+
workflowName: escalation.workflow_type || '',
|
|
81
|
+
taskQueue: escalation.task_queue || '',
|
|
82
|
+
escalationId: escalation.id,
|
|
83
|
+
status: 'claimed',
|
|
84
|
+
data: { assigned_to: userId },
|
|
85
|
+
});
|
|
59
86
|
return {
|
|
60
|
-
escalation
|
|
87
|
+
escalation,
|
|
61
88
|
isExtension: row.prev_assigned_to === userId,
|
|
62
89
|
};
|
|
63
90
|
}
|
|
64
91
|
async function resolveEscalation(id, resolverPayload) {
|
|
65
92
|
const pool = (0, db_1.getPool)();
|
|
66
93
|
const { rows } = await pool.query(sql_1.RESOLVE_ESCALATION, [id, JSON.stringify(resolverPayload)]);
|
|
67
|
-
|
|
94
|
+
const escalation = rows[0] || null;
|
|
95
|
+
if (escalation) {
|
|
96
|
+
(0, publish_1.publishEscalationEvent)({
|
|
97
|
+
type: 'escalation.resolved',
|
|
98
|
+
source: 'service',
|
|
99
|
+
workflowId: escalation.workflow_id || '',
|
|
100
|
+
workflowName: escalation.workflow_type || '',
|
|
101
|
+
taskQueue: escalation.task_queue || '',
|
|
102
|
+
escalationId: escalation.id,
|
|
103
|
+
status: 'resolved',
|
|
104
|
+
data: {},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return escalation;
|
|
68
108
|
}
|
|
69
109
|
/**
|
|
70
110
|
* Bulk update priority for a set of escalations.
|
|
@@ -148,3 +188,40 @@ async function getEscalationsByOriginId(originId) {
|
|
|
148
188
|
const { rows } = await pool.query(sql_1.GET_ESCALATIONS_BY_ORIGIN_ID, [originId]);
|
|
149
189
|
return rows;
|
|
150
190
|
}
|
|
191
|
+
// --- Metadata candidate key lookups -----------------------------------------
|
|
192
|
+
async function findByMetadata(key, value, status, limit = 50, offset = 0) {
|
|
193
|
+
const pool = (0, db_1.getPool)();
|
|
194
|
+
const filter = JSON.stringify({ [key]: value });
|
|
195
|
+
const [countResult, dataResult] = await Promise.all([
|
|
196
|
+
pool.query(sql_1.COUNT_BY_METADATA, [filter, status || null]),
|
|
197
|
+
pool.query(sql_1.FIND_BY_METADATA, [filter, status || null, limit, offset]),
|
|
198
|
+
]);
|
|
199
|
+
return {
|
|
200
|
+
escalations: dataResult.rows,
|
|
201
|
+
total: parseInt(countResult.rows[0].count, 10),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
async function claimByMetadata(key, value, userId, durationMinutes = 30, metadata) {
|
|
205
|
+
const pool = (0, db_1.getPool)();
|
|
206
|
+
const filter = JSON.stringify({ [key]: value });
|
|
207
|
+
const metaPatch = metadata ? JSON.stringify(metadata) : null;
|
|
208
|
+
const { rows } = await pool.query(sql_1.CLAIM_BY_METADATA, [filter, userId, durationMinutes, metaPatch]);
|
|
209
|
+
if (rows.length === 0)
|
|
210
|
+
return null;
|
|
211
|
+
const row = rows[0];
|
|
212
|
+
const escalation = row;
|
|
213
|
+
(0, publish_1.publishEscalationEvent)({
|
|
214
|
+
type: 'escalation.claimed',
|
|
215
|
+
source: 'service',
|
|
216
|
+
workflowId: escalation.workflow_id || '',
|
|
217
|
+
workflowName: escalation.workflow_type || '',
|
|
218
|
+
taskQueue: escalation.task_queue || '',
|
|
219
|
+
escalationId: escalation.id,
|
|
220
|
+
status: 'claimed',
|
|
221
|
+
data: { assigned_to: userId },
|
|
222
|
+
});
|
|
223
|
+
return {
|
|
224
|
+
escalation,
|
|
225
|
+
isExtension: row.prev_assigned_to === userId,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
@@ -19,3 +19,8 @@ export declare const BULK_RESOLVE_FOR_TRIAGE = "UPDATE lt_escalations\nSET statu
|
|
|
19
19
|
export declare const UPDATE_ESCALATION_METADATA = "UPDATE lt_escalations\nSET metadata = COALESCE(metadata, '{}'::jsonb) || $2::jsonb,\n updated_at = NOW()\nWHERE id = $1\nRETURNING *";
|
|
20
20
|
export declare const ENRICH_ESCALATION_ROUTING = "UPDATE lt_escalations\nSET metadata = COALESCE(metadata, '{}'::jsonb) || $2::jsonb,\n workflow_type = COALESCE(workflow_type, $3),\n workflow_id = COALESCE(workflow_id, $4),\n task_queue = COALESCE(task_queue, $5),\n task_id = COALESCE(task_id, $6),\n updated_at = NOW()\nWHERE id = $1\nRETURNING *";
|
|
21
21
|
export declare const LIST_DISTINCT_TYPES = "SELECT DISTINCT type FROM lt_escalations ORDER BY type";
|
|
22
|
+
/** Find escalations by a single metadata key-value pair. */
|
|
23
|
+
export declare const FIND_BY_METADATA = "SELECT * FROM lt_escalations\nWHERE metadata @> $1::jsonb\n AND ($2::text IS NULL OR status = $2)\nORDER BY priority ASC, created_at ASC\nLIMIT $3 OFFSET $4";
|
|
24
|
+
export declare const COUNT_BY_METADATA = "SELECT COUNT(*) FROM lt_escalations\nWHERE metadata @> $1::jsonb\n AND ($2::text IS NULL OR status = $2)";
|
|
25
|
+
/** Atomic claim by metadata: find one available escalation, claim it, and optionally merge metadata. */
|
|
26
|
+
export declare const CLAIM_BY_METADATA = "WITH target AS (\n SELECT id, assigned_to\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n assigned_to IS NULL\n OR assigned_until <= NOW()\n OR assigned_to = $2\n )\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n),\nupdated AS (\n UPDATE lt_escalations e\n SET assigned_to = $2,\n claimed_at = NOW(),\n assigned_until = NOW() + INTERVAL '1 minute' * $3,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END\n FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT * FROM updated";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Escalation SQL – externalized from crud.ts, bulk.ts, queries.ts
|
|
4
4
|
// ---------------------------------------------------------------------------
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LIST_DISTINCT_TYPES = exports.ENRICH_ESCALATION_ROUTING = exports.UPDATE_ESCALATION_METADATA = exports.BULK_RESOLVE_FOR_TRIAGE = exports.BULK_ESCALATE_TO_ROLE = exports.BULK_ASSIGN = exports.BULK_CLAIM = exports.GET_ESCALATIONS_BY_ORIGIN_ID = exports.GET_ESCALATIONS_BY_WORKFLOW_ID = exports.GET_ESCALATIONS_BY_TASK_ID = exports.GET_ESCALATION = exports.ESCALATE_TO_ROLE = exports.RELEASE_EXPIRED_CLAIMS = exports.RELEASE_ESCALATION = exports.GET_ESCALATION_ROLES = exports.UPDATE_ESCALATIONS_PRIORITY = exports.RESOLVE_ESCALATION = exports.CLAIM_ESCALATION = exports.CREATE_ESCALATION = exports.ENSURE_ROLE_EXISTS = void 0;
|
|
6
|
+
exports.CLAIM_BY_METADATA = exports.COUNT_BY_METADATA = exports.FIND_BY_METADATA = exports.LIST_DISTINCT_TYPES = exports.ENRICH_ESCALATION_ROUTING = exports.UPDATE_ESCALATION_METADATA = exports.BULK_RESOLVE_FOR_TRIAGE = exports.BULK_ESCALATE_TO_ROLE = exports.BULK_ASSIGN = exports.BULK_CLAIM = exports.GET_ESCALATIONS_BY_ORIGIN_ID = exports.GET_ESCALATIONS_BY_WORKFLOW_ID = exports.GET_ESCALATIONS_BY_TASK_ID = exports.GET_ESCALATION = exports.ESCALATE_TO_ROLE = exports.RELEASE_EXPIRED_CLAIMS = exports.RELEASE_ESCALATION = exports.GET_ESCALATION_ROLES = exports.UPDATE_ESCALATIONS_PRIORITY = exports.RESOLVE_ESCALATION = exports.CLAIM_ESCALATION = exports.CREATE_ESCALATION = exports.ENSURE_ROLE_EXISTS = void 0;
|
|
7
7
|
// --- Role management -------------------------------------------------------
|
|
8
8
|
exports.ENSURE_ROLE_EXISTS = 'INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING';
|
|
9
9
|
// --- Single-record CRUD ---------------------------------------------------
|
|
@@ -133,3 +133,44 @@ SET metadata = COALESCE(metadata, '{}'::jsonb) || $2::jsonb,
|
|
|
133
133
|
WHERE id = $1
|
|
134
134
|
RETURNING *`;
|
|
135
135
|
exports.LIST_DISTINCT_TYPES = 'SELECT DISTINCT type FROM lt_escalations ORDER BY type';
|
|
136
|
+
// --- Metadata candidate key lookups -----------------------------------------
|
|
137
|
+
/** Find escalations by a single metadata key-value pair. */
|
|
138
|
+
exports.FIND_BY_METADATA = `\
|
|
139
|
+
SELECT * FROM lt_escalations
|
|
140
|
+
WHERE metadata @> $1::jsonb
|
|
141
|
+
AND ($2::text IS NULL OR status = $2)
|
|
142
|
+
ORDER BY priority ASC, created_at ASC
|
|
143
|
+
LIMIT $3 OFFSET $4`;
|
|
144
|
+
exports.COUNT_BY_METADATA = `\
|
|
145
|
+
SELECT COUNT(*) FROM lt_escalations
|
|
146
|
+
WHERE metadata @> $1::jsonb
|
|
147
|
+
AND ($2::text IS NULL OR status = $2)`;
|
|
148
|
+
/** Atomic claim by metadata: find one available escalation, claim it, and optionally merge metadata. */
|
|
149
|
+
exports.CLAIM_BY_METADATA = `\
|
|
150
|
+
WITH target AS (
|
|
151
|
+
SELECT id, assigned_to
|
|
152
|
+
FROM lt_escalations
|
|
153
|
+
WHERE metadata @> $1::jsonb
|
|
154
|
+
AND status = 'pending'
|
|
155
|
+
AND (
|
|
156
|
+
assigned_to IS NULL
|
|
157
|
+
OR assigned_until <= NOW()
|
|
158
|
+
OR assigned_to = $2
|
|
159
|
+
)
|
|
160
|
+
ORDER BY priority ASC, created_at ASC
|
|
161
|
+
LIMIT 1
|
|
162
|
+
FOR UPDATE SKIP LOCKED
|
|
163
|
+
),
|
|
164
|
+
updated AS (
|
|
165
|
+
UPDATE lt_escalations e
|
|
166
|
+
SET assigned_to = $2,
|
|
167
|
+
claimed_at = NOW(),
|
|
168
|
+
assigned_until = NOW() + INTERVAL '1 minute' * $3,
|
|
169
|
+
metadata = CASE WHEN $4::jsonb IS NOT NULL
|
|
170
|
+
THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb
|
|
171
|
+
ELSE e.metadata END
|
|
172
|
+
FROM target t
|
|
173
|
+
WHERE e.id = t.id
|
|
174
|
+
RETURNING e.*, t.assigned_to AS prev_assigned_to
|
|
175
|
+
)
|
|
176
|
+
SELECT * FROM updated`;
|
|
@@ -81,16 +81,7 @@ async function ltCreateTask(input) {
|
|
|
81
81
|
executing_as: input.executingAs,
|
|
82
82
|
status: input.status,
|
|
83
83
|
});
|
|
84
|
-
(
|
|
85
|
-
type: 'task.created',
|
|
86
|
-
source: 'interceptor',
|
|
87
|
-
workflowId: input.workflowId,
|
|
88
|
-
workflowName: input.workflowType,
|
|
89
|
-
taskQueue: input.taskQueue || 'unknown',
|
|
90
|
-
taskId: task.id,
|
|
91
|
-
originId: input.originId,
|
|
92
|
-
status: input.status || 'pending',
|
|
93
|
-
});
|
|
84
|
+
// Event published by service layer (services/task/crud.ts)
|
|
94
85
|
return task.id;
|
|
95
86
|
}
|
|
96
87
|
/**
|
|
@@ -109,19 +100,7 @@ async function ltCompleteTask(input) {
|
|
|
109
100
|
data: input.data,
|
|
110
101
|
milestones: input.milestones,
|
|
111
102
|
});
|
|
112
|
-
//
|
|
113
|
-
if (input.workflowId) {
|
|
114
|
-
(0, publish_1.publishTaskEvent)({
|
|
115
|
-
type: 'task.completed',
|
|
116
|
-
source: 'orchestrator',
|
|
117
|
-
workflowId: input.workflowId,
|
|
118
|
-
workflowName: input.workflowName || 'unknown',
|
|
119
|
-
taskQueue: input.taskQueue || 'unknown',
|
|
120
|
-
taskId: input.taskId,
|
|
121
|
-
status: 'completed',
|
|
122
|
-
milestones: input.milestones,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
103
|
+
// task.completed event published by service layer (services/task/crud.ts)
|
|
125
104
|
// Publish milestone event from orchestrator context
|
|
126
105
|
if (input.milestones?.length && input.workflowId) {
|
|
127
106
|
(0, publish_1.publishMilestoneEvent)({
|
|
@@ -115,28 +115,8 @@ async function createAdvisoryEscalation(state, result) {
|
|
|
115
115
|
traceId: state.traceId,
|
|
116
116
|
spanId: state.spanId,
|
|
117
117
|
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
source: 'interceptor',
|
|
121
|
-
workflowId: state.workflowId,
|
|
122
|
-
workflowName: state.workflowName,
|
|
123
|
-
taskQueue: state.taskQueue,
|
|
124
|
-
taskId: state.taskId,
|
|
125
|
-
escalationId,
|
|
126
|
-
originId: state.envelope?.lt?.originId,
|
|
127
|
-
status: 'pending',
|
|
128
|
-
data: result.data,
|
|
129
|
-
});
|
|
130
|
-
(0, publish_1.publishTaskEvent)({
|
|
131
|
-
type: 'task.escalated',
|
|
132
|
-
source: 'interceptor',
|
|
133
|
-
workflowId: state.workflowId,
|
|
134
|
-
workflowName: state.workflowName,
|
|
135
|
-
taskQueue: state.taskQueue,
|
|
136
|
-
taskId: state.taskId,
|
|
137
|
-
originId: state.envelope?.lt?.originId,
|
|
138
|
-
status: 'needs_intervention',
|
|
139
|
-
});
|
|
118
|
+
// escalation.created event published by service layer (services/escalation/crud.ts)
|
|
119
|
+
// task.escalated event published by service layer (services/task/crud.ts)
|
|
140
120
|
// Auto-claim to submitting user if known
|
|
141
121
|
const userId = state.envelope?.lt?.userId;
|
|
142
122
|
if (userId) {
|
|
@@ -41,28 +41,8 @@ async function handleEscalation(state, result) {
|
|
|
41
41
|
traceId: state.traceId,
|
|
42
42
|
spanId: state.spanId,
|
|
43
43
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
source: 'interceptor',
|
|
47
|
-
workflowId: state.workflowId,
|
|
48
|
-
workflowName: state.workflowName,
|
|
49
|
-
taskQueue: state.taskQueue,
|
|
50
|
-
taskId: state.taskId,
|
|
51
|
-
escalationId,
|
|
52
|
-
originId: state.envelope?.lt?.originId,
|
|
53
|
-
status: 'pending',
|
|
54
|
-
data: result.data,
|
|
55
|
-
});
|
|
56
|
-
(0, publish_1.publishTaskEvent)({
|
|
57
|
-
type: 'task.escalated',
|
|
58
|
-
source: 'interceptor',
|
|
59
|
-
workflowId: state.workflowId,
|
|
60
|
-
workflowName: state.workflowName,
|
|
61
|
-
taskQueue: state.taskQueue,
|
|
62
|
-
taskId: state.taskId,
|
|
63
|
-
originId: state.envelope?.lt?.originId,
|
|
64
|
-
status: 'needs_intervention',
|
|
65
|
-
});
|
|
44
|
+
// escalation.created event published by service layer (services/escalation/crud.ts)
|
|
45
|
+
// task.escalated event published by service layer (services/task/crud.ts)
|
|
66
46
|
return result;
|
|
67
47
|
}
|
|
68
48
|
/**
|
|
@@ -109,28 +89,9 @@ async function handleErrorEscalation(state, err) {
|
|
|
109
89
|
traceId: state.traceId,
|
|
110
90
|
spanId: state.spanId,
|
|
111
91
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
workflowId: state.workflowId,
|
|
116
|
-
workflowName: state.workflowName,
|
|
117
|
-
taskQueue: state.taskQueue,
|
|
118
|
-
taskId: state.taskId,
|
|
119
|
-
escalationId: errorEscalationId,
|
|
120
|
-
originId: state.envelope?.lt?.originId,
|
|
121
|
-
status: 'pending',
|
|
122
|
-
data: { error: err.message },
|
|
123
|
-
});
|
|
124
|
-
(0, publish_1.publishTaskEvent)({
|
|
125
|
-
type: 'task.escalated',
|
|
126
|
-
source: 'interceptor',
|
|
127
|
-
workflowId: state.workflowId,
|
|
128
|
-
workflowName: state.workflowName,
|
|
129
|
-
taskQueue: state.taskQueue,
|
|
130
|
-
taskId: state.taskId,
|
|
131
|
-
originId: state.envelope?.lt?.originId,
|
|
132
|
-
status: 'needs_intervention',
|
|
133
|
-
});
|
|
92
|
+
// escalation.created event published by service layer (services/escalation/crud.ts)
|
|
93
|
+
// task.escalated event published by service layer (services/task/crud.ts)
|
|
94
|
+
// Publish workflow.failed event (error path only runs once — no replay guard needed)
|
|
134
95
|
(0, publish_1.publishWorkflowEvent)({
|
|
135
96
|
type: 'workflow.failed',
|
|
136
97
|
source: 'interceptor',
|
|
@@ -44,6 +44,7 @@ const escalation_1 = require("./escalation");
|
|
|
44
44
|
const completion_1 = require("./completion");
|
|
45
45
|
const lifecycle_1 = require("./lifecycle");
|
|
46
46
|
const context_2 = require("../iam/context");
|
|
47
|
+
const publish_1 = require("../../lib/events/publish");
|
|
47
48
|
const envelope_1 = require("../iam/envelope");
|
|
48
49
|
const DEFAULT_ACTIVITY_QUEUE = 'lt-interceptor';
|
|
49
50
|
/**
|
|
@@ -104,13 +105,36 @@ function createLTInterceptor(options) {
|
|
|
104
105
|
// task creation, and escalation wiring.
|
|
105
106
|
if (envelope?.metadata?.certified !== true) {
|
|
106
107
|
const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
|
|
107
|
-
|
|
108
|
+
// Publish workflow events even for uncertified workflows
|
|
109
|
+
const taskQueue = (0, lifecycle_1.deriveTaskQueue)(wf);
|
|
110
|
+
(0, lifecycle_1.publishStartedEvents)(wf, taskQueue, undefined, wf.workflowId);
|
|
111
|
+
const result = toolCtx ? await (0, context_2.runWithToolContext)(toolCtx, next) : await next();
|
|
112
|
+
(0, publish_1.publishWorkflowEvent)({
|
|
113
|
+
type: 'workflow.completed',
|
|
114
|
+
source: 'interceptor',
|
|
115
|
+
workflowId: wf.workflowId,
|
|
116
|
+
workflowName: wf.workflowName,
|
|
117
|
+
taskQueue,
|
|
118
|
+
status: 'completed',
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
108
121
|
}
|
|
109
122
|
// 3. Load config — unregistered/uncertified workflows get ToolContext only
|
|
110
123
|
const wfConfig = await activities.ltGetWorkflowConfig(wf.workflowName);
|
|
111
124
|
if (!wfConfig) {
|
|
112
125
|
const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
|
|
113
|
-
|
|
126
|
+
const taskQueue2 = (0, lifecycle_1.deriveTaskQueue)(wf);
|
|
127
|
+
(0, lifecycle_1.publishStartedEvents)(wf, taskQueue2, undefined, wf.workflowId);
|
|
128
|
+
const result2 = toolCtx ? await (0, context_2.runWithToolContext)(toolCtx, next) : await next();
|
|
129
|
+
(0, publish_1.publishWorkflowEvent)({
|
|
130
|
+
type: 'workflow.completed',
|
|
131
|
+
source: 'interceptor',
|
|
132
|
+
workflowId: wf.workflowId,
|
|
133
|
+
workflowName: wf.workflowName,
|
|
134
|
+
taskQueue: taskQueue2,
|
|
135
|
+
status: 'completed',
|
|
136
|
+
});
|
|
137
|
+
return result2;
|
|
114
138
|
}
|
|
115
139
|
const taskQueue = (0, lifecycle_1.deriveTaskQueue)(wf);
|
|
116
140
|
// 3. Find existing task and handle re-run escalation resolution
|
|
@@ -37,7 +37,7 @@ export declare function resolveReRun(activities: ProxiedActivities, envelope: LT
|
|
|
37
37
|
* Also injects originId back into the envelope for downstream consistency.
|
|
38
38
|
*/
|
|
39
39
|
export declare function ensureTaskWithRouting(activities: ProxiedActivities, wf: WorkflowIdentity, envelope: LTEnvelope | undefined, existingTask: any | null, taskQueue: string, reRun: ReRunContext): Promise<TaskContext>;
|
|
40
|
-
/** Publish workflow.started
|
|
40
|
+
/** Publish workflow.started event (guarded against replay). */
|
|
41
41
|
export declare function publishStartedEvents(wf: WorkflowIdentity, taskQueue: string, taskId: string | undefined, originId: string): void;
|
|
42
42
|
/** Complete a task and signal parent for plain (non-LTReturn) results. */
|
|
43
43
|
export declare function completePlainResult(activities: ProxiedActivities, wf: WorkflowIdentity, taskQueue: string, taskId: string | undefined, routing: Record<string, any> | null, result: any): Promise<void>;
|
|
@@ -13,6 +13,7 @@ exports.resolveReRun = resolveReRun;
|
|
|
13
13
|
exports.ensureTaskWithRouting = ensureTaskWithRouting;
|
|
14
14
|
exports.publishStartedEvents = publishStartedEvents;
|
|
15
15
|
exports.completePlainResult = completePlainResult;
|
|
16
|
+
const hotmesh_1 = require("@hotmeshio/hotmesh");
|
|
16
17
|
const publish_1 = require("../../lib/events/publish");
|
|
17
18
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
18
19
|
/** Extract workflow identity fields from the HotMesh context map. */
|
|
@@ -56,17 +57,7 @@ async function resolveReRun(activities, envelope, existingTask, wf, taskQueue) {
|
|
|
56
57
|
escalationId: escalationId,
|
|
57
58
|
resolverPayload: envelope.resolver,
|
|
58
59
|
});
|
|
59
|
-
|
|
60
|
-
type: 'escalation.resolved',
|
|
61
|
-
source: 'interceptor',
|
|
62
|
-
workflowId: wf.workflowId,
|
|
63
|
-
workflowName: wf.workflowName,
|
|
64
|
-
taskQueue,
|
|
65
|
-
taskId: task?.id || existingTask?.id,
|
|
66
|
-
escalationId: escalationId,
|
|
67
|
-
originId: envelope?.lt?.originId,
|
|
68
|
-
status: 'resolved',
|
|
69
|
-
});
|
|
60
|
+
// escalation.resolved event published by service layer (services/escalation/crud.ts)
|
|
70
61
|
}
|
|
71
62
|
return { isReRun, task, metadata };
|
|
72
63
|
}
|
|
@@ -128,28 +119,23 @@ async function ensureTaskWithRouting(activities, wf, envelope, existingTask, tas
|
|
|
128
119
|
}
|
|
129
120
|
return { taskId, routing, originId };
|
|
130
121
|
}
|
|
131
|
-
/** Publish workflow.started
|
|
122
|
+
/** Publish workflow.started event (guarded against replay). */
|
|
132
123
|
function publishStartedEvents(wf, taskQueue, taskId, originId) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
taskQueue,
|
|
149
|
-
taskId: taskId,
|
|
150
|
-
originId,
|
|
151
|
-
status: 'in_progress',
|
|
152
|
-
});
|
|
124
|
+
const { replay } = hotmesh_1.Durable.workflow.workflowInfo();
|
|
125
|
+
const isFirstExecution = Object.keys(replay).length === 0;
|
|
126
|
+
if (isFirstExecution) {
|
|
127
|
+
(0, publish_1.publishWorkflowEvent)({
|
|
128
|
+
type: 'workflow.started',
|
|
129
|
+
source: 'interceptor',
|
|
130
|
+
workflowId: wf.workflowId,
|
|
131
|
+
workflowName: wf.workflowName,
|
|
132
|
+
taskQueue,
|
|
133
|
+
taskId,
|
|
134
|
+
originId,
|
|
135
|
+
status: 'running',
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// task.started event published by service layer (services/task/crud.ts)
|
|
153
139
|
}
|
|
154
140
|
/** Complete a task and signal parent for plain (non-LTReturn) results. */
|
|
155
141
|
async function completePlainResult(activities, wf, taskQueue, taskId, routing, result) {
|
|
@@ -8,6 +8,7 @@ exports.getTaskBySignalId = getTaskBySignalId;
|
|
|
8
8
|
exports.getTaskByWorkflowId = getTaskByWorkflowId;
|
|
9
9
|
exports.listTasks = listTasks;
|
|
10
10
|
const db_1 = require("../../lib/db");
|
|
11
|
+
const publish_1 = require("../../lib/events/publish");
|
|
11
12
|
const sql_1 = require("./sql");
|
|
12
13
|
async function createTask(input) {
|
|
13
14
|
const pool = (0, db_1.getPool)();
|
|
@@ -30,7 +31,18 @@ async function createTask(input) {
|
|
|
30
31
|
input.executing_as || null,
|
|
31
32
|
input.status || null,
|
|
32
33
|
]);
|
|
33
|
-
|
|
34
|
+
const task = rows[0];
|
|
35
|
+
(0, publish_1.publishTaskEvent)({
|
|
36
|
+
type: 'task.created',
|
|
37
|
+
source: 'service',
|
|
38
|
+
workflowId: task.workflow_id || '',
|
|
39
|
+
workflowName: task.workflow_type || '',
|
|
40
|
+
taskQueue: task.task_queue || '',
|
|
41
|
+
taskId: task.id,
|
|
42
|
+
originId: task.origin_id || undefined,
|
|
43
|
+
status: task.status || 'pending',
|
|
44
|
+
});
|
|
45
|
+
return task;
|
|
34
46
|
}
|
|
35
47
|
async function updateTask(id, input) {
|
|
36
48
|
const pool = (0, db_1.getPool)();
|
|
@@ -59,7 +71,29 @@ async function updateTask(id, input) {
|
|
|
59
71
|
}
|
|
60
72
|
values.push(id);
|
|
61
73
|
const { rows } = await pool.query(`UPDATE lt_tasks SET ${sets.join(', ')} WHERE id = $${idx} RETURNING *`, values);
|
|
62
|
-
|
|
74
|
+
const task = rows[0];
|
|
75
|
+
// Publish status-driven events from the single write path
|
|
76
|
+
if (input.status && task) {
|
|
77
|
+
const STATUS_EVENTS = {
|
|
78
|
+
in_progress: 'task.started',
|
|
79
|
+
completed: 'task.completed',
|
|
80
|
+
needs_intervention: 'task.escalated',
|
|
81
|
+
};
|
|
82
|
+
const eventType = STATUS_EVENTS[input.status];
|
|
83
|
+
if (eventType) {
|
|
84
|
+
(0, publish_1.publishTaskEvent)({
|
|
85
|
+
type: eventType,
|
|
86
|
+
source: 'service',
|
|
87
|
+
workflowId: task.workflow_id || '',
|
|
88
|
+
workflowName: task.workflow_type || '',
|
|
89
|
+
taskQueue: task.task_queue || '',
|
|
90
|
+
taskId: task.id,
|
|
91
|
+
originId: task.origin_id || undefined,
|
|
92
|
+
status: input.status,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return task;
|
|
63
97
|
}
|
|
64
98
|
async function appendMilestones(id, milestones) {
|
|
65
99
|
const pool = (0, db_1.getPool)();
|
package/build/start/server.js
CHANGED
|
@@ -30,13 +30,14 @@ function startServer() {
|
|
|
30
30
|
const prodDist = path_1.default.join(__dirname, '..', '..', 'dashboard', 'dist');
|
|
31
31
|
const dashboardDist = (0, fs_1.existsSync)(devDist) ? devDist : prodDist;
|
|
32
32
|
if ((0, fs_1.existsSync)(dashboardDist)) {
|
|
33
|
-
app.use(express_1.default.static(dashboardDist));
|
|
33
|
+
app.use(express_1.default.static(dashboardDist, { index: false }));
|
|
34
34
|
// SPA fallback — inject <base href="/"> so relative asset paths
|
|
35
35
|
// resolve from root regardless of route depth (e.g. /admin/users).
|
|
36
|
-
|
|
37
|
-
const
|
|
36
|
+
// Read on each request so dashboard rebuilds take effect without restart.
|
|
37
|
+
const indexPath = path_1.default.join(dashboardDist, 'index.html');
|
|
38
38
|
app.get('/{*splat}', (_req, res) => {
|
|
39
|
-
|
|
39
|
+
const html = (0, fs_1.readFileSync)(indexPath, 'utf-8').replace('<head>', '<head><base href="/">');
|
|
40
|
+
res.type('html').send(html);
|
|
40
41
|
});
|
|
41
42
|
logger_1.loggerRegistry.info(`[long-tail] Dashboard: http://localhost:${config_1.config.PORT}/`);
|
|
42
43
|
}
|