@async/pipeline 0.2.0 → 0.2.3
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/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/internal/core/index.d.ts +42 -1
- package/dist/internal/core/index.d.ts.map +1 -1
- package/dist/internal/core/index.js +57 -1
- package/dist/internal/core/index.js.map +1 -1
- package/dist/internal/node/cli.d.ts +1 -0
- package/dist/internal/node/cli.d.ts.map +1 -1
- package/dist/internal/node/cli.js +142 -9
- package/dist/internal/node/cli.js.map +1 -1
- package/dist/internal/node/github.js +15 -3
- package/dist/internal/node/github.js.map +1 -1
- package/dist/internal/node/index.d.ts +1 -0
- package/dist/internal/node/index.d.ts.map +1 -1
- package/dist/internal/node/index.js +1 -0
- package/dist/internal/node/index.js.map +1 -1
- package/dist/internal/node/mcp.d.ts +16 -0
- package/dist/internal/node/mcp.d.ts.map +1 -0
- package/dist/internal/node/mcp.js +243 -0
- package/dist/internal/node/mcp.js.map +1 -0
- package/dist/internal/node/runner.d.ts.map +1 -1
- package/dist/internal/node/runner.js +178 -10
- package/dist/internal/node/runner.js.map +1 -1
- package/dist/internal/node/sources.js +1 -1
- package/dist/internal/node/sources.js.map +1 -1
- package/dist/internal/node/store.d.ts +64 -0
- package/dist/internal/node/store.d.ts.map +1 -1
- package/dist/internal/node/store.js +170 -3
- package/dist/internal/node/store.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
import { buildGraph, tasksForJob } from "../core/index.js";
|
|
5
|
+
import { runJob } from "./runner.js";
|
|
6
|
+
import { readPipelineMetadata } from "./sources.js";
|
|
7
|
+
import { computeTaskInputManifest, diffInputManifests, readCacheInputManifest, readContextPacks, readTaskBaseline } from "./store.js";
|
|
8
|
+
/**
|
|
9
|
+
* ADR-0002: a hand-rolled MCP server over stdio. The protocol surface this
|
|
10
|
+
* server needs — initialize, ping, tools/list, tools/call as line-delimited
|
|
11
|
+
* JSON-RPC 2.0 — is small and pinned, which is what keeps the zero-runtime-
|
|
12
|
+
* dependency promise intact. Every tool delegates to the same internals the
|
|
13
|
+
* CLI uses, so the MCP surface cannot drift from `--format json` output.
|
|
14
|
+
*/
|
|
15
|
+
const MCP_PROTOCOL_VERSION = "2025-06-18";
|
|
16
|
+
const TOOLS = [
|
|
17
|
+
{
|
|
18
|
+
name: "list_tasks",
|
|
19
|
+
description: "List the pipeline's tasks and jobs: ids, descriptions, dependencies, inputs, outputs, cache settings, and job targets. Reads metadata only; executes nothing.",
|
|
20
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
21
|
+
readOnly: true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "graph",
|
|
25
|
+
description: "The dependency graph and deterministic execution order, for the whole pipeline or expanded from one job's targets.",
|
|
26
|
+
inputSchema: { type: "object", properties: { job: { type: "string", description: "Optional job id to expand" } }, additionalProperties: false },
|
|
27
|
+
readOnly: true
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "explain_task",
|
|
31
|
+
description: "The full normalized definition of one task.",
|
|
32
|
+
inputSchema: { type: "object", properties: { task: { type: "string" } }, required: ["task"], additionalProperties: false },
|
|
33
|
+
readOnly: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "metadata",
|
|
37
|
+
description: "Full pipeline metadata as JSON. Does not clone sources, run prepare, execute tasks, or evaluate deferred shell callbacks.",
|
|
38
|
+
inputSchema: { type: "object", properties: { includeSources: { type: "boolean" } }, additionalProperties: false },
|
|
39
|
+
readOnly: true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "list_runs",
|
|
43
|
+
description: "Recent run records under .async/runs: id, job, status, timings.",
|
|
44
|
+
inputSchema: { type: "object", properties: { limit: { type: "number", description: "Max records, newest first (default 20)" } }, additionalProperties: false },
|
|
45
|
+
readOnly: true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "read_run",
|
|
49
|
+
description: "One run's execution record plus any failure context packs (error, redacted log tail, input diff vs last passing state, reproduction command).",
|
|
50
|
+
inputSchema: { type: "object", properties: { runId: { type: "string" } }, required: ["runId"], additionalProperties: false },
|
|
51
|
+
readOnly: true
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "diff_inputs",
|
|
55
|
+
description: "Which of a task's declared input files changed (content digests) since the task last passed. Reads files; executes nothing.",
|
|
56
|
+
inputSchema: { type: "object", properties: { task: { type: "string" } }, required: ["task"], additionalProperties: false },
|
|
57
|
+
readOnly: true
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "run_job",
|
|
61
|
+
description: "Run a job through the scheduler: same run lock, cache, records, and evidence as the CLI. Only available when the server was started with --allow-run.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
job: { type: "string" },
|
|
66
|
+
force: { type: "boolean", description: "Re-run tasks while still recording fresh cache entries" }
|
|
67
|
+
},
|
|
68
|
+
required: ["job"],
|
|
69
|
+
additionalProperties: false
|
|
70
|
+
},
|
|
71
|
+
readOnly: false
|
|
72
|
+
}
|
|
73
|
+
];
|
|
74
|
+
export async function runMcpServer(options) {
|
|
75
|
+
const lines = createInterface({ input: options.input, crlfDelay: Infinity });
|
|
76
|
+
for await (const line of lines) {
|
|
77
|
+
const trimmed = line.trim();
|
|
78
|
+
if (!trimmed)
|
|
79
|
+
continue;
|
|
80
|
+
let message;
|
|
81
|
+
try {
|
|
82
|
+
message = JSON.parse(trimmed);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
options.write(JSON.stringify({ jsonrpc: "2.0", id: null, error: { code: -32700, message: "Parse error" } }));
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const response = await handleMessage(message, options);
|
|
89
|
+
if (response !== undefined)
|
|
90
|
+
options.write(JSON.stringify(response));
|
|
91
|
+
}
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
async function handleMessage(message, options) {
|
|
95
|
+
if (!message.method)
|
|
96
|
+
return undefined; // responses and malformed traffic are ignored
|
|
97
|
+
if (message.method.startsWith("notifications/"))
|
|
98
|
+
return undefined;
|
|
99
|
+
const id = message.id ?? null;
|
|
100
|
+
if (message.method === "initialize") {
|
|
101
|
+
return result(id, {
|
|
102
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
103
|
+
capabilities: { tools: {} },
|
|
104
|
+
serverInfo: { name: "async-pipeline", version: options.serverVersion ?? "0.0.0" }
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (message.method === "ping")
|
|
108
|
+
return result(id, {});
|
|
109
|
+
if (message.method === "tools/list") {
|
|
110
|
+
const tools = TOOLS
|
|
111
|
+
.filter((tool) => tool.readOnly || options.allowRun)
|
|
112
|
+
.map(({ name, description, inputSchema }) => ({ name, description, inputSchema }));
|
|
113
|
+
return result(id, { tools });
|
|
114
|
+
}
|
|
115
|
+
if (message.method === "tools/call") {
|
|
116
|
+
const name = typeof message.params?.name === "string" ? message.params.name : "";
|
|
117
|
+
const args = (message.params?.arguments ?? {});
|
|
118
|
+
const tool = TOOLS.find((candidate) => candidate.name === name);
|
|
119
|
+
if (!tool) {
|
|
120
|
+
return error(id, -32602, `Unknown tool "${name}".`);
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const payload = await callTool(name, args, options);
|
|
124
|
+
return result(id, { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] });
|
|
125
|
+
}
|
|
126
|
+
catch (cause) {
|
|
127
|
+
const text = cause instanceof Error ? cause.message : String(cause);
|
|
128
|
+
return result(id, { content: [{ type: "text", text }], isError: true });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return error(id, -32601, `Method "${message.method}" not found.`);
|
|
132
|
+
}
|
|
133
|
+
async function callTool(name, args, options) {
|
|
134
|
+
const { pipeline, store } = options;
|
|
135
|
+
if (name === "list_tasks") {
|
|
136
|
+
return {
|
|
137
|
+
pipeline: pipeline.name,
|
|
138
|
+
tasks: Object.values(pipeline.tasks).map((task) => ({
|
|
139
|
+
id: task.id,
|
|
140
|
+
description: task.description,
|
|
141
|
+
dependsOn: task.dependsOn,
|
|
142
|
+
inputs: task.inputs,
|
|
143
|
+
outputs: task.outputs,
|
|
144
|
+
cache: task.cache.enabled
|
|
145
|
+
})),
|
|
146
|
+
jobs: Object.values(pipeline.jobs).map((job) => ({ id: job.id, target: job.target, trigger: job.trigger }))
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (name === "graph") {
|
|
150
|
+
const jobId = typeof args.job === "string" ? args.job : undefined;
|
|
151
|
+
const graph = jobId ? tasksForJob(pipeline, jobId) : buildGraph(pipeline);
|
|
152
|
+
return graph;
|
|
153
|
+
}
|
|
154
|
+
if (name === "explain_task") {
|
|
155
|
+
const task = pipeline.tasks[requireString(args, "task")];
|
|
156
|
+
if (!task)
|
|
157
|
+
throw new Error(`Unknown task "${String(args.task)}".`);
|
|
158
|
+
return JSON.parse(JSON.stringify(task, (_key, value) => (typeof value === "function" ? "[function]" : value)));
|
|
159
|
+
}
|
|
160
|
+
if (name === "metadata") {
|
|
161
|
+
return readPipelineMetadata(options.configPath, {
|
|
162
|
+
cwd: options.cwd,
|
|
163
|
+
includeSources: args.includeSources === true,
|
|
164
|
+
store
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (name === "list_runs") {
|
|
168
|
+
const limit = typeof args.limit === "number" && args.limit > 0 ? Math.floor(args.limit) : 20;
|
|
169
|
+
let entries;
|
|
170
|
+
try {
|
|
171
|
+
entries = (await readdir(store.runsDir)).sort().reverse();
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return { runs: [] };
|
|
175
|
+
}
|
|
176
|
+
const runs = [];
|
|
177
|
+
for (const entry of entries.slice(0, limit)) {
|
|
178
|
+
try {
|
|
179
|
+
const record = JSON.parse(await readFile(join(store.runsDir, entry, "execution.json"), "utf8"));
|
|
180
|
+
runs.push({ id: record.id, jobId: record.jobId, status: record.status, startedAt: record.startedAt, finishedAt: record.finishedAt });
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Partial or foreign directories under runs/ are skipped, not fatal.
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return { runs };
|
|
187
|
+
}
|
|
188
|
+
if (name === "read_run") {
|
|
189
|
+
const runId = requireString(args, "runId");
|
|
190
|
+
const record = JSON.parse(await readFile(join(store.runsDir, runId, "execution.json"), "utf8"));
|
|
191
|
+
const contextPacks = await readContextPacks(store, runId);
|
|
192
|
+
return { record, contextPacks };
|
|
193
|
+
}
|
|
194
|
+
if (name === "diff_inputs") {
|
|
195
|
+
const taskId = requireString(args, "task");
|
|
196
|
+
const task = pipeline.tasks[taskId];
|
|
197
|
+
if (!task)
|
|
198
|
+
throw new Error(`Unknown task "${taskId}".`);
|
|
199
|
+
const baseline = await readTaskBaseline(store, taskId);
|
|
200
|
+
const baselineManifest = baseline ? await readCacheInputManifest(store, baseline.cacheKey) : null;
|
|
201
|
+
const current = await computeTaskInputManifest(pipeline, task, options.cwd);
|
|
202
|
+
if (!baseline || !baselineManifest) {
|
|
203
|
+
return { task: taskId, baselineMissing: true, currentFiles: Object.keys(current.files).length };
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
task: taskId,
|
|
207
|
+
baselineCacheKey: baseline.cacheKey,
|
|
208
|
+
baselineRecordedAt: baseline.recordedAt,
|
|
209
|
+
...diffInputManifests(baselineManifest, current)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (name === "run_job") {
|
|
213
|
+
if (!options.allowRun) {
|
|
214
|
+
throw new Error("run_job is disabled. Start the server with `async-pipeline mcp --allow-run` to expose it.");
|
|
215
|
+
}
|
|
216
|
+
const jobId = requireString(args, "job");
|
|
217
|
+
return runJob(pipeline, {
|
|
218
|
+
id: jobId,
|
|
219
|
+
cwd: options.cwd,
|
|
220
|
+
env: options.env,
|
|
221
|
+
mode: options.env.CI ? "ci" : "manual",
|
|
222
|
+
force: args.force === true,
|
|
223
|
+
// stdout is the JSON-RPC channel: task output must never echo into it.
|
|
224
|
+
// It still lands in task logs and the execution record as always.
|
|
225
|
+
echo: false
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
throw new Error(`Unknown tool "${name}".`);
|
|
229
|
+
}
|
|
230
|
+
function requireString(args, key) {
|
|
231
|
+
const value = args[key];
|
|
232
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
233
|
+
throw new Error(`Tool argument "${key}" must be a non-empty string.`);
|
|
234
|
+
}
|
|
235
|
+
return value;
|
|
236
|
+
}
|
|
237
|
+
function result(id, payload) {
|
|
238
|
+
return { jsonrpc: "2.0", id, result: payload };
|
|
239
|
+
}
|
|
240
|
+
function error(id, code, message) {
|
|
241
|
+
return { jsonrpc: "2.0", id, error: { code, message } };
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
3
4
|
import { availableParallelism } from "node:os";
|
|
4
|
-
import { posix, relative } from "node:path";
|
|
5
|
+
import { join, posix, relative } from "node:path";
|
|
5
6
|
import { setTimeout as delay } from "node:timers/promises";
|
|
6
|
-
import { sh, tasksForJob } from "../core/index.js";
|
|
7
|
-
import { acquireRunLock, computeTaskCacheKey, createStore, outputFilesExist, readCacheEntry, resolveOutputFiles, restoreCacheOutputs, writeCacheEntry, writeExecution, writeTaskLog } from "./store.js";
|
|
7
|
+
import { isAgentStep, isResolvedAgentStep, pipelineError, sh, tasksForJob } from "../core/index.js";
|
|
8
|
+
import { acquireRunLock, computeTaskCacheKey, computeTaskCacheKeyDetailed, createStore, diffInputManifests, outputFilesExist, readCacheEntry, readCacheInputManifest, readTaskBaseline, resolveOutputFiles, restoreCacheOutputs, writeAgentPrompt, writeAgentTranscript, writeCacheEntry, writeCacheInputManifest, writeContextPack, writeExecution, writeTaskBaseline, writeTaskLog } from "./store.js";
|
|
8
9
|
import { createRunPlan, sourceContext } from "./sources.js";
|
|
9
10
|
export class HostCommandExecutor {
|
|
10
11
|
name = "host";
|
|
@@ -393,7 +394,7 @@ export async function planJob(pipeline, options) {
|
|
|
393
394
|
source: taskDefinition.source,
|
|
394
395
|
writeLog() { }
|
|
395
396
|
});
|
|
396
|
-
const steps = await resolveTaskSteps(taskDefinition.steps, taskContext);
|
|
397
|
+
const steps = await resolveTaskSteps(plan.pipeline.agents, taskDefinition.steps, taskContext);
|
|
397
398
|
const taskSource = taskDefinition.source?.name ? plan.sources[taskDefinition.source.name] : undefined;
|
|
398
399
|
const prepareCommands = taskSource
|
|
399
400
|
? (await resolvePrepareCommands(taskSource, {
|
|
@@ -505,8 +506,8 @@ async function runTask(pipeline, taskDefinition, options) {
|
|
|
505
506
|
.filter((value) => typeof value === "string" && value.length > 0)
|
|
506
507
|
];
|
|
507
508
|
const redactLog = (log) => redactKnownValues(log, redactValues);
|
|
508
|
-
const resolvedSteps = await resolveTaskSteps(taskDefinition.steps, context);
|
|
509
|
-
const cacheKey = await
|
|
509
|
+
const resolvedSteps = await resolveTaskSteps(pipeline.agents, taskDefinition.steps, context);
|
|
510
|
+
const { cacheKey, inputs: inputManifest } = await computeTaskCacheKeyDetailed(pipeline, taskDefinition, options.cwd, {
|
|
510
511
|
candidate: options.candidate,
|
|
511
512
|
dependencyFingerprints: options.dependencyFingerprints,
|
|
512
513
|
prepareCommands: (options.sourcePrepareCommands ?? []).map((command) => command.command),
|
|
@@ -530,6 +531,12 @@ async function runTask(pipeline, taskDefinition, options) {
|
|
|
530
531
|
durationMs: Date.now() - started
|
|
531
532
|
};
|
|
532
533
|
await writeTaskLog(options.store, options.runId, taskDefinition.id, `[cache hit] ${cacheKey}\n`);
|
|
534
|
+
// A hit proves this input state passes: refresh the diff baseline, and
|
|
535
|
+
// backfill the digest manifest for entries created before 0.2.3.
|
|
536
|
+
if ((await readCacheInputManifest(options.store, cacheKey)) === null) {
|
|
537
|
+
await writeCacheInputManifest(options.store, cacheKey, inputManifest);
|
|
538
|
+
}
|
|
539
|
+
await writeTaskBaseline(options.store, taskDefinition.id, cacheKey);
|
|
533
540
|
return result;
|
|
534
541
|
}
|
|
535
542
|
taskLog.append(`[cache miss] ${cacheHit.reason}\n`);
|
|
@@ -557,6 +564,30 @@ async function runTask(pipeline, taskDefinition, options) {
|
|
|
557
564
|
await runFunctionStep(step, context, taskDefinition.timeoutMs);
|
|
558
565
|
continue;
|
|
559
566
|
}
|
|
567
|
+
if (isAgentStep(step)) {
|
|
568
|
+
if (!isResolvedAgentStep(step)) {
|
|
569
|
+
throw new Error(`Agent step for task "${taskDefinition.id}" was not resolved.`);
|
|
570
|
+
}
|
|
571
|
+
const result = await runAgentStep(step, taskDefinition, {
|
|
572
|
+
executor: options.executor,
|
|
573
|
+
cwd: options.cwd,
|
|
574
|
+
env: taskEnv,
|
|
575
|
+
echo: options.echo,
|
|
576
|
+
redactValues,
|
|
577
|
+
forwardEnvKeys,
|
|
578
|
+
store: options.store,
|
|
579
|
+
runId: options.runId
|
|
580
|
+
});
|
|
581
|
+
taskLog.append(result.stdout);
|
|
582
|
+
taskLog.append(result.stderr);
|
|
583
|
+
if (result.timedOut) {
|
|
584
|
+
throw new Error(`Task "${taskDefinition.id}" timed out after ${taskDefinition.timeoutMs}ms.`);
|
|
585
|
+
}
|
|
586
|
+
if (result.code !== 0) {
|
|
587
|
+
throw new Error(`Agent step failed with exit code ${result.code} (profile "${step.use}", model "${step.model}").`);
|
|
588
|
+
}
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
560
591
|
if (!isShellCommand(step)) {
|
|
561
592
|
throw new Error(`Deferred shell step for task "${taskDefinition.id}" was not resolved.`);
|
|
562
593
|
}
|
|
@@ -585,6 +616,8 @@ async function runTask(pipeline, taskDefinition, options) {
|
|
|
585
616
|
await writeTaskLog(options.store, options.runId, taskDefinition.id, redactLog(taskLog.read()));
|
|
586
617
|
if (taskDefinition.cache.enabled) {
|
|
587
618
|
await writeTaskCacheEntry(taskDefinition, options.store, cacheKey, result, options.cwd);
|
|
619
|
+
await writeCacheInputManifest(options.store, cacheKey, inputManifest);
|
|
620
|
+
await writeTaskBaseline(options.store, taskDefinition.id, cacheKey);
|
|
588
621
|
}
|
|
589
622
|
return result;
|
|
590
623
|
}
|
|
@@ -612,7 +645,111 @@ async function runTask(pipeline, taskDefinition, options) {
|
|
|
612
645
|
error: lastError,
|
|
613
646
|
metadata
|
|
614
647
|
};
|
|
615
|
-
|
|
648
|
+
const redactedLog = redactLog(taskLog.read());
|
|
649
|
+
await writeTaskLog(options.store, options.runId, taskDefinition.id, redactedLog);
|
|
650
|
+
try {
|
|
651
|
+
await writeFailureContextPack({
|
|
652
|
+
store: options.store,
|
|
653
|
+
runId: options.runId,
|
|
654
|
+
taskDefinition,
|
|
655
|
+
error: redactLog(lastError),
|
|
656
|
+
attempts,
|
|
657
|
+
cacheKey,
|
|
658
|
+
redactedLog,
|
|
659
|
+
inputManifest,
|
|
660
|
+
rootCwd: options.rootCwd
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
catch {
|
|
664
|
+
// Packs are evidence, not state: failing to write one must not mask the task failure.
|
|
665
|
+
}
|
|
666
|
+
return result;
|
|
667
|
+
}
|
|
668
|
+
const CONTEXT_PACK_LOG_TAIL_BYTES = 4096;
|
|
669
|
+
/**
|
|
670
|
+
* ADR-0003: a bounded, machine-readable failure summary next to the run
|
|
671
|
+
* record — the failing task, a redacted log tail, the reproduction command,
|
|
672
|
+
* the input diff against the task's last passing cache entry (digests only,
|
|
673
|
+
* never contents), and the registered claims whose test titles appear in the
|
|
674
|
+
* log.
|
|
675
|
+
*/
|
|
676
|
+
async function writeFailureContextPack(options) {
|
|
677
|
+
let inputDiff = { baselineMissing: true };
|
|
678
|
+
const baseline = await readTaskBaseline(options.store, options.taskDefinition.id);
|
|
679
|
+
if (baseline) {
|
|
680
|
+
const baselineManifest = await readCacheInputManifest(options.store, baseline.cacheKey);
|
|
681
|
+
if (baselineManifest) {
|
|
682
|
+
inputDiff = {
|
|
683
|
+
baselineCacheKey: baseline.cacheKey,
|
|
684
|
+
baselineRecordedAt: baseline.recordedAt,
|
|
685
|
+
...diffInputManifests(baselineManifest, options.inputManifest)
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
const claims = await matchRegisteredClaims(options.rootCwd, options.redactedLog);
|
|
690
|
+
const pack = {
|
|
691
|
+
schemaVersion: 1,
|
|
692
|
+
task: options.taskDefinition.id,
|
|
693
|
+
runId: options.runId,
|
|
694
|
+
status: "failed",
|
|
695
|
+
error: options.error,
|
|
696
|
+
attempts: options.attempts,
|
|
697
|
+
cacheKey: options.cacheKey,
|
|
698
|
+
reproduce: `async-pipeline run-task ${options.taskDefinition.id}`,
|
|
699
|
+
logTail: options.redactedLog.slice(-CONTEXT_PACK_LOG_TAIL_BYTES),
|
|
700
|
+
inputDiff,
|
|
701
|
+
...(claims.length > 0 ? { claims } : {})
|
|
702
|
+
};
|
|
703
|
+
await writeContextPack(options.store, options.runId, options.taskDefinition.id, pack);
|
|
704
|
+
}
|
|
705
|
+
/** When the project keeps a claims registry, name the promises this failure touches. */
|
|
706
|
+
async function matchRegisteredClaims(rootCwd, log) {
|
|
707
|
+
try {
|
|
708
|
+
const registry = JSON.parse(await readFile(join(rootCwd, "tests", "claims.json"), "utf8"));
|
|
709
|
+
const matched = [];
|
|
710
|
+
for (const claim of registry.claims ?? []) {
|
|
711
|
+
if (!claim.id || !Array.isArray(claim.tests))
|
|
712
|
+
continue;
|
|
713
|
+
if (claim.tests.some((title) => typeof title === "string" && title.length > 0 && log.includes(title))) {
|
|
714
|
+
matched.push(claim.id);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return matched.sort();
|
|
718
|
+
}
|
|
719
|
+
catch {
|
|
720
|
+
return [];
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
async function runAgentStep(step, taskDefinition, options) {
|
|
724
|
+
// The prompt travels as a file redirected to the adapter's stdin: shell-safe
|
|
725
|
+
// for arbitrary prompt text, and the prompt becomes run evidence alongside
|
|
726
|
+
// the transcript. The adapter also sees profile/model/prompt-file env keys
|
|
727
|
+
// so wrapper scripts can stay generic.
|
|
728
|
+
const promptPath = await writeAgentPrompt(options.store, options.runId, taskDefinition.id, step.prompt);
|
|
729
|
+
const command = `${step.command.map((part) => shellEscape(part)).join(" ")} < ${shellEscape(promptPath)}`;
|
|
730
|
+
const env = {
|
|
731
|
+
...options.env,
|
|
732
|
+
ASYNC_PIPELINE_AGENT_PROFILE: step.use,
|
|
733
|
+
ASYNC_PIPELINE_AGENT_MODEL: step.model,
|
|
734
|
+
ASYNC_PIPELINE_AGENT_PROMPT_FILE: promptPath
|
|
735
|
+
};
|
|
736
|
+
const startedAt = new Date().toISOString();
|
|
737
|
+
const started = Date.now();
|
|
738
|
+
const result = await options.executor.runShell(command, {
|
|
739
|
+
cwd: options.cwd,
|
|
740
|
+
env,
|
|
741
|
+
task: taskDefinition,
|
|
742
|
+
timeoutMs: taskDefinition.timeoutMs,
|
|
743
|
+
echo: options.echo,
|
|
744
|
+
redactValues: options.redactValues,
|
|
745
|
+
forwardEnvKeys: options.forwardEnvKeys
|
|
746
|
+
});
|
|
747
|
+
const redact = (value) => redactKnownValues(value, options.redactValues ?? []);
|
|
748
|
+
const transcript = [
|
|
749
|
+
JSON.stringify({ type: "request", at: startedAt, task: taskDefinition.id, profile: step.use, model: step.model, prompt: redact(step.prompt) }),
|
|
750
|
+
JSON.stringify({ type: "response", at: new Date().toISOString(), durationMs: Date.now() - started, code: result.code, timedOut: result.timedOut ?? false, stdout: redact(result.stdout), stderr: redact(result.stderr) })
|
|
751
|
+
].join("\n");
|
|
752
|
+
await writeAgentTranscript(options.store, options.runId, taskDefinition.id, `${transcript}\n`);
|
|
616
753
|
return result;
|
|
617
754
|
}
|
|
618
755
|
async function runShellStep(step, taskDefinition, options) {
|
|
@@ -651,7 +788,7 @@ async function runSourcePrepare(source, options) {
|
|
|
651
788
|
log.append(`${message}\n`);
|
|
652
789
|
}
|
|
653
790
|
});
|
|
654
|
-
const steps = await resolveTaskSteps(source.definition.prepare, context);
|
|
791
|
+
const steps = await resolveTaskSteps({}, source.definition.prepare, context);
|
|
655
792
|
try {
|
|
656
793
|
for (const step of steps) {
|
|
657
794
|
if (typeof step === "function") {
|
|
@@ -718,16 +855,20 @@ async function resolvePrepareCommands(source, options) {
|
|
|
718
855
|
source: sourceContext(source),
|
|
719
856
|
writeLog() { }
|
|
720
857
|
});
|
|
721
|
-
const steps = await resolveTaskSteps(source.definition.prepare, context);
|
|
858
|
+
const steps = await resolveTaskSteps({}, source.definition.prepare, context);
|
|
722
859
|
return steps.filter(isShellCommand);
|
|
723
860
|
}
|
|
724
|
-
async function resolveTaskSteps(steps, context) {
|
|
861
|
+
async function resolveTaskSteps(agents, steps, context) {
|
|
725
862
|
const resolved = [];
|
|
726
863
|
for (const step of steps) {
|
|
727
864
|
if (typeof step === "function" || step.kind === "shell") {
|
|
728
865
|
resolved.push(step);
|
|
729
866
|
continue;
|
|
730
867
|
}
|
|
868
|
+
if (step.kind === "agent") {
|
|
869
|
+
resolved.push(resolveAgentStep(agents, step, context));
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
731
872
|
const command = await step.command(context);
|
|
732
873
|
if (command.kind !== "shell") {
|
|
733
874
|
throw new Error(`Deferred shell step for task "${context.taskId}" must return sh\`...\`.`);
|
|
@@ -736,6 +877,33 @@ async function resolveTaskSteps(steps, context) {
|
|
|
736
877
|
}
|
|
737
878
|
return resolved;
|
|
738
879
|
}
|
|
880
|
+
/** Mirrors env.var(...) resolution in resolveEnvDefinitions: selector from the task env, optional default, optional value map. */
|
|
881
|
+
function resolveAgentValue(value, env, what, taskId) {
|
|
882
|
+
if (typeof value === "string")
|
|
883
|
+
return value;
|
|
884
|
+
const selector = env[value.name] ?? value.default;
|
|
885
|
+
if (selector === undefined || selector === "") {
|
|
886
|
+
throw new Error(`Required variable "${value.name}" for ${what} is not available for task "${taskId}".`);
|
|
887
|
+
}
|
|
888
|
+
if (value.values) {
|
|
889
|
+
const mapped = value.values[selector];
|
|
890
|
+
if (mapped === undefined) {
|
|
891
|
+
throw new Error(`Variable "${value.name}" value "${selector}" is not mapped for ${what} in task "${taskId}".`);
|
|
892
|
+
}
|
|
893
|
+
return mapped;
|
|
894
|
+
}
|
|
895
|
+
return selector;
|
|
896
|
+
}
|
|
897
|
+
function resolveAgentStep(agents, step, context) {
|
|
898
|
+
const use = resolveAgentValue(step.use, context.env, "the agent profile selection", context.taskId);
|
|
899
|
+
const profile = agents[use];
|
|
900
|
+
if (!profile) {
|
|
901
|
+
const known = Object.keys(agents).sort();
|
|
902
|
+
throw pipelineError("ASYNC_PIPELINE_AGENT_UNKNOWN", `Task "${context.taskId}" resolved agent profile "${use}", which is not declared in the pipeline's agents block.${known.length > 0 ? ` Known profiles: ${known.join(", ")}.` : " No agent profiles are declared."}`);
|
|
903
|
+
}
|
|
904
|
+
const model = resolveAgentValue(step.model ?? profile.model, context.env, `agent profile "${use}" model`, context.taskId);
|
|
905
|
+
return { kind: "agent", use, prompt: step.prompt, model, command: [...profile.command] };
|
|
906
|
+
}
|
|
739
907
|
function createTaskContext(taskDefinition, options) {
|
|
740
908
|
return {
|
|
741
909
|
taskId: taskDefinition.id,
|