agentweaver 0.1.10 → 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/README.md +218 -224
- package/dist/artifacts.js +109 -55
- package/dist/executors/{codex-local-executor.js → codex-executor.js} +6 -5
- package/dist/executors/configs/{codex-local-config.js → codex-config.js} +1 -1
- package/dist/executors/configs/jira-fetch-config.js +2 -0
- package/dist/executors/configs/telegram-notifier-config.js +3 -0
- package/dist/executors/fetch-gitlab-diff-executor.js +1 -1
- package/dist/executors/fetch-gitlab-review-executor.js +1 -1
- package/dist/executors/git-commit-executor.js +25 -0
- 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/executors/telegram-notifier-executor.js +54 -0
- package/dist/flow-state.js +46 -1
- package/dist/gitlab.js +13 -8
- package/dist/index.js +477 -514
- package/dist/interactive-ui.js +609 -88
- package/dist/jira.js +109 -5
- package/dist/pipeline/auto-flow.js +6 -6
- package/dist/pipeline/context.js +1 -0
- package/dist/pipeline/flow-catalog.js +34 -4
- package/dist/pipeline/flow-model-settings.js +77 -0
- package/dist/pipeline/flow-specs/auto-common.json +446 -0
- package/dist/pipeline/flow-specs/auto-golang.json +563 -0
- package/dist/pipeline/flow-specs/{bug-analyze.json → bugz/bug-analyze.json} +43 -25
- package/dist/pipeline/flow-specs/{bug-fix.json → bugz/bug-fix.json} +5 -4
- package/dist/pipeline/flow-specs/git-commit.json +196 -0
- package/dist/pipeline/flow-specs/{gitlab-diff-review.json → gitlab/gitlab-diff-review.json} +20 -50
- package/dist/pipeline/flow-specs/{gitlab-review.json → gitlab/gitlab-review.json} +65 -133
- package/dist/pipeline/flow-specs/{mr-description.json → gitlab/mr-description.json} +17 -10
- package/dist/pipeline/flow-specs/{run-go-linter-loop.json → go/run-go-linter-loop.json} +40 -14
- package/dist/pipeline/flow-specs/{run-go-tests-loop.json → go/run-go-tests-loop.json} +40 -14
- package/dist/pipeline/flow-specs/implement.json +5 -4
- package/dist/pipeline/flow-specs/plan.json +40 -148
- package/dist/pipeline/flow-specs/{review-fix.json → review/review-fix.json} +74 -13
- package/dist/pipeline/flow-specs/review/review-loop.json +282 -0
- package/dist/pipeline/flow-specs/review/review-project.json +87 -0
- package/dist/pipeline/flow-specs/review/review.json +126 -0
- package/dist/pipeline/flow-specs/task-describe.json +252 -11
- package/dist/pipeline/launch-profile-config.js +38 -0
- package/dist/pipeline/node-registry.js +75 -45
- package/dist/pipeline/nodes/build-failure-summary-node.js +16 -29
- package/dist/pipeline/nodes/build-review-fix-prompt-node.js +36 -0
- package/dist/pipeline/nodes/codex-prompt-node.js +41 -0
- package/dist/pipeline/nodes/commit-message-form-node.js +79 -0
- package/dist/pipeline/nodes/git-commit-form-node.js +138 -0
- package/dist/pipeline/nodes/git-commit-node.js +28 -0
- package/dist/pipeline/nodes/git-status-node.js +221 -0
- package/dist/pipeline/nodes/gitlab-review-artifacts-node.js +10 -6
- package/dist/pipeline/nodes/jira-context-node.js +10 -0
- package/dist/pipeline/nodes/jira-fetch-node.js +3 -0
- package/dist/pipeline/nodes/llm-prompt-node.js +62 -0
- package/dist/pipeline/nodes/plan-codex-node.js +1 -1
- package/dist/pipeline/nodes/read-file-node.js +11 -0
- package/dist/pipeline/nodes/review-findings-form-node.js +48 -14
- package/dist/pipeline/nodes/select-files-form-node.js +72 -0
- package/dist/pipeline/nodes/telegram-notifier-node.js +28 -0
- package/dist/pipeline/nodes/user-input-node.js +43 -8
- package/dist/pipeline/nodes/write-selection-file-node.js +46 -0
- package/dist/pipeline/prompt-registry.js +3 -4
- package/dist/pipeline/prompt-runtime.js +13 -3
- package/dist/pipeline/registry.js +6 -8
- package/dist/pipeline/spec-compiler.js +5 -0
- package/dist/pipeline/spec-types.js +9 -3
- package/dist/pipeline/spec-validator.js +4 -0
- package/dist/pipeline/types.js +1 -0
- package/dist/pipeline/value-resolver.js +50 -38
- package/dist/prompts.js +119 -110
- package/dist/runtime/agentweaver-home.js +8 -0
- package/dist/runtime/command-resolution.js +0 -38
- package/dist/runtime/env-loader.js +43 -0
- package/dist/runtime/process-runner.js +9 -3
- package/dist/structured-artifact-schema-registry.js +54 -0
- package/dist/structured-artifact-schemas.json +22 -20
- package/dist/structured-artifacts.js +3 -43
- package/dist/user-input.js +38 -3
- package/package.json +2 -6
- package/Dockerfile.codex +0 -56
- package/dist/executors/claude-executor.js +0 -46
- package/dist/executors/codex-docker-executor.js +0 -27
- package/dist/executors/configs/claude-config.js +0 -12
- package/dist/executors/configs/codex-docker-config.js +0 -10
- package/dist/executors/configs/verify-build-config.js +0 -7
- package/dist/executors/verify-build-executor.js +0 -123
- package/dist/pipeline/flow-specs/auto.json +0 -979
- package/dist/pipeline/flow-specs/opencode/auto-opencode.json +0 -1365
- package/dist/pipeline/flow-specs/opencode/bugz/bug-analyze-opencode.json +0 -382
- package/dist/pipeline/flow-specs/opencode/bugz/bug-fix-opencode.json +0 -56
- package/dist/pipeline/flow-specs/opencode/gitlab/gitlab-diff-review-opencode.json +0 -308
- package/dist/pipeline/flow-specs/opencode/gitlab/gitlab-review-opencode.json +0 -437
- package/dist/pipeline/flow-specs/opencode/gitlab/mr-description-opencode.json +0 -117
- package/dist/pipeline/flow-specs/opencode/go/run-go-linter-loop-opencode.json +0 -321
- package/dist/pipeline/flow-specs/opencode/go/run-go-tests-loop-opencode.json +0 -321
- package/dist/pipeline/flow-specs/opencode/implement-opencode.json +0 -64
- package/dist/pipeline/flow-specs/opencode/plan-opencode.json +0 -603
- package/dist/pipeline/flow-specs/opencode/review/review-fix-opencode.json +0 -209
- package/dist/pipeline/flow-specs/opencode/review/review-opencode.json +0 -452
- package/dist/pipeline/flow-specs/opencode/task-describe-opencode.json +0 -148
- package/dist/pipeline/flow-specs/review-project.json +0 -243
- package/dist/pipeline/flow-specs/review.json +0 -312
- package/dist/pipeline/flows/preflight-flow.js +0 -19
- package/dist/pipeline/nodes/claude-prompt-node.js +0 -54
- package/dist/pipeline/nodes/codex-docker-prompt-node.js +0 -32
- package/dist/pipeline/nodes/codex-local-prompt-node.js +0 -32
- package/dist/pipeline/nodes/review-claude-node.js +0 -38
- package/dist/pipeline/nodes/review-reply-codex-node.js +0 -40
- package/dist/pipeline/nodes/verify-build-node.js +0 -15
- package/dist/runtime/docker-runtime.js +0 -51
- package/docker-compose.yml +0 -445
- package/verify_build.sh +0 -105
package/dist/artifacts.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { existsSync, mkdirSync } from "node:fs";
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { TaskRunnerError } from "./errors.js";
|
|
5
5
|
export const REVIEW_FILE_RE = /^review-(.+)-(\d+)\.md$/;
|
|
6
|
-
export const REVIEW_REPLY_FILE_RE = /^review-reply-(.+)-(\d+)\.md$/;
|
|
7
6
|
export const READY_TO_MERGE_FILE = "ready-to-merge.md";
|
|
8
7
|
export function scopesRootDir() {
|
|
9
8
|
return path.join(process.cwd(), ".agentweaver", "scopes");
|
|
@@ -47,17 +46,51 @@ export function artifactFile(prefix, taskKey, iteration) {
|
|
|
47
46
|
export function artifactJsonFile(prefix, taskKey, iteration) {
|
|
48
47
|
return taskArtifactsFile(taskKey, `${prefix}-${taskKey}-${iteration}.json`);
|
|
49
48
|
}
|
|
50
|
-
|
|
51
|
-
return
|
|
49
|
+
function escapeRegExp(value) {
|
|
50
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
52
51
|
}
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
function latestVersionedArtifactIteration(taskKey, prefix, extension, directory) {
|
|
53
|
+
if (!existsSync(directory)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const re = new RegExp(`^${escapeRegExp(prefix)}-${escapeRegExp(taskKey)}-(\\d+)\\.${extension}$`);
|
|
57
|
+
let maxIteration = null;
|
|
58
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
59
|
+
if (!entry.isFile()) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const match = re.exec(entry.name);
|
|
63
|
+
if (!match) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const currentIteration = Number.parseInt(match[1] ?? "0", 10);
|
|
67
|
+
maxIteration = maxIteration === null ? currentIteration : Math.max(maxIteration, currentIteration);
|
|
68
|
+
}
|
|
69
|
+
return maxIteration;
|
|
70
|
+
}
|
|
71
|
+
export function latestArtifactIteration(taskKey, prefix, extension = "md") {
|
|
72
|
+
return latestVersionedArtifactIteration(taskKey, prefix, extension, extension === "md" ? taskWorkspaceDir(taskKey) : taskArtifactsDir(taskKey));
|
|
73
|
+
}
|
|
74
|
+
export function nextArtifactIteration(taskKey, prefix, extension = "md") {
|
|
75
|
+
return (latestArtifactIteration(taskKey, prefix, extension) ?? 0) + 1;
|
|
76
|
+
}
|
|
77
|
+
function versionedMarkdownArtifactFile(taskKey, prefix, iteration) {
|
|
78
|
+
return artifactFile(prefix, taskKey, iteration ?? (latestArtifactIteration(taskKey, prefix, "md") ?? 1));
|
|
79
|
+
}
|
|
80
|
+
function versionedJsonArtifactFile(taskKey, prefix, iteration) {
|
|
81
|
+
return artifactJsonFile(prefix, taskKey, iteration ?? (latestArtifactIteration(taskKey, prefix, "json") ?? 1));
|
|
55
82
|
}
|
|
56
|
-
export function
|
|
57
|
-
return
|
|
83
|
+
export function designFile(taskKey, iteration) {
|
|
84
|
+
return versionedMarkdownArtifactFile(taskKey, "design", iteration);
|
|
58
85
|
}
|
|
59
|
-
export function
|
|
60
|
-
return
|
|
86
|
+
export function designJsonFile(taskKey, iteration) {
|
|
87
|
+
return versionedJsonArtifactFile(taskKey, "design", iteration);
|
|
88
|
+
}
|
|
89
|
+
export function planFile(taskKey, iteration) {
|
|
90
|
+
return versionedMarkdownArtifactFile(taskKey, "plan", iteration);
|
|
91
|
+
}
|
|
92
|
+
export function planJsonFile(taskKey, iteration) {
|
|
93
|
+
return versionedJsonArtifactFile(taskKey, "plan", iteration);
|
|
61
94
|
}
|
|
62
95
|
export function planningQuestionsJsonFile(taskKey) {
|
|
63
96
|
return taskArtifactsFile(taskKey, `planning-questions-${taskKey}.json`);
|
|
@@ -65,35 +98,35 @@ export function planningQuestionsJsonFile(taskKey) {
|
|
|
65
98
|
export function planningAnswersJsonFile(taskKey) {
|
|
66
99
|
return taskArtifactsFile(taskKey, `planning-answers-${taskKey}.json`);
|
|
67
100
|
}
|
|
68
|
-
export function bugAnalyzeFile(taskKey) {
|
|
69
|
-
return
|
|
101
|
+
export function bugAnalyzeFile(taskKey, iteration) {
|
|
102
|
+
return versionedMarkdownArtifactFile(taskKey, "bug-analyze", iteration);
|
|
70
103
|
}
|
|
71
|
-
export function bugAnalyzeJsonFile(taskKey) {
|
|
72
|
-
return
|
|
104
|
+
export function bugAnalyzeJsonFile(taskKey, iteration) {
|
|
105
|
+
return versionedJsonArtifactFile(taskKey, "bug-analyze", iteration);
|
|
73
106
|
}
|
|
74
|
-
export function bugFixDesignFile(taskKey) {
|
|
75
|
-
return
|
|
107
|
+
export function bugFixDesignFile(taskKey, iteration) {
|
|
108
|
+
return versionedMarkdownArtifactFile(taskKey, "bug-fix-design", iteration);
|
|
76
109
|
}
|
|
77
|
-
export function bugFixDesignJsonFile(taskKey) {
|
|
78
|
-
return
|
|
110
|
+
export function bugFixDesignJsonFile(taskKey, iteration) {
|
|
111
|
+
return versionedJsonArtifactFile(taskKey, "bug-fix-design", iteration);
|
|
79
112
|
}
|
|
80
|
-
export function bugFixPlanFile(taskKey) {
|
|
81
|
-
return
|
|
113
|
+
export function bugFixPlanFile(taskKey, iteration) {
|
|
114
|
+
return versionedMarkdownArtifactFile(taskKey, "bug-fix-plan", iteration);
|
|
82
115
|
}
|
|
83
|
-
export function bugFixPlanJsonFile(taskKey) {
|
|
84
|
-
return
|
|
116
|
+
export function bugFixPlanJsonFile(taskKey, iteration) {
|
|
117
|
+
return versionedJsonArtifactFile(taskKey, "bug-fix-plan", iteration);
|
|
85
118
|
}
|
|
86
|
-
export function qaFile(taskKey) {
|
|
87
|
-
return
|
|
119
|
+
export function qaFile(taskKey, iteration) {
|
|
120
|
+
return versionedMarkdownArtifactFile(taskKey, "qa", iteration);
|
|
88
121
|
}
|
|
89
|
-
export function qaJsonFile(taskKey) {
|
|
90
|
-
return
|
|
122
|
+
export function qaJsonFile(taskKey, iteration) {
|
|
123
|
+
return versionedJsonArtifactFile(taskKey, "qa", iteration);
|
|
91
124
|
}
|
|
92
|
-
export function taskSummaryFile(taskKey) {
|
|
93
|
-
return
|
|
125
|
+
export function taskSummaryFile(taskKey, iteration) {
|
|
126
|
+
return versionedMarkdownArtifactFile(taskKey, "task", iteration);
|
|
94
127
|
}
|
|
95
|
-
export function taskSummaryJsonFile(taskKey) {
|
|
96
|
-
return
|
|
128
|
+
export function taskSummaryJsonFile(taskKey, iteration) {
|
|
129
|
+
return versionedJsonArtifactFile(taskKey, "task", iteration);
|
|
97
130
|
}
|
|
98
131
|
export function readyToMergeFile(taskKey) {
|
|
99
132
|
return taskWorkspaceFile(taskKey, READY_TO_MERGE_FILE);
|
|
@@ -101,6 +134,9 @@ export function readyToMergeFile(taskKey) {
|
|
|
101
134
|
export function jiraTaskFile(taskKey) {
|
|
102
135
|
return taskArtifactsFile(taskKey, `${taskKey}.json`);
|
|
103
136
|
}
|
|
137
|
+
export function jiraTaskEnrichedFile(taskKey) {
|
|
138
|
+
return taskArtifactsFile(taskKey, `${taskKey}-enriched.json`);
|
|
139
|
+
}
|
|
104
140
|
export function jiraAttachmentsDir(taskKey) {
|
|
105
141
|
return path.join(taskArtifactsDir(taskKey), "jira-attachments");
|
|
106
142
|
}
|
|
@@ -110,39 +146,57 @@ export function jiraAttachmentsManifestFile(taskKey) {
|
|
|
110
146
|
export function jiraAttachmentsContextFile(taskKey) {
|
|
111
147
|
return taskWorkspaceFile(taskKey, `jira-attachments-context-${taskKey}.txt`);
|
|
112
148
|
}
|
|
113
|
-
export function jiraDescriptionFile(taskKey) {
|
|
114
|
-
return
|
|
149
|
+
export function jiraDescriptionFile(taskKey, iteration) {
|
|
150
|
+
return versionedMarkdownArtifactFile(taskKey, "jira-description", iteration);
|
|
151
|
+
}
|
|
152
|
+
export function jiraDescriptionJsonFile(taskKey, iteration) {
|
|
153
|
+
return versionedJsonArtifactFile(taskKey, "jira-description", iteration);
|
|
154
|
+
}
|
|
155
|
+
export function taskDescribeInputJsonFile(taskKey) {
|
|
156
|
+
return taskArtifactsFile(taskKey, `task-describe-input-${taskKey}.json`);
|
|
115
157
|
}
|
|
116
|
-
export function
|
|
117
|
-
return taskArtifactsFile(taskKey, `
|
|
158
|
+
export function gitStatusJsonFile(taskKey) {
|
|
159
|
+
return taskArtifactsFile(taskKey, `git-status-${taskKey}.json`);
|
|
118
160
|
}
|
|
119
|
-
export function
|
|
120
|
-
return taskWorkspaceFile(taskKey, `
|
|
161
|
+
export function gitDiffFile(taskKey) {
|
|
162
|
+
return taskWorkspaceFile(taskKey, `git-diff-${taskKey}.txt`);
|
|
121
163
|
}
|
|
122
|
-
export function
|
|
123
|
-
return taskArtifactsFile(taskKey, `
|
|
164
|
+
export function gitCommitMessageJsonFile(taskKey) {
|
|
165
|
+
return taskArtifactsFile(taskKey, `git-commit-message-${taskKey}.json`);
|
|
124
166
|
}
|
|
125
|
-
export function
|
|
126
|
-
return
|
|
167
|
+
export function gitCommitInputJsonFile(taskKey) {
|
|
168
|
+
return taskArtifactsFile(taskKey, `git-commit-input-${taskKey}.json`);
|
|
127
169
|
}
|
|
128
|
-
export function
|
|
129
|
-
return taskArtifactsFile(taskKey, `
|
|
170
|
+
export function selectFilesOutputJsonFile(taskKey) {
|
|
171
|
+
return taskArtifactsFile(taskKey, `select-files-output-${taskKey}.json`);
|
|
172
|
+
}
|
|
173
|
+
export function commitMessageOutputJsonFile(taskKey) {
|
|
174
|
+
return taskArtifactsFile(taskKey, `commit-message-output-${taskKey}.json`);
|
|
175
|
+
}
|
|
176
|
+
export function mrDescriptionFile(taskKey, iteration) {
|
|
177
|
+
return versionedMarkdownArtifactFile(taskKey, "mr-description", iteration);
|
|
178
|
+
}
|
|
179
|
+
export function mrDescriptionJsonFile(taskKey, iteration) {
|
|
180
|
+
return versionedJsonArtifactFile(taskKey, "mr-description", iteration);
|
|
181
|
+
}
|
|
182
|
+
export function gitlabReviewFile(taskKey, iteration) {
|
|
183
|
+
return versionedMarkdownArtifactFile(taskKey, "gitlab-review", iteration);
|
|
184
|
+
}
|
|
185
|
+
export function gitlabReviewJsonFile(taskKey, iteration) {
|
|
186
|
+
return versionedJsonArtifactFile(taskKey, "gitlab-review", iteration);
|
|
130
187
|
}
|
|
131
188
|
export function gitlabReviewInputJsonFile(taskKey) {
|
|
132
189
|
return taskArtifactsFile(taskKey, `gitlab-review-input-${taskKey}.json`);
|
|
133
190
|
}
|
|
134
|
-
export function gitlabDiffFile(taskKey) {
|
|
135
|
-
return
|
|
191
|
+
export function gitlabDiffFile(taskKey, iteration) {
|
|
192
|
+
return versionedMarkdownArtifactFile(taskKey, "gitlab-diff", iteration);
|
|
136
193
|
}
|
|
137
|
-
export function gitlabDiffJsonFile(taskKey) {
|
|
138
|
-
return
|
|
194
|
+
export function gitlabDiffJsonFile(taskKey, iteration) {
|
|
195
|
+
return versionedJsonArtifactFile(taskKey, "gitlab-diff", iteration);
|
|
139
196
|
}
|
|
140
197
|
export function gitlabDiffReviewInputJsonFile(taskKey) {
|
|
141
198
|
return taskArtifactsFile(taskKey, `gitlab-diff-review-input-${taskKey}.json`);
|
|
142
199
|
}
|
|
143
|
-
export function autoStateFile(taskKey) {
|
|
144
|
-
return taskArtifactsFile(taskKey, `.agentweaver-state-${taskKey}.json`);
|
|
145
|
-
}
|
|
146
200
|
export function flowStateFile(scopeKey, flowId) {
|
|
147
201
|
return scopeArtifactsFile(scopeKey, `.agentweaver-flow-state-${encodeURIComponent(flowId)}.json`);
|
|
148
202
|
}
|
|
@@ -165,18 +219,18 @@ export function reviewFile(taskKey, iteration) {
|
|
|
165
219
|
export function reviewJsonFile(taskKey, iteration) {
|
|
166
220
|
return artifactJsonFile("review", taskKey, iteration);
|
|
167
221
|
}
|
|
168
|
-
export function reviewReplyFile(taskKey, iteration) {
|
|
169
|
-
return artifactFile("review-reply", taskKey, iteration);
|
|
170
|
-
}
|
|
171
|
-
export function reviewReplyJsonFile(taskKey, iteration) {
|
|
172
|
-
return artifactJsonFile("review-reply", taskKey, iteration);
|
|
173
|
-
}
|
|
174
222
|
export function reviewFixFile(taskKey, iteration) {
|
|
175
223
|
return artifactFile("review-fix", taskKey, iteration);
|
|
176
224
|
}
|
|
177
225
|
export function reviewFixJsonFile(taskKey, iteration) {
|
|
178
226
|
return artifactJsonFile("review-fix", taskKey, iteration);
|
|
179
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
|
+
}
|
|
180
234
|
export function reviewFixSelectionJsonFile(taskKey, iteration) {
|
|
181
235
|
return artifactJsonFile("review-fix-selection", taskKey, iteration);
|
|
182
236
|
}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { codexExecutorDefaultConfig } from "./configs/codex-config.js";
|
|
2
2
|
import { processExecutor } from "./process-executor.js";
|
|
3
3
|
function resolveModel(config, env) {
|
|
4
4
|
return env[config.modelEnvVar]?.trim() || config.defaultModel;
|
|
5
5
|
}
|
|
6
|
-
export const
|
|
7
|
-
kind: "codex
|
|
6
|
+
export const codexExecutor = {
|
|
7
|
+
kind: "codex",
|
|
8
8
|
version: 1,
|
|
9
|
-
defaultConfig:
|
|
9
|
+
defaultConfig: codexExecutorDefaultConfig,
|
|
10
10
|
async execute(context, input, config) {
|
|
11
11
|
const env = input.env ?? context.env;
|
|
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,
|
|
@@ -15,7 +15,7 @@ export const fetchGitLabDiffExecutor = {
|
|
|
15
15
|
context.ui.writeStdout(`Saving GitLab diff markdown to: ${input.outputFile}\n`);
|
|
16
16
|
context.ui.writeStdout(`Saving GitLab diff JSON to: ${input.outputJsonFile}\n`);
|
|
17
17
|
}
|
|
18
|
-
const artifact = await fetchGitLabMergeRequestDiff(input.mergeRequestUrl, input.outputFile, input.outputJsonFile);
|
|
18
|
+
const artifact = await fetchGitLabMergeRequestDiff(input.mergeRequestUrl, input.outputFile, input.outputJsonFile, context.mdLang);
|
|
19
19
|
return {
|
|
20
20
|
outputFile: input.outputFile,
|
|
21
21
|
outputJsonFile: input.outputJsonFile,
|
|
@@ -14,7 +14,7 @@ export const fetchGitLabReviewExecutor = {
|
|
|
14
14
|
context.ui.writeStdout(`Saving GitLab review markdown to: ${input.outputFile}\n`);
|
|
15
15
|
context.ui.writeStdout(`Saving GitLab review JSON to: ${input.outputJsonFile}\n`);
|
|
16
16
|
}
|
|
17
|
-
const artifact = await fetchGitLabReview(input.mergeRequestUrl, input.outputFile, input.outputJsonFile);
|
|
17
|
+
const artifact = await fetchGitLabReview(input.mergeRequestUrl, input.outputFile, input.outputJsonFile, context.mdLang);
|
|
18
18
|
return {
|
|
19
19
|
outputFile: input.outputFile,
|
|
20
20
|
outputJsonFile: input.outputJsonFile,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const gitCommitExecutor = {
|
|
2
|
+
kind: "git-commit",
|
|
3
|
+
version: 1,
|
|
4
|
+
defaultConfig: {},
|
|
5
|
+
async execute(context, input) {
|
|
6
|
+
if (input.files.length > 0) {
|
|
7
|
+
await context.runtime.runCommand(["git", "add", ...input.files], {
|
|
8
|
+
dryRun: context.dryRun,
|
|
9
|
+
verbose: context.verbose,
|
|
10
|
+
label: "git add",
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
const commitArgs = input.editEnabled
|
|
14
|
+
? ["git", "commit", "-e", "-m", input.message]
|
|
15
|
+
: ["git", "commit", "-m", input.message];
|
|
16
|
+
const output = await context.runtime.runCommand(commitArgs, {
|
|
17
|
+
dryRun: context.dryRun,
|
|
18
|
+
verbose: context.verbose,
|
|
19
|
+
label: "git commit",
|
|
20
|
+
});
|
|
21
|
+
const match = output.match(/\[\S+ ([0-9a-f]{7,40})\]/);
|
|
22
|
+
const commitHash = match?.[1] ?? null;
|
|
23
|
+
return { output, commitHash };
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -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
|
},
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { telegramNotifierExecutorDefaultConfig } from "./configs/telegram-notifier-config.js";
|
|
2
|
+
export const telegramNotifierExecutor = {
|
|
3
|
+
kind: "telegram-notifier",
|
|
4
|
+
version: 1,
|
|
5
|
+
defaultConfig: telegramNotifierExecutorDefaultConfig,
|
|
6
|
+
async execute(context, input, config) {
|
|
7
|
+
const botToken = context.env.TELEGRAM_BOT_TOKEN;
|
|
8
|
+
if (!botToken) {
|
|
9
|
+
context.ui.writeStderr(`Telegram notifier error: BOT_TOKEN environment variable is not set\n`);
|
|
10
|
+
return { success: false };
|
|
11
|
+
}
|
|
12
|
+
const chatId = context.env.TELEGRAM_CHAT_ID ?? input.chatId;
|
|
13
|
+
if (!chatId) {
|
|
14
|
+
context.ui.writeStderr(`Telegram notifier error: chatId is required (set TELEGRAM_CHAT_ID env or pass in input)\n`);
|
|
15
|
+
return { success: false };
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
headers: {
|
|
21
|
+
"Content-Type": "application/json",
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify({
|
|
24
|
+
chat_id: chatId,
|
|
25
|
+
text: input.text,
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
const errorText = await response.text();
|
|
30
|
+
if (config.printFailureOutput) {
|
|
31
|
+
context.ui.writeStderr(`Telegram API error: ${response.status} ${response.statusText}\n${errorText}\n`);
|
|
32
|
+
}
|
|
33
|
+
return { success: false };
|
|
34
|
+
}
|
|
35
|
+
const data = (await response.json());
|
|
36
|
+
if (!data.ok) {
|
|
37
|
+
context.ui.writeStderr(`Telegram API error: ${JSON.stringify(data)}\n`);
|
|
38
|
+
return { success: false };
|
|
39
|
+
}
|
|
40
|
+
const messageId = data.result?.message_id;
|
|
41
|
+
if (messageId !== undefined) {
|
|
42
|
+
return { success: true, messageId };
|
|
43
|
+
}
|
|
44
|
+
return { success: true };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
48
|
+
if (config.printFailureOutput) {
|
|
49
|
+
context.ui.writeStderr(`Telegram notifier error: ${errorMessage}\n`);
|
|
50
|
+
}
|
|
51
|
+
return { success: false };
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
};
|
package/dist/flow-state.js
CHANGED
|
@@ -29,14 +29,16 @@ export function stripExecutionStatePayload(executionState) {
|
|
|
29
29
|
})),
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
export function createFlowRunState(scopeKey, flowId, executionState) {
|
|
32
|
+
export function createFlowRunState(scopeKey, flowId, executionState, jiraRef, launchProfile) {
|
|
33
33
|
return {
|
|
34
34
|
schemaVersion: FLOW_STATE_SCHEMA_VERSION,
|
|
35
35
|
flowId,
|
|
36
36
|
scopeKey,
|
|
37
|
+
...(jiraRef ? { jiraRef } : {}),
|
|
37
38
|
status: "pending",
|
|
38
39
|
currentStep: null,
|
|
39
40
|
updatedAt: nowIso8601(),
|
|
41
|
+
...(launchProfile ? { launchProfile } : {}),
|
|
40
42
|
executionState: stripExecutionStatePayload(executionState),
|
|
41
43
|
};
|
|
42
44
|
}
|
|
@@ -120,6 +122,49 @@ function normalizePhaseState(phase) {
|
|
|
120
122
|
steps: normalizedSteps,
|
|
121
123
|
};
|
|
122
124
|
}
|
|
125
|
+
function createPendingPhaseState(phase) {
|
|
126
|
+
return {
|
|
127
|
+
id: phase.id,
|
|
128
|
+
status: "pending",
|
|
129
|
+
repeatVars: { ...phase.repeatVars },
|
|
130
|
+
steps: phase.steps.map((step) => ({
|
|
131
|
+
id: step.id,
|
|
132
|
+
status: "pending",
|
|
133
|
+
})),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
export function rewindFlowRunStateToPhase(state, orderedPhases, targetPhaseId) {
|
|
137
|
+
const targetIndex = orderedPhases.findIndex((phase) => phase.id === targetPhaseId);
|
|
138
|
+
if (targetIndex < 0) {
|
|
139
|
+
throw new TaskRunnerError(`Unknown flow phase '${targetPhaseId}'.`);
|
|
140
|
+
}
|
|
141
|
+
const existingPhaseStates = new Map(state.executionState.phases.map((phase) => [phase.id, phase]));
|
|
142
|
+
const rewoundPhases = [];
|
|
143
|
+
for (const [index, phase] of orderedPhases.entries()) {
|
|
144
|
+
if (index < targetIndex) {
|
|
145
|
+
const existingPhaseState = existingPhaseStates.get(phase.id);
|
|
146
|
+
if (!existingPhaseState) {
|
|
147
|
+
throw new TaskRunnerError(`Cannot restart from phase '${targetPhaseId}' because earlier phase '${phase.id}' has no persisted execution state.`);
|
|
148
|
+
}
|
|
149
|
+
if (existingPhaseState.status !== "done" && existingPhaseState.status !== "skipped") {
|
|
150
|
+
throw new TaskRunnerError(`Cannot restart from phase '${targetPhaseId}' because earlier phase '${phase.id}' is not completed in persisted state.`);
|
|
151
|
+
}
|
|
152
|
+
rewoundPhases.push(existingPhaseState);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
rewoundPhases.push(createPendingPhaseState(phase));
|
|
156
|
+
}
|
|
157
|
+
state.status = "pending";
|
|
158
|
+
state.currentStep = null;
|
|
159
|
+
state.lastError = null;
|
|
160
|
+
state.executionState = {
|
|
161
|
+
...state.executionState,
|
|
162
|
+
terminated: false,
|
|
163
|
+
phases: rewoundPhases,
|
|
164
|
+
};
|
|
165
|
+
delete state.executionState.terminationReason;
|
|
166
|
+
return state;
|
|
167
|
+
}
|
|
123
168
|
export function prepareFlowStateForResume(state) {
|
|
124
169
|
state.status = "pending";
|
|
125
170
|
state.lastError = null;
|
package/dist/gitlab.js
CHANGED
|
@@ -3,6 +3,9 @@ import { writeFile } from "node:fs/promises";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { TaskRunnerError } from "./errors.js";
|
|
5
5
|
const MERGE_REQUEST_PATH_RE = /^(?<projectPath>.+?)\/-\/merge_requests\/(?<iid>\d+)(?:\/.*)?$/;
|
|
6
|
+
function normalizeMarkdownLanguage(mdLang) {
|
|
7
|
+
return mdLang === "en" ? "en" : "ru";
|
|
8
|
+
}
|
|
6
9
|
function normalizeUrl(value) {
|
|
7
10
|
return value.trim().replace(/\/+$/, "");
|
|
8
11
|
}
|
|
@@ -118,7 +121,8 @@ function normalizeDiscussionNotes(discussions) {
|
|
|
118
121
|
}));
|
|
119
122
|
});
|
|
120
123
|
}
|
|
121
|
-
function buildGitLabReviewMarkdown(artifact) {
|
|
124
|
+
function buildGitLabReviewMarkdown(artifact, mdLang) {
|
|
125
|
+
const lang = normalizeMarkdownLanguage(mdLang);
|
|
122
126
|
const lines = [
|
|
123
127
|
"# GitLab Review",
|
|
124
128
|
"",
|
|
@@ -130,7 +134,7 @@ function buildGitLabReviewMarkdown(artifact) {
|
|
|
130
134
|
"",
|
|
131
135
|
];
|
|
132
136
|
if (artifact.comments.length === 0) {
|
|
133
|
-
lines.push("Код-ревью комментариев не найдено.");
|
|
137
|
+
lines.push(lang === "en" ? "No code review comments found." : "Код-ревью комментариев не найдено.");
|
|
134
138
|
return lines.join("\n");
|
|
135
139
|
}
|
|
136
140
|
artifact.comments.forEach((comment, index) => {
|
|
@@ -243,7 +247,8 @@ async function fetchMergeRequestDiffs(target, token) {
|
|
|
243
247
|
page = chunk.nextPage;
|
|
244
248
|
}
|
|
245
249
|
}
|
|
246
|
-
function buildGitLabMergeRequestDiffMarkdown(artifact) {
|
|
250
|
+
function buildGitLabMergeRequestDiffMarkdown(artifact, mdLang) {
|
|
251
|
+
const lang = normalizeMarkdownLanguage(mdLang);
|
|
247
252
|
const lines = [
|
|
248
253
|
"# GitLab MR Diff",
|
|
249
254
|
"",
|
|
@@ -265,7 +270,7 @@ function buildGitLabMergeRequestDiffMarkdown(artifact) {
|
|
|
265
270
|
lines.push("## Description", "", description, "");
|
|
266
271
|
}
|
|
267
272
|
if (artifact.files.length === 0) {
|
|
268
|
-
lines.push("Изменений в diff не найдено.");
|
|
273
|
+
lines.push(lang === "en" ? "No changes found in the diff." : "Изменений в diff не найдено.");
|
|
269
274
|
return lines.join("\n");
|
|
270
275
|
}
|
|
271
276
|
artifact.files.forEach((file, index) => {
|
|
@@ -287,7 +292,7 @@ function buildGitLabMergeRequestDiffMarkdown(artifact) {
|
|
|
287
292
|
});
|
|
288
293
|
return lines.join("\n");
|
|
289
294
|
}
|
|
290
|
-
export async function fetchGitLabReview(mergeRequestUrl, outputFile, outputJsonFile) {
|
|
295
|
+
export async function fetchGitLabReview(mergeRequestUrl, outputFile, outputJsonFile, mdLang) {
|
|
291
296
|
const token = process.env.GITLAB_TOKEN?.trim();
|
|
292
297
|
if (!token) {
|
|
293
298
|
throw new TaskRunnerError("GITLAB_TOKEN is required for gitlab-review flow.");
|
|
@@ -307,10 +312,10 @@ export async function fetchGitLabReview(mergeRequestUrl, outputFile, outputJsonF
|
|
|
307
312
|
mkdirSync(path.dirname(outputFile), { recursive: true });
|
|
308
313
|
mkdirSync(path.dirname(outputJsonFile), { recursive: true });
|
|
309
314
|
await writeFile(outputJsonFile, `${JSON.stringify(artifact, null, 2)}\n`, "utf8");
|
|
310
|
-
await writeFile(outputFile, `${buildGitLabReviewMarkdown(artifact)}\n`, "utf8");
|
|
315
|
+
await writeFile(outputFile, `${buildGitLabReviewMarkdown(artifact, mdLang)}\n`, "utf8");
|
|
311
316
|
return artifact;
|
|
312
317
|
}
|
|
313
|
-
export async function fetchGitLabMergeRequestDiff(mergeRequestUrl, outputFile, outputJsonFile) {
|
|
318
|
+
export async function fetchGitLabMergeRequestDiff(mergeRequestUrl, outputFile, outputJsonFile, mdLang) {
|
|
314
319
|
const token = process.env.GITLAB_TOKEN?.trim();
|
|
315
320
|
if (!token) {
|
|
316
321
|
throw new TaskRunnerError("GITLAB_TOKEN is required for gitlab-diff-review flow.");
|
|
@@ -342,6 +347,6 @@ export async function fetchGitLabMergeRequestDiff(mergeRequestUrl, outputFile, o
|
|
|
342
347
|
mkdirSync(path.dirname(outputFile), { recursive: true });
|
|
343
348
|
mkdirSync(path.dirname(outputJsonFile), { recursive: true });
|
|
344
349
|
await writeFile(outputJsonFile, `${JSON.stringify(artifact, null, 2)}\n`, "utf8");
|
|
345
|
-
await writeFile(outputFile, `${buildGitLabMergeRequestDiffMarkdown(artifact)}\n`, "utf8");
|
|
350
|
+
await writeFile(outputFile, `${buildGitLabMergeRequestDiffMarkdown(artifact, mdLang)}\n`, "utf8");
|
|
346
351
|
return artifact;
|
|
347
352
|
}
|