@autobe/agent 0.9.1 → 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 +16 -5
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +6 -4
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- 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/context/IAutoBeApplicationProps.d.ts +0 -61
- package/lib/factory/createAutoBeApplication.js +298 -773
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +5116 -7271
- 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 +97 -294
- 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/orchestrateInterface.js +9 -3
- package/lib/orchestrate/interface/orchestrateInterface.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} +11 -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 -349
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.js +323 -566
- 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 -76
- 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 +32 -22
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioArtifacts.d.ts +2 -0
- 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 -41
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestWriteHistories.d.ts +5 -4
- package/lib/orchestrate/test/transformTestWriteHistories.js +169 -32
- package/lib/orchestrate/test/transformTestWriteHistories.js.map +1 -1
- package/lib/structures/IAutoBeConfig.d.ts +11 -0
- package/lib/structures/IAutoBeProps.d.ts +12 -1
- 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 -8
- package/src/AutoBeAgent.ts +26 -4
- package/src/constants/AutoBeSystemPromptConstant.ts +6 -4
- package/src/context/AutoBeTokenUsage.ts +85 -1
- package/src/context/IAutoBeApplicationProps.ts +0 -62
- 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 +8 -37
- package/src/orchestrate/facade/transformFacadeStateMessage.ts +2 -1
- package/src/orchestrate/index.ts +2 -2
- package/src/orchestrate/interface/orchestrateInterface.ts +7 -0
- 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} +17 -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 +38 -16
- package/src/orchestrate/test/orchestrateTestCorrect.ts +111 -338
- package/src/orchestrate/test/orchestrateTestScenario.ts +114 -69
- package/src/orchestrate/test/orchestrateTestWrite.ts +55 -153
- 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 +32 -22
- package/src/orchestrate/test/structures/IAutoBeTestScenarioArtifacts.ts +3 -0
- 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 -43
- package/src/orchestrate/test/transformTestWriteHistories.ts +89 -35
- package/src/structures/IAutoBeConfig.ts +9 -0
- package/src/structures/IAutoBeProps.ts +17 -1
- 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(
|
|
@@ -71,7 +102,7 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
|
71
102
|
endpoint: pg.endpoint,
|
|
72
103
|
draft: plan.draft,
|
|
73
104
|
functionName: plan.functionName,
|
|
74
|
-
dependencies: plan.
|
|
105
|
+
dependencies: plan.dependencies,
|
|
75
106
|
} satisfies AutoBeTestScenario;
|
|
76
107
|
});
|
|
77
108
|
}),
|
|
@@ -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,10 +157,12 @@ 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<
|
|
164
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
165
|
+
> => [
|
|
127
166
|
{
|
|
128
167
|
id: v4(),
|
|
129
168
|
created_at: new Date().toISOString(),
|
|
@@ -135,17 +174,24 @@ const createHistoryProperties = (
|
|
|
135
174
|
created_at: new Date().toISOString(),
|
|
136
175
|
type: "systemMessage",
|
|
137
176
|
text: [
|
|
177
|
+
"# Operations",
|
|
138
178
|
"Below are the full operations. Please refer to this.",
|
|
139
179
|
"Your role is to draft all test cases for each given Operation.",
|
|
140
180
|
"It is also permissible to write multiple test codes on a single endpoint.",
|
|
141
181
|
"However, rather than meaningless tests, business logic tests should be written and an E2E test situation should be assumed.",
|
|
142
182
|
"",
|
|
183
|
+
"Please carefully analyze each operation to identify all dependencies required for testing.",
|
|
184
|
+
"For example, if you want to test liking and then deleting a post,",
|
|
185
|
+
"you might think to test post creation, liking, and unlike operations.",
|
|
186
|
+
"However, even if not explicitly mentioned, user registration and login are essential prerequisites.",
|
|
187
|
+
"Pay close attention to IDs and related values in the API,",
|
|
188
|
+
"and ensure you identify all dependencies between endpoints.",
|
|
189
|
+
"",
|
|
143
190
|
"```json",
|
|
144
191
|
JSON.stringify(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
summary: el.summary,
|
|
192
|
+
entire.map((el) => ({
|
|
193
|
+
...el,
|
|
194
|
+
specification: undefined,
|
|
149
195
|
})),
|
|
150
196
|
),
|
|
151
197
|
"```",
|
|
@@ -174,6 +220,8 @@ const createHistoryProperties = (
|
|
|
174
220
|
|
|
175
221
|
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
176
222
|
model: Model;
|
|
223
|
+
endpointNotFound: string;
|
|
224
|
+
dict: HashMap<AutoBeOpenApi.IEndpoint, AutoBeOpenApi.IOperation>;
|
|
177
225
|
build: (next: IAutoBeTestScenarioApplication.IProps) => void;
|
|
178
226
|
}): IAgenticaController.IClass<Model> {
|
|
179
227
|
assertSchemaModel(props.model);
|
|
@@ -187,55 +235,53 @@ function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
|
187
235
|
typia.validate<IAutoBeTestScenarioApplication.IProps>(next);
|
|
188
236
|
if (result.success === false) return result;
|
|
189
237
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
) {
|
|
205
|
-
errors.push({
|
|
206
|
-
path: `planGroups[${j}].path`,
|
|
207
|
-
expected: `planGroup's {method + path} cannot duplicated.`,
|
|
208
|
-
value: target.endpoint.path,
|
|
209
|
-
});
|
|
210
|
-
}
|
|
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
|
+
});
|
|
211
252
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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)
|
|
219
266
|
errors.push({
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
267
|
+
value: dep.endpoint,
|
|
268
|
+
path: `$input.scenarioGroups[${i}].scenarios[${j}].dependencies[${k}].endpoint`,
|
|
269
|
+
expected: "AutoBeOpenApi.IEndpoint",
|
|
270
|
+
description: props.endpointNotFound,
|
|
223
271
|
});
|
|
224
|
-
|
|
225
|
-
}
|
|
272
|
+
});
|
|
226
273
|
});
|
|
227
274
|
});
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
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
|
+
};
|
|
239
285
|
};
|
|
240
286
|
return {
|
|
241
287
|
protocol: "class",
|
|
@@ -266,5 +312,4 @@ const collection = {
|
|
|
266
312
|
llama: claude,
|
|
267
313
|
deepseek: claude,
|
|
268
314
|
"3.1": claude,
|
|
269
|
-
"3.0": typia.llm.application<IAutoBeTestScenarioApplication, "3.0">(),
|
|
270
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,51 +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
103
|
return pointer.value;
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
96
107
|
model: Model;
|
|
97
|
-
|
|
108
|
+
artifacts: IAutoBeTestScenarioArtifacts;
|
|
109
|
+
build: (next: IAutoBeTestWriteApplication.IProps) => void;
|
|
98
110
|
}): IAgenticaController.IClass<Model> {
|
|
99
111
|
assertSchemaModel(props.model);
|
|
100
112
|
|
|
@@ -106,15 +118,17 @@ function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
|
106
118
|
name: "Create Test Code",
|
|
107
119
|
application,
|
|
108
120
|
execute: {
|
|
109
|
-
|
|
121
|
+
write: (next) => {
|
|
122
|
+
next.draft = completeTestCode(props.artifacts, next.draft);
|
|
123
|
+
next.final = completeTestCode(props.artifacts, next.final);
|
|
110
124
|
props.build(next);
|
|
111
125
|
},
|
|
112
|
-
} satisfies
|
|
126
|
+
} satisfies IAutoBeTestWriteApplication,
|
|
113
127
|
};
|
|
114
128
|
}
|
|
115
129
|
|
|
116
130
|
const claude = typia.llm.application<
|
|
117
|
-
|
|
131
|
+
IAutoBeTestWriteApplication,
|
|
118
132
|
"claude",
|
|
119
133
|
{
|
|
120
134
|
reference: true;
|
|
@@ -122,7 +136,7 @@ const claude = typia.llm.application<
|
|
|
122
136
|
>();
|
|
123
137
|
const collection = {
|
|
124
138
|
chatgpt: typia.llm.application<
|
|
125
|
-
|
|
139
|
+
IAutoBeTestWriteApplication,
|
|
126
140
|
"chatgpt",
|
|
127
141
|
{ reference: true }
|
|
128
142
|
>(),
|
|
@@ -130,117 +144,5 @@ const collection = {
|
|
|
130
144
|
llama: claude,
|
|
131
145
|
deepseek: claude,
|
|
132
146
|
"3.1": claude,
|
|
133
|
-
"3.0": typia.llm.application<
|
|
147
|
+
"3.0": typia.llm.application<IAutoBeTestWriteApplication, "3.0">(),
|
|
134
148
|
};
|
|
135
|
-
|
|
136
|
-
interface IApplication {
|
|
137
|
-
createTestCode(props: ICreateTestCodeProps): void;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
interface ICreateTestCodeProps {
|
|
141
|
-
/**
|
|
142
|
-
* Strategic approach for test implementation.
|
|
143
|
-
*
|
|
144
|
-
* Define the high-level strategy and logical flow for testing the given
|
|
145
|
-
* scenario. Focus on test methodology, data preparation, and assertion
|
|
146
|
-
* strategy.
|
|
147
|
-
*
|
|
148
|
-
* ### Critical Requirements
|
|
149
|
-
*
|
|
150
|
-
* - Must follow the Test Generation Guildelines.
|
|
151
|
-
* - Must Planning the test code Never occur the typescript compile error.
|
|
152
|
-
*
|
|
153
|
-
* ### Planning Elements:
|
|
154
|
-
*
|
|
155
|
-
* #### Test Methodology
|
|
156
|
-
*
|
|
157
|
-
* - Identify test scenario type (CRUD operation, authentication flow,
|
|
158
|
-
* validation test)
|
|
159
|
-
* - Define test data requirements and preparation strategy
|
|
160
|
-
* - Plan positive/negative test cases and edge cases
|
|
161
|
-
* - Design assertion logic and validation points
|
|
162
|
-
*
|
|
163
|
-
* #### Execution Strategy
|
|
164
|
-
*
|
|
165
|
-
* - Outline step-by-step test execution flow
|
|
166
|
-
* - Plan error handling and exception plans
|
|
167
|
-
* - Define cleanup and teardown procedures
|
|
168
|
-
* - Identify dependencies and prerequisites
|
|
169
|
-
*
|
|
170
|
-
* ### Example Plan:
|
|
171
|
-
*
|
|
172
|
-
* Test Strategy: Article Creation Validation
|
|
173
|
-
* 1. Prepare valid article data with required fields
|
|
174
|
-
* 2. Execute POST request to create article
|
|
175
|
-
* 3. Validate response structure and data integrity
|
|
176
|
-
* 4. Test error plans (missing fields, invalid data)
|
|
177
|
-
* 5. Verify database state changes
|
|
178
|
-
* 6. Reconsider the scenario if it doesn't follow the Test Generation
|
|
179
|
-
* Guildelines.
|
|
180
|
-
*/
|
|
181
|
-
scenario: string;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Functional domain classification for test organization.
|
|
185
|
-
*
|
|
186
|
-
* Determines file structure and test categorization based on API
|
|
187
|
-
* functionality. Used for organizing tests into logical groups and directory
|
|
188
|
-
* hierarchies.
|
|
189
|
-
*
|
|
190
|
-
* ### Naming Rules:
|
|
191
|
-
*
|
|
192
|
-
* - Lowercase English words only
|
|
193
|
-
* - Singular nouns (e.g., "article", "user", "comment")
|
|
194
|
-
* - Kebab-case for compound words (e.g., "user-profile", "payment-method")
|
|
195
|
-
* - Match primary API resource being tested
|
|
196
|
-
* - Domain Name must be named only one word.
|
|
197
|
-
*
|
|
198
|
-
* ### Domain Examples:
|
|
199
|
-
*
|
|
200
|
-
* - `article` → Article management operations
|
|
201
|
-
* - `comment` → Comment-related functionality
|
|
202
|
-
* - `auth` → Authentication and authorization
|
|
203
|
-
* - `user` → User management operations
|
|
204
|
-
* - `payment` → Payment processing
|
|
205
|
-
* - `notification` → Notification system
|
|
206
|
-
*/
|
|
207
|
-
domain: string;
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Complete TypeScript E2E test implementation.
|
|
211
|
-
*
|
|
212
|
-
* Generate fully functional, compilation-error-free test code following
|
|
213
|
-
*
|
|
214
|
-
* @nestia/e2e framework conventions and TypeScript best practices.
|
|
215
|
-
*
|
|
216
|
-
* ### Technical Implementation Requirements:
|
|
217
|
-
*
|
|
218
|
-
* #### Import Declarations
|
|
219
|
-
* ```typescript
|
|
220
|
-
* import api from "@ORGANIZATION/PROJECT-api";
|
|
221
|
-
* import { ITargetType } from "@ORGANIZATION/PROJECT-api/lib/structures/[path]";
|
|
222
|
-
* import { TestValidator } from "@nestia/e2e";
|
|
223
|
-
* import typia from "typia";
|
|
224
|
-
* ```
|
|
225
|
-
* - Must use exact `@ORGANIZATION/PROJECT-api` module path
|
|
226
|
-
* - Include `@ORGANIZATION` prefix in all API-related imports
|
|
227
|
-
* - Import specific DTO types from correct structure paths
|
|
228
|
-
*
|
|
229
|
-
* #### Code Quality Standards
|
|
230
|
-
* - Zero TypeScript compilation errors (mandatory)
|
|
231
|
-
* - Explicit type annotations for all variables
|
|
232
|
-
* - Proper async/await patterns throughout
|
|
233
|
-
* - Comprehensive error handling
|
|
234
|
-
* - Clean, readable code structure
|
|
235
|
-
* - Consistent formatting and naming conventions
|
|
236
|
-
*
|
|
237
|
-
* ### Critical Error Prevention
|
|
238
|
-
* - Verify all import paths are correct and accessible
|
|
239
|
-
* - Ensure type compatibility between variables and assignments
|
|
240
|
-
* - Include all required object properties and methods
|
|
241
|
-
* - Validate API function signatures and parameter types
|
|
242
|
-
* - Confirm proper generic type usage
|
|
243
|
-
* - Test async function declarations and Promise handling
|
|
244
|
-
*/
|
|
245
|
-
content: string;
|
|
246
|
-
}
|