@osolmaz/pi-workflows 0.12.0 → 0.12.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 +4 -3
- package/dist/builtins/autoimplement.workflow.d.ts +485 -126
- package/dist/builtins/autoimplement.workflow.js +17 -105
- package/dist/builtins/autoimplement.workflow.js.map +1 -1
- package/dist/builtins/catalog.js +4 -4
- package/dist/builtins/index.d.ts +2 -1
- package/dist/builtins/index.js +2 -1
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/monitor.workflow.d.ts +2 -4
- package/dist/builtins/monitor.workflow.js +26 -128
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/pi-agent-group.d.ts +72 -0
- package/dist/builtins/pi-agent-group.js +1087 -0
- package/dist/builtins/pi-agent-group.js.map +1 -0
- package/dist/builtins/plan-approval.workflow.d.ts +39 -5
- package/dist/builtins/plan-approval.workflow.js +92 -14
- package/dist/builtins/plan-approval.workflow.js.map +1 -1
- package/dist/builtins/plan-change.workflow.d.ts +301 -0
- package/dist/builtins/plan-change.workflow.js +256 -0
- package/dist/builtins/plan-change.workflow.js.map +1 -0
- package/dist/builtins/plan-presentation.js +2 -2
- package/dist/builtins/plan-presentation.js.map +1 -1
- package/dist/builtins/sanity-check.workflow.d.ts +5 -3
- package/dist/builtins/sanity-check.workflow.js +105 -21
- package/dist/builtins/sanity-check.workflow.js.map +1 -1
- package/dist/extension/decision-channels.d.ts +2 -2
- package/dist/extension/decision-channels.js +22 -28
- package/dist/extension/decision-channels.js.map +1 -1
- package/dist/extension/index.js +62 -33
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/session-events.d.ts +2 -2
- package/dist/extension/widget.js +23 -3
- package/dist/extension/widget.js.map +1 -1
- package/dist/render/graph-render.js +1 -2
- package/dist/render/graph-render.js.map +1 -1
- package/dist/viewer/render.js +7 -6
- package/dist/viewer/render.js.map +1 -1
- package/dist/workflows/catalog.js +7 -2
- package/dist/workflows/catalog.js.map +1 -1
- package/dist/workflows/composition.js +8 -0
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/decision-presentation.d.ts +1 -1
- package/dist/workflows/decision-presentation.js +51 -38
- package/dist/workflows/decision-presentation.js.map +1 -1
- package/dist/workflows/engine.d.ts +2 -2
- package/dist/workflows/engine.js +14 -13
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +13 -0
- package/dist/workflows/errors.js +15 -0
- package/dist/workflows/errors.js.map +1 -1
- package/dist/workflows/human-decision.d.ts +16 -4
- package/dist/workflows/human-decision.js +175 -72
- package/dist/workflows/human-decision.js.map +1 -1
- package/dist/workflows/index.d.ts +2 -2
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/progress.d.ts +1 -0
- package/dist/workflows/progress.js +15 -3
- package/dist/workflows/progress.js.map +1 -1
- package/dist/workflows/schema.js +10 -0
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.js +5 -0
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +33 -45
- package/docs/HUMAN_DECISIONS.md +25 -35
- package/docs/HUMAN_DECISION_PRESENTATIONS.md +14 -24
- package/docs/MONITOR.md +5 -11
- package/docs/WORKFLOW_COMPOSITION.md +8 -7
- package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +322 -0
- package/docs/plans/2026-08-21-sanity-check-plan.md +202 -94
- package/docs/run-bundles.md +6 -6
- package/docs/workflows.md +26 -6
- package/examples/workflows/approved-plan.workflow.ts +19 -46
- package/herdr-plugin.toml +1 -1
- package/package.json +7 -7
- package/schemas/human-decision-accepted-v1.schema.json +15 -3
- package/schemas/human-decision-continuation-v1.schema.json +10 -1
- package/schemas/human-decision-delivery-v1.schema.json +8 -0
- package/schemas/human-decision-receipt-v1.schema.json +8 -0
- package/schemas/human-decision-request-v1.schema.json +24 -4
- package/skills/autoimplement/SKILL.md +27 -0
- package/skills/monitor/SKILL.md +31 -3
- package/skills/pi-workflows/SKILL.md +2 -1
- package/skills/sanity-check/SKILL.md +44 -0
- package/src/builtins/autoimplement.workflow.ts +19 -118
- package/src/builtins/catalog.ts +4 -4
- package/src/builtins/index.ts +11 -0
- package/src/builtins/monitor.workflow.ts +27 -150
- package/src/builtins/pi-agent-group.ts +1407 -0
- package/src/builtins/plan-approval.workflow.ts +157 -24
- package/src/builtins/plan-change.workflow.ts +321 -0
- package/src/builtins/plan-presentation.ts +2 -2
- package/src/builtins/sanity-check.workflow.ts +186 -41
- package/src/extension/decision-channels.ts +29 -59
- package/src/extension/index.ts +79 -41
- package/src/extension/session-events.ts +2 -2
- package/src/extension/widget.ts +24 -5
- package/src/render/graph-render.ts +1 -2
- package/src/viewer/render.ts +7 -6
- package/src/workflows/catalog.ts +7 -2
- package/src/workflows/composition.ts +9 -0
- package/src/workflows/decision-presentation.ts +56 -43
- package/src/workflows/engine.ts +17 -15
- package/src/workflows/errors.ts +24 -0
- package/src/workflows/human-decision.ts +218 -101
- package/src/workflows/index.ts +5 -11
- package/src/workflows/progress.ts +18 -3
- package/src/workflows/schema.ts +17 -0
- package/src/workflows/store.ts +5 -0
- package/src/workflows/types.ts +39 -56
- package/dist/builtins/sanity-check-session.d.ts +0 -17
- package/dist/builtins/sanity-check-session.js +0 -168
- package/dist/builtins/sanity-check-session.js.map +0 -1
- package/schemas/human-decision-accepted-v2.schema.json +0 -50
- package/schemas/human-decision-delivery-v2.schema.json +0 -36
- package/schemas/human-decision-receipt-v2.schema.json +0 -39
- package/schemas/human-decision-request-v2.schema.json +0 -69
- package/schemas/human-decision-resolution-v2.schema.json +0 -27
- package/src/builtins/sanity-check-session.ts +0 -205
package/dist/extension/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { projectControllerStorePath, SqliteControllerStore, } from "../controlle
|
|
|
6
6
|
import { compositionMetadata } from "../workflows/composition.js";
|
|
7
7
|
import { humanDecisionChannelRequest } from "../workflows/decision-presentation.js";
|
|
8
8
|
import { WorkflowEngine } from "../workflows/engine.js";
|
|
9
|
-
import { ClaimLostError, errorMessage, isClaimLostError, TimeoutError, } from "../workflows/errors.js";
|
|
9
|
+
import { BuiltinWorkflowRevisionChangedError, ClaimLostError, errorMessage, isClaimLostError, TimeoutError, } from "../workflows/errors.js";
|
|
10
10
|
import { HumanDecisionStore, createHumanDecisionAttemptId, validateHumanDecisionResponse, } from "../workflows/human-decision.js";
|
|
11
11
|
import { discoverWorkflows, resolveWorkflowRef } from "../workflows/loader.js";
|
|
12
12
|
import { migrateLegacyWorkflowSources } from "../workflows/migrate-sources.js";
|
|
@@ -55,10 +55,8 @@ function humanDecisionRequest(value) {
|
|
|
55
55
|
const schema = value !== null && typeof value === "object"
|
|
56
56
|
? value.schema
|
|
57
57
|
: undefined;
|
|
58
|
-
if (schema !== "pi-workflows.human-decision-request.v1"
|
|
59
|
-
schema !== "pi-workflows.human-decision-request.v2") {
|
|
58
|
+
if (schema !== "pi-workflows.human-decision-request.v1")
|
|
60
59
|
return null;
|
|
61
|
-
}
|
|
62
60
|
return value;
|
|
63
61
|
}
|
|
64
62
|
function definitionDigest(snapshot) {
|
|
@@ -70,6 +68,20 @@ function launchSourceIdentity(workflow, root) {
|
|
|
70
68
|
mounted: compositionMetadata(workflow)?.sources ?? [],
|
|
71
69
|
};
|
|
72
70
|
}
|
|
71
|
+
function continuationSourceChangedError(runId, previous, current) {
|
|
72
|
+
if (previous.kind === "builtin" &&
|
|
73
|
+
current.kind === "builtin" &&
|
|
74
|
+
previous.id === current.id &&
|
|
75
|
+
previous.revision !== current.revision) {
|
|
76
|
+
return new BuiltinWorkflowRevisionChangedError({
|
|
77
|
+
runId,
|
|
78
|
+
workflowId: current.id,
|
|
79
|
+
previousRevision: previous.revision,
|
|
80
|
+
currentRevision: current.revision,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return new Error(`Workflow source changed since run ${runId} started; revert the edit to answer its checkpoint`);
|
|
84
|
+
}
|
|
73
85
|
function preparedLaunchOptions(options) {
|
|
74
86
|
return {
|
|
75
87
|
...(options.presentation !== undefined ? { presentation: options.presentation } : {}),
|
|
@@ -888,7 +900,7 @@ export default function piWorkflows(pi) {
|
|
|
888
900
|
}
|
|
889
901
|
if (parent.state.workflowSource !== undefined &&
|
|
890
902
|
!isDeepStrictEqual(parent.state.workflowSource, workflowSource)) {
|
|
891
|
-
throw
|
|
903
|
+
throw continuationSourceChangedError(options.parentRunId, parent.state.workflowSource, workflowSource);
|
|
892
904
|
}
|
|
893
905
|
}
|
|
894
906
|
// Interactive runs are queued and claimed atomically, so this session
|
|
@@ -1633,7 +1645,7 @@ export default function piWorkflows(pi) {
|
|
|
1633
1645
|
};
|
|
1634
1646
|
const store = new HumanDecisionStore(new WorkflowRunStore().outputRoot);
|
|
1635
1647
|
const acceptance = await store.accept(request, submission);
|
|
1636
|
-
if (acceptance.status === "conflict") {
|
|
1648
|
+
if (acceptance.status === "conflict" || acceptance.decision.provenance !== "human") {
|
|
1637
1649
|
throw new Error("That human decision was already answered differently.");
|
|
1638
1650
|
}
|
|
1639
1651
|
accepted = acceptance.decision;
|
|
@@ -1663,6 +1675,7 @@ export default function piWorkflows(pi) {
|
|
|
1663
1675
|
schema: "pi-workflows.human-decision-continuation.v1",
|
|
1664
1676
|
decisionId: request.decisionId,
|
|
1665
1677
|
requestDigest: request.requestDigest,
|
|
1678
|
+
provenance: accepted.provenance,
|
|
1666
1679
|
parentRunId: waiting.parentRunId,
|
|
1667
1680
|
runId: continuationRunId,
|
|
1668
1681
|
createdAt: accepted.acceptedAt,
|
|
@@ -1775,60 +1788,76 @@ export default function piWorkflows(pi) {
|
|
|
1775
1788
|
const ownedBySession = queueRecord !== undefined &&
|
|
1776
1789
|
(queueRecord.originSessionId === null ||
|
|
1777
1790
|
queueRecord.originSessionId === ctx.sessionManager.getSessionId());
|
|
1778
|
-
|
|
1779
|
-
if (
|
|
1791
|
+
let resolved = await store.readResolved(request.decisionId);
|
|
1792
|
+
if (resolved === null) {
|
|
1780
1793
|
let cancellation = await store.readCancellation(request.decisionId);
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1794
|
+
const expired = request.expiresAt !== undefined && Date.parse(request.expiresAt) <= Date.now();
|
|
1795
|
+
if (cancellation === null && expired) {
|
|
1796
|
+
if (request.defaultResponse === undefined) {
|
|
1797
|
+
await store.cancel(request, "expired");
|
|
1798
|
+
cancellation = await store.readCancellation(request.decisionId);
|
|
1799
|
+
}
|
|
1800
|
+
else {
|
|
1801
|
+
try {
|
|
1802
|
+
resolved = (await store.resolveTimeout(request)).decision;
|
|
1803
|
+
}
|
|
1804
|
+
catch {
|
|
1805
|
+
cancellation = await store.readCancellation(request.decisionId);
|
|
1806
|
+
resolved = await store.readResolved(request.decisionId);
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1786
1809
|
}
|
|
1787
1810
|
if (cancellation !== null) {
|
|
1788
1811
|
await settleHumanDecisionChannels(cancellation);
|
|
1789
1812
|
continue;
|
|
1790
1813
|
}
|
|
1791
|
-
if (
|
|
1814
|
+
if (resolved === null) {
|
|
1815
|
+
if (!deliverPending || !ownedBySession)
|
|
1816
|
+
continue;
|
|
1817
|
+
const channels = audienceChannels(decisionChannelConfig, request.audience);
|
|
1818
|
+
for (const channelId of channels) {
|
|
1819
|
+
const channel = telegramDecisionChannels.get(channelId);
|
|
1820
|
+
if (channel !== undefined)
|
|
1821
|
+
await channel.deliver(humanDecisionChannelRequest(request));
|
|
1822
|
+
}
|
|
1823
|
+
if (ctx.mode === "tui" && channels.includes("pi") && lastWaitingRunId === null) {
|
|
1824
|
+
lastWaitingRunId = request.runId;
|
|
1825
|
+
queueMicrotask(() => void promptHumanDecision(ctx, request));
|
|
1826
|
+
}
|
|
1792
1827
|
continue;
|
|
1793
|
-
const channels = audienceChannels(decisionChannelConfig, request.audience);
|
|
1794
|
-
for (const channelId of channels) {
|
|
1795
|
-
const channel = telegramDecisionChannels.get(channelId);
|
|
1796
|
-
if (channel !== undefined)
|
|
1797
|
-
await channel.deliver(humanDecisionChannelRequest(request));
|
|
1798
|
-
}
|
|
1799
|
-
if (ctx.mode === "tui" && channels.includes("pi") && lastWaitingRunId === null) {
|
|
1800
|
-
lastWaitingRunId = request.runId;
|
|
1801
|
-
queueMicrotask(() => void promptHumanDecision(ctx, request));
|
|
1802
1828
|
}
|
|
1803
|
-
continue;
|
|
1804
1829
|
}
|
|
1805
1830
|
if (!ownedBySession)
|
|
1806
1831
|
continue;
|
|
1832
|
+
const currentParent = await readRunBundle(runStore.runDirFor(request.runId));
|
|
1833
|
+
if (currentParent === null || currentParent.state.status !== "waiting")
|
|
1834
|
+
continue;
|
|
1807
1835
|
const runId = `continuation-${request.decisionId.slice("decision-".length)}`;
|
|
1808
1836
|
const continuation = (await store.readContinuation(request.decisionId)) ?? {
|
|
1809
1837
|
schema: "pi-workflows.human-decision-continuation.v1",
|
|
1810
1838
|
decisionId: request.decisionId,
|
|
1811
1839
|
requestDigest: request.requestDigest,
|
|
1840
|
+
provenance: resolved.provenance,
|
|
1812
1841
|
parentRunId: request.runId,
|
|
1813
1842
|
runId,
|
|
1814
|
-
createdAt:
|
|
1843
|
+
createdAt: resolved.acceptedAt,
|
|
1815
1844
|
};
|
|
1816
1845
|
await store.recordContinuation(request.decisionId, continuation);
|
|
1817
1846
|
const existing = await readRunBundle(runStore.runDirFor(continuation.runId));
|
|
1818
1847
|
if (existing === null && activeRun === null) {
|
|
1819
|
-
if (
|
|
1848
|
+
if (currentParent.state.workflowSource === undefined)
|
|
1820
1849
|
continue;
|
|
1821
|
-
const workflowRef =
|
|
1822
|
-
? `builtin:${
|
|
1823
|
-
:
|
|
1824
|
-
await startRun(ctx, workflowRef,
|
|
1850
|
+
const workflowRef = currentParent.state.workflowSource.kind === "builtin"
|
|
1851
|
+
? `builtin:${currentParent.state.workflowSource.id}`
|
|
1852
|
+
: currentParent.state.workflowSource.path;
|
|
1853
|
+
await startRun(ctx, workflowRef, currentParent.state.input, {
|
|
1825
1854
|
parentRunId: request.runId,
|
|
1826
|
-
humanDecision:
|
|
1855
|
+
humanDecision: resolved,
|
|
1827
1856
|
runId: continuation.runId,
|
|
1828
1857
|
quiet: true,
|
|
1829
1858
|
});
|
|
1830
1859
|
}
|
|
1831
|
-
await settleHumanDecisionChannels(
|
|
1860
|
+
await settleHumanDecisionChannels(resolved);
|
|
1832
1861
|
if (activeRun !== null)
|
|
1833
1862
|
break;
|
|
1834
1863
|
}
|
|
@@ -1890,7 +1919,7 @@ export default function piWorkflows(pi) {
|
|
|
1890
1919
|
}
|
|
1891
1920
|
if (parent.state.workflowSource !== undefined &&
|
|
1892
1921
|
!isDeepStrictEqual(parent.state.workflowSource, workflowSource)) {
|
|
1893
|
-
throw
|
|
1922
|
+
throw continuationSourceChangedError(options.parentRunId, parent.state.workflowSource, workflowSource);
|
|
1894
1923
|
}
|
|
1895
1924
|
}
|
|
1896
1925
|
const snapshot = createDefinitionSnapshot(workflow);
|