@auto-engineer/component-implementor-react 1.108.0 → 1.109.0
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +6 -6
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +49 -0
- package/dist/src/commands/implement-component.d.ts +3 -0
- package/dist/src/commands/implement-component.d.ts.map +1 -1
- package/dist/src/commands/implement-component.js +11 -33
- package/dist/src/commands/implement-component.js.map +1 -1
- package/dist/src/commands/implement-component.test.js +6 -66
- package/dist/src/commands/implement-component.test.js.map +1 -1
- package/dist/src/pipeline/run-pipeline.d.ts +5 -25
- package/dist/src/pipeline/run-pipeline.d.ts.map +1 -1
- package/dist/src/pipeline/run-pipeline.js +17 -47
- package/dist/src/pipeline/run-pipeline.js.map +1 -1
- package/dist/src/pipeline/run-pipeline.test.js +29 -132
- package/dist/src/pipeline/run-pipeline.test.js.map +1 -1
- package/dist/src/pipeline/steps/fix-from-feedback.d.ts +4 -0
- package/dist/src/pipeline/steps/fix-from-feedback.d.ts.map +1 -0
- package/dist/src/pipeline/steps/fix-from-feedback.js +94 -0
- package/dist/src/pipeline/steps/fix-from-feedback.js.map +1 -0
- package/dist/src/pipeline/steps/generate-component.test.js +1 -5
- package/dist/src/pipeline/steps/generate-component.test.js.map +1 -1
- package/dist/src/pipeline/steps/generate-story.test.js +1 -5
- package/dist/src/pipeline/steps/generate-story.test.js.map +1 -1
- package/dist/src/pipeline/steps/generate-test.test.js +1 -5
- package/dist/src/pipeline/steps/generate-test.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/commands/implement-component.test.ts +6 -66
- package/src/commands/implement-component.ts +16 -47
- package/src/pipeline/run-pipeline.test.ts +32 -141
- package/src/pipeline/run-pipeline.ts +22 -74
- package/src/pipeline/steps/fix-from-feedback.ts +105 -0
- package/src/pipeline/steps/generate-component.test.ts +1 -5
- package/src/pipeline/steps/generate-story.test.ts +1 -5
- package/src/pipeline/steps/generate-test.test.ts +1 -5
- package/dist/src/pipeline/steps/lint-fix-loop.d.ts +0 -4
- package/dist/src/pipeline/steps/lint-fix-loop.d.ts.map +0 -1
- package/dist/src/pipeline/steps/lint-fix-loop.js +0 -46
- package/dist/src/pipeline/steps/lint-fix-loop.js.map +0 -1
- package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts +0 -2
- package/dist/src/pipeline/steps/lint-fix-loop.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/lint-fix-loop.test.js +0 -136
- package/dist/src/pipeline/steps/lint-fix-loop.test.js.map +0 -1
- package/dist/src/pipeline/steps/story-fix-loop.d.ts +0 -4
- package/dist/src/pipeline/steps/story-fix-loop.d.ts.map +0 -1
- package/dist/src/pipeline/steps/story-fix-loop.js +0 -35
- package/dist/src/pipeline/steps/story-fix-loop.js.map +0 -1
- package/dist/src/pipeline/steps/story-fix-loop.test.d.ts +0 -2
- package/dist/src/pipeline/steps/story-fix-loop.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/story-fix-loop.test.js +0 -98
- package/dist/src/pipeline/steps/story-fix-loop.test.js.map +0 -1
- package/dist/src/pipeline/steps/storybook-test.d.ts +0 -3
- package/dist/src/pipeline/steps/storybook-test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/storybook-test.js +0 -22
- package/dist/src/pipeline/steps/storybook-test.js.map +0 -1
- package/dist/src/pipeline/steps/storybook-test.test.d.ts +0 -2
- package/dist/src/pipeline/steps/storybook-test.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/storybook-test.test.js +0 -70
- package/dist/src/pipeline/steps/storybook-test.test.js.map +0 -1
- package/dist/src/pipeline/steps/test-fix-loop.d.ts +0 -4
- package/dist/src/pipeline/steps/test-fix-loop.d.ts.map +0 -1
- package/dist/src/pipeline/steps/test-fix-loop.js +0 -45
- package/dist/src/pipeline/steps/test-fix-loop.js.map +0 -1
- package/dist/src/pipeline/steps/test-fix-loop.test.d.ts +0 -2
- package/dist/src/pipeline/steps/test-fix-loop.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/test-fix-loop.test.js +0 -172
- package/dist/src/pipeline/steps/test-fix-loop.test.js.map +0 -1
- package/dist/src/pipeline/steps/type-fix-loop.d.ts +0 -4
- package/dist/src/pipeline/steps/type-fix-loop.d.ts.map +0 -1
- package/dist/src/pipeline/steps/type-fix-loop.js +0 -44
- package/dist/src/pipeline/steps/type-fix-loop.js.map +0 -1
- package/dist/src/pipeline/steps/type-fix-loop.test.d.ts +0 -2
- package/dist/src/pipeline/steps/type-fix-loop.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/type-fix-loop.test.js +0 -116
- package/dist/src/pipeline/steps/type-fix-loop.test.js.map +0 -1
- package/dist/src/pipeline/steps/visual-test.d.ts +0 -3
- package/dist/src/pipeline/steps/visual-test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/visual-test.js +0 -4
- package/dist/src/pipeline/steps/visual-test.js.map +0 -1
- package/dist/src/pipeline/steps/visual-test.test.d.ts +0 -2
- package/dist/src/pipeline/steps/visual-test.test.d.ts.map +0 -1
- package/dist/src/pipeline/steps/visual-test.test.js +0 -9
- package/dist/src/pipeline/steps/visual-test.test.js.map +0 -1
- package/src/pipeline/steps/lint-fix-loop.test.ts +0 -176
- package/src/pipeline/steps/lint-fix-loop.ts +0 -61
- package/src/pipeline/steps/story-fix-loop.test.ts +0 -127
- package/src/pipeline/steps/story-fix-loop.ts +0 -48
- package/src/pipeline/steps/storybook-test.test.ts +0 -86
- package/src/pipeline/steps/storybook-test.ts +0 -27
- package/src/pipeline/steps/test-fix-loop.test.ts +0 -205
- package/src/pipeline/steps/test-fix-loop.ts +0 -57
- package/src/pipeline/steps/type-fix-loop.test.ts +0 -149
- package/src/pipeline/steps/type-fix-loop.ts +0 -56
- package/src/pipeline/steps/visual-test.test.ts +0 -10
- package/src/pipeline/steps/visual-test.ts +0 -5
package/package.json
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"ai": "^6.0.0",
|
|
8
8
|
"debug": "^4.4.1",
|
|
9
|
-
"@auto-engineer/message-bus": "1.
|
|
10
|
-
"@auto-engineer/model-factory": "1.
|
|
9
|
+
"@auto-engineer/message-bus": "1.109.0",
|
|
10
|
+
"@auto-engineer/model-factory": "1.109.0"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"vitest": "^3.2.1"
|
|
14
14
|
},
|
|
15
|
-
"version": "1.
|
|
15
|
+
"version": "1.109.0",
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
@@ -69,11 +69,6 @@ describe('implement-component', () => {
|
|
|
69
69
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
70
70
|
success: true,
|
|
71
71
|
llmCalls: 4,
|
|
72
|
-
fixIterations: 1,
|
|
73
|
-
typeFixIterations: 0,
|
|
74
|
-
testFixIterations: 0,
|
|
75
|
-
lintFixIterations: 0,
|
|
76
|
-
storyFixIterations: 0,
|
|
77
72
|
});
|
|
78
73
|
|
|
79
74
|
const result = await handleImplementComponent(makeCommand());
|
|
@@ -92,6 +87,9 @@ describe('implement-component', () => {
|
|
|
92
87
|
],
|
|
93
88
|
targetDir: '/project/client',
|
|
94
89
|
job: makeCommand().data.job,
|
|
90
|
+
llmCalls: expect.any(Number),
|
|
91
|
+
attemptNumber: 0,
|
|
92
|
+
intermediate: true,
|
|
95
93
|
},
|
|
96
94
|
timestamp: expect.any(Date),
|
|
97
95
|
requestId: 'req-1',
|
|
@@ -107,11 +105,6 @@ describe('implement-component', () => {
|
|
|
107
105
|
success: false,
|
|
108
106
|
error: 'Step "Type Fix Loop" failed: errors remain',
|
|
109
107
|
llmCalls: 5,
|
|
110
|
-
fixIterations: 3,
|
|
111
|
-
typeFixIterations: 0,
|
|
112
|
-
testFixIterations: 0,
|
|
113
|
-
lintFixIterations: 0,
|
|
114
|
-
storyFixIterations: 0,
|
|
115
108
|
});
|
|
116
109
|
|
|
117
110
|
const result = await handleImplementComponent(makeCommand());
|
|
@@ -134,11 +127,6 @@ describe('implement-component', () => {
|
|
|
134
127
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
135
128
|
success: true,
|
|
136
129
|
llmCalls: 3,
|
|
137
|
-
fixIterations: 0,
|
|
138
|
-
typeFixIterations: 0,
|
|
139
|
-
testFixIterations: 0,
|
|
140
|
-
lintFixIterations: 0,
|
|
141
|
-
storyFixIterations: 0,
|
|
142
130
|
});
|
|
143
131
|
|
|
144
132
|
const command = makeCommand({
|
|
@@ -195,11 +183,6 @@ describe('implement-component', () => {
|
|
|
195
183
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
196
184
|
success: true,
|
|
197
185
|
llmCalls: 4,
|
|
198
|
-
fixIterations: 1,
|
|
199
|
-
typeFixIterations: 0,
|
|
200
|
-
testFixIterations: 0,
|
|
201
|
-
lintFixIterations: 0,
|
|
202
|
-
storyFixIterations: 0,
|
|
203
186
|
});
|
|
204
187
|
|
|
205
188
|
const command = {
|
|
@@ -237,11 +220,6 @@ describe('implement-component', () => {
|
|
|
237
220
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
238
221
|
success: true,
|
|
239
222
|
llmCalls: 2,
|
|
240
|
-
fixIterations: 0,
|
|
241
|
-
typeFixIterations: 0,
|
|
242
|
-
testFixIterations: 0,
|
|
243
|
-
lintFixIterations: 0,
|
|
244
|
-
storyFixIterations: 0,
|
|
245
223
|
});
|
|
246
224
|
|
|
247
225
|
const command = {
|
|
@@ -283,11 +261,6 @@ describe('implement-component', () => {
|
|
|
283
261
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
284
262
|
success: true,
|
|
285
263
|
llmCalls: 4,
|
|
286
|
-
fixIterations: 0,
|
|
287
|
-
typeFixIterations: 0,
|
|
288
|
-
testFixIterations: 0,
|
|
289
|
-
lintFixIterations: 0,
|
|
290
|
-
storyFixIterations: 0,
|
|
291
264
|
});
|
|
292
265
|
|
|
293
266
|
const command = makeCommand({
|
|
@@ -323,6 +296,9 @@ describe('implement-component', () => {
|
|
|
323
296
|
]),
|
|
324
297
|
targetDir: '/project/client',
|
|
325
298
|
job: command.data.job,
|
|
299
|
+
llmCalls: expect.any(Number),
|
|
300
|
+
attemptNumber: 0,
|
|
301
|
+
intermediate: true,
|
|
326
302
|
},
|
|
327
303
|
timestamp: expect.any(Date),
|
|
328
304
|
requestId: 'req-1',
|
|
@@ -335,11 +311,6 @@ describe('implement-component', () => {
|
|
|
335
311
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
336
312
|
success: true,
|
|
337
313
|
llmCalls: 2,
|
|
338
|
-
fixIterations: 0,
|
|
339
|
-
typeFixIterations: 0,
|
|
340
|
-
testFixIterations: 0,
|
|
341
|
-
lintFixIterations: 0,
|
|
342
|
-
storyFixIterations: 0,
|
|
343
314
|
});
|
|
344
315
|
|
|
345
316
|
await handleImplementComponent(makeCommand());
|
|
@@ -360,7 +331,6 @@ describe('implement-component', () => {
|
|
|
360
331
|
},
|
|
361
332
|
isModify: false,
|
|
362
333
|
llmCalls: 0,
|
|
363
|
-
fixIterations: 0,
|
|
364
334
|
}),
|
|
365
335
|
);
|
|
366
336
|
});
|
|
@@ -377,11 +347,6 @@ describe('implement-component', () => {
|
|
|
377
347
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
378
348
|
success: true,
|
|
379
349
|
llmCalls: 0,
|
|
380
|
-
fixIterations: 0,
|
|
381
|
-
typeFixIterations: 0,
|
|
382
|
-
testFixIterations: 0,
|
|
383
|
-
lintFixIterations: 0,
|
|
384
|
-
storyFixIterations: 0,
|
|
385
350
|
});
|
|
386
351
|
|
|
387
352
|
const result = await commandHandler.handle(makeCommand());
|
|
@@ -396,11 +361,6 @@ describe('implement-component', () => {
|
|
|
396
361
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
397
362
|
success: true,
|
|
398
363
|
llmCalls: 0,
|
|
399
|
-
fixIterations: 0,
|
|
400
|
-
typeFixIterations: 0,
|
|
401
|
-
testFixIterations: 0,
|
|
402
|
-
lintFixIterations: 0,
|
|
403
|
-
storyFixIterations: 0,
|
|
404
364
|
});
|
|
405
365
|
|
|
406
366
|
const command = makeCommand({
|
|
@@ -439,11 +399,6 @@ describe('implement-component', () => {
|
|
|
439
399
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
440
400
|
success: true,
|
|
441
401
|
llmCalls: 1,
|
|
442
|
-
fixIterations: 0,
|
|
443
|
-
typeFixIterations: 0,
|
|
444
|
-
testFixIterations: 0,
|
|
445
|
-
lintFixIterations: 0,
|
|
446
|
-
storyFixIterations: 0,
|
|
447
402
|
});
|
|
448
403
|
|
|
449
404
|
const command = makeCommand({
|
|
@@ -481,11 +436,6 @@ describe('implement-component', () => {
|
|
|
481
436
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
482
437
|
success: true,
|
|
483
438
|
llmCalls: 1,
|
|
484
|
-
fixIterations: 0,
|
|
485
|
-
typeFixIterations: 0,
|
|
486
|
-
testFixIterations: 0,
|
|
487
|
-
lintFixIterations: 0,
|
|
488
|
-
storyFixIterations: 0,
|
|
489
439
|
});
|
|
490
440
|
|
|
491
441
|
const command = makeCommand({
|
|
@@ -522,11 +472,6 @@ describe('implement-component', () => {
|
|
|
522
472
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
523
473
|
success: false,
|
|
524
474
|
llmCalls: 0,
|
|
525
|
-
fixIterations: 0,
|
|
526
|
-
typeFixIterations: 0,
|
|
527
|
-
testFixIterations: 0,
|
|
528
|
-
lintFixIterations: 0,
|
|
529
|
-
storyFixIterations: 0,
|
|
530
475
|
});
|
|
531
476
|
|
|
532
477
|
const result = await handleImplementComponent(makeCommand());
|
|
@@ -566,11 +511,6 @@ describe('implement-component', () => {
|
|
|
566
511
|
vi.mocked(runPipeline).mockResolvedValue({
|
|
567
512
|
success: true,
|
|
568
513
|
llmCalls: 0,
|
|
569
|
-
fixIterations: 0,
|
|
570
|
-
typeFixIterations: 0,
|
|
571
|
-
testFixIterations: 0,
|
|
572
|
-
lintFixIterations: 0,
|
|
573
|
-
storyFixIterations: 0,
|
|
574
514
|
});
|
|
575
515
|
|
|
576
516
|
const command = makeCommand({
|
|
@@ -67,6 +67,9 @@ export type ComponentImplementedEvent = Event<
|
|
|
67
67
|
filesCreated: string[];
|
|
68
68
|
targetDir: string;
|
|
69
69
|
job: ComponentJob;
|
|
70
|
+
llmCalls: number;
|
|
71
|
+
attemptNumber: number;
|
|
72
|
+
intermediate?: boolean;
|
|
70
73
|
}
|
|
71
74
|
>;
|
|
72
75
|
|
|
@@ -130,37 +133,13 @@ function buildPipelineConfig(): PipelineConfig {
|
|
|
130
133
|
process.env.IMPL_MODEL ??
|
|
131
134
|
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL ??
|
|
132
135
|
'',
|
|
133
|
-
|
|
134
|
-
process.env.
|
|
135
|
-
process.env.IMPL_FIXER_MODEL ??
|
|
136
|
-
process.env.IMPL_MODEL ??
|
|
137
|
-
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL ??
|
|
138
|
-
'',
|
|
139
|
-
testFixer:
|
|
140
|
-
process.env.STEP_TEST_FIXER_MODEL ??
|
|
141
|
-
process.env.IMPL_FIXER_MODEL ??
|
|
142
|
-
process.env.IMPL_MODEL ??
|
|
143
|
-
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL ??
|
|
144
|
-
'',
|
|
145
|
-
lintFixer:
|
|
146
|
-
process.env.STEP_LINT_FIXER_MODEL ??
|
|
147
|
-
process.env.IMPL_FIXER_MODEL ??
|
|
148
|
-
process.env.IMPL_MODEL ??
|
|
149
|
-
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL ??
|
|
150
|
-
'',
|
|
151
|
-
storyFixer:
|
|
152
|
-
process.env.STEP_STORY_FIXER_MODEL ??
|
|
136
|
+
fixer:
|
|
137
|
+
process.env.STEP_FIXER_MODEL ??
|
|
153
138
|
process.env.IMPL_FIXER_MODEL ??
|
|
154
139
|
process.env.IMPL_MODEL ??
|
|
155
140
|
process.env.CUSTOM_PROVIDER_DEFAULT_MODEL ??
|
|
156
141
|
'',
|
|
157
142
|
},
|
|
158
|
-
maxTypeFixIterations: 3,
|
|
159
|
-
maxTestFixIterations: 3,
|
|
160
|
-
maxLintFixIterations: 2,
|
|
161
|
-
maxStoryFixIterations: 2,
|
|
162
|
-
enableStorybookTest: process.env.ENABLE_STORYBOOK_TEST === 'true',
|
|
163
|
-
enableVisualTest: process.env.ENABLE_VISUAL_TEST === 'true',
|
|
164
143
|
};
|
|
165
144
|
}
|
|
166
145
|
|
|
@@ -169,10 +148,7 @@ function createPipelineModels(): PipelineModels {
|
|
|
169
148
|
return {
|
|
170
149
|
generateTest: model,
|
|
171
150
|
generateComponent: model,
|
|
172
|
-
|
|
173
|
-
testFixer: model,
|
|
174
|
-
lintFixer: model,
|
|
175
|
-
storyFixer: model,
|
|
151
|
+
fixer: model,
|
|
176
152
|
};
|
|
177
153
|
}
|
|
178
154
|
|
|
@@ -209,6 +185,9 @@ export async function handleImplementComponent(
|
|
|
209
185
|
|
|
210
186
|
await mkdir(path.dirname(testPath), { recursive: true });
|
|
211
187
|
|
|
188
|
+
const attemptNumber = command.data.context?.attemptNumber ?? 0;
|
|
189
|
+
const errorFeedback = command.data.context?.previousOutputs;
|
|
190
|
+
|
|
212
191
|
const ctx: PipelineContext = {
|
|
213
192
|
componentName,
|
|
214
193
|
componentPath,
|
|
@@ -225,11 +204,8 @@ export async function handleImplementComponent(
|
|
|
225
204
|
isModify,
|
|
226
205
|
storyVariants: payload.storyVariants,
|
|
227
206
|
llmCalls: 0,
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
testFixIterations: 0,
|
|
231
|
-
lintFixIterations: 0,
|
|
232
|
-
storyFixIterations: 0,
|
|
207
|
+
errorFeedback,
|
|
208
|
+
attemptNumber,
|
|
233
209
|
};
|
|
234
210
|
|
|
235
211
|
const config = buildPipelineConfig();
|
|
@@ -240,12 +216,7 @@ export async function handleImplementComponent(
|
|
|
240
216
|
const result = await runPipeline(steps, ctx);
|
|
241
217
|
|
|
242
218
|
if (!result.success) {
|
|
243
|
-
debug(
|
|
244
|
-
'Pipeline failed: %s (LLM calls: %d, fix iterations: %d)',
|
|
245
|
-
result.error,
|
|
246
|
-
result.llmCalls,
|
|
247
|
-
result.fixIterations,
|
|
248
|
-
);
|
|
219
|
+
debug('Pipeline failed: %s (LLM calls: %d)', result.error, result.llmCalls);
|
|
249
220
|
return {
|
|
250
221
|
type: 'ComponentImplementationFailed',
|
|
251
222
|
data: { error: result.error ?? 'Pipeline failed', name: componentName },
|
|
@@ -255,12 +226,7 @@ export async function handleImplementComponent(
|
|
|
255
226
|
};
|
|
256
227
|
}
|
|
257
228
|
|
|
258
|
-
debug(
|
|
259
|
-
'Pipeline succeeded for %s (LLM calls: %d, fix iterations: %d)',
|
|
260
|
-
componentName,
|
|
261
|
-
result.llmCalls,
|
|
262
|
-
result.fixIterations,
|
|
263
|
-
);
|
|
229
|
+
debug('Pipeline succeeded for %s (LLM calls: %d)', componentName, result.llmCalls);
|
|
264
230
|
|
|
265
231
|
return {
|
|
266
232
|
type: 'ComponentImplemented',
|
|
@@ -272,6 +238,9 @@ export async function handleImplementComponent(
|
|
|
272
238
|
filesCreated: [testPath, componentPath, storyPath],
|
|
273
239
|
targetDir,
|
|
274
240
|
job,
|
|
241
|
+
llmCalls: result.llmCalls,
|
|
242
|
+
attemptNumber,
|
|
243
|
+
intermediate: true,
|
|
275
244
|
},
|
|
276
245
|
timestamp: new Date(),
|
|
277
246
|
requestId: command.requestId,
|
|
@@ -7,26 +7,11 @@ vi.mock('./steps/generate-test', () => ({
|
|
|
7
7
|
vi.mock('./steps/generate-component', () => ({
|
|
8
8
|
generateComponentStep: vi.fn(async () => ({ success: true })),
|
|
9
9
|
}));
|
|
10
|
-
vi.mock('./steps/type-fix-loop', () => ({
|
|
11
|
-
typeFixLoop: vi.fn(async () => ({ success: true })),
|
|
12
|
-
}));
|
|
13
|
-
vi.mock('./steps/test-fix-loop', () => ({
|
|
14
|
-
testFixLoop: vi.fn(async () => ({ success: true })),
|
|
15
|
-
}));
|
|
16
|
-
vi.mock('./steps/lint-fix-loop', () => ({
|
|
17
|
-
lintFixLoop: vi.fn(async () => ({ success: true })),
|
|
18
|
-
}));
|
|
19
10
|
vi.mock('./steps/generate-story', () => ({
|
|
20
11
|
generateStoryStep: vi.fn(async () => ({ success: true })),
|
|
21
12
|
}));
|
|
22
|
-
vi.mock('./steps/
|
|
23
|
-
|
|
24
|
-
}));
|
|
25
|
-
vi.mock('./steps/storybook-test', () => ({
|
|
26
|
-
storybookTestStep: vi.fn(async () => ({ success: true })),
|
|
27
|
-
}));
|
|
28
|
-
vi.mock('./steps/visual-test', () => ({
|
|
29
|
-
visualTestStep: vi.fn(async () => ({ success: true })),
|
|
13
|
+
vi.mock('./steps/fix-from-feedback', () => ({
|
|
14
|
+
fixFromFeedbackStep: vi.fn(async () => ({ success: true })),
|
|
30
15
|
}));
|
|
31
16
|
|
|
32
17
|
import {
|
|
@@ -37,15 +22,10 @@ import {
|
|
|
37
22
|
type PipelineStep,
|
|
38
23
|
runPipeline,
|
|
39
24
|
} from './run-pipeline';
|
|
25
|
+
import { fixFromFeedbackStep } from './steps/fix-from-feedback';
|
|
40
26
|
import { generateComponentStep } from './steps/generate-component';
|
|
41
27
|
import { generateStoryStep } from './steps/generate-story';
|
|
42
28
|
import { generateTestStep } from './steps/generate-test';
|
|
43
|
-
import { lintFixLoop } from './steps/lint-fix-loop';
|
|
44
|
-
import { storyFixLoop } from './steps/story-fix-loop';
|
|
45
|
-
import { storybookTestStep } from './steps/storybook-test';
|
|
46
|
-
import { testFixLoop } from './steps/test-fix-loop';
|
|
47
|
-
import { typeFixLoop } from './steps/type-fix-loop';
|
|
48
|
-
import { visualTestStep } from './steps/visual-test';
|
|
49
29
|
|
|
50
30
|
afterEach(() => {
|
|
51
31
|
vi.clearAllMocks();
|
|
@@ -64,19 +44,11 @@ function makeCtx(overrides: Partial<PipelineContext> = {}): PipelineContext {
|
|
|
64
44
|
composes: [],
|
|
65
45
|
isModify: false,
|
|
66
46
|
llmCalls: 0,
|
|
67
|
-
|
|
68
|
-
typeFixIterations: 0,
|
|
69
|
-
testFixIterations: 0,
|
|
70
|
-
lintFixIterations: 0,
|
|
71
|
-
storyFixIterations: 0,
|
|
47
|
+
attemptNumber: 0,
|
|
72
48
|
...overrides,
|
|
73
49
|
};
|
|
74
50
|
}
|
|
75
51
|
|
|
76
|
-
function successStep(name: string): PipelineStep {
|
|
77
|
-
return { name, run: async () => ({ success: true }) };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
52
|
function failStep(name: string, error: string): PipelineStep {
|
|
81
53
|
return { name, run: async () => ({ success: false, error }) };
|
|
82
54
|
}
|
|
@@ -113,11 +85,6 @@ describe('runPipeline', () => {
|
|
|
113
85
|
expect(result).toEqual({
|
|
114
86
|
success: true,
|
|
115
87
|
llmCalls: 0,
|
|
116
|
-
fixIterations: 0,
|
|
117
|
-
typeFixIterations: 0,
|
|
118
|
-
testFixIterations: 0,
|
|
119
|
-
lintFixIterations: 0,
|
|
120
|
-
storyFixIterations: 0,
|
|
121
88
|
});
|
|
122
89
|
expect(executionOrder).toEqual(['A', 'B', 'C']);
|
|
123
90
|
});
|
|
@@ -148,11 +115,6 @@ describe('runPipeline', () => {
|
|
|
148
115
|
success: false,
|
|
149
116
|
error: 'Step "Step B" failed: something broke',
|
|
150
117
|
llmCalls: 0,
|
|
151
|
-
fixIterations: 0,
|
|
152
|
-
typeFixIterations: 0,
|
|
153
|
-
testFixIterations: 0,
|
|
154
|
-
lintFixIterations: 0,
|
|
155
|
-
storyFixIterations: 0,
|
|
156
118
|
});
|
|
157
119
|
expect(executionOrder).toEqual(['A']);
|
|
158
120
|
});
|
|
@@ -163,34 +125,24 @@ describe('runPipeline', () => {
|
|
|
163
125
|
expect(result).toEqual({
|
|
164
126
|
success: true,
|
|
165
127
|
llmCalls: 0,
|
|
166
|
-
fixIterations: 0,
|
|
167
|
-
typeFixIterations: 0,
|
|
168
|
-
testFixIterations: 0,
|
|
169
|
-
lintFixIterations: 0,
|
|
170
|
-
storyFixIterations: 0,
|
|
171
128
|
});
|
|
172
129
|
});
|
|
173
130
|
|
|
174
|
-
it('reports accumulated llmCalls
|
|
131
|
+
it('reports accumulated llmCalls from context', async () => {
|
|
175
132
|
const steps: PipelineStep[] = [{ name: 'Step A', run: async () => ({ success: true }) }];
|
|
176
|
-
const ctx = makeCtx({ llmCalls: 5
|
|
133
|
+
const ctx = makeCtx({ llmCalls: 5 });
|
|
177
134
|
|
|
178
135
|
const result = await runPipeline(steps, ctx);
|
|
179
136
|
|
|
180
137
|
expect(result).toEqual({
|
|
181
138
|
success: true,
|
|
182
139
|
llmCalls: 5,
|
|
183
|
-
fixIterations: 3,
|
|
184
|
-
typeFixIterations: 0,
|
|
185
|
-
testFixIterations: 0,
|
|
186
|
-
lintFixIterations: 0,
|
|
187
|
-
storyFixIterations: 0,
|
|
188
140
|
});
|
|
189
141
|
});
|
|
190
142
|
|
|
191
143
|
it('reports context metrics on failure', async () => {
|
|
192
144
|
const steps: PipelineStep[] = [failStep('Broken', 'oops')];
|
|
193
|
-
const ctx = makeCtx({ llmCalls: 2
|
|
145
|
+
const ctx = makeCtx({ llmCalls: 2 });
|
|
194
146
|
|
|
195
147
|
const result = await runPipeline(steps, ctx);
|
|
196
148
|
|
|
@@ -198,11 +150,6 @@ describe('runPipeline', () => {
|
|
|
198
150
|
success: false,
|
|
199
151
|
error: 'Step "Broken" failed: oops',
|
|
200
152
|
llmCalls: 2,
|
|
201
|
-
fixIterations: 1,
|
|
202
|
-
typeFixIterations: 0,
|
|
203
|
-
testFixIterations: 0,
|
|
204
|
-
lintFixIterations: 0,
|
|
205
|
-
storyFixIterations: 0,
|
|
206
153
|
});
|
|
207
154
|
});
|
|
208
155
|
});
|
|
@@ -213,101 +160,37 @@ function makeModels(): PipelineModels {
|
|
|
213
160
|
return {
|
|
214
161
|
generateTest: fakeModel,
|
|
215
162
|
generateComponent: fakeModel,
|
|
216
|
-
|
|
217
|
-
testFixer: fakeModel,
|
|
218
|
-
lintFixer: fakeModel,
|
|
219
|
-
storyFixer: fakeModel,
|
|
163
|
+
fixer: fakeModel,
|
|
220
164
|
};
|
|
221
165
|
}
|
|
222
166
|
|
|
223
|
-
function makeConfig(
|
|
167
|
+
function makeConfig(): PipelineConfig {
|
|
224
168
|
return {
|
|
225
169
|
models: {
|
|
226
170
|
generateTest: '',
|
|
227
171
|
generateComponent: '',
|
|
228
|
-
|
|
229
|
-
testFixer: '',
|
|
230
|
-
lintFixer: '',
|
|
231
|
-
storyFixer: '',
|
|
172
|
+
fixer: '',
|
|
232
173
|
},
|
|
233
|
-
maxTypeFixIterations: 3,
|
|
234
|
-
maxTestFixIterations: 3,
|
|
235
|
-
maxLintFixIterations: 2,
|
|
236
|
-
maxStoryFixIterations: 2,
|
|
237
|
-
enableStorybookTest: false,
|
|
238
|
-
enableVisualTest: false,
|
|
239
|
-
...overrides,
|
|
240
174
|
};
|
|
241
175
|
}
|
|
242
176
|
|
|
243
177
|
describe('buildPipelineSteps', () => {
|
|
244
|
-
it('returns
|
|
178
|
+
it('returns 3 core steps for first attempt', () => {
|
|
245
179
|
const steps = buildPipelineSteps(makeModels(), makeConfig(), makeCtx());
|
|
246
180
|
|
|
247
|
-
expect(steps.map((s) => s.name)).toEqual([
|
|
248
|
-
'Generate Test',
|
|
249
|
-
'Generate Component',
|
|
250
|
-
'Type Fix Loop',
|
|
251
|
-
'Test Fix Loop',
|
|
252
|
-
'Lint Fix Loop',
|
|
253
|
-
'Generate Story',
|
|
254
|
-
'Story Fix Loop',
|
|
255
|
-
]);
|
|
181
|
+
expect(steps.map((s) => s.name)).toEqual(['Generate Test', 'Generate Component', 'Generate Story']);
|
|
256
182
|
});
|
|
257
183
|
|
|
258
|
-
it('
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
expect(steps.map((s) => s.name)).toEqual([
|
|
262
|
-
'Generate Test',
|
|
263
|
-
'Generate Component',
|
|
264
|
-
'Type Fix Loop',
|
|
265
|
-
'Test Fix Loop',
|
|
266
|
-
'Lint Fix Loop',
|
|
267
|
-
'Generate Story',
|
|
268
|
-
'Story Fix Loop',
|
|
269
|
-
'Storybook Test',
|
|
270
|
-
]);
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('adds Visual Test step when enabled', () => {
|
|
274
|
-
const steps = buildPipelineSteps(makeModels(), makeConfig({ enableVisualTest: true }), makeCtx());
|
|
275
|
-
|
|
276
|
-
expect(steps.map((s) => s.name)).toEqual([
|
|
277
|
-
'Generate Test',
|
|
278
|
-
'Generate Component',
|
|
279
|
-
'Type Fix Loop',
|
|
280
|
-
'Test Fix Loop',
|
|
281
|
-
'Lint Fix Loop',
|
|
282
|
-
'Generate Story',
|
|
283
|
-
'Story Fix Loop',
|
|
284
|
-
'Visual Test',
|
|
285
|
-
]);
|
|
286
|
-
});
|
|
184
|
+
it('returns fix + story steps for retry attempt', () => {
|
|
185
|
+
const ctx = makeCtx({ attemptNumber: 1, errorFeedback: 'Test failed: expected X to equal Y' });
|
|
186
|
+
const steps = buildPipelineSteps(makeModels(), makeConfig(), ctx);
|
|
287
187
|
|
|
288
|
-
|
|
289
|
-
const steps = buildPipelineSteps(
|
|
290
|
-
makeModels(),
|
|
291
|
-
makeConfig({ enableStorybookTest: true, enableVisualTest: true }),
|
|
292
|
-
makeCtx(),
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
expect(steps.map((s) => s.name)).toEqual([
|
|
296
|
-
'Generate Test',
|
|
297
|
-
'Generate Component',
|
|
298
|
-
'Type Fix Loop',
|
|
299
|
-
'Test Fix Loop',
|
|
300
|
-
'Lint Fix Loop',
|
|
301
|
-
'Generate Story',
|
|
302
|
-
'Story Fix Loop',
|
|
303
|
-
'Storybook Test',
|
|
304
|
-
'Visual Test',
|
|
305
|
-
]);
|
|
188
|
+
expect(steps.map((s) => s.name)).toEqual(['Fix From Feedback', 'Generate Story']);
|
|
306
189
|
});
|
|
307
190
|
|
|
308
|
-
it('wires each step to its corresponding function', async () => {
|
|
191
|
+
it('wires each step to its corresponding function on first attempt', async () => {
|
|
309
192
|
const models = makeModels();
|
|
310
|
-
const config = makeConfig(
|
|
193
|
+
const config = makeConfig();
|
|
311
194
|
const ctx = makeCtx();
|
|
312
195
|
const steps = buildPipelineSteps(models, config, ctx);
|
|
313
196
|
|
|
@@ -317,12 +200,20 @@ describe('buildPipelineSteps', () => {
|
|
|
317
200
|
|
|
318
201
|
expect(generateTestStep).toHaveBeenCalledWith(models.generateTest, ctx);
|
|
319
202
|
expect(generateComponentStep).toHaveBeenCalledWith(models.generateComponent, ctx);
|
|
320
|
-
expect(typeFixLoop).toHaveBeenCalledWith(models.typeFixer, ctx, 3);
|
|
321
|
-
expect(testFixLoop).toHaveBeenCalledWith(models.testFixer, ctx, 3);
|
|
322
|
-
expect(lintFixLoop).toHaveBeenCalledWith(models.lintFixer, ctx, 2);
|
|
323
203
|
expect(generateStoryStep).toHaveBeenCalledWith(ctx);
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('wires fix step on retry attempt', async () => {
|
|
207
|
+
const models = makeModels();
|
|
208
|
+
const config = makeConfig();
|
|
209
|
+
const ctx = makeCtx({ attemptNumber: 1, errorFeedback: 'Some error' });
|
|
210
|
+
const steps = buildPipelineSteps(models, config, ctx);
|
|
211
|
+
|
|
212
|
+
for (const step of steps) {
|
|
213
|
+
await step.run();
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
expect(fixFromFeedbackStep).toHaveBeenCalledWith(models.fixer, ctx);
|
|
217
|
+
expect(generateStoryStep).toHaveBeenCalledWith(ctx);
|
|
327
218
|
});
|
|
328
219
|
});
|