@osolmaz/pi-workflows 0.2.0 → 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 +72 -5
- package/dist/builtins/catalog.d.ts +2 -0
- package/dist/builtins/catalog.js +22 -0
- package/dist/builtins/catalog.js.map +1 -0
- package/dist/builtins/monitor.workflow.d.ts +71 -0
- package/dist/builtins/monitor.workflow.js +250 -0
- package/dist/builtins/monitor.workflow.js.map +1 -0
- package/dist/controllers/conditions.d.ts +6 -0
- package/dist/controllers/conditions.js +68 -0
- package/dist/controllers/conditions.js.map +1 -0
- package/dist/controllers/definition.d.ts +6 -0
- package/dist/controllers/definition.js +45 -0
- package/dist/controllers/definition.js.map +1 -0
- package/dist/controllers/effects.d.ts +14 -0
- package/dist/controllers/effects.js +104 -0
- package/dist/controllers/effects.js.map +1 -0
- package/dist/controllers/errors.d.ts +12 -0
- package/dist/controllers/errors.js +25 -0
- package/dist/controllers/errors.js.map +1 -0
- package/dist/controllers/index.d.ts +13 -0
- package/dist/controllers/index.js +13 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/controllers/json.d.ts +5 -0
- package/dist/controllers/json.js +57 -0
- package/dist/controllers/json.js.map +1 -0
- package/dist/controllers/loader.d.ts +23 -0
- package/dist/controllers/loader.js +74 -0
- package/dist/controllers/loader.js.map +1 -0
- package/dist/controllers/manager.d.ts +58 -0
- package/dist/controllers/manager.js +399 -0
- package/dist/controllers/manager.js.map +1 -0
- package/dist/controllers/results.d.ts +5 -0
- package/dist/controllers/results.js +32 -0
- package/dist/controllers/results.js.map +1 -0
- package/dist/controllers/sqlite.d.ts +235 -0
- package/dist/controllers/sqlite.js +1087 -0
- package/dist/controllers/sqlite.js.map +1 -0
- package/dist/controllers/store.d.ts +112 -0
- package/dist/controllers/store.js +32 -0
- package/dist/controllers/store.js.map +1 -0
- package/dist/controllers/types.d.ts +159 -0
- package/dist/controllers/types.js +2 -0
- package/dist/controllers/types.js.map +1 -0
- package/dist/controllers/workflow-engine-scheduler.d.ts +25 -0
- package/dist/controllers/workflow-engine-scheduler.js +95 -0
- package/dist/controllers/workflow-engine-scheduler.js.map +1 -0
- package/dist/controllers/workflows.d.ts +27 -0
- package/dist/controllers/workflows.js +109 -0
- package/dist/controllers/workflows.js.map +1 -0
- package/dist/extension/controller-host.d.ts +47 -0
- package/dist/extension/controller-host.js +110 -0
- package/dist/extension/controller-host.js.map +1 -0
- package/dist/extension/executor.d.ts +3 -0
- package/dist/extension/executor.js +12 -2
- package/dist/extension/executor.js.map +1 -1
- package/dist/extension/index.d.ts +7 -0
- package/dist/extension/index.js +1118 -106
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +6 -0
- package/dist/extension/recorder.js +20 -8
- package/dist/extension/recorder.js.map +1 -1
- package/dist/extension/workflow-tool.d.ts +28 -0
- package/dist/extension/workflow-tool.js +33 -0
- package/dist/extension/workflow-tool.js.map +1 -0
- package/dist/host/processes.d.ts +24 -0
- package/dist/host/processes.js +114 -0
- package/dist/host/processes.js.map +1 -0
- package/dist/host/rpc-bridge.d.ts +9 -0
- package/dist/host/rpc-bridge.js +39 -0
- package/dist/host/rpc-bridge.js.map +1 -0
- package/dist/host/rpc-executor.d.ts +38 -0
- package/dist/host/rpc-executor.js +254 -0
- package/dist/host/rpc-executor.js.map +1 -0
- package/dist/host/runner.d.ts +50 -0
- package/dist/host/runner.js +379 -0
- package/dist/host/runner.js.map +1 -0
- package/dist/viewer/cli.d.ts +7 -3
- package/dist/viewer/cli.js +150 -19
- package/dist/viewer/cli.js.map +1 -1
- package/dist/workflows/catalog.d.ts +43 -0
- package/dist/workflows/catalog.js +79 -0
- package/dist/workflows/catalog.js.map +1 -0
- package/dist/workflows/engine.d.ts +37 -2
- package/dist/workflows/engine.js +297 -29
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +23 -0
- package/dist/workflows/errors.js +38 -0
- package/dist/workflows/errors.js.map +1 -1
- package/dist/workflows/graph.js +0 -5
- package/dist/workflows/graph.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/loader.d.ts +19 -15
- package/dist/workflows/loader.js +63 -19
- package/dist/workflows/loader.js.map +1 -1
- package/dist/workflows/migrate-sources.d.ts +41 -0
- package/dist/workflows/migrate-sources.js +129 -0
- package/dist/workflows/migrate-sources.js.map +1 -0
- package/dist/workflows/schema.js +3 -2
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.d.ts +50 -6
- package/dist/workflows/store.js +448 -53
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +27 -3
- package/docs/CONTROLLERS.md +215 -0
- package/docs/development.md +14 -9
- package/docs/plans/2026-08-04-controller-runtime-plan.md +169 -0
- package/docs/plans/2026-08-05-always-on-workflows-plan.md +125 -0
- package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +184 -0
- package/docs/plans/2026-08-12-coordinated-workflow-timeouts-plan.md +74 -0
- package/docs/plans/2026-08-13-built-in-workflow-catalog-plan.md +97 -0
- package/docs/run-bundles.md +85 -28
- package/docs/workflows.md +161 -17
- package/examples/controllers/pull-request.controller.ts +215 -0
- package/package.json +10 -2
- package/src/builtins/catalog.ts +22 -0
- package/src/builtins/monitor.workflow.ts +302 -0
- package/src/controllers/conditions.ts +110 -0
- package/src/controllers/definition.ts +65 -0
- package/src/controllers/effects.ts +123 -0
- package/src/controllers/errors.ts +27 -0
- package/src/controllers/index.ts +90 -0
- package/src/controllers/json.ts +62 -0
- package/src/controllers/loader.ts +104 -0
- package/src/controllers/manager.ts +533 -0
- package/src/controllers/results.ts +46 -0
- package/src/controllers/sqlite.ts +1545 -0
- package/src/controllers/store.ts +160 -0
- package/src/controllers/types.ts +183 -0
- package/src/controllers/workflow-engine-scheduler.ts +148 -0
- package/src/controllers/workflows.ts +152 -0
- package/src/extension/controller-host.ts +163 -0
- package/src/extension/executor.ts +13 -2
- package/src/extension/index.ts +1325 -130
- package/src/extension/recorder.ts +65 -36
- package/src/extension/workflow-tool.ts +59 -0
- package/src/host/processes.ts +119 -0
- package/src/host/rpc-bridge.ts +44 -0
- package/src/host/rpc-executor.ts +299 -0
- package/src/host/runner.ts +445 -0
- package/src/viewer/cli.ts +167 -21
- package/src/workflows/catalog.ts +135 -0
- package/src/workflows/engine.ts +404 -41
- package/src/workflows/errors.ts +45 -0
- package/src/workflows/graph.ts +0 -5
- package/src/workflows/index.ts +2 -0
- package/src/workflows/loader.ts +76 -22
- package/src/workflows/migrate-sources.ts +167 -0
- package/src/workflows/schema.ts +3 -2
- package/src/workflows/store.ts +557 -48
- package/src/workflows/types.ts +22 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { StringEnum } from "@earendil-works/pi-ai";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
export const RPC_SUBMISSION_PREFIX = "PI_WORKFLOWS_STEP_SUBMISSION ";
|
|
4
|
+
/**
|
|
5
|
+
* Loaded into headless `pi --mode rpc` children spawned by the standalone
|
|
6
|
+
* host. The child has no workflow engine, so this bridge only registers the
|
|
7
|
+
* `workflow` tool and reports every submission to the host over stderr; the
|
|
8
|
+
* host validates against the engine and re-prompts on rejection.
|
|
9
|
+
*/
|
|
10
|
+
export default function piWorkflowsRpcBridge(pi) {
|
|
11
|
+
pi.registerTool({
|
|
12
|
+
name: "workflow",
|
|
13
|
+
label: "Workflow",
|
|
14
|
+
description: [
|
|
15
|
+
"Submit the output for the pending workflow step with action submit.",
|
|
16
|
+
"Only call this tool when a workflow step contract in the conversation asks you to.",
|
|
17
|
+
"Pass the exact step id from the contract and your result as the output.",
|
|
18
|
+
].join(" "),
|
|
19
|
+
parameters: Type.Object({
|
|
20
|
+
action: StringEnum(["submit"]),
|
|
21
|
+
step: Type.String({ description: "Step id from the workflow step contract" }),
|
|
22
|
+
attempt: Type.String({ description: "Attempt id from the workflow step contract" }),
|
|
23
|
+
output: Type.Unknown({ description: "Step output matching the expected shape" }),
|
|
24
|
+
}, { additionalProperties: false }),
|
|
25
|
+
async execute(_toolCallId, params) {
|
|
26
|
+
process.stderr.write(`${RPC_SUBMISSION_PREFIX}${JSON.stringify(params)}\n`);
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: "Submission recorded. Continue only when the workflow sends the next step.",
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
details: {},
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=rpc-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-bridge.js","sourceRoot":"","sources":["../../src/host/rpc-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE/B,MAAM,CAAC,MAAM,qBAAqB,GAAG,+BAA+B,CAAC;AAErE;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,EAAgB;IAC3D,EAAE,CAAC,YAAY,CAAC;QACd,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE;YACX,qEAAqE;YACrE,oFAAoF;YACpF,yEAAyE;SAC1E,CAAC,IAAI,CAAC,GAAG,CAAC;QACX,UAAU,EAAE,IAAI,CAAC,MAAM,CACrB;YACE,MAAM,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAU,CAAC;YACvC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;YAC7E,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,4CAA4C,EAAE,CAAC;YACnF,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,yCAAyC,EAAE,CAAC;SACjF,EACD,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAChC;QACD,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM;YAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5E,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,2EAA2E;qBAClF;iBACF;gBACD,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AgentStepExecutor, AgentStepRequest, AgentStepSubmission } from "../workflows/types.js";
|
|
2
|
+
import type { HostProcessRegistry } from "./processes.js";
|
|
3
|
+
export type RpcStepExecutorOptions = {
|
|
4
|
+
cwd: string;
|
|
5
|
+
registry: HostProcessRegistry;
|
|
6
|
+
/** Absolute path to the pi binary; defaults to the installed `pi`. */
|
|
7
|
+
piBin?: string;
|
|
8
|
+
/** Extra environment for the child; the host's environment is inherited. */
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
/** Extra pi arguments, for example a model override. */
|
|
11
|
+
piArgs?: string[];
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Runs agent steps in a headless `pi --mode rpc` child. One child serves one
|
|
15
|
+
* workflow run. The rpc-bridge extension inside the child registers the
|
|
16
|
+
* `workflow` tool and reports submissions over stderr; this executor
|
|
17
|
+
* validates them through `request.accept` and re-prompts on rejection, so
|
|
18
|
+
* the model sees the same tool contract as an in-session run.
|
|
19
|
+
*/
|
|
20
|
+
export declare class RpcStepExecutor implements AgentStepExecutor {
|
|
21
|
+
private readonly options;
|
|
22
|
+
private child;
|
|
23
|
+
private childExited;
|
|
24
|
+
private stderrBuffer;
|
|
25
|
+
private submissions;
|
|
26
|
+
private submissionWaiters;
|
|
27
|
+
private stdoutBuffer;
|
|
28
|
+
constructor(options: RpcStepExecutorOptions);
|
|
29
|
+
runAgentStep(request: AgentStepRequest, signal: AbortSignal): Promise<AgentStepSubmission>;
|
|
30
|
+
/** Stop the child's whole process group, then unregister it. */
|
|
31
|
+
close(): Promise<void>;
|
|
32
|
+
private currentExit;
|
|
33
|
+
private ensureStarted;
|
|
34
|
+
private promptForSubmission;
|
|
35
|
+
private takeMatchingSubmission;
|
|
36
|
+
private sendAbortQuietly;
|
|
37
|
+
private wakeSubmissionWaiters;
|
|
38
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { RPC_SUBMISSION_PREFIX } from "./rpc-bridge.js";
|
|
5
|
+
// Production resolves the compiled .js; tests and dev checkouts load the .ts
|
|
6
|
+
// source, which pi compiles itself when loading extensions.
|
|
7
|
+
const BRIDGE_PATH = ["./rpc-bridge.js", "./rpc-bridge.ts"]
|
|
8
|
+
.map((candidate) => fileURLToPath(new URL(candidate, import.meta.url)))
|
|
9
|
+
.find((candidate) => fs.existsSync(candidate));
|
|
10
|
+
const ABORT_GRACE_MS = 3_000;
|
|
11
|
+
/**
|
|
12
|
+
* Runs agent steps in a headless `pi --mode rpc` child. One child serves one
|
|
13
|
+
* workflow run. The rpc-bridge extension inside the child registers the
|
|
14
|
+
* `workflow` tool and reports submissions over stderr; this executor
|
|
15
|
+
* validates them through `request.accept` and re-prompts on rejection, so
|
|
16
|
+
* the model sees the same tool contract as an in-session run.
|
|
17
|
+
*/
|
|
18
|
+
export class RpcStepExecutor {
|
|
19
|
+
options;
|
|
20
|
+
child = null;
|
|
21
|
+
childExited = null;
|
|
22
|
+
stderrBuffer = "";
|
|
23
|
+
submissions = [];
|
|
24
|
+
submissionWaiters = [];
|
|
25
|
+
stdoutBuffer = "";
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.options = options;
|
|
28
|
+
}
|
|
29
|
+
async runAgentStep(request, signal) {
|
|
30
|
+
this.ensureStarted();
|
|
31
|
+
let prompt = request.prompt;
|
|
32
|
+
for (;;) {
|
|
33
|
+
throwIfAborted(signal);
|
|
34
|
+
const submission = await this.promptForSubmission(prompt, request, signal);
|
|
35
|
+
const accepted = await request.accept(submission.output);
|
|
36
|
+
if (accepted.ok) {
|
|
37
|
+
return { output: accepted.value };
|
|
38
|
+
}
|
|
39
|
+
prompt = [
|
|
40
|
+
`The workflow rejected your submission for step ${JSON.stringify(request.contract.nodeId)}:`,
|
|
41
|
+
accepted.error,
|
|
42
|
+
"",
|
|
43
|
+
"Call the `workflow` tool again with a corrected output.",
|
|
44
|
+
].join("\n");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Stop the child's whole process group, then unregister it. */
|
|
48
|
+
async close() {
|
|
49
|
+
const child = this.child;
|
|
50
|
+
this.child = null;
|
|
51
|
+
if (child === null) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const pid = child.pid;
|
|
55
|
+
if (this.childExited === null) {
|
|
56
|
+
try {
|
|
57
|
+
child.stdin?.end();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// The pipe may already be closed.
|
|
61
|
+
}
|
|
62
|
+
// The child spawns in its own group; tool calls can leave
|
|
63
|
+
// grandchildren that leader-only signals would orphan forever.
|
|
64
|
+
if (pid !== undefined) {
|
|
65
|
+
killGroup(pid, "SIGTERM");
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
child.kill("SIGTERM");
|
|
69
|
+
}
|
|
70
|
+
const exited = await waitForExit(child, ABORT_GRACE_MS);
|
|
71
|
+
if (!exited) {
|
|
72
|
+
if (pid !== undefined) {
|
|
73
|
+
killGroup(pid, "SIGKILL");
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
child.kill("SIGKILL");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (pid !== undefined) {
|
|
81
|
+
this.options.registry.unregister(pid);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
currentExit() {
|
|
85
|
+
return this.childExited;
|
|
86
|
+
}
|
|
87
|
+
ensureStarted() {
|
|
88
|
+
if (this.child !== null) {
|
|
89
|
+
const exited = this.currentExit();
|
|
90
|
+
if (exited !== null) {
|
|
91
|
+
throw new Error(`Headless pi session exited (code ${exited.code}, signal ${exited.signal})`);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (BRIDGE_PATH === undefined) {
|
|
96
|
+
throw new Error("The pi-workflows rpc-bridge extension is missing from this installation");
|
|
97
|
+
}
|
|
98
|
+
const piBin = this.options.piBin ?? "pi";
|
|
99
|
+
const child = spawn(piBin, [
|
|
100
|
+
"--mode",
|
|
101
|
+
"rpc",
|
|
102
|
+
"--no-session",
|
|
103
|
+
// Isolation is required: an installed pi-workflows extension would
|
|
104
|
+
// otherwise load beside the bridge, register a competing workflow
|
|
105
|
+
// tool, and start its own resume and controller workers.
|
|
106
|
+
"--no-extensions",
|
|
107
|
+
"-e",
|
|
108
|
+
BRIDGE_PATH,
|
|
109
|
+
...(this.options.piArgs ?? []),
|
|
110
|
+
], {
|
|
111
|
+
cwd: this.options.cwd,
|
|
112
|
+
env: { ...process.env, ...this.options.env },
|
|
113
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
114
|
+
// Own process group: the host kills groups, never individual PIDs,
|
|
115
|
+
// so a killed host cannot leave an orphaned agent working.
|
|
116
|
+
detached: true,
|
|
117
|
+
});
|
|
118
|
+
this.child = child;
|
|
119
|
+
if (child.pid !== undefined) {
|
|
120
|
+
this.options.registry.register(child.pid);
|
|
121
|
+
}
|
|
122
|
+
child.on("exit", (code, signal) => {
|
|
123
|
+
this.childExited = { code, signal };
|
|
124
|
+
if (child.pid !== undefined) {
|
|
125
|
+
this.options.registry.unregister(child.pid);
|
|
126
|
+
}
|
|
127
|
+
this.wakeSubmissionWaiters();
|
|
128
|
+
});
|
|
129
|
+
// A failed spawn (missing binary, EACCES) emits error instead of exit;
|
|
130
|
+
// without a listener it would crash the host as an uncaught exception.
|
|
131
|
+
child.on("error", (error) => {
|
|
132
|
+
this.childExited = { code: null, signal: error.message };
|
|
133
|
+
this.wakeSubmissionWaiters();
|
|
134
|
+
});
|
|
135
|
+
child.stdin?.on("error", () => {
|
|
136
|
+
// Writes racing child exit surface asynchronously as EPIPE; the step
|
|
137
|
+
// fails through the exit path instead of an uncaught stream error.
|
|
138
|
+
});
|
|
139
|
+
child.stderr?.on("data", (chunk) => {
|
|
140
|
+
this.stderrBuffer += chunk.toString("utf8");
|
|
141
|
+
const lines = this.stderrBuffer.split("\n");
|
|
142
|
+
this.stderrBuffer = lines.pop() ?? "";
|
|
143
|
+
for (const line of lines) {
|
|
144
|
+
if (!line.startsWith(RPC_SUBMISSION_PREFIX)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
try {
|
|
148
|
+
const parsed = JSON.parse(line.slice(RPC_SUBMISSION_PREFIX.length));
|
|
149
|
+
if (parsed.action === "submit" &&
|
|
150
|
+
typeof parsed.step === "string" &&
|
|
151
|
+
typeof parsed.attempt === "string") {
|
|
152
|
+
this.submissions.push(parsed);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// A malformed marker line is ignored; the step times out instead.
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
this.wakeSubmissionWaiters();
|
|
160
|
+
});
|
|
161
|
+
// stdout carries the RPC event stream. The submission channel is stderr,
|
|
162
|
+
// so stdout is only drained to keep the pipe from blocking.
|
|
163
|
+
child.stdout?.on("data", (chunk) => {
|
|
164
|
+
this.stdoutBuffer = (this.stdoutBuffer + chunk.toString("utf8")).slice(-64 * 1024);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async promptForSubmission(prompt, request, signal) {
|
|
168
|
+
const child = this.child;
|
|
169
|
+
if (child === null || this.childExited !== null) {
|
|
170
|
+
throw new Error("Headless pi session is not running");
|
|
171
|
+
}
|
|
172
|
+
const matching = this.takeMatchingSubmission(request);
|
|
173
|
+
if (matching !== undefined) {
|
|
174
|
+
return matching;
|
|
175
|
+
}
|
|
176
|
+
child.stdin?.write(`${JSON.stringify({ type: "prompt", message: prompt })}\n`);
|
|
177
|
+
for (;;) {
|
|
178
|
+
throwIfAborted(signal);
|
|
179
|
+
const exited = this.currentExit();
|
|
180
|
+
if (exited !== null) {
|
|
181
|
+
throw new Error(`Headless pi session exited mid-step (code ${exited.code})`);
|
|
182
|
+
}
|
|
183
|
+
const found = this.takeMatchingSubmission(request);
|
|
184
|
+
if (found !== undefined) {
|
|
185
|
+
return found;
|
|
186
|
+
}
|
|
187
|
+
await new Promise((resolve, reject) => {
|
|
188
|
+
const waiter = () => {
|
|
189
|
+
signal.removeEventListener("abort", onAbort);
|
|
190
|
+
resolve();
|
|
191
|
+
};
|
|
192
|
+
const onAbort = () => {
|
|
193
|
+
this.sendAbortQuietly();
|
|
194
|
+
reject(signal.reason ?? new Error("Workflow step aborted"));
|
|
195
|
+
};
|
|
196
|
+
this.submissionWaiters.push(waiter);
|
|
197
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
takeMatchingSubmission(request) {
|
|
202
|
+
const index = this.submissions.findIndex((candidate) => candidate.step === request.contract.nodeId &&
|
|
203
|
+
candidate.attempt === request.contract.attemptId);
|
|
204
|
+
return index === -1 ? undefined : this.submissions.splice(index, 1)[0];
|
|
205
|
+
}
|
|
206
|
+
sendAbortQuietly() {
|
|
207
|
+
try {
|
|
208
|
+
this.child?.stdin?.write(`${JSON.stringify({ type: "abort" })}\n`);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Best-effort.
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
wakeSubmissionWaiters() {
|
|
215
|
+
const waiters = this.submissionWaiters;
|
|
216
|
+
this.submissionWaiters = [];
|
|
217
|
+
for (const waiter of waiters) {
|
|
218
|
+
waiter();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function killGroup(pid, signal) {
|
|
223
|
+
try {
|
|
224
|
+
process.kill(-pid, signal);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Group signals are unsupported here; the leader still needs it.
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
process.kill(pid, signal);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
// Already gone.
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function throwIfAborted(signal) {
|
|
238
|
+
if (signal.aborted) {
|
|
239
|
+
throw signal.reason ?? new Error("Workflow step aborted");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
async function waitForExit(child, timeoutMs) {
|
|
243
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return await new Promise((resolve) => {
|
|
247
|
+
const timer = setTimeout(() => resolve(false), timeoutMs);
|
|
248
|
+
child.once("exit", () => {
|
|
249
|
+
clearTimeout(timer);
|
|
250
|
+
resolve(true);
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=rpc-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc-executor.js","sourceRoot":"","sources":["../../src/host/rpc-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { HostProcessRegistry } from "./processes.js";
|
|
2
|
+
export type WorkflowHostOptions = {
|
|
3
|
+
cwd: string;
|
|
4
|
+
runnerId?: string;
|
|
5
|
+
/** Explicit store path; defaults to the project-scoped controller store. */
|
|
6
|
+
storeFile?: string;
|
|
7
|
+
/** Explicit run-bundle root; defaults to the shared runs directory. */
|
|
8
|
+
runsDir?: string;
|
|
9
|
+
registry?: HostProcessRegistry;
|
|
10
|
+
piArgs?: string[];
|
|
11
|
+
/** Extra environment for headless children (for example a test provider). */
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
/** Poll interval for the claim loop; tests use a faster cadence. */
|
|
14
|
+
claimPollMs?: number;
|
|
15
|
+
onLog?: (message: string) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The always-on runner: claims parked workflow runs and reconciles durable
|
|
19
|
+
* controllers without a Pi session. Conversation nodes execute in headless
|
|
20
|
+
* `pi --mode rpc` children. Everything the host does is recoverable: claims
|
|
21
|
+
* expire, bundles fence stale writers, and child processes are reaped by
|
|
22
|
+
* the next host.
|
|
23
|
+
*/
|
|
24
|
+
export declare class WorkflowHost {
|
|
25
|
+
private readonly options;
|
|
26
|
+
private readonly runnerId;
|
|
27
|
+
private readonly registry;
|
|
28
|
+
private readonly store;
|
|
29
|
+
private readonly childRunStore;
|
|
30
|
+
private manager;
|
|
31
|
+
private pollTimer;
|
|
32
|
+
private readonly activeRuns;
|
|
33
|
+
private readonly migrationBlockedRuns;
|
|
34
|
+
private readonly schedulerExecutors;
|
|
35
|
+
/** Runs whose resume refused (edited source); skipped until a host restart. */
|
|
36
|
+
private readonly skippedRuns;
|
|
37
|
+
private stopping;
|
|
38
|
+
private readonly stateDir;
|
|
39
|
+
constructor(options: WorkflowHostOptions);
|
|
40
|
+
private log;
|
|
41
|
+
/** Take the advisory lock, reap orphans, and start claiming. */
|
|
42
|
+
start(): Promise<void>;
|
|
43
|
+
/** Drain: stop claiming, park in-flight runs, stop controllers, kill children. */
|
|
44
|
+
stop(): Promise<void>;
|
|
45
|
+
private readonly parkedEngines;
|
|
46
|
+
private claimOnce;
|
|
47
|
+
private runClaimed;
|
|
48
|
+
private failUnresumable;
|
|
49
|
+
private recordEvent;
|
|
50
|
+
}
|