@hotmeshio/long-tail 0.4.14 → 0.4.16
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/adapters/express.js +14 -0
- package/build/api/escalations/claim.js +1 -10
- package/build/api/escalations/create.js +1 -11
- package/build/api/escalations/metadata.d.ts +2 -0
- package/build/api/escalations/metadata.js +6 -12
- package/build/api/escalations/resolve.js +4 -23
- package/build/api/settings.js +5 -6
- package/build/bin/ltc.js +2 -0
- package/build/index.js +2 -2
- package/build/lib/cli/commands/escalations.d.ts +2 -0
- package/build/lib/cli/commands/escalations.js +4 -0
- package/build/lib/events/nats-ws-proxy.d.ts +19 -0
- package/build/lib/events/nats-ws-proxy.js +68 -0
- package/build/lib/events/nats.d.ts +16 -0
- package/build/lib/events/nats.js +23 -1
- package/build/lib/events/publish.js +2 -0
- package/build/modules/config.d.ts +3 -0
- package/build/modules/config.js +3 -0
- package/build/routes/escalations/metadata.js +4 -2
- package/build/routes/nats-credentials.js +4 -4
- package/build/sdk/index.d.ts +2 -0
- package/build/services/escalation/crud.d.ts +1 -1
- package/build/services/escalation/crud.js +56 -6
- package/build/services/escalation/sql.d.ts +2 -2
- package/build/services/escalation/sql.js +5 -2
- package/build/services/interceptor/activities/escalation.js +1 -11
- 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/index.js +14 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/startup.d.ts +3 -0
- package/dashboard/dist/assets/{AdminDashboard-BuqyRY2r.js → AdminDashboard-Cfo0mwL2.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BuqyRY2r.js.map → AdminDashboard-Cfo0mwL2.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Bum1dUIi.js → AgentConfigPage-DBtvb2x5.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Bum1dUIi.js.map → AgentConfigPage-DBtvb2x5.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-0Kq-tBF2.js → AgentDetailPage-3mZA7SOb.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-0Kq-tBF2.js.map → AgentDetailPage-3mZA7SOb.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-B5gYDSOX.js → AgentsPage-CTVocfBb.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-B5gYDSOX.js.map → AgentsPage-CTVocfBb.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-BWHThQDC.js → AvailableEscalationsPage-CA9x9o5s.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-BWHThQDC.js.map → AvailableEscalationsPage-CA9x9o5s.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-BQ336piW.js → BotPicker-BQp_Vs73.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-BQ336piW.js.map → BotPicker-BQp_Vs73.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CkiJROX-.js → CapabilitiesPage-wpVtkGeU.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CkiJROX-.js.map → CapabilitiesPage-wpVtkGeU.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-SM8_UjNe.js → CollapsibleSection-2eZMMZiG.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-SM8_UjNe.js.map → CollapsibleSection-2eZMMZiG.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-f6niro9_.js → CredentialsPage-DJGLssm0.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-f6niro9_.js.map → CredentialsPage-DJGLssm0.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DINmdqoe.js → CronLabel-DY8VdTS9.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DINmdqoe.js.map → CronLabel-DY8VdTS9.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-BCUcYxfB.js → CustomDurationPicker-DbyqfK35.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BCUcYxfB.js.map → CustomDurationPicker-DbyqfK35.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-DPYZnXsX.js → ElapsedCell-BPYm8RA7.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-DPYZnXsX.js.map → ElapsedCell-BPYm8RA7.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CTB8AEBd.js → EscalationsOverview-kYGHfnLf.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CTB8AEBd.js.map → EscalationsOverview-kYGHfnLf.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-8_r3Tg09.js → EventTable-DSDzJMer.js} +2 -2
- package/dashboard/dist/assets/{EventTable-8_r3Tg09.js.map → EventTable-DSDzJMer.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-Bjxnjv6p.js → HomePage-CwRebzmO.js} +2 -2
- package/dashboard/dist/assets/{HomePage-Bjxnjv6p.js.map → HomePage-CwRebzmO.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-B60JrvJ9.js → ListToolbar-DEef1_-T.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-B60JrvJ9.js.map → ListToolbar-DEef1_-T.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-whVRP_Nj.js → McpOverview-CZFW5qMb.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-whVRP_Nj.js.map → McpOverview-CZFW5qMb.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DPuujJkH.js → McpQueryDetailPage-q9xH-QRo.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DPuujJkH.js.map → McpQueryDetailPage-q9xH-QRo.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DciK6r7r.js → McpQueryPage-D14466yi.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DciK6r7r.js.map → McpQueryPage-D14466yi.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-QEz8BCTu.js → McpRunDetailPage-X0sfRFTk.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-QEz8BCTu.js.map → McpRunDetailPage-X0sfRFTk.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BA6AVpi_.js → McpRunsPage-aZg057y3.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BA6AVpi_.js.map → McpRunsPage-aZg057y3.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-DrUMzwnl.js → OperatorDashboard-iZEHnndU.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DrUMzwnl.js.map → OperatorDashboard-iZEHnndU.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-Dc5ASJpQ.js → ProcessDetailPage-DyzNjwu8.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-Dc5ASJpQ.js.map → ProcessDetailPage-DyzNjwu8.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-Sa-bjC-g.js → ProcessesListPage-CT_3b5Wt.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-Sa-bjC-g.js.map → ProcessesListPage-CT_3b5Wt.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DmO8Jlbw.js → RolesPage-CpRJq-sg.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DmO8Jlbw.js.map → RolesPage-CpRJq-sg.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-yWEwIZRe.js → RunAsSelector-C20rdNsC.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-yWEwIZRe.js.map → RunAsSelector-C20rdNsC.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CmzfFQ09.js → SwimlaneTimeline-CbFaU4bq.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CmzfFQ09.js.map → SwimlaneTimeline-CbFaU4bq.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CI4JTC62.js → TaskDetailPage-22cJsFmM.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CI4JTC62.js.map → TaskDetailPage-22cJsFmM.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-xdNmQsNE.js → TasksListPage-BDmaUIKu.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-xdNmQsNE.js.map → TasksListPage-BDmaUIKu.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-B_um9BWR.js → TimeAgo-7wqEp87-.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-B_um9BWR.js.map → TimeAgo-7wqEp87-.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BJ6trAqW.js → TimestampCell-BBCf8zsN.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BJ6trAqW.js.map → TimestampCell-BBCf8zsN.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-DMQhLDES.js → ToolTestPanel-Dosq1cqG.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-DMQhLDES.js.map → ToolTestPanel-Dosq1cqG.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-YeGQA0vD.js → TopicDetailPage-DW97-YHQ.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-YeGQA0vD.js.map → TopicDetailPage-DW97-YHQ.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-B3QZNlWz.js → TopicsPage-tVPdz-k0.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-B3QZNlWz.js.map → TopicsPage-tVPdz-k0.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-MpSZ2_EH.js → UserName-DX7IBjFn.js} +2 -2
- package/dashboard/dist/assets/{UserName-MpSZ2_EH.js.map → UserName-DX7IBjFn.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DqMqDb1h.js → WorkflowExecutionPage-BjC0j9_L.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DqMqDb1h.js.map → WorkflowExecutionPage-BjC0j9_L.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-BF7FpMmk.js → WorkflowsDashboard-eCH4gpAk.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-BF7FpMmk.js.map → WorkflowsDashboard-eCH4gpAk.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-YFc_KBMS.js → WorkflowsOverview-DaJRDkNy.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-YFc_KBMS.js.map → WorkflowsOverview-DaJRDkNy.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BOLs5KTB.js → YamlWorkflowsPage-CkpQaUmz.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BOLs5KTB.js.map → YamlWorkflowsPage-CkpQaUmz.js.map} +1 -1
- package/dashboard/dist/assets/{agents-CPYVSCQ3.js → agents-B-P5MlEx.js} +2 -2
- package/dashboard/dist/assets/{agents-CPYVSCQ3.js.map → agents-B-P5MlEx.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DCXjHjID.js → bots-CZz9iVys.js} +2 -2
- package/dashboard/dist/assets/{bots-DCXjHjID.js.map → bots-CZz9iVys.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CreogBYU.js → capabilities-DrZ8Vw_v.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CreogBYU.js.map → capabilities-DrZ8Vw_v.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Cm_-Gb1x.js → controlplane-cj-1c-1C.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Cm_-Gb1x.js.map → controlplane-cj-1c-1C.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-ulsBFHVb.js → escalation-BEVFyQnE.js} +2 -2
- package/dashboard/dist/assets/{escalation-ulsBFHVb.js.map → escalation-BEVFyQnE.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-CLqe28Ba.js → escalation-columns-Beox3TXH.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-CLqe28Ba.js.map → escalation-columns-Beox3TXH.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-etjHeZEI.js → helpers-B4gzNq9h.js} +2 -2
- package/dashboard/dist/assets/{helpers-etjHeZEI.js.map → helpers-B4gzNq9h.js.map} +1 -1
- package/dashboard/dist/assets/{index-BkOv2dQA.js → index-3n5VREXN.js} +2 -2
- package/dashboard/dist/assets/{index-BkOv2dQA.js.map → index-3n5VREXN.js.map} +1 -1
- package/dashboard/dist/assets/{index-CKDOaej4.js → index-BAXzN-QB.js} +2 -2
- package/dashboard/dist/assets/{index-CKDOaej4.js.map → index-BAXzN-QB.js.map} +1 -1
- package/dashboard/dist/assets/{index-DVqtJBno.js → index-BCQ65lNu.js} +2 -2
- package/dashboard/dist/assets/{index-DVqtJBno.js.map → index-BCQ65lNu.js.map} +1 -1
- package/dashboard/dist/assets/{index-BkCkBW_D.js → index-BYXiz05a.js} +2 -2
- package/dashboard/dist/assets/{index-BkCkBW_D.js.map → index-BYXiz05a.js.map} +1 -1
- package/dashboard/dist/assets/{index-CcvHiZW-.js → index-Bh-PnP17.js} +2 -2
- package/dashboard/dist/assets/{index-CcvHiZW-.js.map → index-Bh-PnP17.js.map} +1 -1
- package/dashboard/dist/assets/{index-DYmrNJ_H.js → index-BpN31nuC.js} +17 -17
- package/dashboard/dist/assets/index-BpN31nuC.js.map +1 -0
- package/dashboard/dist/assets/{index-DT68ewTC.js → index-C5dHozmW.js} +2 -2
- package/dashboard/dist/assets/{index-DT68ewTC.js.map → index-C5dHozmW.js.map} +1 -1
- package/dashboard/dist/assets/{index-7Fbktqcl.js → index-D1MywQ2z.js} +2 -2
- package/dashboard/dist/assets/{index-7Fbktqcl.js.map → index-D1MywQ2z.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cnpo94XG.js → index-D4KGadbW.js} +2 -2
- package/dashboard/dist/assets/{index-Cnpo94XG.js.map → index-D4KGadbW.js.map} +1 -1
- package/dashboard/dist/assets/{index-DT0JeuiL.js → index-DdKbIZNE.js} +2 -2
- package/dashboard/dist/assets/{index-DT0JeuiL.js.map → index-DdKbIZNE.js.map} +1 -1
- package/dashboard/dist/assets/{index-DFuHrLll.js → index-UtAfnStw.js} +2 -2
- package/dashboard/dist/assets/{index-DFuHrLll.js.map → index-UtAfnStw.js.map} +1 -1
- package/dashboard/dist/assets/{index-DGpIF_Td.js → index-_DfbFHXk.js} +2 -2
- package/dashboard/dist/assets/{index-DGpIF_Td.js.map → index-_DfbFHXk.js.map} +1 -1
- package/dashboard/dist/assets/{index-CihScSLF.js → index-aJRDh4zW.js} +2 -2
- package/dashboard/dist/assets/{index-CihScSLF.js.map → index-aJRDh4zW.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-CXA2DJwY.js → knowledge-DhtKWMON.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CXA2DJwY.js.map → knowledge-DhtKWMON.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DeC-PpeL.js → mcp-BXN7-wGF.js} +2 -2
- package/dashboard/dist/assets/{mcp-DeC-PpeL.js.map → mcp-BXN7-wGF.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-DldD_RPZ.js → mcp-query-BIJP4mQJ.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-DldD_RPZ.js.map → mcp-query-BIJP4mQJ.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-BIGZ6exX.js → namespaces-ne_yDQZX.js} +2 -2
- package/dashboard/dist/assets/{namespaces-BIGZ6exX.js.map → namespaces-ne_yDQZX.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-BtihifKT.js → pipelines-Bcz62DoS.js} +2 -2
- package/dashboard/dist/assets/{pipelines-BtihifKT.js.map → pipelines-Bcz62DoS.js.map} +1 -1
- package/dashboard/dist/assets/{roles-4DocbpKy.js → roles-De2CzGCy.js} +2 -2
- package/dashboard/dist/assets/{roles-4DocbpKy.js.map → roles-De2CzGCy.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-B9P_7SR_.js → tasks-4yL5EfxI.js} +2 -2
- package/dashboard/dist/assets/{tasks-B9P_7SR_.js.map → tasks-4yL5EfxI.js.map} +1 -1
- package/dashboard/dist/assets/{topics-CcLT-IrY.js → topics-DDKHpRwP.js} +2 -2
- package/dashboard/dist/assets/{topics-CcLT-IrY.js.map → topics-DDKHpRwP.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-B9UOxef_.js → useEventHooks-NzIyvoGY.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-B9UOxef_.js.map → useEventHooks-NzIyvoGY.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-V_MENSI5.js → useYamlActivityEvents-Dv6GhDkh.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-V_MENSI5.js.map → useYamlActivityEvents-Dv6GhDkh.js.map} +1 -1
- package/dashboard/dist/assets/{users-BHF3YOU1.js → users-pSMWP58G.js} +2 -2
- package/dashboard/dist/assets/{users-BHF3YOU1.js.map → users-pSMWP58G.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DorgmYSk.js → workflows-COYPOe2I.js} +2 -2
- package/dashboard/dist/assets/{workflows-DorgmYSk.js.map → workflows-COYPOe2I.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-DTGpqnEG.js → yaml-workflows-1dF3ig6u.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-DTGpqnEG.js.map → yaml-workflows-1dF3ig6u.js.map} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/docs/api/http/escalations.md +6 -4
- package/docs/api/http/settings.md +1 -1
- package/docs/api/sdk/escalations.md +6 -4
- package/package.json +3 -2
- package/dashboard/dist/assets/index-DYmrNJ_H.js.map +0 -1
|
@@ -17,8 +17,11 @@ exports.getEscalationsByOriginId = getEscalationsByOriginId;
|
|
|
17
17
|
exports.findByMetadata = findByMetadata;
|
|
18
18
|
exports.claimByMetadata = claimByMetadata;
|
|
19
19
|
const db_1 = require("../../lib/db");
|
|
20
|
+
const publish_1 = require("../../lib/events/publish");
|
|
21
|
+
const logger_1 = require("../../lib/logger");
|
|
20
22
|
const sql_1 = require("./sql");
|
|
21
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()}`);
|
|
22
25
|
const pool = (0, db_1.getPool)();
|
|
23
26
|
// Ensure the role exists in lt_roles (FK constraint)
|
|
24
27
|
await pool.query(sql_1.ENSURE_ROLE_EXISTS, [input.role]);
|
|
@@ -40,7 +43,18 @@ async function createEscalation(input) {
|
|
|
40
43
|
input.trace_id || null,
|
|
41
44
|
input.span_id || null,
|
|
42
45
|
]);
|
|
43
|
-
|
|
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;
|
|
44
58
|
}
|
|
45
59
|
/**
|
|
46
60
|
* Atomic claim operation. Does NOT change status — "claimed" is implicit
|
|
@@ -58,15 +72,39 @@ async function claimEscalation(id, userId, durationMinutes = 30) {
|
|
|
58
72
|
if (rows.length === 0)
|
|
59
73
|
return null;
|
|
60
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
|
+
});
|
|
61
86
|
return {
|
|
62
|
-
escalation
|
|
87
|
+
escalation,
|
|
63
88
|
isExtension: row.prev_assigned_to === userId,
|
|
64
89
|
};
|
|
65
90
|
}
|
|
66
91
|
async function resolveEscalation(id, resolverPayload) {
|
|
67
92
|
const pool = (0, db_1.getPool)();
|
|
68
93
|
const { rows } = await pool.query(sql_1.RESOLVE_ESCALATION, [id, JSON.stringify(resolverPayload)]);
|
|
69
|
-
|
|
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;
|
|
70
108
|
}
|
|
71
109
|
/**
|
|
72
110
|
* Bulk update priority for a set of escalations.
|
|
@@ -163,15 +201,27 @@ async function findByMetadata(key, value, status, limit = 50, offset = 0) {
|
|
|
163
201
|
total: parseInt(countResult.rows[0].count, 10),
|
|
164
202
|
};
|
|
165
203
|
}
|
|
166
|
-
async function claimByMetadata(key, value, userId, durationMinutes = 30) {
|
|
204
|
+
async function claimByMetadata(key, value, userId, durationMinutes = 30, metadata) {
|
|
167
205
|
const pool = (0, db_1.getPool)();
|
|
168
206
|
const filter = JSON.stringify({ [key]: value });
|
|
169
|
-
const
|
|
207
|
+
const metaPatch = metadata ? JSON.stringify(metadata) : null;
|
|
208
|
+
const { rows } = await pool.query(sql_1.CLAIM_BY_METADATA, [filter, userId, durationMinutes, metaPatch]);
|
|
170
209
|
if (rows.length === 0)
|
|
171
210
|
return null;
|
|
172
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
|
+
});
|
|
173
223
|
return {
|
|
174
|
-
escalation
|
|
224
|
+
escalation,
|
|
175
225
|
isExtension: row.prev_assigned_to === userId,
|
|
176
226
|
};
|
|
177
227
|
}
|
|
@@ -22,5 +22,5 @@ export declare const LIST_DISTINCT_TYPES = "SELECT DISTINCT type FROM lt_escalat
|
|
|
22
22
|
/** Find escalations by a single metadata key-value pair. */
|
|
23
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
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 and
|
|
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 FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT * FROM updated";
|
|
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";
|
|
@@ -145,7 +145,7 @@ exports.COUNT_BY_METADATA = `\
|
|
|
145
145
|
SELECT COUNT(*) FROM lt_escalations
|
|
146
146
|
WHERE metadata @> $1::jsonb
|
|
147
147
|
AND ($2::text IS NULL OR status = $2)`;
|
|
148
|
-
/** Atomic claim by metadata: find one available escalation and
|
|
148
|
+
/** Atomic claim by metadata: find one available escalation, claim it, and optionally merge metadata. */
|
|
149
149
|
exports.CLAIM_BY_METADATA = `\
|
|
150
150
|
WITH target AS (
|
|
151
151
|
SELECT id, assigned_to
|
|
@@ -165,7 +165,10 @@ updated AS (
|
|
|
165
165
|
UPDATE lt_escalations e
|
|
166
166
|
SET assigned_to = $2,
|
|
167
167
|
claimed_at = NOW(),
|
|
168
|
-
assigned_until = NOW() + INTERVAL '1 minute' * $3
|
|
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
|
|
169
172
|
FROM target t
|
|
170
173
|
WHERE e.id = t.id
|
|
171
174
|
RETURNING e.*, t.assigned_to AS prev_assigned_to
|
|
@@ -39,7 +39,6 @@ exports.ltEnrichEscalationRouting = ltEnrichEscalationRouting;
|
|
|
39
39
|
exports.ltCreateEscalation = ltCreateEscalation;
|
|
40
40
|
const escalationService = __importStar(require("../../escalation"));
|
|
41
41
|
const logger_1 = require("../../../lib/logger");
|
|
42
|
-
const publish_1 = require("../../../lib/events/publish");
|
|
43
42
|
/**
|
|
44
43
|
* Resolve an escalation record. Called by the interceptor after
|
|
45
44
|
* detecting a re-run (resolver data present in the envelope).
|
|
@@ -107,15 +106,6 @@ async function ltCreateEscalation(input) {
|
|
|
107
106
|
trace_id: input.traceId,
|
|
108
107
|
span_id: input.spanId,
|
|
109
108
|
});
|
|
110
|
-
(
|
|
111
|
-
type: 'escalation.created',
|
|
112
|
-
source: 'interceptor',
|
|
113
|
-
workflowId: input.workflowId || '',
|
|
114
|
-
workflowName: input.workflowType || '',
|
|
115
|
-
taskQueue: input.taskQueue || '',
|
|
116
|
-
escalationId: escalation.id,
|
|
117
|
-
status: 'pending',
|
|
118
|
-
data: { type: input.type, role: input.role },
|
|
119
|
-
});
|
|
109
|
+
// Event published by service layer (services/escalation/crud.ts)
|
|
120
110
|
return escalation.id;
|
|
121
111
|
}
|
|
@@ -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/index.js
CHANGED
|
@@ -14,6 +14,8 @@ const adapters_1 = require("./adapters");
|
|
|
14
14
|
const workers_1 = require("./workers");
|
|
15
15
|
const server_1 = require("./server");
|
|
16
16
|
const socketio_1 = require("../lib/events/socketio");
|
|
17
|
+
const nats_1 = require("../lib/events/nats");
|
|
18
|
+
const nats_ws_proxy_1 = require("../lib/events/nats-ws-proxy");
|
|
17
19
|
/**
|
|
18
20
|
* Start Long Tail with a declarative configuration.
|
|
19
21
|
*
|
|
@@ -79,6 +81,18 @@ async function start(startConfig) {
|
|
|
79
81
|
socketAdapter.attachServer(httpServer);
|
|
80
82
|
await socketAdapter.connect();
|
|
81
83
|
}
|
|
84
|
+
// Attach NATS WebSocket proxy (if configured)
|
|
85
|
+
const natsAdapter = events_1.eventRegistry.getAdapter(nats_1.NatsEventAdapter);
|
|
86
|
+
if (natsAdapter?.wsProxyTarget && httpServer) {
|
|
87
|
+
(0, nats_ws_proxy_1.attachNatsWsProxy)(httpServer, natsAdapter.wsProxyTarget, {
|
|
88
|
+
onWsUrlDerived: (url) => {
|
|
89
|
+
// Auto-set wsUrl if not explicitly configured
|
|
90
|
+
if (!natsAdapter.wsUrl) {
|
|
91
|
+
natsAdapter.setWsUrl(url);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
82
96
|
}
|
|
83
97
|
// 7. Return instance
|
|
84
98
|
const connection = (0, workers_1.buildConnection)();
|