agentweaver 0.1.11 → 0.1.12
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/artifacts.js +9 -0
- package/dist/executors/codex-executor.js +2 -1
- package/dist/executors/jira-fetch-executor.js +1 -0
- package/dist/executors/opencode-executor.js +22 -11
- package/dist/executors/process-executor.js +3 -0
- package/dist/index.js +42 -34
- package/dist/interactive-ui.js +579 -159
- package/dist/jira.js +57 -0
- package/dist/pipeline/flow-specs/gitlab/gitlab-review.json +105 -21
- package/dist/pipeline/flow-specs/review/review-fix.json +1 -0
- package/dist/pipeline/flow-specs/review/review-loop.json +2 -0
- package/dist/pipeline/flow-specs/task-describe.json +64 -3
- package/dist/pipeline/nodes/jira-fetch-node.js +3 -0
- package/dist/pipeline/nodes/review-findings-form-node.js +33 -3
- package/dist/pipeline/nodes/user-input-node.js +18 -4
- package/dist/pipeline/prompt-registry.js +2 -1
- package/dist/pipeline/spec-types.js +2 -0
- package/dist/pipeline/value-resolver.js +11 -1
- package/dist/prompts.js +17 -2
- package/dist/runtime/process-runner.js +9 -3
- package/dist/structured-artifact-schema-registry.js +1 -0
- package/dist/structured-artifact-schemas.json +22 -0
- package/dist/user-input.js +8 -1
- package/package.json +1 -1
package/dist/artifacts.js
CHANGED
|
@@ -134,6 +134,9 @@ export function readyToMergeFile(taskKey) {
|
|
|
134
134
|
export function jiraTaskFile(taskKey) {
|
|
135
135
|
return taskArtifactsFile(taskKey, `${taskKey}.json`);
|
|
136
136
|
}
|
|
137
|
+
export function jiraTaskEnrichedFile(taskKey) {
|
|
138
|
+
return taskArtifactsFile(taskKey, `${taskKey}-enriched.json`);
|
|
139
|
+
}
|
|
137
140
|
export function jiraAttachmentsDir(taskKey) {
|
|
138
141
|
return path.join(taskArtifactsDir(taskKey), "jira-attachments");
|
|
139
142
|
}
|
|
@@ -222,6 +225,12 @@ export function reviewFixFile(taskKey, iteration) {
|
|
|
222
225
|
export function reviewFixJsonFile(taskKey, iteration) {
|
|
223
226
|
return artifactJsonFile("review-fix", taskKey, iteration);
|
|
224
227
|
}
|
|
228
|
+
export function reviewAssessmentFile(taskKey, iteration) {
|
|
229
|
+
return artifactFile("review-assessment", taskKey, iteration);
|
|
230
|
+
}
|
|
231
|
+
export function reviewAssessmentJsonFile(taskKey, iteration) {
|
|
232
|
+
return artifactJsonFile("review-assessment", taskKey, iteration);
|
|
233
|
+
}
|
|
225
234
|
export function reviewFixSelectionJsonFile(taskKey, iteration) {
|
|
226
235
|
return artifactJsonFile("review-fix-selection", taskKey, iteration);
|
|
227
236
|
}
|
|
@@ -12,9 +12,10 @@ export const codexExecutor = {
|
|
|
12
12
|
const command = input.command ?? context.runtime.resolveCmd(config.defaultCommand, config.commandEnvVar);
|
|
13
13
|
const model = input.model?.trim() || resolveModel(config, env);
|
|
14
14
|
const result = await processExecutor.execute(context, {
|
|
15
|
-
argv: [command, config.subcommand, "--model", model, config.fullAutoFlag,
|
|
15
|
+
argv: [command, config.subcommand, "--model", model, config.fullAutoFlag, "-"],
|
|
16
16
|
env,
|
|
17
17
|
label: `codex:${model}`,
|
|
18
|
+
stdin: input.prompt,
|
|
18
19
|
}, processExecutor.defaultConfig);
|
|
19
20
|
return {
|
|
20
21
|
output: result.output,
|
|
@@ -12,6 +12,7 @@ export const jiraFetchExecutor = {
|
|
|
12
12
|
planningContextAttachments: artifacts.planningContextAttachments,
|
|
13
13
|
...(artifacts.attachmentsManifestFile ? { attachmentsManifestFile: artifacts.attachmentsManifestFile } : {}),
|
|
14
14
|
...(artifacts.attachmentsContextFile ? { attachmentsContextFile: artifacts.attachmentsContextFile } : {}),
|
|
15
|
+
...(artifacts.enrichedFile ? { enrichedFile: artifacts.enrichedFile } : {}),
|
|
15
16
|
};
|
|
16
17
|
},
|
|
17
18
|
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
1
4
|
import { opencodeExecutorDefaultConfig } from "./configs/opencode-config.js";
|
|
2
5
|
import { processExecutor } from "./process-executor.js";
|
|
3
6
|
function resolveModel(config, inputModel, env) {
|
|
@@ -17,19 +20,27 @@ export const opencodeExecutor = {
|
|
|
17
20
|
const command = input.command ?? context.runtime.resolveCmd(config.defaultCommand, config.commandEnvVar);
|
|
18
21
|
const model = resolveModel(config, input.model, env);
|
|
19
22
|
const argv = [command, config.subcommand];
|
|
23
|
+
const tempDir = mkdtempSync(path.join(os.tmpdir(), "agentweaver-opencode-"));
|
|
24
|
+
const promptFile = path.join(tempDir, "prompt.md");
|
|
25
|
+
writeFileSync(promptFile, input.prompt, "utf8");
|
|
20
26
|
if (model) {
|
|
21
27
|
argv.push("--model", model);
|
|
22
28
|
}
|
|
23
|
-
argv.push(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
argv.push("--file", promptFile, "--", "Use the attached file as the full task prompt. Follow it exactly.");
|
|
30
|
+
try {
|
|
31
|
+
const result = await processExecutor.execute(context, {
|
|
32
|
+
argv,
|
|
33
|
+
env,
|
|
34
|
+
label: model ? `opencode:${model}` : "opencode",
|
|
35
|
+
}, processExecutor.defaultConfig);
|
|
36
|
+
return {
|
|
37
|
+
output: result.output,
|
|
38
|
+
command,
|
|
39
|
+
...(model ? { model } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
44
|
+
}
|
|
34
45
|
},
|
|
35
46
|
};
|
|
@@ -15,6 +15,9 @@ export const processExecutor = {
|
|
|
15
15
|
if (input.label) {
|
|
16
16
|
options.label = input.label;
|
|
17
17
|
}
|
|
18
|
+
if (input.stdin !== undefined) {
|
|
19
|
+
options.stdin = input.stdin;
|
|
20
|
+
}
|
|
18
21
|
const output = await context.runtime.runCommand(input.argv, options);
|
|
19
22
|
return { output };
|
|
20
23
|
},
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { REVIEW_FILE_RE, bugAnalyzeArtifacts, bugAnalyzeJsonFile, bugFixDesignJsonFile, bugFixPlanJsonFile, designJsonFile, gitlabDiffFile, gitlabDiffJsonFile, ensureScopeWorkspaceDir, gitlabReviewFile, gitlabReviewJsonFile, latestArtifactIteration, nextArtifactIteration, planJsonFile, planArtifacts, qaJsonFile, readyToMergeFile, requireArtifacts, reviewFile, reviewFixSelectionJsonFile, reviewJsonFile, scopeWorkspaceDir, flowStateFile, taskSummaryFile, } from "./artifacts.js";
|
|
6
|
+
import { REVIEW_FILE_RE, bugAnalyzeArtifacts, bugAnalyzeJsonFile, bugFixDesignJsonFile, bugFixPlanJsonFile, designJsonFile, gitlabDiffFile, gitlabDiffJsonFile, ensureScopeWorkspaceDir, gitlabReviewFile, gitlabReviewJsonFile, latestArtifactIteration, nextArtifactIteration, planJsonFile, planArtifacts, qaJsonFile, readyToMergeFile, requireArtifacts, reviewAssessmentFile, reviewAssessmentJsonFile, reviewFile, reviewFixSelectionJsonFile, reviewJsonFile, scopeWorkspaceDir, flowStateFile, taskSummaryFile, } from "./artifacts.js";
|
|
7
7
|
import { FlowInterruptedError, TaskRunnerError } from "./errors.js";
|
|
8
8
|
import { createFlowRunState, hasResumableFlowState, loadFlowRunState, prepareFlowStateForResume, resetFlowRunState, rewindFlowRunStateToPhase, saveFlowRunState, stripExecutionStatePayload, } from "./flow-state.js";
|
|
9
9
|
import { requireJiraTaskFile } from "./jira.js";
|
|
@@ -194,14 +194,11 @@ function launchProfileSelectionForm() {
|
|
|
194
194
|
type: "single-select",
|
|
195
195
|
label: "Executor",
|
|
196
196
|
required: true,
|
|
197
|
-
default:
|
|
198
|
-
options:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
label: id === defaultExecutor ? `${id} [default]` : id,
|
|
203
|
-
})),
|
|
204
|
-
],
|
|
197
|
+
default: defaultExecutor,
|
|
198
|
+
options: LLM_EXECUTOR_IDS.map((id) => ({
|
|
199
|
+
value: id,
|
|
200
|
+
label: id === defaultExecutor ? `${id} [default]` : id,
|
|
201
|
+
})),
|
|
205
202
|
},
|
|
206
203
|
],
|
|
207
204
|
};
|
|
@@ -209,15 +206,10 @@ function launchProfileSelectionForm() {
|
|
|
209
206
|
function launchModelSelectionForm(executor) {
|
|
210
207
|
const resolvedExecutor = executor === "default" ? DEFAULT_LAUNCH_PROFILE.executor : executor;
|
|
211
208
|
const defaultModel = defaultModelForExecutor(resolvedExecutor);
|
|
212
|
-
const options =
|
|
213
|
-
|
|
214
|
-
: [
|
|
215
|
-
|
|
216
|
-
...ALLOWED_MODELS_BY_EXECUTOR[executor].map((model) => ({
|
|
217
|
-
value: model,
|
|
218
|
-
label: model === defaultModel ? `${model} [default]` : model,
|
|
219
|
-
})),
|
|
220
|
-
];
|
|
209
|
+
const options = ALLOWED_MODELS_BY_EXECUTOR[resolvedExecutor].map((model) => ({
|
|
210
|
+
value: model,
|
|
211
|
+
label: model === defaultModel ? `${model} [default]` : model,
|
|
212
|
+
}));
|
|
221
213
|
return {
|
|
222
214
|
formId: "flow-launch-model",
|
|
223
215
|
title: "Настройки запуска LLM",
|
|
@@ -229,25 +221,38 @@ function launchModelSelectionForm(executor) {
|
|
|
229
221
|
type: "single-select",
|
|
230
222
|
label: "Model",
|
|
231
223
|
required: true,
|
|
232
|
-
default:
|
|
224
|
+
default: defaultModel,
|
|
233
225
|
options,
|
|
234
226
|
},
|
|
235
227
|
],
|
|
236
228
|
};
|
|
237
229
|
}
|
|
230
|
+
function isFormCancellation(error, formId) {
|
|
231
|
+
return error instanceof TaskRunnerError && error.message === `User cancelled form '${formId}'.`;
|
|
232
|
+
}
|
|
238
233
|
async function requestInteractiveLaunchProfile(requestUserInput) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
234
|
+
for (;;) {
|
|
235
|
+
const executorFormResult = await requestUserInput(launchProfileSelectionForm());
|
|
236
|
+
const rawExecutor = String(executorFormResult.values.executor ?? DEFAULT_LAUNCH_PROFILE.executor);
|
|
237
|
+
const executor = LLM_EXECUTOR_IDS.find((id) => id === rawExecutor);
|
|
238
|
+
if (!executor) {
|
|
239
|
+
throw new TaskRunnerError(`Unsupported launch executor '${rawExecutor}'.`);
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const modelFormResult = await requestUserInput(launchModelSelectionForm(executor));
|
|
243
|
+
const rawModel = String(modelFormResult.values.model ?? defaultModelForExecutor(executor)).trim();
|
|
244
|
+
return resolveLaunchProfile({
|
|
245
|
+
executor,
|
|
246
|
+
model: rawModel.length > 0 ? rawModel : defaultModelForExecutor(executor),
|
|
247
|
+
}, DEFAULT_LAUNCH_PROFILE);
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
if (isFormCancellation(error, "flow-launch-model")) {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
251
256
|
}
|
|
252
257
|
function buildResolverContext(pipelineContext, flowParams, flowConstants, repeatVars, executionState) {
|
|
253
258
|
return {
|
|
@@ -521,13 +526,13 @@ const FLOW_DESCRIPTIONS = {
|
|
|
521
526
|
"bug-analyze": "Analyzes bug from Jira and creates structured artifacts: root cause hypothesis, fix design, and implementation plan.",
|
|
522
527
|
"git-commit": "Collects git status/diff, generates commit message via LLM, allows file selection and commit confirmation.",
|
|
523
528
|
"gitlab-diff-review": "Requests GitLab MR URL via user-input, downloads merge request diff via API, and runs code review with markdown and structured JSON artifacts.",
|
|
524
|
-
"gitlab-review": "Requests GitLab MR URL via user-input, downloads code review comments via API, and
|
|
529
|
+
"gitlab-review": "Requests GitLab MR URL via user-input, downloads code review comments via API, assesses which findings are fair and proposes fixes, then runs review-fix for the selected findings.",
|
|
525
530
|
"bug-fix": "Takes bug-analyze results as source of truth and implements the bug fix in code.",
|
|
526
531
|
"mr-description": "Prepares a brief intent description for a merge request based on the task and current changes.",
|
|
527
532
|
plan: "Loads task from Jira and creates design, implementation plan, and QA plan in structured JSON and markdown.",
|
|
528
533
|
"task-describe": "Builds a brief task description either from Jira or from quick user-input without Jira.",
|
|
529
534
|
implement: "Implements the task from approved design/plan artifacts and runs post-verify builds if needed.",
|
|
530
|
-
review: "Runs code review of current changes
|
|
535
|
+
review: "Runs code review of current changes and writes structured findings artifacts.",
|
|
531
536
|
"review-fix": "Fixes issues after review-reply, updates code, and runs mandatory checks after modifications.",
|
|
532
537
|
"review-loop": "Iteratively runs review and review-fix cycles up to 5 times until ready-to-merge is achieved.",
|
|
533
538
|
"run-go-tests-loop": "Cycles through `./run_go_tests.py` locally, analyzes the last error, and fixes code until successful or attempts exhausted.",
|
|
@@ -880,9 +885,11 @@ async function executeCommand(baseConfig, runFollowupVerify = true, requestUserI
|
|
|
880
885
|
iteration,
|
|
881
886
|
gitlabReviewIteration,
|
|
882
887
|
extraPrompt: config.extraPrompt,
|
|
888
|
+
reviewFixSelectionJsonFile: reviewFixSelectionJsonFile(config.taskKey, iteration),
|
|
889
|
+
reviewFixPoints: config.reviewFixPoints,
|
|
883
890
|
}, launchProfile ? { launchProfile } : {}, requestUserInput, undefined, launchMode, runtime);
|
|
884
891
|
if (!config.dryRun) {
|
|
885
|
-
printSummary("GitLab Review", `Artifacts:\n${gitlabReviewFile(config.taskKey)}\n${gitlabReviewJsonFile(config.taskKey)}`);
|
|
892
|
+
printSummary("GitLab Review", `Artifacts:\n${gitlabReviewFile(config.taskKey)}\n${gitlabReviewJsonFile(config.taskKey)}\n${reviewFile(config.taskKey, iteration)}\n${reviewJsonFile(config.taskKey, iteration)}\n${reviewAssessmentFile(config.taskKey, iteration)}\n${reviewAssessmentJsonFile(config.taskKey, iteration)}`);
|
|
886
893
|
}
|
|
887
894
|
return false;
|
|
888
895
|
}
|
|
@@ -982,6 +989,7 @@ async function executeCommand(baseConfig, runFollowupVerify = true, requestUserI
|
|
|
982
989
|
await runDeclarativeFlowBySpecFile("review/review-fix.json", config, {
|
|
983
990
|
taskKey: config.taskKey,
|
|
984
991
|
latestIteration,
|
|
992
|
+
reviewAssessmentJsonFile: null,
|
|
985
993
|
reviewFixSelectionJsonFile: reviewFixSelectionJsonFile(config.taskKey, latestIteration),
|
|
986
994
|
extraPrompt: config.extraPrompt,
|
|
987
995
|
reviewFixPoints: config.reviewFixPoints,
|