@acpus/runtime 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 +7 -0
- package/dist/artifacts.d.ts +30 -0
- package/dist/artifacts.d.ts.map +1 -0
- package/dist/artifacts.js +97 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/client.d.ts +54 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +159 -0
- package/dist/client.js.map +1 -0
- package/dist/evaluator.d.ts +37 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +101 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/executors/agent.d.ts +74 -0
- package/dist/executors/agent.d.ts.map +1 -0
- package/dist/executors/agent.js +401 -0
- package/dist/executors/agent.js.map +1 -0
- package/dist/executors/mock-program.d.ts +24 -0
- package/dist/executors/mock-program.d.ts.map +1 -0
- package/dist/executors/mock-program.js +79 -0
- package/dist/executors/mock-program.js.map +1 -0
- package/dist/executors/program.d.ts +21 -0
- package/dist/executors/program.d.ts.map +1 -0
- package/dist/executors/program.js +178 -0
- package/dist/executors/program.js.map +1 -0
- package/dist/executors/types.d.ts +26 -0
- package/dist/executors/types.d.ts.map +1 -0
- package/dist/executors/types.js +2 -0
- package/dist/executors/types.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/interpreter.d.ts +186 -0
- package/dist/interpreter.d.ts.map +1 -0
- package/dist/interpreter.js +1500 -0
- package/dist/interpreter.js.map +1 -0
- package/dist/keys.d.ts +36 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +59 -0
- package/dist/keys.js.map +1 -0
- package/dist/state-machine.d.ts +27 -0
- package/dist/state-machine.d.ts.map +1 -0
- package/dist/state-machine.js +87 -0
- package/dist/state-machine.js.map +1 -0
- package/dist/store.d.ts +46 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +260 -0
- package/dist/store.js.map +1 -0
- package/dist/supervisor-app.d.ts +27 -0
- package/dist/supervisor-app.d.ts.map +1 -0
- package/dist/supervisor-app.js +548 -0
- package/dist/supervisor-app.js.map +1 -0
- package/dist/supervisor-discovery.d.ts +17 -0
- package/dist/supervisor-discovery.d.ts.map +1 -0
- package/dist/supervisor-discovery.js +186 -0
- package/dist/supervisor-discovery.js.map +1 -0
- package/dist/supervisor-entry.d.ts +11 -0
- package/dist/supervisor-entry.d.ts.map +1 -0
- package/dist/supervisor-entry.js +50 -0
- package/dist/supervisor-entry.js.map +1 -0
- package/dist/supervisor-lock.d.ts +26 -0
- package/dist/supervisor-lock.d.ts.map +1 -0
- package/dist/supervisor-lock.js +49 -0
- package/dist/supervisor-lock.js.map +1 -0
- package/dist/supervisor-runner.d.ts +11 -0
- package/dist/supervisor-runner.d.ts.map +1 -0
- package/dist/supervisor-runner.js +128 -0
- package/dist/supervisor-runner.js.map +1 -0
- package/dist/types.d.ts +230 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validate-input.d.ts +27 -0
- package/dist/validate-input.d.ts.map +1 -0
- package/dist/validate-input.js +56 -0
- package/dist/validate-input.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, resolve } from "node:path";
|
|
5
|
+
import { parseDurationMs } from "@acpus/core";
|
|
6
|
+
import { ExpressionEvaluator } from "../evaluator.js";
|
|
7
|
+
import { Ajv } from "ajv";
|
|
8
|
+
import { jsonrepair } from "jsonrepair";
|
|
9
|
+
/** Fixed runtime prompt used when continuing an existing agent session. */
|
|
10
|
+
const CONTINUATION_PROMPT = "Continue the previous task from where you left off.";
|
|
11
|
+
/** Grace period (ms) to wait for a cooperative cancel before SIGKILL. */
|
|
12
|
+
const DEFAULT_CANCEL_GRACE_MS = 5000;
|
|
13
|
+
/**
|
|
14
|
+
* Drives an ACP agent through the `acpx` CLI. Acpus owns scheduling/state;
|
|
15
|
+
* acpx owns the ACP saved-session lifecycle and dead-pid recovery.
|
|
16
|
+
*
|
|
17
|
+
* - Session name is derived from the resolved node key (stable, unique per
|
|
18
|
+
* loop round / fanout lane / subworkflow nesting).
|
|
19
|
+
* - First run: `sessions ensure` then `prompt -s <session>` with the rendered
|
|
20
|
+
* prompt; continuation: same session with a fixed continuation prompt.
|
|
21
|
+
* - Cancel is cooperative: on abort we run `acpx cancel -s <session>` and wait
|
|
22
|
+
* for the in-flight prompt to settle (SIGKILL only as a last resort).
|
|
23
|
+
* - Output is the concatenation of `agent_message_chunk` text from the ACP
|
|
24
|
+
* NDJSON stream; the full stream is returned as `stdout` for transcript
|
|
25
|
+
* capture by the interpreter.
|
|
26
|
+
*/
|
|
27
|
+
export class AgentExecutor {
|
|
28
|
+
evaluator;
|
|
29
|
+
ajv;
|
|
30
|
+
acpxPath;
|
|
31
|
+
cancelGraceMs;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.evaluator = options?.evaluator ?? new ExpressionEvaluator();
|
|
34
|
+
this.ajv = new Ajv({ allErrors: true, strict: false });
|
|
35
|
+
this.acpxPath = options?.acpxPath;
|
|
36
|
+
this.cancelGraceMs = options?.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;
|
|
37
|
+
}
|
|
38
|
+
async execute({ node, context, signal, nodeKey, prompt: preparedPrompt, continuation, retry, onStream }) {
|
|
39
|
+
const agent = node.metadata.agent;
|
|
40
|
+
if (!agent) {
|
|
41
|
+
return { failureKind: "spawn", error: `Agent step '${node.id}' has no resolved agent definition` };
|
|
42
|
+
}
|
|
43
|
+
const outputSchema = node.metadata.output;
|
|
44
|
+
const sessionName = this.sessionName(context.run_id, nodeKey);
|
|
45
|
+
const timeoutSeconds = this.resolveTimeoutSeconds(node.metadata.timeout);
|
|
46
|
+
// Evaluate local templates before touching acpx. These are deterministic
|
|
47
|
+
// config errors and must not consume output-retry attempts.
|
|
48
|
+
let cwd;
|
|
49
|
+
let env;
|
|
50
|
+
let prompt;
|
|
51
|
+
try {
|
|
52
|
+
cwd = this.resolveCwd(agent.cwd, context);
|
|
53
|
+
env = { ...process.env, ...this.stringEnv(agent.env, context) };
|
|
54
|
+
prompt = preparedPrompt ?? renderAgentRequestPrompt(node, context, this.evaluator, Boolean(continuation), Boolean(retry));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return {
|
|
58
|
+
failureKind: "config",
|
|
59
|
+
error: `Failed to evaluate agent configuration template: ${error instanceof Error ? error.message : String(error)}`
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (signal.aborted) {
|
|
63
|
+
return { partial: true, error: "Aborted before execution", prompt, responseText: "" };
|
|
64
|
+
}
|
|
65
|
+
const invoker = this.resolveInvoker();
|
|
66
|
+
const build = this.argsBuilder(agent, cwd);
|
|
67
|
+
try {
|
|
68
|
+
// Ensure a saved session exists (idempotent). acpx requires a session
|
|
69
|
+
// record before prompt commands route to it.
|
|
70
|
+
const ensureResult = await execa(invoker.command, [...invoker.prefixArgs, ...build([], ["sessions", "ensure", "--name", sessionName])], {
|
|
71
|
+
reject: false,
|
|
72
|
+
env
|
|
73
|
+
});
|
|
74
|
+
if (ensureResult.failed) {
|
|
75
|
+
const exitCode = ensureResult.exitCode ?? 1;
|
|
76
|
+
const stderr = ensureResult.stderr ?? "";
|
|
77
|
+
const detail = stderr || ensureResult.shortMessage || `acpx sessions ensure exited with code ${exitCode}`;
|
|
78
|
+
return { failureKind: "spawn", exitCode, error: detail, prompt, responseText: "", stdout: ensureResult.stdout ?? "", stderr };
|
|
79
|
+
}
|
|
80
|
+
if (signal.aborted) {
|
|
81
|
+
// Best-effort cleanup of the session we just created; fire-and-forget.
|
|
82
|
+
void execa(invoker.command, [...invoker.prefixArgs, ...build([], ["sessions", "close", sessionName])], {
|
|
83
|
+
reject: false,
|
|
84
|
+
env
|
|
85
|
+
}).catch(() => undefined);
|
|
86
|
+
return { partial: true, error: "Aborted before prompt", prompt, responseText: "" };
|
|
87
|
+
}
|
|
88
|
+
// Run the prompt, streaming the ACP protocol as NDJSON.
|
|
89
|
+
const promptGlobalArgs = [...(timeoutSeconds ? ["--timeout", timeoutSeconds] : []), "--format", "json"];
|
|
90
|
+
const promptArgs = [...invoker.prefixArgs, ...build(promptGlobalArgs, ["prompt", "-s", sessionName, prompt])];
|
|
91
|
+
const proc = execa(invoker.command, promptArgs, { reject: false, env });
|
|
92
|
+
proc.stdout?.on("data", (chunk) => onStream?.("stdout", String(chunk)));
|
|
93
|
+
proc.stderr?.on("data", (chunk) => onStream?.("stderr", String(chunk)));
|
|
94
|
+
const cancellation = this.wireCooperativeCancel(proc, signal, invoker, build, sessionName, env);
|
|
95
|
+
const result = await proc;
|
|
96
|
+
cancellation.cleanup();
|
|
97
|
+
const stdout = result.stdout ?? "";
|
|
98
|
+
const stderr = result.stderr ?? "";
|
|
99
|
+
const { text, stopReason } = parseAcpStream(stdout);
|
|
100
|
+
// Cooperative cancel (or any cancelled turn) → paused with partial transcript.
|
|
101
|
+
if (cancellation.cancelled || stopReason === "cancelled") {
|
|
102
|
+
return { partial: true, output: { text }, prompt, responseText: text, stdout, stderr, error: "Aborted" };
|
|
103
|
+
}
|
|
104
|
+
// Spawn failure (no exit code) → non-recoverable.
|
|
105
|
+
if (result.failed && (result.exitCode === undefined || result.exitCode === null)) {
|
|
106
|
+
return { failureKind: "spawn", error: result.shortMessage || "Failed to spawn acpx", prompt, responseText: text, stdout, stderr };
|
|
107
|
+
}
|
|
108
|
+
// Non-zero exit (and not cancelled) → non-recoverable agent failure.
|
|
109
|
+
if (result.exitCode !== 0) {
|
|
110
|
+
return { failureKind: "exit", exitCode: result.exitCode ?? 1, error: stderr || `acpx exited with code ${result.exitCode}`, prompt, responseText: text, stdout, stderr };
|
|
111
|
+
}
|
|
112
|
+
// Assemble structured output. When a schema is declared, extract a JSON
|
|
113
|
+
// object from the (possibly prose-wrapped) reply; failure to extract is a
|
|
114
|
+
// retryable parse failure. Otherwise wrap as { text }.
|
|
115
|
+
let output;
|
|
116
|
+
if (outputSchema) {
|
|
117
|
+
const parsed = extractJson(text);
|
|
118
|
+
if (parsed === undefined) {
|
|
119
|
+
return { failureKind: "parse", error: "Failed to parse agent output as JSON", output: { text }, prompt, responseText: text, stdout, stderr };
|
|
120
|
+
}
|
|
121
|
+
const validate = this.ajv.compile(outputSchema);
|
|
122
|
+
if (!validate(parsed)) {
|
|
123
|
+
return { failureKind: "schema", error: `Output validation failed: ${this.ajv.errorsText(validate.errors)}`, output: parsed, prompt, responseText: text, stdout, stderr };
|
|
124
|
+
}
|
|
125
|
+
output = parsed;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
output = { text };
|
|
129
|
+
}
|
|
130
|
+
return { exitCode: 0, output, prompt, responseText: text, stdout, stderr };
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
return { failureKind: "spawn", error: error instanceof Error ? error.message : String(error), prompt, responseText: "" };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* On abort, request a cooperative `session/cancel` via acpx and schedule a
|
|
138
|
+
* SIGKILL fallback if the in-flight prompt does not settle within the grace
|
|
139
|
+
* period. Returns a handle exposing whether cancel fired and a cleanup fn.
|
|
140
|
+
*/
|
|
141
|
+
wireCooperativeCancel(proc, signal, invoker, build, sessionName, env) {
|
|
142
|
+
const handle = { cancelled: false, cleanup: () => undefined };
|
|
143
|
+
let killTimer;
|
|
144
|
+
const onAbort = () => {
|
|
145
|
+
handle.cancelled = true;
|
|
146
|
+
// Fire-and-forget cooperative cancel; failures are non-fatal.
|
|
147
|
+
void execa(invoker.command, [...invoker.prefixArgs, ...build([], ["cancel", "-s", sessionName])], { reject: false, env }).catch(() => undefined);
|
|
148
|
+
// Last-resort kill if the prompt process refuses to settle.
|
|
149
|
+
killTimer = setTimeout(() => { proc.kill("SIGKILL"); }, this.cancelGraceMs);
|
|
150
|
+
};
|
|
151
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
152
|
+
if (signal.aborted)
|
|
153
|
+
onAbort();
|
|
154
|
+
handle.cleanup = () => {
|
|
155
|
+
if (killTimer)
|
|
156
|
+
clearTimeout(killTimer);
|
|
157
|
+
signal.removeEventListener("abort", onAbort);
|
|
158
|
+
};
|
|
159
|
+
return handle;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build acpx arg lists for a subcommand. Global flags (--cwd, --model,
|
|
163
|
+
* --format) precede the command. For `command` agents the custom ACP server
|
|
164
|
+
* is selected via the `--agent` escape hatch; for `builtin` agents the
|
|
165
|
+
* adapter name is the command prefix.
|
|
166
|
+
*/
|
|
167
|
+
argsBuilder(agent, cwd) {
|
|
168
|
+
const globalBase = [
|
|
169
|
+
"--cwd",
|
|
170
|
+
cwd,
|
|
171
|
+
...(agent.model ? ["--model", agent.model] : [])
|
|
172
|
+
];
|
|
173
|
+
if (agent.type === "command") {
|
|
174
|
+
const command = agent.use ?? "";
|
|
175
|
+
return (global, sub) => ["--agent", command, ...globalBase, ...global, ...sub];
|
|
176
|
+
}
|
|
177
|
+
// builtin (default): adapter name from `use`.
|
|
178
|
+
const adapter = agent.use ?? "";
|
|
179
|
+
return (global, sub) => [...globalBase, ...global, adapter, ...sub];
|
|
180
|
+
}
|
|
181
|
+
/** Resolve how to invoke acpx: an explicit path, or the resolved package bin via node. */
|
|
182
|
+
resolveInvoker() {
|
|
183
|
+
if (this.acpxPath)
|
|
184
|
+
return { command: this.acpxPath, prefixArgs: [] };
|
|
185
|
+
const req = createRequire(import.meta.url);
|
|
186
|
+
const pkgJsonPath = req.resolve("acpx/package.json");
|
|
187
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
188
|
+
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.acpx ?? "dist/cli.js";
|
|
189
|
+
return { command: process.execPath, prefixArgs: [resolve(dirname(pkgJsonPath), bin)] };
|
|
190
|
+
}
|
|
191
|
+
sessionName(runId, nodeKey) {
|
|
192
|
+
return `acpus-${runId}-${sanitizeSession(nodeKey)}`;
|
|
193
|
+
}
|
|
194
|
+
resolveCwd(cwd, context) {
|
|
195
|
+
if (typeof cwd === "string" && cwd.length > 0) {
|
|
196
|
+
return resolve(this.evaluator.evaluateTemplate(cwd, context));
|
|
197
|
+
}
|
|
198
|
+
return process.cwd();
|
|
199
|
+
}
|
|
200
|
+
resolveTimeoutSeconds(timeout) {
|
|
201
|
+
const milliseconds = typeof timeout === "number"
|
|
202
|
+
? timeout
|
|
203
|
+
: typeof timeout === "string"
|
|
204
|
+
? parseDurationMs(timeout)
|
|
205
|
+
: undefined;
|
|
206
|
+
if (milliseconds === undefined || milliseconds <= 0)
|
|
207
|
+
return undefined;
|
|
208
|
+
return String(milliseconds / 1000);
|
|
209
|
+
}
|
|
210
|
+
stringEnv(env, context) {
|
|
211
|
+
if (!env)
|
|
212
|
+
return {};
|
|
213
|
+
const out = {};
|
|
214
|
+
for (const [k, v] of Object.entries(env))
|
|
215
|
+
out[k] = typeof v === "string" ? this.evaluator.evaluateTemplate(v, context) : String(v);
|
|
216
|
+
return out;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/** Replace characters not safe for an acpx `-s <name>` value, reversibly enough to stay unique. */
|
|
220
|
+
function sanitizeSession(nodeKey) {
|
|
221
|
+
return nodeKey.replace(/\//g, "__").replace(/:/g, "-");
|
|
222
|
+
}
|
|
223
|
+
/** Render the declared output schema as an explicit contract section appended to the prompt. */
|
|
224
|
+
function schemaSection(outputSchema) {
|
|
225
|
+
return `\n\n# OUTPUT SCHEMA\n**After completing the task, your final response MUST be exactly one JSON object that conforms to this schema, with no Markdown, prose, or extra keys.**\n${JSON.stringify(outputSchema, null, 2)}`;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Decide the prompt text for an agent turn:
|
|
229
|
+
* - first run → rendered task template
|
|
230
|
+
* - continuation → fixed continuation prompt
|
|
231
|
+
* - parse/schema retry→ fixed continuation prompt
|
|
232
|
+
* When an output schema is declared it is appended as a `# OUTPUT SCHEMA`
|
|
233
|
+
* section on the first run and on retries, but NOT on a plain continuation
|
|
234
|
+
* (the original task is still live in the acpx session there).
|
|
235
|
+
*/
|
|
236
|
+
export function buildAgentPrompt(renderedTask, outputSchema, continuation, retry) {
|
|
237
|
+
if (retry) {
|
|
238
|
+
return outputSchema ? CONTINUATION_PROMPT + schemaSection(outputSchema) : CONTINUATION_PROMPT;
|
|
239
|
+
}
|
|
240
|
+
if (continuation) {
|
|
241
|
+
return CONTINUATION_PROMPT;
|
|
242
|
+
}
|
|
243
|
+
return outputSchema ? renderedTask + schemaSection(outputSchema) : renderedTask;
|
|
244
|
+
}
|
|
245
|
+
/** Render the exact Agent request prompt that will be sent to acpx. */
|
|
246
|
+
export function renderAgentRequestPrompt(node, context, evaluator, continuation, retry) {
|
|
247
|
+
const renderedTask = evaluator.evaluateTemplate(node.metadata.prompt ?? "", context);
|
|
248
|
+
const outputSchema = node.metadata.output;
|
|
249
|
+
return buildAgentPrompt(renderedTask, outputSchema, continuation, retry);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Parse an ACP NDJSON stream: concatenate `agent_message_chunk` text and
|
|
253
|
+
* surface the final turn `stopReason`. Unparseable lines are ignored.
|
|
254
|
+
*/
|
|
255
|
+
function parseAcpStream(ndjson) {
|
|
256
|
+
let text = "";
|
|
257
|
+
let stopReason;
|
|
258
|
+
for (const line of ndjson.split("\n")) {
|
|
259
|
+
const trimmed = line.trim();
|
|
260
|
+
if (!trimmed)
|
|
261
|
+
continue;
|
|
262
|
+
let msg;
|
|
263
|
+
try {
|
|
264
|
+
msg = JSON.parse(trimmed);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (typeof msg !== "object" || msg === null)
|
|
270
|
+
continue;
|
|
271
|
+
const obj = msg;
|
|
272
|
+
const params = obj.params;
|
|
273
|
+
const update = params?.update;
|
|
274
|
+
if (update?.sessionUpdate === "agent_message_chunk") {
|
|
275
|
+
const content = update.content;
|
|
276
|
+
if (content?.type === "text" && typeof content.text === "string") {
|
|
277
|
+
text += content.text;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const result = obj.result;
|
|
281
|
+
if (result && typeof result.stopReason === "string") {
|
|
282
|
+
stopReason = result.stopReason;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return { text, stopReason };
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Extract a JSON value from an agent reply that may wrap JSON in prose and/or
|
|
289
|
+
* Markdown code fences. Three tiers, strictest first:
|
|
290
|
+
* 1. Strict fast path: parse the whole trimmed reply (pure-JSON response).
|
|
291
|
+
* 2. Independent balanced scan: try every `{...}`/`[...]` candidate from each
|
|
292
|
+
* opening brace/bracket so unbalanced prose/code cannot block later JSON.
|
|
293
|
+
* 3. Candidate-local jsonrepair fallback: for each later candidate, try strict
|
|
294
|
+
* parse first, then repair that same candidate before moving earlier.
|
|
295
|
+
* Returns `undefined` when no JSON can be recovered (→ retryable parse failure).
|
|
296
|
+
*/
|
|
297
|
+
export function extractJson(text) {
|
|
298
|
+
const trimmed = text.trim();
|
|
299
|
+
if (!trimmed)
|
|
300
|
+
return undefined;
|
|
301
|
+
// Tier 1: strict fast path.
|
|
302
|
+
try {
|
|
303
|
+
return JSON.parse(trimmed);
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
// fall through
|
|
307
|
+
}
|
|
308
|
+
// Tier 2/3: latest balanced candidate wins; repair is candidate-local so a
|
|
309
|
+
// malformed final answer is preferred over an earlier strict-JSON draft.
|
|
310
|
+
const candidates = balancedJsonCandidates(text);
|
|
311
|
+
for (let i = candidates.length - 1; i >= 0; i--) {
|
|
312
|
+
const candidate = candidates[i];
|
|
313
|
+
try {
|
|
314
|
+
return JSON.parse(candidate);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
// try jsonrepair for this same candidate before moving earlier
|
|
318
|
+
}
|
|
319
|
+
const repaired = repairJsonCandidate(candidate);
|
|
320
|
+
if (repaired !== undefined) {
|
|
321
|
+
return repaired;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Collect independently balanced `{...}` / `[...]` substrings from `text`.
|
|
328
|
+
* Each opening brace/bracket is treated as a potential candidate start, so a
|
|
329
|
+
* stray prose/code `{` cannot keep depth open and hide a later final JSON block.
|
|
330
|
+
*/
|
|
331
|
+
function balancedJsonCandidates(text) {
|
|
332
|
+
const out = [];
|
|
333
|
+
for (let i = 0; i < text.length; i++) {
|
|
334
|
+
if (text[i] !== "{" && text[i] !== "[")
|
|
335
|
+
continue;
|
|
336
|
+
const end = balancedCandidateEnd(text, i);
|
|
337
|
+
if (end !== undefined) {
|
|
338
|
+
out.push({ start: i, end, value: text.slice(i, end) });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const outer = out.filter((candidate) => !out.some((other) => other !== candidate && other.start < candidate.start && candidate.end < other.end));
|
|
342
|
+
// Source order here is by candidate end position, not start position. This
|
|
343
|
+
// keeps an outer final JSON object ahead of its nested children when iterated
|
|
344
|
+
// backwards, and still lets later independent JSON blocks supersede drafts.
|
|
345
|
+
outer.sort((a, b) => a.end - b.end || a.start - b.start);
|
|
346
|
+
return outer.map((candidate) => candidate.value);
|
|
347
|
+
}
|
|
348
|
+
function balancedCandidateEnd(text, start) {
|
|
349
|
+
const stack = [text[start] === "{" ? "}" : "]"];
|
|
350
|
+
let inString = false;
|
|
351
|
+
let escaped = false;
|
|
352
|
+
for (let i = start + 1; i < text.length; i++) {
|
|
353
|
+
const ch = text[i];
|
|
354
|
+
if (inString) {
|
|
355
|
+
if (escaped)
|
|
356
|
+
escaped = false;
|
|
357
|
+
else if (ch === "\\")
|
|
358
|
+
escaped = true;
|
|
359
|
+
else if (ch === '"')
|
|
360
|
+
inString = false;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (ch === '"') {
|
|
364
|
+
inString = true;
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
if (ch === "{" || ch === "[") {
|
|
368
|
+
stack.push(ch === "{" ? "}" : "]");
|
|
369
|
+
}
|
|
370
|
+
else if (ch === "}" || ch === "]") {
|
|
371
|
+
if (stack.length === 0 || ch !== stack[stack.length - 1]) {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
374
|
+
stack.pop();
|
|
375
|
+
if (stack.length === 0)
|
|
376
|
+
return i + 1;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return undefined;
|
|
380
|
+
}
|
|
381
|
+
function repairJsonCandidate(candidate) {
|
|
382
|
+
if (!isRepairableJsonCandidate(candidate))
|
|
383
|
+
return undefined;
|
|
384
|
+
try {
|
|
385
|
+
const repaired = JSON.parse(jsonrepair(candidate));
|
|
386
|
+
if (typeof repaired === "object" && repaired !== null)
|
|
387
|
+
return repaired;
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
// fall through
|
|
391
|
+
}
|
|
392
|
+
return undefined;
|
|
393
|
+
}
|
|
394
|
+
function isRepairableJsonCandidate(candidate) {
|
|
395
|
+
const trimmed = candidate.trim();
|
|
396
|
+
// Keep repair intentionally narrow. jsonrepair can turn prose snippets like
|
|
397
|
+
// `[1-9]` into `["1-9"]`; in this runtime, malformed final outputs we want to
|
|
398
|
+
// save are object-shaped contracts with key/value separators.
|
|
399
|
+
return trimmed.startsWith("{") && trimmed.includes(":");
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/executors/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ExecutorResult, FailureKind } from "../types.js";
|
|
2
|
+
import type { ExecutorAdapter, ExecutionRequest } from "./types.js";
|
|
3
|
+
import { ExpressionEvaluator } from "../evaluator.js";
|
|
4
|
+
export interface MockProgramResponse {
|
|
5
|
+
stdout?: string;
|
|
6
|
+
stderr?: string;
|
|
7
|
+
exitCode?: number;
|
|
8
|
+
parsedOutput?: unknown;
|
|
9
|
+
/** Simulate a non-recoverable failure (timeout/spawn/killed/capture). */
|
|
10
|
+
failureKind?: FailureKind;
|
|
11
|
+
delay?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Mock program executor for testing. Takes a step-id → {stdout, exitCode, parsedOutput} map,
|
|
15
|
+
* resolves cmd template, handles capture config.
|
|
16
|
+
*/
|
|
17
|
+
export declare class MockProgramExecutor implements ExecutorAdapter {
|
|
18
|
+
private readonly responses;
|
|
19
|
+
private readonly evaluator;
|
|
20
|
+
private readonly ajv;
|
|
21
|
+
constructor(responses: Record<string, MockProgramResponse>, evaluator?: ExpressionEvaluator);
|
|
22
|
+
execute({ node, context, signal }: ExecutionRequest): Promise<ExecutorResult>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=mock-program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-program.d.ts","sourceRoot":"","sources":["../../src/executors/mock-program.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yEAAyE;IACzE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,mBAAoB,YAAW,eAAe;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+C;gBAEvD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,SAAS,CAAC,EAAE,mBAAmB;IAKrF,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAyEpF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ExpressionEvaluator } from "../evaluator.js";
|
|
2
|
+
import { Ajv } from "ajv";
|
|
3
|
+
/**
|
|
4
|
+
* Mock program executor for testing. Takes a step-id → {stdout, exitCode, parsedOutput} map,
|
|
5
|
+
* resolves cmd template, handles capture config.
|
|
6
|
+
*/
|
|
7
|
+
export class MockProgramExecutor {
|
|
8
|
+
responses;
|
|
9
|
+
evaluator;
|
|
10
|
+
ajv = new Ajv({ allErrors: true, strict: false });
|
|
11
|
+
constructor(responses, evaluator) {
|
|
12
|
+
this.responses = new Map(Object.entries(responses));
|
|
13
|
+
this.evaluator = evaluator ?? new ExpressionEvaluator();
|
|
14
|
+
}
|
|
15
|
+
async execute({ node, context, signal }) {
|
|
16
|
+
const stepId = node.id;
|
|
17
|
+
const response = this.responses.get(stepId);
|
|
18
|
+
if (!response) {
|
|
19
|
+
return { error: `No mock response configured for step '${stepId}'`, exitCode: 1 };
|
|
20
|
+
}
|
|
21
|
+
// Resolve cmd template
|
|
22
|
+
const cmdTemplate = node.metadata.cmd;
|
|
23
|
+
if (cmdTemplate) {
|
|
24
|
+
if (Array.isArray(cmdTemplate)) {
|
|
25
|
+
cmdTemplate.map((c) => this.evaluator.evaluateTemplate(c, context));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.evaluator.evaluateTemplate(cmdTemplate, context);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Check for abort
|
|
32
|
+
if (signal.aborted) {
|
|
33
|
+
return { partial: true, error: "Aborted before execution" };
|
|
34
|
+
}
|
|
35
|
+
let aborted = false;
|
|
36
|
+
const onAbort = () => { aborted = true; };
|
|
37
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
38
|
+
try {
|
|
39
|
+
await new Promise((resolve) => setTimeout(resolve, response.delay ?? 5));
|
|
40
|
+
if (aborted || signal.aborted) {
|
|
41
|
+
return { partial: true, error: "Aborted during execution" };
|
|
42
|
+
}
|
|
43
|
+
const stdout = response.stdout ?? "";
|
|
44
|
+
const stderr = response.stderr ?? "";
|
|
45
|
+
// Simulate a non-recoverable failure if configured.
|
|
46
|
+
if (response.failureKind) {
|
|
47
|
+
return { failureKind: response.failureKind, error: `Simulated ${response.failureKind} failure`, stdout, stderr };
|
|
48
|
+
}
|
|
49
|
+
const exitCode = response.exitCode ?? 0;
|
|
50
|
+
// Handle capture config — a non-zero exit code is still step data.
|
|
51
|
+
const capture = node.metadata.capture;
|
|
52
|
+
let output = response.parsedOutput;
|
|
53
|
+
if (output === undefined && response.stdout && capture?.parse === "json") {
|
|
54
|
+
try {
|
|
55
|
+
output = JSON.parse(response.stdout);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return { failureKind: "capture", error: "Failed to parse stdout as JSON", exitCode, stdout, stderr };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (output === undefined && response.stdout && capture?.parse === "text") {
|
|
62
|
+
output = response.stdout;
|
|
63
|
+
}
|
|
64
|
+
// Validate output against schema when declared (mirrors real ProgramExecutor).
|
|
65
|
+
const outputSchema = node.metadata.output;
|
|
66
|
+
if (outputSchema && output !== undefined) {
|
|
67
|
+
const validate = this.ajv.compile(outputSchema);
|
|
68
|
+
if (!validate(output)) {
|
|
69
|
+
return { failureKind: "schema", error: `Output validation failed: ${this.ajv.errorsText(validate.errors)}`, exitCode, stdout, stderr };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { output, exitCode, stdout, stderr };
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
signal.removeEventListener("abort", onAbort);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=mock-program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-program.js","sourceRoot":"","sources":["../../src/executors/mock-program.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ExecutorResult } from "../types.js";
|
|
2
|
+
import type { ExecutorAdapter, ExecutionRequest } from "./types.js";
|
|
3
|
+
import { ExpressionEvaluator } from "../evaluator.js";
|
|
4
|
+
/**
|
|
5
|
+
* Real program executor using execa for subprocess management.
|
|
6
|
+
* Handles cmd template resolution, capture config, timeout, and abort signal.
|
|
7
|
+
*
|
|
8
|
+
* A non-zero exit code is treated as step data (the node completes and exposes
|
|
9
|
+
* exit_code). Only non-recoverable conditions — timeout, signal kill, spawn
|
|
10
|
+
* failure, or capture parse failure — fail the node via `failureKind`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ProgramExecutor implements ExecutorAdapter {
|
|
13
|
+
private readonly evaluator;
|
|
14
|
+
private readonly ajv;
|
|
15
|
+
constructor(evaluator?: ExpressionEvaluator);
|
|
16
|
+
execute({ node, context, signal }: ExecutionRequest): Promise<ExecutorResult>;
|
|
17
|
+
private resolveCmd;
|
|
18
|
+
/** Evaluate template expressions in env values; non-strings are stringified. */
|
|
19
|
+
private evaluateEnv;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../src/executors/program.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAqB,cAAc,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA+C;gBAEvD,SAAS,CAAC,EAAE,mBAAmB;IAIrC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;IA8InF,OAAO,CAAC,UAAU;IAelB,gFAAgF;IAChF,OAAO,CAAC,WAAW;CAQpB"}
|