@oisincoveney/pipeline 1.11.0 → 1.11.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/dist/pipeline-runtime.js +2 -39
- package/dist/runner-output.js +48 -0
- package/dist/safe-json.js +4 -1
- package/dist/schedule-planner.js +6 -3
- package/package.json +1 -1
package/dist/pipeline-runtime.js
CHANGED
|
@@ -4,6 +4,7 @@ import { loadPipelineConfig } from "./config.js";
|
|
|
4
4
|
import { compileWorkflowPlan } from "./workflow-planner.js";
|
|
5
5
|
import { artifactExists, runJscpd, runSemgrep, runTests, runTypecheck } from "./gates.js";
|
|
6
6
|
import { createRunnerLaunchPlan, runLaunchPlan } from "./runner.js";
|
|
7
|
+
import { normalizeRunnerOutput } from "./runner-output.js";
|
|
7
8
|
import { runtimeActorId } from "./runtime-machines/contracts.js";
|
|
8
9
|
import { gateEvaluationMachine } from "./runtime-machines/gate-machine.js";
|
|
9
10
|
import { hookInvocationMachine } from "./runtime-machines/hook-machine.js";
|
|
@@ -1143,45 +1144,7 @@ function createOutputRepairPlan(inputs) {
|
|
|
1143
1144
|
});
|
|
1144
1145
|
}
|
|
1145
1146
|
function normalizeAgentOutput(plan, stdout) {
|
|
1146
|
-
|
|
1147
|
-
const text = lastJsonLineValue(stdout, (value) => {
|
|
1148
|
-
if (!isRecord(value)) return;
|
|
1149
|
-
const item = value.item;
|
|
1150
|
-
if (isRecord(item) && item.type === "agent_message") return typeof item.text === "string" ? item.text : void 0;
|
|
1151
|
-
if (value.type === "agent_message") return typeof value.text === "string" ? value.text : void 0;
|
|
1152
|
-
});
|
|
1153
|
-
if (text) return {
|
|
1154
|
-
evidence: ["normalized runner output from codex JSONL"],
|
|
1155
|
-
output: text
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
if (plan.type === "opencode") {
|
|
1159
|
-
const text = lastJsonLineValue(stdout, (value) => {
|
|
1160
|
-
if (!isRecord(value)) return;
|
|
1161
|
-
const part = value.part;
|
|
1162
|
-
if (isRecord(part) && part.type === "text") return typeof part.text === "string" ? part.text : void 0;
|
|
1163
|
-
});
|
|
1164
|
-
if (text) return {
|
|
1165
|
-
evidence: ["normalized runner output from opencode JSON events"],
|
|
1166
|
-
output: text
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
return {
|
|
1170
|
-
evidence: [],
|
|
1171
|
-
output: stdout
|
|
1172
|
-
};
|
|
1173
|
-
}
|
|
1174
|
-
function lastJsonLineValue(text, extract) {
|
|
1175
|
-
let latest;
|
|
1176
|
-
for (const line of text.split(LINE_RE)) {
|
|
1177
|
-
const trimmed = line.trim();
|
|
1178
|
-
if (!trimmed) continue;
|
|
1179
|
-
try {
|
|
1180
|
-
const extracted = extract(parseJson(trimmed, "runner JSON event"));
|
|
1181
|
-
if (extracted) latest = extracted;
|
|
1182
|
-
} catch {}
|
|
1183
|
-
}
|
|
1184
|
-
return latest;
|
|
1147
|
+
return normalizeRunnerOutput(plan, stdout);
|
|
1185
1148
|
}
|
|
1186
1149
|
function renderAgentPrompt(node, context) {
|
|
1187
1150
|
const profile = node.profile ? context.config.profiles[node.profile] : void 0;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isRecord, parseJson } from "./safe-json.js";
|
|
2
|
+
//#region src/runner-output.ts
|
|
3
|
+
const LINE_RE = /\r?\n/;
|
|
4
|
+
function normalizeRunnerOutput(plan, stdout) {
|
|
5
|
+
if (plan.type === "codex") {
|
|
6
|
+
const output = lastJsonLineValue(stdout, codexAgentMessageText);
|
|
7
|
+
if (output) return {
|
|
8
|
+
evidence: ["normalized runner output from codex JSONL"],
|
|
9
|
+
output
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
if (plan.type === "opencode") {
|
|
13
|
+
const output = lastJsonLineValue(stdout, opencodeTextPart);
|
|
14
|
+
if (output) return {
|
|
15
|
+
evidence: ["normalized runner output from opencode JSON events"],
|
|
16
|
+
output
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
evidence: [],
|
|
21
|
+
output: stdout
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function codexAgentMessageText(value) {
|
|
25
|
+
if (!isRecord(value)) return;
|
|
26
|
+
const item = value.item;
|
|
27
|
+
if (isRecord(item) && item.type === "agent_message") return typeof item.text === "string" ? item.text : void 0;
|
|
28
|
+
if (value.type === "agent_message") return typeof value.text === "string" ? value.text : void 0;
|
|
29
|
+
}
|
|
30
|
+
function opencodeTextPart(value) {
|
|
31
|
+
if (!isRecord(value)) return;
|
|
32
|
+
const part = value.part;
|
|
33
|
+
if (isRecord(part) && part.type === "text") return typeof part.text === "string" ? part.text : void 0;
|
|
34
|
+
}
|
|
35
|
+
function lastJsonLineValue(text, extract) {
|
|
36
|
+
let latest;
|
|
37
|
+
for (const line of text.split(LINE_RE)) {
|
|
38
|
+
const trimmed = line.trim();
|
|
39
|
+
if (!trimmed) continue;
|
|
40
|
+
try {
|
|
41
|
+
const extracted = extract(parseJson(trimmed, "runner JSON event"));
|
|
42
|
+
if (extracted) latest = extracted;
|
|
43
|
+
} catch {}
|
|
44
|
+
}
|
|
45
|
+
return latest;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { normalizeRunnerOutput };
|
package/dist/safe-json.js
CHANGED
|
@@ -8,5 +8,8 @@ function parseJson(value, label = "JSON") {
|
|
|
8
8
|
throw new Error(`Failed to parse ${label}: ${message}`);
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
function isRecord(value) {
|
|
12
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13
|
+
}
|
|
11
14
|
//#endregion
|
|
12
|
-
export { parseJson };
|
|
15
|
+
export { isRecord, parseJson };
|
package/dist/schedule-planner.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { validatePipelineConfig, workflowSchema } from "./config.js";
|
|
2
2
|
import { compileWorkflowPlan } from "./workflow-planner.js";
|
|
3
3
|
import { createRunnerLaunchPlan, runLaunchPlan } from "./runner.js";
|
|
4
|
+
import { normalizeRunnerOutput } from "./runner-output.js";
|
|
4
5
|
import { dirname, join } from "node:path";
|
|
5
6
|
import { parseDocument, stringify } from "yaml";
|
|
6
7
|
import { z } from "zod";
|
|
@@ -259,14 +260,16 @@ function implementationTrack(id) {
|
|
|
259
260
|
}
|
|
260
261
|
async function refineScheduleArtifact(baseline, plannerProfile, options) {
|
|
261
262
|
if (!plannerProfile) return baseline;
|
|
262
|
-
const
|
|
263
|
+
const executor = options.executor ?? runLaunchPlan;
|
|
264
|
+
const plan = createRunnerLaunchPlan(options.config, {
|
|
263
265
|
nodeId: "schedule-plan",
|
|
264
266
|
profileId: plannerProfile,
|
|
265
267
|
prompt: plannerPrompt(options.entrypointId, options.task, baseline),
|
|
266
268
|
worktreePath: options.worktreePath
|
|
267
|
-
})
|
|
269
|
+
});
|
|
270
|
+
const result = await executor(plan, {});
|
|
268
271
|
if (result.exitCode !== 0) throw new ScheduleArtifactError(`schedule planner '${plannerProfile}' failed with exit ${result.exitCode}`);
|
|
269
|
-
const source = result.stdout.trim();
|
|
272
|
+
const source = normalizeRunnerOutput(plan, result.stdout).output.trim();
|
|
270
273
|
if (!source) return baseline;
|
|
271
274
|
return parseScheduleArtifact(source, "planner output");
|
|
272
275
|
}
|
package/package.json
CHANGED