@autobe/agent 0.9.2 → 0.10.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/lib/AutoBeAgent.js +11 -4
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +6 -6
- package/lib/context/AutoBeTokenUsage.d.ts +15 -1
- package/lib/context/AutoBeTokenUsage.js +56 -1
- package/lib/context/AutoBeTokenUsage.js.map +1 -1
- package/lib/factory/createAutoBeApplication.js +288 -643
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +5057 -7211
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +82 -319
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js +0 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +95 -266
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/facade/transformFacadeStateMessage.js +2 -2
- package/lib/orchestrate/facade/transformFacadeStateMessage.js.map +1 -1
- package/lib/orchestrate/index.d.ts +2 -2
- package/lib/orchestrate/index.js +4 -4
- package/lib/orchestrate/index.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +56 -142
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +195 -199
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js +75 -172
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +772 -1097
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
- package/lib/orchestrate/interface/transformInterfaceHistories.js +2 -0
- package/lib/orchestrate/interface/transformInterfaceHistories.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js +64 -175
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +552 -1073
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js +571 -1119
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js +9 -0
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js +8 -0
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js.map +1 -1
- package/lib/orchestrate/realize/orchestrateRealize.d.ts +11 -0
- package/lib/orchestrate/realize/orchestrateRealize.js +109 -0
- package/lib/orchestrate/realize/orchestrateRealize.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.d.ts +25 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js +337 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizeIntegrator.d.ts +52 -0
- package/lib/orchestrate/realize/orchestrateRealizeIntegrator.js +57 -0
- package/lib/orchestrate/realize/orchestrateRealizeIntegrator.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.d.ts +80 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.js +53 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizeValidator.d.ts +46 -0
- package/lib/orchestrate/realize/orchestrateRealizeValidator.js +37 -0
- package/lib/orchestrate/realize/orchestrateRealizeValidator.js.map +1 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.d.ts +33 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js +3 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js.map +1 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.d.ts +5 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js +127 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js.map +1 -0
- package/lib/orchestrate/test/compile/completeTestCode.d.ts +2 -0
- package/lib/orchestrate/test/compile/completeTestCode.js +21 -0
- package/lib/orchestrate/test/compile/completeTestCode.js.map +1 -0
- package/lib/orchestrate/test/{filterTestFileName.js → compile/filterTestFileName.js} +1 -1
- package/lib/orchestrate/test/compile/filterTestFileName.js.map +1 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.d.ts +3 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.js +27 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.js.map +1 -0
- package/lib/orchestrate/test/compile/getTestScenarioArtifacts.d.ts +5 -0
- package/lib/orchestrate/test/{compileTestScenario.js → compile/getTestScenarioArtifacts.js} +10 -5
- package/lib/orchestrate/test/compile/getTestScenarioArtifacts.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTest.js +14 -9
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestCorrect.js +150 -448
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.js +272 -530
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestWrite.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestWrite.js +139 -90
- package/lib/orchestrate/test/orchestrateTestWrite.js.map +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.d.ts +121 -0
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestFunction.d.ts +8 -0
- package/lib/{utils/types/BackoffOptions.js → orchestrate/test/structures/IAutoBeTestFunction.js} +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestFunction.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +14 -2
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.d.ts +112 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.d.ts +7 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js.map +1 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +3 -2
- package/lib/orchestrate/test/transformTestCorrectHistories.js +28 -67
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestWriteHistories.d.ts +5 -4
- package/lib/orchestrate/test/transformTestWriteHistories.js +168 -43
- package/lib/orchestrate/test/transformTestWriteHistories.js.map +1 -1
- package/lib/structures/IAutoBeConfig.d.ts +11 -0
- package/lib/utils/backoffRetry.d.ts +4 -7
- package/lib/utils/backoffRetry.js +19 -37
- package/lib/utils/backoffRetry.js.map +1 -1
- package/lib/utils/forceRetry.d.ts +1 -0
- package/lib/{orchestrate/orchestrateRealize.js → utils/forceRetry.js} +15 -8
- package/lib/utils/forceRetry.js.map +1 -0
- package/package.json +8 -7
- package/src/AutoBeAgent.ts +17 -3
- package/src/constants/AutoBeSystemPromptConstant.ts +6 -6
- package/src/context/AutoBeTokenUsage.ts +85 -1
- package/src/factory/createAutoBeApplication.ts +2 -3
- package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +8 -3
- package/src/orchestrate/analyze/AutoBeAnalyzeReviewer.ts +0 -1
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +6 -5
- package/src/orchestrate/facade/transformFacadeStateMessage.ts +2 -1
- package/src/orchestrate/index.ts +2 -2
- package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +4 -3
- package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +26 -23
- package/src/orchestrate/interface/orchestrateInterfaceEndpoints.ts +6 -4
- package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +14 -11
- package/src/orchestrate/interface/transformInterfaceHistories.ts +2 -0
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +10 -5
- package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +11 -5
- package/src/orchestrate/prisma/orchestratePrismaSchema.ts +16 -8
- package/src/orchestrate/prisma/transformPrismaComponentsHistories.ts +9 -0
- package/src/orchestrate/prisma/transformPrismaSchemaHistories.ts +8 -0
- package/src/orchestrate/realize/orchestrateRealize.ts +169 -0
- package/src/orchestrate/realize/orchestrateRealizeCoder.ts +156 -0
- package/src/orchestrate/realize/orchestrateRealizeIntegrator.ts +75 -0
- package/src/orchestrate/realize/orchestrateRealizePlanner.ts +115 -0
- package/src/orchestrate/realize/orchestrateRealizeValidator.ts +64 -0
- package/src/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.ts +36 -0
- package/src/orchestrate/realize/transformRealizeCoderHistories.ts +136 -0
- package/src/orchestrate/test/compile/completeTestCode.ts +35 -0
- package/src/orchestrate/test/{filterTestFileName.ts → compile/filterTestFileName.ts} +1 -1
- package/src/orchestrate/test/compile/getTestExternalDeclarations.ts +24 -0
- package/src/orchestrate/test/{compileTestScenario.ts → compile/getTestScenarioArtifacts.ts} +16 -8
- package/src/orchestrate/test/experimental/orchestrateTestCorrect.ast +240 -0
- package/src/orchestrate/test/experimental/orchestrateTestWrite.ast +316 -0
- package/src/orchestrate/test/experimental/transformTestCorrectHistories.ast +52 -0
- package/src/orchestrate/test/orchestrateTest.ts +33 -16
- package/src/orchestrate/test/orchestrateTestCorrect.ts +109 -497
- package/src/orchestrate/test/orchestrateTestScenario.ts +102 -71
- package/src/orchestrate/test/orchestrateTestWrite.ts +55 -181
- package/src/orchestrate/test/structures/IAutoBeTestCorrectApplication.ts +126 -0
- package/src/orchestrate/test/structures/IAutoBeTestFunction.ts +10 -0
- package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +14 -2
- package/src/orchestrate/test/structures/IAutoBeTestWriteApplication.ts +117 -0
- package/src/orchestrate/test/structures/IAutoBeTestWriteResult.ts +9 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +38 -71
- package/src/orchestrate/test/transformTestWriteHistories.ts +88 -46
- package/src/structures/IAutoBeConfig.ts +9 -0
- package/src/utils/backoffRetry.ts +25 -36
- package/src/utils/forceRetry.ts +13 -0
- package/lib/factory/invertOpenApiDocument.d.ts +0 -3
- package/lib/factory/invertOpenApiDocument.js +0 -51
- package/lib/factory/invertOpenApiDocument.js.map +0 -1
- package/lib/orchestrate/orchestrateRealize.d.ts +0 -5
- package/lib/orchestrate/orchestrateRealize.js.map +0 -1
- package/lib/orchestrate/test/compileTestScenario.d.ts +0 -5
- package/lib/orchestrate/test/compileTestScenario.js.map +0 -1
- package/lib/orchestrate/test/filterTestFileName.js.map +0 -1
- package/lib/utils/StringUtil.d.ts +0 -4
- package/lib/utils/StringUtil.js +0 -43
- package/lib/utils/StringUtil.js.map +0 -1
- package/lib/utils/types/BackoffOptions.d.ts +0 -12
- package/lib/utils/types/BackoffOptions.js.map +0 -1
- package/src/factory/invertOpenApiDocument.ts +0 -63
- package/src/orchestrate/orchestrateRealize.ts +0 -18
- package/src/utils/StringUtil.ts +0 -45
- package/src/utils/types/BackoffOptions.ts +0 -15
- /package/lib/orchestrate/test/{filterTestFileName.d.ts → compile/filterTestFileName.d.ts} +0 -0
|
@@ -8,8 +8,9 @@ import {
|
|
|
8
8
|
AutoBeTestScenario,
|
|
9
9
|
AutoBeTestScenarioEvent,
|
|
10
10
|
} from "@autobe/interface";
|
|
11
|
+
import { AutoBeEndpointComparator } from "@autobe/utils";
|
|
11
12
|
import { ILlmApplication, ILlmSchema, IValidation } from "@samchon/openapi";
|
|
12
|
-
import { IPointer } from "tstl";
|
|
13
|
+
import { HashMap, IPointer, Pair } from "tstl";
|
|
13
14
|
import typia from "typia";
|
|
14
15
|
import { v4 } from "uuid";
|
|
15
16
|
|
|
@@ -18,37 +19,67 @@ import { AutoBeContext } from "../../context/AutoBeContext";
|
|
|
18
19
|
import { assertSchemaModel } from "../../context/assertSchemaModel";
|
|
19
20
|
import { divideArray } from "../../utils/divideArray";
|
|
20
21
|
import { enforceToolCall } from "../../utils/enforceToolCall";
|
|
22
|
+
import { forceRetry } from "../../utils/forceRetry";
|
|
21
23
|
import { IAutoBeTestScenarioApplication } from "./structures/IAutoBeTestScenarioApplication";
|
|
22
24
|
|
|
23
25
|
export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
24
26
|
ctx: AutoBeContext<Model>,
|
|
25
27
|
): Promise<AutoBeTestScenarioEvent> {
|
|
26
|
-
const operations
|
|
28
|
+
const operations: AutoBeOpenApi.IOperation[] =
|
|
29
|
+
ctx.state().interface?.document.operations ?? [];
|
|
27
30
|
if (operations.length === 0) {
|
|
28
31
|
throw new Error(
|
|
29
32
|
"Cannot write test scenarios because these are no operations.",
|
|
30
33
|
);
|
|
31
34
|
}
|
|
32
35
|
|
|
36
|
+
const dict: HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation> =
|
|
37
|
+
new HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation>(
|
|
38
|
+
operations.map(
|
|
39
|
+
(op) =>
|
|
40
|
+
new Pair(
|
|
41
|
+
{
|
|
42
|
+
path: op.path,
|
|
43
|
+
method: op.method,
|
|
44
|
+
},
|
|
45
|
+
op,
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
AutoBeEndpointComparator.hashCode,
|
|
49
|
+
AutoBeEndpointComparator.equals,
|
|
50
|
+
);
|
|
51
|
+
const endpointNotFound: string = [
|
|
52
|
+
`You have to select one of the endpoints below`,
|
|
53
|
+
"",
|
|
54
|
+
" method | path ",
|
|
55
|
+
"--------|------",
|
|
56
|
+
...operations.map((op) => `\`${op.method}\` | \`${op.path}\``).join("\n"),
|
|
57
|
+
].join("\n");
|
|
58
|
+
|
|
33
59
|
const exclude: IAutoBeTestScenarioApplication.IScenarioGroup[] = [];
|
|
34
60
|
let include: AutoBeOpenApi.IOperation[] = Array.from(operations);
|
|
35
61
|
|
|
36
62
|
do {
|
|
37
|
-
const matrix = divideArray({
|
|
38
|
-
|
|
63
|
+
const matrix: AutoBeOpenApi.IOperation[][] = divideArray({
|
|
64
|
+
array: include,
|
|
65
|
+
capacity: 5,
|
|
66
|
+
});
|
|
39
67
|
await Promise.all(
|
|
40
|
-
matrix.map(async (
|
|
68
|
+
matrix.map(async (include) => {
|
|
41
69
|
exclude.push(
|
|
42
|
-
...(await
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
...(await forceRetry(() =>
|
|
71
|
+
execute(
|
|
72
|
+
ctx,
|
|
73
|
+
dict,
|
|
74
|
+
endpointNotFound,
|
|
75
|
+
operations,
|
|
76
|
+
include,
|
|
77
|
+
exclude.map((x) => x.endpoint),
|
|
78
|
+
),
|
|
47
79
|
)),
|
|
48
80
|
);
|
|
49
81
|
}),
|
|
50
82
|
);
|
|
51
|
-
|
|
52
83
|
include = include.filter((op) => {
|
|
53
84
|
if (
|
|
54
85
|
exclude.some(
|
|
@@ -81,9 +112,11 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
|
81
112
|
|
|
82
113
|
const execute = async <Model extends ILlmSchema.Model>(
|
|
83
114
|
ctx: AutoBeContext<Model>,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
115
|
+
dict: HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation>,
|
|
116
|
+
endpointNotFound: string,
|
|
117
|
+
entire: AutoBeOpenApi.IOperation[],
|
|
118
|
+
include: AutoBeOpenApi.IEndpoint[],
|
|
119
|
+
exclude: AutoBeOpenApi.IEndpoint[],
|
|
87
120
|
) => {
|
|
88
121
|
const pointer: IPointer<IAutoBeTestScenarioApplication.IScenarioGroup[]> = {
|
|
89
122
|
value: [],
|
|
@@ -97,11 +130,12 @@ const execute = async <Model extends ILlmSchema.Model>(
|
|
|
97
130
|
describe: null,
|
|
98
131
|
},
|
|
99
132
|
},
|
|
100
|
-
|
|
101
|
-
histories: createHistoryProperties(ops, include, exclude),
|
|
133
|
+
histories: createHistoryProperties(entire, include, exclude),
|
|
102
134
|
controllers: [
|
|
103
135
|
createApplication({
|
|
104
136
|
model: ctx.model,
|
|
137
|
+
endpointNotFound,
|
|
138
|
+
dict,
|
|
105
139
|
build: (next) => {
|
|
106
140
|
pointer.value ??= [];
|
|
107
141
|
pointer.value.push(...next.scenarioGroups);
|
|
@@ -111,7 +145,10 @@ const execute = async <Model extends ILlmSchema.Model>(
|
|
|
111
145
|
});
|
|
112
146
|
enforceToolCall(agentica);
|
|
113
147
|
|
|
114
|
-
await agentica.conversate(`create test scenarios.`)
|
|
148
|
+
await agentica.conversate(`create test scenarios.`).finally(() => {
|
|
149
|
+
const tokenUsage = agentica.getTokenUsage();
|
|
150
|
+
ctx.usage().record(tokenUsage, ["test"]);
|
|
151
|
+
});
|
|
115
152
|
if (pointer.value.length === 0) {
|
|
116
153
|
throw new Error("Failed to create test plans.");
|
|
117
154
|
}
|
|
@@ -120,7 +157,7 @@ const execute = async <Model extends ILlmSchema.Model>(
|
|
|
120
157
|
};
|
|
121
158
|
|
|
122
159
|
const createHistoryProperties = (
|
|
123
|
-
|
|
160
|
+
entire: AutoBeOpenApi.IOperation[],
|
|
124
161
|
include: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
|
|
125
162
|
exclude: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
|
|
126
163
|
): Array<
|
|
@@ -152,14 +189,9 @@ const createHistoryProperties = (
|
|
|
152
189
|
"",
|
|
153
190
|
"```json",
|
|
154
191
|
JSON.stringify(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
summary: el.summary,
|
|
159
|
-
description: el.description,
|
|
160
|
-
parameters: el.parameters,
|
|
161
|
-
requestBody: el.requestBody,
|
|
162
|
-
responseBody: el.responseBody,
|
|
192
|
+
entire.map((el) => ({
|
|
193
|
+
...el,
|
|
194
|
+
specification: undefined,
|
|
163
195
|
})),
|
|
164
196
|
),
|
|
165
197
|
"```",
|
|
@@ -188,6 +220,8 @@ const createHistoryProperties = (
|
|
|
188
220
|
|
|
189
221
|
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
190
222
|
model: Model;
|
|
223
|
+
endpointNotFound: string;
|
|
224
|
+
dict: HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation>;
|
|
191
225
|
build: (next: IAutoBeTestScenarioApplication.IProps) => void;
|
|
192
226
|
}): IAgenticaController.IClass<Model> {
|
|
193
227
|
assertSchemaModel(props.model);
|
|
@@ -201,55 +235,53 @@ function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
|
201
235
|
typia.validate<IAutoBeTestScenarioApplication.IProps>(next);
|
|
202
236
|
if (result.success === false) return result;
|
|
203
237
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
) {
|
|
219
|
-
errors.push({
|
|
220
|
-
path: `planGroups[${j}].path`,
|
|
221
|
-
expected: `planGroup's {method + path} cannot duplicated.`,
|
|
222
|
-
value: target.endpoint.path,
|
|
223
|
-
});
|
|
224
|
-
}
|
|
238
|
+
// merge to unique scenario groups
|
|
239
|
+
const scenarioGroups: IAutoBeTestScenarioApplication.IScenarioGroup[] = [];
|
|
240
|
+
result.data.scenarioGroups.forEach((sg) => {
|
|
241
|
+
const created = scenarioGroups.find(
|
|
242
|
+
(el) =>
|
|
243
|
+
el.endpoint.method === sg.endpoint.method &&
|
|
244
|
+
el.endpoint.path === sg.endpoint.path,
|
|
245
|
+
);
|
|
246
|
+
if (created) {
|
|
247
|
+
created.scenarios.push(...sg.scenarios);
|
|
248
|
+
} else {
|
|
249
|
+
scenarioGroups.push(sg);
|
|
250
|
+
}
|
|
251
|
+
});
|
|
225
252
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
253
|
+
// validate endpoints
|
|
254
|
+
const errors: IValidation.IError[] = [];
|
|
255
|
+
scenarioGroups.forEach((group, i) => {
|
|
256
|
+
if (props.dict.has(group.endpoint) === false)
|
|
257
|
+
errors.push({
|
|
258
|
+
value: group.endpoint,
|
|
259
|
+
path: `$input.scenarioGroups[${i}].endpoint`,
|
|
260
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
261
|
+
description: props.endpointNotFound,
|
|
262
|
+
});
|
|
263
|
+
group.scenarios.forEach((s, j) => {
|
|
264
|
+
s.dependencies.forEach((dep, k) => {
|
|
265
|
+
if (props.dict.has(dep.endpoint) === false)
|
|
233
266
|
errors.push({
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
267
|
+
value: dep.endpoint,
|
|
268
|
+
path: `$input.scenarioGroups[${i}].scenarios[${j}].dependencies[${k}].endpoint`,
|
|
269
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
270
|
+
description: props.endpointNotFound,
|
|
237
271
|
});
|
|
238
|
-
|
|
239
|
-
}
|
|
272
|
+
});
|
|
240
273
|
});
|
|
241
274
|
});
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return result;
|
|
275
|
+
return errors.length === 0
|
|
276
|
+
? {
|
|
277
|
+
success: true,
|
|
278
|
+
data: scenarioGroups,
|
|
279
|
+
}
|
|
280
|
+
: {
|
|
281
|
+
success: false,
|
|
282
|
+
data: scenarioGroups,
|
|
283
|
+
errors,
|
|
284
|
+
};
|
|
253
285
|
};
|
|
254
286
|
return {
|
|
255
287
|
protocol: "class",
|
|
@@ -280,5 +312,4 @@ const collection = {
|
|
|
280
312
|
llama: claude,
|
|
281
313
|
deepseek: claude,
|
|
282
314
|
"3.1": claude,
|
|
283
|
-
"3.0": typia.llm.application<IAutoBeTestScenarioApplication, "3.0">(),
|
|
284
315
|
};
|
|
@@ -7,40 +7,54 @@ import typia from "typia";
|
|
|
7
7
|
import { AutoBeContext } from "../../context/AutoBeContext";
|
|
8
8
|
import { assertSchemaModel } from "../../context/assertSchemaModel";
|
|
9
9
|
import { enforceToolCall } from "../../utils/enforceToolCall";
|
|
10
|
-
import {
|
|
10
|
+
import { forceRetry } from "../../utils/forceRetry";
|
|
11
|
+
import { completeTestCode } from "./compile/completeTestCode";
|
|
12
|
+
import { getTestScenarioArtifacts } from "./compile/getTestScenarioArtifacts";
|
|
11
13
|
import { IAutoBeTestScenarioArtifacts } from "./structures/IAutoBeTestScenarioArtifacts";
|
|
14
|
+
import { IAutoBeTestWriteApplication } from "./structures/IAutoBeTestWriteApplication";
|
|
15
|
+
import { IAutoBeTestWriteResult } from "./structures/IAutoBeTestWriteResult";
|
|
12
16
|
import { transformTestWriteHistories } from "./transformTestWriteHistories";
|
|
13
17
|
|
|
14
18
|
export async function orchestrateTestWrite<Model extends ILlmSchema.Model>(
|
|
15
19
|
ctx: AutoBeContext<Model>,
|
|
16
20
|
scenarios: AutoBeTestScenario[],
|
|
17
|
-
): Promise<
|
|
21
|
+
): Promise<IAutoBeTestWriteResult[]> {
|
|
18
22
|
const start: Date = new Date();
|
|
19
23
|
let complete: number = 0;
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
return Promise.all(
|
|
22
26
|
/**
|
|
23
27
|
* Generate test code for each scenario. Maps through plans array to create
|
|
24
28
|
* individual test code implementations. Each scenario is processed to
|
|
25
29
|
* generate corresponding test code and progress events.
|
|
26
30
|
*/
|
|
27
|
-
scenarios.map(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
scenarios.map((scenario) =>
|
|
32
|
+
forceRetry(async () => {
|
|
33
|
+
const artifacts: IAutoBeTestScenarioArtifacts =
|
|
34
|
+
await getTestScenarioArtifacts(ctx, scenario);
|
|
35
|
+
const result: IAutoBeTestWriteApplication.IProps = await process(
|
|
36
|
+
ctx,
|
|
37
|
+
scenario,
|
|
38
|
+
artifacts,
|
|
39
|
+
);
|
|
40
|
+
const event: AutoBeTestWriteEvent = {
|
|
41
|
+
type: "testWrite",
|
|
42
|
+
created_at: start.toISOString(),
|
|
43
|
+
location: `test/features/api/${result.domain}/${scenario.functionName}.ts`,
|
|
44
|
+
...result,
|
|
45
|
+
completed: ++complete,
|
|
46
|
+
total: scenarios.length,
|
|
47
|
+
step: ctx.state().interface?.step ?? 0,
|
|
48
|
+
};
|
|
49
|
+
ctx.dispatch(event);
|
|
50
|
+
return {
|
|
51
|
+
scenario,
|
|
52
|
+
artifacts,
|
|
53
|
+
event,
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
),
|
|
41
57
|
);
|
|
42
|
-
|
|
43
|
-
return events;
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
/**
|
|
@@ -50,80 +64,49 @@ export async function orchestrateTestWrite<Model extends ILlmSchema.Model>(
|
|
|
50
64
|
*
|
|
51
65
|
* @param ctx - The AutoBeContext containing model, vendor and configuration
|
|
52
66
|
* @param scenario - The test scenario information to generate code for
|
|
53
|
-
* @
|
|
54
|
-
*
|
|
67
|
+
* @param artifacts - The artifacts containing the reference files and schemas
|
|
68
|
+
* @returns Promise resolving to IAutoBeTestWriteApplication.IProps containing
|
|
69
|
+
* the generated test code
|
|
55
70
|
*/
|
|
56
71
|
async function process<Model extends ILlmSchema.Model>(
|
|
57
72
|
ctx: AutoBeContext<Model>,
|
|
58
73
|
scenario: AutoBeTestScenario,
|
|
59
|
-
|
|
60
|
-
|
|
74
|
+
artifacts: IAutoBeTestScenarioArtifacts,
|
|
75
|
+
): Promise<IAutoBeTestWriteApplication.IProps> {
|
|
76
|
+
const pointer: IPointer<IAutoBeTestWriteApplication.IProps | null> = {
|
|
61
77
|
value: null,
|
|
62
78
|
};
|
|
63
|
-
const
|
|
64
|
-
ctx,
|
|
65
|
-
scenario,
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
const agentica = new MicroAgentica({
|
|
79
|
+
const agentica: MicroAgentica<Model> = new MicroAgentica({
|
|
69
80
|
model: ctx.model,
|
|
70
81
|
vendor: ctx.vendor,
|
|
71
82
|
config: {
|
|
72
83
|
...(ctx.config ?? {}),
|
|
73
84
|
},
|
|
74
|
-
histories: transformTestWriteHistories(
|
|
75
|
-
scenario,
|
|
76
|
-
artifacts,
|
|
77
|
-
}),
|
|
85
|
+
histories: transformTestWriteHistories(scenario, artifacts),
|
|
78
86
|
controllers: [
|
|
79
87
|
createApplication({
|
|
80
88
|
model: ctx.model,
|
|
89
|
+
artifacts,
|
|
81
90
|
build: (next) => {
|
|
82
91
|
pointer.value = next;
|
|
83
92
|
},
|
|
84
93
|
}),
|
|
85
94
|
],
|
|
86
|
-
tokenUsage: ctx.usage(),
|
|
87
95
|
});
|
|
88
96
|
enforceToolCall(agentica);
|
|
89
97
|
|
|
90
|
-
await agentica.conversate("Create e2e test functions.")
|
|
98
|
+
await agentica.conversate("Create e2e test functions.").finally(() => {
|
|
99
|
+
const tokenUsage = agentica.getTokenUsage();
|
|
100
|
+
ctx.usage().record(tokenUsage, ["test"]);
|
|
101
|
+
});
|
|
91
102
|
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
|
-
|
|
121
103
|
return pointer.value;
|
|
122
104
|
}
|
|
123
105
|
|
|
124
106
|
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
125
107
|
model: Model;
|
|
126
|
-
|
|
108
|
+
artifacts: IAutoBeTestScenarioArtifacts;
|
|
109
|
+
build: (next: IAutoBeTestWriteApplication.IProps) => void;
|
|
127
110
|
}): IAgenticaController.IClass<Model> {
|
|
128
111
|
assertSchemaModel(props.model);
|
|
129
112
|
|
|
@@ -135,15 +118,17 @@ function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
|
135
118
|
name: "Create Test Code",
|
|
136
119
|
application,
|
|
137
120
|
execute: {
|
|
138
|
-
|
|
121
|
+
write: (next) => {
|
|
122
|
+
next.draft = completeTestCode(props.artifacts, next.draft);
|
|
123
|
+
next.final = completeTestCode(props.artifacts, next.final);
|
|
139
124
|
props.build(next);
|
|
140
125
|
},
|
|
141
|
-
} satisfies
|
|
126
|
+
} satisfies IAutoBeTestWriteApplication,
|
|
142
127
|
};
|
|
143
128
|
}
|
|
144
129
|
|
|
145
130
|
const claude = typia.llm.application<
|
|
146
|
-
|
|
131
|
+
IAutoBeTestWriteApplication,
|
|
147
132
|
"claude",
|
|
148
133
|
{
|
|
149
134
|
reference: true;
|
|
@@ -151,7 +136,7 @@ const claude = typia.llm.application<
|
|
|
151
136
|
>();
|
|
152
137
|
const collection = {
|
|
153
138
|
chatgpt: typia.llm.application<
|
|
154
|
-
|
|
139
|
+
IAutoBeTestWriteApplication,
|
|
155
140
|
"chatgpt",
|
|
156
141
|
{ reference: true }
|
|
157
142
|
>(),
|
|
@@ -159,116 +144,5 @@ const collection = {
|
|
|
159
144
|
llama: claude,
|
|
160
145
|
deepseek: claude,
|
|
161
146
|
"3.1": claude,
|
|
162
|
-
"3.0": typia.llm.application<
|
|
147
|
+
"3.0": typia.llm.application<IAutoBeTestWriteApplication, "3.0">(),
|
|
163
148
|
};
|
|
164
|
-
|
|
165
|
-
interface IApplication {
|
|
166
|
-
createTestCode(props: ICreateTestCodeProps): void;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
interface ICreateTestCodeProps {
|
|
170
|
-
/**
|
|
171
|
-
* Strategic approach for test implementation.
|
|
172
|
-
*
|
|
173
|
-
* Define the high-level strategy and logical flow for testing the given
|
|
174
|
-
* scenario. Focus on test methodology, data preparation, and assertion
|
|
175
|
-
* strategy.
|
|
176
|
-
*
|
|
177
|
-
* ### Critical Requirements
|
|
178
|
-
*
|
|
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.
|
|
182
|
-
*
|
|
183
|
-
* ### Planning Elements:
|
|
184
|
-
*
|
|
185
|
-
* #### Test Methodology
|
|
186
|
-
*
|
|
187
|
-
* - Identify test scenario type (CRUD operation, authentication flow,
|
|
188
|
-
* validation test)
|
|
189
|
-
* - Define test data requirements and preparation strategy
|
|
190
|
-
* - Plan positive/negative test cases and edge cases
|
|
191
|
-
* - Design assertion logic and validation points
|
|
192
|
-
*
|
|
193
|
-
* #### Execution Strategy
|
|
194
|
-
*
|
|
195
|
-
* - Outline step-by-step test execution flow
|
|
196
|
-
* - Plan error handling and exception plans
|
|
197
|
-
* - Define cleanup and teardown procedures
|
|
198
|
-
* - Identify dependencies and prerequisites
|
|
199
|
-
*
|
|
200
|
-
* ### Example Plan:
|
|
201
|
-
*
|
|
202
|
-
* Test Strategy: Article Creation Validation
|
|
203
|
-
* 1. Prepare valid article data with required fields
|
|
204
|
-
* 2. Execute POST request to create article
|
|
205
|
-
* 3. Validate response structure and data integrity
|
|
206
|
-
* 4. Test error plans (missing fields, invalid data)
|
|
207
|
-
* 5. Verify database state changes
|
|
208
|
-
* 6. Reconsider the scenario if it doesn't follow the Test Generation
|
|
209
|
-
* Guidelines.
|
|
210
|
-
*/
|
|
211
|
-
scenario: string;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Functional domain classification for test organization.
|
|
215
|
-
*
|
|
216
|
-
* Determines file structure and test categorization based on API
|
|
217
|
-
* functionality. Used for organizing tests into logical groups and directory
|
|
218
|
-
* hierarchies.
|
|
219
|
-
*
|
|
220
|
-
* ### Naming Rules:
|
|
221
|
-
*
|
|
222
|
-
* - Lowercase English words only
|
|
223
|
-
* - Singular nouns (e.g., "article", "user", "comment")
|
|
224
|
-
* - Kebab-case for compound words (e.g., "user-profile", "payment-method")
|
|
225
|
-
* - Match primary API resource being tested
|
|
226
|
-
* - Domain Name must be named only one word.
|
|
227
|
-
*
|
|
228
|
-
* ### Domain Examples:
|
|
229
|
-
*
|
|
230
|
-
* - `article` → Article management operations
|
|
231
|
-
* - `comment` → Comment-related functionality
|
|
232
|
-
* - `auth` → Authentication and authorization
|
|
233
|
-
* - `user` → User management operations
|
|
234
|
-
* - `payment` → Payment processing
|
|
235
|
-
* - `notification` → Notification system
|
|
236
|
-
*/
|
|
237
|
-
domain: string;
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Complete TypeScript E2E test implementation.
|
|
241
|
-
*
|
|
242
|
-
* Generate fully functional, compilation-error-free test code following
|
|
243
|
-
*
|
|
244
|
-
* @nestia/e2e framework conventions and TypeScript best practices.
|
|
245
|
-
*
|
|
246
|
-
* ### Technical Implementation Requirements:
|
|
247
|
-
*
|
|
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
|
|
256
|
-
*
|
|
257
|
-
* #### Code Quality Standards
|
|
258
|
-
* - Zero TypeScript compilation errors (mandatory)
|
|
259
|
-
* - Explicit type annotations for all variables
|
|
260
|
-
* - Proper async/await patterns throughout
|
|
261
|
-
* - Comprehensive error handling
|
|
262
|
-
* - Clean, readable code structure
|
|
263
|
-
* - Consistent formatting and naming conventions
|
|
264
|
-
*
|
|
265
|
-
* ### Critical Error Prevention
|
|
266
|
-
* - Verify all API function signatures and parameter types
|
|
267
|
-
* - Ensure type compatibility between variables and assignments
|
|
268
|
-
* - Include all required object properties and methods
|
|
269
|
-
* - Confirm proper generic type usage
|
|
270
|
-
* - Test async function declarations and Promise handling
|
|
271
|
-
* - NO IMPORT STATEMENTS ANYWHERE IN CODE
|
|
272
|
-
*/
|
|
273
|
-
content: string;
|
|
274
|
-
}
|