@agwab/pi-workflow 0.2.1 → 0.4.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 +3 -1
- package/dist/artifact-graph-runtime.d.ts +1 -1
- package/dist/artifact-graph-runtime.js +10 -5
- package/dist/artifact-graph-schema.js +127 -5
- package/dist/compiler.js +52 -19
- package/dist/dynamic-generated-task-runtime.js +3 -1
- package/dist/dynamic-profiles.d.ts +1 -1
- package/dist/engine-run-graph.d.ts +3 -0
- package/dist/engine-run-graph.js +194 -4
- package/dist/engine.d.ts +5 -0
- package/dist/engine.js +389 -41
- package/dist/extension.d.ts +2 -1
- package/dist/extension.js +30 -8
- package/dist/index.d.ts +11 -3
- package/dist/index.js +6 -1
- package/dist/prompt-json.d.ts +7 -0
- package/dist/prompt-json.js +13 -0
- package/dist/roles.d.ts +1 -1
- package/dist/roles.js +5 -8
- package/dist/store.d.ts +20 -1
- package/dist/store.js +139 -35
- package/dist/strings.d.ts +11 -0
- package/dist/strings.js +24 -0
- package/dist/subagent-backend.js +710 -40
- package/dist/types.d.ts +107 -1
- package/dist/verification-ontology.d.ts +31 -0
- package/dist/verification-ontology.js +66 -0
- package/dist/workflow-artifact-tool.js +5 -6
- package/dist/workflow-artifacts.d.ts +7 -0
- package/dist/workflow-artifacts.js +55 -4
- package/dist/workflow-fetch-cache-extension.d.ts +1 -0
- package/dist/workflow-fetch-cache-extension.js +57 -9
- package/dist/workflow-metrics.d.ts +113 -0
- package/dist/workflow-metrics.js +272 -0
- package/dist/workflow-output-artifacts.js +5 -3
- package/dist/workflow-partial-output.d.ts +45 -0
- package/dist/workflow-partial-output.js +205 -0
- package/dist/workflow-progress-health.js +42 -10
- package/dist/workflow-runtime.js +10 -1
- package/dist/workflow-view.js +3 -1
- package/dist/workflow-web-source-extension.js +194 -52
- package/dist/workflow-web-source.d.ts +2 -1
- package/dist/workflow-web-source.js +109 -30
- package/docs/usage.md +76 -29
- package/node_modules/@agwab/pi-subagent/README.md +3 -3
- package/node_modules/@agwab/pi-subagent/api.mjs +1 -0
- package/node_modules/@agwab/pi-subagent/docs/usage.md +63 -12
- package/node_modules/@agwab/pi-subagent/package.json +2 -2
- package/node_modules/@agwab/pi-subagent/src/api.ts +54 -1
- package/node_modules/@agwab/pi-subagent/src/artifacts/registry.ts +9 -4
- package/node_modules/@agwab/pi-subagent/src/artifacts/result.ts +8 -0
- package/node_modules/@agwab/pi-subagent/src/core/constants.ts +9 -0
- package/node_modules/@agwab/pi-subagent/src/core/validation.ts +21 -0
- package/node_modules/@agwab/pi-subagent/src/index.ts +1046 -576
- package/node_modules/@agwab/pi-subagent/src/orchestrate/async.ts +279 -156
- package/node_modules/@agwab/pi-subagent/src/orchestrate/interrupt.ts +165 -89
- package/node_modules/@agwab/pi-subagent/src/orchestrate/reconcile.ts +111 -65
- package/node_modules/@agwab/pi-subagent/src/orchestrate/run-ref.ts +219 -0
- package/node_modules/@agwab/pi-subagent/src/orchestrate/run.ts +88 -8
- package/node_modules/@agwab/pi-subagent/src/orchestrate/status.ts +614 -298
- package/node_modules/@agwab/pi-subagent/src/panel.ts +1356 -560
- package/node_modules/@agwab/pi-subagent/src/runners/headless-model.ts +53 -5
- package/node_modules/@agwab/pi-subagent/src/runners/tmux.ts +13 -6
- package/package.json +2 -2
- package/skills/workflow-guide/SKILL.md +1 -0
- package/src/artifact-graph-runtime.ts +19 -13
- package/src/artifact-graph-schema.ts +143 -3
- package/src/cli.mjs +52 -0
- package/src/compiler.ts +63 -18
- package/src/dynamic-generated-task-runtime.ts +3 -1
- package/src/dynamic-profiles.ts +1 -1
- package/src/engine-run-graph.ts +246 -4
- package/src/engine.ts +545 -38
- package/src/extension.ts +36 -6
- package/src/index.ts +52 -1
- package/src/prompt-json.ts +13 -0
- package/src/roles.ts +6 -9
- package/src/store.ts +194 -42
- package/src/strings.ts +38 -0
- package/src/subagent-backend.ts +921 -62
- package/src/types.ts +116 -2
- package/src/verification-ontology.ts +88 -0
- package/src/workflow-artifact-tool.ts +5 -7
- package/src/workflow-artifacts.ts +83 -3
- package/src/workflow-fetch-cache-extension.ts +78 -13
- package/src/workflow-metrics.ts +478 -0
- package/src/workflow-output-artifacts.ts +5 -3
- package/src/workflow-partial-output.ts +299 -0
- package/src/workflow-progress-health.ts +47 -15
- package/src/workflow-runtime.ts +18 -2
- package/src/workflow-view.ts +2 -1
- package/src/workflow-web-source-extension.ts +654 -232
- package/src/workflow-web-source.ts +153 -39
- package/workflows/README.md +7 -25
- package/workflows/deep-research/batched-verification.spec.json +253 -0
- package/workflows/deep-research/helpers/batch-verification-candidates.mjs +136 -0
- package/workflows/deep-research/helpers/claim-evidence-gate.mjs +229 -36
- package/workflows/deep-research/helpers/final-audit-packet.mjs +1 -4
- package/workflows/deep-research/helpers/normalize-input-packet.mjs +81 -2
- package/workflows/deep-research/helpers/render-executive.mjs +40 -26
- package/workflows/deep-research/helpers/sanitize-verification-candidates.mjs +89 -15
- package/workflows/deep-research/helpers/shadow-select-verification.mjs +229 -0
- package/workflows/deep-research/helpers/verification-ontology.mjs +77 -0
- package/workflows/deep-research/schemas/deep-research-executive-render-control.schema.json +3 -3
- package/workflows/deep-research/schemas/deep-research-research-questions-control.schema.json +38 -0
- package/workflows/deep-research/schemas/deep-research-sanitize-claims-control.schema.json +63 -0
- package/workflows/deep-research/schemas/deep-research-verify-claims-batch-control.schema.json +47 -0
- package/workflows/deep-research/schemas/deep-research-verify-claims-control.schema.json +13 -3
- package/workflows/deep-research/spec.json +32 -12
- package/workflows/impact-review/spec.json +3 -3
- package/workflows/spec-review/helpers/spec-review-pipeline.mjs +1 -8
- package/dist/dynamic-loader.d.ts +0 -25
- package/dist/dynamic-loader.js +0 -13
- package/skills/workflow-guide/scaffolds/dag-required-reads/spec.json.validate.stderr +0 -0
- package/skills/workflow-guide/scaffolds/dag-required-reads/spec.json.validate.stdout +0 -13
- package/src/dynamic-loader.ts +0 -49
- package/workflows/impact-review/schemas/docs-release-impact-control.schema.json +0 -42
- package/workflows/impact-review/schemas/security-performance-impact-control.schema.json +0 -42
- package/workflows/impact-review/schemas/state-data-impact-control.schema.json +0 -42
package/dist/engine-run-graph.js
CHANGED
|
@@ -92,6 +92,118 @@ export function reconcileDynamicGeneratedRunRecords(cwd, run, compiledFlow) {
|
|
|
92
92
|
}
|
|
93
93
|
return changed;
|
|
94
94
|
}
|
|
95
|
+
export function reconcileForeachGeneratedRunRecords(cwd, run, compiledFlow) {
|
|
96
|
+
let changed = false;
|
|
97
|
+
const compiledSpecIds = new Set(compiledFlow.tasks.map((task) => compiledTaskSpecId(task)));
|
|
98
|
+
const compiledTaskBySpecId = new Map(compiledFlow.tasks.map((task) => [compiledTaskSpecId(task), task]));
|
|
99
|
+
const placeholderToGeneratedSpecIds = new Map();
|
|
100
|
+
const streamingPlaceholderSpecIds = new Set();
|
|
101
|
+
for (const compiledTask of compiledFlow.tasks) {
|
|
102
|
+
const specId = compiledTaskSpecId(compiledTask);
|
|
103
|
+
if (compiledTask.foreach && foreachStreamingEnabled(compiledTask)) {
|
|
104
|
+
streamingPlaceholderSpecIds.add(specId);
|
|
105
|
+
}
|
|
106
|
+
const placeholderSpecId = foreachGeneratedPlaceholderSpecId(compiledTask, compiledFlow, specId);
|
|
107
|
+
if (!placeholderSpecId)
|
|
108
|
+
continue;
|
|
109
|
+
if (compiledTask.foreachGenerated?.placeholderSpecId !== placeholderSpecId) {
|
|
110
|
+
compiledTask.foreachGenerated = { placeholderSpecId };
|
|
111
|
+
changed = true;
|
|
112
|
+
}
|
|
113
|
+
const generated = placeholderToGeneratedSpecIds.get(placeholderSpecId) ?? [];
|
|
114
|
+
generated.push(specId);
|
|
115
|
+
placeholderToGeneratedSpecIds.set(placeholderSpecId, generated);
|
|
116
|
+
}
|
|
117
|
+
if (placeholderToGeneratedSpecIds.size === 0)
|
|
118
|
+
return changed;
|
|
119
|
+
const filteredRunTasks = [];
|
|
120
|
+
const seenGeneratedSpecIds = new Set();
|
|
121
|
+
for (const task of run.tasks) {
|
|
122
|
+
const generatedSpecIds = placeholderToGeneratedSpecIds.get(task.specId);
|
|
123
|
+
let placeholderSpecId = foreachGeneratedPlaceholderSpecId(task, compiledFlow, task.specId);
|
|
124
|
+
if (generatedSpecIds && !placeholderSpecId) {
|
|
125
|
+
const compiledTask = compiledTaskBySpecId.get(task.specId);
|
|
126
|
+
if (compiledTask?.foreach &&
|
|
127
|
+
streamingPlaceholderSpecIds.has(task.specId)) {
|
|
128
|
+
filteredRunTasks.push(task);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (generatedSpecIds.includes(task.specId)) {
|
|
132
|
+
placeholderSpecId = task.specId;
|
|
133
|
+
task.foreachGenerated = { placeholderSpecId };
|
|
134
|
+
changed = true;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
changed = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (placeholderSpecId && !compiledSpecIds.has(task.specId)) {
|
|
142
|
+
changed = true;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (placeholderSpecId && seenGeneratedSpecIds.has(task.specId)) {
|
|
146
|
+
changed = true;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (placeholderSpecId) {
|
|
150
|
+
seenGeneratedSpecIds.add(task.specId);
|
|
151
|
+
if (task.foreachGenerated?.placeholderSpecId !== placeholderSpecId) {
|
|
152
|
+
task.foreachGenerated = { placeholderSpecId };
|
|
153
|
+
changed = true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
filteredRunTasks.push(task);
|
|
157
|
+
}
|
|
158
|
+
const runTaskBySpecId = new Map();
|
|
159
|
+
for (const task of filteredRunTasks) {
|
|
160
|
+
if (!runTaskBySpecId.has(task.specId))
|
|
161
|
+
runTaskBySpecId.set(task.specId, task);
|
|
162
|
+
}
|
|
163
|
+
const reordered = [];
|
|
164
|
+
const usedSpecIds = new Set();
|
|
165
|
+
let nextIndex = nextTaskRecordIndex({ ...run, tasks: filteredRunTasks });
|
|
166
|
+
for (const compiledTask of compiledFlow.tasks) {
|
|
167
|
+
const specId = compiledTaskSpecId(compiledTask);
|
|
168
|
+
const existing = runTaskBySpecId.get(specId);
|
|
169
|
+
if (existing) {
|
|
170
|
+
const placeholderSpecId = compiledTask.foreachGenerated?.placeholderSpecId;
|
|
171
|
+
if (placeholderSpecId &&
|
|
172
|
+
existing.foreachGenerated?.placeholderSpecId !== placeholderSpecId) {
|
|
173
|
+
existing.foreachGenerated = { placeholderSpecId };
|
|
174
|
+
changed = true;
|
|
175
|
+
}
|
|
176
|
+
reordered.push(existing);
|
|
177
|
+
usedSpecIds.add(specId);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (!compiledTask.foreachGenerated)
|
|
181
|
+
continue;
|
|
182
|
+
const created = createTaskRunRecord(cwd, run.runId, compiledTask, nextIndex);
|
|
183
|
+
nextIndex += 1;
|
|
184
|
+
reordered.push(created);
|
|
185
|
+
usedSpecIds.add(specId);
|
|
186
|
+
changed = true;
|
|
187
|
+
}
|
|
188
|
+
for (const task of filteredRunTasks) {
|
|
189
|
+
if (!usedSpecIds.has(task.specId))
|
|
190
|
+
reordered.push(task);
|
|
191
|
+
}
|
|
192
|
+
if (!sameTaskRecordOrder(run.tasks, reordered))
|
|
193
|
+
changed = true;
|
|
194
|
+
for (const task of reordered) {
|
|
195
|
+
if (!task.dependsOn)
|
|
196
|
+
continue;
|
|
197
|
+
const replaced = replaceForeachGeneratedDependencies(task.dependsOn, placeholderToGeneratedSpecIds, streamingPlaceholderSpecIds);
|
|
198
|
+
if (!sameStringList(task.dependsOn, replaced)) {
|
|
199
|
+
task.dependsOn = replaced;
|
|
200
|
+
changed = true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (changed)
|
|
204
|
+
run.tasks = reordered;
|
|
205
|
+
return changed;
|
|
206
|
+
}
|
|
95
207
|
export function assertRunTaskPositionalAlignment(run, compiledFlow) {
|
|
96
208
|
const maxLength = Math.max(run.tasks.length, compiledFlow.tasks.length);
|
|
97
209
|
for (let index = 0; index < maxLength; index += 1) {
|
|
@@ -141,6 +253,43 @@ export function compiledTaskSpecId(task) {
|
|
|
141
253
|
const specId = task.specId;
|
|
142
254
|
return typeof specId === "string" && specId.trim() !== "" ? specId : task.id;
|
|
143
255
|
}
|
|
256
|
+
function foreachGeneratedPlaceholderSpecId(task, compiledFlow, specId) {
|
|
257
|
+
const explicit = task.foreachGenerated?.placeholderSpecId;
|
|
258
|
+
if (typeof explicit === "string" && explicit.trim() !== "")
|
|
259
|
+
return explicit;
|
|
260
|
+
if (task.foreach)
|
|
261
|
+
return undefined;
|
|
262
|
+
if (task.kind !== "foreach" || !task.stageId)
|
|
263
|
+
return undefined;
|
|
264
|
+
const placeholderSpecId = foreachPlaceholderSpecId(compiledFlow, task.stageId);
|
|
265
|
+
if (!placeholderSpecId || specId === placeholderSpecId)
|
|
266
|
+
return undefined;
|
|
267
|
+
return placeholderSpecId;
|
|
268
|
+
}
|
|
269
|
+
function foreachPlaceholderSpecId(compiledFlow, stageId) {
|
|
270
|
+
const stage = (compiledFlow.stages ?? []).find((candidate) => candidate?.id === stageId);
|
|
271
|
+
if (stage?.type !== "foreach")
|
|
272
|
+
return undefined;
|
|
273
|
+
return `${stageId}.item`;
|
|
274
|
+
}
|
|
275
|
+
function replaceForeachGeneratedDependencies(dependsOn, placeholderToGeneratedSpecIds, keepPlaceholderSpecIds = new Set()) {
|
|
276
|
+
const replaced = [];
|
|
277
|
+
for (const dep of dependsOn) {
|
|
278
|
+
const generatedSpecIds = placeholderToGeneratedSpecIds.get(dep);
|
|
279
|
+
if (generatedSpecIds) {
|
|
280
|
+
if (keepPlaceholderSpecIds.has(dep))
|
|
281
|
+
replaced.push(dep);
|
|
282
|
+
replaced.push(...generatedSpecIds);
|
|
283
|
+
}
|
|
284
|
+
else
|
|
285
|
+
replaced.push(dep);
|
|
286
|
+
}
|
|
287
|
+
return [...new Set(replaced)];
|
|
288
|
+
}
|
|
289
|
+
function sameStringList(left, right) {
|
|
290
|
+
return (left.length === right.length &&
|
|
291
|
+
left.every((value, index) => value === right[index]));
|
|
292
|
+
}
|
|
144
293
|
function isLoopGeneratedCompiledTask(task, loopIds) {
|
|
145
294
|
return Boolean((task.loopChild?.loopId && loopIds.has(task.loopChild.loopId)) ||
|
|
146
295
|
(task.loopExhausted?.loopId && loopIds.has(task.loopExhausted.loopId)));
|
|
@@ -206,6 +355,29 @@ export function dependenciesReady(compiledTask, bySpecId, compiledFlow) {
|
|
|
206
355
|
if (deps.length === 0)
|
|
207
356
|
return true;
|
|
208
357
|
const partial = stageSourcePolicy(compiledFlow, compiledTask.stageId ?? "") === "partial";
|
|
358
|
+
if (foreachStreamingEnabled(compiledTask)) {
|
|
359
|
+
let completedDependencyReady = false;
|
|
360
|
+
let runningDependencyMayHavePartialItems = false;
|
|
361
|
+
let allKnownDependenciesTerminal = true;
|
|
362
|
+
for (const dep of deps) {
|
|
363
|
+
const status = bySpecId.get(dep)?.status;
|
|
364
|
+
if (status === "completed") {
|
|
365
|
+
completedDependencyReady = true;
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (status && isTerminalTaskStatus(status)) {
|
|
369
|
+
if (!partial)
|
|
370
|
+
return false;
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
if (status === "running")
|
|
374
|
+
runningDependencyMayHavePartialItems = true;
|
|
375
|
+
allKnownDependenciesTerminal = false;
|
|
376
|
+
}
|
|
377
|
+
return (completedDependencyReady ||
|
|
378
|
+
runningDependencyMayHavePartialItems ||
|
|
379
|
+
allKnownDependenciesTerminal);
|
|
380
|
+
}
|
|
209
381
|
return deps.every((dep) => {
|
|
210
382
|
const status = bySpecId.get(dep)?.status;
|
|
211
383
|
if (status === "completed")
|
|
@@ -215,6 +387,18 @@ export function dependenciesReady(compiledTask, bySpecId, compiledFlow) {
|
|
|
215
387
|
return false;
|
|
216
388
|
});
|
|
217
389
|
}
|
|
390
|
+
export function foreachStreamingEnabled(compiledTask) {
|
|
391
|
+
const streaming = compiledTask.foreach?.from?.streaming;
|
|
392
|
+
return Boolean(streaming &&
|
|
393
|
+
typeof streaming === "object" &&
|
|
394
|
+
streaming.enabled === true);
|
|
395
|
+
}
|
|
396
|
+
export function foreachStreamingMinChunk(compiledTask) {
|
|
397
|
+
const value = compiledTask.foreach?.from?.streaming?.minChunk;
|
|
398
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0
|
|
399
|
+
? Math.floor(value)
|
|
400
|
+
: 1;
|
|
401
|
+
}
|
|
218
402
|
export function buildForeachGeneratedTasks(template, runtimeTask, items) {
|
|
219
403
|
const seen = new Set();
|
|
220
404
|
const tasks = [];
|
|
@@ -228,14 +412,15 @@ export function buildForeachGeneratedTasks(template, runtimeTask, items) {
|
|
|
228
412
|
seen.add(taskId);
|
|
229
413
|
const specId = `${template.stageId}.${taskId}`;
|
|
230
414
|
const itemText = formatForeachItem(item);
|
|
231
|
-
const instructions = template.foreach.prompt.replace(/\$\{item\}/g, itemText);
|
|
415
|
+
const instructions = template.foreach.prompt.replace(/\$\{item\}/g, escapeReplacementText(itemText));
|
|
232
416
|
const compiledPrompt = [
|
|
233
417
|
template.foreach.injectRuntimeTask && runtimeTask
|
|
234
418
|
? `# Task\n\n${runtimeTask}`
|
|
235
419
|
: undefined,
|
|
236
|
-
`# Workflow Stage\n\nstage=${template.stageId}\ntype=foreach
|
|
237
|
-
`# Instructions\n\n${instructions}`,
|
|
420
|
+
`# Workflow Stage\n\nstage=${template.stageId}\ntype=foreach`,
|
|
238
421
|
template.foreach.roleText || undefined,
|
|
422
|
+
`# Workflow Item\n\nitem=${taskId}`,
|
|
423
|
+
`# Instructions\n\n${instructions}`,
|
|
239
424
|
]
|
|
240
425
|
.filter(Boolean)
|
|
241
426
|
.join("\n\n");
|
|
@@ -249,6 +434,7 @@ export function buildForeachGeneratedTasks(template, runtimeTask, items) {
|
|
|
249
434
|
compiledPrompt,
|
|
250
435
|
dependsOn: [...(template.dependsOn ?? [])],
|
|
251
436
|
foreach: undefined,
|
|
437
|
+
foreachGenerated: { placeholderSpecId: template.id },
|
|
252
438
|
});
|
|
253
439
|
}
|
|
254
440
|
return { tasks };
|
|
@@ -274,6 +460,9 @@ export function sanitizeTaskId(value) {
|
|
|
274
460
|
function formatForeachItem(item) {
|
|
275
461
|
return typeof item === "string" ? item : JSON.stringify(item);
|
|
276
462
|
}
|
|
463
|
+
function escapeReplacementText(value) {
|
|
464
|
+
return value.replace(/\$/g, "$$$$");
|
|
465
|
+
}
|
|
277
466
|
export function sourceStageIdsForFrom(from) {
|
|
278
467
|
if (Array.isArray(from))
|
|
279
468
|
return from.filter((item) => typeof item === "string");
|
|
@@ -321,7 +510,8 @@ export function markDagDependentsSkipped(run, compiledFlow) {
|
|
|
321
510
|
const status = bySpecId.get(dep)?.status;
|
|
322
511
|
return (status === "failed" ||
|
|
323
512
|
status === "interrupted" ||
|
|
324
|
-
status === "skipped"
|
|
513
|
+
status === "skipped" ||
|
|
514
|
+
status === "blocked");
|
|
325
515
|
});
|
|
326
516
|
if (!failedDep)
|
|
327
517
|
continue;
|
package/dist/engine.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export interface ResumeRunSummary {
|
|
|
25
25
|
run: WorkflowRunRecord;
|
|
26
26
|
resetTaskIds: string[];
|
|
27
27
|
}
|
|
28
|
+
export interface StopRunSummary {
|
|
29
|
+
run: WorkflowRunRecord;
|
|
30
|
+
interruptedTaskIds: string[];
|
|
31
|
+
}
|
|
32
|
+
export declare function stopRun(cwd: string, runIdOrPrefix: string): Promise<StopRunSummary>;
|
|
28
33
|
export declare function resumeRun(cwd: string, runIdOrPrefix: string, options?: WorkflowScheduleOptions): Promise<ResumeRunSummary>;
|
|
29
34
|
export declare function resumeSupervisors(cwd: string, options?: WorkflowScheduleOptions): Promise<void>;
|
|
30
35
|
export declare function watchRun(cwd: string, runId: string, options?: WorkflowScheduleOptions): void;
|