task-o-matic 0.0.7 → 0.0.9

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.
Files changed (78) hide show
  1. package/README.md +286 -23
  2. package/dist/commands/benchmark.d.ts +3 -0
  3. package/dist/commands/benchmark.d.ts.map +1 -0
  4. package/dist/commands/benchmark.js +569 -0
  5. package/dist/commands/prd.d.ts.map +1 -1
  6. package/dist/commands/prd.js +203 -9
  7. package/dist/commands/tasks/execute-loop.d.ts +3 -0
  8. package/dist/commands/tasks/execute-loop.d.ts.map +1 -0
  9. package/dist/commands/tasks/execute-loop.js +118 -0
  10. package/dist/commands/tasks/index.d.ts +1 -0
  11. package/dist/commands/tasks/index.d.ts.map +1 -1
  12. package/dist/commands/tasks/index.js +1 -0
  13. package/dist/commands/tasks.d.ts.map +1 -1
  14. package/dist/commands/tasks.js +1 -0
  15. package/dist/commands/workflow.d.ts.map +1 -1
  16. package/dist/commands/workflow.js +491 -331
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +2 -0
  19. package/dist/lib/ai-service/ai-operations.d.ts +5 -0
  20. package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
  21. package/dist/lib/ai-service/ai-operations.js +167 -0
  22. package/dist/lib/benchmark/registry.d.ts +11 -0
  23. package/dist/lib/benchmark/registry.d.ts.map +1 -0
  24. package/dist/lib/benchmark/registry.js +89 -0
  25. package/dist/lib/benchmark/runner.d.ts +6 -0
  26. package/dist/lib/benchmark/runner.d.ts.map +1 -0
  27. package/dist/lib/benchmark/runner.js +150 -0
  28. package/dist/lib/benchmark/storage.d.ts +13 -0
  29. package/dist/lib/benchmark/storage.d.ts.map +1 -0
  30. package/dist/lib/benchmark/storage.js +99 -0
  31. package/dist/lib/benchmark/types.d.ts +104 -0
  32. package/dist/lib/benchmark/types.d.ts.map +1 -0
  33. package/dist/lib/benchmark/types.js +2 -0
  34. package/dist/lib/index.d.ts +9 -0
  35. package/dist/lib/index.d.ts.map +1 -1
  36. package/dist/lib/index.js +7 -1
  37. package/dist/lib/prompt-registry.d.ts.map +1 -1
  38. package/dist/lib/prompt-registry.js +23 -0
  39. package/dist/lib/task-loop-execution.d.ts +25 -0
  40. package/dist/lib/task-loop-execution.d.ts.map +1 -0
  41. package/dist/lib/task-loop-execution.js +473 -0
  42. package/dist/prompts/index.d.ts +7 -6
  43. package/dist/prompts/index.d.ts.map +1 -1
  44. package/dist/prompts/index.js +1 -0
  45. package/dist/prompts/prd-question.d.ts +3 -0
  46. package/dist/prompts/prd-question.d.ts.map +1 -0
  47. package/dist/prompts/prd-question.js +40 -0
  48. package/dist/services/benchmark.d.ts +12 -0
  49. package/dist/services/benchmark.d.ts.map +1 -0
  50. package/dist/services/benchmark.js +18 -0
  51. package/dist/services/prd.d.ts +25 -0
  52. package/dist/services/prd.d.ts.map +1 -1
  53. package/dist/services/prd.js +224 -29
  54. package/dist/services/tasks.d.ts.map +1 -1
  55. package/dist/services/tasks.js +90 -3
  56. package/dist/services/workflow-benchmark.d.ts +34 -0
  57. package/dist/services/workflow-benchmark.d.ts.map +1 -0
  58. package/dist/services/workflow-benchmark.js +317 -0
  59. package/dist/services/workflow.d.ts +85 -0
  60. package/dist/services/workflow.d.ts.map +1 -0
  61. package/dist/services/workflow.js +476 -0
  62. package/dist/test/task-loop-git.test.d.ts +2 -0
  63. package/dist/test/task-loop-git.test.d.ts.map +1 -0
  64. package/dist/test/task-loop-git.test.js +62 -0
  65. package/dist/types/index.d.ts +53 -0
  66. package/dist/types/index.d.ts.map +1 -1
  67. package/dist/types/options.d.ts +2 -1
  68. package/dist/types/options.d.ts.map +1 -1
  69. package/dist/types/options.js +16 -0
  70. package/dist/types/results.d.ts +29 -1
  71. package/dist/types/results.d.ts.map +1 -1
  72. package/dist/types/workflow-options.d.ts +45 -0
  73. package/dist/types/workflow-options.d.ts.map +1 -0
  74. package/dist/types/workflow-options.js +2 -0
  75. package/dist/types/workflow-results.d.ts +82 -0
  76. package/dist/types/workflow-results.d.ts.map +1 -0
  77. package/dist/types/workflow-results.js +2 -0
  78. package/package.json +1 -1
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.prdService = exports.PRDService = void 0;
4
37
  const fs_1 = require("fs");
@@ -16,8 +49,8 @@ class PRDService {
16
49
  const startTime = Date.now();
17
50
  const steps = [];
18
51
  input.callbacks?.onProgress?.({
19
- type: 'started',
20
- message: 'Starting PRD parsing...',
52
+ type: "started",
53
+ message: "Starting PRD parsing...",
21
54
  });
22
55
  // Validate file exists
23
56
  if (!(0, fs_1.existsSync)(input.file)) {
@@ -32,14 +65,14 @@ class PRDService {
32
65
  const workingDir = input.workingDirectory || process.cwd();
33
66
  config_1.configManager.setWorkingDirectory(workingDir);
34
67
  input.callbacks?.onProgress?.({
35
- type: 'progress',
36
- message: 'Reading PRD file...',
68
+ type: "progress",
69
+ message: "Reading PRD file...",
37
70
  });
38
71
  const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
39
72
  // Save PRD file to .task-o-matic/prd directory
40
73
  input.callbacks?.onProgress?.({
41
- type: 'progress',
42
- message: 'Saving PRD to project directory...',
74
+ type: "progress",
75
+ message: "Saving PRD to project directory...",
43
76
  });
44
77
  const stepStart1 = Date.now();
45
78
  const prdDir = (0, path_1.join)(taskOMaticDir, "prd");
@@ -54,31 +87,57 @@ class PRDService {
54
87
  // Get relative path from .task-o-matic directory for storage
55
88
  const relativePrdPath = (0, path_1.relative)(taskOMaticDir, savedPrdPath);
56
89
  steps.push({
57
- step: 'Save PRD File',
58
- status: 'completed',
90
+ step: "Save PRD File",
91
+ status: "completed",
59
92
  duration: Date.now() - stepStart1,
60
93
  });
61
94
  // Validate AI provider if specified
62
- if (input.aiOptions?.aiProvider && !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
95
+ if (input.aiOptions?.aiProvider &&
96
+ !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
63
97
  throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
64
98
  }
65
99
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
66
100
  input.callbacks?.onProgress?.({
67
- type: 'progress',
68
- message: 'Parsing PRD with AI...',
101
+ type: "progress",
102
+ message: "Parsing PRD with AI...",
69
103
  });
70
104
  const stepStart2 = Date.now();
71
- const result = await (0, ai_service_factory_1.getAIOperations)().parsePRD(prdContent, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
105
+ // Capture metrics
106
+ let tokenUsage;
107
+ let timeToFirstToken;
108
+ // Wrap streaming options to capture metrics
109
+ const metricsStreamingOptions = {
110
+ ...input.streamingOptions,
111
+ onFinish: async (result) => {
112
+ if (result.usage) {
113
+ tokenUsage = {
114
+ prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
115
+ completion: result.usage.outputTokens || result.usage.completionTokens || 0,
116
+ total: result.usage.totalTokens || 0,
117
+ };
118
+ }
119
+ // Call original onFinish if provided
120
+ await input.streamingOptions?.onFinish?.(result);
121
+ },
122
+ onChunk: (chunk) => {
123
+ if (chunk && !timeToFirstToken) {
124
+ timeToFirstToken = Date.now() - stepStart2;
125
+ }
126
+ // Call original onChunk if provided
127
+ input.streamingOptions?.onChunk?.(chunk);
128
+ },
129
+ };
130
+ const result = await (0, ai_service_factory_1.getAIOperations)().parsePRD(prdContent, aiConfig, input.promptOverride, input.messageOverride, metricsStreamingOptions, undefined, // retryConfig
72
131
  workingDir, // Pass working directory to AI operations
73
132
  input.enableFilesystemTools);
74
133
  steps.push({
75
- step: 'AI Parsing',
76
- status: 'completed',
134
+ step: "AI Parsing",
135
+ status: "completed",
77
136
  duration: Date.now() - stepStart2,
78
137
  details: { tasksFound: result.tasks.length },
79
138
  });
80
139
  input.callbacks?.onProgress?.({
81
- type: 'progress',
140
+ type: "progress",
82
141
  message: `Creating ${result.tasks.length} tasks...`,
83
142
  });
84
143
  // Create tasks
@@ -87,7 +146,7 @@ class PRDService {
87
146
  for (let i = 0; i < result.tasks.length; i++) {
88
147
  const task = result.tasks[i];
89
148
  input.callbacks?.onProgress?.({
90
- type: 'progress',
149
+ type: "progress",
91
150
  message: `Creating task ${i + 1}/${result.tasks.length}: ${task.title}`,
92
151
  current: i + 1,
93
152
  total: result.tasks.length,
@@ -117,16 +176,23 @@ class PRDService {
117
176
  await (0, ai_service_factory_1.getStorage)().saveTaskAIMetadata(aiMetadata);
118
177
  }
119
178
  steps.push({
120
- step: 'Create Tasks',
121
- status: 'completed',
179
+ step: "Create Tasks",
180
+ status: "completed",
122
181
  duration: Date.now() - stepStart3,
123
182
  details: { count: createdTasks.length },
124
183
  });
125
184
  input.callbacks?.onProgress?.({
126
- type: 'completed',
185
+ type: "completed",
127
186
  message: `Successfully created ${createdTasks.length} tasks from PRD`,
128
187
  });
129
188
  const duration = Date.now() - startTime;
189
+ // Calculate cost if token usage is available
190
+ let cost;
191
+ if (tokenUsage) {
192
+ // Cost calculation would depend on the model
193
+ // For now, we'll leave it undefined and can add pricing later
194
+ // This matches the benchmark pattern where cost calculation is done elsewhere
195
+ }
130
196
  return {
131
197
  success: true,
132
198
  prd: {
@@ -140,14 +206,48 @@ class PRDService {
140
206
  duration,
141
207
  aiProvider: input.aiOptions?.aiProvider || "default",
142
208
  aiModel: input.aiOptions?.aiModel || "default",
209
+ tokenUsage,
210
+ timeToFirstToken,
211
+ cost,
143
212
  },
144
213
  steps,
145
214
  };
146
215
  }
216
+ async generateQuestions(input) {
217
+ input.callbacks?.onProgress?.({
218
+ type: "started",
219
+ message: "Generating clarifying questions...",
220
+ });
221
+ if (!(0, fs_1.existsSync)(input.file)) {
222
+ throw new Error(`PRD file not found: ${input.file}`);
223
+ }
224
+ const workingDir = input.workingDirectory || process.cwd();
225
+ config_1.configManager.setWorkingDirectory(workingDir);
226
+ input.callbacks?.onProgress?.({
227
+ type: "progress",
228
+ message: "Reading PRD file...",
229
+ });
230
+ const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
231
+ if (input.aiOptions?.aiProvider &&
232
+ !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
233
+ throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
234
+ }
235
+ const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
236
+ input.callbacks?.onProgress?.({
237
+ type: "progress",
238
+ message: "Analyzing PRD with AI...",
239
+ });
240
+ const questions = await (0, ai_service_factory_1.getAIOperations)().generatePRDQuestions(prdContent, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, workingDir, input.enableFilesystemTools);
241
+ input.callbacks?.onProgress?.({
242
+ type: "completed",
243
+ message: `Generated ${questions.length} questions`,
244
+ });
245
+ return questions;
246
+ }
147
247
  async reworkPRD(input) {
148
248
  input.callbacks?.onProgress?.({
149
- type: 'started',
150
- message: 'Starting PRD improvement...',
249
+ type: "started",
250
+ message: "Starting PRD improvement...",
151
251
  });
152
252
  // Validate file exists
153
253
  if (!(0, fs_1.existsSync)(input.file)) {
@@ -157,34 +257,129 @@ class PRDService {
157
257
  const workingDir = input.workingDirectory || process.cwd();
158
258
  config_1.configManager.setWorkingDirectory(workingDir);
159
259
  input.callbacks?.onProgress?.({
160
- type: 'progress',
161
- message: 'Reading PRD file...',
260
+ type: "progress",
261
+ message: "Reading PRD file...",
162
262
  });
163
263
  const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
164
264
  // Validate AI provider if specified
165
- if (input.aiOptions?.aiProvider && !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
265
+ if (input.aiOptions?.aiProvider &&
266
+ !(0, validation_1.isValidAIProvider)(input.aiOptions.aiProvider)) {
166
267
  throw new Error(`Invalid AI provider: ${input.aiOptions.aiProvider}`);
167
268
  }
168
269
  const aiConfig = (0, ai_config_builder_1.buildAIConfig)(input.aiOptions);
169
270
  input.callbacks?.onProgress?.({
170
- type: 'progress',
171
- message: 'Calling AI to improve PRD...',
271
+ type: "progress",
272
+ message: "Calling AI to improve PRD...",
172
273
  });
173
274
  const improvedPRD = await (0, ai_service_factory_1.getAIOperations)().reworkPRD(prdContent, input.feedback, aiConfig, input.promptOverride, input.messageOverride, input.streamingOptions, undefined, // retryConfig
174
275
  workingDir, // Pass working directory to AI operations
175
276
  input.enableFilesystemTools);
176
277
  input.callbacks?.onProgress?.({
177
- type: 'progress',
178
- message: 'Saving improved PRD...',
278
+ type: "progress",
279
+ message: "Saving improved PRD...",
179
280
  });
180
281
  const outputPath = input.output || input.file;
181
282
  (0, fs_1.writeFileSync)(outputPath, improvedPRD);
182
283
  input.callbacks?.onProgress?.({
183
- type: 'completed',
284
+ type: "completed",
184
285
  message: `PRD improved and saved to ${outputPath}`,
185
286
  });
186
287
  return outputPath;
187
288
  }
289
+ async refinePRDWithQuestions(input) {
290
+ input.callbacks?.onProgress?.({
291
+ type: "started",
292
+ message: "Starting PRD question/refine process...",
293
+ });
294
+ // Step 1: Generate questions
295
+ input.callbacks?.onProgress?.({
296
+ type: "progress",
297
+ message: "Generating clarifying questions...",
298
+ });
299
+ const questions = await this.generateQuestions({
300
+ file: input.file,
301
+ workingDirectory: input.workingDirectory,
302
+ enableFilesystemTools: input.enableFilesystemTools,
303
+ aiOptions: input.aiOptions,
304
+ streamingOptions: input.streamingOptions,
305
+ callbacks: input.callbacks,
306
+ });
307
+ if (questions.length === 0) {
308
+ input.callbacks?.onProgress?.({
309
+ type: "completed",
310
+ message: "No questions generated - PRD appears complete",
311
+ });
312
+ return {
313
+ questions: [],
314
+ answers: {},
315
+ refinedPRDPath: input.file,
316
+ };
317
+ }
318
+ // Step 2: Get stack info for context
319
+ const workingDir = input.workingDirectory || process.cwd();
320
+ const PromptBuilder = (await Promise.resolve().then(() => __importStar(require("../lib/prompt-builder")))).PromptBuilder;
321
+ let stackInfo = "";
322
+ try {
323
+ stackInfo = await PromptBuilder.detectStackInfo(workingDir);
324
+ if (stackInfo === "Not detected") {
325
+ stackInfo = "";
326
+ }
327
+ }
328
+ catch (error) {
329
+ // Stack info not available
330
+ }
331
+ // Step 3: Get answers
332
+ let answers;
333
+ if (input.questionMode === "user") {
334
+ // User mode: return questions for CLI to prompt user
335
+ // Answers should be provided in input.answers
336
+ if (!input.answers || Object.keys(input.answers).length === 0) {
337
+ throw new Error("User mode selected but no answers provided. CLI layer should collect answers.");
338
+ }
339
+ answers = input.answers;
340
+ }
341
+ else {
342
+ // AI mode: use AI to answer questions with context
343
+ input.callbacks?.onProgress?.({
344
+ type: "progress",
345
+ message: "AI is answering questions...",
346
+ });
347
+ const prdContent = (0, fs_1.readFileSync)(input.file, "utf-8");
348
+ // Use questionAIOptions if provided, otherwise use main aiOptions
349
+ const answeringAIConfig = (0, ai_config_builder_1.buildAIConfig)(input.questionAIOptions || input.aiOptions);
350
+ answers = await (0, ai_service_factory_1.getAIOperations)().answerPRDQuestions(prdContent, questions, answeringAIConfig, {
351
+ stackInfo,
352
+ }, input.streamingOptions);
353
+ }
354
+ // Step 4: Format questions + answers as structured feedback
355
+ let feedback = "Please incorporate the following clarifications into the PRD:\n\n";
356
+ questions.forEach((q, i) => {
357
+ feedback += `Q${i + 1}: ${q}\nA: ${answers[q] || "No answer provided"}\n\n`;
358
+ });
359
+ // Step 5: Automatically call reworkPRD with formatted feedback
360
+ input.callbacks?.onProgress?.({
361
+ type: "progress",
362
+ message: "Refining PRD with answers...",
363
+ });
364
+ const refinedPRDPath = await this.reworkPRD({
365
+ file: input.file,
366
+ feedback,
367
+ workingDirectory: input.workingDirectory,
368
+ enableFilesystemTools: input.enableFilesystemTools,
369
+ aiOptions: input.aiOptions,
370
+ streamingOptions: input.streamingOptions,
371
+ callbacks: input.callbacks,
372
+ });
373
+ input.callbacks?.onProgress?.({
374
+ type: "completed",
375
+ message: `PRD refined with ${questions.length} questions answered`,
376
+ });
377
+ return {
378
+ questions,
379
+ answers,
380
+ refinedPRDPath,
381
+ };
382
+ }
188
383
  }
189
384
  exports.PRDService = PRDService;
190
385
  // Export singleton instance
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/services/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/services/tasks.ts"],"names":[],"mappings":"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"}
@@ -328,7 +328,33 @@ class TaskService {
328
328
  message: "Calling AI for enhancement...",
329
329
  type: "progress",
330
330
  });
331
- const enhancedContent = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(task.id, task.title, task.description ?? "", stackInfo, streamingOptions, undefined, enhancementAIConfig, context.existingResearch);
331
+ // Capture metrics
332
+ let tokenUsage;
333
+ let timeToFirstToken;
334
+ const aiStartTime = Date.now();
335
+ // Wrap streaming options to capture metrics
336
+ const metricsStreamingOptions = {
337
+ ...streamingOptions,
338
+ onFinish: async (result) => {
339
+ if (result.usage) {
340
+ tokenUsage = {
341
+ prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
342
+ completion: result.usage.outputTokens || result.usage.completionTokens || 0,
343
+ total: result.usage.totalTokens || 0,
344
+ };
345
+ }
346
+ // Call original onFinish if provided
347
+ await streamingOptions?.onFinish?.(result);
348
+ },
349
+ onChunk: (chunk) => {
350
+ if (chunk && !timeToFirstToken) {
351
+ timeToFirstToken = Date.now() - aiStartTime;
352
+ }
353
+ // Call original onChunk if provided
354
+ streamingOptions?.onChunk?.(chunk);
355
+ },
356
+ };
357
+ const enhancedContent = await (0, ai_service_factory_1.getAIOperations)().enhanceTaskWithDocumentation(task.id, task.title, task.description ?? "", stackInfo, metricsStreamingOptions, undefined, enhancementAIConfig, context.existingResearch);
332
358
  hooks_1.hooks.emit("task:progress", {
333
359
  message: "Saving enhanced content...",
334
360
  type: "progress",
@@ -369,6 +395,9 @@ class TaskService {
369
395
  originalLength,
370
396
  enhancedLength: enhancedContent.length,
371
397
  duration,
398
+ tokenUsage,
399
+ timeToFirstToken,
400
+ cost: undefined, // Cost calculation can be added later
372
401
  },
373
402
  metadata: {
374
403
  aiProvider: aiConfig.provider,
@@ -406,8 +435,34 @@ class TaskService {
406
435
  message: "Calling AI to break down task...",
407
436
  type: "progress",
408
437
  });
438
+ // Capture metrics
439
+ let tokenUsage;
440
+ let timeToFirstToken;
441
+ const aiStartTime = Date.now();
442
+ // Wrap streaming options to capture metrics
443
+ const metricsStreamingOptions = {
444
+ ...streamingOptions,
445
+ onFinish: async (result) => {
446
+ if (result.usage) {
447
+ tokenUsage = {
448
+ prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
449
+ completion: result.usage.outputTokens || result.usage.completionTokens || 0,
450
+ total: result.usage.totalTokens || 0,
451
+ };
452
+ }
453
+ // Call original onFinish if provided
454
+ await streamingOptions?.onFinish?.(result);
455
+ },
456
+ onChunk: (chunk) => {
457
+ if (chunk && !timeToFirstToken) {
458
+ timeToFirstToken = Date.now() - aiStartTime;
459
+ }
460
+ // Call original onChunk if provided
461
+ streamingOptions?.onChunk?.(chunk);
462
+ },
463
+ };
409
464
  // Use AI service to break down the task with enhanced context
410
- const subtaskData = await (0, ai_service_factory_1.getAIOperations)().breakdownTask(task, breakdownAIConfig, promptOverride, messageOverride, streamingOptions, undefined, fullContent, stackInfo, existingSubtasks, enableFilesystemTools);
465
+ const subtaskData = await (0, ai_service_factory_1.getAIOperations)().breakdownTask(task, breakdownAIConfig, promptOverride, messageOverride, metricsStreamingOptions, undefined, fullContent, stackInfo, existingSubtasks, enableFilesystemTools);
411
466
  hooks_1.hooks.emit("task:progress", {
412
467
  message: `Creating ${subtaskData.length} subtasks...`,
413
468
  type: "progress",
@@ -453,6 +508,9 @@ class TaskService {
453
508
  stats: {
454
509
  subtasksCreated: createdSubtasks.length,
455
510
  duration,
511
+ tokenUsage,
512
+ timeToFirstToken,
513
+ cost: undefined, // Cost calculation can be added later
456
514
  },
457
515
  metadata: {
458
516
  aiProvider: aiConfig.provider,
@@ -604,7 +662,33 @@ class TaskService {
604
662
  message: "Calling AI to create plan...",
605
663
  type: "progress",
606
664
  });
607
- const plan = await aiService.planTask(taskContext, taskDetails, planAIConfig, undefined, undefined, streamingOptions);
665
+ // Capture metrics
666
+ let tokenUsage;
667
+ let timeToFirstToken;
668
+ const aiStartTime = Date.now();
669
+ // Wrap streaming options to capture metrics
670
+ const metricsStreamingOptions = {
671
+ ...streamingOptions,
672
+ onFinish: async (result) => {
673
+ if (result.usage) {
674
+ tokenUsage = {
675
+ prompt: result.usage.inputTokens || result.usage.promptTokens || 0,
676
+ completion: result.usage.outputTokens || result.usage.completionTokens || 0,
677
+ total: result.usage.totalTokens || 0,
678
+ };
679
+ }
680
+ // Call original onFinish if provided
681
+ await streamingOptions?.onFinish?.(result);
682
+ },
683
+ onChunk: (chunk) => {
684
+ if (chunk && !timeToFirstToken) {
685
+ timeToFirstToken = Date.now() - aiStartTime;
686
+ }
687
+ // Call original onChunk if provided
688
+ streamingOptions?.onChunk?.(chunk);
689
+ },
690
+ };
691
+ const plan = await aiService.planTask(taskContext, taskDetails, planAIConfig, undefined, undefined, metricsStreamingOptions);
608
692
  hooks_1.hooks.emit("task:progress", {
609
693
  message: "Saving plan...",
610
694
  type: "progress",
@@ -623,6 +707,9 @@ class TaskService {
623
707
  plan,
624
708
  stats: {
625
709
  duration,
710
+ tokenUsage,
711
+ timeToFirstToken,
712
+ cost: undefined, // Cost calculation can be added later
626
713
  },
627
714
  metadata: {
628
715
  aiProvider: aiConfig.provider,
@@ -0,0 +1,34 @@
1
+ import { AIOptions } from "../utils/ai-config-builder";
2
+ import { StreamingOptions } from "../types";
3
+ import { WorkflowBenchmarkInput, WorkflowBenchmarkResult } from "../lib/benchmark/types";
4
+ /**
5
+ * WorkflowBenchmarkService - Executes complete workflows for benchmarking
6
+ * Creates isolated environments for each model to ensure fair comparison
7
+ */
8
+ export declare class WorkflowBenchmarkService {
9
+ /**
10
+ * Execute a complete workflow for benchmarking purposes
11
+ */
12
+ executeWorkflow(input: WorkflowBenchmarkInput, aiOptions: AIOptions, streamingOptions?: StreamingOptions): Promise<WorkflowBenchmarkResult["output"]>;
13
+ /**
14
+ * Create a temporary project directory for benchmarking
15
+ */
16
+ private createTempProjectDir;
17
+ /**
18
+ * Clean up temporary project directory
19
+ */
20
+ private cleanupTempProjectDir;
21
+ /**
22
+ * Apply the results from a selected benchmark to the actual project
23
+ */
24
+ applyBenchmarkResult(selectedResult: WorkflowBenchmarkResult, targetProjectDir: string, originalResponses: WorkflowBenchmarkInput["collectedResponses"]): Promise<{
25
+ success: boolean;
26
+ message: string;
27
+ }>;
28
+ /**
29
+ * Validate workflow benchmark input
30
+ */
31
+ validateInput(input: any): input is WorkflowBenchmarkInput;
32
+ }
33
+ export declare const workflowBenchmarkService: WorkflowBenchmarkService;
34
+ //# sourceMappingURL=workflow-benchmark.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-benchmark.d.ts","sourceRoot":"","sources":["../../src/services/workflow-benchmark.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAQ,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAGzF;;;GAGG;AACH,qBAAa,wBAAwB;IACnC;;OAEG;IACG,eAAe,CACnB,KAAK,EAAE,sBAAsB,EAC7B,SAAS,EAAE,SAAS,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,GAClC,OAAO,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAiL7C;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACG,oBAAoB,CACxB,cAAc,EAAE,uBAAuB,EACvC,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,sBAAsB,CAAC,oBAAoB,CAAC,GAC9D,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAyFjD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,sBAAsB;CAU3D;AAED,eAAO,MAAM,wBAAwB,0BAAiC,CAAC"}