@autobe/agent 0.5.2 → 0.7.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 +4 -4
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +5 -2
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/context/AutoBeContext.d.ts +2 -2
- package/lib/context/IAutoBeApplicationProps.d.ts +6 -0
- package/lib/factory/createAgenticaHistory.js +1 -0
- package/lib/factory/createAgenticaHistory.js.map +1 -1
- package/lib/factory/createAutoBeApplication.js +17 -17
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +6228 -4563
- package/lib/index.mjs.map +1 -1
- package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeAgent.d.ts +4 -8
- package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeAgent.js +25 -20
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -0
- package/lib/orchestrate/analyze/AutoBeAnalyzeFileSystem.js.map +1 -0
- package/lib/orchestrate/analyze/AutoBeAnalyzePointer.d.ts +9 -0
- package/lib/orchestrate/analyze/AutoBeAnalyzePointer.js +3 -0
- package/lib/orchestrate/analyze/AutoBeAnalyzePointer.js.map +1 -0
- package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeReviewer.d.ts +1 -1
- package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeReviewer.js +8 -5
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js.map +1 -0
- package/lib/orchestrate/analyze/orchestrateAnalyze.d.ts +31 -0
- package/lib/orchestrate/{orchestrateAnalyze.js → analyze/orchestrateAnalyze.js} +200 -59
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -0
- package/lib/orchestrate/facade/transformFacadeStateMessage.js +1 -1
- package/lib/orchestrate/facade/transformFacadeStateMessage.js.map +1 -1
- package/lib/orchestrate/index.d.ts +3 -3
- package/lib/orchestrate/index.js +6 -6
- package/lib/orchestrate/index.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +8 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +6 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +3 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
- package/lib/orchestrate/interface/transformInterfaceHistories.js +41 -0
- package/lib/orchestrate/interface/transformInterfaceHistories.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js +6 -5
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.d.ts +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js +28 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaCorrectHistories.js +9 -0
- package/lib/orchestrate/prisma/transformPrismaCorrectHistories.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaHistories.js +9 -0
- package/lib/orchestrate/prisma/transformPrismaHistories.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js +7 -0
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js.map +1 -1
- package/lib/orchestrate/{orchestrateTest.d.ts → test/orchestrateTest.d.ts} +2 -2
- package/lib/orchestrate/test/orchestrateTest.js +70 -0
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.js +543 -0
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestProgress.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestProgress.js +403 -0
- package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTestScenario.d.ts +4 -0
- package/lib/orchestrate/test/orchestrateTestScenario.js +700 -0
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +2 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.js +47 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestHistories.d.ts +3 -0
- package/lib/orchestrate/test/transformTestHistories.js +74 -0
- package/lib/orchestrate/test/transformTestHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestProgressHistories.d.ts +2 -0
- package/lib/orchestrate/test/transformTestProgressHistories.js +47 -0
- package/lib/orchestrate/test/transformTestProgressHistories.js.map +1 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.d.ts +4 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.js +176 -0
- package/lib/orchestrate/test/transformTestScenarioHistories.js.map +1 -0
- package/lib/structures/IAutoBeVendor.d.ts +45 -2
- package/package.json +6 -6
- package/src/AutoBeAgent.ts +5 -3
- package/src/constants/AutoBeSystemPromptConstant.ts +5 -2
- package/src/context/AutoBeContext.ts +2 -2
- package/src/context/IAutoBeApplicationProps.ts +6 -0
- package/src/factory/createAgenticaHistory.ts +1 -0
- package/src/factory/createAutoBeApplication.ts +2 -2
- package/src/{analyze → orchestrate/analyze}/AutoBeAnalyzeAgent.ts +38 -36
- package/src/orchestrate/analyze/AutoBeAnalyzePointer.ts +10 -0
- package/src/{analyze → orchestrate/analyze}/AutoBeAnalyzeReviewer.ts +9 -6
- package/src/orchestrate/{orchestrateAnalyze.ts → analyze/orchestrateAnalyze.ts} +91 -39
- package/src/orchestrate/index.ts +3 -3
- package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +8 -1
- package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +6 -1
- package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +3 -1
- package/src/orchestrate/interface/transformInterfaceHistories.ts +40 -0
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +4 -1
- package/src/orchestrate/prisma/transformPrismaComponentsHistories.ts +28 -0
- package/src/orchestrate/prisma/transformPrismaCorrectHistories.ts +9 -0
- package/src/orchestrate/prisma/transformPrismaHistories.ts +9 -0
- package/src/orchestrate/prisma/transformPrismaSchemaHistories.ts +7 -0
- package/src/orchestrate/test/orchestrateTest.ts +86 -0
- package/src/orchestrate/test/orchestrateTestCorrect.ts +368 -0
- package/src/orchestrate/test/orchestrateTestProgress.ts +264 -0
- package/src/orchestrate/test/orchestrateTestScenario.ts +178 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +51 -0
- package/src/orchestrate/test/transformTestHistories.ts +77 -0
- package/src/orchestrate/test/transformTestProgressHistories.ts +51 -0
- package/src/orchestrate/test/transformTestScenarioHistories.ts +184 -0
- package/src/structures/IAutoBeVendor.ts +48 -2
- package/lib/analyze/AnalyzeAgent.d.ts +0 -24
- package/lib/analyze/AnalyzeAgent.js +0 -942
- package/lib/analyze/AnalyzeAgent.js.map +0 -1
- package/lib/analyze/AutoBeAnalyzeAgent.js.map +0 -1
- package/lib/analyze/AutoBeAnalyzeFileSystem.js.map +0 -1
- package/lib/analyze/AutoBeAnalyzeReviewer.js.map +0 -1
- package/lib/orchestrate/orchestrateAnalyze.d.ts +0 -6
- package/lib/orchestrate/orchestrateAnalyze.js.map +0 -1
- package/lib/orchestrate/orchestrateTest.js +0 -19
- package/lib/orchestrate/orchestrateTest.js.map +0 -1
- package/src/analyze/AnalyzeAgent.ts +0 -183
- package/src/orchestrate/orchestrateTest.ts +0 -18
- /package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeFileSystem.d.ts +0 -0
- /package/lib/{analyze → orchestrate/analyze}/AutoBeAnalyzeFileSystem.js +0 -0
- /package/src/{analyze → orchestrate/analyze}/AutoBeAnalyzeFileSystem.ts +0 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { IAgenticaController, MicroAgentica } from "@agentica/core";
|
|
2
|
+
import { AutoBeTest, AutoBeTestProgressEvent } from "@autobe/interface";
|
|
3
|
+
import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
|
|
4
|
+
import { IPointer } from "tstl";
|
|
5
|
+
import typia from "typia";
|
|
6
|
+
|
|
7
|
+
import { AutoBeContext } from "../../context/AutoBeContext";
|
|
8
|
+
import { assertSchemaModel } from "../../context/assertSchemaModel";
|
|
9
|
+
import { transformTestProgressHistories } from "./transformTestProgressHistories";
|
|
10
|
+
|
|
11
|
+
export async function orchestrateTestProgress<Model extends ILlmSchema.Model>(
|
|
12
|
+
ctx: AutoBeContext<Model>,
|
|
13
|
+
scenarios: AutoBeTest.Scenario[],
|
|
14
|
+
): Promise<AutoBeTestProgressEvent[]> {
|
|
15
|
+
const start: Date = new Date();
|
|
16
|
+
let complete: number = 0;
|
|
17
|
+
|
|
18
|
+
const events: AutoBeTestProgressEvent[] = await Promise.all(
|
|
19
|
+
/**
|
|
20
|
+
* Generate test code for each scenario. Maps through scenarios array to
|
|
21
|
+
* create individual test code implementations. Each scenario is processed
|
|
22
|
+
* to generate corresponding test code and progress events.
|
|
23
|
+
*/
|
|
24
|
+
scenarios.map(async (scenario) => {
|
|
25
|
+
const code: ICreateTestCodeProps = await process(ctx, scenario);
|
|
26
|
+
|
|
27
|
+
const event: AutoBeTestProgressEvent = {
|
|
28
|
+
type: "testProgress",
|
|
29
|
+
created_at: start.toISOString(),
|
|
30
|
+
filename: `${code.domain}/${scenario.functionName}.ts`,
|
|
31
|
+
content: code.content,
|
|
32
|
+
completed: ++complete,
|
|
33
|
+
total: scenarios.length,
|
|
34
|
+
step: ctx.state().interface?.step ?? 0,
|
|
35
|
+
};
|
|
36
|
+
ctx.dispatch(event);
|
|
37
|
+
return event;
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return events;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Process function that generates test code for each individual scenario. Takes
|
|
46
|
+
* the AutoBeContext and scenario information as input and uses MicroAgentica to
|
|
47
|
+
* generate appropriate test code through LLM interaction.
|
|
48
|
+
*
|
|
49
|
+
* @param ctx - The AutoBeContext containing model, vendor and configuration
|
|
50
|
+
* @param scenario - The test scenario information to generate code for
|
|
51
|
+
* @returns Promise resolving to ICreateTestCodeProps containing the generated
|
|
52
|
+
* test code
|
|
53
|
+
*/
|
|
54
|
+
async function process<Model extends ILlmSchema.Model>(
|
|
55
|
+
ctx: AutoBeContext<Model>,
|
|
56
|
+
scenario: AutoBeTest.Scenario,
|
|
57
|
+
): Promise<ICreateTestCodeProps> {
|
|
58
|
+
const pointer: IPointer<ICreateTestCodeProps | null> = {
|
|
59
|
+
value: null,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const apiFiles = Object.entries(ctx.state().interface?.files ?? {})
|
|
63
|
+
.filter(([filename]) => {
|
|
64
|
+
return filename.startsWith("src/api/");
|
|
65
|
+
})
|
|
66
|
+
.reduce<Record<string, string>>((acc, [filename, content]) => {
|
|
67
|
+
return Object.assign(acc, { [filename]: content });
|
|
68
|
+
}, {});
|
|
69
|
+
|
|
70
|
+
const dtoFiles = Object.entries(ctx.state().interface?.files ?? {})
|
|
71
|
+
.filter(([filename]) => {
|
|
72
|
+
return filename.startsWith("src/api/structures/");
|
|
73
|
+
})
|
|
74
|
+
.reduce<Record<string, string>>((acc, [filename, content]) => {
|
|
75
|
+
return Object.assign(acc, { [filename]: content });
|
|
76
|
+
}, {});
|
|
77
|
+
|
|
78
|
+
const agentica = new MicroAgentica({
|
|
79
|
+
model: ctx.model,
|
|
80
|
+
vendor: ctx.vendor,
|
|
81
|
+
config: {
|
|
82
|
+
...(ctx.config ?? {}),
|
|
83
|
+
},
|
|
84
|
+
histories: transformTestProgressHistories(apiFiles, dtoFiles),
|
|
85
|
+
controllers: [
|
|
86
|
+
createApplication({
|
|
87
|
+
model: ctx.model,
|
|
88
|
+
build: (next) => {
|
|
89
|
+
pointer.value = next;
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
],
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
agentica.on("request", async (event) => {
|
|
96
|
+
if (event.body.tools) event.body.tool_choice = "required";
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await agentica.conversate(
|
|
100
|
+
[
|
|
101
|
+
"Create test code for below scenario:",
|
|
102
|
+
"",
|
|
103
|
+
"```json",
|
|
104
|
+
JSON.stringify(scenario, null, 2),
|
|
105
|
+
"```",
|
|
106
|
+
].join("\n"),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (pointer.value === null) throw new Error("Failed to create test code.");
|
|
110
|
+
return pointer.value;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
114
|
+
model: Model;
|
|
115
|
+
build: (next: ICreateTestCodeProps) => void;
|
|
116
|
+
}): IAgenticaController.IClass<Model> {
|
|
117
|
+
assertSchemaModel(props.model);
|
|
118
|
+
|
|
119
|
+
const application: ILlmApplication<Model> = collection[
|
|
120
|
+
props.model
|
|
121
|
+
] as unknown as ILlmApplication<Model>;
|
|
122
|
+
return {
|
|
123
|
+
protocol: "class",
|
|
124
|
+
name: "Create Test Code",
|
|
125
|
+
application,
|
|
126
|
+
execute: {
|
|
127
|
+
createTestCode: (next) => {
|
|
128
|
+
props.build(next);
|
|
129
|
+
},
|
|
130
|
+
} satisfies IApplication,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const claude = typia.llm.application<
|
|
135
|
+
IApplication,
|
|
136
|
+
"claude",
|
|
137
|
+
{
|
|
138
|
+
reference: true;
|
|
139
|
+
}
|
|
140
|
+
>();
|
|
141
|
+
const collection = {
|
|
142
|
+
chatgpt: typia.llm.application<
|
|
143
|
+
IApplication,
|
|
144
|
+
"chatgpt",
|
|
145
|
+
{ reference: true }
|
|
146
|
+
>(),
|
|
147
|
+
claude,
|
|
148
|
+
llama: claude,
|
|
149
|
+
deepseek: claude,
|
|
150
|
+
"3.1": claude,
|
|
151
|
+
"3.0": typia.llm.application<IApplication, "3.0">(),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
interface IApplication {
|
|
155
|
+
createTestCode(props: ICreateTestCodeProps): void;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface ICreateTestCodeProps {
|
|
159
|
+
/**
|
|
160
|
+
* Strategic approach for test implementation.
|
|
161
|
+
*
|
|
162
|
+
* Define the high-level strategy and logical flow for testing the given
|
|
163
|
+
* scenario. Focus on test methodology, data preparation, and assertion
|
|
164
|
+
* strategy.
|
|
165
|
+
*
|
|
166
|
+
* ### Critical Requirements
|
|
167
|
+
*
|
|
168
|
+
* - Must follow the Test Generation Guildelines.
|
|
169
|
+
* - Must Planning the test code Never occur the typescript compile error.
|
|
170
|
+
*
|
|
171
|
+
* ### Planning Elements:
|
|
172
|
+
*
|
|
173
|
+
* #### Test Methodology
|
|
174
|
+
*
|
|
175
|
+
* - Identify test scenario type (CRUD operation, authentication flow,
|
|
176
|
+
* validation test)
|
|
177
|
+
* - Define test data requirements and preparation strategy
|
|
178
|
+
* - Plan positive/negative test cases and edge cases
|
|
179
|
+
* - Design assertion logic and validation points
|
|
180
|
+
*
|
|
181
|
+
* #### Execution Strategy
|
|
182
|
+
*
|
|
183
|
+
* - Outline step-by-step test execution flow
|
|
184
|
+
* - Plan error handling and exception scenarios
|
|
185
|
+
* - Define cleanup and teardown procedures
|
|
186
|
+
* - Identify dependencies and prerequisites
|
|
187
|
+
*
|
|
188
|
+
* ### Example Plan:
|
|
189
|
+
*
|
|
190
|
+
* Test Strategy: Article Creation Validation
|
|
191
|
+
* 1. Prepare valid article data with required fields
|
|
192
|
+
* 2. Execute POST request to create article
|
|
193
|
+
* 3. Validate response structure and data integrity
|
|
194
|
+
* 4. Test error scenarios (missing fields, invalid data)
|
|
195
|
+
* 5. Verify database state changes
|
|
196
|
+
* 6. Reconsider the plan if it doesn't follow the Test Generation
|
|
197
|
+
* Guildelines.
|
|
198
|
+
*/
|
|
199
|
+
plan: string;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Functional domain classification for test organization.
|
|
203
|
+
*
|
|
204
|
+
* Determines file structure and test categorization based on API
|
|
205
|
+
* functionality. Used for organizing tests into logical groups and directory
|
|
206
|
+
* hierarchies.
|
|
207
|
+
*
|
|
208
|
+
* ### Naming Rules:
|
|
209
|
+
*
|
|
210
|
+
* - Lowercase English words only
|
|
211
|
+
* - Singular nouns (e.g., "article", "user", "comment")
|
|
212
|
+
* - Kebab-case for compound words (e.g., "user-profile", "payment-method")
|
|
213
|
+
* - Match primary API resource being tested
|
|
214
|
+
* - Domain Name must be named only one word.
|
|
215
|
+
*
|
|
216
|
+
* ### Domain Examples:
|
|
217
|
+
*
|
|
218
|
+
* - `article` → Article management operations
|
|
219
|
+
* - `comment` → Comment-related functionality
|
|
220
|
+
* - `auth` → Authentication and authorization
|
|
221
|
+
* - `user` → User management operations
|
|
222
|
+
* - `payment` → Payment processing
|
|
223
|
+
* - `notification` → Notification system
|
|
224
|
+
*/
|
|
225
|
+
domain: string;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Complete TypeScript E2E test implementation.
|
|
229
|
+
*
|
|
230
|
+
* Generate fully functional, compilation-error-free test code following
|
|
231
|
+
*
|
|
232
|
+
* @nestia/e2e framework conventions and TypeScript best practices.
|
|
233
|
+
*
|
|
234
|
+
* ### Technical Implementation Requirements:
|
|
235
|
+
*
|
|
236
|
+
* #### Import Declarations
|
|
237
|
+
* ```typescript
|
|
238
|
+
* import api from "@ORGANIZATION/PROJECT-api";
|
|
239
|
+
* import { ITargetType } from "@ORGANIZATION/PROJECT-api/lib/structures/[path]";
|
|
240
|
+
* import { TestValidator } from "@nestia/e2e";
|
|
241
|
+
* import typia from "typia";
|
|
242
|
+
* ```
|
|
243
|
+
* - Must use exact `@ORGANIZATION/PROJECT-api` module path
|
|
244
|
+
* - Include `@ORGANIZATION` prefix in all API-related imports
|
|
245
|
+
* - Import specific DTO types from correct structure paths
|
|
246
|
+
*
|
|
247
|
+
* #### Code Quality Standards
|
|
248
|
+
* - Zero TypeScript compilation errors (mandatory)
|
|
249
|
+
* - Explicit type annotations for all variables
|
|
250
|
+
* - Proper async/await patterns throughout
|
|
251
|
+
* - Comprehensive error handling
|
|
252
|
+
* - Clean, readable code structure
|
|
253
|
+
* - Consistent formatting and naming conventions
|
|
254
|
+
*
|
|
255
|
+
* ### Critical Error Prevention
|
|
256
|
+
* - Verify all import paths are correct and accessible
|
|
257
|
+
* - Ensure type compatibility between variables and assignments
|
|
258
|
+
* - Include all required object properties and methods
|
|
259
|
+
* - Validate API function signatures and parameter types
|
|
260
|
+
* - Confirm proper generic type usage
|
|
261
|
+
* - Test async function declarations and Promise handling
|
|
262
|
+
*/
|
|
263
|
+
content: string;
|
|
264
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { IAgenticaController, MicroAgentica } from "@agentica/core";
|
|
2
|
+
import { AutoBeOpenApi, AutoBeTest } from "@autobe/interface";
|
|
3
|
+
import { AutoBeTestScenarioEvent } from "@autobe/interface/src/events/AutoBeTestScenarioEvent";
|
|
4
|
+
import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
|
|
5
|
+
import { IPointer } from "tstl";
|
|
6
|
+
import typia from "typia";
|
|
7
|
+
|
|
8
|
+
import { AutoBeContext } from "../../context/AutoBeContext";
|
|
9
|
+
import { assertSchemaModel } from "../../context/assertSchemaModel";
|
|
10
|
+
import { transformTestScenarioHistories } from "./transformTestScenarioHistories";
|
|
11
|
+
|
|
12
|
+
export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
|
|
13
|
+
ctx: AutoBeContext<Model>,
|
|
14
|
+
): Promise<AutoBeTestScenarioEvent> {
|
|
15
|
+
const files = Object.entries(ctx.state().interface?.files ?? {})
|
|
16
|
+
.filter(([filename]) => {
|
|
17
|
+
return filename.startsWith("test/features/api/");
|
|
18
|
+
})
|
|
19
|
+
.reduce<Record<string, string>>((acc, [filename, content]) => {
|
|
20
|
+
return Object.assign(acc, { [filename]: content });
|
|
21
|
+
}, {});
|
|
22
|
+
|
|
23
|
+
const operations = ctx.state().interface?.document.operations ?? [];
|
|
24
|
+
const endpoints: Omit<AutoBeOpenApi.IOperation, "specification">[] =
|
|
25
|
+
operations.map((it) => {
|
|
26
|
+
return {
|
|
27
|
+
method: it.method,
|
|
28
|
+
path: it.path,
|
|
29
|
+
summary: it.summary,
|
|
30
|
+
description: it.description,
|
|
31
|
+
parameters: it.parameters,
|
|
32
|
+
requestBody: it.requestBody,
|
|
33
|
+
responseBody: it.responseBody,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const start: Date = new Date();
|
|
38
|
+
|
|
39
|
+
let completed: number = 0;
|
|
40
|
+
|
|
41
|
+
const scenarios: AutoBeTest.IScenario[][] = await Promise.all(
|
|
42
|
+
endpoints.map(async (endpoint, i, arr) => {
|
|
43
|
+
const endponits = arr.filter((_el, j) => i !== j);
|
|
44
|
+
const rows: AutoBeTest.IScenario[] = await process(
|
|
45
|
+
ctx,
|
|
46
|
+
endpoint,
|
|
47
|
+
endponits,
|
|
48
|
+
files,
|
|
49
|
+
);
|
|
50
|
+
ctx.dispatch({
|
|
51
|
+
type: "testScenario",
|
|
52
|
+
scenarios: rows,
|
|
53
|
+
total: rows.flatMap((el) => el.scenarios).length,
|
|
54
|
+
step: ctx.state().test?.step ?? 0,
|
|
55
|
+
completed,
|
|
56
|
+
created_at: start.toISOString(),
|
|
57
|
+
});
|
|
58
|
+
return rows;
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
type: "testScenario",
|
|
64
|
+
scenarios: scenarios.flat(),
|
|
65
|
+
total: scenarios.flat().flatMap((el) => el.scenarios).length,
|
|
66
|
+
step: ctx.state().test?.step ?? 0,
|
|
67
|
+
completed,
|
|
68
|
+
created_at: start.toISOString(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function process<Model extends ILlmSchema.Model>(
|
|
73
|
+
ctx: AutoBeContext<Model>,
|
|
74
|
+
endpoint: AutoBeOpenApi.IEndpoint,
|
|
75
|
+
endpoints: AutoBeOpenApi.IEndpoint[],
|
|
76
|
+
files: Record<string, string>,
|
|
77
|
+
): Promise<AutoBeTest.IScenario[]> {
|
|
78
|
+
const pointer: IPointer<AutoBeTest.IScenario[] | null> = {
|
|
79
|
+
value: null,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const agentica = new MicroAgentica({
|
|
83
|
+
model: ctx.model,
|
|
84
|
+
vendor: ctx.vendor,
|
|
85
|
+
config: {
|
|
86
|
+
...(ctx.config ?? { locale: "en-US" }),
|
|
87
|
+
systemPrompt: {
|
|
88
|
+
describe: () => {
|
|
89
|
+
return "Answer only 'completion' or 'failure'.";
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
tokenUsage: ctx.usage(),
|
|
94
|
+
histories: [
|
|
95
|
+
...transformTestScenarioHistories(ctx.state(), endpoints, files),
|
|
96
|
+
],
|
|
97
|
+
controllers: [
|
|
98
|
+
createApplication({
|
|
99
|
+
model: ctx.model,
|
|
100
|
+
build: (next) => {
|
|
101
|
+
pointer.value = next.scenarios;
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
agentica.on("request", async (event) => {
|
|
108
|
+
if (event.body.tools) event.body.tool_choice = "required";
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await agentica.conversate(
|
|
112
|
+
[
|
|
113
|
+
"Make User Scenarios for below endpoint:",
|
|
114
|
+
"",
|
|
115
|
+
"```json",
|
|
116
|
+
JSON.stringify(endpoint, null, 2),
|
|
117
|
+
"```",
|
|
118
|
+
].join("\n"),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (pointer.value === null) throw new Error("Failed to make scenarios.");
|
|
122
|
+
return pointer.value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function createApplication<Model extends ILlmSchema.Model>(props: {
|
|
126
|
+
model: Model;
|
|
127
|
+
build: (next: IMakeScenarioProps) => void;
|
|
128
|
+
}): IAgenticaController.IClass<Model> {
|
|
129
|
+
assertSchemaModel(props.model);
|
|
130
|
+
|
|
131
|
+
const application: ILlmApplication<Model> = collection[
|
|
132
|
+
props.model
|
|
133
|
+
] as unknown as ILlmApplication<Model>;
|
|
134
|
+
return {
|
|
135
|
+
protocol: "class",
|
|
136
|
+
name: "Make User Scenarios",
|
|
137
|
+
application,
|
|
138
|
+
execute: {
|
|
139
|
+
makeScenario: (next) => {
|
|
140
|
+
props.build(next);
|
|
141
|
+
},
|
|
142
|
+
} satisfies IApplication,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const claude = typia.llm.application<
|
|
147
|
+
IApplication,
|
|
148
|
+
"claude",
|
|
149
|
+
{
|
|
150
|
+
reference: true;
|
|
151
|
+
}
|
|
152
|
+
>();
|
|
153
|
+
const collection = {
|
|
154
|
+
chatgpt: typia.llm.application<
|
|
155
|
+
IApplication,
|
|
156
|
+
"chatgpt",
|
|
157
|
+
{ reference: true }
|
|
158
|
+
>(),
|
|
159
|
+
claude,
|
|
160
|
+
llama: claude,
|
|
161
|
+
deepseek: claude,
|
|
162
|
+
"3.1": claude,
|
|
163
|
+
"3.0": typia.llm.application<IApplication, "3.0">(),
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
interface IApplication {
|
|
167
|
+
/**
|
|
168
|
+
* Make user scenarios for the given endpoints.
|
|
169
|
+
*
|
|
170
|
+
* @param props Properties containing the endpoints and user scenarios.
|
|
171
|
+
*/
|
|
172
|
+
makeScenario(props: IMakeScenarioProps): void;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface IMakeScenarioProps {
|
|
176
|
+
/** Array of user scenarios. */
|
|
177
|
+
scenarios: AutoBeTest.IScenario[];
|
|
178
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { IAgenticaHistoryJson } from "@agentica/core";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
|
|
4
|
+
import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
|
|
5
|
+
|
|
6
|
+
export const transformTestCorrectHistories = (
|
|
7
|
+
apiFiles: Record<string, string>,
|
|
8
|
+
dtoFiles: Record<string, string>,
|
|
9
|
+
): Array<
|
|
10
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
11
|
+
> => {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
id: v4(),
|
|
15
|
+
created_at: new Date().toISOString(),
|
|
16
|
+
type: "systemMessage",
|
|
17
|
+
text: AutoBeSystemPromptConstant.TEST_CORRECT,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: v4(),
|
|
21
|
+
created_at: new Date().toISOString(),
|
|
22
|
+
type: "assistantMessage",
|
|
23
|
+
text: [
|
|
24
|
+
"You are the world's best TypeScript compiler error fixer.",
|
|
25
|
+
"You will be given a **TypeScript code** with compilation errors, and your job is to fix the errors.",
|
|
26
|
+
"",
|
|
27
|
+
"## Rules",
|
|
28
|
+
"- Follow the base E2E test style strictly. Never use other frameworks like Jest or Mocha.",
|
|
29
|
+
"- Use `TestValidator.equals(...)` and `typia.assert(...)` to verify results.",
|
|
30
|
+
"- Use `api.functional.XXX` for all API calls. These are defined in API Files.",
|
|
31
|
+
"- Use helper functions like `generate_random_xxx(...)` **only if** they already exist in the base test imports.",
|
|
32
|
+
"- Do not invent new helpers or use utilities that are not explicitly shown.",
|
|
33
|
+
"- Keep all tests deterministic and reliable.",
|
|
34
|
+
"",
|
|
35
|
+
"## File References",
|
|
36
|
+
"### API Files",
|
|
37
|
+
"```typescript",
|
|
38
|
+
JSON.stringify(apiFiles, null, 2),
|
|
39
|
+
"```",
|
|
40
|
+
"",
|
|
41
|
+
"### DTO Files",
|
|
42
|
+
"```typescript",
|
|
43
|
+
JSON.stringify(dtoFiles, null, 2),
|
|
44
|
+
"```",
|
|
45
|
+
"",
|
|
46
|
+
"Now Fix the E2E test function based on the given error information.",
|
|
47
|
+
"Only output a single `async function` named `test_api_{...}`. No explanation, no commentary.",
|
|
48
|
+
].join("\n"),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { IAgenticaHistoryJson } from "@agentica/core";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
|
|
4
|
+
import { AutoBeState } from "../../context/AutoBeState";
|
|
5
|
+
|
|
6
|
+
export const transformTestHistories = (
|
|
7
|
+
state: AutoBeState,
|
|
8
|
+
): Array<
|
|
9
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
10
|
+
> => {
|
|
11
|
+
if (state.analyze === null)
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
id: v4(),
|
|
15
|
+
created_at: new Date().toISOString(),
|
|
16
|
+
type: "systemMessage",
|
|
17
|
+
text: [
|
|
18
|
+
"Requirement analysis is not yet completed.",
|
|
19
|
+
"Don't call the any tool function,",
|
|
20
|
+
"but say to process the requirement analysis.",
|
|
21
|
+
].join(" "),
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
else if (state.prisma === null)
|
|
25
|
+
return [
|
|
26
|
+
{
|
|
27
|
+
id: v4(),
|
|
28
|
+
created_at: new Date().toISOString(),
|
|
29
|
+
type: "systemMessage",
|
|
30
|
+
text: [
|
|
31
|
+
"Prisma DB schema generation is not yet completed.",
|
|
32
|
+
"Don't call the any tool function,",
|
|
33
|
+
"but say to process the Prisma DB schema generation.",
|
|
34
|
+
].join(" "),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
else if (state.analyze.step !== state.prisma.step)
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
id: v4(),
|
|
41
|
+
created_at: new Date().toISOString(),
|
|
42
|
+
type: "systemMessage",
|
|
43
|
+
text: [
|
|
44
|
+
"Prisma DB schema generation has not been updated",
|
|
45
|
+
"for the latest requirement analysis.",
|
|
46
|
+
"Don't call the any tool function,",
|
|
47
|
+
"but say to re-process the Prisma DB schema generation.",
|
|
48
|
+
].join(" "),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
else if (state.prisma.compiled.type !== "success")
|
|
52
|
+
return [
|
|
53
|
+
{
|
|
54
|
+
id: v4(),
|
|
55
|
+
created_at: new Date().toISOString(),
|
|
56
|
+
type: "systemMessage",
|
|
57
|
+
text: [
|
|
58
|
+
"Prisma DB schema generation has not been updated",
|
|
59
|
+
"for the latest requirement analysis.",
|
|
60
|
+
"Don't call the any tool function,",
|
|
61
|
+
"but say to re-process the Prisma DB schema generation.",
|
|
62
|
+
].join(" "),
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
id: v4(),
|
|
68
|
+
created_at: new Date().toISOString(),
|
|
69
|
+
type: "systemMessage",
|
|
70
|
+
text: [
|
|
71
|
+
"Interface generation is not yet completed.",
|
|
72
|
+
"Don't call the any tool function,",
|
|
73
|
+
"but say to process the interface generation.",
|
|
74
|
+
].join(" "),
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { IAgenticaHistoryJson } from "@agentica/core";
|
|
2
|
+
import { v4 } from "uuid";
|
|
3
|
+
|
|
4
|
+
import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
|
|
5
|
+
|
|
6
|
+
export const transformTestProgressHistories = (
|
|
7
|
+
apiFiles: Record<string, string>,
|
|
8
|
+
dtoFiles: Record<string, string>,
|
|
9
|
+
): Array<
|
|
10
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
11
|
+
> => {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
id: v4(),
|
|
15
|
+
created_at: new Date().toISOString(),
|
|
16
|
+
type: "systemMessage",
|
|
17
|
+
text: AutoBeSystemPromptConstant.TEST_PROGRESS,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: v4(),
|
|
21
|
+
created_at: new Date().toISOString(),
|
|
22
|
+
type: "assistantMessage",
|
|
23
|
+
text: [
|
|
24
|
+
"You are the world's best E2E test code generator.",
|
|
25
|
+
"You will be given a **scenario**, and your job is to generate the corresponding **E2E test code** using only the provided API functions and DTOs.",
|
|
26
|
+
"",
|
|
27
|
+
"## Rules",
|
|
28
|
+
"- Follow the base E2E test style strictly. Never use other frameworks like Jest or Mocha.",
|
|
29
|
+
"- Use `TestValidator.equals(...)` and `typia.assert(...)` to verify results.",
|
|
30
|
+
"- Use `HubApi.functional.XXX` for all API calls. These are defined in API Files.",
|
|
31
|
+
"- Use helper functions like `generate_random_xxx(...)` **only if** they already exist in the base test imports.",
|
|
32
|
+
"- Do not invent new helpers or use utilities that are not explicitly shown.",
|
|
33
|
+
"- Keep all tests deterministic and reliable.",
|
|
34
|
+
"",
|
|
35
|
+
"## File References",
|
|
36
|
+
"### API Files",
|
|
37
|
+
"```typescript",
|
|
38
|
+
JSON.stringify(apiFiles, null, 2),
|
|
39
|
+
"```",
|
|
40
|
+
"",
|
|
41
|
+
"### DTO Files",
|
|
42
|
+
"```typescript",
|
|
43
|
+
JSON.stringify(dtoFiles, null, 2),
|
|
44
|
+
"```",
|
|
45
|
+
"",
|
|
46
|
+
"Now generate the E2E test function based on the given scenario.",
|
|
47
|
+
"Only output a single `async function` named `test_api_{...}`. No explanation, no commentary.",
|
|
48
|
+
].join("\n"),
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
};
|