@clemrig/factory 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +198 -2
- package/dist/app/doctor.d.ts +20 -0
- package/dist/app/doctor.js +38 -0
- package/dist/app/doctor.js.map +1 -0
- package/dist/app/factory.d.ts +12 -0
- package/dist/app/factory.js +22 -0
- package/dist/app/factory.js.map +1 -0
- package/dist/app/init.d.ts +6 -0
- package/dist/app/init.js +15 -0
- package/dist/app/init.js.map +1 -0
- package/dist/app/run.d.ts +24 -0
- package/dist/app/run.js +100 -0
- package/dist/app/run.js.map +1 -0
- package/dist/app/runs.d.ts +36 -0
- package/dist/app/runs.js +66 -0
- package/dist/app/runs.js.map +1 -0
- package/dist/cli/application.d.ts +6 -0
- package/dist/cli/application.js +63 -0
- package/dist/cli/application.js.map +1 -0
- package/dist/cli/args.d.ts +12 -0
- package/dist/cli/args.js +45 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/doctor.d.ts +5 -0
- package/dist/cli/doctor.js +33 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/help.d.ts +1 -0
- package/dist/cli/help.js +17 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/init.d.ts +6 -0
- package/dist/cli/init.js +18 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/launcher.d.ts +5 -0
- package/dist/cli/launcher.js +55 -0
- package/dist/cli/launcher.js.map +1 -0
- package/dist/cli/reporter.d.ts +17 -0
- package/dist/cli/reporter.js +123 -0
- package/dist/cli/reporter.js.map +1 -0
- package/dist/cli/run.d.ts +9 -0
- package/dist/cli/run.js +39 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/status.d.ts +4 -0
- package/dist/cli/status.js +15 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/ui.d.ts +3 -0
- package/dist/cli/ui.js +18 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/engine/metrics.d.ts +45 -0
- package/dist/engine/metrics.js +60 -0
- package/dist/engine/metrics.js.map +1 -0
- package/dist/engine/primitives.d.ts +34 -0
- package/dist/engine/primitives.js +81 -0
- package/dist/engine/primitives.js.map +1 -0
- package/dist/engine/profiles.d.ts +53 -0
- package/dist/engine/profiles.js +117 -0
- package/dist/engine/profiles.js.map +1 -0
- package/dist/engine/runner.d.ts +13 -0
- package/dist/engine/runner.js +157 -0
- package/dist/engine/runner.js.map +1 -0
- package/dist/engine/types.d.ts +194 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/workflow.d.ts +18 -0
- package/dist/engine/workflow.js +196 -0
- package/dist/engine/workflow.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -0
- package/dist/system/environment.d.ts +2 -0
- package/dist/system/environment.js +13 -0
- package/dist/system/environment.js.map +1 -0
- package/dist/system/factory.d.ts +16 -0
- package/dist/system/factory.js +62 -0
- package/dist/system/factory.js.map +1 -0
- package/dist/system/process.d.ts +21 -0
- package/dist/system/process.js +238 -0
- package/dist/system/process.js.map +1 -0
- package/dist/system/runtimes/adapter.d.ts +90 -0
- package/dist/system/runtimes/adapter.js +20 -0
- package/dist/system/runtimes/adapter.js.map +1 -0
- package/dist/system/runtimes/agent-runtime.d.ts +45 -0
- package/dist/system/runtimes/agent-runtime.js +184 -0
- package/dist/system/runtimes/agent-runtime.js.map +1 -0
- package/dist/system/runtimes/claude-code.d.ts +10 -0
- package/dist/system/runtimes/claude-code.js +383 -0
- package/dist/system/runtimes/claude-code.js.map +1 -0
- package/dist/system/runtimes/inspect.d.ts +25 -0
- package/dist/system/runtimes/inspect.js +129 -0
- package/dist/system/runtimes/inspect.js.map +1 -0
- package/dist/system/runtimes/pi.d.ts +7 -0
- package/dist/system/runtimes/pi.js +235 -0
- package/dist/system/runtimes/pi.js.map +1 -0
- package/dist/system/runtimes/protocol.d.ts +9 -0
- package/dist/system/runtimes/protocol.js +38 -0
- package/dist/system/runtimes/protocol.js.map +1 -0
- package/dist/system/runtimes/registry.d.ts +5 -0
- package/dist/system/runtimes/registry.js +5 -0
- package/dist/system/runtimes/registry.js.map +1 -0
- package/dist/system/store.d.ts +20 -0
- package/dist/system/store.js +126 -0
- package/dist/system/store.js.map +1 -0
- package/dist/system/templates.d.ts +8 -0
- package/dist/system/templates.js +30 -0
- package/dist/system/templates.js.map +1 -0
- package/dist/ui/server.d.ts +8 -0
- package/dist/ui/server.js +111 -0
- package/dist/ui/server.js.map +1 -0
- package/dist/ui/static/dashboard.js +266 -0
- package/dist/ui/static/follow.js +67 -0
- package/dist/ui/static/index.html +20 -0
- package/dist/ui/static/style.css +166 -0
- package/dist/ui/static/timeline.js +180 -0
- package/package.json +52 -4
- package/templates/init/factory.ts +4 -0
- package/templates/init/gitignore +3 -0
- package/templates/init/tsconfig.json +13 -0
- package/templates/init/workflows/ask/index.ts +57 -0
- package/templates/init/workflows/ask/prompts/answer.md +7 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
const MAX_CAPTURE_BYTES = 2 * 1024 * 1024;
|
|
3
|
+
const MAX_LINE_BYTES = 32 * 1024 * 1024;
|
|
4
|
+
const KILL_GRACE_MS = 1_000;
|
|
5
|
+
export class ProcessStartError extends Error {
|
|
6
|
+
constructor(executable, cause) {
|
|
7
|
+
super(`Could not start ${executable}: ${cause.message}`, { cause });
|
|
8
|
+
this.name = "ProcessStartError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export class ProcessInterruptedError extends Error {
|
|
12
|
+
constructor(signal, executable) {
|
|
13
|
+
super(`Process interrupted by ${signal}: ${executable}`);
|
|
14
|
+
this.name = "ProcessInterruptedError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
class BoundedCapture {
|
|
18
|
+
#chunks = [];
|
|
19
|
+
#length = 0;
|
|
20
|
+
#dropped = false;
|
|
21
|
+
append(chunk) {
|
|
22
|
+
if (chunk.length === 0)
|
|
23
|
+
return;
|
|
24
|
+
if (chunk.length >= MAX_CAPTURE_BYTES) {
|
|
25
|
+
this.#dropped ||= this.#length > 0 || chunk.length > MAX_CAPTURE_BYTES;
|
|
26
|
+
this.#chunks = [chunk.subarray(chunk.length - MAX_CAPTURE_BYTES)];
|
|
27
|
+
this.#length = MAX_CAPTURE_BYTES;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.#chunks.push(chunk);
|
|
31
|
+
this.#length += chunk.length;
|
|
32
|
+
while (this.#length > MAX_CAPTURE_BYTES) {
|
|
33
|
+
const first = this.#chunks.shift();
|
|
34
|
+
if (!first)
|
|
35
|
+
break;
|
|
36
|
+
this.#length -= first.length;
|
|
37
|
+
this.#dropped = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
get truncated() {
|
|
41
|
+
return this.#dropped;
|
|
42
|
+
}
|
|
43
|
+
text() {
|
|
44
|
+
const prefix = this.#dropped ? "[earlier process output truncated]\n" : "";
|
|
45
|
+
return prefix + Buffer.concat(this.#chunks, this.#length).toString("utf8");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function signalGroup(child, signal) {
|
|
49
|
+
if (!child.pid)
|
|
50
|
+
return;
|
|
51
|
+
if (process.platform !== "win32") {
|
|
52
|
+
try {
|
|
53
|
+
process.kill(-child.pid, signal);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// The process group can already be gone.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
child.kill(signal);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// The child can already be gone.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function groupStillExists(child) {
|
|
68
|
+
if (process.platform === "win32" || !child.pid)
|
|
69
|
+
return false;
|
|
70
|
+
try {
|
|
71
|
+
process.kill(-child.pid, 0);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Children still running, so that a forced exit does not leave them behind. */
|
|
79
|
+
const running = new Set();
|
|
80
|
+
/** Kills every running child's process group at once, before a forced exit. */
|
|
81
|
+
export function killProcessGroups() {
|
|
82
|
+
for (const child of running)
|
|
83
|
+
signalGroup(child, "SIGKILL");
|
|
84
|
+
}
|
|
85
|
+
/** Runs `work` with `dir` as the process's working directory, then restores the previous one. */
|
|
86
|
+
export async function inDirectory(dir, work) {
|
|
87
|
+
const previous = process.cwd();
|
|
88
|
+
process.chdir(dir);
|
|
89
|
+
try {
|
|
90
|
+
return await work();
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
process.chdir(previous);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Runs an executable without a shell. A failure terminates the entire child group
|
|
98
|
+
* and settles only after the child closes and the TERM→KILL grace period finishes.
|
|
99
|
+
*/
|
|
100
|
+
export async function runProcess(command, cwd, timeoutMs, onLine, stdin) {
|
|
101
|
+
if (command.length === 0 || !command[0])
|
|
102
|
+
throw new Error("Process command must include an executable");
|
|
103
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
|
|
104
|
+
throw new Error("Process timeout must be positive");
|
|
105
|
+
const executable = command[0];
|
|
106
|
+
return new Promise((resolve, reject) => {
|
|
107
|
+
const child = spawn(executable, command.slice(1), {
|
|
108
|
+
cwd,
|
|
109
|
+
detached: process.platform !== "win32",
|
|
110
|
+
shell: false,
|
|
111
|
+
stdio: [stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
112
|
+
});
|
|
113
|
+
running.add(child);
|
|
114
|
+
const stdout = new BoundedCapture();
|
|
115
|
+
const stderr = new BoundedCapture();
|
|
116
|
+
let pending = Buffer.alloc(0);
|
|
117
|
+
let failure;
|
|
118
|
+
let closeResult;
|
|
119
|
+
let terminating = false;
|
|
120
|
+
let killSent = false;
|
|
121
|
+
let killTimer;
|
|
122
|
+
let settled = false;
|
|
123
|
+
const onParentSignal = (signal) => {
|
|
124
|
+
requestTermination(new ProcessInterruptedError(signal, executable));
|
|
125
|
+
};
|
|
126
|
+
const cleanup = () => {
|
|
127
|
+
running.delete(child);
|
|
128
|
+
clearTimeout(timeout);
|
|
129
|
+
if (killTimer)
|
|
130
|
+
clearTimeout(killTimer);
|
|
131
|
+
process.removeListener("SIGINT", onParentSignal);
|
|
132
|
+
process.removeListener("SIGTERM", onParentSignal);
|
|
133
|
+
};
|
|
134
|
+
const settle = () => {
|
|
135
|
+
if (settled || !closeResult || (terminating && !killSent))
|
|
136
|
+
return;
|
|
137
|
+
settled = true;
|
|
138
|
+
cleanup();
|
|
139
|
+
if (failure) {
|
|
140
|
+
reject(failure);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
resolve({
|
|
144
|
+
exitCode: closeResult.code ?? (closeResult.signal ? 1 : 0),
|
|
145
|
+
stdout: stdout.text(),
|
|
146
|
+
stderr: stderr.text(),
|
|
147
|
+
stdoutTruncated: stdout.truncated,
|
|
148
|
+
stderrTruncated: stderr.truncated,
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const sendKill = () => {
|
|
152
|
+
killTimer = undefined;
|
|
153
|
+
killSent = true;
|
|
154
|
+
signalGroup(child, "SIGKILL");
|
|
155
|
+
settle();
|
|
156
|
+
};
|
|
157
|
+
const requestTermination = (error) => {
|
|
158
|
+
if (!failure || error instanceof ProcessInterruptedError)
|
|
159
|
+
failure = error;
|
|
160
|
+
if (terminating)
|
|
161
|
+
return;
|
|
162
|
+
terminating = true;
|
|
163
|
+
signalGroup(child, "SIGTERM");
|
|
164
|
+
killTimer = setTimeout(sendKill, KILL_GRACE_MS);
|
|
165
|
+
};
|
|
166
|
+
const timeout = setTimeout(() => {
|
|
167
|
+
requestTermination(new Error(`Process timed out after ${timeoutMs}ms: ${executable}`));
|
|
168
|
+
}, timeoutMs);
|
|
169
|
+
timeout.unref();
|
|
170
|
+
process.once("SIGINT", onParentSignal);
|
|
171
|
+
process.once("SIGTERM", onParentSignal);
|
|
172
|
+
child.once("error", (error) => {
|
|
173
|
+
requestTermination(new ProcessStartError(executable, error));
|
|
174
|
+
});
|
|
175
|
+
if (stdin !== undefined) {
|
|
176
|
+
if (!child.stdin)
|
|
177
|
+
requestTermination(new Error("Process stdin is unavailable"));
|
|
178
|
+
else {
|
|
179
|
+
child.stdin.once("error", (error) => {
|
|
180
|
+
requestTermination(new Error(`Could not write process stdin: ${error.message}`, {
|
|
181
|
+
cause: error,
|
|
182
|
+
}));
|
|
183
|
+
});
|
|
184
|
+
child.stdin.end(stdin);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!child.stdout || !child.stderr)
|
|
188
|
+
requestTermination(new Error("Process output streams are unavailable"));
|
|
189
|
+
child.stdout?.on("data", (chunk) => {
|
|
190
|
+
stdout.append(chunk);
|
|
191
|
+
if (!onLine || failure)
|
|
192
|
+
return;
|
|
193
|
+
pending = Buffer.concat([pending, chunk]);
|
|
194
|
+
while (!failure) {
|
|
195
|
+
const newline = pending.indexOf(0x0a);
|
|
196
|
+
if (newline < 0)
|
|
197
|
+
break;
|
|
198
|
+
const line = pending
|
|
199
|
+
.subarray(0, newline)
|
|
200
|
+
.toString("utf8")
|
|
201
|
+
.replace(/\r$/, "");
|
|
202
|
+
pending = pending.subarray(newline + 1);
|
|
203
|
+
if (Buffer.byteLength(line) > MAX_LINE_BYTES) {
|
|
204
|
+
requestTermination(new Error(`Process output line exceeded ${MAX_LINE_BYTES} byte limit`));
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
onLine(line);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
requestTermination(error instanceof Error ? error : new Error(String(error)));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!failure && pending.length > MAX_LINE_BYTES)
|
|
215
|
+
requestTermination(new Error(`Process output line exceeded ${MAX_LINE_BYTES} byte limit`));
|
|
216
|
+
});
|
|
217
|
+
child.stderr?.on("data", (chunk) => stderr.append(chunk));
|
|
218
|
+
child.once("close", (code, signal) => {
|
|
219
|
+
closeResult = { code, signal };
|
|
220
|
+
if (!failure && groupStillExists(child))
|
|
221
|
+
requestTermination(new Error(`Process group remained after ${executable} exited`));
|
|
222
|
+
if (!failure && onLine && pending.length > 0) {
|
|
223
|
+
if (pending.length > MAX_LINE_BYTES)
|
|
224
|
+
requestTermination(new Error(`Process output line exceeded ${MAX_LINE_BYTES} byte limit`));
|
|
225
|
+
else {
|
|
226
|
+
try {
|
|
227
|
+
onLine(pending.toString("utf8").replace(/\r$/, ""));
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
requestTermination(error instanceof Error ? error : new Error(String(error)));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
settle();
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/system/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { AgentUsage, TokenCounts } from "../../engine/metrics.js";
|
|
3
|
+
import type { ResolvedProfile, Runtime } from "../../engine/profiles.js";
|
|
4
|
+
/** A runtime's profile, with its defaults applied. */
|
|
5
|
+
export type ProfileOf<R extends Runtime> = Extract<ResolvedProfile, {
|
|
6
|
+
runtime: R;
|
|
7
|
+
}>;
|
|
8
|
+
/** One agent call, as a runtime prepares it. */
|
|
9
|
+
export interface RuntimeCall<R extends Runtime> {
|
|
10
|
+
profile: ProfileOf<R>;
|
|
11
|
+
/** The workflow's prompt, appended to the runtime's own system prompt. */
|
|
12
|
+
systemPrompt: string;
|
|
13
|
+
/** The conversation within the run. */
|
|
14
|
+
session: string;
|
|
15
|
+
/** The run, and the directory where it keeps this runtime's sessions. */
|
|
16
|
+
sessions: {
|
|
17
|
+
runId: string;
|
|
18
|
+
directory: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** What an output line of a runtime means for the call, the same for every runtime. */
|
|
22
|
+
export type RuntimeEvent = {
|
|
23
|
+
type: "tool";
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
status: "started" | "completed" | "failed";
|
|
27
|
+
}
|
|
28
|
+
/** A model response's tokens as the call goes, before the figures announced at its end. */
|
|
29
|
+
| {
|
|
30
|
+
type: "response";
|
|
31
|
+
tokens: TokenCounts;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A measure as the runtime announces it: one response's final figures, or its
|
|
35
|
+
* session's total so far; `undefined` when nothing measurable was announced.
|
|
36
|
+
*/
|
|
37
|
+
| {
|
|
38
|
+
type: "usage";
|
|
39
|
+
scope: "response" | "session";
|
|
40
|
+
usage: AgentUsage | undefined;
|
|
41
|
+
}
|
|
42
|
+
/** A customization of the session that does not change what the agent can do. */
|
|
43
|
+
| {
|
|
44
|
+
type: "warning";
|
|
45
|
+
message: string;
|
|
46
|
+
}
|
|
47
|
+
/** The runtime reported that the call failed: it stops there. */
|
|
48
|
+
| {
|
|
49
|
+
type: "failure";
|
|
50
|
+
message: string;
|
|
51
|
+
}
|
|
52
|
+
/** The agent's final text. */
|
|
53
|
+
| {
|
|
54
|
+
type: "result";
|
|
55
|
+
text: string;
|
|
56
|
+
};
|
|
57
|
+
/** A prepared call: the arguments after the executable, and the reader of its output. */
|
|
58
|
+
export interface RuntimeProcess {
|
|
59
|
+
args: string[];
|
|
60
|
+
/** Reads one parsed output line; throws on output the adapter cannot rely on. */
|
|
61
|
+
read(event: unknown): RuntimeEvent[];
|
|
62
|
+
}
|
|
63
|
+
/** The connection a profile would use: connected or not, and which one, never the account. */
|
|
64
|
+
export interface Connection {
|
|
65
|
+
connected: boolean;
|
|
66
|
+
detail: string;
|
|
67
|
+
}
|
|
68
|
+
/** What factory needs from an agent runtime. */
|
|
69
|
+
export interface RuntimeAdapter<R extends Runtime> {
|
|
70
|
+
name: R;
|
|
71
|
+
/** As the operator reads it. */
|
|
72
|
+
label: string;
|
|
73
|
+
/** Found in the PATH. */
|
|
74
|
+
executable: string;
|
|
75
|
+
/** The oldest version validated by a real call; `--version` prints it first. */
|
|
76
|
+
minimumVersion: string;
|
|
77
|
+
/** The command that reports a profile's connection without a provider request, and how to read its output. */
|
|
78
|
+
connection(profile: ProfileOf<R>): {
|
|
79
|
+
args: string[];
|
|
80
|
+
read(stdout: string): Connection;
|
|
81
|
+
};
|
|
82
|
+
/** The model a call is recorded with. */
|
|
83
|
+
model(profile: ProfileOf<R>): string;
|
|
84
|
+
start(call: RuntimeCall<R>): Promise<RuntimeProcess>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* An output event the adapter relies on, validated: a missing or malformed field
|
|
88
|
+
* stops the call with the event and the field, rather than being misread.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseEvent<T>(label: string, schema: z.ZodType<T>, event: unknown): T;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An output event the adapter relies on, validated: a missing or malformed field
|
|
3
|
+
* stops the call with the event and the field, rather than being misread.
|
|
4
|
+
*/
|
|
5
|
+
export function parseEvent(label, schema, event) {
|
|
6
|
+
const parsed = schema.safeParse(event);
|
|
7
|
+
if (parsed.success)
|
|
8
|
+
return parsed.data;
|
|
9
|
+
const type = typeof event === "object" &&
|
|
10
|
+
event !== null &&
|
|
11
|
+
"type" in event &&
|
|
12
|
+
typeof event.type === "string"
|
|
13
|
+
? `${event.type} `
|
|
14
|
+
: "";
|
|
15
|
+
const issues = parsed.error.issues
|
|
16
|
+
.map(({ path, message }) => `${path.join(".") || "value"}: ${message}`)
|
|
17
|
+
.join("; ");
|
|
18
|
+
throw new Error(`${label} emitted an unexpected ${type}event: ${issues}`);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/system/runtimes/adapter.ts"],"names":[],"mappings":"AA+EA;;;GAGG;AACH,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,MAAoB,EACpB,KAAc;IAEd,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACvC,MAAM,IAAI,GACR,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC5B,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG;QAClB,CAAC,CAAC,EAAE,CAAC;IACT,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;SAC/B,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;SACtE,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,0BAA0B,IAAI,UAAU,MAAM,EAAE,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type UsageReport } from "../../engine/metrics.js";
|
|
2
|
+
import { type Runtime } from "../../engine/profiles.js";
|
|
3
|
+
import type { AgentPort, AgentRequest, RecordActivity } from "../../engine/types.js";
|
|
4
|
+
import type { RuntimeAdapter, RuntimeCall } from "./adapter.js";
|
|
5
|
+
export interface CallOptions {
|
|
6
|
+
/** The repository the agent works in. */
|
|
7
|
+
repo: string;
|
|
8
|
+
/** The executable's absolute path; by default its name, looked up in the PATH. */
|
|
9
|
+
executable?: string;
|
|
10
|
+
/** Records the call's activity under the calling stage. */
|
|
11
|
+
record?: RecordActivity;
|
|
12
|
+
/** Each measure as the runtime announces it; one unmeasured report when a started call announced none. */
|
|
13
|
+
onUsage?: (report: UsageReport) => void | Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One agent call, the same for every runtime: the request goes through standard
|
|
17
|
+
* input, the adapter reads each output line, and the final text is the result.
|
|
18
|
+
* The call's activity is recorded as it goes; a call that started always reports
|
|
19
|
+
* its measures, even when it fails.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runCall<R extends Runtime>(adapter: RuntimeAdapter<R>, call: RuntimeCall<R> & {
|
|
22
|
+
context: unknown;
|
|
23
|
+
schema: Record<string, unknown>;
|
|
24
|
+
}, options: CallOptions): Promise<unknown>;
|
|
25
|
+
export interface AgentRuntimeOptions extends Pick<CallOptions, "onUsage"> {
|
|
26
|
+
/** The repository agents work in. */
|
|
27
|
+
dir: string;
|
|
28
|
+
/** Relative skill, extension and MCP command paths of profiles belong to it. */
|
|
29
|
+
factoryDir: string;
|
|
30
|
+
/** Prompt texts by name. */
|
|
31
|
+
prompts: Record<string, string>;
|
|
32
|
+
/** The run, whose directory keeps each runtime's sessions in a subdirectory of its name. */
|
|
33
|
+
run: {
|
|
34
|
+
id: string;
|
|
35
|
+
directory: string;
|
|
36
|
+
};
|
|
37
|
+
/** The executables checked before the run, by absolute path. */
|
|
38
|
+
executables?: Partial<Record<Runtime, string>>;
|
|
39
|
+
}
|
|
40
|
+
/** Validates each request's profile, then runs it on the runtime the profile selects, with its named prompt. */
|
|
41
|
+
export declare class AgentRuntime implements AgentPort {
|
|
42
|
+
#private;
|
|
43
|
+
constructor(options: AgentRuntimeOptions);
|
|
44
|
+
execute(request: AgentRequest, record?: RecordActivity): Promise<unknown>;
|
|
45
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { mkdir } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { sumUsage, } from "../../engine/metrics.js";
|
|
4
|
+
import { resolveProfile, } from "../../engine/profiles.js";
|
|
5
|
+
import { ProcessStartError, runProcess } from "../process.js";
|
|
6
|
+
import { agentPrompt, parseAgentJson } from "./protocol.js";
|
|
7
|
+
import { runtimes } from "./registry.js";
|
|
8
|
+
/** The figures announced for the call: its session's total, or the sum of its responses. */
|
|
9
|
+
function callUsage(reports) {
|
|
10
|
+
const session = reports.findLast((report) => report.scope === "session" && report.usage);
|
|
11
|
+
if (session?.usage)
|
|
12
|
+
return { scope: "session", usage: session.usage };
|
|
13
|
+
const responses = reports.flatMap(({ usage }) => (usage ? [usage] : []));
|
|
14
|
+
return responses.length ? { scope: "call", usage: sumUsage(responses) } : {};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One agent call, the same for every runtime: the request goes through standard
|
|
18
|
+
* input, the adapter reads each output line, and the final text is the result.
|
|
19
|
+
* The call's activity is recorded as it goes; a call that started always reports
|
|
20
|
+
* its measures, even when it fails.
|
|
21
|
+
*/
|
|
22
|
+
export async function runCall(adapter, call, options) {
|
|
23
|
+
const { label } = adapter;
|
|
24
|
+
const { record, onUsage } = options;
|
|
25
|
+
const session = `${adapter.name}:${call.session}`;
|
|
26
|
+
await mkdir(call.sessions.directory, { recursive: true, mode: 0o700 });
|
|
27
|
+
const started = await adapter.start(call);
|
|
28
|
+
// A request that cannot be written fails before the call starts.
|
|
29
|
+
const request = agentPrompt(call);
|
|
30
|
+
record?.({
|
|
31
|
+
kind: "call",
|
|
32
|
+
status: "started",
|
|
33
|
+
runtime: adapter.name,
|
|
34
|
+
model: adapter.model(call.profile),
|
|
35
|
+
session: call.session,
|
|
36
|
+
});
|
|
37
|
+
const reports = [];
|
|
38
|
+
const tools = new Map();
|
|
39
|
+
let text;
|
|
40
|
+
let running = true;
|
|
41
|
+
let succeeded = false;
|
|
42
|
+
try {
|
|
43
|
+
const exit = await runProcess([options.executable ?? adapter.executable, ...started.args], options.repo, call.profile.timeoutMs, (line) => {
|
|
44
|
+
if (!line)
|
|
45
|
+
return;
|
|
46
|
+
let event;
|
|
47
|
+
try {
|
|
48
|
+
event = JSON.parse(line);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new Error(`${label} emitted invalid JSONL output`);
|
|
52
|
+
}
|
|
53
|
+
for (const item of started.read(event))
|
|
54
|
+
switch (item.type) {
|
|
55
|
+
case "tool": {
|
|
56
|
+
const { id, name, status } = item;
|
|
57
|
+
if (status === "started") {
|
|
58
|
+
tools.set(id, Date.now());
|
|
59
|
+
record?.({ kind: "tool", id, name, status });
|
|
60
|
+
}
|
|
61
|
+
else
|
|
62
|
+
record?.({
|
|
63
|
+
kind: "tool",
|
|
64
|
+
id,
|
|
65
|
+
name,
|
|
66
|
+
status,
|
|
67
|
+
durationMs: Date.now() - (tools.get(id) ?? Date.now()),
|
|
68
|
+
});
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
case "response":
|
|
72
|
+
record?.({
|
|
73
|
+
kind: "response",
|
|
74
|
+
tokens: item.tokens,
|
|
75
|
+
provisional: true,
|
|
76
|
+
});
|
|
77
|
+
break;
|
|
78
|
+
case "usage":
|
|
79
|
+
reports.push({ session, scope: item.scope, usage: item.usage });
|
|
80
|
+
if (item.scope === "response" && item.usage) {
|
|
81
|
+
const { costUsd, ...tokens } = item.usage;
|
|
82
|
+
record?.({
|
|
83
|
+
kind: "response",
|
|
84
|
+
tokens,
|
|
85
|
+
costUsd,
|
|
86
|
+
provisional: false,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
case "warning":
|
|
91
|
+
record?.({ kind: "warning", message: item.message });
|
|
92
|
+
break;
|
|
93
|
+
case "failure":
|
|
94
|
+
throw new Error(item.message);
|
|
95
|
+
case "result":
|
|
96
|
+
text = item.text;
|
|
97
|
+
}
|
|
98
|
+
}, request);
|
|
99
|
+
if (exit.exitCode !== 0)
|
|
100
|
+
throw new Error(`${label} exited with code ${exit.exitCode}: ${exit.stderr.trim() || "no error output"}`);
|
|
101
|
+
if (text === undefined)
|
|
102
|
+
throw new Error(`${label} completed without a final result`);
|
|
103
|
+
succeeded = true;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (error instanceof ProcessStartError)
|
|
107
|
+
running = false;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
for (const report of reports)
|
|
112
|
+
await onUsage?.(report);
|
|
113
|
+
if (running && !reports.length)
|
|
114
|
+
await onUsage?.({ session, scope: "response", usage: undefined });
|
|
115
|
+
record?.({
|
|
116
|
+
kind: "call",
|
|
117
|
+
status: succeeded ? "completed" : "failed",
|
|
118
|
+
runtime: adapter.name,
|
|
119
|
+
...callUsage(reports),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
return parseAgentJson(text);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// The workflow's gate owns output-format feedback and retry routing.
|
|
127
|
+
return text;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Relative skill, extension and MCP command paths belong to `.factory/`; a bare command stays a PATH lookup. */
|
|
131
|
+
function resolvePaths(profile, factoryDir) {
|
|
132
|
+
if (profile.runtime === "pi")
|
|
133
|
+
return {
|
|
134
|
+
...profile,
|
|
135
|
+
skills: profile.skills.map((path) => resolve(factoryDir, path)),
|
|
136
|
+
extensions: profile.extensions.map((path) => resolve(factoryDir, path)),
|
|
137
|
+
};
|
|
138
|
+
const command = (value) => value.includes("/") && !isAbsolute(value)
|
|
139
|
+
? resolve(factoryDir, value)
|
|
140
|
+
: value;
|
|
141
|
+
return {
|
|
142
|
+
...profile,
|
|
143
|
+
mcpServers: Object.fromEntries(Object.entries(profile.mcpServers).map(([name, server]) => [
|
|
144
|
+
name,
|
|
145
|
+
{ ...server, command: command(server.command) },
|
|
146
|
+
])),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/** Validates each request's profile, then runs it on the runtime the profile selects, with its named prompt. */
|
|
150
|
+
export class AgentRuntime {
|
|
151
|
+
#options;
|
|
152
|
+
constructor(options) {
|
|
153
|
+
this.#options = options;
|
|
154
|
+
}
|
|
155
|
+
async execute(request, record) {
|
|
156
|
+
const { dir, factoryDir, prompts, run, onUsage, executables } = this.#options;
|
|
157
|
+
const systemPrompt = Object.hasOwn(prompts, request.prompt)
|
|
158
|
+
? prompts[request.prompt]
|
|
159
|
+
: undefined;
|
|
160
|
+
if (systemPrompt === undefined)
|
|
161
|
+
throw new Error(`No prompt loaded: ${request.prompt}`);
|
|
162
|
+
const profile = resolvePaths(resolveProfile(request.profile), factoryDir);
|
|
163
|
+
const options = {
|
|
164
|
+
repo: dir,
|
|
165
|
+
executable: executables?.[profile.runtime],
|
|
166
|
+
record,
|
|
167
|
+
onUsage,
|
|
168
|
+
};
|
|
169
|
+
const call = {
|
|
170
|
+
systemPrompt,
|
|
171
|
+
session: request.session,
|
|
172
|
+
sessions: {
|
|
173
|
+
runId: run.id,
|
|
174
|
+
directory: join(run.directory, profile.runtime),
|
|
175
|
+
},
|
|
176
|
+
context: request.context,
|
|
177
|
+
schema: request.schema,
|
|
178
|
+
};
|
|
179
|
+
return profile.runtime === "pi"
|
|
180
|
+
? runCall(runtimes.pi, { ...call, profile }, options)
|
|
181
|
+
: runCall(runtimes["claude-code"], { ...call, profile }, options);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=agent-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runtime.js","sourceRoot":"","sources":["../../../src/system/runtimes/agent-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type RuntimeAdapter } from "./adapter.js";
|
|
2
|
+
/** Claude Code session IDs are UUIDs: a stable one per session name. */
|
|
3
|
+
export declare function claudeCodeSessionId(name: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Claude Code in print mode, in a session that holds only the profile's tools and
|
|
6
|
+
* MCP servers. Its sessions need UUIDs: the run keeps a marker per session, so
|
|
7
|
+
* that the next call resumes it. At the end of each call, Claude Code announces
|
|
8
|
+
* its session's total, which is reported as it is.
|
|
9
|
+
*/
|
|
10
|
+
export declare const claudeCode: RuntimeAdapter<"claude-code">;
|