agentweaver 0.1.16 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -10
- package/dist/artifacts.js +73 -3
- package/dist/doctor/checks/executors.js +2 -2
- package/dist/flow-state.js +138 -1
- package/dist/index.js +175 -61
- package/dist/interactive/controller.js +56 -23
- package/dist/interactive/ink/index.js +22 -1
- package/dist/interactive/tree.js +2 -2
- package/dist/pipeline/auto-flow.js +9 -6
- package/dist/pipeline/context.js +6 -5
- package/dist/pipeline/declarative-flows.js +39 -20
- package/dist/pipeline/flow-catalog.js +36 -14
- package/dist/pipeline/flow-specs/auto-common.json +1 -0
- package/dist/pipeline/flow-specs/auto-golang.json +27 -1
- package/dist/pipeline/flow-specs/design-review/design-review-loop.json +13 -1
- package/dist/pipeline/flow-specs/plan.json +4 -2
- package/dist/pipeline/launch-profile-config.js +30 -18
- package/dist/pipeline/node-contract.js +1 -0
- package/dist/pipeline/node-registry.js +74 -5
- package/dist/pipeline/nodes/flow-run-node.js +188 -173
- package/dist/pipeline/nodes/llm-prompt-node.js +15 -33
- package/dist/pipeline/plugin-loader.js +389 -0
- package/dist/pipeline/plugin-types.js +1 -0
- package/dist/pipeline/registry.js +71 -4
- package/dist/pipeline/spec-compiler.js +1 -0
- package/dist/pipeline/spec-loader.js +14 -0
- package/dist/pipeline/spec-validator.js +6 -0
- package/dist/pipeline/value-resolver.js +2 -1
- package/dist/plugin-sdk.js +1 -0
- package/dist/runtime/artifact-registry.js +3 -0
- package/dist/runtime/execution-routing.js +25 -19
- package/dist/runtime/interactive-execution-routing.js +66 -57
- package/docs/example/.flows/examples/claude-example.json +50 -0
- package/docs/example/.plugins/claude-example-plugin/index.js +149 -0
- package/docs/example/.plugins/claude-example-plugin/plugin.json +8 -0
- package/docs/examples/.flows/claude-example.json +50 -0
- package/docs/examples/.plugins/claude-example-plugin/index.js +149 -0
- package/docs/examples/.plugins/claude-example-plugin/plugin.json +8 -0
- package/docs/plugin-sdk.md +731 -0
- package/package.json +6 -2
|
@@ -32,6 +32,43 @@ import { summaryFileLoadNode } from "./nodes/summary-file-load-node.js";
|
|
|
32
32
|
import { telegramNotifierNode } from "./nodes/telegram-notifier-node.js";
|
|
33
33
|
import { userInputNode } from "./nodes/user-input-node.js";
|
|
34
34
|
import { writeSelectionFileNode } from "./nodes/write-selection-file-node.js";
|
|
35
|
+
import { TaskRunnerError } from "../errors.js";
|
|
36
|
+
export const BUILT_IN_NODE_KINDS = [
|
|
37
|
+
"build-failure-summary",
|
|
38
|
+
"build-review-fix-prompt",
|
|
39
|
+
"clear-ready-to-merge",
|
|
40
|
+
"codex-prompt",
|
|
41
|
+
"command-check",
|
|
42
|
+
"commit-message-form",
|
|
43
|
+
"design-review-verdict",
|
|
44
|
+
"ensure-summary-json",
|
|
45
|
+
"fetch-gitlab-diff",
|
|
46
|
+
"fetch-gitlab-review",
|
|
47
|
+
"file-check",
|
|
48
|
+
"flow-run",
|
|
49
|
+
"git-commit",
|
|
50
|
+
"git-commit-form",
|
|
51
|
+
"git-status",
|
|
52
|
+
"gitlab-review-artifacts",
|
|
53
|
+
"jira-context",
|
|
54
|
+
"jira-fetch",
|
|
55
|
+
"jira-issue-check",
|
|
56
|
+
"local-script-check",
|
|
57
|
+
"llm-prompt",
|
|
58
|
+
"opencode-prompt",
|
|
59
|
+
"plan-codex",
|
|
60
|
+
"planning-bundle",
|
|
61
|
+
"planning-questions-form",
|
|
62
|
+
"read-file",
|
|
63
|
+
"review-findings-form",
|
|
64
|
+
"review-verdict",
|
|
65
|
+
"select-files-form",
|
|
66
|
+
"structured-summary",
|
|
67
|
+
"summary-file-load",
|
|
68
|
+
"telegram-notify",
|
|
69
|
+
"user-input",
|
|
70
|
+
"write-selection-file",
|
|
71
|
+
];
|
|
35
72
|
const builtInNodes = {
|
|
36
73
|
"build-failure-summary": buildFailureSummaryNode,
|
|
37
74
|
"build-review-fix-prompt": buildReviewFixPromptNode,
|
|
@@ -249,19 +286,51 @@ const builtInNodeMetadata = {
|
|
|
249
286
|
requiredParams: ["outputFile", "reviewFindingsJsonFile", "selectionMode"],
|
|
250
287
|
},
|
|
251
288
|
};
|
|
252
|
-
|
|
289
|
+
function coreOwner(id) {
|
|
290
|
+
return {
|
|
291
|
+
kind: "core",
|
|
292
|
+
id: `core:${id}`,
|
|
293
|
+
manifestPath: "built-in node registry",
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
export function createNodeRegistry(pluginNodes = []) {
|
|
297
|
+
const definitions = new Map(Object.entries(builtInNodes));
|
|
298
|
+
const metadata = new Map(Object.entries(builtInNodeMetadata));
|
|
299
|
+
const owners = new Map(Object.keys(builtInNodes).map((id) => [id, coreOwner(id)]));
|
|
300
|
+
for (const registration of pluginNodes) {
|
|
301
|
+
const existingOwner = owners.get(registration.id);
|
|
302
|
+
if (existingOwner) {
|
|
303
|
+
throw new TaskRunnerError(`Duplicate node id '${registration.id}' conflicts between ${existingOwner.id} (${existingOwner.manifestPath}) and plugin '${registration.pluginId}' (${registration.manifestPath}).`);
|
|
304
|
+
}
|
|
305
|
+
definitions.set(registration.id, registration.definition);
|
|
306
|
+
metadata.set(registration.id, registration.metadata);
|
|
307
|
+
owners.set(registration.id, {
|
|
308
|
+
kind: "plugin",
|
|
309
|
+
id: registration.pluginId,
|
|
310
|
+
manifestPath: registration.manifestPath,
|
|
311
|
+
entrypointPath: registration.entrypointPath,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
253
314
|
return {
|
|
254
315
|
get(kind) {
|
|
255
|
-
|
|
316
|
+
const definition = definitions.get(kind);
|
|
317
|
+
if (!definition) {
|
|
318
|
+
throw new TaskRunnerError(`Unknown node kind '${kind}'.`);
|
|
319
|
+
}
|
|
320
|
+
return definition;
|
|
256
321
|
},
|
|
257
322
|
getMeta(kind) {
|
|
258
|
-
|
|
323
|
+
const definition = metadata.get(kind);
|
|
324
|
+
if (!definition) {
|
|
325
|
+
throw new TaskRunnerError(`Unknown node metadata '${kind}'.`);
|
|
326
|
+
}
|
|
327
|
+
return definition;
|
|
259
328
|
},
|
|
260
329
|
has(kind) {
|
|
261
|
-
return kind
|
|
330
|
+
return definitions.has(kind);
|
|
262
331
|
},
|
|
263
332
|
kinds() {
|
|
264
|
-
return
|
|
333
|
+
return [...definitions.keys()];
|
|
265
334
|
},
|
|
266
335
|
};
|
|
267
336
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { printInfo } from "../../tui.js";
|
|
2
|
+
import { nextArtifactIteration } from "../../artifacts.js";
|
|
2
3
|
import { resolveDesignReviewInputContract } from "../../runtime/design-review-input-contract.js";
|
|
3
4
|
import { resolvePlanReviseInputContract } from "../../runtime/plan-revise-input-contract.js";
|
|
4
5
|
import { inspectReviewInputContract } from "../../runtime/review-input-contract.js";
|
|
@@ -20,6 +21,189 @@ function withArtifactLineageRefPaths(params, lineageRefs) {
|
|
|
20
21
|
[ARTIFACT_LINEAGE_REF_PATHS_PARAM]: merged,
|
|
21
22
|
};
|
|
22
23
|
}
|
|
24
|
+
function parsePositiveInteger(value) {
|
|
25
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
|
|
26
|
+
}
|
|
27
|
+
export function resolveNestedFlowParams(flowKind, flowParams) {
|
|
28
|
+
let resolvedFlowParams = withCanonicalReviewLoopParams(flowKind, flowParams);
|
|
29
|
+
if (flowKind === "design-review-flow") {
|
|
30
|
+
const taskKey = String(flowParams["taskKey"] ?? "");
|
|
31
|
+
if (!taskKey) {
|
|
32
|
+
return resolvedFlowParams;
|
|
33
|
+
}
|
|
34
|
+
const contract = resolveDesignReviewInputContract(taskKey);
|
|
35
|
+
const iteration = parsePositiveInteger(flowParams["iteration"]) ?? nextArtifactIteration(taskKey, "design-review");
|
|
36
|
+
return withArtifactLineageRefPaths({
|
|
37
|
+
...flowParams,
|
|
38
|
+
iteration,
|
|
39
|
+
planningIteration: contract.planningIteration,
|
|
40
|
+
designFile: contract.designFile,
|
|
41
|
+
designJsonFile: contract.designJsonFile,
|
|
42
|
+
planFile: contract.planFile,
|
|
43
|
+
planJsonFile: contract.planJsonFile,
|
|
44
|
+
hasQaArtifacts: contract.hasQaArtifacts,
|
|
45
|
+
qaFilePath: contract.qaFilePath,
|
|
46
|
+
qaJsonFilePath: contract.qaJsonFilePath,
|
|
47
|
+
qaFile: contract.qaFile,
|
|
48
|
+
qaJsonFile: contract.qaJsonFile,
|
|
49
|
+
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
50
|
+
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
51
|
+
taskContextJsonFile: contract.taskContextJsonFile,
|
|
52
|
+
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
53
|
+
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
54
|
+
jiraTaskFile: contract.jiraTaskFile,
|
|
55
|
+
hasJiraAttachmentsManifestFile: contract.hasJiraAttachmentsManifestFile,
|
|
56
|
+
jiraAttachmentsManifestFilePath: contract.jiraAttachmentsManifestFilePath,
|
|
57
|
+
jiraAttachmentsManifestFile: contract.jiraAttachmentsManifestFile,
|
|
58
|
+
hasJiraAttachmentsContextFile: contract.hasJiraAttachmentsContextFile,
|
|
59
|
+
jiraAttachmentsContextFilePath: contract.jiraAttachmentsContextFilePath,
|
|
60
|
+
jiraAttachmentsContextFile: contract.jiraAttachmentsContextFile,
|
|
61
|
+
hasPlanningAnswersJsonFile: contract.hasPlanningAnswersJsonFile,
|
|
62
|
+
planningAnswersJsonFilePath: contract.planningAnswersJsonFilePath,
|
|
63
|
+
planningAnswersJsonFile: contract.planningAnswersJsonFile,
|
|
64
|
+
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
65
|
+
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
66
|
+
taskInputJsonFile: contract.taskInputJsonFile,
|
|
67
|
+
}, {
|
|
68
|
+
"params.designFile": contract.designFile,
|
|
69
|
+
"params.designJsonFile": contract.designJsonFile,
|
|
70
|
+
"params.planFile": contract.planFile,
|
|
71
|
+
"params.planJsonFile": contract.planJsonFile,
|
|
72
|
+
...(contract.qaFilePath ? { "params.qaFile": contract.qaFilePath } : {}),
|
|
73
|
+
...(contract.qaJsonFilePath ? { "params.qaJsonFile": contract.qaJsonFilePath } : {}),
|
|
74
|
+
...(contract.taskContextJsonFilePath
|
|
75
|
+
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
76
|
+
: {}),
|
|
77
|
+
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
78
|
+
...(contract.jiraAttachmentsManifestFilePath
|
|
79
|
+
? { "params.jiraAttachmentsManifestFile": contract.jiraAttachmentsManifestFilePath }
|
|
80
|
+
: {}),
|
|
81
|
+
...(contract.jiraAttachmentsContextFilePath
|
|
82
|
+
? { "params.jiraAttachmentsContextFile": contract.jiraAttachmentsContextFilePath }
|
|
83
|
+
: {}),
|
|
84
|
+
...(contract.planningAnswersJsonFilePath
|
|
85
|
+
? { "params.planningAnswersJsonFile": contract.planningAnswersJsonFilePath }
|
|
86
|
+
: {}),
|
|
87
|
+
...(contract.taskInputJsonFilePath
|
|
88
|
+
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
89
|
+
: {}),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (flowKind === "plan-revise-flow") {
|
|
93
|
+
const taskKey = String(flowParams["taskKey"] ?? "");
|
|
94
|
+
if (!taskKey) {
|
|
95
|
+
return resolvedFlowParams;
|
|
96
|
+
}
|
|
97
|
+
const contract = resolvePlanReviseInputContract(taskKey);
|
|
98
|
+
return withArtifactLineageRefPaths({
|
|
99
|
+
...flowParams,
|
|
100
|
+
reviewIteration: contract.reviewIteration,
|
|
101
|
+
reviewFile: contract.reviewFile,
|
|
102
|
+
reviewJsonFile: contract.reviewJsonFile,
|
|
103
|
+
sourcePlanningIteration: contract.sourcePlanningIteration,
|
|
104
|
+
outputIteration: contract.outputIteration,
|
|
105
|
+
designFile: contract.designFile,
|
|
106
|
+
designJsonFile: contract.designJsonFile,
|
|
107
|
+
planFile: contract.planFile,
|
|
108
|
+
planJsonFile: contract.planJsonFile,
|
|
109
|
+
hasQaArtifacts: contract.hasQaArtifacts,
|
|
110
|
+
qaFilePath: contract.qaFilePath,
|
|
111
|
+
qaJsonFilePath: contract.qaJsonFilePath,
|
|
112
|
+
qaFile: contract.qaFile,
|
|
113
|
+
qaJsonFile: contract.qaJsonFile,
|
|
114
|
+
revisedDesignFile: contract.revisedDesignFile,
|
|
115
|
+
revisedDesignJsonFile: contract.revisedDesignJsonFile,
|
|
116
|
+
revisedPlanFile: contract.revisedPlanFile,
|
|
117
|
+
revisedPlanJsonFile: contract.revisedPlanJsonFile,
|
|
118
|
+
revisedQaFile: contract.revisedQaFile,
|
|
119
|
+
revisedQaJsonFile: contract.revisedQaJsonFile,
|
|
120
|
+
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
121
|
+
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
122
|
+
taskContextJsonFile: contract.taskContextJsonFile,
|
|
123
|
+
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
124
|
+
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
125
|
+
jiraTaskFile: contract.jiraTaskFile,
|
|
126
|
+
hasJiraAttachmentsManifestFile: contract.hasJiraAttachmentsManifestFile,
|
|
127
|
+
jiraAttachmentsManifestFilePath: contract.jiraAttachmentsManifestFilePath,
|
|
128
|
+
jiraAttachmentsManifestFile: contract.jiraAttachmentsManifestFile,
|
|
129
|
+
hasJiraAttachmentsContextFile: contract.hasJiraAttachmentsContextFile,
|
|
130
|
+
jiraAttachmentsContextFilePath: contract.jiraAttachmentsContextFilePath,
|
|
131
|
+
jiraAttachmentsContextFile: contract.jiraAttachmentsContextFile,
|
|
132
|
+
hasPlanningAnswersJsonFile: contract.hasPlanningAnswersJsonFile,
|
|
133
|
+
planningAnswersJsonFilePath: contract.planningAnswersJsonFilePath,
|
|
134
|
+
planningAnswersJsonFile: contract.planningAnswersJsonFile,
|
|
135
|
+
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
136
|
+
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
137
|
+
taskInputJsonFile: contract.taskInputJsonFile,
|
|
138
|
+
}, {
|
|
139
|
+
"params.reviewFile": contract.reviewFile,
|
|
140
|
+
"params.reviewJsonFile": contract.reviewJsonFile,
|
|
141
|
+
"params.designFile": contract.designFile,
|
|
142
|
+
"params.designJsonFile": contract.designJsonFile,
|
|
143
|
+
"params.planFile": contract.planFile,
|
|
144
|
+
"params.planJsonFile": contract.planJsonFile,
|
|
145
|
+
...(contract.qaFilePath ? { "params.qaFile": contract.qaFilePath } : {}),
|
|
146
|
+
...(contract.qaJsonFilePath ? { "params.qaJsonFile": contract.qaJsonFilePath } : {}),
|
|
147
|
+
...(contract.taskContextJsonFilePath
|
|
148
|
+
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
149
|
+
: {}),
|
|
150
|
+
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
151
|
+
...(contract.jiraAttachmentsManifestFilePath
|
|
152
|
+
? { "params.jiraAttachmentsManifestFile": contract.jiraAttachmentsManifestFilePath }
|
|
153
|
+
: {}),
|
|
154
|
+
...(contract.jiraAttachmentsContextFilePath
|
|
155
|
+
? { "params.jiraAttachmentsContextFile": contract.jiraAttachmentsContextFilePath }
|
|
156
|
+
: {}),
|
|
157
|
+
...(contract.planningAnswersJsonFilePath
|
|
158
|
+
? { "params.planningAnswersJsonFile": contract.planningAnswersJsonFilePath }
|
|
159
|
+
: {}),
|
|
160
|
+
...(contract.taskInputJsonFilePath
|
|
161
|
+
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
162
|
+
: {}),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (flowKind === "review-flow") {
|
|
166
|
+
const taskKey = String(flowParams["taskKey"] ?? "");
|
|
167
|
+
if (!taskKey) {
|
|
168
|
+
return resolvedFlowParams;
|
|
169
|
+
}
|
|
170
|
+
const inspection = inspectReviewInputContract(taskKey);
|
|
171
|
+
if (inspection.status !== "ready") {
|
|
172
|
+
return resolvedFlowParams;
|
|
173
|
+
}
|
|
174
|
+
const { contract } = inspection;
|
|
175
|
+
return withArtifactLineageRefPaths({
|
|
176
|
+
...flowParams,
|
|
177
|
+
planningIteration: contract.planningIteration,
|
|
178
|
+
designFile: contract.designFile,
|
|
179
|
+
designJsonFile: contract.designJsonFile,
|
|
180
|
+
planFile: contract.planFile,
|
|
181
|
+
planJsonFile: contract.planJsonFile,
|
|
182
|
+
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
183
|
+
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
184
|
+
taskContextJsonFile: contract.taskContextJsonFile,
|
|
185
|
+
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
186
|
+
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
187
|
+
jiraTaskFile: contract.jiraTaskFile,
|
|
188
|
+
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
189
|
+
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
190
|
+
taskInputJsonFile: contract.taskInputJsonFile,
|
|
191
|
+
}, {
|
|
192
|
+
"params.designFile": contract.designFile,
|
|
193
|
+
"params.designJsonFile": contract.designJsonFile,
|
|
194
|
+
"params.planFile": contract.planFile,
|
|
195
|
+
"params.planJsonFile": contract.planJsonFile,
|
|
196
|
+
...(contract.taskContextJsonFilePath
|
|
197
|
+
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
198
|
+
: {}),
|
|
199
|
+
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
200
|
+
...(contract.taskInputJsonFilePath
|
|
201
|
+
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
202
|
+
: {}),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return resolvedFlowParams;
|
|
206
|
+
}
|
|
23
207
|
export const flowRunNode = {
|
|
24
208
|
kind: "flow-run",
|
|
25
209
|
version: 1,
|
|
@@ -31,179 +215,10 @@ export const flowRunNode = {
|
|
|
31
215
|
if (labelText) {
|
|
32
216
|
printInfo(String(labelText));
|
|
33
217
|
}
|
|
34
|
-
const flow = loadNamedDeclarativeFlow(fileName, context.cwd
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (taskKey) {
|
|
39
|
-
const contract = resolveDesignReviewInputContract(taskKey);
|
|
40
|
-
resolvedFlowParams = withArtifactLineageRefPaths({
|
|
41
|
-
...flowParams,
|
|
42
|
-
iteration: contract.planningIteration,
|
|
43
|
-
planningIteration: contract.planningIteration,
|
|
44
|
-
designFile: contract.designFile,
|
|
45
|
-
designJsonFile: contract.designJsonFile,
|
|
46
|
-
planFile: contract.planFile,
|
|
47
|
-
planJsonFile: contract.planJsonFile,
|
|
48
|
-
hasQaArtifacts: contract.hasQaArtifacts,
|
|
49
|
-
qaFilePath: contract.qaFilePath,
|
|
50
|
-
qaJsonFilePath: contract.qaJsonFilePath,
|
|
51
|
-
qaFile: contract.qaFile,
|
|
52
|
-
qaJsonFile: contract.qaJsonFile,
|
|
53
|
-
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
54
|
-
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
55
|
-
taskContextJsonFile: contract.taskContextJsonFile,
|
|
56
|
-
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
57
|
-
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
58
|
-
jiraTaskFile: contract.jiraTaskFile,
|
|
59
|
-
hasJiraAttachmentsManifestFile: contract.hasJiraAttachmentsManifestFile,
|
|
60
|
-
jiraAttachmentsManifestFilePath: contract.jiraAttachmentsManifestFilePath,
|
|
61
|
-
jiraAttachmentsManifestFile: contract.jiraAttachmentsManifestFile,
|
|
62
|
-
hasJiraAttachmentsContextFile: contract.hasJiraAttachmentsContextFile,
|
|
63
|
-
jiraAttachmentsContextFilePath: contract.jiraAttachmentsContextFilePath,
|
|
64
|
-
jiraAttachmentsContextFile: contract.jiraAttachmentsContextFile,
|
|
65
|
-
hasPlanningAnswersJsonFile: contract.hasPlanningAnswersJsonFile,
|
|
66
|
-
planningAnswersJsonFilePath: contract.planningAnswersJsonFilePath,
|
|
67
|
-
planningAnswersJsonFile: contract.planningAnswersJsonFile,
|
|
68
|
-
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
69
|
-
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
70
|
-
taskInputJsonFile: contract.taskInputJsonFile,
|
|
71
|
-
}, {
|
|
72
|
-
"params.designFile": contract.designFile,
|
|
73
|
-
"params.designJsonFile": contract.designJsonFile,
|
|
74
|
-
"params.planFile": contract.planFile,
|
|
75
|
-
"params.planJsonFile": contract.planJsonFile,
|
|
76
|
-
...(contract.qaFilePath ? { "params.qaFile": contract.qaFilePath } : {}),
|
|
77
|
-
...(contract.qaJsonFilePath ? { "params.qaJsonFile": contract.qaJsonFilePath } : {}),
|
|
78
|
-
...(contract.taskContextJsonFilePath
|
|
79
|
-
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
80
|
-
: {}),
|
|
81
|
-
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
82
|
-
...(contract.jiraAttachmentsManifestFilePath
|
|
83
|
-
? { "params.jiraAttachmentsManifestFile": contract.jiraAttachmentsManifestFilePath }
|
|
84
|
-
: {}),
|
|
85
|
-
...(contract.jiraAttachmentsContextFilePath
|
|
86
|
-
? { "params.jiraAttachmentsContextFile": contract.jiraAttachmentsContextFilePath }
|
|
87
|
-
: {}),
|
|
88
|
-
...(contract.planningAnswersJsonFilePath
|
|
89
|
-
? { "params.planningAnswersJsonFile": contract.planningAnswersJsonFilePath }
|
|
90
|
-
: {}),
|
|
91
|
-
...(contract.taskInputJsonFilePath
|
|
92
|
-
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
93
|
-
: {}),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else if (flow.kind === "plan-revise-flow") {
|
|
98
|
-
const taskKey = String(flowParams["taskKey"] ?? "");
|
|
99
|
-
if (taskKey) {
|
|
100
|
-
const contract = resolvePlanReviseInputContract(taskKey);
|
|
101
|
-
resolvedFlowParams = withArtifactLineageRefPaths({
|
|
102
|
-
...flowParams,
|
|
103
|
-
reviewIteration: contract.reviewIteration,
|
|
104
|
-
reviewFile: contract.reviewFile,
|
|
105
|
-
reviewJsonFile: contract.reviewJsonFile,
|
|
106
|
-
sourcePlanningIteration: contract.sourcePlanningIteration,
|
|
107
|
-
outputIteration: contract.outputIteration,
|
|
108
|
-
designFile: contract.designFile,
|
|
109
|
-
designJsonFile: contract.designJsonFile,
|
|
110
|
-
planFile: contract.planFile,
|
|
111
|
-
planJsonFile: contract.planJsonFile,
|
|
112
|
-
hasQaArtifacts: contract.hasQaArtifacts,
|
|
113
|
-
qaFilePath: contract.qaFilePath,
|
|
114
|
-
qaJsonFilePath: contract.qaJsonFilePath,
|
|
115
|
-
qaFile: contract.qaFile,
|
|
116
|
-
qaJsonFile: contract.qaJsonFile,
|
|
117
|
-
revisedDesignFile: contract.revisedDesignFile,
|
|
118
|
-
revisedDesignJsonFile: contract.revisedDesignJsonFile,
|
|
119
|
-
revisedPlanFile: contract.revisedPlanFile,
|
|
120
|
-
revisedPlanJsonFile: contract.revisedPlanJsonFile,
|
|
121
|
-
revisedQaFile: contract.revisedQaFile,
|
|
122
|
-
revisedQaJsonFile: contract.revisedQaJsonFile,
|
|
123
|
-
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
124
|
-
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
125
|
-
taskContextJsonFile: contract.taskContextJsonFile,
|
|
126
|
-
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
127
|
-
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
128
|
-
jiraTaskFile: contract.jiraTaskFile,
|
|
129
|
-
hasJiraAttachmentsManifestFile: contract.hasJiraAttachmentsManifestFile,
|
|
130
|
-
jiraAttachmentsManifestFilePath: contract.jiraAttachmentsManifestFilePath,
|
|
131
|
-
jiraAttachmentsManifestFile: contract.jiraAttachmentsManifestFile,
|
|
132
|
-
hasJiraAttachmentsContextFile: contract.hasJiraAttachmentsContextFile,
|
|
133
|
-
jiraAttachmentsContextFilePath: contract.jiraAttachmentsContextFilePath,
|
|
134
|
-
jiraAttachmentsContextFile: contract.jiraAttachmentsContextFile,
|
|
135
|
-
hasPlanningAnswersJsonFile: contract.hasPlanningAnswersJsonFile,
|
|
136
|
-
planningAnswersJsonFilePath: contract.planningAnswersJsonFilePath,
|
|
137
|
-
planningAnswersJsonFile: contract.planningAnswersJsonFile,
|
|
138
|
-
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
139
|
-
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
140
|
-
taskInputJsonFile: contract.taskInputJsonFile,
|
|
141
|
-
}, {
|
|
142
|
-
"params.reviewFile": contract.reviewFile,
|
|
143
|
-
"params.reviewJsonFile": contract.reviewJsonFile,
|
|
144
|
-
"params.designFile": contract.designFile,
|
|
145
|
-
"params.designJsonFile": contract.designJsonFile,
|
|
146
|
-
"params.planFile": contract.planFile,
|
|
147
|
-
"params.planJsonFile": contract.planJsonFile,
|
|
148
|
-
...(contract.qaFilePath ? { "params.qaFile": contract.qaFilePath } : {}),
|
|
149
|
-
...(contract.qaJsonFilePath ? { "params.qaJsonFile": contract.qaJsonFilePath } : {}),
|
|
150
|
-
...(contract.taskContextJsonFilePath
|
|
151
|
-
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
152
|
-
: {}),
|
|
153
|
-
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
154
|
-
...(contract.jiraAttachmentsManifestFilePath
|
|
155
|
-
? { "params.jiraAttachmentsManifestFile": contract.jiraAttachmentsManifestFilePath }
|
|
156
|
-
: {}),
|
|
157
|
-
...(contract.jiraAttachmentsContextFilePath
|
|
158
|
-
? { "params.jiraAttachmentsContextFile": contract.jiraAttachmentsContextFilePath }
|
|
159
|
-
: {}),
|
|
160
|
-
...(contract.planningAnswersJsonFilePath
|
|
161
|
-
? { "params.planningAnswersJsonFile": contract.planningAnswersJsonFilePath }
|
|
162
|
-
: {}),
|
|
163
|
-
...(contract.taskInputJsonFilePath
|
|
164
|
-
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
165
|
-
: {}),
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (flow.kind === "review-flow") {
|
|
170
|
-
const taskKey = String(flowParams["taskKey"] ?? "");
|
|
171
|
-
if (taskKey) {
|
|
172
|
-
const inspection = inspectReviewInputContract(taskKey);
|
|
173
|
-
if (inspection.status === "ready") {
|
|
174
|
-
const { contract } = inspection;
|
|
175
|
-
resolvedFlowParams = withArtifactLineageRefPaths({
|
|
176
|
-
...flowParams,
|
|
177
|
-
planningIteration: contract.planningIteration,
|
|
178
|
-
designFile: contract.designFile,
|
|
179
|
-
designJsonFile: contract.designJsonFile,
|
|
180
|
-
planFile: contract.planFile,
|
|
181
|
-
planJsonFile: contract.planJsonFile,
|
|
182
|
-
hasTaskContextJsonFile: contract.hasTaskContextJsonFile,
|
|
183
|
-
taskContextJsonFilePath: contract.taskContextJsonFilePath,
|
|
184
|
-
taskContextJsonFile: contract.taskContextJsonFile,
|
|
185
|
-
hasJiraTaskFile: contract.hasJiraTaskFile,
|
|
186
|
-
jiraTaskFilePath: contract.jiraTaskFilePath,
|
|
187
|
-
jiraTaskFile: contract.jiraTaskFile,
|
|
188
|
-
hasTaskInputJsonFile: contract.hasTaskInputJsonFile,
|
|
189
|
-
taskInputJsonFilePath: contract.taskInputJsonFilePath,
|
|
190
|
-
taskInputJsonFile: contract.taskInputJsonFile,
|
|
191
|
-
}, {
|
|
192
|
-
"params.designFile": contract.designFile,
|
|
193
|
-
"params.designJsonFile": contract.designJsonFile,
|
|
194
|
-
"params.planFile": contract.planFile,
|
|
195
|
-
"params.planJsonFile": contract.planJsonFile,
|
|
196
|
-
...(contract.taskContextJsonFilePath
|
|
197
|
-
? { "params.taskContextJsonFile": contract.taskContextJsonFilePath }
|
|
198
|
-
: {}),
|
|
199
|
-
...(contract.jiraTaskFilePath ? { "params.jiraTaskFile": contract.jiraTaskFilePath } : {}),
|
|
200
|
-
...(contract.taskInputJsonFilePath
|
|
201
|
-
? { "params.taskInputJsonFile": contract.taskInputJsonFilePath }
|
|
202
|
-
: {}),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
218
|
+
const flow = await loadNamedDeclarativeFlow(fileName, context.cwd, {
|
|
219
|
+
...(context.registryContext ? { registryContext: context.registryContext } : {}),
|
|
220
|
+
});
|
|
221
|
+
const resolvedFlowParams = resolveNestedFlowParams(flow.kind, flowParams);
|
|
207
222
|
const resumeValue = isFlowRunResumeEnvelope(context.resumeStepValue)
|
|
208
223
|
&& context.resumeStepValue.flowKind === flow.kind
|
|
209
224
|
&& context.resumeStepValue.flowVersion === flow.version
|
|
@@ -26,46 +26,28 @@ export const llmPromptNode = {
|
|
|
26
26
|
const model = params.routingGroup
|
|
27
27
|
? routedProfile?.model ?? params.model ?? fallbackProfile?.model
|
|
28
28
|
: params.model ?? fallbackProfile?.model;
|
|
29
|
-
if (!executor || !isLlmExecutorId(executor)) {
|
|
29
|
+
if (!executor || !isLlmExecutorId(executor, context.executors)) {
|
|
30
30
|
throw new TaskRunnerError(`Unsupported llm executor '${String(executor ?? params.executor ?? "undefined")}'.`);
|
|
31
31
|
}
|
|
32
|
-
if (model && !isAllowedModelForExecutor(executor, model)) {
|
|
32
|
+
if (model && !isAllowedModelForExecutor(executor, model, context.executors)) {
|
|
33
33
|
throw new TaskRunnerError(`Model '${model}' is not allowed for executor '${executor}'.`);
|
|
34
34
|
}
|
|
35
35
|
printInfo(params.labelText);
|
|
36
36
|
printPrompt(`LLM:${executor}`, params.prompt);
|
|
37
37
|
const executorContext = toExecutorContext(context);
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
value
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
if (executor === "opencode") {
|
|
54
|
-
const executor = context.executors.get("opencode");
|
|
55
|
-
const value = await executor.execute(executorContext, {
|
|
56
|
-
prompt: params.prompt,
|
|
57
|
-
...(model ? { model } : {}),
|
|
58
|
-
env: { ...context.env },
|
|
59
|
-
}, executor.defaultConfig);
|
|
60
|
-
return {
|
|
61
|
-
value: {
|
|
62
|
-
...value,
|
|
63
|
-
executor: "opencode",
|
|
64
|
-
},
|
|
65
|
-
outputs: outputsForArtifacts(params.requiredArtifacts),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
throw new TaskRunnerError(`Unsupported llm executor '${executor}'.`);
|
|
38
|
+
const resolvedExecutor = context.executors.get(executor);
|
|
39
|
+
const value = await resolvedExecutor.execute(executorContext, {
|
|
40
|
+
prompt: params.prompt,
|
|
41
|
+
...(model ? { model } : {}),
|
|
42
|
+
env: { ...context.env },
|
|
43
|
+
}, resolvedExecutor.defaultConfig);
|
|
44
|
+
return {
|
|
45
|
+
value: {
|
|
46
|
+
...value,
|
|
47
|
+
executor,
|
|
48
|
+
},
|
|
49
|
+
outputs: outputsForArtifacts(params.requiredArtifacts),
|
|
50
|
+
};
|
|
69
51
|
},
|
|
70
52
|
checks(_context, params) {
|
|
71
53
|
if (!params.requiredArtifacts || params.requiredArtifacts.length === 0) {
|