task-o-matic 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/display/task.d.ts +28 -2
- package/dist/cli/display/task.d.ts.map +1 -1
- package/dist/cli/display/task.js +27 -21
- package/dist/commands/benchmark.js +203 -173
- package/dist/commands/tasks/show.d.ts.map +1 -1
- package/dist/commands/tasks/show.js +21 -1
- package/dist/commands/tasks/tree.d.ts.map +1 -1
- package/dist/commands/tasks/tree.js +21 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +59 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/lib/ai-service/model-provider.d.ts +4 -0
- package/dist/lib/ai-service/model-provider.d.ts.map +1 -1
- package/dist/lib/ai-service/model-provider.js +21 -5
- package/dist/lib/ai-service/prd-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/prd-operations.js +1 -4
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +59 -23
- package/dist/lib/git-utils.d.ts +35 -0
- package/dist/lib/git-utils.d.ts.map +1 -1
- package/dist/lib/git-utils.js +81 -15
- package/dist/lib/hooks/logger.d.ts.map +1 -1
- package/dist/lib/hooks/logger.js +16 -0
- package/dist/lib/hooks.d.ts +10 -1
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/logger.d.ts +20 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +32 -0
- package/dist/lib/provider-defaults.json +22 -0
- package/dist/lib/task-execution-core.d.ts.map +1 -1
- package/dist/lib/task-execution-core.js +29 -33
- package/dist/lib/task-loop-execution.d.ts.map +1 -1
- package/dist/lib/task-loop-execution.js +5 -1
- package/dist/lib/task-planning.d.ts.map +1 -1
- package/dist/lib/task-planning.js +9 -9
- package/dist/lib/task-review.d.ts.map +1 -1
- package/dist/lib/task-review.js +10 -13
- package/dist/lib/validation.d.ts.map +1 -1
- package/dist/lib/validation.js +12 -15
- package/dist/services/benchmark.d.ts +14 -0
- package/dist/services/benchmark.d.ts.map +1 -1
- package/dist/services/benchmark.js +325 -0
- package/dist/services/workflow.d.ts +12 -0
- package/dist/services/workflow.d.ts.map +1 -1
- package/dist/services/workflow.js +20 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/workflow-options.d.ts +25 -0
- package/dist/types/workflow-options.d.ts.map +1 -1
- package/dist/utils/streaming-utils.d.ts.map +1 -1
- package/dist/utils/streaming-utils.js +4 -0
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"openrouter": {
|
|
3
|
+
"model": "z-ai/glm-4.6",
|
|
4
|
+
"maxTokens": 32768,
|
|
5
|
+
"temperature": 0.5
|
|
6
|
+
},
|
|
7
|
+
"anthropic": {
|
|
8
|
+
"model": "claude-sonnet-4.5",
|
|
9
|
+
"maxTokens": 32768,
|
|
10
|
+
"temperature": 0.5
|
|
11
|
+
},
|
|
12
|
+
"openai": {
|
|
13
|
+
"model": "gpt-5",
|
|
14
|
+
"maxTokens": 32768,
|
|
15
|
+
"temperature": 0.5
|
|
16
|
+
},
|
|
17
|
+
"custom": {
|
|
18
|
+
"model": "llama-3.3-70b",
|
|
19
|
+
"maxTokens": 32768,
|
|
20
|
+
"temperature": 0.5
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-execution-core.d.ts","sourceRoot":"","sources":["../../src/lib/task-execution-core.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EAKpB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"task-execution-core.d.ts","sourceRoot":"","sources":["../../src/lib/task-execution-core.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EAKpB,MAAM,UAAU,CAAC;AAgBlB;;;GAGG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAsE9B"}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.executeTaskCore = executeTaskCore;
|
|
7
4
|
const task_o_matic_error_1 = require("../utils/task-o-matic-error");
|
|
@@ -14,7 +11,7 @@ const prompt_builder_1 = require("./prompt-builder");
|
|
|
14
11
|
const task_planning_1 = require("./task-planning");
|
|
15
12
|
const task_review_1 = require("./task-review");
|
|
16
13
|
const git_utils_1 = require("./git-utils");
|
|
17
|
-
const
|
|
14
|
+
const logger_1 = require("./logger");
|
|
18
15
|
/**
|
|
19
16
|
* Execute a single task with all features (retry, planning, review, etc.)
|
|
20
17
|
* This is the core unified execution logic used by both execute and execute-loop commands
|
|
@@ -66,25 +63,25 @@ async function executeTaskCore(taskId, config) {
|
|
|
66
63
|
*/
|
|
67
64
|
async function executeTaskWithSubtasks(task, subtasks, config) {
|
|
68
65
|
const { dry } = config;
|
|
69
|
-
|
|
66
|
+
logger_1.logger.info(`📋 Task has ${subtasks.length} subtasks, executing recursively...`);
|
|
70
67
|
const subtaskResults = [];
|
|
71
68
|
let allSuccess = true;
|
|
72
69
|
// Execute subtasks one by one
|
|
73
70
|
for (let i = 0; i < subtasks.length; i++) {
|
|
74
71
|
const subtask = subtasks[i];
|
|
75
|
-
|
|
72
|
+
logger_1.logger.progress(`\n[${i + 1}/${subtasks.length}] Executing subtask: ${subtask.title} (${subtask.id})`);
|
|
76
73
|
try {
|
|
77
74
|
const result = await executeTaskCore(subtask.id, config);
|
|
78
75
|
subtaskResults.push(result);
|
|
79
76
|
if (!result.success) {
|
|
80
77
|
allSuccess = false;
|
|
81
|
-
|
|
78
|
+
logger_1.logger.error(`❌ Failed to execute subtask ${subtask.id}: ${subtask.title}`);
|
|
82
79
|
break; // Stop on first failure
|
|
83
80
|
}
|
|
84
81
|
}
|
|
85
82
|
catch (error) {
|
|
86
83
|
allSuccess = false;
|
|
87
|
-
|
|
84
|
+
logger_1.logger.error(`❌ Failed to execute subtask ${subtask.id}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
88
85
|
break;
|
|
89
86
|
}
|
|
90
87
|
}
|
|
@@ -92,11 +89,11 @@ async function executeTaskWithSubtasks(task, subtasks, config) {
|
|
|
92
89
|
if (!dry) {
|
|
93
90
|
if (allSuccess) {
|
|
94
91
|
await tasks_1.taskService.setTaskStatus(task.id, "completed");
|
|
95
|
-
|
|
92
|
+
logger_1.logger.success(`✅ Main task ${task.title} completed after all subtasks`);
|
|
96
93
|
}
|
|
97
94
|
else {
|
|
98
95
|
await tasks_1.taskService.setTaskStatus(task.id, "todo");
|
|
99
|
-
|
|
96
|
+
logger_1.logger.error(`❌ Main task ${task.title} failed due to subtask failure, status reset to todo`);
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
return {
|
|
@@ -126,12 +123,12 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
126
123
|
currentModel = modelConfig.model;
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
|
-
|
|
126
|
+
logger_1.logger.info(`\n🎯 Attempt ${currentAttempt}/${maxRetries} for task: ${task.title} (${task.id})`);
|
|
130
127
|
if (currentModel) {
|
|
131
|
-
|
|
128
|
+
logger_1.logger.progress(` Using executor: ${currentExecutor} with model: ${currentModel}`);
|
|
132
129
|
}
|
|
133
130
|
else {
|
|
134
|
-
|
|
131
|
+
logger_1.logger.progress(` Using executor: ${currentExecutor}`);
|
|
135
132
|
}
|
|
136
133
|
// Build retry context if this is a retry attempt
|
|
137
134
|
let retryContext = "";
|
|
@@ -164,11 +161,9 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
164
161
|
try {
|
|
165
162
|
const result = await executeSingleAttempt(task, attemptConfig, attempts, planContent, currentAttempt, maxRetries, retryContext);
|
|
166
163
|
// Check if all verifications passed
|
|
167
|
-
const allVerificationsPassed = result.attempts[result.attempts.length - 1]
|
|
168
|
-
?.verificationResults?.every((r) => r.success) ?? true;
|
|
164
|
+
const allVerificationsPassed = result.attempts[result.attempts.length - 1]?.verificationResults?.every((r) => r.success) ?? true;
|
|
169
165
|
if (!allVerificationsPassed) {
|
|
170
|
-
const failedVerification = result.attempts[result.attempts.length - 1]
|
|
171
|
-
?.verificationResults?.find((r) => !r.success);
|
|
166
|
+
const failedVerification = result.attempts[result.attempts.length - 1]?.verificationResults?.find((r) => !r.success);
|
|
172
167
|
lastError = `Verification command "${failedVerification?.command}" failed:\n${failedVerification?.error}`;
|
|
173
168
|
currentAttempt++;
|
|
174
169
|
continue;
|
|
@@ -184,12 +179,12 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
184
179
|
});
|
|
185
180
|
if (!reviewResult.approved) {
|
|
186
181
|
lastError = `AI Review Failed:\n${reviewResult.feedback}`;
|
|
187
|
-
|
|
182
|
+
logger_1.logger.error(`❌ AI Review Rejected Changes: ${reviewResult.feedback}`);
|
|
188
183
|
currentAttempt++;
|
|
189
184
|
continue;
|
|
190
185
|
}
|
|
191
186
|
else {
|
|
192
|
-
|
|
187
|
+
logger_1.logger.success(`✅ AI Review Approved: ${reviewResult.feedback}`);
|
|
193
188
|
result.reviewFeedback = reviewResult.feedback;
|
|
194
189
|
}
|
|
195
190
|
}
|
|
@@ -198,10 +193,10 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
198
193
|
}
|
|
199
194
|
catch (error) {
|
|
200
195
|
lastError = error instanceof Error ? error.message : String(error);
|
|
201
|
-
|
|
196
|
+
logger_1.logger.error(`❌ Task execution failed on attempt ${currentAttempt}: ${lastError}`);
|
|
202
197
|
if (!dry && currentAttempt < maxRetries) {
|
|
203
198
|
await tasks_1.taskService.setTaskStatus(task.id, "todo");
|
|
204
|
-
|
|
199
|
+
logger_1.logger.warn("⏸ Task status reset to todo for retry");
|
|
205
200
|
}
|
|
206
201
|
currentAttempt++;
|
|
207
202
|
}
|
|
@@ -209,7 +204,7 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
209
204
|
// All retries exhausted
|
|
210
205
|
if (!dry) {
|
|
211
206
|
await tasks_1.taskService.setTaskStatus(task.id, "todo");
|
|
212
|
-
|
|
207
|
+
logger_1.logger.error("❌ All retry attempts exhausted, task status reset to todo");
|
|
213
208
|
}
|
|
214
209
|
return {
|
|
215
210
|
success: false,
|
|
@@ -222,7 +217,7 @@ async function executeTaskWithRetry(task, config, attempts, planContent) {
|
|
|
222
217
|
async function executeSingleAttempt(task, config, attempts, planContent, attemptNumber, maxRetries, retryContext) {
|
|
223
218
|
const { tool, executorConfig, customMessage, verificationCommands = [], autoCommit: enableAutoCommit = false, dry = false, } = config;
|
|
224
219
|
const attemptStartTime = Date.now();
|
|
225
|
-
|
|
220
|
+
logger_1.logger.info(`🎯 ${dry ? "DRY RUN" : "Executing"} task: ${task.title} (${task.id})`);
|
|
226
221
|
// Capture git state before execution
|
|
227
222
|
const gitStateBefore = await (0, git_utils_1.captureGitState)();
|
|
228
223
|
// Build execution message
|
|
@@ -230,7 +225,7 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
230
225
|
if (customMessage) {
|
|
231
226
|
// Use custom message override
|
|
232
227
|
executionMessage = customMessage;
|
|
233
|
-
|
|
228
|
+
logger_1.logger.progress("📝 Using custom execution message");
|
|
234
229
|
}
|
|
235
230
|
else {
|
|
236
231
|
// Build comprehensive execution message with full context
|
|
@@ -262,7 +257,7 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
262
257
|
// Update task status to in-progress
|
|
263
258
|
if (!dry) {
|
|
264
259
|
await tasks_1.taskService.setTaskStatus(task.id, "in-progress");
|
|
265
|
-
|
|
260
|
+
logger_1.logger.warn("⏳ Task status updated to in-progress");
|
|
266
261
|
}
|
|
267
262
|
// Emit execution:start event
|
|
268
263
|
await hooks_1.hooks.emit("execution:start", { taskId: task.id, tool });
|
|
@@ -271,7 +266,7 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
271
266
|
const executor = executor_factory_1.ExecutorFactory.create(tool, executorConfig);
|
|
272
267
|
// Log session resumption if applicable
|
|
273
268
|
if (executorConfig?.continueLastSession && attemptNumber > 1) {
|
|
274
|
-
|
|
269
|
+
logger_1.logger.progress("🔄 Resuming previous session to provide error feedback to AI");
|
|
275
270
|
}
|
|
276
271
|
await executor.execute(executionMessage, dry, executorConfig);
|
|
277
272
|
// Run verification commands
|
|
@@ -289,13 +284,13 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
289
284
|
verificationResults,
|
|
290
285
|
timestamp: Date.now() - attemptStartTime,
|
|
291
286
|
});
|
|
292
|
-
|
|
287
|
+
logger_1.logger.error(`❌ Task execution failed verification on attempt ${attemptNumber}`);
|
|
293
288
|
throw new Error(error);
|
|
294
289
|
}
|
|
295
290
|
// Extract commit info if enabled
|
|
296
291
|
let commitInfo;
|
|
297
292
|
if (enableAutoCommit && !dry) {
|
|
298
|
-
|
|
293
|
+
logger_1.logger.info("📝 Extracting commit information...");
|
|
299
294
|
const gitStateAfter = await (0, git_utils_1.captureGitState)();
|
|
300
295
|
const gitState = {
|
|
301
296
|
beforeHead: gitStateBefore.beforeHead || "",
|
|
@@ -303,9 +298,9 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
303
298
|
hasUncommittedChanges: gitStateAfter.hasUncommittedChanges || false,
|
|
304
299
|
};
|
|
305
300
|
commitInfo = await (0, git_utils_1.extractCommitInfo)(task.id, task.title, executionMessage, gitState);
|
|
306
|
-
|
|
301
|
+
logger_1.logger.success(`✅ Commit message: ${commitInfo.message}`);
|
|
307
302
|
if (commitInfo.files.length > 0) {
|
|
308
|
-
|
|
303
|
+
logger_1.logger.success(`📁 Changed files: ${commitInfo.files.join(", ")}`);
|
|
309
304
|
}
|
|
310
305
|
// Auto-commit the changes
|
|
311
306
|
await (0, git_utils_1.autoCommit)(commitInfo);
|
|
@@ -313,7 +308,7 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
313
308
|
// Update task status to completed
|
|
314
309
|
if (!dry) {
|
|
315
310
|
await tasks_1.taskService.setTaskStatus(task.id, "completed");
|
|
316
|
-
|
|
311
|
+
logger_1.logger.success("✅ Task execution completed successfully");
|
|
317
312
|
}
|
|
318
313
|
// Record successful attempt
|
|
319
314
|
attempts.push({
|
|
@@ -337,7 +332,8 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
337
332
|
catch (error) {
|
|
338
333
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
339
334
|
// Record failed attempt if not already recorded
|
|
340
|
-
if (attempts.length === 0 ||
|
|
335
|
+
if (attempts.length === 0 ||
|
|
336
|
+
attempts[attempts.length - 1].attemptNumber !== attemptNumber) {
|
|
341
337
|
attempts.push({
|
|
342
338
|
attemptNumber,
|
|
343
339
|
success: false,
|
|
@@ -354,7 +350,7 @@ async function executeSingleAttempt(task, config, attempts, planContent, attempt
|
|
|
354
350
|
});
|
|
355
351
|
if (!dry) {
|
|
356
352
|
await tasks_1.taskService.setTaskStatus(task.id, "todo");
|
|
357
|
-
|
|
353
|
+
logger_1.logger.error("❌ Task execution failed, status reset to todo");
|
|
358
354
|
}
|
|
359
355
|
throw error;
|
|
360
356
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-loop-execution.d.ts","sourceRoot":"","sources":["../../src/lib/task-loop-execution.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAIlB,MAAM,UAAU,CAAC;AAIlB;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"task-loop-execution.d.ts","sourceRoot":"","sources":["../../src/lib/task-loop-execution.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAIlB,MAAM,UAAU,CAAC;AAIlB;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAmL5B"}
|
|
@@ -14,9 +14,12 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
14
14
|
async function executeTaskLoop(options) {
|
|
15
15
|
const startTime = Date.now();
|
|
16
16
|
const { filters = {}, tool = "opencode", config = {}, dry = false } = options;
|
|
17
|
-
const { maxRetries = 3, verificationCommands = [], autoCommit = false, tryModels, plan, planModel, reviewPlan, review, reviewModel, customMessage, continueSession,
|
|
17
|
+
const { maxRetries = 3, verificationCommands = [], autoCommit = false, tryModels, plan, planModel, reviewPlan, review, reviewModel, customMessage, continueSession, model, // NEW: Extract model from config
|
|
18
|
+
} = config;
|
|
18
19
|
console.log(chalk_1.default.blue.bold("\n🔄 Starting Task Loop Execution\n"));
|
|
19
20
|
console.log(chalk_1.default.cyan(`Executor Tool: ${tool}`));
|
|
21
|
+
if (model)
|
|
22
|
+
console.log(chalk_1.default.cyan(`Executor Model: ${model}`));
|
|
20
23
|
console.log(chalk_1.default.cyan(`Max Retries per Task: ${maxRetries}`));
|
|
21
24
|
console.log(chalk_1.default.cyan(`Verification Commands: ${verificationCommands.length > 0
|
|
22
25
|
? verificationCommands.join(", ")
|
|
@@ -68,6 +71,7 @@ async function executeTaskLoop(options) {
|
|
|
68
71
|
customMessage, // NEW: Support custom message override
|
|
69
72
|
executorConfig: {
|
|
70
73
|
continueLastSession: continueSession, // NEW: Support session continuation
|
|
74
|
+
model, // NEW: Pass model to executor
|
|
71
75
|
},
|
|
72
76
|
verificationCommands,
|
|
73
77
|
enableRetry: true, // Always enable retry in loop
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-planning.d.ts","sourceRoot":"","sources":["../../src/lib/task-planning.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAS9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"task-planning.d.ts","sourceRoot":"","sources":["../../src/lib/task-planning.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAS9D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,YAAY,EACzB,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,cAAc,CAAC,CAqHzB"}
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.executePlanningPhase = executePlanningPhase;
|
|
7
|
-
const
|
|
7
|
+
const logger_1 = require("./logger");
|
|
8
8
|
const executor_factory_1 = require("./executors/executor-factory");
|
|
9
9
|
const fs_1 = require("fs");
|
|
10
10
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
@@ -18,7 +18,7 @@ const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
|
18
18
|
*/
|
|
19
19
|
async function executePlanningPhase(task, defaultTool, config, execFn = execAsync) {
|
|
20
20
|
const { planModel, reviewPlan, autoCommit, dry } = config;
|
|
21
|
-
|
|
21
|
+
logger_1.logger.info(`\n🧠 Starting Planning Phase for Task: ${task.title}`);
|
|
22
22
|
const planFileName = `task-${task.id}-plan.md`;
|
|
23
23
|
// Parse executor and model from planModel string
|
|
24
24
|
const planExecutor = planModel
|
|
@@ -38,7 +38,7 @@ Requirements:
|
|
|
38
38
|
5. Do NOT implement the code yet, just create the plan file.
|
|
39
39
|
|
|
40
40
|
Please create the "${planFileName}" file now.`;
|
|
41
|
-
|
|
41
|
+
logger_1.logger.progress(` Using executor for planning: ${planExecutor}${planModelName ? ` (${planModelName})` : ""}`);
|
|
42
42
|
// Create executor for planning
|
|
43
43
|
const planningConfig = {
|
|
44
44
|
model: planModelName,
|
|
@@ -54,11 +54,11 @@ Please create the "${planFileName}" file now.`;
|
|
|
54
54
|
// Verify plan file exists and read it
|
|
55
55
|
if ((0, fs_1.existsSync)(planFileName)) {
|
|
56
56
|
planContent = (0, fs_1.readFileSync)(planFileName, "utf-8");
|
|
57
|
-
|
|
57
|
+
logger_1.logger.success(`✅ Plan created successfully: ${planFileName}`);
|
|
58
58
|
// Human Review Loop
|
|
59
59
|
if (reviewPlan) {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
logger_1.logger.warn(`\n👀 Pausing for Human Review of the Plan: ${planFileName}`);
|
|
61
|
+
logger_1.logger.progress("You can edit the file now.");
|
|
62
62
|
const { feedback } = await inquirer_1.default.prompt([
|
|
63
63
|
{
|
|
64
64
|
type: "input",
|
|
@@ -67,7 +67,7 @@ Please create the "${planFileName}" file now.`;
|
|
|
67
67
|
},
|
|
68
68
|
]);
|
|
69
69
|
if (feedback && feedback.trim() !== "") {
|
|
70
|
-
|
|
70
|
+
logger_1.logger.info("🔄 Refining plan based on feedback...");
|
|
71
71
|
planningPrompt = `The user provided the following feedback on the plan you just created:
|
|
72
72
|
|
|
73
73
|
"${feedback}"
|
|
@@ -84,7 +84,7 @@ Please update the plan file "${planFileName}" to incorporate this feedback.`;
|
|
|
84
84
|
planningComplete = true;
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
|
|
87
|
+
logger_1.logger.warn(`⚠️ Plan file ${planFileName} was not created by the executor.`);
|
|
88
88
|
planningComplete = true; // Exit loop to avoid infinite retry if file not created
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -100,7 +100,7 @@ Please update the plan file "${planFileName}" to incorporate this feedback.`;
|
|
|
100
100
|
}
|
|
101
101
|
catch (error) {
|
|
102
102
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
103
|
-
|
|
103
|
+
logger_1.logger.error(`❌ Planning phase failed: ${errorMessage}`);
|
|
104
104
|
return {
|
|
105
105
|
success: false,
|
|
106
106
|
error: errorMessage,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-review.d.ts","sourceRoot":"","sources":["../../src/lib/task-review.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,IAAI,EAAE,MAAM,UAAU,CAAC;AAO9C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,EACpB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"task-review.d.ts","sourceRoot":"","sources":["../../src/lib/task-review.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,IAAI,EAAE,MAAM,UAAU,CAAC;AAO9C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,EACpB,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,YAAY,CAAC,CAoGvB"}
|
package/dist/lib/task-review.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.executeReviewPhase = executeReviewPhase;
|
|
7
|
-
const
|
|
4
|
+
const logger_1 = require("./logger");
|
|
8
5
|
const ai_service_factory_1 = require("../utils/ai-service-factory");
|
|
9
6
|
const child_process_1 = require("child_process");
|
|
10
7
|
const util_1 = require("util");
|
|
@@ -15,9 +12,9 @@ const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
|
15
12
|
*/
|
|
16
13
|
async function executeReviewPhase(task, config, execFn = execAsync) {
|
|
17
14
|
const { reviewModel, planContent, dry } = config;
|
|
18
|
-
|
|
15
|
+
logger_1.logger.info("\n🕵️ Starting AI Review Phase...");
|
|
19
16
|
if (dry) {
|
|
20
|
-
|
|
17
|
+
logger_1.logger.warn("🔍 DRY RUN - Review phase skipped");
|
|
21
18
|
return {
|
|
22
19
|
approved: true,
|
|
23
20
|
feedback: "Dry run - review skipped",
|
|
@@ -28,7 +25,7 @@ async function executeReviewPhase(task, config, execFn = execAsync) {
|
|
|
28
25
|
// Get git diff
|
|
29
26
|
const { stdout: diff } = await execFn("git diff HEAD");
|
|
30
27
|
if (!diff.trim()) {
|
|
31
|
-
|
|
28
|
+
logger_1.logger.warn("⚠️ No changes detected to review.");
|
|
32
29
|
return {
|
|
33
30
|
approved: true,
|
|
34
31
|
feedback: "No changes to review",
|
|
@@ -41,10 +38,10 @@ async function executeReviewPhase(task, config, execFn = execAsync) {
|
|
|
41
38
|
: undefined;
|
|
42
39
|
const reviewModelName = reviewModel ? reviewModel.split(":")[1] : undefined;
|
|
43
40
|
if (reviewExecutor && reviewModelName) {
|
|
44
|
-
|
|
41
|
+
logger_1.logger.progress(` Using executor for review: ${reviewExecutor} (${reviewModelName})`);
|
|
45
42
|
}
|
|
46
43
|
else {
|
|
47
|
-
|
|
44
|
+
logger_1.logger.progress(" Using default AI provider for review");
|
|
48
45
|
}
|
|
49
46
|
const reviewPrompt = `You are a strict code reviewer. Review the following changes for the task.
|
|
50
47
|
|
|
@@ -72,10 +69,10 @@ Return a JSON object:
|
|
|
72
69
|
if (jsonMatch) {
|
|
73
70
|
const reviewResult = JSON.parse(jsonMatch[0]);
|
|
74
71
|
if (!reviewResult.approved) {
|
|
75
|
-
|
|
72
|
+
logger_1.logger.error(`❌ AI Review Rejected Changes: ${reviewResult.feedback}`);
|
|
76
73
|
}
|
|
77
74
|
else {
|
|
78
|
-
|
|
75
|
+
logger_1.logger.success(`✅ AI Review Approved: ${reviewResult.feedback}`);
|
|
79
76
|
}
|
|
80
77
|
return {
|
|
81
78
|
approved: reviewResult.approved,
|
|
@@ -84,7 +81,7 @@ Return a JSON object:
|
|
|
84
81
|
};
|
|
85
82
|
}
|
|
86
83
|
else {
|
|
87
|
-
|
|
84
|
+
logger_1.logger.warn("⚠️ Could not parse AI review response. Assuming approval.");
|
|
88
85
|
return {
|
|
89
86
|
approved: true,
|
|
90
87
|
feedback: "Could not parse review response, assuming approval",
|
|
@@ -94,7 +91,7 @@ Return a JSON object:
|
|
|
94
91
|
}
|
|
95
92
|
catch (error) {
|
|
96
93
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
97
|
-
|
|
94
|
+
logger_1.logger.error(`❌ AI Review failed: ${errorMessage}`);
|
|
98
95
|
// If review crashes, warn but don't fail the task
|
|
99
96
|
return {
|
|
100
97
|
approved: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,GACf,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAE/C;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,OAAO,EACZ,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,gBAAgB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,GACf,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAE/C;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,OAAO,EACZ,MAAM,GAAE,CACN,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAa,GAC3D,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqF7B"}
|
package/dist/lib/validation.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.isValidAIProvider = isValidAIProvider;
|
|
7
4
|
exports.runValidations = runValidations;
|
|
8
5
|
const child_process_1 = require("child_process");
|
|
9
6
|
const util_1 = require("util");
|
|
10
|
-
const
|
|
7
|
+
const logger_1 = require("./logger");
|
|
11
8
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
12
9
|
function isValidAIProvider(provider) {
|
|
13
10
|
return ["openrouter", "openai", "anthropic", "custom"].includes(provider);
|
|
@@ -23,9 +20,9 @@ async function runValidations(validations, dry, execFn = execAsync) {
|
|
|
23
20
|
return results;
|
|
24
21
|
}
|
|
25
22
|
if (dry) {
|
|
26
|
-
|
|
23
|
+
logger_1.logger.warn("🔍 DRY RUN - Validation/verification commands that would run:");
|
|
27
24
|
validations.forEach((cmd) => {
|
|
28
|
-
|
|
25
|
+
logger_1.logger.progress(` ${cmd}`);
|
|
29
26
|
results.push({
|
|
30
27
|
command: cmd,
|
|
31
28
|
success: true,
|
|
@@ -34,16 +31,16 @@ async function runValidations(validations, dry, execFn = execAsync) {
|
|
|
34
31
|
});
|
|
35
32
|
return results;
|
|
36
33
|
}
|
|
37
|
-
|
|
34
|
+
logger_1.logger.info(`🧪 Running ${validations.length} validation/verification command${validations.length > 1 ? "s" : ""}...`);
|
|
38
35
|
for (let i = 0; i < validations.length; i++) {
|
|
39
36
|
const validation = validations[i];
|
|
40
|
-
|
|
37
|
+
logger_1.logger.info(`🧪 Running validation [${i + 1}/${validations.length}]: ${validation}`);
|
|
41
38
|
try {
|
|
42
39
|
const { stdout, stderr } = await execFn(validation);
|
|
43
|
-
|
|
40
|
+
logger_1.logger.success(`✅ Validation passed: ${validation}`);
|
|
44
41
|
// Show stdout if there's any output
|
|
45
42
|
if (stdout && stdout.trim()) {
|
|
46
|
-
|
|
43
|
+
logger_1.logger.progress(` Output: ${stdout.trim()}`);
|
|
47
44
|
}
|
|
48
45
|
results.push({
|
|
49
46
|
command: validation,
|
|
@@ -52,17 +49,17 @@ async function runValidations(validations, dry, execFn = execAsync) {
|
|
|
52
49
|
});
|
|
53
50
|
}
|
|
54
51
|
catch (error) {
|
|
55
|
-
|
|
52
|
+
logger_1.logger.error(`❌ Validation failed: ${validation}`);
|
|
56
53
|
const errorOutput = error.stderr || error.stdout || error.message;
|
|
57
54
|
// Show error details
|
|
58
55
|
if (error.stdout && error.stdout.trim()) {
|
|
59
|
-
|
|
56
|
+
logger_1.logger.warn(` stdout: ${error.stdout.trim()}`);
|
|
60
57
|
}
|
|
61
58
|
if (error.stderr && error.stderr.trim()) {
|
|
62
|
-
|
|
59
|
+
logger_1.logger.error(` stderr: ${error.stderr.trim()}`);
|
|
63
60
|
}
|
|
64
61
|
if (error.message) {
|
|
65
|
-
|
|
62
|
+
logger_1.logger.error(` Error: ${error.message}`);
|
|
66
63
|
}
|
|
67
64
|
results.push({
|
|
68
65
|
command: validation,
|
|
@@ -75,7 +72,7 @@ async function runValidations(validations, dry, execFn = execAsync) {
|
|
|
75
72
|
}
|
|
76
73
|
const allPassed = results.every((r) => r.success);
|
|
77
74
|
if (allPassed) {
|
|
78
|
-
|
|
75
|
+
logger_1.logger.success(`🎉 All ${validations.length} validation${validations.length > 1 ? "s" : ""} passed!`);
|
|
79
76
|
}
|
|
80
77
|
return results;
|
|
81
78
|
}
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { BenchmarkConfig, BenchmarkRun, BenchmarkProgressEvent } from "../lib/benchmark/types";
|
|
2
|
+
import { ExecuteLoopOptions } from "../types";
|
|
3
|
+
import { WorkflowBenchmarkInput } from "../lib/benchmark/types";
|
|
4
|
+
export interface ExecutionBenchmarkOptions {
|
|
5
|
+
taskId: string;
|
|
6
|
+
verificationCommands?: string[];
|
|
7
|
+
maxRetries?: number;
|
|
8
|
+
keepBranches?: boolean;
|
|
9
|
+
}
|
|
2
10
|
export declare class BenchmarkService {
|
|
3
11
|
runBenchmark(operationId: string, input: any, config: BenchmarkConfig, onProgress?: (event: BenchmarkProgressEvent) => void): Promise<BenchmarkRun>;
|
|
12
|
+
runExecutionBenchmark(options: ExecutionBenchmarkOptions, config: BenchmarkConfig, onProgress?: (event: BenchmarkProgressEvent) => void): Promise<BenchmarkRun>;
|
|
13
|
+
runExecuteLoopBenchmark(options: {
|
|
14
|
+
loopOptions: ExecuteLoopOptions;
|
|
15
|
+
keepBranches?: boolean;
|
|
16
|
+
}, config: BenchmarkConfig, onProgress?: (event: BenchmarkProgressEvent) => void): Promise<BenchmarkRun>;
|
|
17
|
+
runWorkflowBenchmark(input: WorkflowBenchmarkInput, config: BenchmarkConfig, onProgress?: (event: BenchmarkProgressEvent) => void): Promise<BenchmarkRun>;
|
|
4
18
|
getRun(id: string): BenchmarkRun | null;
|
|
5
19
|
listRuns(): Array<{
|
|
6
20
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/services/benchmark.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,
|
|
1
|
+
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/services/benchmark.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,sBAAsB,EAEvB,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAuB,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,qBAAa,gBAAgB;IACrB,YAAY,CAChB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GACnD,OAAO,CAAC,YAAY,CAAC;IAIlB,qBAAqB,CACzB,OAAO,EAAE,yBAAyB,EAClC,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GACnD,OAAO,CAAC,YAAY,CAAC;IA8HlB,uBAAuB,CAC3B,OAAO,EAAE;QACP,WAAW,EAAE,kBAAkB,CAAC;QAChC,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,EACD,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GACnD,OAAO,CAAC,YAAY,CAAC;IAoGlB,oBAAoB,CACxB,KAAK,EAAE,sBAAsB,EAC7B,MAAM,EAAE,eAAe,EACvB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,GACnD,OAAO,CAAC,YAAY,CAAC;IAiJxB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIvC,QAAQ,IAAI,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAGtE;AAED,eAAO,MAAM,gBAAgB,kBAAyB,CAAC"}
|