@autobe/agent 0.9.1 → 0.9.2
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/lib/AutoBeAgent.js +5 -1
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +5 -3
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/context/IAutoBeApplicationProps.d.ts +0 -61
- package/lib/factory/createAutoBeApplication.js +15 -135
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +247 -248
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +4 -30
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterface.js +9 -3
- package/lib/orchestrate/interface/orchestrateInterface.js.map +1 -1
- package/lib/orchestrate/test/compileTestScenario.js +1 -0
- package/lib/orchestrate/test/compileTestScenario.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.js +130 -31
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.js +98 -83
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestWrite.js +17 -3
- package/lib/orchestrate/test/orchestrateTestWrite.js.map +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +18 -20
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioArtifacts.d.ts +2 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +1 -1
- package/lib/orchestrate/test/transformTestCorrectHistories.js +32 -6
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestWriteHistories.js +13 -1
- package/lib/orchestrate/test/transformTestWriteHistories.js.map +1 -1
- package/lib/structures/IAutoBeProps.d.ts +12 -1
- package/package.json +4 -5
- package/src/AutoBeAgent.ts +9 -1
- package/src/constants/AutoBeSystemPromptConstant.ts +5 -3
- package/src/context/IAutoBeApplicationProps.ts +0 -62
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +4 -34
- package/src/orchestrate/interface/orchestrateInterface.ts +7 -0
- package/src/orchestrate/test/compileTestScenario.ts +1 -0
- package/src/orchestrate/test/orchestrateTest.ts +9 -4
- package/src/orchestrate/test/orchestrateTestCorrect.ts +197 -36
- package/src/orchestrate/test/orchestrateTestScenario.ts +17 -3
- package/src/orchestrate/test/orchestrateTestWrite.ts +43 -15
- package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +18 -20
- package/src/orchestrate/test/structures/IAutoBeTestScenarioArtifacts.ts +3 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +33 -5
- package/src/orchestrate/test/transformTestWriteHistories.ts +12 -0
- package/src/structures/IAutoBeProps.ts +17 -1
|
@@ -112,7 +112,12 @@ async function step<Model extends ILlmSchema.Model>(
|
|
|
112
112
|
// COMPILE TEST CODE
|
|
113
113
|
const result: IAutoBeTypeScriptCompilerResult =
|
|
114
114
|
await ctx.compiler.typescript.compile({
|
|
115
|
-
files:
|
|
115
|
+
files: {
|
|
116
|
+
...entireFiles,
|
|
117
|
+
...testFiles
|
|
118
|
+
.map((el) => ({ [el.location]: el.content }))
|
|
119
|
+
.reduce((acc, cur) => Object.assign(acc, cur), {}),
|
|
120
|
+
},
|
|
116
121
|
});
|
|
117
122
|
|
|
118
123
|
if (result.type === "success") {
|
|
@@ -213,14 +218,29 @@ async function step<Model extends ILlmSchema.Model>(
|
|
|
213
218
|
step: ctx.state().interface?.step ?? 0,
|
|
214
219
|
});
|
|
215
220
|
|
|
216
|
-
return {
|
|
221
|
+
return {
|
|
222
|
+
location: filename,
|
|
223
|
+
content: response.content,
|
|
224
|
+
scenario: scenario,
|
|
225
|
+
};
|
|
217
226
|
},
|
|
218
227
|
),
|
|
219
228
|
);
|
|
220
229
|
|
|
221
230
|
return step(
|
|
222
231
|
ctx,
|
|
223
|
-
entireFiles
|
|
232
|
+
Object.entries(entireFiles)
|
|
233
|
+
.map(([filename, content]) => {
|
|
234
|
+
const overwritten = validatedFiles.find(
|
|
235
|
+
(el) => el.location === filename,
|
|
236
|
+
);
|
|
237
|
+
return overwritten
|
|
238
|
+
? { [overwritten.location]: overwritten.content }
|
|
239
|
+
: {
|
|
240
|
+
[filename]: content,
|
|
241
|
+
};
|
|
242
|
+
})
|
|
243
|
+
.reduce((acc, cur) => Object.assign(acc, cur), {}),
|
|
224
244
|
testFiles.map((f) => {
|
|
225
245
|
const validated = validatedFiles.find((v) => v.location === f.location);
|
|
226
246
|
return validated ? validated : f;
|
|
@@ -253,13 +273,34 @@ async function process<Model extends ILlmSchema.Model>(
|
|
|
253
273
|
scenario,
|
|
254
274
|
);
|
|
255
275
|
|
|
276
|
+
const lines = code.split("\n").map((line, num, arr) => {
|
|
277
|
+
const start = arr
|
|
278
|
+
.slice(0, num)
|
|
279
|
+
.map((el) => el.length + 1)
|
|
280
|
+
.reduce((acc, cur) => acc + cur, 0);
|
|
281
|
+
return {
|
|
282
|
+
line: num + 1,
|
|
283
|
+
text: line,
|
|
284
|
+
start: start,
|
|
285
|
+
end: start + line.length + 1, // exclusive
|
|
286
|
+
};
|
|
287
|
+
});
|
|
288
|
+
|
|
256
289
|
const agentica = new MicroAgentica({
|
|
257
290
|
model: ctx.model,
|
|
258
291
|
vendor: { ...ctx.vendor },
|
|
259
292
|
config: {
|
|
260
293
|
...(ctx.config ?? {}),
|
|
261
294
|
},
|
|
262
|
-
histories: transformTestCorrectHistories(
|
|
295
|
+
histories: transformTestCorrectHistories(
|
|
296
|
+
code,
|
|
297
|
+
artifacts,
|
|
298
|
+
diagnostics.map((diagnostic) =>
|
|
299
|
+
diagnostic.start === undefined || diagnostic.length === undefined
|
|
300
|
+
? ""
|
|
301
|
+
: formatDiagnostic(code, lines, diagnostic),
|
|
302
|
+
),
|
|
303
|
+
),
|
|
263
304
|
controllers: [
|
|
264
305
|
createApplication({
|
|
265
306
|
model: ctx.model,
|
|
@@ -275,38 +316,7 @@ async function process<Model extends ILlmSchema.Model>(
|
|
|
275
316
|
await randomBackoffRetry(async () => {
|
|
276
317
|
await agentica.conversate(
|
|
277
318
|
[
|
|
278
|
-
"
|
|
279
|
-
"",
|
|
280
|
-
"## Original Code",
|
|
281
|
-
"```typescript",
|
|
282
|
-
code,
|
|
283
|
-
"```",
|
|
284
|
-
"",
|
|
285
|
-
diagnostics.map((diagnostic) => {
|
|
286
|
-
if (diagnostic.start === undefined || diagnostic.length === undefined)
|
|
287
|
-
return "";
|
|
288
|
-
|
|
289
|
-
const checkDtoRegexp = `Cannot find module '@ORGANIZATION/template-api/lib/structures/IBbsArticleComment' or its corresponding type declarations.`;
|
|
290
|
-
const [group] = [
|
|
291
|
-
...checkDtoRegexp.matchAll(
|
|
292
|
-
/Cannot find module '(.*lib\/structures\/.*)'/g,
|
|
293
|
-
),
|
|
294
|
-
];
|
|
295
|
-
|
|
296
|
-
const [_, filename] = group ?? [];
|
|
297
|
-
|
|
298
|
-
return [
|
|
299
|
-
"## Error Information",
|
|
300
|
-
`- Position: Characters ${diagnostic.start} to ${diagnostic.start + diagnostic.length}`,
|
|
301
|
-
`- Error Message: ${diagnostic.messageText}`,
|
|
302
|
-
`- Problematic Code: \`${code.substring(diagnostic.start, diagnostic.start + diagnostic.length)}\``,
|
|
303
|
-
filename
|
|
304
|
-
? `The type files located under **/lib/structures are declared in '@ORGANIZATION/PROJECT-api/lib/structures'.\n` +
|
|
305
|
-
`Note: '@ORGANIZATION/PROJECT-api' must be written exactly as is and should not be replaced.\n`
|
|
306
|
-
: "",
|
|
307
|
-
].join("\n");
|
|
308
|
-
}),
|
|
309
|
-
"## Instructions",
|
|
319
|
+
"# Instructions",
|
|
310
320
|
"1. Focus on the specific error location and message",
|
|
311
321
|
"2. Provide the corrected TypeScript code",
|
|
312
322
|
"3. Ensure the fix resolves the compilation error",
|
|
@@ -316,9 +326,160 @@ async function process<Model extends ILlmSchema.Model>(
|
|
|
316
326
|
);
|
|
317
327
|
});
|
|
318
328
|
if (pointer.value === null) throw new Error("Failed to modify test code.");
|
|
329
|
+
|
|
330
|
+
const typeReferences: string[] = Array.from(
|
|
331
|
+
new Set(
|
|
332
|
+
Object.keys(artifacts.document.components.schemas).map(
|
|
333
|
+
(key) => key.split(".")[0]!,
|
|
334
|
+
),
|
|
335
|
+
),
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
pointer.value.content = pointer.value.content
|
|
339
|
+
.replace(/^[ \t]*import\b[\s\S]*?;[ \t]*$/gm, "")
|
|
340
|
+
.trim();
|
|
341
|
+
pointer.value.content = [
|
|
342
|
+
`import { TestValidator } from "@nestia/e2e";`,
|
|
343
|
+
`import typia, { tags } from "typia";`,
|
|
344
|
+
"",
|
|
345
|
+
`import api from "@ORGANIZATION/PROJECT-api";`,
|
|
346
|
+
...typeReferences.map(
|
|
347
|
+
(ref) =>
|
|
348
|
+
`import type { ${ref} } from "@ORGANIZATION/PROJECT-api/lib/structures/${ref}";`,
|
|
349
|
+
),
|
|
350
|
+
"",
|
|
351
|
+
pointer.value.content,
|
|
352
|
+
].join("\n");
|
|
353
|
+
|
|
354
|
+
pointer.value.content = pointer.value.content.replaceAll(
|
|
355
|
+
'string & Format<"uuid">',
|
|
356
|
+
'string & tags.Format<"uuid">',
|
|
357
|
+
);
|
|
358
|
+
|
|
319
359
|
return pointer.value;
|
|
320
360
|
}
|
|
321
361
|
|
|
362
|
+
function formatDiagnostic(
|
|
363
|
+
code: string,
|
|
364
|
+
lines: {
|
|
365
|
+
line: number; // line number
|
|
366
|
+
text: string;
|
|
367
|
+
start: number;
|
|
368
|
+
end: number; // exclusive
|
|
369
|
+
}[],
|
|
370
|
+
diagnostic: IAutoBeTypeScriptCompilerResult.IDiagnostic,
|
|
371
|
+
): string {
|
|
372
|
+
const { start, length, messageText } = diagnostic;
|
|
373
|
+
const message = messageText;
|
|
374
|
+
if (typeof start === "number" && typeof length === "number") {
|
|
375
|
+
const end = start + length;
|
|
376
|
+
const problematicCode = code.substring(start, end);
|
|
377
|
+
const errorLine = lines.find((line) => line.end > start) ?? null;
|
|
378
|
+
const lineText = errorLine?.text ?? "";
|
|
379
|
+
|
|
380
|
+
const hints = getHints(message, lineText);
|
|
381
|
+
|
|
382
|
+
function createAdjustedArray(n: number): number[] {
|
|
383
|
+
let start = n - 2;
|
|
384
|
+
|
|
385
|
+
// 시작 값이 음수라면, 0부터 시작해서 5개의 숫자 생성
|
|
386
|
+
if (start < 0) {
|
|
387
|
+
start = 0;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return Array.from({ length: 5 }, (_, i) => start + i);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const errorLines = createAdjustedArray(errorLine?.line ?? 0);
|
|
394
|
+
|
|
395
|
+
const context = errorLines
|
|
396
|
+
.map((num) => {
|
|
397
|
+
if (num === errorLine?.line) {
|
|
398
|
+
if (lines[num - 1]) {
|
|
399
|
+
return `${lines[num - 1]?.text} // <- ERROR LINE (line:${num})`;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (lines[num - 1]) {
|
|
403
|
+
return lines[num - 1]?.text;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return null;
|
|
407
|
+
})
|
|
408
|
+
.filter((el) => el !== null);
|
|
409
|
+
|
|
410
|
+
return [
|
|
411
|
+
"## Error Information",
|
|
412
|
+
`- Position: Characters ${start} to ${end}`,
|
|
413
|
+
`- Error Message: ${message}`,
|
|
414
|
+
`- Error Lines: \n${
|
|
415
|
+
context.length
|
|
416
|
+
? [
|
|
417
|
+
"\t```ts", //
|
|
418
|
+
...context.map((el) => `\t${el}`),
|
|
419
|
+
"\t```",
|
|
420
|
+
].join("\n")
|
|
421
|
+
: "(none)"
|
|
422
|
+
}`,
|
|
423
|
+
`- Problematic Code: ${problematicCode.length > 0 ? `\`${problematicCode}\`` : "(none)"}`,
|
|
424
|
+
...hints.map((hint) => `- Hint: ${hint}`),
|
|
425
|
+
].join("\n");
|
|
426
|
+
}
|
|
427
|
+
return ["## Error Information", `- Error Message: ${message}`].join("\n");
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function getHints(message: string, lineText: string): string[] {
|
|
431
|
+
const isTestValidator = lineText.includes("TestValidator");
|
|
432
|
+
const isTypia =
|
|
433
|
+
message === "Cannot find name 'Format'. Did you mean 'FormData'?";
|
|
434
|
+
const isJest = message === "Cannot find name 'expect'.";
|
|
435
|
+
const isCurrying =
|
|
436
|
+
isTestValidator && message === "Expected 1 arguments, but got 2";
|
|
437
|
+
const isAssignability =
|
|
438
|
+
/Argument of type '([^']+)' is not assignable to parameter of type '([^']+)'/.test(
|
|
439
|
+
message,
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
const hints: string[] = [];
|
|
443
|
+
|
|
444
|
+
if (isTypia) {
|
|
445
|
+
hints.push(
|
|
446
|
+
"If you want to use typia tags, use `tags.Format` instead of `Format`.",
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (isJest) {
|
|
451
|
+
hints.push(
|
|
452
|
+
'Detected invalid `expect` usage. Use `TestValidator.equals("description")(expected)(actual)`.',
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (isCurrying) {
|
|
457
|
+
hints.push(
|
|
458
|
+
"`TestValidator.equals` is a curried function and must be called in **three steps**: `title → expected → actual`.",
|
|
459
|
+
);
|
|
460
|
+
} else if (isTestValidator) {
|
|
461
|
+
hints.push(
|
|
462
|
+
"The second argument `expected` must be assignable from the type of `actual`. Consider swapping the order if you get a type error.",
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (isAssignability && isTestValidator) {
|
|
467
|
+
const match = lineText
|
|
468
|
+
.trim()
|
|
469
|
+
.match(/TestValidator\.equals\("([^"]+)"\)\(([^)]+)\)\(([^)]+)\)/);
|
|
470
|
+
if (match) {
|
|
471
|
+
const [, title, expected, actual] = match;
|
|
472
|
+
if (actual.includes(expected)) {
|
|
473
|
+
hints.push(
|
|
474
|
+
`You can try rearranging the order like this: TestValidator.equals("${title}")(${actual})(${expected})`,
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return hints;
|
|
481
|
+
}
|
|
482
|
+
|
|
322
483
|
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
323
484
|
model: Model;
|
|
324
485
|
build: (next: ICorrectTestFunctionProps) => void;
|
|
@@ -34,7 +34,7 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
|
34
34
|
let include: AutoBeOpenApi.IOperation[] = Array.from(operations);
|
|
35
35
|
|
|
36
36
|
do {
|
|
37
|
-
const matrix = divideArray({ array: include, capacity:
|
|
37
|
+
const matrix = divideArray({ array: include, capacity: 5 });
|
|
38
38
|
|
|
39
39
|
await Promise.all(
|
|
40
40
|
matrix.map(async (_include) => {
|
|
@@ -71,7 +71,7 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
|
71
71
|
endpoint: pg.endpoint,
|
|
72
72
|
draft: plan.draft,
|
|
73
73
|
functionName: plan.functionName,
|
|
74
|
-
dependencies: plan.
|
|
74
|
+
dependencies: plan.dependencies,
|
|
75
75
|
} satisfies AutoBeTestScenario;
|
|
76
76
|
});
|
|
77
77
|
}),
|
|
@@ -123,7 +123,9 @@ const createHistoryProperties = (
|
|
|
123
123
|
operations: AutoBeOpenApi.IOperation[],
|
|
124
124
|
include: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
|
|
125
125
|
exclude: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
|
|
126
|
-
)
|
|
126
|
+
): Array<
|
|
127
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
128
|
+
> => [
|
|
127
129
|
{
|
|
128
130
|
id: v4(),
|
|
129
131
|
created_at: new Date().toISOString(),
|
|
@@ -135,17 +137,29 @@ const createHistoryProperties = (
|
|
|
135
137
|
created_at: new Date().toISOString(),
|
|
136
138
|
type: "systemMessage",
|
|
137
139
|
text: [
|
|
140
|
+
"# Operations",
|
|
138
141
|
"Below are the full operations. Please refer to this.",
|
|
139
142
|
"Your role is to draft all test cases for each given Operation.",
|
|
140
143
|
"It is also permissible to write multiple test codes on a single endpoint.",
|
|
141
144
|
"However, rather than meaningless tests, business logic tests should be written and an E2E test situation should be assumed.",
|
|
142
145
|
"",
|
|
146
|
+
"Please carefully analyze each operation to identify all dependencies required for testing.",
|
|
147
|
+
"For example, if you want to test liking and then deleting a post,",
|
|
148
|
+
"you might think to test post creation, liking, and unlike operations.",
|
|
149
|
+
"However, even if not explicitly mentioned, user registration and login are essential prerequisites.",
|
|
150
|
+
"Pay close attention to IDs and related values in the API,",
|
|
151
|
+
"and ensure you identify all dependencies between endpoints.",
|
|
152
|
+
"",
|
|
143
153
|
"```json",
|
|
144
154
|
JSON.stringify(
|
|
145
155
|
operations.map((el) => ({
|
|
146
156
|
path: el.path,
|
|
147
157
|
method: el.method,
|
|
148
158
|
summary: el.summary,
|
|
159
|
+
description: el.description,
|
|
160
|
+
parameters: el.parameters,
|
|
161
|
+
requestBody: el.requestBody,
|
|
162
|
+
responseBody: el.responseBody,
|
|
149
163
|
})),
|
|
150
164
|
),
|
|
151
165
|
"```",
|
|
@@ -89,6 +89,35 @@ async function process<Model extends ILlmSchema.Model>(
|
|
|
89
89
|
|
|
90
90
|
await agentica.conversate("Create e2e test functions.");
|
|
91
91
|
if (pointer.value === null) throw new Error("Failed to create test code.");
|
|
92
|
+
|
|
93
|
+
const typeReferences: string[] = Array.from(
|
|
94
|
+
new Set(
|
|
95
|
+
Object.keys(artifacts.document.components.schemas).map(
|
|
96
|
+
(key) => key.split(".")[0]!,
|
|
97
|
+
),
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
pointer.value.content = pointer.value.content
|
|
101
|
+
.replace(/^[ \t]*import\b[\s\S]*?;[ \t]*$/gm, "")
|
|
102
|
+
.trim();
|
|
103
|
+
pointer.value.content = [
|
|
104
|
+
`import { TestValidator } from "@nestia/e2e";`,
|
|
105
|
+
`import typia, { tags } from "typia";`,
|
|
106
|
+
"",
|
|
107
|
+
`import api from "@ORGANIZATION/PROJECT-api";`,
|
|
108
|
+
...typeReferences.map(
|
|
109
|
+
(ref) =>
|
|
110
|
+
`import type { ${ref} } from "@ORGANIZATION/PROJECT-api/lib/structures/${ref}";`,
|
|
111
|
+
),
|
|
112
|
+
"",
|
|
113
|
+
pointer.value.content,
|
|
114
|
+
].join("\n");
|
|
115
|
+
|
|
116
|
+
pointer.value.content = pointer.value.content.replaceAll(
|
|
117
|
+
'string & Format<"uuid">',
|
|
118
|
+
'string & tags.Format<"uuid">',
|
|
119
|
+
);
|
|
120
|
+
|
|
92
121
|
return pointer.value;
|
|
93
122
|
}
|
|
94
123
|
|
|
@@ -147,8 +176,9 @@ interface ICreateTestCodeProps {
|
|
|
147
176
|
*
|
|
148
177
|
* ### Critical Requirements
|
|
149
178
|
*
|
|
150
|
-
* - Must follow the Test Generation
|
|
151
|
-
* - Must Planning the test code Never occur the
|
|
179
|
+
* - Must follow the Test Generation Guidelines.
|
|
180
|
+
* - Must Planning the test code Never occur the TypeScript compile error.
|
|
181
|
+
* - NEVER include import statements in planning or implementation.
|
|
152
182
|
*
|
|
153
183
|
* ### Planning Elements:
|
|
154
184
|
*
|
|
@@ -176,7 +206,7 @@ interface ICreateTestCodeProps {
|
|
|
176
206
|
* 4. Test error plans (missing fields, invalid data)
|
|
177
207
|
* 5. Verify database state changes
|
|
178
208
|
* 6. Reconsider the scenario if it doesn't follow the Test Generation
|
|
179
|
-
*
|
|
209
|
+
* Guidelines.
|
|
180
210
|
*/
|
|
181
211
|
scenario: string;
|
|
182
212
|
|
|
@@ -215,16 +245,14 @@ interface ICreateTestCodeProps {
|
|
|
215
245
|
*
|
|
216
246
|
* ### Technical Implementation Requirements:
|
|
217
247
|
*
|
|
218
|
-
* ####
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* - Include `@ORGANIZATION` prefix in all API-related imports
|
|
227
|
-
* - Import specific DTO types from correct structure paths
|
|
248
|
+
* #### NO IMPORT DECLARATIONS
|
|
249
|
+
* - NEVER write any import statements
|
|
250
|
+
* - Start code directly with `export async function`
|
|
251
|
+
* - All dependencies assumed globally available:
|
|
252
|
+
* - `api` for SDK functions
|
|
253
|
+
* - `typia` for validation and random data
|
|
254
|
+
* - All DTO types (ITargetType, etc.)
|
|
255
|
+
* - `TestValidator` for assertions
|
|
228
256
|
*
|
|
229
257
|
* #### Code Quality Standards
|
|
230
258
|
* - Zero TypeScript compilation errors (mandatory)
|
|
@@ -235,12 +263,12 @@ interface ICreateTestCodeProps {
|
|
|
235
263
|
* - Consistent formatting and naming conventions
|
|
236
264
|
*
|
|
237
265
|
* ### Critical Error Prevention
|
|
238
|
-
* - Verify all
|
|
266
|
+
* - Verify all API function signatures and parameter types
|
|
239
267
|
* - Ensure type compatibility between variables and assignments
|
|
240
268
|
* - Include all required object properties and methods
|
|
241
|
-
* - Validate API function signatures and parameter types
|
|
242
269
|
* - Confirm proper generic type usage
|
|
243
270
|
* - Test async function declarations and Promise handling
|
|
271
|
+
* - NO IMPORT STATEMENTS ANYWHERE IN CODE
|
|
244
272
|
*/
|
|
245
273
|
content: string;
|
|
246
274
|
}
|
|
@@ -26,17 +26,9 @@ export namespace IAutoBeTestScenarioApplication {
|
|
|
26
26
|
/**
|
|
27
27
|
* Represents a test scenario for a single API operation.
|
|
28
28
|
*
|
|
29
|
-
* This interface
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* - `draft`: A free-form, human-readable test scenario description for the API
|
|
33
|
-
* endpoint.
|
|
34
|
-
* - `dependsOn`: A list of other API endpoints that must be invoked beforehand
|
|
35
|
-
* in order to prepare the context for this test. Each dependency includes
|
|
36
|
-
* the purpose of the dependency.
|
|
37
|
-
*
|
|
38
|
-
* This structure is intended to help organize test specifications for complex
|
|
39
|
-
* workflows and ensure that all prerequisites are explicitly declared.
|
|
29
|
+
* This interface defines a structured, user-centric test draft that includes
|
|
30
|
+
* a descriptive function name, a detailed scenario draft, and logical
|
|
31
|
+
* dependencies on other endpoints required for context or setup.
|
|
40
32
|
*/
|
|
41
33
|
export interface IScenario {
|
|
42
34
|
/**
|
|
@@ -44,7 +36,7 @@ export namespace IAutoBeTestScenarioApplication {
|
|
|
44
36
|
* be tested. This should include both successful and failure scenarios,
|
|
45
37
|
* business rule validations, edge cases, and any sequence of steps
|
|
46
38
|
* necessary to perform the test. A subsequent agent will use this draft to
|
|
47
|
-
* generate multiple test
|
|
39
|
+
* generate multiple concrete test cases.
|
|
48
40
|
*/
|
|
49
41
|
draft: string;
|
|
50
42
|
|
|
@@ -109,20 +101,26 @@ export namespace IAutoBeTestScenarioApplication {
|
|
|
109
101
|
functionName: string;
|
|
110
102
|
|
|
111
103
|
/**
|
|
112
|
-
* A list of other API endpoints that
|
|
113
|
-
*
|
|
114
|
-
*
|
|
104
|
+
* A list of other API endpoints that this scenario logically depends on.
|
|
105
|
+
*
|
|
106
|
+
* These dependencies represent context or prerequisite conditions, such as
|
|
107
|
+
* authentication, resource creation, or data setup, that are relevant to
|
|
108
|
+
* the test. This list is not a strict execution order — if ordering is
|
|
109
|
+
* important, it must be described explicitly in the `purpose`.
|
|
115
110
|
*/
|
|
116
|
-
|
|
111
|
+
dependencies: IDependencies[];
|
|
117
112
|
}
|
|
118
113
|
|
|
119
|
-
export interface
|
|
120
|
-
/** Target API endpoint that
|
|
114
|
+
export interface IDependencies {
|
|
115
|
+
/** Target API endpoint that this scenario depends on. */
|
|
121
116
|
endpoint: AutoBeOpenApi.IEndpoint;
|
|
122
117
|
|
|
123
118
|
/**
|
|
124
|
-
* A concise
|
|
125
|
-
*
|
|
119
|
+
* A concise explanation of why this API call is relevant or required for
|
|
120
|
+
* the main test scenario.
|
|
121
|
+
*
|
|
122
|
+
* This should describe the contextual or setup role of the dependency, such
|
|
123
|
+
* as creating necessary data or establishing user authentication.
|
|
126
124
|
*
|
|
127
125
|
* Example: "Creates a category so that a product can be linked to it during
|
|
128
126
|
* creation."
|
|
@@ -5,7 +5,9 @@ import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptCo
|
|
|
5
5
|
import { IAutoBeTestScenarioArtifacts } from "./structures/IAutoBeTestScenarioArtifacts";
|
|
6
6
|
|
|
7
7
|
export const transformTestCorrectHistories = (
|
|
8
|
+
code: string,
|
|
8
9
|
artifacts: IAutoBeTestScenarioArtifacts,
|
|
10
|
+
diagnostics: string[],
|
|
9
11
|
): Array<
|
|
10
12
|
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
11
13
|
> => {
|
|
@@ -14,17 +16,38 @@ export const transformTestCorrectHistories = (
|
|
|
14
16
|
id: v4(),
|
|
15
17
|
created_at: new Date().toISOString(),
|
|
16
18
|
type: "systemMessage",
|
|
17
|
-
text: AutoBeSystemPromptConstant.
|
|
19
|
+
text: AutoBeSystemPromptConstant.TEST_WRITE,
|
|
18
20
|
},
|
|
19
21
|
{
|
|
20
22
|
id: v4(),
|
|
21
23
|
created_at: new Date().toISOString(),
|
|
22
24
|
type: "assistantMessage",
|
|
25
|
+
text: [
|
|
26
|
+
"# Original Code",
|
|
27
|
+
"```typescript",
|
|
28
|
+
code,
|
|
29
|
+
"```",
|
|
30
|
+
"",
|
|
31
|
+
"# Compile Errors",
|
|
32
|
+
"Fix the compilation error in the provided code.",
|
|
33
|
+
...diagnostics,
|
|
34
|
+
].join("\n"),
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: v4(),
|
|
38
|
+
created_at: new Date().toISOString(),
|
|
39
|
+
type: "systemMessage",
|
|
40
|
+
text: AutoBeSystemPromptConstant.TEST_CORRECT,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: v4(),
|
|
44
|
+
created_at: new Date().toISOString(),
|
|
45
|
+
type: "systemMessage",
|
|
23
46
|
text: [
|
|
24
47
|
"You are the world's best TypeScript compiler error fixer.",
|
|
25
48
|
"You will be given a **TypeScript code** with compilation errors, and your job is to fix the errors.",
|
|
26
49
|
"",
|
|
27
|
-
"
|
|
50
|
+
"# Rules",
|
|
28
51
|
"- Follow the base E2E test style strictly. Never use other frameworks like Jest or Mocha.",
|
|
29
52
|
"- Use `TestValidator.equals(...)` and `typia.assert(...)` to verify results.",
|
|
30
53
|
"- Use `api.functional.XXX` for all API calls. These are defined in API Files.",
|
|
@@ -32,13 +55,18 @@ export const transformTestCorrectHistories = (
|
|
|
32
55
|
"- Do not invent new helpers or use utilities that are not explicitly shown.",
|
|
33
56
|
"- Keep all tests deterministic and reliable.",
|
|
34
57
|
"",
|
|
35
|
-
"
|
|
36
|
-
|
|
58
|
+
"# File References",
|
|
59
|
+
`The import statements are automatically inserted based on the AST, which provides all necessary types and SDKs required.`,
|
|
60
|
+
`Therefore, if an import is not automatically included,`,
|
|
61
|
+
`it means that the corresponding type or SDK is not available for use in the current test code.`,
|
|
62
|
+
`You must solve the issue using only the provided SDK and types.`,
|
|
63
|
+
"",
|
|
64
|
+
"## API Files",
|
|
37
65
|
"```typescript",
|
|
38
66
|
JSON.stringify(artifacts.sdk),
|
|
39
67
|
"```",
|
|
40
68
|
"",
|
|
41
|
-
"
|
|
69
|
+
"## DTO Files",
|
|
42
70
|
"```typescript",
|
|
43
71
|
JSON.stringify(artifacts.dto),
|
|
44
72
|
"```",
|
|
@@ -18,6 +18,18 @@ export const transformTestWriteHistories = (props: {
|
|
|
18
18
|
type: "systemMessage",
|
|
19
19
|
text: AutoBeSystemPromptConstant.TEST_WRITE,
|
|
20
20
|
},
|
|
21
|
+
{
|
|
22
|
+
id: v4(),
|
|
23
|
+
created_at: new Date().toISOString(),
|
|
24
|
+
type: "systemMessage",
|
|
25
|
+
text: AutoBeSystemPromptConstant.TEST_VALIDATOR,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: v4(),
|
|
29
|
+
created_at: new Date().toISOString(),
|
|
30
|
+
type: "systemMessage",
|
|
31
|
+
text: AutoBeSystemPromptConstant.TEST_TYPESCRIPT_SYNTAX,
|
|
32
|
+
},
|
|
21
33
|
{
|
|
22
34
|
id: v4(),
|
|
23
35
|
created_at: new Date().toISOString(),
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AutoBeHistory,
|
|
3
|
+
IAutoBeCompiler,
|
|
4
|
+
IAutoBeTokenUsageJson,
|
|
5
|
+
} from "@autobe/interface";
|
|
2
6
|
import { ILlmSchema } from "@samchon/openapi";
|
|
3
7
|
|
|
8
|
+
import { AutoBeTokenUsage } from "../context/AutoBeTokenUsage";
|
|
4
9
|
import { IAutoBeConfig } from "./IAutoBeConfig";
|
|
5
10
|
import { IAutoBeVendor } from "./IAutoBeVendor";
|
|
6
11
|
|
|
@@ -101,4 +106,15 @@ export interface IAutoBeProps<Model extends ILlmSchema.Model> {
|
|
|
101
106
|
* time-sensitive operations throughout the development process.
|
|
102
107
|
*/
|
|
103
108
|
config?: IAutoBeConfig | undefined;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Token usage information.
|
|
112
|
+
*
|
|
113
|
+
* You can start token usage tracing by assigning this property.
|
|
114
|
+
*
|
|
115
|
+
* If you assign {@link IAutoBeTokenUsageJson} value, the token usage tracing
|
|
116
|
+
* would be from the value. Otherwise you assign the {@link AutoBeTokenUsage}
|
|
117
|
+
* typed instance, the tracing would be binded to the instance.
|
|
118
|
+
*/
|
|
119
|
+
tokenUsage?: IAutoBeTokenUsageJson | AutoBeTokenUsage | undefined;
|
|
104
120
|
}
|