@themoltnet/node-red-contrib-core 0.10.0 → 0.12.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/README.md +40 -20
- package/dist/nodes/runtime-session-download.js +1 -1
- package/dist/nodes/runtime-session-upload.js +1 -1
- package/dist/nodes/src.js +185 -36
- package/dist/nodes/task-artifact-download.html +7 -2
- package/dist/nodes/task-artifact-download.js +10 -4
- package/dist/nodes/task-artifact-stage.html +93 -0
- package/dist/nodes/task-artifact-stage.js +54 -0
- package/dist/nodes/task-artifact-upload.js +1 -1
- package/dist/nodes/task-artifact-utils.js +35 -7
- package/dist/nodes/task-builder.js +2 -1
- package/dist/nodes/task-cancel.html +77 -0
- package/dist/nodes/task-cancel.js +135 -0
- package/dist/nodes/task-wait.html +12 -0
- package/dist/nodes/task-wait.js +4 -1
- package/dist/nodes/tasks-create.js +1 -0
- package/examples/deep-review-freeform.flow.json +1006 -159
- package/package.json +4 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { t as withAgent } from "./agent-call.js";
|
|
2
|
+
import { t as bool } from "./query-utils.js";
|
|
3
|
+
import { c as resolveMaxBytes, l as resolveTeamId, s as resolveField, u as resolveUploadBody } from "./task-artifact-utils.js";
|
|
4
|
+
//#region src/nodes/task-artifact-stage.ts
|
|
5
|
+
var init = (RED) => {
|
|
6
|
+
function TaskArtifactStageNode(def) {
|
|
7
|
+
RED.nodes.createNode(this, def);
|
|
8
|
+
const agentNode = def.agent ? RED.nodes.getNode(def.agent) : null;
|
|
9
|
+
this.on("input", (msg, send, done) => {
|
|
10
|
+
const run = async () => {
|
|
11
|
+
try {
|
|
12
|
+
if (!agentNode || typeof agentNode.getAgent !== "function") throw new Error("task-artifact-stage: no moltnet-agent configured");
|
|
13
|
+
const teamId = resolveTeamId(msg, def.teamId, agentNode, bool(def.allowMsgTeamOverride) ?? false);
|
|
14
|
+
if (!teamId) throw new Error("task-artifact-stage: teamId is required");
|
|
15
|
+
const body = resolveUploadBody(msg, resolveMaxBytes(def.maxBytes), "task-artifact-stage");
|
|
16
|
+
const query = {
|
|
17
|
+
contentType: resolveField(msg, "contentType", def.contentType),
|
|
18
|
+
contentEncoding: resolveField(msg, "contentEncoding", def.contentEncoding)
|
|
19
|
+
};
|
|
20
|
+
this.status({
|
|
21
|
+
fill: "blue",
|
|
22
|
+
shape: "dot",
|
|
23
|
+
text: "staging..."
|
|
24
|
+
});
|
|
25
|
+
const artifact = await withAgent(agentNode, (agent) => agent.tasks.artifacts.stage(body, query, { teamId }));
|
|
26
|
+
const out = RED.util.cloneMessage({
|
|
27
|
+
...msg,
|
|
28
|
+
payload: void 0
|
|
29
|
+
});
|
|
30
|
+
out.payload = artifact;
|
|
31
|
+
out.artifact = artifact;
|
|
32
|
+
this.status({
|
|
33
|
+
fill: "green",
|
|
34
|
+
shape: "dot",
|
|
35
|
+
text: artifact.cid
|
|
36
|
+
});
|
|
37
|
+
send(out);
|
|
38
|
+
done();
|
|
39
|
+
} catch (err) {
|
|
40
|
+
this.status({
|
|
41
|
+
fill: "red",
|
|
42
|
+
shape: "ring",
|
|
43
|
+
text: "error"
|
|
44
|
+
});
|
|
45
|
+
done(err instanceof Error ? err : new Error(String(err)));
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
run();
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
RED.nodes.registerType("moltnet-task-artifact-stage", TaskArtifactStageNode);
|
|
52
|
+
};
|
|
53
|
+
//#endregion
|
|
54
|
+
export { init as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as withAgent } from "./agent-call.js";
|
|
2
2
|
import { t as bool } from "./query-utils.js";
|
|
3
|
-
import { a as requireAttemptContext, c as
|
|
3
|
+
import { a as requireAttemptContext, c as resolveMaxBytes, s as resolveField, u as resolveUploadBody } from "./task-artifact-utils.js";
|
|
4
4
|
//#region src/nodes/task-artifact-upload.ts
|
|
5
5
|
var init = (RED) => {
|
|
6
6
|
function TaskArtifactUploadNode(def) {
|
|
@@ -17,8 +17,22 @@ function resolveTeamId(msg, configured, agentNode, allowMsgTeamOverride) {
|
|
|
17
17
|
return nonEmpty(payloadRecord(msg).teamId) ?? nonEmpty(configured) ?? agentNode.teamId;
|
|
18
18
|
}
|
|
19
19
|
function resolveAttemptN(msg, configured) {
|
|
20
|
+
return resolveAttemptSelection(msg, configured).attemptN;
|
|
21
|
+
}
|
|
22
|
+
function resolveAttemptSelection(msg, configured) {
|
|
20
23
|
const payload = payloadRecord(msg);
|
|
21
|
-
|
|
24
|
+
const candidate = [
|
|
25
|
+
msg.attemptN,
|
|
26
|
+
payload.attemptN,
|
|
27
|
+
recordField(payload.attempt, "attemptN"),
|
|
28
|
+
recordField(payload.artifact, "attemptN"),
|
|
29
|
+
configured
|
|
30
|
+
].find(isSupplied);
|
|
31
|
+
if (candidate === void 0) return { supplied: false };
|
|
32
|
+
return {
|
|
33
|
+
supplied: true,
|
|
34
|
+
attemptN: positiveInt(candidate)
|
|
35
|
+
};
|
|
22
36
|
}
|
|
23
37
|
function requireArtifactContext(nodeName, msg, configuredTaskId, configuredTeamId, agentNode, allowMsgTeamOverride) {
|
|
24
38
|
const taskId = resolveTaskId(msg, configuredTaskId);
|
|
@@ -59,9 +73,8 @@ function resolveUploadBody(msg, maxBytes, nodeName = "task-artifact-upload") {
|
|
|
59
73
|
}
|
|
60
74
|
const record = payloadRecord(msg);
|
|
61
75
|
if (typeof record.contentBase64 === "string") {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return Buffer.from(normalized, "base64");
|
|
76
|
+
if (decodedBase64Length(record.contentBase64) > maxBytes) throw tooLarge("upload", maxBytes, nodeName);
|
|
77
|
+
return Buffer.from(record.contentBase64, "base64");
|
|
65
78
|
}
|
|
66
79
|
const content = record.content ?? record.body;
|
|
67
80
|
if (Buffer.isBuffer(content)) return enforceMaxBytes(content, maxBytes, nodeName);
|
|
@@ -139,11 +152,26 @@ function pushChunk(chunks, chunk, bytes, maxBytes, nodeName) {
|
|
|
139
152
|
}
|
|
140
153
|
function decodedBase64Length(value) {
|
|
141
154
|
if (!value) return 0;
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
let characters = 0;
|
|
156
|
+
let previous = "";
|
|
157
|
+
let last = "";
|
|
158
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
159
|
+
if (isBase64Whitespace(value.charCodeAt(index))) continue;
|
|
160
|
+
characters += 1;
|
|
161
|
+
previous = last;
|
|
162
|
+
last = value[index];
|
|
163
|
+
}
|
|
164
|
+
const padding = last === "=" ? previous === "=" ? 2 : 1 : 0;
|
|
165
|
+
return Math.max(0, Math.floor(characters * 3 / 4) - padding);
|
|
166
|
+
}
|
|
167
|
+
function isSupplied(value) {
|
|
168
|
+
return value !== void 0 && value !== null && value !== "";
|
|
169
|
+
}
|
|
170
|
+
function isBase64Whitespace(code) {
|
|
171
|
+
return code === 32 || code >= 9 && code <= 13;
|
|
144
172
|
}
|
|
145
173
|
function tooLarge(operation, maxBytes, nodeName) {
|
|
146
174
|
return /* @__PURE__ */ new Error(`${nodeName}: ${operation} body exceeds ${maxBytes} bytes`);
|
|
147
175
|
}
|
|
148
176
|
//#endregion
|
|
149
|
-
export { requireAttemptContext as a,
|
|
177
|
+
export { requireAttemptContext as a, resolveMaxBytes as c, requireArtifactContext as i, resolveTeamId as l, payloadRecord as n, resolveAttemptSelection as o, recordField as r, resolveField as s, collectArtifactBody as t, resolveUploadBody as u };
|
|
@@ -75,7 +75,8 @@ var init = (RED) => {
|
|
|
75
75
|
}
|
|
76
76
|
if (def.referencesFrom) {
|
|
77
77
|
const ref = RED.util.getMessageProperty(msg, def.referencesFrom);
|
|
78
|
-
if (ref
|
|
78
|
+
if (ref?.artifact || ref?.artifactSource === "staged" || ref?.cid) builder.artifactReference(ref, def.referencesRole ?? "context");
|
|
79
|
+
else if (ref?.outputCid) builder.references(ref, def.referencesRole ?? "context");
|
|
79
80
|
}
|
|
80
81
|
if (def.submitOutputGate) builder.requireSubmitOutput();
|
|
81
82
|
if (def.schemaCid) builder.requireSchema(def.schemaCid);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<script type="text/javascript">
|
|
2
|
+
RED.nodes.registerType('moltnet-task-cancel', {
|
|
3
|
+
category: 'moltnet',
|
|
4
|
+
color: '#00d4c8',
|
|
5
|
+
paletteLabel: 'task: cancel',
|
|
6
|
+
defaults: {
|
|
7
|
+
name: { value: '' },
|
|
8
|
+
agent: { value: '', type: 'moltnet-agent', required: true },
|
|
9
|
+
taskId: { value: '' },
|
|
10
|
+
reason: { value: '' },
|
|
11
|
+
skipMissing: { value: false },
|
|
12
|
+
ignoreErrors: { value: false },
|
|
13
|
+
},
|
|
14
|
+
inputs: 1,
|
|
15
|
+
outputs: 1,
|
|
16
|
+
icon: 'font-awesome/fa-ban',
|
|
17
|
+
label: function () {
|
|
18
|
+
return this.name || 'task: cancel';
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script type="text/html" data-template-name="moltnet-task-cancel">
|
|
24
|
+
<div class="form-row">
|
|
25
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
|
|
26
|
+
<input type="text" id="node-input-name" />
|
|
27
|
+
</div>
|
|
28
|
+
<div class="form-row">
|
|
29
|
+
<label for="node-input-agent"><i class="fa fa-user"></i> Agent</label>
|
|
30
|
+
<input type="text" id="node-input-agent" />
|
|
31
|
+
</div>
|
|
32
|
+
<div class="form-row">
|
|
33
|
+
<label for="node-input-taskId"><i class="fa fa-hashtag"></i> Task ID</label>
|
|
34
|
+
<input
|
|
35
|
+
type="text"
|
|
36
|
+
id="node-input-taskId"
|
|
37
|
+
placeholder="msg.taskId / msg.payload rows"
|
|
38
|
+
/>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="form-row">
|
|
41
|
+
<label for="node-input-reason"><i class="fa fa-comment"></i> Reason</label>
|
|
42
|
+
<input type="text" id="node-input-reason" placeholder="workflow failed" />
|
|
43
|
+
</div>
|
|
44
|
+
<div class="form-row">
|
|
45
|
+
<label> </label>
|
|
46
|
+
<input
|
|
47
|
+
type="checkbox"
|
|
48
|
+
id="node-input-skipMissing"
|
|
49
|
+
style="display:inline-block; width:auto; vertical-align:top;"
|
|
50
|
+
/>
|
|
51
|
+
<span>Pass through when no task id is available</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="form-row">
|
|
54
|
+
<label> </label>
|
|
55
|
+
<input
|
|
56
|
+
type="checkbox"
|
|
57
|
+
id="node-input-ignoreErrors"
|
|
58
|
+
style="display:inline-block; width:auto; vertical-align:top;"
|
|
59
|
+
/>
|
|
60
|
+
<span>Keep the original message if cancel fails</span>
|
|
61
|
+
</div>
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<script type="text/html" data-help-name="moltnet-task-cancel">
|
|
65
|
+
<p>Cancels one or more MoltNet tasks.</p>
|
|
66
|
+
<p>
|
|
67
|
+
Task ids are resolved from <code>msg.taskId</code>,
|
|
68
|
+
<code>msg.taskIds</code>, <code>msg.payload.taskId</code>,
|
|
69
|
+
<code>msg.payload.id</code>, <code>msg.payload.failure.taskId</code>, an
|
|
70
|
+
array on <code>msg.payload</code>, or the configured Task ID.
|
|
71
|
+
</p>
|
|
72
|
+
<p>
|
|
73
|
+
The original <code>msg.payload</code> is preserved. Cancelled task rows are
|
|
74
|
+
written to <code>msg.cancelledTasks</code>; ignored cancel failures are
|
|
75
|
+
written to <code>msg.cancelErrors</code>.
|
|
76
|
+
</p>
|
|
77
|
+
</script>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { t as withAgent } from "./agent-call.js";
|
|
2
|
+
//#region src/nodes/task-cancel.ts
|
|
3
|
+
var TERMINAL_STATUSES = new Set([
|
|
4
|
+
"completed",
|
|
5
|
+
"failed",
|
|
6
|
+
"cancelled",
|
|
7
|
+
"expired"
|
|
8
|
+
]);
|
|
9
|
+
var init = (RED) => {
|
|
10
|
+
function TaskCancelNode(def) {
|
|
11
|
+
RED.nodes.createNode(this, def);
|
|
12
|
+
const agentNode = def.agent ? RED.nodes.getNode(def.agent) : null;
|
|
13
|
+
this.on("input", (msg, send, done) => {
|
|
14
|
+
const run = async () => {
|
|
15
|
+
try {
|
|
16
|
+
if (!agentNode || typeof agentNode.getAgent !== "function") throw new Error("task-cancel: no moltnet-agent configured");
|
|
17
|
+
const taskIds = resolveTaskIds(msg, def.taskId);
|
|
18
|
+
if (taskIds.length === 0) {
|
|
19
|
+
if (def.skipMissing) {
|
|
20
|
+
const out = RED.util.cloneMessage(msg);
|
|
21
|
+
out.cancelledTasks = [];
|
|
22
|
+
out.cancelErrors = [];
|
|
23
|
+
this.status({
|
|
24
|
+
fill: "yellow",
|
|
25
|
+
shape: "ring",
|
|
26
|
+
text: "no task id"
|
|
27
|
+
});
|
|
28
|
+
send(out);
|
|
29
|
+
done();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
throw new Error("task-cancel: taskId is required");
|
|
33
|
+
}
|
|
34
|
+
this.status({
|
|
35
|
+
fill: "blue",
|
|
36
|
+
shape: "dot",
|
|
37
|
+
text: `cancelling ${taskIds.length}`
|
|
38
|
+
});
|
|
39
|
+
const reason = resolveReason(msg, def.reason);
|
|
40
|
+
const cancelled = [];
|
|
41
|
+
const errors = [];
|
|
42
|
+
await withAgent(agentNode, async (agent) => {
|
|
43
|
+
for (const taskId of taskIds) try {
|
|
44
|
+
const task = await agent.tasks.cancel(taskId, { reason });
|
|
45
|
+
cancelled.push(task);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
const message = errorMessage(error);
|
|
48
|
+
if (!def.ignoreErrors) throw error;
|
|
49
|
+
errors.push({
|
|
50
|
+
taskId,
|
|
51
|
+
message
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const out = RED.util.cloneMessage(msg);
|
|
56
|
+
out.cancelledTasks = cancelled;
|
|
57
|
+
out.cancelErrors = errors;
|
|
58
|
+
if (cancelled.length === 1) out.cancelledTask = cancelled[0];
|
|
59
|
+
if (taskIds.length === 1) out.taskId = taskIds[0];
|
|
60
|
+
this.status({
|
|
61
|
+
fill: errors.length > 0 ? "yellow" : "green",
|
|
62
|
+
shape: errors.length > 0 ? "ring" : "dot",
|
|
63
|
+
text: errors.length > 0 ? `cancelled ${cancelled.length}, ${errors.length} error(s)` : `cancelled ${cancelled.length}`
|
|
64
|
+
});
|
|
65
|
+
send(out);
|
|
66
|
+
done();
|
|
67
|
+
} catch (err) {
|
|
68
|
+
this.status({
|
|
69
|
+
fill: "red",
|
|
70
|
+
shape: "ring",
|
|
71
|
+
text: "error"
|
|
72
|
+
});
|
|
73
|
+
done(err instanceof Error ? err : new Error(String(err)));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
run();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
RED.nodes.registerType("moltnet-task-cancel", TaskCancelNode);
|
|
80
|
+
};
|
|
81
|
+
function resolveTaskIds(msg, configured) {
|
|
82
|
+
const ids = /* @__PURE__ */ new Set();
|
|
83
|
+
addId(ids, msg.taskId);
|
|
84
|
+
addIds(ids, msg.taskIds);
|
|
85
|
+
collectFromPayload(ids, msg.payload);
|
|
86
|
+
addId(ids, configured);
|
|
87
|
+
return [...ids];
|
|
88
|
+
}
|
|
89
|
+
function collectFromPayload(ids, value) {
|
|
90
|
+
if (!value) return;
|
|
91
|
+
if (typeof value === "string") {
|
|
92
|
+
addId(ids, value);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
for (const item of value) collectFromPayload(ids, item);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (typeof value !== "object") return;
|
|
100
|
+
const record = value;
|
|
101
|
+
addId(ids, record.taskId);
|
|
102
|
+
addId(ids, record.id);
|
|
103
|
+
addIds(ids, record.taskIds);
|
|
104
|
+
addIds(ids, record.ids);
|
|
105
|
+
if (Array.isArray(record.tasks)) addIds(ids, record.tasks);
|
|
106
|
+
if (record.failure && typeof record.failure === "object") addId(ids, record.failure.taskId);
|
|
107
|
+
if (typeof record.status === "string" && TERMINAL_STATUSES.has(record.status)) return;
|
|
108
|
+
}
|
|
109
|
+
function addIds(ids, value) {
|
|
110
|
+
if (!Array.isArray(value)) return;
|
|
111
|
+
for (const item of value) collectFromPayload(ids, item);
|
|
112
|
+
}
|
|
113
|
+
function addId(ids, value) {
|
|
114
|
+
if (typeof value === "string" && value.trim()) ids.add(value.trim());
|
|
115
|
+
}
|
|
116
|
+
function resolveReason(msg, configured) {
|
|
117
|
+
if (configured && configured.trim()) return configured.trim();
|
|
118
|
+
const payload = msg.payload;
|
|
119
|
+
if (payload && typeof payload === "object") {
|
|
120
|
+
const p = payload;
|
|
121
|
+
if (p.failure && typeof p.failure === "object") {
|
|
122
|
+
const error = p.failure.error;
|
|
123
|
+
if (error && typeof error === "object") {
|
|
124
|
+
const message = error.message;
|
|
125
|
+
if (typeof message === "string" && message.trim()) return `workflow failed: ${message.trim()}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return "workflow failed";
|
|
130
|
+
}
|
|
131
|
+
function errorMessage(error) {
|
|
132
|
+
return error instanceof Error ? error.message : String(error);
|
|
133
|
+
}
|
|
134
|
+
//#endregion
|
|
135
|
+
export { init as default };
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
agent: { value: '', type: 'moltnet-agent', required: true },
|
|
17
17
|
taskId: { value: '' },
|
|
18
18
|
pollIntervalSec: { value: 5, validate: RED.validators.number() },
|
|
19
|
+
// Legacy field used by older example flows. Keeping it in defaults lets
|
|
20
|
+
// the editor migrate existing nodes instead of showing them as broken.
|
|
21
|
+
intervalMs: { value: undefined, required: false },
|
|
19
22
|
timeoutSec: { value: 1800, validate: RED.validators.number() },
|
|
20
23
|
tail: { value: false },
|
|
21
24
|
kinds: { value: '' },
|
|
@@ -28,6 +31,14 @@
|
|
|
28
31
|
return this.name || 'task: wait';
|
|
29
32
|
},
|
|
30
33
|
oneditprepare: function () {
|
|
34
|
+
if (
|
|
35
|
+
(this.pollIntervalSec === undefined ||
|
|
36
|
+
this.pollIntervalSec === null ||
|
|
37
|
+
this.pollIntervalSec === '') &&
|
|
38
|
+
typeof this.intervalMs === 'number'
|
|
39
|
+
) {
|
|
40
|
+
$('#node-input-pollIntervalSec').val(this.intervalMs / 1000);
|
|
41
|
+
}
|
|
31
42
|
// Render one checkbox per message kind. `kinds` is stored as a
|
|
32
43
|
// comma-separated string (the runtime contract); empty = all kinds.
|
|
33
44
|
const selected = (this.kinds || '')
|
|
@@ -56,6 +67,7 @@
|
|
|
56
67
|
toggle();
|
|
57
68
|
},
|
|
58
69
|
oneditsave: function () {
|
|
70
|
+
this.intervalMs = undefined;
|
|
59
71
|
const all = $('.mn-kind').length;
|
|
60
72
|
const checked = $('.mn-kind:checked')
|
|
61
73
|
.map(function () {
|
package/dist/nodes/task-wait.js
CHANGED
|
@@ -7,7 +7,8 @@ var init = (RED) => {
|
|
|
7
7
|
function TaskWaitNode(def) {
|
|
8
8
|
RED.nodes.createNode(this, def);
|
|
9
9
|
const agentNode = def.agent ? RED.nodes.getNode(def.agent) : null;
|
|
10
|
-
const
|
|
10
|
+
const pollSec = def.pollIntervalSec ?? (typeof def.intervalMs === "number" ? def.intervalMs / 1e3 : void 0);
|
|
11
|
+
const pollMs = Math.max(1, pollSec || DEFAULT_POLL_SEC) * 1e3;
|
|
11
12
|
const timeoutMs = (def.timeoutSec ?? DEFAULT_TIMEOUT_SEC) > 0 ? (def.timeoutSec ?? DEFAULT_TIMEOUT_SEC) * 1e3 : 0;
|
|
12
13
|
const kindAllow = parseKinds(def.kinds);
|
|
13
14
|
const active = /* @__PURE__ */ new Map();
|
|
@@ -24,6 +25,7 @@ var init = (RED) => {
|
|
|
24
25
|
if (!agentNode || typeof agentNode.getAgent !== "function") throw new Error("task-wait: no moltnet-agent configured");
|
|
25
26
|
const taskId = resolveTaskId(msg, def.taskId);
|
|
26
27
|
if (!taskId) throw new Error("task-wait: taskId is required");
|
|
28
|
+
msg.taskId = taskId;
|
|
27
29
|
taskIdForStatus = taskId;
|
|
28
30
|
label = describeWait(taskId, msg, label);
|
|
29
31
|
active.set(taskId, label);
|
|
@@ -61,6 +63,7 @@ var init = (RED) => {
|
|
|
61
63
|
...snapshot,
|
|
62
64
|
correlationId
|
|
63
65
|
} : snapshot;
|
|
66
|
+
resultMsg.taskId = taskId;
|
|
64
67
|
if (correlationId) resultMsg.correlationId = correlationId;
|
|
65
68
|
active.delete(taskId);
|
|
66
69
|
this.status({
|
|
@@ -34,6 +34,7 @@ var init = (RED) => {
|
|
|
34
34
|
const task = await withAgent(agentNode, (agent) => agent.tasks.create(createBody, { teamId }));
|
|
35
35
|
const out = RED.util.cloneMessage(msg);
|
|
36
36
|
if (correlationId) out.correlationId = correlationId;
|
|
37
|
+
out.taskId = task.id;
|
|
37
38
|
out.payload = task;
|
|
38
39
|
active.delete(invocationId);
|
|
39
40
|
this.status({
|