@themoltnet/node-red-contrib-core 0.6.0 → 0.7.1
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 +97 -8
- package/dist/nodes/agent-call.js +19 -0
- package/dist/nodes/agent.js +3 -0
- package/dist/nodes/entries-search.js +2 -1
- package/dist/nodes/runtime-profile.js +2 -1
- package/dist/nodes/src.js +45 -5
- package/dist/nodes/task-artifact-download.js +3 -2
- package/dist/nodes/task-artifact-upload.js +3 -2
- package/dist/nodes/task-artifacts-list.js +2 -2
- package/dist/nodes/task-get.js +2 -2
- package/dist/nodes/task-wait.js +65 -11
- package/dist/nodes/tasks-create.js +46 -5
- package/dist/nodes/tasks-list.js +2 -2
- package/dist/nodes/workflow-status.js +2 -2
- package/examples/deep-review-freeform.flow.json +780 -0
- package/package.json +26 -3
|
@@ -0,0 +1,780 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"disabled": false,
|
|
4
|
+
"id": "deep_review_tab",
|
|
5
|
+
"info": "Freeform-only deep review workflow. Configure the moltnet-agent node after import, then edit the seed node for the target PR/branch/local diff.",
|
|
6
|
+
"label": "MoltNet deep review (freeform)",
|
|
7
|
+
"type": "tab"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"apiUrl": "",
|
|
11
|
+
"clientId": "",
|
|
12
|
+
"diaryId": "",
|
|
13
|
+
"id": "deep_review_agent_cfg",
|
|
14
|
+
"name": "deep-review-agent",
|
|
15
|
+
"teamId": "",
|
|
16
|
+
"type": "moltnet-agent"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"agent": "deep_review_agent_cfg",
|
|
20
|
+
"id": "deep_review_profile_freeze",
|
|
21
|
+
"name": "FREEZE profile",
|
|
22
|
+
"profileId": "1a653eb9-7bfa-475f-b517-c070c9c25b5e",
|
|
23
|
+
"profileName": "deep-review-freeze-ollama-qwen-coder-v1",
|
|
24
|
+
"type": "moltnet-runtime-profile"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"agent": "deep_review_agent_cfg",
|
|
28
|
+
"id": "deep_review_profile_preflight",
|
|
29
|
+
"name": "PREFLIGHT profile",
|
|
30
|
+
"profileId": "f4bb1d9b-6281-4158-ad88-cbcb1198c3dc",
|
|
31
|
+
"profileName": "deep-review-preflight-ollama-qwen-coder-v1",
|
|
32
|
+
"type": "moltnet-runtime-profile"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"agent": "deep_review_agent_cfg",
|
|
36
|
+
"id": "deep_review_profile_specialist",
|
|
37
|
+
"name": "SPECIALIST profile",
|
|
38
|
+
"profileId": "f50e9c58-4180-4e07-b120-08b6097c13d5",
|
|
39
|
+
"profileName": "deep-review-specialist-ollama-qwen-coder-v1",
|
|
40
|
+
"type": "moltnet-runtime-profile"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"agent": "deep_review_agent_cfg",
|
|
44
|
+
"id": "deep_review_profile_aggregate",
|
|
45
|
+
"name": "AGGREGATE profile",
|
|
46
|
+
"profileId": "29db793d-3ad9-420b-96e7-df5356b3d19b",
|
|
47
|
+
"profileName": "deep-review-aggregate-ollama-kimi-v1",
|
|
48
|
+
"type": "moltnet-runtime-profile"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "deep_review_note",
|
|
52
|
+
"info": "This example keeps MoltNet generic: every agent step is taskType=freeform. Node-RED owns orchestration, correlationId threading, gates, profile routing, specialist fan-out/fan-in, and aggregation. Agents own the judgment and produce structured freeform artifacts. The FREEZE branch parses compact inline JSON for control flow, then lists and downloads any persistent review bundle artifact uploaded by the agent during the attempt. Runtime-profile config nodes pin each stage to an Ollama Cloud profile: FREEZE/PREFLIGHT/SPECIALIST use qwen3-coder:480b-cloud for reliable tool calls, and AGGREGATE uses kimi-k2.7-code:cloud.",
|
|
53
|
+
"name": "Freeform-only deep review workflow",
|
|
54
|
+
"type": "comment",
|
|
55
|
+
"wires": [],
|
|
56
|
+
"x": 260,
|
|
57
|
+
"y": 40,
|
|
58
|
+
"z": "deep_review_tab"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"crontab": "",
|
|
62
|
+
"id": "deep_review_start",
|
|
63
|
+
"name": "start review",
|
|
64
|
+
"once": false,
|
|
65
|
+
"onceDelay": 0.1,
|
|
66
|
+
"payload": "",
|
|
67
|
+
"payloadType": "date",
|
|
68
|
+
"props": [
|
|
69
|
+
{
|
|
70
|
+
"p": "payload"
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"repeat": "",
|
|
74
|
+
"topic": "",
|
|
75
|
+
"type": "inject",
|
|
76
|
+
"wires": [["deep_review_seed"]],
|
|
77
|
+
"x": 130,
|
|
78
|
+
"y": 100,
|
|
79
|
+
"z": "deep_review_tab"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"finalize": "",
|
|
83
|
+
"func": "msg.review = {\n workflow: 'deep-review-freeform:v1',\n target: {\n kind: 'github_pr',\n owner: 'getlarge',\n repo: 'themoltnet',\n prNumber: 1486,\n baseRef: 'main',\n headRef: 'issue-1481-review-fixes'\n },\n dimensions: [\n 'correctness',\n 'security',\n 'performance',\n 'dry-codebase-fit',\n 'design-api-backcompat',\n 'tests',\n 'operability',\n 'readability'\n ],\n publishPolicy: 'none',\n sizeGate: { maxFiles: 25, maxLoc: 1500 },\n memory: {\n query: 'task artifacts node-red review workflow branch issue-1481-review-fixes',\n tags: ['decision'],\n limit: 8\n }\n};\nmsg.payload = {\n query: msg.review.memory.query,\n tags: msg.review.memory.tags,\n limit: msg.review.memory.limit\n};\nreturn msg;",
|
|
84
|
+
"id": "deep_review_seed",
|
|
85
|
+
"initialize": "",
|
|
86
|
+
"libs": [],
|
|
87
|
+
"name": "seed target + config",
|
|
88
|
+
"noerr": 0,
|
|
89
|
+
"outputs": 1,
|
|
90
|
+
"timeout": 0,
|
|
91
|
+
"type": "function",
|
|
92
|
+
"wires": [["deep_review_entries_search"]],
|
|
93
|
+
"x": 350,
|
|
94
|
+
"y": 100,
|
|
95
|
+
"z": "deep_review_tab"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"agent": "deep_review_agent_cfg",
|
|
99
|
+
"diaryId": "",
|
|
100
|
+
"entryTypes": "",
|
|
101
|
+
"excludeSuperseded": true,
|
|
102
|
+
"excludeTags": "",
|
|
103
|
+
"id": "deep_review_entries_search",
|
|
104
|
+
"limit": "",
|
|
105
|
+
"name": "optional memory search",
|
|
106
|
+
"offset": "",
|
|
107
|
+
"query": "",
|
|
108
|
+
"tags": "",
|
|
109
|
+
"type": "moltnet-entries-search",
|
|
110
|
+
"wImportance": "",
|
|
111
|
+
"wRecency": "",
|
|
112
|
+
"wRelevance": "",
|
|
113
|
+
"wires": [["deep_review_stash_memory"]],
|
|
114
|
+
"x": 610,
|
|
115
|
+
"y": 100,
|
|
116
|
+
"z": "deep_review_tab"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"finalize": "",
|
|
120
|
+
"func": "const entries = Array.isArray(msg.payload) ? msg.payload : [];\nmsg.reviewMemory = entries.map((entry) => ({\n id: entry.id,\n title: entry.title || '',\n type: entry.entryType || entry.type || '',\n tags: entry.tags || [],\n summary: String(entry.content || entry.summary || '').slice(0, 700)\n}));\nreturn msg;",
|
|
121
|
+
"id": "deep_review_stash_memory",
|
|
122
|
+
"initialize": "",
|
|
123
|
+
"libs": [],
|
|
124
|
+
"name": "stash memory hits",
|
|
125
|
+
"noerr": 0,
|
|
126
|
+
"outputs": 1,
|
|
127
|
+
"timeout": 0,
|
|
128
|
+
"type": "function",
|
|
129
|
+
"wires": [["deep_review_build_freeze"]],
|
|
130
|
+
"x": 850,
|
|
131
|
+
"y": 100,
|
|
132
|
+
"z": "deep_review_tab"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"finalize": "",
|
|
136
|
+
"func": "const target = msg.review.target;\nmsg.payload = {\n taskType: 'freeform',\n title: 'Deep review: freeze scope',\n tags: ['deep-review', 'deep-review:freeze', msg.review.workflow],\n correlationId: msg.correlationId,\n input: {\n brief: [\n 'Freeze the review scope for a deep code review workflow.',\n '',\n 'Target JSON:',\n JSON.stringify(target, null, 2),\n '',\n 'Create an immutable review bundle. Always return a compact inline freeform artifact. If task artifact upload tools are available, also upload large patch/file-list content after writing the local files successfully.',\n '',\n 'Before calling moltnet_upload_task_artifact for a workspace file, create the file first and verify it exists. Never call artifact upload with a guessed path such as review.patch if the file was not written.',\n '',\n 'The bundle should include: target metadata, base/head refs or PR number, changed files, diff stats, and either a patch artifact CID or enough precise instructions for downstream agents to fetch the same diff.',\n '',\n 'Return a freeform artifact with kind \"json\" and title \"review-bundle\". The artifact body must be JSON with fields: target, changedFiles, stats, diffArtifactCid, patchArtifactCid, notes, memoryEntryIds.',\n '',\n 'If the submit tool requires a verification block, every verification.results[].kind must be one of: gate, assertion, rubric, sideEffect. For a submit-tool-call success criterion, report it as kind \"gate\"; never use \"submit-tool-call\" as a verification result kind.'\n ].join('\\n'),\n expectedOutput: 'Summary plus artifact kind=json title=review-bundle. Use task artifact CIDs for large patch/file-list content only after the local files exist.',\n constraints: [\n 'Do not review findings in this task.',\n 'Do not modify code.',\n 'If the target cannot be resolved, explain the blocker in the output.',\n 'When self-verifying a submit-tool-call gate, use verification result kind \"gate\".'\n ],\n context: [\n { slug: 'review-config', binding: 'context_inline', content: JSON.stringify(msg.review, null, 2) },\n { slug: 'memory-hits', binding: 'context_inline', content: JSON.stringify(msg.reviewMemory || [], null, 2) }\n ],\n execution: { workspace: 'dedicated_worktree' }\n }\n};\nreturn msg;",
|
|
137
|
+
"id": "deep_review_build_freeze",
|
|
138
|
+
"initialize": "",
|
|
139
|
+
"libs": [],
|
|
140
|
+
"name": "build FREEZE task",
|
|
141
|
+
"noerr": 0,
|
|
142
|
+
"outputs": 1,
|
|
143
|
+
"timeout": 0,
|
|
144
|
+
"type": "function",
|
|
145
|
+
"wires": [["deep_review_create_freeze"]],
|
|
146
|
+
"x": 170,
|
|
147
|
+
"y": 180,
|
|
148
|
+
"z": "deep_review_tab"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"agent": "deep_review_agent_cfg",
|
|
152
|
+
"generateCorrelationId": true,
|
|
153
|
+
"id": "deep_review_create_freeze",
|
|
154
|
+
"maxAttempts": 2,
|
|
155
|
+
"name": "FREEZE",
|
|
156
|
+
"runtimeProfile": "deep_review_profile_freeze",
|
|
157
|
+
"type": "moltnet-tasks-create",
|
|
158
|
+
"wires": [["deep_review_wait_freeze"]],
|
|
159
|
+
"x": 400,
|
|
160
|
+
"y": 180,
|
|
161
|
+
"z": "deep_review_tab"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"agent": "deep_review_agent_cfg",
|
|
165
|
+
"id": "deep_review_wait_freeze",
|
|
166
|
+
"intervalMs": 2500,
|
|
167
|
+
"kinds": "",
|
|
168
|
+
"name": "wait FREEZE",
|
|
169
|
+
"tail": true,
|
|
170
|
+
"timeoutSec": 7200,
|
|
171
|
+
"type": "moltnet-task-wait",
|
|
172
|
+
"wires": [["1d29dc178889e4a5"], ["deep_review_stash_freeze_snapshot"]],
|
|
173
|
+
"x": 620,
|
|
174
|
+
"y": 180,
|
|
175
|
+
"z": "deep_review_tab"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"finalize": "",
|
|
179
|
+
"func": "msg.freezeSnapshot = msg.payload;\nreturn msg;",
|
|
180
|
+
"id": "deep_review_stash_freeze_snapshot",
|
|
181
|
+
"initialize": "",
|
|
182
|
+
"libs": [],
|
|
183
|
+
"name": "stash FREEZE snapshot",
|
|
184
|
+
"noerr": 0,
|
|
185
|
+
"outputs": 1,
|
|
186
|
+
"timeout": 0,
|
|
187
|
+
"type": "function",
|
|
188
|
+
"wires": [["deep_review_read_freeze"]],
|
|
189
|
+
"x": 850,
|
|
190
|
+
"y": 200,
|
|
191
|
+
"z": "deep_review_tab"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"agent": "deep_review_agent_cfg",
|
|
195
|
+
"allowMsgTeamOverride": false,
|
|
196
|
+
"cursor": "",
|
|
197
|
+
"id": "deep_review_list_freeze_artifacts",
|
|
198
|
+
"limit": 20,
|
|
199
|
+
"name": "list FREEZE artifacts",
|
|
200
|
+
"taskId": "",
|
|
201
|
+
"teamId": "",
|
|
202
|
+
"type": "moltnet-task-artifacts-list",
|
|
203
|
+
"wires": [["deep_review_select_bundle_artifact"]],
|
|
204
|
+
"x": 740,
|
|
205
|
+
"y": 300,
|
|
206
|
+
"z": "deep_review_tab"
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"finalize": "",
|
|
210
|
+
"func": "const artifacts = Array.isArray(msg.payload)\n ? msg.payload\n : Array.isArray(msg.artifacts?.page?.artifacts)\n ? msg.artifacts.page.artifacts\n : [];\nconst preferred = artifacts.find((artifact) =>\n artifact.title === 'review-bundle' ||\n artifact.title === 'review-bundle.json' ||\n artifact.title === 'review.patch' ||\n artifact.title === 'patch.diff' ||\n artifact.kind === 'review-bundle' ||\n artifact.kind === 'review-patch'\n);\nif (!preferred) {\n node.status({ fill: 'yellow', shape: 'ring', text: `no bundle artifact (${artifacts.length})` });\n return null;\n}\nmsg.payload = { artifact: preferred, cid: preferred.cid };\nmsg.cid = preferred.cid;\nmsg.attemptN = preferred.attemptN;\nmsg.reviewBundleArtifact = preferred;\nreturn msg;",
|
|
211
|
+
"id": "deep_review_select_bundle_artifact",
|
|
212
|
+
"initialize": "",
|
|
213
|
+
"libs": [],
|
|
214
|
+
"name": "select bundle artifact",
|
|
215
|
+
"noerr": 0,
|
|
216
|
+
"outputs": 1,
|
|
217
|
+
"timeout": 0,
|
|
218
|
+
"type": "function",
|
|
219
|
+
"wires": [["deep_review_download_bundle_artifact"]],
|
|
220
|
+
"x": 980,
|
|
221
|
+
"y": 300,
|
|
222
|
+
"z": "deep_review_tab"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"agent": "deep_review_agent_cfg",
|
|
226
|
+
"allowMsgTeamOverride": false,
|
|
227
|
+
"attemptN": "",
|
|
228
|
+
"cid": "",
|
|
229
|
+
"id": "deep_review_download_bundle_artifact",
|
|
230
|
+
"maxBytes": 26214400,
|
|
231
|
+
"name": "download bundle artifact",
|
|
232
|
+
"taskId": "",
|
|
233
|
+
"teamId": "",
|
|
234
|
+
"type": "moltnet-task-artifact-download",
|
|
235
|
+
"wires": [["deep_review_debug_bundle_artifact"]],
|
|
236
|
+
"x": 1230,
|
|
237
|
+
"y": 300,
|
|
238
|
+
"z": "deep_review_tab"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"artifactKind": "json",
|
|
242
|
+
"artifactTitle": "review-bundle",
|
|
243
|
+
"id": "deep_review_read_freeze",
|
|
244
|
+
"name": "read bundle",
|
|
245
|
+
"role": "context",
|
|
246
|
+
"source": "payload",
|
|
247
|
+
"type": "moltnet-task-reader",
|
|
248
|
+
"wires": [["deep_review_stash_bundle"]],
|
|
249
|
+
"x": 1090,
|
|
250
|
+
"y": 200,
|
|
251
|
+
"z": "deep_review_tab"
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"active": true,
|
|
255
|
+
"complete": "artifact",
|
|
256
|
+
"console": false,
|
|
257
|
+
"id": "deep_review_debug_bundle_artifact",
|
|
258
|
+
"name": "downloaded review bundle",
|
|
259
|
+
"statusType": "auto",
|
|
260
|
+
"statusVal": "",
|
|
261
|
+
"targetType": "msg",
|
|
262
|
+
"tosidebar": true,
|
|
263
|
+
"tostatus": false,
|
|
264
|
+
"type": "debug",
|
|
265
|
+
"wires": [],
|
|
266
|
+
"x": 1500,
|
|
267
|
+
"y": 300,
|
|
268
|
+
"z": "deep_review_tab"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"finalize": "",
|
|
272
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || {};\nmsg.reviewBundle = msg.result?.artifactBody || msg.payload || {};\nmsg.reviewBundleRef = msg.result?.artifactRef || msg.result?.outputRef || null;\nmsg.review.freezeTaskId = msg.freezeSnapshot?.taskId || msg.result?.outputRef?.taskId || null;\nmsg.review.freezeAttemptN = msg.freezeSnapshot?.acceptedAttemptN || msg.freezeSnapshot?.attempt?.attemptN || null;\nmsg.taskId = msg.review.freezeTaskId;\nmsg.attemptN = msg.review.freezeAttemptN;\nstate.correlationId = msg.correlationId;\nstate.review = msg.review;\nstate.reviewBundle = msg.reviewBundle;\nstate.reviewBundleRef = msg.reviewBundleRef;\nstate.freezeSnapshot = msg.freezeSnapshot || null;\nstate.tasks = state.tasks || {};\nstate.tasks.freeze = { taskId: msg.review.freezeTaskId, attemptN: msg.review.freezeAttemptN };\nstate.specialistResults = state.specialistResults || [];\nflow.set(key, state);\nmsg.reviewState = state;\nreturn msg;",
|
|
273
|
+
"id": "deep_review_stash_bundle",
|
|
274
|
+
"initialize": "",
|
|
275
|
+
"libs": [],
|
|
276
|
+
"name": "stash bundle ref/body",
|
|
277
|
+
"noerr": 0,
|
|
278
|
+
"outputs": 1,
|
|
279
|
+
"timeout": 0,
|
|
280
|
+
"type": "function",
|
|
281
|
+
"wires": [
|
|
282
|
+
["deep_review_build_preflight", "deep_review_list_freeze_artifacts"]
|
|
283
|
+
],
|
|
284
|
+
"x": 1320,
|
|
285
|
+
"y": 200,
|
|
286
|
+
"z": "deep_review_tab"
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"finalize": "",
|
|
290
|
+
"func": "msg.payload = {\n taskType: 'freeform',\n title: 'Deep review: preflight',\n tags: ['deep-review', 'deep-review:preflight', msg.review.workflow],\n correlationId: msg.correlationId,\n input: {\n brief: [\n 'Run the design preflight for this deep review.',\n '',\n 'Decide whether the approach is sound before line-level review.',\n 'Return a freeform artifact with kind \"json\" and title \"preflight\".',\n '',\n 'The artifact body must be JSON:',\n '{ \"verdict\": \"PROCEED|PIVOT|ASK\", \"summary\": \"...\", \"questions\": [], \"pivotSize\": \"small|medium|large|null\", \"recommendedNextStep\": \"...\" }',\n '',\n 'PIVOT only when the approach is materially wrong, not when you merely prefer another implementation.',\n '',\n 'If the submit tool requires a verification block, every verification.results[].kind must be one of: gate, assertion, rubric, sideEffect. For a submit-tool-call success criterion, report it as kind \"gate\"; never use \"submit-tool-call\" as a verification result kind.'\n ].join('\\n'),\n expectedOutput: 'Summary plus artifact kind=json title=preflight.',\n constraints: ['Do not produce line-level findings.', 'Do not modify code.', 'When self-verifying a submit-tool-call gate, use verification result kind \"gate\".'],\n context: [\n { slug: 'review-config', binding: 'context_inline', content: JSON.stringify(msg.review, null, 2) },\n { slug: 'review-bundle', binding: 'context_inline', content: JSON.stringify(msg.reviewBundle, null, 2) },\n { slug: 'review-bundle-ref', binding: 'context_inline', content: JSON.stringify(msg.reviewBundleRef, null, 2) }\n ],\n execution: { workspace: 'shared_mount' }\n }\n};\nreturn msg;",
|
|
291
|
+
"id": "deep_review_build_preflight",
|
|
292
|
+
"initialize": "",
|
|
293
|
+
"libs": [],
|
|
294
|
+
"name": "build PREFLIGHT task",
|
|
295
|
+
"noerr": 0,
|
|
296
|
+
"outputs": 1,
|
|
297
|
+
"timeout": 0,
|
|
298
|
+
"type": "function",
|
|
299
|
+
"wires": [["deep_review_create_preflight"]],
|
|
300
|
+
"x": 200,
|
|
301
|
+
"y": 500,
|
|
302
|
+
"z": "deep_review_tab"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"agent": "deep_review_agent_cfg",
|
|
306
|
+
"generateCorrelationId": false,
|
|
307
|
+
"id": "deep_review_create_preflight",
|
|
308
|
+
"maxAttempts": 2,
|
|
309
|
+
"name": "PREFLIGHT",
|
|
310
|
+
"runtimeProfile": "deep_review_profile_preflight",
|
|
311
|
+
"type": "moltnet-tasks-create",
|
|
312
|
+
"wires": [["deep_review_wait_preflight"]],
|
|
313
|
+
"x": 440,
|
|
314
|
+
"y": 500,
|
|
315
|
+
"z": "deep_review_tab"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"agent": "deep_review_agent_cfg",
|
|
319
|
+
"id": "deep_review_wait_preflight",
|
|
320
|
+
"intervalMs": 2500,
|
|
321
|
+
"kinds": "",
|
|
322
|
+
"name": "wait PREFLIGHT",
|
|
323
|
+
"tail": true,
|
|
324
|
+
"timeoutSec": 7200,
|
|
325
|
+
"type": "moltnet-task-wait",
|
|
326
|
+
"wires": [["deep_review_tail_link_out"], ["deep_review_read_preflight"]],
|
|
327
|
+
"x": 680,
|
|
328
|
+
"y": 500,
|
|
329
|
+
"z": "deep_review_tab"
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
"artifactKind": "json",
|
|
333
|
+
"artifactTitle": "preflight",
|
|
334
|
+
"id": "deep_review_read_preflight",
|
|
335
|
+
"name": "read preflight",
|
|
336
|
+
"role": "context",
|
|
337
|
+
"source": "payload",
|
|
338
|
+
"type": "moltnet-task-reader",
|
|
339
|
+
"wires": [["deep_review_stash_preflight"]],
|
|
340
|
+
"x": 920,
|
|
341
|
+
"y": 500,
|
|
342
|
+
"z": "deep_review_tab"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"finalize": "",
|
|
346
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || {};\nmsg.preflight = msg.result?.artifactBody || msg.payload || {};\nmsg.preflight.verdict = String(msg.preflight.verdict || 'ASK').toUpperCase();\nstate.correlationId = msg.correlationId;\nstate.review = state.review || msg.review;\nstate.reviewBundle = state.reviewBundle || msg.reviewBundle;\nstate.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nstate.preflight = msg.preflight;\nstate.preflightRef = msg.result?.artifactRef || msg.result?.outputRef || null;\nstate.tasks = state.tasks || {};\nstate.tasks.preflight = { taskId: msg.result?.outputRef?.taskId || msg.payload?.taskId || null };\nflow.set(key, state);\nmsg.reviewState = state;\nreturn msg;",
|
|
347
|
+
"id": "deep_review_stash_preflight",
|
|
348
|
+
"initialize": "",
|
|
349
|
+
"libs": [],
|
|
350
|
+
"name": "stash preflight",
|
|
351
|
+
"noerr": 0,
|
|
352
|
+
"outputs": 1,
|
|
353
|
+
"timeout": 0,
|
|
354
|
+
"type": "function",
|
|
355
|
+
"wires": [["deep_review_switch_preflight"]],
|
|
356
|
+
"x": 1140,
|
|
357
|
+
"y": 500,
|
|
358
|
+
"z": "deep_review_tab"
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"checkall": "true",
|
|
362
|
+
"id": "deep_review_switch_preflight",
|
|
363
|
+
"name": "preflight verdict",
|
|
364
|
+
"outputs": 4,
|
|
365
|
+
"property": "preflight.verdict",
|
|
366
|
+
"propertyType": "msg",
|
|
367
|
+
"repair": false,
|
|
368
|
+
"rules": [
|
|
369
|
+
{
|
|
370
|
+
"t": "eq",
|
|
371
|
+
"v": "ASK",
|
|
372
|
+
"vt": "str"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"t": "eq",
|
|
376
|
+
"v": "PIVOT",
|
|
377
|
+
"vt": "str"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"t": "eq",
|
|
381
|
+
"v": "PROCEED",
|
|
382
|
+
"vt": "str"
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
"t": "else"
|
|
386
|
+
}
|
|
387
|
+
],
|
|
388
|
+
"type": "switch",
|
|
389
|
+
"wires": [
|
|
390
|
+
["deep_review_debug_ask"],
|
|
391
|
+
["deep_review_build_pivot_publish"],
|
|
392
|
+
["deep_review_dimensions_payload"],
|
|
393
|
+
["deep_review_debug_ask"]
|
|
394
|
+
],
|
|
395
|
+
"x": 200,
|
|
396
|
+
"y": 660,
|
|
397
|
+
"z": "deep_review_tab"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"finalize": "",
|
|
401
|
+
"func": "msg.payload = {\n taskType: 'freeform',\n title: 'Deep review: publish pivot report',\n tags: ['deep-review', 'deep-review:pivot', msg.review.workflow],\n correlationId: msg.correlationId,\n input: {\n brief: 'Prepare the preflight PIVOT result as a final design review artifact. Do not add line-level findings. If publishPolicy is not none and required credentials/tools are available, publish according to policy; otherwise only return the artifact. If the submit tool requires verification, use verification result kind \"gate\" for any submit-tool-call success criterion; never use \"submit-tool-call\" as verification.results[].kind.',\n expectedOutput: 'Summary plus artifact kind=markdown title=design-review.',\n constraints: ['When self-verifying a submit-tool-call gate, use verification result kind \"gate\".'],\n context: [\n { slug: 'review-config', binding: 'context_inline', content: JSON.stringify(msg.review, null, 2) },\n { slug: 'review-bundle', binding: 'context_inline', content: JSON.stringify(msg.reviewBundle, null, 2) },\n { slug: 'preflight', binding: 'context_inline', content: JSON.stringify(msg.preflight, null, 2) }\n ],\n execution: { workspace: 'none' }\n }\n};\nreturn msg;",
|
|
402
|
+
"id": "deep_review_build_pivot_publish",
|
|
403
|
+
"initialize": "",
|
|
404
|
+
"libs": [],
|
|
405
|
+
"name": "build PIVOT publish task",
|
|
406
|
+
"noerr": 0,
|
|
407
|
+
"outputs": 1,
|
|
408
|
+
"timeout": 0,
|
|
409
|
+
"type": "function",
|
|
410
|
+
"wires": [["deep_review_create_pivot_publish"]],
|
|
411
|
+
"x": 460,
|
|
412
|
+
"y": 640,
|
|
413
|
+
"z": "deep_review_tab"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"agent": "deep_review_agent_cfg",
|
|
417
|
+
"generateCorrelationId": false,
|
|
418
|
+
"id": "deep_review_create_pivot_publish",
|
|
419
|
+
"maxAttempts": 2,
|
|
420
|
+
"name": "PUBLISH PIVOT",
|
|
421
|
+
"runtimeProfile": "deep_review_profile_aggregate",
|
|
422
|
+
"type": "moltnet-tasks-create",
|
|
423
|
+
"wires": [["deep_review_wait_pivot_publish"]],
|
|
424
|
+
"x": 740,
|
|
425
|
+
"y": 640,
|
|
426
|
+
"z": "deep_review_tab"
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"agent": "deep_review_agent_cfg",
|
|
430
|
+
"id": "deep_review_wait_pivot_publish",
|
|
431
|
+
"intervalMs": 2500,
|
|
432
|
+
"kinds": "",
|
|
433
|
+
"name": "wait PIVOT",
|
|
434
|
+
"tail": true,
|
|
435
|
+
"timeoutSec": 7200,
|
|
436
|
+
"type": "moltnet-task-wait",
|
|
437
|
+
"wires": [["d673ff9b232453fe"], ["deep_review_pivot_done_link_out"]],
|
|
438
|
+
"x": 1000,
|
|
439
|
+
"y": 640,
|
|
440
|
+
"z": "deep_review_tab"
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
"finalize": "",
|
|
444
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || {};\nstate.correlationId = msg.correlationId;\nstate.review = state.review || msg.review;\nstate.reviewBundle = state.reviewBundle || msg.reviewBundle;\nstate.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nstate.preflight = state.preflight || msg.preflight;\nstate.dimensions = [...((state.review || msg.review).dimensions || [])];\nstate.pendingDimensions = [];\nstate.expectedSpecialists = state.dimensions.length;\nstate.completedSpecialists = 0;\nstate.aggregateStarted = false;\nstate.specialistResults = [];\nstate.tasks = state.tasks || {};\nstate.tasks.specialists = {};\nflow.set(key, state);\nmsg.reviewState = state;\nmsg.pendingDimensions = [];\nmsg.specialistResults = state.specialistResults;\nif (state.dimensions.length === 0) {\n node.status({ fill: 'yellow', shape: 'ring', text: 'no dimensions' });\n return [null, msg];\n}\nnode.status({ fill: 'blue', shape: 'dot', text: `fan out ${state.dimensions.length}` });\nconst messages = state.dimensions.map((dimension, index) => ({\n ...msg,\n reviewDimension: dimension,\n payload: { dimension, index, total: state.dimensions.length }\n}));\nreturn [messages, null];",
|
|
445
|
+
"id": "deep_review_dimensions_payload",
|
|
446
|
+
"initialize": "",
|
|
447
|
+
"libs": [],
|
|
448
|
+
"name": "init specialist fanout",
|
|
449
|
+
"noerr": 0,
|
|
450
|
+
"outputs": 2,
|
|
451
|
+
"timeout": 0,
|
|
452
|
+
"type": "function",
|
|
453
|
+
"wires": [
|
|
454
|
+
["deep_review_build_specialist"],
|
|
455
|
+
["deep_review_build_aggregate"]
|
|
456
|
+
],
|
|
457
|
+
"x": 440,
|
|
458
|
+
"y": 720,
|
|
459
|
+
"z": "deep_review_tab"
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"finalize": "",
|
|
463
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || msg.reviewState || {};\nconst expected = Number(state.expectedSpecialists || state.dimensions?.length || 0);\nconst completed = Array.isArray(state.specialistResults) ? state.specialistResults.length : 0;\nstate.completedSpecialists = completed;\nflow.set(key, state);\nmsg.reviewState = state;\nmsg.review = state.review || msg.review;\nmsg.reviewBundle = state.reviewBundle || msg.reviewBundle;\nmsg.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nmsg.preflight = state.preflight || msg.preflight;\nmsg.specialistResults = state.specialistResults || [];\nmsg.pendingDimensions = [];\nif (expected === 0) {\n node.status({ fill: 'yellow', shape: 'ring', text: 'no specialist dimensions' });\n return msg;\n}\nif (completed < expected) {\n node.status({ fill: 'blue', shape: 'dot', text: `${completed}/${expected} specialist(s)` });\n return null;\n}\nif (state.aggregateStarted) {\n node.status({ fill: 'grey', shape: 'ring', text: 'aggregate already started' });\n return null;\n}\nstate.aggregateStarted = true;\nstate.aggregateReadyAt = new Date().toISOString();\nflow.set(key, state);\nmsg.reviewState = state;\nnode.status({ fill: 'green', shape: 'dot', text: `${completed}/${expected} complete` });\nreturn msg;",
|
|
464
|
+
"id": "deep_review_next_dimension",
|
|
465
|
+
"initialize": "",
|
|
466
|
+
"libs": [],
|
|
467
|
+
"name": "aggregate when complete",
|
|
468
|
+
"noerr": 0,
|
|
469
|
+
"outputs": 1,
|
|
470
|
+
"timeout": 0,
|
|
471
|
+
"type": "function",
|
|
472
|
+
"wires": [["deep_review_build_aggregate"]],
|
|
473
|
+
"x": 540,
|
|
474
|
+
"y": 820,
|
|
475
|
+
"z": "deep_review_tab"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"finalize": "",
|
|
479
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || msg.reviewState || {};\nconst dimension = msg.payload.dimension || state.currentDimension;\nmsg.reviewDimension = dimension;\nmsg.review = state.review || msg.review;\nmsg.reviewBundle = state.reviewBundle || msg.reviewBundle;\nmsg.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nmsg.preflight = state.preflight || msg.preflight;\nmsg.payload = {\n taskType: 'freeform',\n title: 'Deep review: ' + dimension,\n tags: ['deep-review', 'deep-review:specialist', 'dimension:' + dimension, msg.review.workflow],\n correlationId: msg.correlationId,\n input: {\n brief: [\n 'Run one specialist pass for a deep review workflow.',\n '',\n 'Dimension: ' + dimension,\n '',\n 'Use only this lens. Ignore unrelated concerns, formatter/lint noise, and personal preference.',\n 'Read the review bundle and inspect surrounding code as needed. If artifact download tools are available, use the bundle CIDs for the patch/file list. Otherwise use the inline bundle metadata to fetch the same target.',\n '',\n 'Return a freeform artifact with kind \"json\" and title \"specialist-findings\". The body must be JSON with fields: dimension, findings, clean, coverageNotes.',\n 'Each finding must include: severity, path, line, problem, why, fixDirection.',\n '',\n 'If the submit tool requires a verification block, every verification.results[].kind must be one of: gate, assertion, rubric, sideEffect. For a submit-tool-call success criterion, report it as kind \"gate\"; never use \"submit-tool-call\" as a verification result kind.'\n ].join('\\n'),\n expectedOutput: 'Summary plus artifact kind=json title=specialist-findings.',\n constraints: ['Do not modify code.', 'Findings only; no broad summary unless clean.', 'When self-verifying a submit-tool-call gate, use verification result kind \"gate\".'],\n context: [\n { slug: 'review-config', binding: 'context_inline', content: JSON.stringify(msg.review, null, 2) },\n { slug: 'review-bundle', binding: 'context_inline', content: JSON.stringify(msg.reviewBundle, null, 2) },\n { slug: 'review-bundle-ref', binding: 'context_inline', content: JSON.stringify(msg.reviewBundleRef, null, 2) },\n { slug: 'preflight', binding: 'context_inline', content: JSON.stringify(msg.preflight, null, 2) }\n ],\n execution: { workspace: 'shared_mount' }\n }\n};\nreturn msg;",
|
|
480
|
+
"id": "deep_review_build_specialist",
|
|
481
|
+
"initialize": "",
|
|
482
|
+
"libs": [],
|
|
483
|
+
"name": "build SPECIALIST task",
|
|
484
|
+
"noerr": 0,
|
|
485
|
+
"outputs": 1,
|
|
486
|
+
"timeout": 0,
|
|
487
|
+
"type": "function",
|
|
488
|
+
"wires": [["deep_review_create_specialist"]],
|
|
489
|
+
"x": 770,
|
|
490
|
+
"y": 720,
|
|
491
|
+
"z": "deep_review_tab"
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"agent": "deep_review_agent_cfg",
|
|
495
|
+
"generateCorrelationId": false,
|
|
496
|
+
"id": "deep_review_create_specialist",
|
|
497
|
+
"maxAttempts": 2,
|
|
498
|
+
"name": "SPECIALIST",
|
|
499
|
+
"runtimeProfile": "deep_review_profile_specialist",
|
|
500
|
+
"type": "moltnet-tasks-create",
|
|
501
|
+
"wires": [["deep_review_wait_specialist"]],
|
|
502
|
+
"x": 1010,
|
|
503
|
+
"y": 720,
|
|
504
|
+
"z": "deep_review_tab"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"agent": "deep_review_agent_cfg",
|
|
508
|
+
"id": "deep_review_wait_specialist",
|
|
509
|
+
"intervalMs": 2500,
|
|
510
|
+
"kinds": "",
|
|
511
|
+
"name": "wait SPECIALIST",
|
|
512
|
+
"tail": true,
|
|
513
|
+
"timeoutSec": 7200,
|
|
514
|
+
"type": "moltnet-task-wait",
|
|
515
|
+
"wires": [["cceba4a8c3d9aafd"], ["deep_review_read_specialist"]],
|
|
516
|
+
"x": 1250,
|
|
517
|
+
"y": 720,
|
|
518
|
+
"z": "deep_review_tab"
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
"artifactKind": "json",
|
|
522
|
+
"artifactTitle": "specialist-findings",
|
|
523
|
+
"id": "deep_review_read_specialist",
|
|
524
|
+
"name": "read specialist",
|
|
525
|
+
"role": "context",
|
|
526
|
+
"source": "payload",
|
|
527
|
+
"type": "moltnet-task-reader",
|
|
528
|
+
"wires": [["deep_review_pack_specialist"]],
|
|
529
|
+
"x": 1480,
|
|
530
|
+
"y": 720,
|
|
531
|
+
"z": "deep_review_tab"
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
"finalize": "",
|
|
535
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || msg.reviewState || {};\nconst result = {\n dimension: msg.reviewDimension || msg.payload?.dimension || state.currentDimension,\n output: msg.payload,\n artifact: msg.result?.artifact || null,\n artifactBody: msg.result?.artifactBody || null,\n artifactRef: msg.result?.artifactRef || null,\n outputRef: msg.result?.outputRef || null\n};\nstate.specialistResults = Array.isArray(state.specialistResults) ? state.specialistResults : [];\nstate.specialistResults = state.specialistResults.filter((item) => item.dimension !== result.dimension);\nstate.specialistResults.push(result);\nstate.tasks = state.tasks || {};\nstate.tasks.specialists = state.tasks.specialists || {};\nstate.tasks.specialists[result.dimension] = {\n taskId: result.outputRef?.taskId || msg.payload?.id || null,\n outputCid: result.outputRef?.outputCid || null,\n artifactCid: result.artifactRef?.artifactCid || result.artifact?.cid || null\n};\nstate.completedSpecialists = state.specialistResults.length;\nflow.set(key, state);\nmsg.reviewState = state;\nmsg.review = state.review || msg.review;\nmsg.reviewBundle = state.reviewBundle || msg.reviewBundle;\nmsg.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nmsg.preflight = state.preflight || msg.preflight;\nmsg.specialistResults = state.specialistResults;\nmsg.pendingDimensions = [];\nmsg.payload = null;\nreturn msg;",
|
|
536
|
+
"id": "deep_review_pack_specialist",
|
|
537
|
+
"initialize": "",
|
|
538
|
+
"libs": [],
|
|
539
|
+
"name": "pack specialist + gate",
|
|
540
|
+
"noerr": 0,
|
|
541
|
+
"outputs": 1,
|
|
542
|
+
"timeout": 0,
|
|
543
|
+
"type": "function",
|
|
544
|
+
"wires": [["deep_review_next_dimension"]],
|
|
545
|
+
"x": 1710,
|
|
546
|
+
"y": 720,
|
|
547
|
+
"z": "deep_review_tab"
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"id": "deep_review_specialist_error_catch",
|
|
551
|
+
"name": "SPECIALIST errors",
|
|
552
|
+
"scope": [
|
|
553
|
+
"deep_review_create_specialist",
|
|
554
|
+
"deep_review_wait_specialist",
|
|
555
|
+
"deep_review_read_specialist"
|
|
556
|
+
],
|
|
557
|
+
"type": "catch",
|
|
558
|
+
"uncaught": false,
|
|
559
|
+
"wires": [["deep_review_pack_specialist_error"]],
|
|
560
|
+
"x": 1490,
|
|
561
|
+
"y": 780,
|
|
562
|
+
"z": "deep_review_tab"
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
"finalize": "",
|
|
566
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || msg.reviewState || {};\nconst payload = msg.payload && typeof msg.payload === 'object' ? msg.payload : {};\nconst tags = Array.isArray(payload.tags) ? payload.tags : [];\nconst dimensionTag = tags.find((tag) => typeof tag === 'string' && tag.startsWith('dimension:'));\nconst dimension = msg.reviewDimension || payload.dimension || (typeof dimensionTag === 'string' ? dimensionTag.slice('dimension:'.length) : null);\nif (!dimension) {\n node.status({ fill: 'red', shape: 'ring', text: 'missing dimension' });\n return null;\n}\nconst error = msg.error || {};\nconst result = {\n dimension,\n status: 'failed',\n output: null,\n artifact: null,\n artifactBody: {\n dimension,\n findings: [],\n clean: false,\n coverageNotes: 'Specialist task failed before readable findings were available.',\n failed: true,\n error: {\n message: String(error.message || 'specialist lane failed'),\n source: error.source || null\n }\n },\n artifactRef: null,\n outputRef: null,\n error: {\n message: String(error.message || 'specialist lane failed'),\n source: error.source || null\n }\n};\nstate.specialistResults = Array.isArray(state.specialistResults) ? state.specialistResults : [];\nstate.specialistResults = state.specialistResults.filter((item) => item.dimension !== dimension);\nstate.specialistResults.push(result);\nstate.tasks = state.tasks || {};\nstate.tasks.specialists = state.tasks.specialists || {};\nstate.tasks.specialists[dimension] = {\n status: 'failed',\n taskId: payload.id || null,\n error: result.error\n};\nstate.completedSpecialists = state.specialistResults.length;\nflow.set(key, state);\nmsg.reviewState = state;\nmsg.review = state.review || msg.review;\nmsg.reviewBundle = state.reviewBundle || msg.reviewBundle;\nmsg.reviewBundleRef = state.reviewBundleRef || msg.reviewBundleRef;\nmsg.preflight = state.preflight || msg.preflight;\nmsg.specialistResults = state.specialistResults;\nmsg.pendingDimensions = [];\nmsg.payload = null;\nnode.status({ fill: 'yellow', shape: 'ring', text: `${dimension} failed` });\nreturn msg;",
|
|
567
|
+
"id": "deep_review_pack_specialist_error",
|
|
568
|
+
"initialize": "",
|
|
569
|
+
"libs": [],
|
|
570
|
+
"name": "pack specialist failure + gate",
|
|
571
|
+
"noerr": 0,
|
|
572
|
+
"outputs": 1,
|
|
573
|
+
"timeout": 0,
|
|
574
|
+
"type": "function",
|
|
575
|
+
"wires": [["deep_review_next_dimension"]],
|
|
576
|
+
"x": 1750,
|
|
577
|
+
"y": 780,
|
|
578
|
+
"z": "deep_review_tab"
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"finalize": "",
|
|
582
|
+
"func": "const key = 'deepReview:' + msg.correlationId;\nconst state = flow.get(key) || msg.reviewState || {};\nmsg.review = state.review || msg.review;\nmsg.reviewBundle = state.reviewBundle || msg.reviewBundle;\nmsg.preflight = state.preflight || msg.preflight;\nmsg.specialistResults = state.specialistResults || msg.specialistResults || [];\nstate.aggregateRequestedAt = new Date().toISOString();\nflow.set(key, state);\nmsg.reviewState = state;\nmsg.payload = {\n taskType: 'freeform',\n title: 'Deep review: aggregate findings',\n tags: ['deep-review', 'deep-review:aggregate', msg.review.workflow],\n correlationId: msg.correlationId,\n input: {\n brief: [\n 'Aggregate the specialist deep-review results into one final review.',\n '',\n 'Dedupe findings, keep the highest severity, rank globally, surface themes, and check whether any changed files in the review bundle were not covered.',\n '',\n 'Some specialist results may have status \"failed\" with an error instead of findings. Treat those as coverage gaps, include them in the final review summary, and do not invent findings for failed dimensions.',\n '',\n 'Return a freeform artifact with kind \"markdown\" and title \"final-review\". Also include a compact kind \"json\" artifact titled \"review-summary\" with fields: verdict, topRisks, findingCounts, coverage.',\n '',\n 'If the submit tool requires a verification block, every verification.results[].kind must be one of: gate, assertion, rubric, sideEffect. For a submit-tool-call success criterion, report it as kind \"gate\"; never use \"submit-tool-call\" as a verification result kind.'\n ].join('\\n'),\n expectedOutput: 'Summary plus artifacts markdown/final-review and json/review-summary.',\n constraints: ['Do not modify code.', 'Do not publish externally unless publishPolicy requires a separate publish task.', 'When self-verifying a submit-tool-call gate, use verification result kind \"gate\".'],\n context: [\n { slug: 'review-config', binding: 'context_inline', content: JSON.stringify(msg.review, null, 2) },\n { slug: 'review-bundle', binding: 'context_inline', content: JSON.stringify(msg.reviewBundle, null, 2) },\n { slug: 'preflight', binding: 'context_inline', content: JSON.stringify(msg.preflight, null, 2) },\n { slug: 'specialist-results', binding: 'context_inline', content: JSON.stringify(msg.specialistResults, null, 2) },\n { slug: 'review-run-state', binding: 'context_inline', content: JSON.stringify({ correlationId: state.correlationId, tasks: state.tasks, dimensions: state.dimensions }, null, 2) }\n ],\n execution: { workspace: 'none' }\n }\n};\nreturn msg;",
|
|
583
|
+
"id": "deep_review_build_aggregate",
|
|
584
|
+
"initialize": "",
|
|
585
|
+
"libs": [],
|
|
586
|
+
"name": "build AGGREGATE task",
|
|
587
|
+
"noerr": 0,
|
|
588
|
+
"outputs": 1,
|
|
589
|
+
"timeout": 0,
|
|
590
|
+
"type": "function",
|
|
591
|
+
"wires": [["deep_review_create_aggregate"]],
|
|
592
|
+
"x": 840,
|
|
593
|
+
"y": 820,
|
|
594
|
+
"z": "deep_review_tab"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"agent": "deep_review_agent_cfg",
|
|
598
|
+
"generateCorrelationId": false,
|
|
599
|
+
"id": "deep_review_create_aggregate",
|
|
600
|
+
"maxAttempts": 2,
|
|
601
|
+
"name": "AGGREGATE",
|
|
602
|
+
"runtimeProfile": "deep_review_profile_aggregate",
|
|
603
|
+
"type": "moltnet-tasks-create",
|
|
604
|
+
"wires": [["deep_review_wait_aggregate"]],
|
|
605
|
+
"x": 1100,
|
|
606
|
+
"y": 820,
|
|
607
|
+
"z": "deep_review_tab"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"agent": "deep_review_agent_cfg",
|
|
611
|
+
"id": "deep_review_wait_aggregate",
|
|
612
|
+
"intervalMs": 2500,
|
|
613
|
+
"kinds": "",
|
|
614
|
+
"name": "wait AGGREGATE",
|
|
615
|
+
"tail": true,
|
|
616
|
+
"timeoutSec": 7200,
|
|
617
|
+
"type": "moltnet-task-wait",
|
|
618
|
+
"wires": [["3ac746883d75229d"], ["deep_review_aggregate_done_link_out"]],
|
|
619
|
+
"x": 1340,
|
|
620
|
+
"y": 820,
|
|
621
|
+
"z": "deep_review_tab"
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
"active": true,
|
|
625
|
+
"complete": "preflight",
|
|
626
|
+
"console": false,
|
|
627
|
+
"id": "deep_review_debug_ask",
|
|
628
|
+
"name": "needs human input",
|
|
629
|
+
"statusType": "auto",
|
|
630
|
+
"statusVal": "",
|
|
631
|
+
"targetType": "msg",
|
|
632
|
+
"tosidebar": true,
|
|
633
|
+
"tostatus": false,
|
|
634
|
+
"type": "debug",
|
|
635
|
+
"wires": [],
|
|
636
|
+
"x": 460,
|
|
637
|
+
"y": 580,
|
|
638
|
+
"z": "deep_review_tab"
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "deep_review_tail_link_out",
|
|
642
|
+
"links": ["deep_review_tail_link_in"],
|
|
643
|
+
"mode": "link",
|
|
644
|
+
"name": "tail events",
|
|
645
|
+
"type": "link out",
|
|
646
|
+
"wires": [],
|
|
647
|
+
"x": 855,
|
|
648
|
+
"y": 440,
|
|
649
|
+
"z": "deep_review_tab"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
"id": "deep_review_tail_link_in",
|
|
653
|
+
"links": [
|
|
654
|
+
"deep_review_tail_link_out",
|
|
655
|
+
"1d29dc178889e4a5",
|
|
656
|
+
"3ac746883d75229d",
|
|
657
|
+
"cceba4a8c3d9aafd",
|
|
658
|
+
"d673ff9b232453fe"
|
|
659
|
+
],
|
|
660
|
+
"name": "tail events",
|
|
661
|
+
"type": "link in",
|
|
662
|
+
"wires": [["deep_review_tail"]],
|
|
663
|
+
"x": 215,
|
|
664
|
+
"y": 960,
|
|
665
|
+
"z": "deep_review_tab"
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
"active": true,
|
|
669
|
+
"complete": "payload",
|
|
670
|
+
"console": false,
|
|
671
|
+
"id": "deep_review_tail",
|
|
672
|
+
"name": "task tail",
|
|
673
|
+
"statusType": "auto",
|
|
674
|
+
"statusVal": "",
|
|
675
|
+
"targetType": "msg",
|
|
676
|
+
"tosidebar": true,
|
|
677
|
+
"tostatus": false,
|
|
678
|
+
"type": "debug",
|
|
679
|
+
"wires": [],
|
|
680
|
+
"x": 360,
|
|
681
|
+
"y": 960,
|
|
682
|
+
"z": "deep_review_tab"
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
"active": true,
|
|
686
|
+
"complete": "payload",
|
|
687
|
+
"console": false,
|
|
688
|
+
"id": "deep_review_done",
|
|
689
|
+
"name": "review done",
|
|
690
|
+
"statusType": "auto",
|
|
691
|
+
"statusVal": "",
|
|
692
|
+
"targetType": "msg",
|
|
693
|
+
"tosidebar": true,
|
|
694
|
+
"tostatus": false,
|
|
695
|
+
"type": "debug",
|
|
696
|
+
"wires": [],
|
|
697
|
+
"x": 370,
|
|
698
|
+
"y": 1080,
|
|
699
|
+
"z": "deep_review_tab"
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
"id": "1d29dc178889e4a5",
|
|
703
|
+
"links": ["deep_review_tail_link_in"],
|
|
704
|
+
"mode": "link",
|
|
705
|
+
"name": "tail events",
|
|
706
|
+
"type": "link out",
|
|
707
|
+
"wires": [],
|
|
708
|
+
"x": 755,
|
|
709
|
+
"y": 140,
|
|
710
|
+
"z": "deep_review_tab"
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"id": "3ac746883d75229d",
|
|
714
|
+
"links": ["deep_review_tail_link_in"],
|
|
715
|
+
"mode": "link",
|
|
716
|
+
"name": "tail events",
|
|
717
|
+
"type": "link out",
|
|
718
|
+
"wires": [],
|
|
719
|
+
"x": 1575,
|
|
720
|
+
"y": 780,
|
|
721
|
+
"z": "deep_review_tab"
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"id": "cceba4a8c3d9aafd",
|
|
725
|
+
"links": ["deep_review_tail_link_in"],
|
|
726
|
+
"mode": "link",
|
|
727
|
+
"name": "tail events",
|
|
728
|
+
"type": "link out",
|
|
729
|
+
"wires": [],
|
|
730
|
+
"x": 1435,
|
|
731
|
+
"y": 680,
|
|
732
|
+
"z": "deep_review_tab"
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
"id": "d673ff9b232453fe",
|
|
736
|
+
"links": ["deep_review_tail_link_in"],
|
|
737
|
+
"mode": "link",
|
|
738
|
+
"name": "tail events",
|
|
739
|
+
"type": "link out",
|
|
740
|
+
"wires": [],
|
|
741
|
+
"x": 1145,
|
|
742
|
+
"y": 600,
|
|
743
|
+
"z": "deep_review_tab"
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
"id": "deep_review_done_link_in",
|
|
747
|
+
"links": [
|
|
748
|
+
"deep_review_pivot_done_link_out",
|
|
749
|
+
"deep_review_aggregate_done_link_out"
|
|
750
|
+
],
|
|
751
|
+
"name": "review done in",
|
|
752
|
+
"type": "link in",
|
|
753
|
+
"wires": [["deep_review_done"]],
|
|
754
|
+
"x": 215,
|
|
755
|
+
"y": 1080,
|
|
756
|
+
"z": "deep_review_tab"
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
"id": "deep_review_pivot_done_link_out",
|
|
760
|
+
"links": ["deep_review_done_link_in"],
|
|
761
|
+
"mode": "link",
|
|
762
|
+
"name": "review done out",
|
|
763
|
+
"type": "link out",
|
|
764
|
+
"wires": [],
|
|
765
|
+
"x": 1145,
|
|
766
|
+
"y": 660,
|
|
767
|
+
"z": "deep_review_tab"
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
"id": "deep_review_aggregate_done_link_out",
|
|
771
|
+
"links": ["deep_review_done_link_in"],
|
|
772
|
+
"mode": "link",
|
|
773
|
+
"name": "review done out",
|
|
774
|
+
"type": "link out",
|
|
775
|
+
"wires": [],
|
|
776
|
+
"x": 1575,
|
|
777
|
+
"y": 840,
|
|
778
|
+
"z": "deep_review_tab"
|
|
779
|
+
}
|
|
780
|
+
]
|