@themoltnet/node-red-contrib-core 0.1.0
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/LICENSE +235 -0
- package/README.md +267 -0
- package/dist/nodes/agent.html +82 -0
- package/dist/nodes/agent.js +28 -0
- package/dist/nodes/runtime-profile.html +156 -0
- package/dist/nodes/runtime-profile.js +40 -0
- package/dist/nodes/task-builder.html +175 -0
- package/dist/nodes/task-builder.js +110 -0
- package/dist/nodes/task-get.html +55 -0
- package/dist/nodes/task-get.js +60 -0
- package/dist/nodes/task-reader.html +64 -0
- package/dist/nodes/task-reader.js +57 -0
- package/dist/nodes/task-snapshot.js +32 -0
- package/dist/nodes/task-wait.html +166 -0
- package/dist/nodes/task-wait.js +133 -0
- package/dist/nodes/tasks-create.html +122 -0
- package/dist/nodes/tasks-create.js +64 -0
- package/dist/nodes/workflow-status.html +55 -0
- package/dist/nodes/workflow-status.js +62 -0
- package/examples/cockpit.flow.json +58 -0
- package/examples/issue-lifecycle.flow.json +196 -0
- package/examples/weather-advisor.flow.json +398 -0
- package/package.json +65 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
//#region src/nodes/workflow-status.ts
|
|
2
|
+
var init = (RED) => {
|
|
3
|
+
function WorkflowStatusNode(def) {
|
|
4
|
+
RED.nodes.createNode(this, def);
|
|
5
|
+
const agentNode = def.agent ? RED.nodes.getNode(def.agent) : null;
|
|
6
|
+
this.on("input", (msg, send, done) => {
|
|
7
|
+
const run = async () => {
|
|
8
|
+
try {
|
|
9
|
+
if (!agentNode || typeof agentNode.getAgent !== "function") throw new Error("workflow-status: no moltnet-agent configured");
|
|
10
|
+
const payload = msg.payload && typeof msg.payload === "object" ? msg.payload : {};
|
|
11
|
+
const correlationId = (typeof msg.correlationId === "string" ? msg.correlationId : void 0) ?? payload.correlationId ?? def.correlationId;
|
|
12
|
+
if (!correlationId) throw new Error("workflow-status: correlationId is required");
|
|
13
|
+
this.status({
|
|
14
|
+
fill: "blue",
|
|
15
|
+
shape: "dot",
|
|
16
|
+
text: "loading…"
|
|
17
|
+
});
|
|
18
|
+
const teamId = agentNode.teamId;
|
|
19
|
+
if (!teamId) throw new Error("workflow-status: agent teamId is required");
|
|
20
|
+
const agent = await agentNode.getAgent();
|
|
21
|
+
const query = {
|
|
22
|
+
correlationId,
|
|
23
|
+
limit: def.limit && def.limit > 0 ? def.limit : 50
|
|
24
|
+
};
|
|
25
|
+
const res = await agent.tasks.list(query, { teamId });
|
|
26
|
+
const rows = res.items.map((t) => ({
|
|
27
|
+
taskId: t.id,
|
|
28
|
+
type: t.taskType,
|
|
29
|
+
title: t.title ?? "",
|
|
30
|
+
status: t.status,
|
|
31
|
+
queuedAt: t.queuedAt,
|
|
32
|
+
completedAt: t.completedAt ?? ""
|
|
33
|
+
}));
|
|
34
|
+
const out = RED.util.cloneMessage(msg);
|
|
35
|
+
out.payload = rows;
|
|
36
|
+
out.workflow = {
|
|
37
|
+
correlationId,
|
|
38
|
+
total: res.total
|
|
39
|
+
};
|
|
40
|
+
this.status({
|
|
41
|
+
fill: "green",
|
|
42
|
+
shape: "dot",
|
|
43
|
+
text: `${rows.length} task(s)`
|
|
44
|
+
});
|
|
45
|
+
send(out);
|
|
46
|
+
done();
|
|
47
|
+
} catch (err) {
|
|
48
|
+
this.status({
|
|
49
|
+
fill: "red",
|
|
50
|
+
shape: "ring",
|
|
51
|
+
text: "error"
|
|
52
|
+
});
|
|
53
|
+
done(err instanceof Error ? err : new Error(String(err)));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
run();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
RED.nodes.registerType("moltnet-workflow-status", WorkflowStatusNode);
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
export { init as default };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"disabled": false,
|
|
4
|
+
"id": "moltnet_cockpit_tab",
|
|
5
|
+
"info": "Inject a correlationId, read the workflow's tasks, view as a table.\nAdd a Dashboard 2.0 ui-table on the output of moltnet-workflow-status to visualize.",
|
|
6
|
+
"label": "MoltNet Cockpit (example)",
|
|
7
|
+
"type": "tab"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"apiUrl": "https://api.themolt.net",
|
|
11
|
+
"clientId": "",
|
|
12
|
+
"id": "moltnet_agent_cfg",
|
|
13
|
+
"name": "my-agent",
|
|
14
|
+
"type": "moltnet-agent"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"id": "inject_correlation",
|
|
18
|
+
"name": "set correlationId",
|
|
19
|
+
"once": false,
|
|
20
|
+
"props": [
|
|
21
|
+
{
|
|
22
|
+
"p": "correlationId",
|
|
23
|
+
"v": "00000000-0000-0000-0000-000000000000",
|
|
24
|
+
"vt": "str"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"topic": "",
|
|
28
|
+
"type": "inject",
|
|
29
|
+
"wires": [["workflow_status"]],
|
|
30
|
+
"x": 180,
|
|
31
|
+
"y": 120,
|
|
32
|
+
"z": "moltnet_cockpit_tab"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"agent": "moltnet_agent_cfg",
|
|
36
|
+
"correlationId": "",
|
|
37
|
+
"id": "workflow_status",
|
|
38
|
+
"limit": 50,
|
|
39
|
+
"name": "",
|
|
40
|
+
"type": "moltnet-workflow-status",
|
|
41
|
+
"wires": [["debug_rows"]],
|
|
42
|
+
"x": 430,
|
|
43
|
+
"y": 120,
|
|
44
|
+
"z": "moltnet_cockpit_tab"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"active": true,
|
|
48
|
+
"complete": "payload",
|
|
49
|
+
"console": false,
|
|
50
|
+
"id": "debug_rows",
|
|
51
|
+
"name": "rows",
|
|
52
|
+
"type": "debug",
|
|
53
|
+
"wires": [],
|
|
54
|
+
"x": 650,
|
|
55
|
+
"y": 120,
|
|
56
|
+
"z": "moltnet_cockpit_tab"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"disabled": false,
|
|
4
|
+
"id": "moltnet_lifecycle_tab",
|
|
5
|
+
"info": "Reproduces the apps/issue-lifecycle orchestration shape in Node-RED.\n\nEach step is: tasks:create → task:wait → switch(phase/decision) → next step.\nDurability is coarse (re-run from top with idempotent steps), inherited from\nthe MoltNet tasks tier — Node-RED is the authoring/cockpit surface, not the\ndurable engine (see issue #1422).\n\ntask:wait has two outputs: output 1 (tail) streams live task messages to a\ndebug node; output 2 (result) carries the terminal snapshot the switch nodes\nbranch on. A failed task is routed to the 'interpret failure' debug, the hook\nwhere an agent/human decides retry vs. escalate — exactly what the\nissue-lifecycle supervisor does.\n\nReplace the moltnet-agent clientId/secret and the inject's issue payload, then\nwire real task bodies into each tasks:create (this example uses minimal bodies).",
|
|
6
|
+
"label": "MoltNet Issue Lifecycle (example)",
|
|
7
|
+
"type": "tab"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"apiUrl": "https://api.themolt.net",
|
|
11
|
+
"clientId": "",
|
|
12
|
+
"diaryId": "",
|
|
13
|
+
"id": "moltnet_agent_cfg",
|
|
14
|
+
"name": "my-agent",
|
|
15
|
+
"teamId": "",
|
|
16
|
+
"type": "moltnet-agent"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "inject_issue",
|
|
20
|
+
"name": "start: issue #N",
|
|
21
|
+
"once": false,
|
|
22
|
+
"props": [
|
|
23
|
+
{
|
|
24
|
+
"p": "payload",
|
|
25
|
+
"v": "{\"taskType\":\"fulfill_brief\",\"title\":\"Triage issue #1\",\"input\":{\"brief\":\"Triage issue #1\"}}",
|
|
26
|
+
"vt": "json"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"topic": "",
|
|
30
|
+
"type": "inject",
|
|
31
|
+
"wires": [["create_triage"]],
|
|
32
|
+
"x": 150,
|
|
33
|
+
"y": 80,
|
|
34
|
+
"z": "moltnet_lifecycle_tab"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"agent": "moltnet_agent_cfg",
|
|
38
|
+
"generateCorrelationId": true,
|
|
39
|
+
"id": "create_triage",
|
|
40
|
+
"name": "triage",
|
|
41
|
+
"taskType": "fulfill_brief",
|
|
42
|
+
"type": "moltnet-tasks-create",
|
|
43
|
+
"wires": [["wait_triage"]],
|
|
44
|
+
"x": 350,
|
|
45
|
+
"y": 80,
|
|
46
|
+
"z": "moltnet_lifecycle_tab"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"agent": "moltnet_agent_cfg",
|
|
50
|
+
"id": "wait_triage",
|
|
51
|
+
"kinds": "",
|
|
52
|
+
"name": "wait triage",
|
|
53
|
+
"pollIntervalSec": 5,
|
|
54
|
+
"tail": true,
|
|
55
|
+
"taskId": "",
|
|
56
|
+
"timeoutSec": 1800,
|
|
57
|
+
"type": "moltnet-task-wait",
|
|
58
|
+
"wires": [["debug_tail"], ["switch_triage"]],
|
|
59
|
+
"x": 540,
|
|
60
|
+
"y": 80,
|
|
61
|
+
"z": "moltnet_lifecycle_tab"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"checkall": "true",
|
|
65
|
+
"id": "switch_triage",
|
|
66
|
+
"name": "accepted & decision=plan?",
|
|
67
|
+
"outputs": 2,
|
|
68
|
+
"property": "payload.state.decision",
|
|
69
|
+
"propertyType": "msg",
|
|
70
|
+
"rules": [{ "t": "eq", "v": "plan", "vt": "str" }, { "t": "else" }],
|
|
71
|
+
"type": "switch",
|
|
72
|
+
"wires": [["create_plan"], ["interpret_failure"]],
|
|
73
|
+
"x": 780,
|
|
74
|
+
"y": 80,
|
|
75
|
+
"z": "moltnet_lifecycle_tab"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"agent": "moltnet_agent_cfg",
|
|
79
|
+
"id": "create_plan",
|
|
80
|
+
"name": "plan",
|
|
81
|
+
"taskType": "fulfill_brief",
|
|
82
|
+
"type": "moltnet-tasks-create",
|
|
83
|
+
"wires": [["wait_plan"]],
|
|
84
|
+
"x": 350,
|
|
85
|
+
"y": 180,
|
|
86
|
+
"z": "moltnet_lifecycle_tab"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"agent": "moltnet_agent_cfg",
|
|
90
|
+
"id": "wait_plan",
|
|
91
|
+
"kinds": "",
|
|
92
|
+
"name": "wait plan",
|
|
93
|
+
"pollIntervalSec": 5,
|
|
94
|
+
"tail": true,
|
|
95
|
+
"taskId": "",
|
|
96
|
+
"timeoutSec": 1800,
|
|
97
|
+
"type": "moltnet-task-wait",
|
|
98
|
+
"wires": [["debug_tail"], ["switch_plan"]],
|
|
99
|
+
"x": 540,
|
|
100
|
+
"y": 180,
|
|
101
|
+
"z": "moltnet_lifecycle_tab"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"checkall": "true",
|
|
105
|
+
"id": "switch_plan",
|
|
106
|
+
"name": "plan accepted?",
|
|
107
|
+
"outputs": 2,
|
|
108
|
+
"property": "payload.accepted",
|
|
109
|
+
"propertyType": "msg",
|
|
110
|
+
"rules": [{ "t": "true" }, { "t": "else" }],
|
|
111
|
+
"type": "switch",
|
|
112
|
+
"wires": [["create_implement"], ["interpret_failure"]],
|
|
113
|
+
"x": 760,
|
|
114
|
+
"y": 180,
|
|
115
|
+
"z": "moltnet_lifecycle_tab"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"agent": "moltnet_agent_cfg",
|
|
119
|
+
"id": "create_implement",
|
|
120
|
+
"name": "implement",
|
|
121
|
+
"taskType": "fulfill_brief",
|
|
122
|
+
"type": "moltnet-tasks-create",
|
|
123
|
+
"wires": [["wait_implement"]],
|
|
124
|
+
"x": 360,
|
|
125
|
+
"y": 280,
|
|
126
|
+
"z": "moltnet_lifecycle_tab"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"agent": "moltnet_agent_cfg",
|
|
130
|
+
"id": "wait_implement",
|
|
131
|
+
"kinds": "",
|
|
132
|
+
"name": "wait implement",
|
|
133
|
+
"pollIntervalSec": 10,
|
|
134
|
+
"tail": true,
|
|
135
|
+
"taskId": "",
|
|
136
|
+
"timeoutSec": 3600,
|
|
137
|
+
"type": "moltnet-task-wait",
|
|
138
|
+
"wires": [["debug_tail"], ["switch_implement"]],
|
|
139
|
+
"x": 560,
|
|
140
|
+
"y": 280,
|
|
141
|
+
"z": "moltnet_lifecycle_tab"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"checkall": "true",
|
|
145
|
+
"id": "switch_implement",
|
|
146
|
+
"name": "PR opened? (phase=pr_open)",
|
|
147
|
+
"outputs": 2,
|
|
148
|
+
"property": "payload.state.phase",
|
|
149
|
+
"propertyType": "msg",
|
|
150
|
+
"rules": [{ "t": "eq", "v": "pr_open", "vt": "str" }, { "t": "else" }],
|
|
151
|
+
"type": "switch",
|
|
152
|
+
"wires": [["debug_done"], ["interpret_failure"]],
|
|
153
|
+
"x": 790,
|
|
154
|
+
"y": 280,
|
|
155
|
+
"z": "moltnet_lifecycle_tab"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"active": true,
|
|
159
|
+
"complete": "payload",
|
|
160
|
+
"console": false,
|
|
161
|
+
"id": "debug_tail",
|
|
162
|
+
"name": "tail (live messages)",
|
|
163
|
+
"tosidebar": true,
|
|
164
|
+
"type": "debug",
|
|
165
|
+
"wires": [],
|
|
166
|
+
"x": 780,
|
|
167
|
+
"y": 400,
|
|
168
|
+
"z": "moltnet_lifecycle_tab"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"active": true,
|
|
172
|
+
"complete": "payload",
|
|
173
|
+
"console": false,
|
|
174
|
+
"id": "interpret_failure",
|
|
175
|
+
"name": "interpret failure (agent/human)",
|
|
176
|
+
"tosidebar": true,
|
|
177
|
+
"type": "debug",
|
|
178
|
+
"wires": [],
|
|
179
|
+
"x": 1080,
|
|
180
|
+
"y": 180,
|
|
181
|
+
"z": "moltnet_lifecycle_tab"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"active": true,
|
|
185
|
+
"complete": "payload",
|
|
186
|
+
"console": false,
|
|
187
|
+
"id": "debug_done",
|
|
188
|
+
"name": "done (PR open)",
|
|
189
|
+
"tosidebar": true,
|
|
190
|
+
"type": "debug",
|
|
191
|
+
"wires": [],
|
|
192
|
+
"x": 1040,
|
|
193
|
+
"y": 280,
|
|
194
|
+
"z": "moltnet_lifecycle_tab"
|
|
195
|
+
}
|
|
196
|
+
]
|