@hotmeshio/long-tail 0.5.3 → 0.5.5
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/README.md +79 -49
- package/build/api/escalations/index.d.ts +1 -1
- package/build/api/escalations/index.js +2 -1
- package/build/api/escalations/resolve.d.ts +10 -0
- package/build/api/escalations/resolve.js +52 -0
- package/build/api/topics.d.ts +14 -4
- package/build/api/topics.js +9 -9
- package/build/lib/events/index.js +6 -0
- package/build/lib/events/publish.js +3 -7
- package/build/lib/events/system-events.js +5 -6
- package/build/routes/escalations/resolve.js +15 -3
- package/build/routes/topics.js +2 -4
- package/build/services/agent/input-mapper.js +33 -10
- package/build/services/escalation/crud.d.ts +18 -0
- package/build/services/escalation/crud.js +29 -0
- package/build/services/escalation/map.js +1 -0
- package/build/services/interceptor/index.js +25 -6
- package/build/services/orchestrator/condition.d.ts +30 -25
- package/build/services/orchestrator/condition.js +30 -26
- package/build/system/mcp-servers/events.js +1 -3
- package/build/types/escalation.d.ts +1 -0
- package/build/types/events.d.ts +90 -23
- package/dashboard/dist/assets/{AdminDashboard-CMzR4d-w.js → AdminDashboard-DIQEViVY.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-CMzR4d-w.js.map → AdminDashboard-DIQEViVY.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-DHCpN4xk.js → AgentConfigPage-Caf5-th-.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-DHCpN4xk.js.map → AgentConfigPage-Caf5-th-.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CSrejvSl.js → AgentDetailPage-_a4tKaM3.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-CSrejvSl.js.map → AgentDetailPage-_a4tKaM3.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-ntuzWHCD.js → AgentsPage-BNlAkEIK.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-ntuzWHCD.js.map → AgentsPage-BNlAkEIK.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-Ci24fdxC.js → AvailableEscalationsPage-Cqy5ECm4.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-Ci24fdxC.js.map → AvailableEscalationsPage-Cqy5ECm4.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-lj42d48P.js → BotPicker-DBvd1yFL.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-lj42d48P.js.map → BotPicker-DBvd1yFL.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-Bea9yLmU.js → CapabilitiesPage-BIdG9RTG.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-Bea9yLmU.js.map → CapabilitiesPage-BIdG9RTG.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BeBsI1M4.js → CollapsibleSection-CggyKhyZ.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BeBsI1M4.js.map → CollapsibleSection-CggyKhyZ.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-BDzFa3HV.js → CredentialsPage-B4sXGLRY.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-BDzFa3HV.js.map → CredentialsPage-B4sXGLRY.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DeNm1I4r.js → CronLabel-GcS5qzZr.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DeNm1I4r.js.map → CronLabel-GcS5qzZr.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-C2OH9YcV.js → CustomDurationPicker-CUYE36-K.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-C2OH9YcV.js.map → CustomDurationPicker-CUYE36-K.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-WdzqA0dR.js → ElapsedCell-BFOMsgwF.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-WdzqA0dR.js.map → ElapsedCell-BFOMsgwF.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-BIEeflEV.js → EscalationsOverview-BfjW6haL.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-BIEeflEV.js.map → EscalationsOverview-BfjW6haL.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-NIhWP__B.js → EventTable-N0XmLk3C.js} +2 -2
- package/dashboard/dist/assets/{EventTable-NIhWP__B.js.map → EventTable-N0XmLk3C.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DtAW8ilc.js → GraphInvokePage-DHiGHiCk.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DtAW8ilc.js.map → GraphInvokePage-DHiGHiCk.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-HsO-M8ub.js → HomePage-jckQolbx.js} +2 -2
- package/dashboard/dist/assets/{HomePage-HsO-M8ub.js.map → HomePage-jckQolbx.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-DqaRlXrF.js → ListToolbar-B71DqaXr.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-DqaRlXrF.js.map → ListToolbar-B71DqaXr.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-B4GsHxij.js → McpOverview-CPD6NRGt.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-B4GsHxij.js.map → McpOverview-CPD6NRGt.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DZKpzWST.js → McpQueryDetailPage-YyqXw6Dt.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DZKpzWST.js.map → McpQueryDetailPage-YyqXw6Dt.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-B-8WR3GV.js → McpQueryPage-BWf45EYD.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-B-8WR3GV.js.map → McpQueryPage-BWf45EYD.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-Dt7Ai3qB.js → McpRunDetailPage-Cv43tkjz.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Dt7Ai3qB.js.map → McpRunDetailPage-Cv43tkjz.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-Bdke-HoQ.js → McpRunsPage-BFards4K.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-Bdke-HoQ.js.map → McpRunsPage-BFards4K.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-VZ97mufd.js → OperatorDashboard-BJZxuOKI.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-VZ97mufd.js.map → OperatorDashboard-BJZxuOKI.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BLfLfmWX.js → ProcessDetailPage-BjkLfyrm.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BLfLfmWX.js.map → ProcessDetailPage-BjkLfyrm.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DG54t-Nd.js → ProcessesListPage-DOzeduP3.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DG54t-Nd.js.map → ProcessesListPage-DOzeduP3.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-Bdlv3DdW.js → RolesPage-DSSQrGTh.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-Bdlv3DdW.js.map → RolesPage-DSSQrGTh.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BFxxMvL3.js → RunAsSelector-CM7lk1YB.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BFxxMvL3.js.map → RunAsSelector-CM7lk1YB.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BZmad7WQ.js → SwimlaneTimeline-DtCgJNpV.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BZmad7WQ.js.map → SwimlaneTimeline-DtCgJNpV.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CLl2mgBC.js → TaskDetailPage-BC9xnyLT.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CLl2mgBC.js.map → TaskDetailPage-BC9xnyLT.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DoHXxZF-.js → TasksListPage-DtbLfUS-.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DoHXxZF-.js.map → TasksListPage-DtbLfUS-.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-DZF9w8Rl.js → TimeAgo-xrDlFnPy.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-DZF9w8Rl.js.map → TimeAgo-xrDlFnPy.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DPpoTdrw.js → TimestampCell-BneATvjR.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DPpoTdrw.js.map → TimestampCell-BneATvjR.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-DtAgJQfr.js → ToolTestPanel-1lQ_GQod.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-DtAgJQfr.js.map → ToolTestPanel-1lQ_GQod.js.map} +1 -1
- package/dashboard/dist/assets/TopicDetailPage-CDtlXyut.js +9 -0
- package/dashboard/dist/assets/TopicDetailPage-CDtlXyut.js.map +1 -0
- package/dashboard/dist/assets/{TopicsPage-Bc-4ne6V.js → TopicsPage-COX2kDKK.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-Bc-4ne6V.js.map → TopicsPage-COX2kDKK.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-O2Q4-E6E.js → UserName-Cb2WvhCN.js} +2 -2
- package/dashboard/dist/assets/{UserName-O2Q4-E6E.js.map → UserName-Cb2WvhCN.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DEDsBmn1.js → WorkflowExecutionPage-BWCTOTXF.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DEDsBmn1.js.map → WorkflowExecutionPage-BWCTOTXF.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-Bcf17vCt.js → WorkflowsDashboard-DOaDSC98.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-Bcf17vCt.js.map → WorkflowsDashboard-DOaDSC98.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Cwo2rqGT.js → WorkflowsOverview-CeE7a51J.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Cwo2rqGT.js.map → WorkflowsOverview-CeE7a51J.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bv8ZFwO-.js → YamlWorkflowDetailPage-cNpR0PHg.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Bv8ZFwO-.js.map → YamlWorkflowDetailPage-cNpR0PHg.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-DOiEQDOq.js → YamlWorkflowsPage-DWvNfzji.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-DOiEQDOq.js.map → YamlWorkflowsPage-DWvNfzji.js.map} +1 -1
- package/dashboard/dist/assets/{agents-D09G0HCv.js → agents-BvTiBKBQ.js} +2 -2
- package/dashboard/dist/assets/{agents-D09G0HCv.js.map → agents-BvTiBKBQ.js.map} +1 -1
- package/dashboard/dist/assets/{bots-D0LhyZZM.js → bots-CeMR1Lnp.js} +2 -2
- package/dashboard/dist/assets/{bots-D0LhyZZM.js.map → bots-CeMR1Lnp.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DON4-NXs.js → capabilities-D7uJlnxj.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DON4-NXs.js.map → capabilities-D7uJlnxj.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-Bihd1kXf.js → controlplane-Cf6lZsSF.js} +2 -2
- package/dashboard/dist/assets/{controlplane-Bihd1kXf.js.map → controlplane-Cf6lZsSF.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-CP2XbdXK.js → escalation-BCFBWGP-.js} +2 -2
- package/dashboard/dist/assets/{escalation-CP2XbdXK.js.map → escalation-BCFBWGP-.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-9aw8Y4qq.js → escalation-columns-Do7k4fte.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-9aw8Y4qq.js.map → escalation-columns-Do7k4fte.js.map} +1 -1
- package/dashboard/dist/assets/{index-DgLZ8Ix5.js → index-8C9YLM_u.js} +2 -2
- package/dashboard/dist/assets/{index-DgLZ8Ix5.js.map → index-8C9YLM_u.js.map} +1 -1
- package/dashboard/dist/assets/{index-CCup2uaP.js → index-B216fPN_.js} +2 -2
- package/dashboard/dist/assets/{index-CCup2uaP.js.map → index-B216fPN_.js.map} +1 -1
- package/dashboard/dist/assets/index-BCfzac3h.css +1 -0
- package/dashboard/dist/assets/{index-Cb7aSzox.js → index-BDhEpETz.js} +2 -2
- package/dashboard/dist/assets/{index-Cb7aSzox.js.map → index-BDhEpETz.js.map} +1 -1
- package/dashboard/dist/assets/{index-_JsRJPds.js → index-BS5pcmBR.js} +2 -2
- package/dashboard/dist/assets/{index-_JsRJPds.js.map → index-BS5pcmBR.js.map} +1 -1
- package/dashboard/dist/assets/{index-B-BK3vtk.js → index-BUu3WKvk.js} +2 -2
- package/dashboard/dist/assets/{index-B-BK3vtk.js.map → index-BUu3WKvk.js.map} +1 -1
- package/dashboard/dist/assets/{index-BTp73vYK.js → index-C1p_rvkY.js} +2 -2
- package/dashboard/dist/assets/{index-BTp73vYK.js.map → index-C1p_rvkY.js.map} +1 -1
- package/dashboard/dist/assets/{index-CMRW_PE-.js → index-C51Jzvoz.js} +2 -2
- package/dashboard/dist/assets/{index-CMRW_PE-.js.map → index-C51Jzvoz.js.map} +1 -1
- package/dashboard/dist/assets/{index-BBBGETMs.js → index-D0fjUKvx.js} +2 -2
- package/dashboard/dist/assets/{index-BBBGETMs.js.map → index-D0fjUKvx.js.map} +1 -1
- package/dashboard/dist/assets/{index-BInTEEIX.js → index-D3SjB3UM.js} +2 -2
- package/dashboard/dist/assets/{index-BInTEEIX.js.map → index-D3SjB3UM.js.map} +1 -1
- package/dashboard/dist/assets/{index-rbuNUyAh.js → index-DSjbScPX.js} +2 -2
- package/dashboard/dist/assets/{index-rbuNUyAh.js.map → index-DSjbScPX.js.map} +1 -1
- package/dashboard/dist/assets/{index-B7lEd0cY.js → index-eWNx4UQ8.js} +3 -3
- package/dashboard/dist/assets/{index-B7lEd0cY.js.map → index-eWNx4UQ8.js.map} +1 -1
- package/dashboard/dist/assets/{index-H5Yb8CY2.js → index-gKm3HAgO.js} +2 -2
- package/dashboard/dist/assets/{index-H5Yb8CY2.js.map → index-gKm3HAgO.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cjb8ulHm.js → index-oulO44Iy.js} +2 -2
- package/dashboard/dist/assets/{index-Cjb8ulHm.js.map → index-oulO44Iy.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-Bl_KaoKJ.js → knowledge-Bje8_ndK.js} +2 -2
- package/dashboard/dist/assets/{knowledge-Bl_KaoKJ.js.map → knowledge-Bje8_ndK.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-DXbFGoA8.js → mcp-Bpl6p11J.js} +2 -2
- package/dashboard/dist/assets/{mcp-DXbFGoA8.js.map → mcp-Bpl6p11J.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-Bg69DF2x.js → mcp-query-DMXj-t5f.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-Bg69DF2x.js.map → mcp-query-DMXj-t5f.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-DK9LTg9F.js → pipelines-CFh9nBxn.js} +2 -2
- package/dashboard/dist/assets/{pipelines-DK9LTg9F.js.map → pipelines-CFh9nBxn.js.map} +1 -1
- package/dashboard/dist/assets/{roles-BrsBN4hO.js → roles-CtjQQWSQ.js} +2 -2
- package/dashboard/dist/assets/{roles-BrsBN4hO.js.map → roles-CtjQQWSQ.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CwjvPECN.js → tasks-Nz9lVCT1.js} +2 -2
- package/dashboard/dist/assets/{tasks-CwjvPECN.js.map → tasks-Nz9lVCT1.js.map} +1 -1
- package/dashboard/dist/assets/topics-CiG2N8Z_.js +2 -0
- package/dashboard/dist/assets/{topics-BrwkmaFR.js.map → topics-CiG2N8Z_.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-Cd1GM1NG.js → useEventHooks-Bimqt7hU.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-Cd1GM1NG.js.map → useEventHooks-Bimqt7hU.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-D9lghZ25.js → useNamespace-FrG0Monz.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-D9lghZ25.js.map → useNamespace-FrG0Monz.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-vOhAwmKO.js → useYamlActivityEvents-JmD4dH5n.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-vOhAwmKO.js.map → useYamlActivityEvents-JmD4dH5n.js.map} +1 -1
- package/dashboard/dist/assets/{users-ChQ7soaq.js → users-DgyonYq6.js} +2 -2
- package/dashboard/dist/assets/{users-ChQ7soaq.js.map → users-DgyonYq6.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-BLKji1_1.js → workflows-BOwGINtF.js} +2 -2
- package/dashboard/dist/assets/{workflows-BLKji1_1.js.map → workflows-BOwGINtF.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BUhMfdaw.js → yaml-workflows-I1tcjCFK.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BUhMfdaw.js.map → yaml-workflows-I1tcjCFK.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +19 -0
- package/docs/api/sdk/escalations.md +33 -0
- package/docs/data.md +61 -38
- package/docs/events.md +34 -13
- package/docs/hitl-guide.md +44 -1
- package/package.json +2 -2
- package/dashboard/dist/assets/TopicDetailPage-W9RKkNNp.js +0 -9
- package/dashboard/dist/assets/TopicDetailPage-W9RKkNNp.js.map +0 -1
- package/dashboard/dist/assets/index-BFyzZGtv.css +0 -1
- package/dashboard/dist/assets/topics-BrwkmaFR.js +0 -2
|
@@ -14,6 +14,24 @@ export declare function claimEscalation(id: string, userId: string, durationMinu
|
|
|
14
14
|
* row is missing or already terminal.
|
|
15
15
|
*/
|
|
16
16
|
export declare function resolveEscalation(id: string, resolverPayload: Record<string, any>): Promise<LTEscalationRecord | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Look up an efficient (atomic) escalation by its `signal_key` — the signal id
|
|
19
|
+
* passed to `conditionLT(signalId, config)` / `condition(signalId, config)`.
|
|
20
|
+
* Returns null when no row carries that key.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getEscalationBySignalKey(signalKey: string): Promise<LTEscalationRecord | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve an efficient (atomic) escalation by its `signal_key` and resume the
|
|
25
|
+
* waiting workflow in place. Convenience for webhook callers that know the
|
|
26
|
+
* deterministic signal id (e.g. `signal-scan-ar-${orderId}`) and want to skip
|
|
27
|
+
* the id lookup. Returns null when the key is unknown or already terminal.
|
|
28
|
+
*
|
|
29
|
+
* Race-free: `signal_key → id` is an immutable mapping, and the state mutation
|
|
30
|
+
* is delegated to `resolveEscalation`, whose `client.resolve` uses FOR UPDATE +
|
|
31
|
+
* `WHERE status = 'pending'` so exactly one concurrent caller commits. No status
|
|
32
|
+
* pre-check (that would be a TOCTOU window) — the atomic resolve is the arbiter.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveEscalationBySignalKey(signalKey: string, resolverPayload: Record<string, any>): Promise<LTEscalationRecord | null>;
|
|
17
35
|
/**
|
|
18
36
|
* Bulk update priority for a set of escalations. Only pending escalations are
|
|
19
37
|
* updated.
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createEscalation = createEscalation;
|
|
4
4
|
exports.claimEscalation = claimEscalation;
|
|
5
5
|
exports.resolveEscalation = resolveEscalation;
|
|
6
|
+
exports.getEscalationBySignalKey = getEscalationBySignalKey;
|
|
7
|
+
exports.resolveEscalationBySignalKey = resolveEscalationBySignalKey;
|
|
6
8
|
exports.updateEscalationsPriority = updateEscalationsPriority;
|
|
7
9
|
exports.getEscalationRoles = getEscalationRoles;
|
|
8
10
|
exports.releaseEscalation = releaseEscalation;
|
|
@@ -109,6 +111,33 @@ async function resolveEscalation(id, resolverPayload) {
|
|
|
109
111
|
});
|
|
110
112
|
return escalation;
|
|
111
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Look up an efficient (atomic) escalation by its `signal_key` — the signal id
|
|
116
|
+
* passed to `conditionLT(signalId, config)` / `condition(signalId, config)`.
|
|
117
|
+
* Returns null when no row carries that key.
|
|
118
|
+
*/
|
|
119
|
+
async function getEscalationBySignalKey(signalKey) {
|
|
120
|
+
const client = await (0, client_1.escalations)();
|
|
121
|
+
const entry = await client.getBySignalKey(signalKey);
|
|
122
|
+
return entry ? (0, map_1.toEscalationRecord)(entry) : null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Resolve an efficient (atomic) escalation by its `signal_key` and resume the
|
|
126
|
+
* waiting workflow in place. Convenience for webhook callers that know the
|
|
127
|
+
* deterministic signal id (e.g. `signal-scan-ar-${orderId}`) and want to skip
|
|
128
|
+
* the id lookup. Returns null when the key is unknown or already terminal.
|
|
129
|
+
*
|
|
130
|
+
* Race-free: `signal_key → id` is an immutable mapping, and the state mutation
|
|
131
|
+
* is delegated to `resolveEscalation`, whose `client.resolve` uses FOR UPDATE +
|
|
132
|
+
* `WHERE status = 'pending'` so exactly one concurrent caller commits. No status
|
|
133
|
+
* pre-check (that would be a TOCTOU window) — the atomic resolve is the arbiter.
|
|
134
|
+
*/
|
|
135
|
+
async function resolveEscalationBySignalKey(signalKey, resolverPayload) {
|
|
136
|
+
const escalation = await getEscalationBySignalKey(signalKey);
|
|
137
|
+
if (!escalation)
|
|
138
|
+
return null;
|
|
139
|
+
return resolveEscalation(escalation.id, resolverPayload);
|
|
140
|
+
}
|
|
112
141
|
/**
|
|
113
142
|
* Bulk update priority for a set of escalations. Only pending escalations are
|
|
114
143
|
* updated.
|
|
@@ -23,6 +23,7 @@ function toEscalationRecord(entry) {
|
|
|
23
23
|
workflow_id: entry.workflow_id,
|
|
24
24
|
task_queue: entry.task_queue,
|
|
25
25
|
workflow_type: entry.workflow_type,
|
|
26
|
+
signal_key: entry.signal_key,
|
|
26
27
|
role: entry.role ?? '',
|
|
27
28
|
assigned_to: entry.assigned_to,
|
|
28
29
|
assigned_until: entry.assigned_until,
|
|
@@ -100,12 +100,31 @@ function createLTInterceptor(options) {
|
|
|
100
100
|
retry: { maximumAttempts: 3 },
|
|
101
101
|
});
|
|
102
102
|
const envelope = (0, state_1.extractEnvelope)(ctx);
|
|
103
|
-
// 2.
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
// (services/
|
|
103
|
+
// 2. Opt-in gate — the envelope drives behavior. Certification is opt-in:
|
|
104
|
+
// only workflows explicitly marked `metadata.certified === true` pay for
|
|
105
|
+
// the config lookup, task tracking, and escalation wiring. Every other
|
|
106
|
+
// durable workflow is a pure pass-through (ToolContext for identity +
|
|
107
|
+
// fire-and-forget lifecycle events) — NO proxyActivity, NO DB lookup, NO
|
|
108
|
+
// extra durable leg. The invoke layer (services/workflow-invocation)
|
|
109
|
+
// stamps certified:true for certified workflows; executeLT propagates it
|
|
110
|
+
// to children. This keeps plain durable workflows free of interceptor cost.
|
|
111
|
+
if (envelope?.metadata?.certified !== true) {
|
|
112
|
+
const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
|
|
113
|
+
const taskQueue0 = (0, lifecycle_1.deriveTaskQueue)(wf);
|
|
114
|
+
(0, lifecycle_1.publishStartedEvents)(wf, taskQueue0, undefined, wf.workflowId);
|
|
115
|
+
const result0 = toolCtx ? await (0, context_2.runWithToolContext)(toolCtx, next) : await next();
|
|
116
|
+
(0, publish_1.publishWorkflowEvent)({
|
|
117
|
+
type: 'workflow.completed',
|
|
118
|
+
source: 'interceptor',
|
|
119
|
+
workflowId: wf.workflowId,
|
|
120
|
+
workflowName: wf.workflowName,
|
|
121
|
+
taskQueue: taskQueue0,
|
|
122
|
+
status: 'completed',
|
|
123
|
+
});
|
|
124
|
+
return result0;
|
|
125
|
+
}
|
|
126
|
+
// 3. Opted in (certified === true): load config. A certified workflow with
|
|
127
|
+
// no registered config still falls back to ToolContext + events only.
|
|
109
128
|
const wfConfig = await activities.ltGetWorkflowConfig(wf.workflowName);
|
|
110
129
|
if (!wfConfig) {
|
|
111
130
|
const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
|
|
@@ -1,34 +1,39 @@
|
|
|
1
|
+
import type { Types } from '@hotmeshio/hotmesh';
|
|
1
2
|
/**
|
|
2
3
|
* Wait for a signal and resolve the associated escalation automatically.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* activity,
|
|
5
|
+
* Two ways to call it:
|
|
6
|
+
*
|
|
7
|
+
* **Efficient (atomic) — pass an escalation config.** The escalation row is
|
|
8
|
+
* written inside this workflow's Leg1 checkpoint (one commit, crash-safe — no
|
|
9
|
+
* separate create activity, no enrich). `signal_key` is the signal id, so the
|
|
10
|
+
* dashboard resolve endpoint (Path 0), `resolveEscalationBySignalKey`, and any
|
|
11
|
+
* webhook resume the SAME job in place. `system.escalation.{id}.created` fires
|
|
12
|
+
* from the engine automatically.
|
|
9
13
|
*
|
|
10
|
-
* Usage (from within a workflow):
|
|
11
14
|
* ```typescript
|
|
12
|
-
*
|
|
15
|
+
* const decision = await conditionLT<{ approved: boolean }>(signalId, {
|
|
16
|
+
* role: 'reviewer',
|
|
17
|
+
* type: 'orderPipeline',
|
|
18
|
+
* subtype: stationName,
|
|
19
|
+
* priority: 2,
|
|
20
|
+
* description: instructions,
|
|
21
|
+
* metadata: { orderId, station: stationName },
|
|
22
|
+
* envelope: { instructions },
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
13
25
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* // ...
|
|
22
|
-
* });
|
|
26
|
+
* **Legacy (two-step) — no config.** Create the escalation first (e.g. via
|
|
27
|
+
* `ltCreateEscalation`) with `signal_id`/`signal_routing` metadata, then wait.
|
|
28
|
+
* On resume the signal payload carries an injected `$escalation_id`; this helper
|
|
29
|
+
* strips it, resolves the escalation as a durable activity, and returns the
|
|
30
|
+
* clean resolver payload. If no `$escalation_id` is present (efficient path, or
|
|
31
|
+
* a manual signal), the payload is returned as-is — the escalation was already
|
|
32
|
+
* resolved server-side.
|
|
23
33
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* }
|
|
34
|
+
* ```typescript
|
|
35
|
+
* await activities.ltCreateEscalation({ type: 'approval', role: 'reviewer', metadata: { signal_id: signalId } });
|
|
36
|
+
* const decision = await conditionLT<{ approved: boolean }>(signalId);
|
|
28
37
|
* ```
|
|
29
|
-
*
|
|
30
|
-
* If the signal payload does not contain `$escalation_id` (e.g., signaled
|
|
31
|
-
* manually), the function returns the payload as-is without calling
|
|
32
|
-
* the resolve activity.
|
|
33
38
|
*/
|
|
34
|
-
export declare function conditionLT<T = Record<string, any>>(signalId: string): Promise<T>;
|
|
39
|
+
export declare function conditionLT<T = Record<string, any>>(signalId: string, escalation?: Types.ConditionQueueConfig): Promise<T>;
|
|
@@ -40,38 +40,42 @@ const LT_ACTIVITY_QUEUE = 'lt-interceptor';
|
|
|
40
40
|
/**
|
|
41
41
|
* Wait for a signal and resolve the associated escalation automatically.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* activity,
|
|
43
|
+
* Two ways to call it:
|
|
44
|
+
*
|
|
45
|
+
* **Efficient (atomic) — pass an escalation config.** The escalation row is
|
|
46
|
+
* written inside this workflow's Leg1 checkpoint (one commit, crash-safe — no
|
|
47
|
+
* separate create activity, no enrich). `signal_key` is the signal id, so the
|
|
48
|
+
* dashboard resolve endpoint (Path 0), `resolveEscalationBySignalKey`, and any
|
|
49
|
+
* webhook resume the SAME job in place. `system.escalation.{id}.created` fires
|
|
50
|
+
* from the engine automatically.
|
|
48
51
|
*
|
|
49
|
-
* Usage (from within a workflow):
|
|
50
52
|
* ```typescript
|
|
51
|
-
*
|
|
53
|
+
* const decision = await conditionLT<{ approved: boolean }>(signalId, {
|
|
54
|
+
* role: 'reviewer',
|
|
55
|
+
* type: 'orderPipeline',
|
|
56
|
+
* subtype: stationName,
|
|
57
|
+
* priority: 2,
|
|
58
|
+
* description: instructions,
|
|
59
|
+
* metadata: { orderId, station: stationName },
|
|
60
|
+
* envelope: { instructions },
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
52
63
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* // ...
|
|
61
|
-
* });
|
|
64
|
+
* **Legacy (two-step) — no config.** Create the escalation first (e.g. via
|
|
65
|
+
* `ltCreateEscalation`) with `signal_id`/`signal_routing` metadata, then wait.
|
|
66
|
+
* On resume the signal payload carries an injected `$escalation_id`; this helper
|
|
67
|
+
* strips it, resolves the escalation as a durable activity, and returns the
|
|
68
|
+
* clean resolver payload. If no `$escalation_id` is present (efficient path, or
|
|
69
|
+
* a manual signal), the payload is returned as-is — the escalation was already
|
|
70
|
+
* resolved server-side.
|
|
62
71
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* }
|
|
72
|
+
* ```typescript
|
|
73
|
+
* await activities.ltCreateEscalation({ type: 'approval', role: 'reviewer', metadata: { signal_id: signalId } });
|
|
74
|
+
* const decision = await conditionLT<{ approved: boolean }>(signalId);
|
|
67
75
|
* ```
|
|
68
|
-
*
|
|
69
|
-
* If the signal payload does not contain `$escalation_id` (e.g., signaled
|
|
70
|
-
* manually), the function returns the payload as-is without calling
|
|
71
|
-
* the resolve activity.
|
|
72
76
|
*/
|
|
73
|
-
async function conditionLT(signalId) {
|
|
74
|
-
const raw = await hotmesh_1.Durable.workflow.condition(signalId);
|
|
77
|
+
async function conditionLT(signalId, escalation) {
|
|
78
|
+
const raw = await hotmesh_1.Durable.workflow.condition(signalId, escalation);
|
|
75
79
|
const escalationId = raw.$escalation_id;
|
|
76
80
|
if (escalationId) {
|
|
77
81
|
// Resolve the escalation as a durable activity (crash-safe)
|
|
@@ -50,12 +50,10 @@ function registerTools(srv) {
|
|
|
50
50
|
},
|
|
51
51
|
}, async (args) => {
|
|
52
52
|
const topic = args.topic.startsWith('app.') ? args.topic : `app.${args.topic}`;
|
|
53
|
+
// Custom `app.*` event: minimal envelope + data, no workflow fields.
|
|
53
54
|
const event = {
|
|
54
55
|
type: topic,
|
|
55
56
|
source: args.source || 'mcp-tool',
|
|
56
|
-
workflowId: '',
|
|
57
|
-
workflowName: '',
|
|
58
|
-
taskQueue: '',
|
|
59
57
|
data: args.data,
|
|
60
58
|
timestamp: new Date().toISOString(),
|
|
61
59
|
};
|
package/build/types/events.d.ts
CHANGED
|
@@ -23,38 +23,105 @@ export type LTEventType = LTSystemEventPattern;
|
|
|
23
23
|
*/
|
|
24
24
|
export type LTAppEventType = `app.${string}`;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* The minimal universal envelope every event carries — system OR custom.
|
|
27
|
+
*
|
|
28
|
+
* Only `type` and `timestamp` are required. `id` is minted by
|
|
29
|
+
* `eventRegistry.publish()` when omitted (custom publishers may supply their
|
|
30
|
+
* own). Everything beyond this base is a per-family extension — see the
|
|
31
|
+
* `LT*Event` interfaces below — added only by the families that need it. A
|
|
32
|
+
* custom app event (e.g. `app.image.resized`) is just this base plus `data`;
|
|
33
|
+
* no workflow fields are injected.
|
|
27
34
|
*/
|
|
28
|
-
export interface
|
|
29
|
-
/** Idempotent event identifier.
|
|
35
|
+
export interface LTEventBase {
|
|
36
|
+
/** Idempotent event identifier. Minted by eventRegistry.publish() if omitted. */
|
|
30
37
|
id?: string;
|
|
31
|
-
/**
|
|
32
|
-
type: LTSystemEventPattern | string;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
/** Subject — structured for system events, free-form `app.*` for custom events. */
|
|
39
|
+
type: LTSystemEventPattern | LTAppEventType | string;
|
|
40
|
+
/** ISO 8601 timestamp. Set by the publisher; eventRegistry ensures it is present. */
|
|
41
|
+
timestamp: string;
|
|
42
|
+
/** Producer tag (e.g. 'interceptor', 'agent', 'dashboard'). Optional. */
|
|
43
|
+
source?: string;
|
|
44
|
+
/** Event payload — topic-specific shape. For custom events this is the whole story. */
|
|
45
|
+
data?: Record<string, any>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Broad, consumer-facing event type: the minimal envelope plus every system
|
|
49
|
+
* extension field as OPTIONAL. Adapters and generic consumers (the agent trigger
|
|
50
|
+
* registry, input_mapper, dashboards) type against this — they cannot assume any
|
|
51
|
+
* extension is present. Producers construct one of the precise `LT*Event` family
|
|
52
|
+
* types below (which narrow the relevant fields to required); each is assignable
|
|
53
|
+
* to this type.
|
|
54
|
+
*/
|
|
55
|
+
export interface LTEvent extends LTEventBase {
|
|
56
|
+
/** Workflow instance — present on workflow/task/escalation/activity events. */
|
|
57
|
+
workflowId?: string;
|
|
58
|
+
/** Workflow function name — present on the same families. */
|
|
59
|
+
workflowName?: string;
|
|
60
|
+
/** Task queue — present on the same families. */
|
|
61
|
+
taskQueue?: string;
|
|
62
|
+
/** Task ID — present when orchestrated. */
|
|
42
63
|
taskId?: string;
|
|
43
|
-
/**
|
|
64
|
+
/** Escalation ID — present on escalation events. */
|
|
44
65
|
escalationId?: string;
|
|
45
|
-
/**
|
|
66
|
+
/** Root process lineage — present on workflow/task/escalation events. */
|
|
46
67
|
originId?: string;
|
|
47
|
-
/**
|
|
68
|
+
/** Lifecycle status. Vocabulary is per-family (see the family interfaces). */
|
|
48
69
|
status?: string;
|
|
49
|
-
/**
|
|
70
|
+
/** Activity step name — present on activity events. */
|
|
50
71
|
activityName?: string;
|
|
51
|
-
/** Milestones
|
|
72
|
+
/** Milestones — present on milestone/task events. */
|
|
52
73
|
milestones?: LTMilestone[];
|
|
53
|
-
/** Optional result data */
|
|
54
|
-
data?: Record<string, any>;
|
|
55
|
-
/** ISO 8601 timestamp */
|
|
56
|
-
timestamp: string;
|
|
57
74
|
}
|
|
75
|
+
/** Workflow context shared by the workflow-bearing families. */
|
|
76
|
+
export interface LTWorkflowContext {
|
|
77
|
+
workflowId: string;
|
|
78
|
+
workflowName: string;
|
|
79
|
+
taskQueue: string;
|
|
80
|
+
originId?: string;
|
|
81
|
+
taskId?: string;
|
|
82
|
+
}
|
|
83
|
+
/** `system.workflow.{workflowId}.{started|completed|failed}`. status ∈ started|in_progress|running|completed|failed. */
|
|
84
|
+
export interface LTWorkflowEvent extends LTEventBase, LTWorkflowContext {
|
|
85
|
+
status: string;
|
|
86
|
+
milestones?: LTMilestone[];
|
|
87
|
+
}
|
|
88
|
+
/** `system.task.{taskId}.{created|started|completed|escalated|failed}`. status ∈ created|in_progress|completed|needs_intervention|failed. */
|
|
89
|
+
export interface LTTaskEvent extends LTEventBase, LTWorkflowContext {
|
|
90
|
+
taskId: string;
|
|
91
|
+
status: string;
|
|
92
|
+
milestones?: LTMilestone[];
|
|
93
|
+
}
|
|
94
|
+
/** `system.escalation.{escalationId}.{created|resolved|claimed|released}`. status ∈ pending|claimed|released|resolved|cancelled. */
|
|
95
|
+
export interface LTEscalationEvent extends LTEventBase, LTWorkflowContext {
|
|
96
|
+
escalationId: string;
|
|
97
|
+
status: string;
|
|
98
|
+
}
|
|
99
|
+
/** `system.activity.{workflowId}.{activityName}.{started|completed|failed}`. */
|
|
100
|
+
export interface LTActivityEvent extends LTEventBase, LTWorkflowContext {
|
|
101
|
+
activityName: string;
|
|
102
|
+
}
|
|
103
|
+
/** `system.milestone.{workflowId}`. */
|
|
104
|
+
export interface LTMilestoneEvent extends LTEventBase, LTWorkflowContext {
|
|
105
|
+
milestones: LTMilestone[];
|
|
106
|
+
activityName?: string;
|
|
107
|
+
}
|
|
108
|
+
/** `system.agent.{agentName}.{started|completed|failed|status_changed|triggers_changed}`. */
|
|
109
|
+
export interface LTAgentEvent extends LTEventBase {
|
|
110
|
+
/** Agent id (carried in workflowId for routing parity). */
|
|
111
|
+
workflowId?: string;
|
|
112
|
+
/** Agent name (carried in workflowName). */
|
|
113
|
+
workflowName?: string;
|
|
114
|
+
status?: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* `system.knowledge.{domain}.{stored|deleted}`, `system.file.{stored|deleted}`,
|
|
118
|
+
* and any custom `app.*` event — no workflow context, everything lives in `data`.
|
|
119
|
+
*/
|
|
120
|
+
export type LTDataEvent = LTEventBase;
|
|
121
|
+
/**
|
|
122
|
+
* Precise union of system event families. Produce these; consume via `LTEvent`.
|
|
123
|
+
*/
|
|
124
|
+
export type LTSystemEvent = LTWorkflowEvent | LTTaskEvent | LTEscalationEvent | LTActivityEvent | LTMilestoneEvent | LTAgentEvent | LTDataEvent;
|
|
58
125
|
/**
|
|
59
126
|
* Pluggable event adapter interface.
|
|
60
127
|
*
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-
|
|
2
|
-
//# sourceMappingURL=AdminDashboard-
|
|
1
|
+
import{j as o}from"./vendor-query-B2UbickB.js";import{c as n}from"./tasks-Nz9lVCT1.js";import{r as m}from"./index-eWNx4UQ8.js";import{f as c}from"./useEventHooks-Bimqt7hU.js";import{u}from"./mcp-Bpl6p11J.js";import{P as d}from"./PageHeaderWithStats-BuKc9MKt.js";import"./vendor-react-CXumBFUA.js";import"./vendor-icons-Dj2F0Jrb.js";function j(){var a;c();const{data:s}=n({limit:1}),{data:e}=m({status:"pending",limit:1}),{data:t}=u(),r=((a=t==null?void 0:t.servers)==null?void 0:a.filter(i=>i.status==="connected").length)??0,l=t?`${r}/${t.total}`:"—";return o.jsx("div",{children:o.jsx(d,{title:"Admin",stats:[{label:"Tasks",value:(s==null?void 0:s.total)??"—"},{label:"Pending Escalations",value:(e==null?void 0:e.total)??"—",dotClass:"bg-status-pending"},{label:"MCP Servers",value:l},{label:"System",value:"Healthy",dotClass:"bg-status-success"}]})})}export{j as AdminDashboard};
|
|
2
|
+
//# sourceMappingURL=AdminDashboard-DIQEViVY.js.map
|
package/dashboard/dist/assets/{AdminDashboard-CMzR4d-w.js.map → AdminDashboard-DIQEViVY.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminDashboard-
|
|
1
|
+
{"version":3,"file":"AdminDashboard-DIQEViVY.js","sources":["../../src/pages/admin/AdminDashboard.tsx"],"sourcesContent":["import { useTasks } from '../../api/tasks';\nimport { useEscalations } from '../../api/escalations';\nimport { useEscalationListEvents } from '../../hooks/useEventHooks';\nimport { useMcpServers } from '../../api/mcp';\nimport { PageHeaderWithStats } from '../../components/common/layout/PageHeaderWithStats';\n\nexport function AdminDashboard() {\n useEscalationListEvents();\n const { data: taskData } = useTasks({ limit: 1 });\n const { data: pendingEsc } = useEscalations({ status: 'pending', limit: 1 });\n const { data: mcpData } = useMcpServers();\n\n const connectedServers =\n mcpData?.servers?.filter((s) => s.status === 'connected').length ?? 0;\n const mcpLabel = mcpData ? `${connectedServers}/${mcpData.total}` : '—';\n\n return (\n <div>\n <PageHeaderWithStats\n title=\"Admin\"\n stats={[\n { label: 'Tasks', value: taskData?.total ?? '—' },\n { label: 'Pending Escalations', value: pendingEsc?.total ?? '—', dotClass: 'bg-status-pending' },\n { label: 'MCP Servers', value: mcpLabel },\n { label: 'System', value: 'Healthy', dotClass: 'bg-status-success' },\n ]}\n />\n </div>\n );\n}\n"],"names":["AdminDashboard","useEscalationListEvents","taskData","useTasks","pendingEsc","useEscalations","mcpData","useMcpServers","connectedServers","_a","s","mcpLabel","jsx","PageHeaderWithStats"],"mappings":"4UAMO,SAASA,GAAiB,OAC/BC,EAAA,EACA,KAAM,CAAE,KAAMC,CAAA,EAAaC,EAAS,CAAE,MAAO,EAAG,EAC1C,CAAE,KAAMC,CAAA,EAAeC,EAAe,CAAE,OAAQ,UAAW,MAAO,EAAG,EACrE,CAAE,KAAMC,CAAA,EAAYC,EAAA,EAEpBC,IACJC,EAAAH,GAAA,YAAAA,EAAS,UAAT,YAAAG,EAAkB,OAAQC,GAAMA,EAAE,SAAW,aAAa,SAAU,EAChEC,EAAWL,EAAU,GAAGE,CAAgB,IAAIF,EAAQ,KAAK,GAAK,IAEpE,aACG,MAAA,CACC,SAAAM,EAAAA,IAACC,EAAA,CACC,MAAM,QACN,MAAO,CACL,CAAE,MAAO,QAAS,OAAOX,GAAA,YAAAA,EAAU,QAAS,GAAA,EAC5C,CAAE,MAAO,sBAAuB,OAAOE,GAAA,YAAAA,EAAY,QAAS,IAAK,SAAU,mBAAA,EAC3E,CAAE,MAAO,cAAe,MAAOO,CAAA,EAC/B,CAAE,MAAO,SAAU,MAAO,UAAW,SAAU,mBAAA,CAAoB,CACrE,CAAA,EAEJ,CAEJ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,a as v}from"./vendor-query-B2UbickB.js";import{a as re,d as le,b as oe}from"./agents-D09G0HCv.js";import{E as ce,C as de,u as pe,a as xe,b as ue,c as me}from"./CronLabel-DeNm1I4r.js";import{c as he,u as fe}from"./index-B7lEd0cY.js";import{P as ve}from"./PageHeader-Bnt2iQQa.js";import{B as O,d as U,h as be,R as Y,m as L,q as Z,a7 as G,a as V,aL as ee,V as ye}from"./vendor-icons-Dj2F0Jrb.js";import{e as ge}from"./knowledge-Bl_KaoKJ.js";import{R as te}from"./RunAsSelector-BFxxMvL3.js";import{u as je}from"./workflows-BLKji1_1.js";import{u as we}from"./yaml-workflows-BUhMfdaw.js";import{u as se}from"./capabilities-DON4-NXs.js";import{u as Ne}from"./topics-BrwkmaFR.js";import{W as Q}from"./WorkflowPill-F1oKUzmc.js";import{e as _e,c as ke,f as Ce}from"./vendor-react-CXumBFUA.js";import"./BotPicker-lj42d48P.js";import"./bots-D0LhyZZM.js";const X={name:"",description:"",goals:"",rules:"",user_id:"",knowledge_domain:"",subscriptions:[],schedules:[]},Se={topic:"",filter:"",reaction_type:"durable",workflow_type:"",pipeline_id:"",mcp_prompt:"",server_id:"",tool_name:"",input_mapping:"{}",execute_as:"",enabled:!0},qe={cron:"0 * * * *",reaction_type:"durable",workflow_type:"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""};function Re(s,a){var o,x,u;const r=(x=(o=s.behaviors)==null?void 0:o.schedules)!=null&&x.length?s.behaviors.schedules.map(n=>({cron:n.cron||"",reaction_type:n.reaction_type||"durable",workflow_type:n.workflow_type||"",pipeline_id:n.pipeline_id||"",server_id:n.server_id||"",tool_name:n.tool_name||"",envelope:n.envelope?JSON.stringify(n.envelope,null,2):"{}",execute_as:n.execute_as||""})):(u=s.behaviors)!=null&&u.cron?[{cron:s.behaviors.cron,reaction_type:"durable",workflow_type:s.workflow_type??"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""}]:[];return{name:s.id,description:s.description??"",goals:s.goals??"",rules:s.rules??"",user_id:s.user_id??"",knowledge_domain:s.knowledge_domain??"",subscriptions:a.map(n=>({id:n.id,topic:n.topic,filter:n.filter?JSON.stringify(n.filter,null,2):"",reaction_type:n.reaction_type,workflow_type:n.workflow_type??"",pipeline_id:n.pipeline_id??"",mcp_prompt:n.mcp_prompt??"",server_id:n.server_id??"",tool_name:n.tool_name??"",input_mapping:JSON.stringify(n.input_mapping??{},null,2),execute_as:n.execute_as??"",enabled:n.enabled})),schedules:r}}function Ae(s){var r;const a={};return s.schedules.length>0&&(a.schedules=s.schedules.map(o=>({cron:o.cron,reaction_type:o.reaction_type||"durable",workflow_type:o.reaction_type==="pipeline"?void 0:o.workflow_type,pipeline_id:o.reaction_type==="pipeline"?o.pipeline_id:void 0,envelope:B(o.envelope)??{},execute_as:o.execute_as||void 0})),a.cron=s.schedules[0].cron),{id:s.name,description:s.description||void 0,goals:s.goals||void 0,rules:s.rules||void 0,user_id:s.user_id||void 0,knowledge_domain:s.knowledge_domain||void 0,behaviors:a,workflow_type:((r=s.schedules[0])==null?void 0:r.workflow_type)||void 0,pipeline_id:void 0}}function Oe(s){return s.subscriptions.map(a=>({id:a.id,topic:a.topic,filter:a.filter?B(a.filter):void 0,reaction_type:a.reaction_type,workflow_type:a.workflow_type||void 0,pipeline_id:a.pipeline_id||void 0,mcp_prompt:a.mcp_prompt||void 0,server_id:a.server_id||void 0,tool_name:a.tool_name||void 0,input_mapping:B(a.input_mapping)??{},execute_as:a.execute_as||void 0,enabled:a.enabled}))}function B(s){if(s.trim())try{return JSON.parse(s)}catch{return}}function Ee(s,a,r,o){let x;try{x=JSON.parse(s)}catch{x={}}const u=o.includes(a),n=r===""||r===void 0||r===null||Array.isArray(r)&&r.length===0||r==="[]";if(!u&&n){const{[a]:p,...c}=x;return JSON.stringify(c,null,2)}let h=r;if(typeof r=="string")try{const p=JSON.parse(r);Array.isArray(p)&&(h=p)}catch{}return JSON.stringify({...x,[a]:h},null,2)}const S="section-header mt-[3em] first:mt-0",$="label",_="hint",R="input",M="input-json w-full";function $e({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Give your automation a name and describe what it does. The name appears everywhere — in events, logs, and the dashboard."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:identity"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Identity",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Name *"}),e.jsx("input",{type:"text",value:s.name,onChange:r=>a("name",r.target.value),placeholder:"health-monitor",className:R}),e.jsx("p",{className:_,children:"Lowercase, kebab-case. This appears everywhere."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Description"}),e.jsx("input",{type:"text",value:s.description,onChange:r=>a("description",r.target.value),placeholder:"Watches for workflow failures and captures diagnostics",className:R}),e.jsx("p",{className:_,children:"One sentence that explains what this automation does."})]})]})}function Pe({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Goals define what drives the automation. Rules define what constrains it."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:motivation"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Motivation",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Goals"}),e.jsx("textarea",{value:s.goals,onChange:r=>a("goals",r.target.value),placeholder:"Detect failures early, capture diagnostics, alert before cascading",rows:4,className:`${R} resize-none`}),e.jsx("p",{className:_,children:"Primary motivation. What the automation is trying to achieve."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Rules"}),e.jsx("textarea",{value:s.rules,onChange:r=>a("rules",r.target.value),placeholder:"Never auto-restart failed workflows. Always escalate to humans.",rows:4,className:`${R} resize-none`}),e.jsx("p",{className:_,children:"Guardrails. What it must never do, even when goals suggest it should."})]})]})]})}function Ie({form:s,set:a}){const{data:r}=ge(),o=(r==null?void 0:r.domains)??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Assign a knowledge domain — the automation's memory. It stores context here over time."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:knowledge"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Knowledge",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Knowledge Domain"}),e.jsx("input",{type:"text",value:s.knowledge_domain,onChange:x=>a("knowledge_domain",x.target.value),placeholder:"e.g., system-health, content-review, vendor-data",className:R,list:"domain-suggestions"}),e.jsx("datalist",{id:"domain-suggestions",children:o.map(x=>e.jsx("option",{value:x.domain},x.domain))}),e.jsx("p",{className:_,children:"Choose an existing domain to share memory, or type a new name to create one."})]}),o.length>0&&e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Existing Domains"}),e.jsx("div",{className:"space-y-0.5 mt-2",children:o.map(x=>e.jsxs("button",{type:"button",onClick:()=>a("knowledge_domain",x.domain),className:`w-full flex items-center gap-3 px-3 py-2 rounded-md text-left transition-colors ${s.knowledge_domain===x.domain?"border-l-2 border-l-accent bg-accent/5":"hover:bg-surface-hover border-l-2 border-l-transparent"}`,children:[e.jsx(U,{className:"w-3.5 h-3.5 text-text-quaternary shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-sm text-text-primary flex-1",children:x.domain}),e.jsxs("span",{className:"text-[10px] text-text-quaternary",children:[x.count," entries"]}),e.jsx("span",{className:"text-[9px] text-text-quaternary",children:e.jsx(he,{date:x.latest})})]},x.domain))})]})]})}function We({serverId:s,toolName:a,onChange:r}){const{data:o}=se(),x=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[u,n]=v.useState(!1),[h,p]=v.useState(""),c=v.useRef(null),f=v.useRef(null);v.useEffect(()=>{if(!u)return;function t(i){f.current&&!f.current.contains(i.target)&&n(!1)}return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[u]);const l=a?`${a}`:"",d=u?h:l,y=v.useMemo(()=>{const t=(u?h:"").toLowerCase();return t?x.filter(i=>i.name.toLowerCase().includes(t)||i.serverName.toLowerCase().includes(t)||(i.description??"").toLowerCase().includes(t)):x},[x,h,u]),m=a?x.find(t=>t.serverId===s&&t.name===a):void 0;return e.jsxs("div",{ref:f,className:"relative",children:[e.jsx("input",{ref:c,type:"text",value:d,onFocus:()=>{n(!0),p(l)},onChange:t=>{const i=t.target.value;p(i),i||r("",""),u||n(!0)},placeholder:"Search capabilities...",className:"input font-mono text-sm w-full"}),!u&&(m==null?void 0:m.description)&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1 italic",children:m.description}),u&&y.length>0&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 max-h-64 overflow-y-auto rounded-md border border-surface-border bg-surface shadow-lg",children:y.map(t=>e.jsxs("button",{type:"button",onClick:()=>{r(t.serverId,t.name),p(t.name),n(!1)},className:`w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors flex items-center gap-3 ${s===t.serverId&&a===t.name?"bg-accent/5":""}`,children:[e.jsx("span",{className:"text-[11px] font-mono text-text-primary shrink-0",children:t.name}),e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[9px] font-medium shrink-0 bg-accent/10 text-accent",children:[e.jsx(be,{className:"w-2 h-2",strokeWidth:1.5}),t.serverName]}),t.description&&e.jsx("span",{className:"text-[10px] text-text-quaternary truncate",children:t.description})]},`${t.serverId}:${t.name}`))}),u&&y.length===0&&h&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 rounded-md border border-surface-border bg-surface shadow-lg px-3 py-4 text-center",children:e.jsxs("p",{className:"text-[11px] text-text-quaternary",children:['No capabilities match "',h,'"']})})]})}const Te={durable:"Workflow",pipeline:"Pipeline",capability:"Capability",mcp_query:"MCP Query"},Le=["durable","pipeline","capability","mcp_query"];function ae({reactionType:s,onReactionTypeChange:a,workflowType:r,onWorkflowTypeChange:o,pipelineId:x,onPipelineIdChange:u,serverId:n,toolName:h,onCapabilityChange:p,mcpPrompt:c,onMcpPromptChange:f,availableTypes:l=[...Le]}){const{data:d}=je(),y=(d??[]).filter(i=>i.invocable).map(i=>i.workflow_type),{data:m}=we({status:"active"}),t=((m==null?void 0:m.workflows)??[]).map(i=>({id:i.id,name:i.graph_topic||i.id}));return e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex gap-1",children:l.map(i=>{const b=s===i;return e.jsx("button",{type:"button",onClick:()=>a(i),className:`px-3 py-1.5 text-[11px] font-medium rounded-md transition-colors ${b?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:Te[i]},i)})}),s==="durable"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Workflow *"}),e.jsxs("select",{value:r,onChange:i=>o(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select workflow..."}),y.map(i=>e.jsx("option",{value:i,children:i},i))]})]}),s==="pipeline"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Pipeline *"}),e.jsxs("select",{value:x,onChange:i=>u(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select pipeline..."}),t.map(i=>e.jsx("option",{value:i.id,children:i.name},i.id))]})]}),s==="capability"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Capability *"}),e.jsx(We,{serverId:n,toolName:h,onChange:p})]}),s==="mcp_query"&&f&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Prompt *"}),e.jsx("textarea",{value:c??"",onChange:i=>f(i.target.value),placeholder:"Analyze the error and suggest remediation...",rows:3,className:"input resize-none"})]})]})}const Me={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",file:"bg-orange-400/15 text-orange-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"};function Je({form:s,set:a}){const{data:r}=Ne({limit:200}),{data:o}=se(),x=(r==null?void 0:r.topics)??[],u=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[n,h]=v.useState(0),p=(t,i,b)=>{const g=[...s.subscriptions];g[t]={...g[t],[i]:b},a("subscriptions",g)},c=()=>{a("subscriptions",[...s.subscriptions,{...Se}]),h(s.subscriptions.length)},f=t=>{a("subscriptions",s.subscriptions.filter((i,b)=>b!==t)),n>=s.subscriptions.length-1&&h(Math.max(0,s.subscriptions.length-2))},l=s.subscriptions,d=l[n],y=t=>t.topic?t.reaction_type==="durable"?!!t.workflow_type:t.reaction_type==="pipeline"?!!t.pipeline_id:t.reaction_type==="mcp_query"?!!t.mcp_prompt:t.reaction_type==="capability"?!!t.server_id&&!!t.tool_name:!1:!1,m=d?x.find(t=>t.topic===d.topic):void 0;return l.length===0?e.jsxs("div",{className:"max-w-xl",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-8",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Y,{className:"w-8 h-8 text-text-quaternary/40 mb-3",strokeWidth:1}),e.jsx("p",{className:"text-sm text-text-tertiary mb-2",children:"No event subscriptions yet"}),e.jsx("p",{className:"text-[11px] text-text-quaternary max-w-sm mb-6",children:"Each subscription listens for a topic pattern and runs a workflow when it matches."}),e.jsxs("button",{onClick:c,className:"flex items-center gap-2 text-xs text-accent hover:text-accent-hover transition-colors",children:[e.jsx(L,{className:"w-3.5 h-3.5"})," Add first subscription"]})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-6",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex gap-8",children:[e.jsxs("div",{className:"w-52 shrink-0 space-y-0.5",children:[l.map((t,i)=>e.jsxs("div",{className:`group/sub flex items-center rounded-md transition-colors ${n===i?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsxs("button",{onClick:()=>h(i),className:"flex-1 text-left px-3 py-2 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${y(t)?"bg-emerald-400":"bg-zinc-500"}`}),e.jsx("span",{className:"text-[11px] font-mono truncate",children:t.topic||"new subscription"})]}),e.jsxs("span",{className:"text-[9px] text-text-quaternary ml-3",children:["→ ",t.workflow_type||t.tool_name||t.reaction_type]})]}),e.jsx("button",{onClick:b=>{b.stopPropagation(),confirm(`Remove subscription "${t.topic||"new"}"?
|
|
1
|
+
import{j as e,a as v}from"./vendor-query-B2UbickB.js";import{a as re,d as le,b as oe}from"./agents-BvTiBKBQ.js";import{E as ce,C as de,u as pe,a as xe,b as ue,c as me}from"./CronLabel-GcS5qzZr.js";import{c as he,u as fe}from"./index-eWNx4UQ8.js";import{P as ve}from"./PageHeader-Bnt2iQQa.js";import{B as O,d as U,h as be,R as Y,m as L,q as Z,a7 as G,a as V,aL as ee,V as ye}from"./vendor-icons-Dj2F0Jrb.js";import{e as ge}from"./knowledge-Bje8_ndK.js";import{R as te}from"./RunAsSelector-CM7lk1YB.js";import{u as je}from"./workflows-BOwGINtF.js";import{u as we}from"./yaml-workflows-I1tcjCFK.js";import{u as se}from"./capabilities-D7uJlnxj.js";import{u as Ne}from"./topics-CiG2N8Z_.js";import{W as Q}from"./WorkflowPill-F1oKUzmc.js";import{e as _e,c as ke,f as Ce}from"./vendor-react-CXumBFUA.js";import"./BotPicker-DBvd1yFL.js";import"./bots-CeMR1Lnp.js";const X={name:"",description:"",goals:"",rules:"",user_id:"",knowledge_domain:"",subscriptions:[],schedules:[]},Se={topic:"",filter:"",reaction_type:"durable",workflow_type:"",pipeline_id:"",mcp_prompt:"",server_id:"",tool_name:"",input_mapping:"{}",execute_as:"",enabled:!0},qe={cron:"0 * * * *",reaction_type:"durable",workflow_type:"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""};function Re(s,a){var o,x,u;const r=(x=(o=s.behaviors)==null?void 0:o.schedules)!=null&&x.length?s.behaviors.schedules.map(n=>({cron:n.cron||"",reaction_type:n.reaction_type||"durable",workflow_type:n.workflow_type||"",pipeline_id:n.pipeline_id||"",server_id:n.server_id||"",tool_name:n.tool_name||"",envelope:n.envelope?JSON.stringify(n.envelope,null,2):"{}",execute_as:n.execute_as||""})):(u=s.behaviors)!=null&&u.cron?[{cron:s.behaviors.cron,reaction_type:"durable",workflow_type:s.workflow_type??"",pipeline_id:"",server_id:"",tool_name:"",envelope:"{}",execute_as:""}]:[];return{name:s.id,description:s.description??"",goals:s.goals??"",rules:s.rules??"",user_id:s.user_id??"",knowledge_domain:s.knowledge_domain??"",subscriptions:a.map(n=>({id:n.id,topic:n.topic,filter:n.filter?JSON.stringify(n.filter,null,2):"",reaction_type:n.reaction_type,workflow_type:n.workflow_type??"",pipeline_id:n.pipeline_id??"",mcp_prompt:n.mcp_prompt??"",server_id:n.server_id??"",tool_name:n.tool_name??"",input_mapping:JSON.stringify(n.input_mapping??{},null,2),execute_as:n.execute_as??"",enabled:n.enabled})),schedules:r}}function Ae(s){var r;const a={};return s.schedules.length>0&&(a.schedules=s.schedules.map(o=>({cron:o.cron,reaction_type:o.reaction_type||"durable",workflow_type:o.reaction_type==="pipeline"?void 0:o.workflow_type,pipeline_id:o.reaction_type==="pipeline"?o.pipeline_id:void 0,envelope:B(o.envelope)??{},execute_as:o.execute_as||void 0})),a.cron=s.schedules[0].cron),{id:s.name,description:s.description||void 0,goals:s.goals||void 0,rules:s.rules||void 0,user_id:s.user_id||void 0,knowledge_domain:s.knowledge_domain||void 0,behaviors:a,workflow_type:((r=s.schedules[0])==null?void 0:r.workflow_type)||void 0,pipeline_id:void 0}}function Oe(s){return s.subscriptions.map(a=>({id:a.id,topic:a.topic,filter:a.filter?B(a.filter):void 0,reaction_type:a.reaction_type,workflow_type:a.workflow_type||void 0,pipeline_id:a.pipeline_id||void 0,mcp_prompt:a.mcp_prompt||void 0,server_id:a.server_id||void 0,tool_name:a.tool_name||void 0,input_mapping:B(a.input_mapping)??{},execute_as:a.execute_as||void 0,enabled:a.enabled}))}function B(s){if(s.trim())try{return JSON.parse(s)}catch{return}}function Ee(s,a,r,o){let x;try{x=JSON.parse(s)}catch{x={}}const u=o.includes(a),n=r===""||r===void 0||r===null||Array.isArray(r)&&r.length===0||r==="[]";if(!u&&n){const{[a]:p,...c}=x;return JSON.stringify(c,null,2)}let h=r;if(typeof r=="string")try{const p=JSON.parse(r);Array.isArray(p)&&(h=p)}catch{}return JSON.stringify({...x,[a]:h},null,2)}const S="section-header mt-[3em] first:mt-0",$="label",_="hint",R="input",M="input-json w-full";function $e({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Give your automation a name and describe what it does. The name appears everywhere — in events, logs, and the dashboard."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:identity"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Identity",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Name *"}),e.jsx("input",{type:"text",value:s.name,onChange:r=>a("name",r.target.value),placeholder:"health-monitor",className:R}),e.jsx("p",{className:_,children:"Lowercase, kebab-case. This appears everywhere."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Description"}),e.jsx("input",{type:"text",value:s.description,onChange:r=>a("description",r.target.value),placeholder:"Watches for workflow failures and captures diagnostics",className:R}),e.jsx("p",{className:_,children:"One sentence that explains what this automation does."})]})]})}function Pe({form:s,set:a}){return e.jsxs("div",{className:"space-y-8",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Goals define what drives the automation. Rules define what constrains it."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:motivation"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Motivation",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-8",children:[e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Goals"}),e.jsx("textarea",{value:s.goals,onChange:r=>a("goals",r.target.value),placeholder:"Detect failures early, capture diagnostics, alert before cascading",rows:4,className:`${R} resize-none`}),e.jsx("p",{className:_,children:"Primary motivation. What the automation is trying to achieve."})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Rules"}),e.jsx("textarea",{value:s.rules,onChange:r=>a("rules",r.target.value),placeholder:"Never auto-restart failed workflows. Always escalate to humans.",rows:4,className:`${R} resize-none`}),e.jsx("p",{className:_,children:"Guardrails. What it must never do, even when goals suggest it should."})]})]})]})}function Ie({form:s,set:a}){const{data:r}=ge(),o=(r==null?void 0:r.domains)??[];return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Assign a knowledge domain — the automation's memory. It stores context here over time."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:knowledge"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Knowledge",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Knowledge Domain"}),e.jsx("input",{type:"text",value:s.knowledge_domain,onChange:x=>a("knowledge_domain",x.target.value),placeholder:"e.g., system-health, content-review, vendor-data",className:R,list:"domain-suggestions"}),e.jsx("datalist",{id:"domain-suggestions",children:o.map(x=>e.jsx("option",{value:x.domain},x.domain))}),e.jsx("p",{className:_,children:"Choose an existing domain to share memory, or type a new name to create one."})]}),o.length>0&&e.jsxs("div",{children:[e.jsx("label",{className:$,children:"Existing Domains"}),e.jsx("div",{className:"space-y-0.5 mt-2",children:o.map(x=>e.jsxs("button",{type:"button",onClick:()=>a("knowledge_domain",x.domain),className:`w-full flex items-center gap-3 px-3 py-2 rounded-md text-left transition-colors ${s.knowledge_domain===x.domain?"border-l-2 border-l-accent bg-accent/5":"hover:bg-surface-hover border-l-2 border-l-transparent"}`,children:[e.jsx(U,{className:"w-3.5 h-3.5 text-text-quaternary shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-sm text-text-primary flex-1",children:x.domain}),e.jsxs("span",{className:"text-[10px] text-text-quaternary",children:[x.count," entries"]}),e.jsx("span",{className:"text-[9px] text-text-quaternary",children:e.jsx(he,{date:x.latest})})]},x.domain))})]})]})}function We({serverId:s,toolName:a,onChange:r}){const{data:o}=se(),x=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[u,n]=v.useState(!1),[h,p]=v.useState(""),c=v.useRef(null),f=v.useRef(null);v.useEffect(()=>{if(!u)return;function t(i){f.current&&!f.current.contains(i.target)&&n(!1)}return document.addEventListener("mousedown",t),()=>document.removeEventListener("mousedown",t)},[u]);const l=a?`${a}`:"",d=u?h:l,y=v.useMemo(()=>{const t=(u?h:"").toLowerCase();return t?x.filter(i=>i.name.toLowerCase().includes(t)||i.serverName.toLowerCase().includes(t)||(i.description??"").toLowerCase().includes(t)):x},[x,h,u]),m=a?x.find(t=>t.serverId===s&&t.name===a):void 0;return e.jsxs("div",{ref:f,className:"relative",children:[e.jsx("input",{ref:c,type:"text",value:d,onFocus:()=>{n(!0),p(l)},onChange:t=>{const i=t.target.value;p(i),i||r("",""),u||n(!0)},placeholder:"Search capabilities...",className:"input font-mono text-sm w-full"}),!u&&(m==null?void 0:m.description)&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-1 italic",children:m.description}),u&&y.length>0&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 max-h-64 overflow-y-auto rounded-md border border-surface-border bg-surface shadow-lg",children:y.map(t=>e.jsxs("button",{type:"button",onClick:()=>{r(t.serverId,t.name),p(t.name),n(!1)},className:`w-full text-left px-3 py-2 hover:bg-surface-hover transition-colors flex items-center gap-3 ${s===t.serverId&&a===t.name?"bg-accent/5":""}`,children:[e.jsx("span",{className:"text-[11px] font-mono text-text-primary shrink-0",children:t.name}),e.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[9px] font-medium shrink-0 bg-accent/10 text-accent",children:[e.jsx(be,{className:"w-2 h-2",strokeWidth:1.5}),t.serverName]}),t.description&&e.jsx("span",{className:"text-[10px] text-text-quaternary truncate",children:t.description})]},`${t.serverId}:${t.name}`))}),u&&y.length===0&&h&&e.jsx("div",{className:"absolute z-50 left-0 right-0 mt-1 rounded-md border border-surface-border bg-surface shadow-lg px-3 py-4 text-center",children:e.jsxs("p",{className:"text-[11px] text-text-quaternary",children:['No capabilities match "',h,'"']})})]})}const Te={durable:"Workflow",pipeline:"Pipeline",capability:"Capability",mcp_query:"MCP Query"},Le=["durable","pipeline","capability","mcp_query"];function ae({reactionType:s,onReactionTypeChange:a,workflowType:r,onWorkflowTypeChange:o,pipelineId:x,onPipelineIdChange:u,serverId:n,toolName:h,onCapabilityChange:p,mcpPrompt:c,onMcpPromptChange:f,availableTypes:l=[...Le]}){const{data:d}=je(),y=(d??[]).filter(i=>i.invocable).map(i=>i.workflow_type),{data:m}=we({status:"active"}),t=((m==null?void 0:m.workflows)??[]).map(i=>({id:i.id,name:i.graph_topic||i.id}));return e.jsxs("div",{className:"space-y-4",children:[e.jsx("div",{className:"flex gap-1",children:l.map(i=>{const b=s===i;return e.jsx("button",{type:"button",onClick:()=>a(i),className:`px-3 py-1.5 text-[11px] font-medium rounded-md transition-colors ${b?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:Te[i]},i)})}),s==="durable"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Workflow *"}),e.jsxs("select",{value:r,onChange:i=>o(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select workflow..."}),y.map(i=>e.jsx("option",{value:i,children:i},i))]})]}),s==="pipeline"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Pipeline *"}),e.jsxs("select",{value:x,onChange:i=>u(i.target.value),className:"input",children:[e.jsx("option",{value:"",children:"Select pipeline..."}),t.map(i=>e.jsx("option",{value:i.id,children:i.name},i.id))]})]}),s==="capability"&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Capability *"}),e.jsx(We,{serverId:n,toolName:h,onChange:p})]}),s==="mcp_query"&&f&&e.jsxs("div",{children:[e.jsx("label",{className:"label",children:"Prompt *"}),e.jsx("textarea",{value:c??"",onChange:i=>f(i.target.value),placeholder:"Analyze the error and suggest remediation...",rows:3,className:"input resize-none"})]})]})}const Me={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",file:"bg-orange-400/15 text-orange-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"};function Je({form:s,set:a}){const{data:r}=Ne({limit:200}),{data:o}=se(),x=(r==null?void 0:r.topics)??[],u=v.useMemo(()=>{var t;return((t=o==null?void 0:o.categories)==null?void 0:t.flatMap(i=>i.tools))??[]},[o]),[n,h]=v.useState(0),p=(t,i,b)=>{const g=[...s.subscriptions];g[t]={...g[t],[i]:b},a("subscriptions",g)},c=()=>{a("subscriptions",[...s.subscriptions,{...Se}]),h(s.subscriptions.length)},f=t=>{a("subscriptions",s.subscriptions.filter((i,b)=>b!==t)),n>=s.subscriptions.length-1&&h(Math.max(0,s.subscriptions.length-2))},l=s.subscriptions,d=l[n],y=t=>t.topic?t.reaction_type==="durable"?!!t.workflow_type:t.reaction_type==="pipeline"?!!t.pipeline_id:t.reaction_type==="mcp_query"?!!t.mcp_prompt:t.reaction_type==="capability"?!!t.server_id&&!!t.tool_name:!1:!1,m=d?x.find(t=>t.topic===d.topic):void 0;return l.length===0?e.jsxs("div",{className:"max-w-xl",children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-8",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex flex-col items-center justify-center py-12 text-center",children:[e.jsx(Y,{className:"w-8 h-8 text-text-quaternary/40 mb-3",strokeWidth:1}),e.jsx("p",{className:"text-sm text-text-tertiary mb-2",children:"No event subscriptions yet"}),e.jsx("p",{className:"text-[11px] text-text-quaternary max-w-sm mb-6",children:"Each subscription listens for a topic pattern and runs a workflow when it matches."}),e.jsxs("button",{onClick:c,className:"flex items-center gap-2 text-xs text-accent hover:text-accent-hover transition-colors",children:[e.jsx(L,{className:"w-3.5 h-3.5"})," Add first subscription"]})]})]}):e.jsxs("div",{children:[e.jsxs("div",{className:"border-l-2 border-accent/30 pl-3 py-1 flex items-start justify-between mb-6",children:[e.jsx("p",{className:"text-[12px] text-text-secondary italic leading-relaxed",children:"Optional. When a matching event is published, the automation runs the configured workflow with the event payload."}),e.jsx("button",{onClick:()=>{window.location.hash="#docs:agents.md:subscriptions"},className:"text-text-quaternary hover:text-accent transition-colors shrink-0 ml-3",title:"Docs: Subscriptions",children:e.jsx(O,{className:"w-3 h-3",strokeWidth:1.5})})]}),e.jsxs("div",{className:"flex gap-8",children:[e.jsxs("div",{className:"w-52 shrink-0 space-y-0.5",children:[l.map((t,i)=>e.jsxs("div",{className:`group/sub flex items-center rounded-md transition-colors ${n===i?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsxs("button",{onClick:()=>h(i),className:"flex-1 text-left px-3 py-2 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:`w-1.5 h-1.5 rounded-full shrink-0 ${y(t)?"bg-emerald-400":"bg-zinc-500"}`}),e.jsx("span",{className:"text-[11px] font-mono truncate",children:t.topic||"new subscription"})]}),e.jsxs("span",{className:"text-[9px] text-text-quaternary ml-3",children:["→ ",t.workflow_type||t.tool_name||t.reaction_type]})]}),e.jsx("button",{onClick:b=>{b.stopPropagation(),confirm(`Remove subscription "${t.topic||"new"}"?
|
|
2
2
|
|
|
3
3
|
This takes effect when you save.`)&&f(i)},className:"opacity-0 group-hover/sub:opacity-100 px-2 text-text-quaternary hover:text-red-400 transition-all",title:"Remove",children:e.jsx(Z,{className:"w-3 h-3"})})]},i)),e.jsxs("button",{onClick:c,className:"w-full flex items-center gap-1.5 px-3 py-2 text-[11px] text-accent hover:text-accent-hover transition-colors",children:[e.jsx(L,{className:"w-3 h-3"})," Add"]})]}),d&&e.jsxs("div",{className:"flex-1 min-w-0 space-y-12",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"When this event fires"}),e.jsx(ze,{value:d.topic,onChange:t=>p(n,"topic",t),topics:x}),(m==null?void 0:m.payload_schema)&&e.jsxs("div",{className:"mt-3 p-3 rounded-md bg-surface-sunken border border-surface-border",children:[e.jsx("p",{className:"text-[10px] text-text-quaternary mb-1 uppercase tracking-wider font-medium",children:"Payload Schema"}),e.jsx("pre",{className:"text-[11px] font-mono text-text-secondary whitespace-pre-wrap overflow-x-auto max-h-40",children:JSON.stringify(m.payload_schema.properties??m.payload_schema,null,2)}),m.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary mt-2 italic",children:m.description})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run this reaction"}),e.jsx(ae,{reactionType:d.reaction_type,onReactionTypeChange:t=>p(n,"reaction_type",t),workflowType:d.workflow_type,onWorkflowTypeChange:t=>p(n,"workflow_type",t),pipelineId:d.pipeline_id,onPipelineIdChange:t=>p(n,"pipeline_id",t),serverId:d.server_id,toolName:d.tool_name,onCapabilityChange:(t,i)=>{var A;const b=[...s.subscriptions],g={...b[n],server_id:t,tool_name:i},k=u.find(w=>w.serverId===t&&w.name===i),E=(A=k==null?void 0:k.inputSchema)==null?void 0:A.properties;if(E&&i){const w={};for(const P of Object.keys(E))P.startsWith("_")||(w[P]=`{event.data.${P}}`);g.input_mapping=JSON.stringify(w,null,2)}b[n]=g,a("subscriptions",b)},mcpPrompt:d.mcp_prompt,onMcpPromptChange:t=>p(n,"mcp_prompt",t)})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-6",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"As identity"}),e.jsx(te,{selected:d.execute_as,onChange:t=>p(n,"execute_as",t)}),e.jsx("p",{className:_,children:"Identity used when invoking the workflow."})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"But only if"}),e.jsx("input",{type:"text",value:d.filter,onChange:t=>p(n,"filter",t.target.value),placeholder:'{"extension": "png"}',className:`${R} font-mono text-xs`}),e.jsx("p",{className:_,children:"JSON filter against event.data. Click an operator to insert:"}),e.jsx("div",{className:"flex flex-wrap gap-1.5 mt-1.5",children:[{label:"equals",value:'{"key": "val"}'},{label:"not equal",value:'{"key": {"$ne": "val"}}'},{label:"in list",value:'{"key": {"$in": ["a", "b"]}}'},{label:"exists",value:'{"key": {"$exists": true}}'}].map(t=>e.jsx("button",{type:"button",onClick:()=>p(n,"filter",t.value),className:"px-2 py-0.5 text-[10px] font-mono rounded bg-accent/8 text-accent hover:bg-accent/15 transition-colors",children:t.label},t.label))})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"With this data"}),d.reaction_type==="capability"&&d.tool_name?e.jsx(Fe,{tool:u.find(t=>t.serverId===d.server_id&&t.name===d.tool_name),value:d.input_mapping,onChange:t=>p(n,"input_mapping",t),eventSchema:m==null?void 0:m.payload_schema}):e.jsxs(e.Fragment,{children:[e.jsx("textarea",{value:d.input_mapping,onChange:t=>p(n,"input_mapping",t.target.value),rows:10,className:M,placeholder:`{
|
|
4
4
|
"data": {
|
|
@@ -13,4 +13,4 @@ This takes effect when you save.`)&&f(i)},className:"opacity-0 group-hover/sub:o
|
|
|
13
13
|
This takes effect when you save.`)&&n(f)},className:"opacity-0 group-hover/sched:opacity-100 px-2 text-text-quaternary hover:text-red-400 transition-all",title:"Remove",children:e.jsx(Z,{className:"w-3 h-3"})})]},f)),e.jsxs("button",{onClick:u,className:"w-full flex items-center gap-1.5 px-3 py-2 text-[11px] text-accent hover:text-accent-hover transition-colors",children:[e.jsx(L,{className:"w-3 h-3"})," Add"]})]}),p&&e.jsxs("div",{className:"flex-1 min-w-0 space-y-12",children:[e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run every"}),e.jsx("input",{type:"text",value:p.cron,onChange:c=>x(r,"cron",c.target.value),placeholder:"0 * * * *",className:`${R} font-mono`}),p.cron&&e.jsx("p",{className:"text-[11px] text-accent/80 mt-1",children:z(p.cron)}),e.jsx("div",{className:"flex gap-3 mt-2 overflow-x-auto",children:Be.map(c=>e.jsx("button",{type:"button",onClick:()=>x(r,"cron",c),className:`text-[10px] font-mono whitespace-nowrap transition-colors ${p.cron===c?"text-accent font-medium":"text-accent/50 hover:text-accent"}`,children:z(c)},c))})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"Run this reaction"}),e.jsx(ae,{reactionType:p.reaction_type,onReactionTypeChange:c=>x(r,"reaction_type",c),workflowType:p.workflow_type,onWorkflowTypeChange:c=>x(r,"workflow_type",c),pipelineId:p.pipeline_id,onPipelineIdChange:c=>x(r,"pipeline_id",c),serverId:p.server_id,toolName:p.tool_name,onCapabilityChange:(c,f)=>{x(r,"server_id",c),x(r,"tool_name",f)},availableTypes:["durable","pipeline","capability"]})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"As identity"}),e.jsx(te,{selected:p.execute_as,onChange:c=>x(r,"execute_as",c)}),e.jsx("p",{className:_,children:"Identity used when invoking."})]}),e.jsxs("div",{children:[e.jsx("label",{className:S,children:"With this data"}),e.jsx("textarea",{value:p.envelope,onChange:c=>x(r,"envelope",c.target.value),rows:10,className:M,placeholder:`{
|
|
14
14
|
"data": { "source": "cron" }
|
|
15
15
|
}`}),e.jsx("p",{className:_,children:"Static payload passed to the workflow on each invocation."})]})]})]})]})}function W({icon:s,color:a,title:r,children:o}){return e.jsxs("div",{className:"mb-10",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-2 pb-1.5 border-b border-surface-border/40",children:[e.jsx(s,{className:`w-3.5 h-3.5 ${a}`,strokeWidth:1.5}),e.jsx("h3",{className:"text-xs font-semibold uppercase tracking-widest text-accent/80",children:r})]}),e.jsx("div",{className:"pl-5.5",children:o})]})}function T({label:s,children:a}){return e.jsxs("div",{className:"flex gap-3 py-0.5",children:[e.jsx("span",{className:"text-[10px] text-text-quaternary w-20 shrink-0",children:s}),e.jsx("span",{className:"text-xs text-text-primary",children:a})]})}function Ye({form:s}){return e.jsxs("div",{children:[e.jsxs(W,{icon:V,color:"text-accent",title:"Identity",children:[e.jsx(T,{label:"Name",children:s.name||"—"}),s.description&&e.jsx(T,{label:"Description",children:s.description})]}),(s.goals||s.rules)&&e.jsxs(W,{icon:ee,color:"text-rose-400",title:"Motivation",children:[s.goals&&e.jsx(T,{label:"Goals",children:s.goals}),s.rules&&e.jsx(T,{label:"Rules",children:s.rules})]}),e.jsx(W,{icon:U,color:"text-emerald-400",title:"Knowledge",children:e.jsx(T,{label:"Domain",children:s.knowledge_domain||"None"})}),e.jsxs("div",{className:"grid grid-cols-2 gap-x-10",children:[e.jsx(W,{icon:Y,color:"text-cyan-400",title:`Subscriptions (${s.subscriptions.length})`,children:s.subscriptions.length===0?e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"None configured"}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.subscriptions.map((a,r)=>e.jsxs("div",{className:"flex items-center py-1.5",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(ce,{topic:a.topic||"unset"})}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"text-text-quaternary text-[10px]",children:"→"}),a.workflow_type?e.jsx(Q,{type:a.workflow_type}):e.jsx("span",{className:"text-[11px] text-text-quaternary",children:a.reaction_type})]})]},r))})}),e.jsx(W,{icon:G,color:"text-amber-400",title:`Schedules (${s.schedules.length})`,children:s.schedules.length===0?e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"None configured"}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.schedules.map((a,r)=>e.jsxs("div",{className:"flex items-center py-1.5",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(de,{cron:a.cron})}),e.jsxs("div",{className:"flex items-center gap-1.5 shrink-0",children:[e.jsx("span",{className:"text-text-quaternary text-[10px]",children:"→"}),a.workflow_type?e.jsx(Q,{type:a.workflow_type}):e.jsx("span",{className:"text-[11px] text-text-quaternary",children:"no workflow"})]})]},r))})})]}),e.jsx("div",{className:"border-l-2 border-emerald-400/30 pl-3 py-2 mt-6",children:e.jsx("p",{className:"text-[11px] text-text-tertiary leading-relaxed",children:"After saving, subscriptions and schedules activate immediately. You can pause the automation anytime."})})]})}const Ge=[{id:1,label:"Identity",icon:V},{id:2,label:"Motivation",icon:ee},{id:3,label:"Knowledge",icon:U},{id:4,label:"Subscriptions",icon:Y},{id:5,label:"Schedules",icon:G},{id:6,label:"Review",icon:ye}];function dt(){var H;const{id:s}=_e(),a=!s,r=ke(),{data:o}=fe(),u=!!((H=o==null?void 0:o.ai)!=null&&H.enabled)?"Agent":"Automation",{data:n,isLoading:h}=re(a?null:s),{data:p}=pe(a?null:s),c=le(),f=oe(),l=xe(),d=ue(),y=me(),[m,t]=v.useState(X),[i,b]=v.useState(!1),[g,k]=v.useState(""),[E,A]=Ce(),w=parseInt(E.get("step")||"1",10),P=v.useCallback(j=>{A(N=>{const q=new URLSearchParams(N);return q.set("step",String(j)),q},{replace:!0})},[A]);v.useEffect(()=>{if(!i){if(a){t(X),b(!0);return}n&&p&&(t(Re(n,p.subscriptions??[])),b(!0))}},[n,p,a,i]);const I=(j,N)=>t(q=>({...q,[j]:N})),ne=async()=>{k("");try{const j=Ae(m);let N=s;a?N=(await c.mutateAsync(j)).id:await f.mutateAsync({id:s,...j});const q=Oe(m),ie=(p==null?void 0:p.subscriptions)??[],J=new Set(ie.map(C=>C.id));for(const C of q)if(C.id&&J.has(C.id)){const{id:F,...D}=C;await d.mutateAsync({agentId:N,subId:F,...D}),J.delete(F)}else{const{id:F,...D}=C;await l.mutateAsync({agentId:N,...D})}for(const C of J)await y.mutateAsync({agentId:N,subId:C});r(`/agents/${N}`)}catch(j){k(j.message)}};if(!a&&h)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-60 bg-surface-sunken rounded"})]});const K=c.isPending||f.isPending;return e.jsxs("div",{children:[e.jsx(ve,{title:a?`New ${u}`:`${u}: ${(n==null?void 0:n.id)??""}`,docsHash:"#docs:agents.md"}),e.jsxs("div",{className:"flex gap-10",children:[e.jsxs("nav",{className:"w-44 shrink-0 sticky top-0 self-start pt-2",children:[e.jsx("div",{className:"space-y-0.5",children:Ge.map(j=>{const N=j.icon,q=w===j.id;return e.jsxs("button",{onClick:()=>P(j.id),className:`w-full flex items-center gap-2.5 px-3 py-2 rounded-md text-left transition-colors ${q?"bg-accent/10 text-accent":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:[e.jsx(N,{className:"w-3.5 h-3.5 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"text-xs font-medium",children:j.label})]},j.id)})}),e.jsxs("div",{className:"mt-8 pt-4 border-t border-surface-border space-y-2",children:[e.jsx("button",{onClick:ne,disabled:!m.name.trim()||K,className:"w-full btn-primary text-xs disabled:opacity-50",children:K?"Saving...":a?`Create ${u}`:"Save"}),e.jsx("button",{onClick:()=>r(a?"/agents":`/agents/${s}`),className:"w-full btn-ghost text-xs",children:"Cancel"})]}),g&&e.jsx("p",{className:"text-xs text-status-error mt-3",children:g})]}),e.jsxs("div",{className:"flex-1 min-w-0 pt-2",children:[w===1&&e.jsx($e,{form:m,set:I}),w===2&&e.jsx(Pe,{form:m,set:I}),w===3&&e.jsx(Ie,{form:m,set:I}),w===4&&e.jsx(Je,{form:m,set:I}),w===5&&e.jsx(Ue,{form:m,set:I}),w===6&&e.jsx(Ye,{form:m})]})]})]})}export{dt as AgentConfigPage};
|
|
16
|
-
//# sourceMappingURL=AgentConfigPage-
|
|
16
|
+
//# sourceMappingURL=AgentConfigPage-Caf5-th-.js.map
|