agentweaver 0.1.15 → 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 +76 -19
- package/dist/artifact-manifest.js +219 -0
- package/dist/artifacts.js +88 -3
- package/dist/doctor/checks/env-diagnostics.js +25 -0
- package/dist/doctor/checks/executors.js +2 -2
- package/dist/doctor/checks/flow-readiness.js +15 -18
- package/dist/flow-state.js +212 -15
- package/dist/index.js +539 -209
- package/dist/interactive/blessed-session.js +361 -0
- package/dist/interactive/controller.js +1326 -0
- package/dist/interactive/create-interactive-session.js +5 -0
- package/dist/interactive/ink/index.js +597 -0
- package/dist/interactive/progress.js +245 -0
- package/dist/interactive/selectors.js +14 -0
- package/dist/interactive/session.js +1 -0
- package/dist/interactive/state.js +34 -0
- package/dist/interactive/tree.js +155 -0
- package/dist/interactive/types.js +1 -0
- package/dist/interactive/view-model.js +1 -0
- package/dist/interactive-ui.js +159 -194
- package/dist/pipeline/auto-flow.js +9 -6
- package/dist/pipeline/context.js +7 -5
- package/dist/pipeline/declarative-flow-runner.js +212 -6
- package/dist/pipeline/declarative-flows.js +63 -17
- package/dist/pipeline/execution-routing-config.js +15 -0
- package/dist/pipeline/flow-catalog.js +50 -12
- package/dist/pipeline/flow-run-resume.js +29 -0
- package/dist/pipeline/flow-specs/auto-common.json +90 -360
- package/dist/pipeline/flow-specs/auto-golang.json +81 -360
- package/dist/pipeline/flow-specs/auto-simple.json +141 -0
- package/dist/pipeline/flow-specs/bugz/bug-analyze.json +2 -0
- package/dist/pipeline/flow-specs/bugz/bug-fix.json +1 -0
- package/dist/pipeline/flow-specs/design-review/design-review-loop.json +316 -0
- package/dist/pipeline/flow-specs/design-review.json +10 -0
- package/dist/pipeline/flow-specs/gitlab/gitlab-diff-review.json +11 -0
- package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +2 -0
- package/dist/pipeline/flow-specs/gitlab/mr-description.json +1 -0
- package/dist/pipeline/flow-specs/go/run-go-linter-loop.json +2 -0
- package/dist/pipeline/flow-specs/go/run-go-tests-loop.json +2 -0
- package/dist/pipeline/flow-specs/implement.json +13 -6
- package/dist/pipeline/flow-specs/instant-task.json +177 -0
- package/dist/pipeline/flow-specs/normalize-task-source.json +311 -0
- package/dist/pipeline/flow-specs/plan-revise.json +7 -1
- package/dist/pipeline/flow-specs/plan.json +51 -71
- package/dist/pipeline/flow-specs/review/review-fix.json +24 -4
- package/dist/pipeline/flow-specs/review/review-loop.json +351 -45
- package/dist/pipeline/flow-specs/review/review-project-loop.json +590 -0
- package/dist/pipeline/flow-specs/review/review-project.json +12 -0
- package/dist/pipeline/flow-specs/review/review.json +37 -31
- package/dist/pipeline/flow-specs/task-describe.json +2 -0
- package/dist/pipeline/flow-specs/task-source/jira-fetch.json +70 -0
- package/dist/pipeline/flow-specs/task-source/manual-input.json +216 -0
- package/dist/pipeline/launch-profile-config.js +30 -18
- package/dist/pipeline/node-contract.js +1 -0
- package/dist/pipeline/node-registry.js +115 -6
- package/dist/pipeline/node-runner.js +3 -2
- package/dist/pipeline/nodes/build-review-fix-prompt-node.js +5 -1
- package/dist/pipeline/nodes/clear-ready-to-merge-node.js +11 -0
- package/dist/pipeline/nodes/commit-message-form-node.js +8 -0
- package/dist/pipeline/nodes/design-review-verdict-node.js +36 -0
- package/dist/pipeline/nodes/ensure-summary-json-node.js +13 -2
- package/dist/pipeline/nodes/fetch-gitlab-diff-node.js +19 -2
- package/dist/pipeline/nodes/fetch-gitlab-review-node.js +19 -2
- package/dist/pipeline/nodes/flow-run-node.js +242 -8
- package/dist/pipeline/nodes/git-commit-form-node.js +8 -0
- package/dist/pipeline/nodes/gitlab-review-artifacts-node.js +19 -2
- package/dist/pipeline/nodes/jira-fetch-node.js +50 -4
- package/dist/pipeline/nodes/llm-prompt-node.js +38 -36
- package/dist/pipeline/nodes/planning-bundle-node.js +10 -0
- package/dist/pipeline/nodes/review-verdict-node.js +86 -0
- package/dist/pipeline/nodes/select-files-form-node.js +8 -0
- package/dist/pipeline/nodes/structured-summary-node.js +24 -0
- package/dist/pipeline/nodes/user-input-node.js +38 -3
- package/dist/pipeline/nodes/write-selection-file-node.js +20 -4
- package/dist/pipeline/plugin-loader.js +389 -0
- package/dist/pipeline/plugin-types.js +1 -0
- package/dist/pipeline/prompt-registry.js +3 -1
- package/dist/pipeline/prompt-runtime.js +4 -1
- package/dist/pipeline/registry.js +71 -4
- package/dist/pipeline/review-iteration.js +26 -0
- package/dist/pipeline/spec-compiler.js +3 -0
- package/dist/pipeline/spec-loader.js +14 -0
- package/dist/pipeline/spec-types.js +3 -0
- package/dist/pipeline/spec-validator.js +20 -0
- package/dist/pipeline/value-resolver.js +76 -2
- package/dist/plugin-sdk.js +1 -0
- package/dist/prompts.js +36 -14
- package/dist/review-severity.js +45 -0
- package/dist/runtime/artifact-registry.js +405 -0
- package/dist/runtime/design-review-input-contract.js +17 -16
- package/dist/runtime/env-loader.js +3 -0
- package/dist/runtime/execution-routing-store.js +134 -0
- package/dist/runtime/execution-routing.js +233 -0
- package/dist/runtime/interactive-execution-routing.js +471 -0
- package/dist/runtime/plan-revise-input-contract.js +35 -32
- package/dist/runtime/planning-bundle.js +123 -0
- package/dist/runtime/ready-to-merge.js +22 -1
- package/dist/runtime/review-input-contract.js +100 -0
- package/dist/structured-artifact-schema-registry.js +9 -0
- package/dist/structured-artifact-schemas.json +140 -1
- package/dist/structured-artifacts.js +77 -6
- package/dist/user-input.js +70 -3
- 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 +11 -4
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { TaskRunnerError } from "../errors.js";
|
|
3
|
+
import { allowedModelsForExecutor, DEFAULT_LAUNCH_PROFILE, defaultModelForExecutor, isAllowedModelForExecutor, resolveLaunchProfile, } from "../pipeline/launch-profile-config.js";
|
|
4
|
+
import { BUILT_IN_EXECUTION_PRESET_IDS, EXECUTION_ROUTING_GROUPS, } from "../pipeline/execution-routing-config.js";
|
|
5
|
+
export const BUILT_IN_EXECUTION_PRESETS = {
|
|
6
|
+
balanced: {
|
|
7
|
+
id: "balanced",
|
|
8
|
+
label: "Balanced",
|
|
9
|
+
description: "Use Codex for planning and review, OpenCode for implementation-style loops.",
|
|
10
|
+
defaultRoute: { executor: "opencode", model: "default" },
|
|
11
|
+
groupOverrides: {
|
|
12
|
+
planning: { executor: "codex", model: "gpt-5.4" },
|
|
13
|
+
"design-review": { executor: "codex", model: "gpt-5.4" },
|
|
14
|
+
review: { executor: "codex", model: "gpt-5.4" },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
"quality-first": {
|
|
18
|
+
id: "quality-first",
|
|
19
|
+
label: "Quality-first",
|
|
20
|
+
description: "Run all routing groups on Codex GPT-5.4.",
|
|
21
|
+
defaultRoute: { executor: "codex", model: "gpt-5.4" },
|
|
22
|
+
},
|
|
23
|
+
"cheap-first": {
|
|
24
|
+
id: "cheap-first",
|
|
25
|
+
label: "Cheap-first",
|
|
26
|
+
description: "Prefer lower-cost models while preserving valid executor and model pairs.",
|
|
27
|
+
defaultRoute: { executor: "opencode", model: "opencode/minimax-m2.5-free" },
|
|
28
|
+
groupOverrides: {
|
|
29
|
+
planning: { executor: "codex", model: "gpt-5.4-mini" },
|
|
30
|
+
"design-review": { executor: "codex", model: "gpt-5.4-mini" },
|
|
31
|
+
review: { executor: "codex", model: "gpt-5.4-mini" },
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
"codex-only": {
|
|
35
|
+
id: "codex-only",
|
|
36
|
+
label: "Codex-only",
|
|
37
|
+
description: "Run all routing groups on Codex with the default Codex model.",
|
|
38
|
+
defaultRoute: { executor: "codex", model: "default" },
|
|
39
|
+
},
|
|
40
|
+
"opencode-only": {
|
|
41
|
+
id: "opencode-only",
|
|
42
|
+
label: "OpenCode-only",
|
|
43
|
+
description: "Run all routing groups on OpenCode with the default OpenCode model.",
|
|
44
|
+
defaultRoute: { executor: "opencode", model: "default" },
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
function stableRoutingPayload(routing) {
|
|
48
|
+
return JSON.stringify({
|
|
49
|
+
defaultRoute: {
|
|
50
|
+
executor: routing.defaultRoute.executor,
|
|
51
|
+
model: routing.defaultRoute.model,
|
|
52
|
+
},
|
|
53
|
+
groups: Object.fromEntries(EXECUTION_ROUTING_GROUPS.map((group) => [
|
|
54
|
+
group,
|
|
55
|
+
{
|
|
56
|
+
executor: routing.groups[group].executor,
|
|
57
|
+
model: routing.groups[group].model,
|
|
58
|
+
},
|
|
59
|
+
])),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function executionRoutingFingerprint(routing) {
|
|
63
|
+
return createHash("sha256").update(stableRoutingPayload({ ...routing, fingerprint: "" })).digest("hex");
|
|
64
|
+
}
|
|
65
|
+
export function validateExecutionRoute(executor, model, executors) {
|
|
66
|
+
if (!executors && !isAllowedModelForExecutor(executor, model)) {
|
|
67
|
+
throw new TaskRunnerError(`Unsupported llm executor '${executor}'.`);
|
|
68
|
+
}
|
|
69
|
+
if (executors && !executors.getRouting(executor)) {
|
|
70
|
+
throw new TaskRunnerError(`Unsupported llm executor '${executor}'.`);
|
|
71
|
+
}
|
|
72
|
+
if (!isAllowedModelForExecutor(executor, model, executors)) {
|
|
73
|
+
throw new TaskRunnerError(`Model '${model}' is not allowed for executor '${executor}'.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function toExecutionRouteSelection(route) {
|
|
77
|
+
return {
|
|
78
|
+
executor: route.executor,
|
|
79
|
+
model: route.model,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function resolveExecutionRoute(selection, fallback, executors) {
|
|
83
|
+
const launchProfile = resolveLaunchProfile({
|
|
84
|
+
executor: selection.executor,
|
|
85
|
+
model: selection.model,
|
|
86
|
+
}, fallback, executors);
|
|
87
|
+
validateExecutionRoute(launchProfile.executor, launchProfile.model, executors);
|
|
88
|
+
return launchProfile;
|
|
89
|
+
}
|
|
90
|
+
export function resolveExecutionRouting(options) {
|
|
91
|
+
const fallbackDefaultRoute = options.fallbackDefaultRoute ?? DEFAULT_LAUNCH_PROFILE;
|
|
92
|
+
const preset = options.presetId ? BUILT_IN_EXECUTION_PRESETS[options.presetId] : null;
|
|
93
|
+
const defaultRouteSelection = options.defaultRoute ?? preset?.defaultRoute ?? toExecutionRouteSelection(fallbackDefaultRoute);
|
|
94
|
+
const defaultRoute = resolveExecutionRoute(defaultRouteSelection, fallbackDefaultRoute, options.executors);
|
|
95
|
+
const groups = Object.fromEntries(EXECUTION_ROUTING_GROUPS.map((group) => {
|
|
96
|
+
const override = options.currentRunOverrides?.[group]
|
|
97
|
+
?? options.presetOverrides?.[group]
|
|
98
|
+
?? preset?.groupOverrides?.[group]
|
|
99
|
+
?? { executor: "default", model: "default" };
|
|
100
|
+
return [group, resolveExecutionRoute(override, defaultRoute, options.executors)];
|
|
101
|
+
}));
|
|
102
|
+
const fingerprint = executionRoutingFingerprint({
|
|
103
|
+
defaultRoute,
|
|
104
|
+
groups,
|
|
105
|
+
});
|
|
106
|
+
return {
|
|
107
|
+
defaultRoute,
|
|
108
|
+
groups,
|
|
109
|
+
fingerprint,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export function routingGroupLabel(group) {
|
|
113
|
+
switch (group) {
|
|
114
|
+
case "planning":
|
|
115
|
+
return "Planning";
|
|
116
|
+
case "design-review":
|
|
117
|
+
return "Design review";
|
|
118
|
+
case "implementation":
|
|
119
|
+
return "Implementation";
|
|
120
|
+
case "review":
|
|
121
|
+
return "Review";
|
|
122
|
+
case "repair-loop":
|
|
123
|
+
return "Repair loop";
|
|
124
|
+
case "local-fix-loop":
|
|
125
|
+
return "Local fix loop";
|
|
126
|
+
default:
|
|
127
|
+
return group;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export function describeExecutionRouting(routing, groups = EXECUTION_ROUTING_GROUPS) {
|
|
131
|
+
const lines = [`Default: ${routing.defaultRoute.executor} / ${routing.defaultRoute.model}`];
|
|
132
|
+
for (const group of groups) {
|
|
133
|
+
const route = routing.groups[group];
|
|
134
|
+
lines.push(`${routingGroupLabel(group)}: ${route.executor} / ${route.model}`);
|
|
135
|
+
}
|
|
136
|
+
return lines.join("\n");
|
|
137
|
+
}
|
|
138
|
+
export function executorsForRoutingGroups(routing, groups) {
|
|
139
|
+
const requiredExecutors = [];
|
|
140
|
+
for (const group of groups) {
|
|
141
|
+
const executor = routing.groups[group].executor;
|
|
142
|
+
if (!requiredExecutors.includes(executor)) {
|
|
143
|
+
requiredExecutors.push(executor);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return requiredExecutors;
|
|
147
|
+
}
|
|
148
|
+
export function normalizeEditableExecutionRouting(routes, executors) {
|
|
149
|
+
const normalizedRoutes = {};
|
|
150
|
+
const validationErrors = [];
|
|
151
|
+
for (const group of EXECUTION_ROUTING_GROUPS) {
|
|
152
|
+
const route = routes[group];
|
|
153
|
+
if (isAllowedModelForExecutor(route.executor, route.model, executors)) {
|
|
154
|
+
normalizedRoutes[group] = { ...route };
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
normalizedRoutes[group] = {
|
|
158
|
+
executor: route.executor,
|
|
159
|
+
model: defaultModelForExecutor(route.executor, executors),
|
|
160
|
+
};
|
|
161
|
+
validationErrors.push(`${routingGroupLabel(group)} model '${route.model}' is not allowed for executor '${route.executor}'. Select a ${route.executor} model.`);
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
routes: normalizedRoutes,
|
|
165
|
+
validationErrors,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export function builtInExecutionPresetList() {
|
|
169
|
+
return BUILT_IN_EXECUTION_PRESET_IDS.map((id) => BUILT_IN_EXECUTION_PRESETS[id]);
|
|
170
|
+
}
|
|
171
|
+
export function selectedExecutionPresetLabel(selection) {
|
|
172
|
+
return selection.label;
|
|
173
|
+
}
|
|
174
|
+
export function cloneResolvedExecutionRouting(routing) {
|
|
175
|
+
return {
|
|
176
|
+
defaultRoute: { ...routing.defaultRoute },
|
|
177
|
+
groups: Object.fromEntries(EXECUTION_ROUTING_GROUPS.map((group) => [group, { ...routing.groups[group] }])),
|
|
178
|
+
fingerprint: routing.fingerprint,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
export function defaultExecutionRouting() {
|
|
182
|
+
return resolveExecutionRouting({
|
|
183
|
+
defaultRoute: {
|
|
184
|
+
executor: DEFAULT_LAUNCH_PROFILE.executor,
|
|
185
|
+
model: DEFAULT_LAUNCH_PROFILE.model,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
export function resolveStoredExecutionRoutingSnapshot(routing, executors) {
|
|
190
|
+
if (executors) {
|
|
191
|
+
validateExecutionRoute(routing.defaultRoute.executor, routing.defaultRoute.model, executors);
|
|
192
|
+
}
|
|
193
|
+
for (const group of EXECUTION_ROUTING_GROUPS) {
|
|
194
|
+
if (executors) {
|
|
195
|
+
validateExecutionRoute(routing.groups[group].executor, routing.groups[group].model, executors);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const fingerprint = executionRoutingFingerprint({
|
|
199
|
+
defaultRoute: routing.defaultRoute,
|
|
200
|
+
groups: routing.groups,
|
|
201
|
+
});
|
|
202
|
+
return {
|
|
203
|
+
defaultRoute: {
|
|
204
|
+
...routing.defaultRoute,
|
|
205
|
+
selectedExecutor: routing.defaultRoute.selectedExecutor ?? routing.defaultRoute.executor,
|
|
206
|
+
selectedModel: routing.defaultRoute.selectedModel ?? routing.defaultRoute.model,
|
|
207
|
+
fingerprint: routing.defaultRoute.fingerprint ?? `${routing.defaultRoute.executor}::${routing.defaultRoute.model}`,
|
|
208
|
+
},
|
|
209
|
+
groups: Object.fromEntries(EXECUTION_ROUTING_GROUPS.map((group) => {
|
|
210
|
+
const route = routing.groups[group];
|
|
211
|
+
return [group, {
|
|
212
|
+
...route,
|
|
213
|
+
selectedExecutor: route.selectedExecutor ?? route.executor,
|
|
214
|
+
selectedModel: route.selectedModel ?? route.model,
|
|
215
|
+
fingerprint: route.fingerprint ?? `${route.executor}::${route.model}`,
|
|
216
|
+
}];
|
|
217
|
+
})),
|
|
218
|
+
fingerprint,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
export function singleLaunchProfileExecutionRouting(launchProfile) {
|
|
222
|
+
return resolveExecutionRouting({
|
|
223
|
+
defaultRoute: toExecutionRouteSelection(launchProfile),
|
|
224
|
+
currentRunOverrides: Object.fromEntries(EXECUTION_ROUTING_GROUPS.map((group) => [group, toExecutionRouteSelection(launchProfile)])),
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
export function modelOptionsForExecutor(executor, executors) {
|
|
228
|
+
const defaultModel = defaultModelForExecutor(executor, executors);
|
|
229
|
+
return allowedModelsForExecutor(executor, executors).map((model) => ({
|
|
230
|
+
value: model,
|
|
231
|
+
label: model === defaultModel ? `${model} [default]` : model,
|
|
232
|
+
}));
|
|
233
|
+
}
|