@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.
Files changed (175) hide show
  1. package/lib/AutoBeAgent.js +11 -4
  2. package/lib/AutoBeAgent.js.map +1 -1
  3. package/lib/constants/AutoBeSystemPromptConstant.d.ts +6 -6
  4. package/lib/context/AutoBeTokenUsage.d.ts +15 -1
  5. package/lib/context/AutoBeTokenUsage.js +56 -1
  6. package/lib/context/AutoBeTokenUsage.js.map +1 -1
  7. package/lib/factory/createAutoBeApplication.js +288 -643
  8. package/lib/factory/createAutoBeApplication.js.map +1 -1
  9. package/lib/index.mjs +5057 -7211
  10. package/lib/index.mjs.map +1 -1
  11. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +82 -319
  12. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
  13. package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js +0 -1
  14. package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js.map +1 -1
  15. package/lib/orchestrate/analyze/orchestrateAnalyze.js +95 -266
  16. package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
  17. package/lib/orchestrate/facade/transformFacadeStateMessage.js +2 -2
  18. package/lib/orchestrate/facade/transformFacadeStateMessage.js.map +1 -1
  19. package/lib/orchestrate/index.d.ts +2 -2
  20. package/lib/orchestrate/index.js +4 -4
  21. package/lib/orchestrate/index.js.map +1 -1
  22. package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +56 -142
  23. package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
  24. package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +195 -199
  25. package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
  26. package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js +75 -172
  27. package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js.map +1 -1
  28. package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +772 -1097
  29. package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
  30. package/lib/orchestrate/interface/transformInterfaceHistories.js +2 -0
  31. package/lib/orchestrate/interface/transformInterfaceHistories.js.map +1 -1
  32. package/lib/orchestrate/prisma/orchestratePrismaComponent.js +64 -175
  33. package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
  34. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +552 -1073
  35. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
  36. package/lib/orchestrate/prisma/orchestratePrismaSchema.js +571 -1119
  37. package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
  38. package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js +9 -0
  39. package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js.map +1 -1
  40. package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js +8 -0
  41. package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js.map +1 -1
  42. package/lib/orchestrate/realize/orchestrateRealize.d.ts +11 -0
  43. package/lib/orchestrate/realize/orchestrateRealize.js +109 -0
  44. package/lib/orchestrate/realize/orchestrateRealize.js.map +1 -0
  45. package/lib/orchestrate/realize/orchestrateRealizeCoder.d.ts +25 -0
  46. package/lib/orchestrate/realize/orchestrateRealizeCoder.js +337 -0
  47. package/lib/orchestrate/realize/orchestrateRealizeCoder.js.map +1 -0
  48. package/lib/orchestrate/realize/orchestrateRealizeIntegrator.d.ts +52 -0
  49. package/lib/orchestrate/realize/orchestrateRealizeIntegrator.js +57 -0
  50. package/lib/orchestrate/realize/orchestrateRealizeIntegrator.js.map +1 -0
  51. package/lib/orchestrate/realize/orchestrateRealizePlanner.d.ts +80 -0
  52. package/lib/orchestrate/realize/orchestrateRealizePlanner.js +53 -0
  53. package/lib/orchestrate/realize/orchestrateRealizePlanner.js.map +1 -0
  54. package/lib/orchestrate/realize/orchestrateRealizeValidator.d.ts +46 -0
  55. package/lib/orchestrate/realize/orchestrateRealizeValidator.js +37 -0
  56. package/lib/orchestrate/realize/orchestrateRealizeValidator.js.map +1 -0
  57. package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.d.ts +33 -0
  58. package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js +3 -0
  59. package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js.map +1 -0
  60. package/lib/orchestrate/realize/transformRealizeCoderHistories.d.ts +5 -0
  61. package/lib/orchestrate/realize/transformRealizeCoderHistories.js +127 -0
  62. package/lib/orchestrate/realize/transformRealizeCoderHistories.js.map +1 -0
  63. package/lib/orchestrate/test/compile/completeTestCode.d.ts +2 -0
  64. package/lib/orchestrate/test/compile/completeTestCode.js +21 -0
  65. package/lib/orchestrate/test/compile/completeTestCode.js.map +1 -0
  66. package/lib/orchestrate/test/{filterTestFileName.js → compile/filterTestFileName.js} +1 -1
  67. package/lib/orchestrate/test/compile/filterTestFileName.js.map +1 -0
  68. package/lib/orchestrate/test/compile/getTestExternalDeclarations.d.ts +3 -0
  69. package/lib/orchestrate/test/compile/getTestExternalDeclarations.js +27 -0
  70. package/lib/orchestrate/test/compile/getTestExternalDeclarations.js.map +1 -0
  71. package/lib/orchestrate/test/compile/getTestScenarioArtifacts.d.ts +5 -0
  72. package/lib/orchestrate/test/{compileTestScenario.js → compile/getTestScenarioArtifacts.js} +10 -5
  73. package/lib/orchestrate/test/compile/getTestScenarioArtifacts.js.map +1 -0
  74. package/lib/orchestrate/test/orchestrateTest.js +14 -9
  75. package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
  76. package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +3 -2
  77. package/lib/orchestrate/test/orchestrateTestCorrect.js +150 -448
  78. package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
  79. package/lib/orchestrate/test/orchestrateTestScenario.js +272 -530
  80. package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
  81. package/lib/orchestrate/test/orchestrateTestWrite.d.ts +3 -2
  82. package/lib/orchestrate/test/orchestrateTestWrite.js +139 -90
  83. package/lib/orchestrate/test/orchestrateTestWrite.js.map +1 -1
  84. package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.d.ts +121 -0
  85. package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js +3 -0
  86. package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js.map +1 -0
  87. package/lib/orchestrate/test/structures/IAutoBeTestFunction.d.ts +8 -0
  88. package/lib/{utils/types/BackoffOptions.js → orchestrate/test/structures/IAutoBeTestFunction.js} +1 -1
  89. package/lib/orchestrate/test/structures/IAutoBeTestFunction.js.map +1 -0
  90. package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +14 -2
  91. package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.d.ts +112 -0
  92. package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js +3 -0
  93. package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js.map +1 -0
  94. package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.d.ts +7 -0
  95. package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js +3 -0
  96. package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js.map +1 -0
  97. package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +3 -2
  98. package/lib/orchestrate/test/transformTestCorrectHistories.js +28 -67
  99. package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
  100. package/lib/orchestrate/test/transformTestWriteHistories.d.ts +5 -4
  101. package/lib/orchestrate/test/transformTestWriteHistories.js +168 -43
  102. package/lib/orchestrate/test/transformTestWriteHistories.js.map +1 -1
  103. package/lib/structures/IAutoBeConfig.d.ts +11 -0
  104. package/lib/utils/backoffRetry.d.ts +4 -7
  105. package/lib/utils/backoffRetry.js +19 -37
  106. package/lib/utils/backoffRetry.js.map +1 -1
  107. package/lib/utils/forceRetry.d.ts +1 -0
  108. package/lib/{orchestrate/orchestrateRealize.js → utils/forceRetry.js} +15 -8
  109. package/lib/utils/forceRetry.js.map +1 -0
  110. package/package.json +8 -7
  111. package/src/AutoBeAgent.ts +17 -3
  112. package/src/constants/AutoBeSystemPromptConstant.ts +6 -6
  113. package/src/context/AutoBeTokenUsage.ts +85 -1
  114. package/src/factory/createAutoBeApplication.ts +2 -3
  115. package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +8 -3
  116. package/src/orchestrate/analyze/AutoBeAnalyzeReviewer.ts +0 -1
  117. package/src/orchestrate/analyze/orchestrateAnalyze.ts +6 -5
  118. package/src/orchestrate/facade/transformFacadeStateMessage.ts +2 -1
  119. package/src/orchestrate/index.ts +2 -2
  120. package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +4 -3
  121. package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +26 -23
  122. package/src/orchestrate/interface/orchestrateInterfaceEndpoints.ts +6 -4
  123. package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +14 -11
  124. package/src/orchestrate/interface/transformInterfaceHistories.ts +2 -0
  125. package/src/orchestrate/prisma/orchestratePrismaComponent.ts +10 -5
  126. package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +11 -5
  127. package/src/orchestrate/prisma/orchestratePrismaSchema.ts +16 -8
  128. package/src/orchestrate/prisma/transformPrismaComponentsHistories.ts +9 -0
  129. package/src/orchestrate/prisma/transformPrismaSchemaHistories.ts +8 -0
  130. package/src/orchestrate/realize/orchestrateRealize.ts +169 -0
  131. package/src/orchestrate/realize/orchestrateRealizeCoder.ts +156 -0
  132. package/src/orchestrate/realize/orchestrateRealizeIntegrator.ts +75 -0
  133. package/src/orchestrate/realize/orchestrateRealizePlanner.ts +115 -0
  134. package/src/orchestrate/realize/orchestrateRealizeValidator.ts +64 -0
  135. package/src/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.ts +36 -0
  136. package/src/orchestrate/realize/transformRealizeCoderHistories.ts +136 -0
  137. package/src/orchestrate/test/compile/completeTestCode.ts +35 -0
  138. package/src/orchestrate/test/{filterTestFileName.ts → compile/filterTestFileName.ts} +1 -1
  139. package/src/orchestrate/test/compile/getTestExternalDeclarations.ts +24 -0
  140. package/src/orchestrate/test/{compileTestScenario.ts → compile/getTestScenarioArtifacts.ts} +16 -8
  141. package/src/orchestrate/test/experimental/orchestrateTestCorrect.ast +240 -0
  142. package/src/orchestrate/test/experimental/orchestrateTestWrite.ast +316 -0
  143. package/src/orchestrate/test/experimental/transformTestCorrectHistories.ast +52 -0
  144. package/src/orchestrate/test/orchestrateTest.ts +33 -16
  145. package/src/orchestrate/test/orchestrateTestCorrect.ts +109 -497
  146. package/src/orchestrate/test/orchestrateTestScenario.ts +102 -71
  147. package/src/orchestrate/test/orchestrateTestWrite.ts +55 -181
  148. package/src/orchestrate/test/structures/IAutoBeTestCorrectApplication.ts +126 -0
  149. package/src/orchestrate/test/structures/IAutoBeTestFunction.ts +10 -0
  150. package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +14 -2
  151. package/src/orchestrate/test/structures/IAutoBeTestWriteApplication.ts +117 -0
  152. package/src/orchestrate/test/structures/IAutoBeTestWriteResult.ts +9 -0
  153. package/src/orchestrate/test/transformTestCorrectHistories.ts +38 -71
  154. package/src/orchestrate/test/transformTestWriteHistories.ts +88 -46
  155. package/src/structures/IAutoBeConfig.ts +9 -0
  156. package/src/utils/backoffRetry.ts +25 -36
  157. package/src/utils/forceRetry.ts +13 -0
  158. package/lib/factory/invertOpenApiDocument.d.ts +0 -3
  159. package/lib/factory/invertOpenApiDocument.js +0 -51
  160. package/lib/factory/invertOpenApiDocument.js.map +0 -1
  161. package/lib/orchestrate/orchestrateRealize.d.ts +0 -5
  162. package/lib/orchestrate/orchestrateRealize.js.map +0 -1
  163. package/lib/orchestrate/test/compileTestScenario.d.ts +0 -5
  164. package/lib/orchestrate/test/compileTestScenario.js.map +0 -1
  165. package/lib/orchestrate/test/filterTestFileName.js.map +0 -1
  166. package/lib/utils/StringUtil.d.ts +0 -4
  167. package/lib/utils/StringUtil.js +0 -43
  168. package/lib/utils/StringUtil.js.map +0 -1
  169. package/lib/utils/types/BackoffOptions.d.ts +0 -12
  170. package/lib/utils/types/BackoffOptions.js.map +0 -1
  171. package/src/factory/invertOpenApiDocument.ts +0 -63
  172. package/src/orchestrate/orchestrateRealize.ts +0 -18
  173. package/src/utils/StringUtil.ts +0 -45
  174. package/src/utils/types/BackoffOptions.ts +0 -15
  175. /package/lib/orchestrate/test/{filterTestFileName.d.ts → compile/filterTestFileName.d.ts} +0 -0
@@ -1,10 +1,7 @@
1
1
  import { IAgenticaController, MicroAgentica } from "@agentica/core";
2
2
  import {
3
- AutoBeTestFile,
4
- AutoBeTestScenario,
5
3
  AutoBeTestValidateEvent,
6
- AutoBeTestWriteEvent,
7
- IAutoBeTypeScriptCompilerResult,
4
+ IAutoBeTypeScriptCompileResult,
8
5
  } from "@autobe/interface";
9
6
  import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
10
7
  import { IPointer } from "tstl";
@@ -12,478 +9,147 @@ import typia from "typia";
12
9
 
13
10
  import { AutoBeContext } from "../../context/AutoBeContext";
14
11
  import { assertSchemaModel } from "../../context/assertSchemaModel";
15
- import { randomBackoffRetry } from "../../utils/backoffRetry";
16
12
  import { enforceToolCall } from "../../utils/enforceToolCall";
17
- import { compileTestScenario } from "./compileTestScenario";
18
- import { filterTestFileName } from "./filterTestFileName";
13
+ import { forceRetry } from "../../utils/forceRetry";
14
+ import { completeTestCode } from "./compile/completeTestCode";
15
+ import { IAutoBeTestCorrectApplication } from "./structures/IAutoBeTestCorrectApplication";
16
+ import { IAutoBeTestFunction } from "./structures/IAutoBeTestFunction";
19
17
  import { IAutoBeTestScenarioArtifacts } from "./structures/IAutoBeTestScenarioArtifacts";
18
+ import { IAutoBeTestWriteResult } from "./structures/IAutoBeTestWriteResult";
20
19
  import { transformTestCorrectHistories } from "./transformTestCorrectHistories";
21
20
 
22
- export async function orchestrateTestCorrect<Model extends ILlmSchema.Model>(
21
+ export const orchestrateTestCorrect = async <Model extends ILlmSchema.Model>(
23
22
  ctx: AutoBeContext<Model>,
24
- codes: AutoBeTestWriteEvent[],
25
- scenarios: AutoBeTestScenario[],
23
+ writeResult: IAutoBeTestWriteResult[],
26
24
  life: number = 4,
27
- ): Promise<AutoBeTestValidateEvent> {
28
- const files: AutoBeTestFile[] = codes.map(
29
- ({ filename, content }, index): AutoBeTestFile => {
30
- const scenario: AutoBeTestScenario = scenarios[index];
31
- return { location: filename, content, scenario };
32
- },
33
- );
34
-
35
- // 1) Build map of new test files from progress events
36
- const testFiles: Record<string, string> = Object.fromEntries(
37
- codes.map((c) => [c.filename, c.content]),
38
- );
39
-
40
- // 2) Keep only files outside the test directory from current state
41
- const retainedFiles: Record<string, string> = Object.fromEntries(
42
- Object.entries(ctx.state().interface?.files ?? {}).filter(([key]) =>
43
- filterTestFileName(key),
25
+ ): Promise<AutoBeTestValidateEvent[]> =>
26
+ Promise.all(
27
+ writeResult.map((w) =>
28
+ forceRetry(async () => {
29
+ const event: AutoBeTestValidateEvent = await compile(ctx, {
30
+ artifacts: w.artifacts,
31
+ scenario: w.scenario,
32
+ location: w.event.location,
33
+ script: w.event.final,
34
+ });
35
+ return predicate(
36
+ ctx,
37
+ {
38
+ artifacts: w.artifacts,
39
+ scenario: w.scenario,
40
+ location: w.event.location,
41
+ script: w.event.final,
42
+ },
43
+ event,
44
+ life,
45
+ );
46
+ }),
44
47
  ),
45
48
  );
46
49
 
47
- // 3) Merge and filter: keep .ts/.json, drop anything under "benchmark"
48
- const external = async (
49
- location: string,
50
- ): Promise<Record<string, string>> => {
51
- const content: string | undefined =
52
- await ctx.compiler.typescript.getExternal(location);
53
- if (content === undefined) throw new Error(`File not found: ${location}`);
54
- return { [location]: content };
55
- };
56
- const mergedFiles: Record<string, string> = {
57
- ...retainedFiles,
58
- ...testFiles,
59
- ...(await external("node_modules/@nestia/e2e/lib/TestValidator.d.ts")),
60
- ...(await external("node_modules/@nestia/fetcher/lib/IConnection.d.ts")),
61
- };
62
-
63
- // 4) Ask the LLM to correct the filtered file set
64
- const response: AutoBeTestValidateEvent = await step(
65
- ctx,
66
- mergedFiles,
67
- files,
68
- life,
69
- );
70
-
71
- // 5) Combine original + corrected files and dispatch event
72
- const event: AutoBeTestValidateEvent = {
73
- ...response,
74
- type: "testValidate",
75
- files: [
76
- ...Object.entries(mergedFiles).map(
77
- ([filename, content]): AutoBeTestFile => {
78
- return {
79
- location: filename,
80
- content,
81
- };
82
- },
83
- ),
84
- ...response.files,
85
- ],
86
- };
87
- return event;
88
- }
89
-
90
- /**
91
- * Modifies test code for each file and checks for compilation errors. When
92
- * compilation errors occur, it uses LLM to fix the code and attempts
93
- * recompilation. This process repeats up to the maximum retry count until
94
- * compilation succeeds.
95
- *
96
- * The function is a critical part of the test generation pipeline that ensures
97
- * all generated test files are syntactically correct and compilable.
98
- *
99
- * @param ctx AutoBe context object
100
- * @param entireFiles Map of all files to compile (filename: content)
101
- * @param testFiles Map of files to compile (filename: content)
102
- * @param life Number of remaining retry attempts
103
- * @returns Event object containing successful compilation result and modified
104
- * files
105
- */
106
- async function step<Model extends ILlmSchema.Model>(
50
+ const compile = async <Model extends ILlmSchema.Model>(
107
51
  ctx: AutoBeContext<Model>,
108
- entireFiles: Record<string, string>,
109
- testFiles: AutoBeTestFile[],
110
- life: number,
111
- ): Promise<AutoBeTestValidateEvent> {
112
- // COMPILE TEST CODE
113
- const result: IAutoBeTypeScriptCompilerResult =
114
- await ctx.compiler.typescript.compile({
52
+ func: IAutoBeTestFunction,
53
+ ): Promise<AutoBeTestValidateEvent> => {
54
+ const compiled: IAutoBeTypeScriptCompileResult =
55
+ await ctx.compiler.test.compile({
115
56
  files: {
116
- ...entireFiles,
117
- ...testFiles
118
- .map((el) => ({ [el.location]: el.content }))
119
- .reduce((acc, cur) => Object.assign(acc, cur), {}),
57
+ ...func.artifacts.dto,
58
+ ...func.artifacts.sdk,
59
+ [func.location]: func.script,
120
60
  },
121
61
  });
122
-
123
- if (result.type === "success") {
124
- // SUCCESS
125
- return {
126
- type: "testValidate",
127
- created_at: new Date().toISOString(),
128
- files: testFiles,
129
- result,
130
- step: ctx.state().interface?.step ?? 0,
131
- };
132
- }
133
-
134
- // EXCEPTION ERROR
135
- if (result.type === "exception") {
136
- ctx.dispatch({
137
- type: "testValidate",
138
- created_at: new Date().toISOString(),
139
- files: testFiles,
140
- result,
141
- step: ctx.state().interface?.step ?? 0,
142
- });
143
- throw new Error(JSON.stringify(result.error, null, 2));
144
- }
145
-
146
- // Make the diagnostics object (e.g. { "test/features/api/article.ts": [error1, error2] })
147
- const diagnostics: Record<
148
- string,
149
- IAutoBeTypeScriptCompilerResult.IDiagnostic[]
150
- > = {};
151
-
152
- result.diagnostics.forEach((d) => {
153
- if (d.file === null) return;
154
-
155
- diagnostics[d.file] = diagnostics[d.file] ?? [];
156
- diagnostics[d.file].push(d);
157
- });
158
-
159
- if (Object.keys(diagnostics).length === 0) {
160
- /**
161
- * SUCCESS (Because typescript compiler can't success to compile the json
162
- * files, so result could be failure. but it's success to compile the ts
163
- * files.)
164
- */
165
- return {
166
- type: "testValidate",
167
- created_at: new Date().toISOString(),
168
- files: testFiles,
169
- result: {
170
- ...result,
171
- type: "success",
172
- },
173
- step: ctx.state().interface?.step ?? 0,
174
- };
175
- }
176
-
177
- // Compile Failed
178
- ctx.dispatch({
62
+ return {
179
63
  type: "testValidate",
64
+ file: {
65
+ scenario: func.scenario,
66
+ location: func.location,
67
+ content: func.script,
68
+ },
69
+ result: compiled,
180
70
  created_at: new Date().toISOString(),
181
- files: testFiles,
182
- result,
183
- step: ctx.state().interface?.step ?? 0,
184
- });
185
-
186
- if (life <= 0)
187
- return {
188
- type: "testValidate",
189
- created_at: new Date().toISOString(),
190
- files: testFiles,
191
- result,
192
- step: ctx.state().interface?.step ?? 0,
193
- };
194
-
195
- // VALIDATION FAILED
196
- const validatedFiles: AutoBeTestFile[] = await Promise.all(
197
- Object.entries(diagnostics).map(
198
- async ([filename, d]): Promise<AutoBeTestFile> => {
199
- const file = testFiles.find((f) => f.location === filename);
200
- const code: string = file?.content!;
201
- const scenario = file?.scenario!;
202
-
203
- const response: ICorrectTestFunctionProps = await process(
204
- ctx,
205
- d,
206
- code,
207
- scenario,
208
- );
209
- ctx.dispatch({
210
- type: "testCorrect",
211
- created_at: new Date().toISOString(),
212
- files: { ...testFiles, [filename]: response.content },
213
- result,
214
- solution: response.solution,
215
- think_without_compile_error: response.think_without_compile_error,
216
- think_again_with_compile_error:
217
- response.think_again_with_compile_error,
218
- step: ctx.state().interface?.step ?? 0,
219
- });
220
-
221
- return {
222
- location: filename,
223
- content: response.content,
224
- scenario: scenario,
225
- };
226
- },
227
- ),
228
- );
71
+ step: ctx.state().analyze?.step ?? 0,
72
+ };
73
+ };
229
74
 
230
- return step(
231
- ctx,
232
- Object.entries(entireFiles)
233
- .map(([filename, content]) => {
234
- const overwritten = validatedFiles.find(
235
- (el) => el.location === filename,
236
- );
237
- return overwritten
238
- ? { [overwritten.location]: overwritten.content }
239
- : {
240
- [filename]: content,
241
- };
242
- })
243
- .reduce((acc, cur) => Object.assign(acc, cur), {}),
244
- testFiles.map((f) => {
245
- const validated = validatedFiles.find((v) => v.location === f.location);
246
- return validated ? validated : f;
247
- }),
248
- life - 1,
249
- );
250
- }
75
+ const predicate = async <Model extends ILlmSchema.Model>(
76
+ ctx: AutoBeContext<Model>,
77
+ content: IAutoBeTestFunction,
78
+ event: AutoBeTestValidateEvent,
79
+ life: number,
80
+ ): Promise<AutoBeTestValidateEvent> => {
81
+ ctx.dispatch(event);
82
+ return event.result.type === "failure"
83
+ ? correct(ctx, content, event, life - 1)
84
+ : event;
85
+ };
251
86
 
252
- /**
253
- * Modifies the code of test files where errors occurred. This function
254
- * processes TypeScript compiler diagnostics and attempts to fix compilation
255
- * errors.
256
- *
257
- * @param ctx The AutoBeContext containing application state and configuration
258
- * @param diagnostics Array of TypeScript compiler diagnostics for the errors
259
- * @param code The source code content to be fixed
260
- * @returns Promise resolving to corrected test function properties
261
- */
262
- async function process<Model extends ILlmSchema.Model>(
87
+ const correct = async <Model extends ILlmSchema.Model>(
263
88
  ctx: AutoBeContext<Model>,
264
- diagnostics: IAutoBeTypeScriptCompilerResult.IDiagnostic[],
265
- code: string,
266
- scenario: AutoBeTestScenario,
267
- ): Promise<ICorrectTestFunctionProps> {
268
- const pointer: IPointer<ICorrectTestFunctionProps | null> = {
89
+ content: IAutoBeTestFunction,
90
+ validate: AutoBeTestValidateEvent,
91
+ life: number,
92
+ ): Promise<AutoBeTestValidateEvent> => {
93
+ if (validate.result.type !== "failure") return validate;
94
+ else if (--life <= 0) return validate;
95
+
96
+ const pointer: IPointer<IAutoBeTestCorrectApplication.IProps | null> = {
269
97
  value: null,
270
98
  };
271
- const artifacts: IAutoBeTestScenarioArtifacts = await compileTestScenario(
272
- ctx,
273
- scenario,
274
- );
275
-
276
- const lines = code.split("\n").map((line, num, arr) => {
277
- const start = arr
278
- .slice(0, num)
279
- .map((el) => el.length + 1)
280
- .reduce((acc, cur) => acc + cur, 0);
281
- return {
282
- line: num + 1,
283
- text: line,
284
- start: start,
285
- end: start + line.length + 1, // exclusive
286
- };
287
- });
288
-
289
99
  const agentica = new MicroAgentica({
290
100
  model: ctx.model,
291
- vendor: { ...ctx.vendor },
101
+ vendor: ctx.vendor,
292
102
  config: {
293
103
  ...(ctx.config ?? {}),
104
+ executor: {
105
+ describe: null,
106
+ },
107
+ retry: 4,
294
108
  },
295
- histories: transformTestCorrectHistories(
296
- code,
297
- artifacts,
298
- diagnostics.map((diagnostic) =>
299
- diagnostic.start === undefined || diagnostic.length === undefined
300
- ? ""
301
- : formatDiagnostic(code, lines, diagnostic),
302
- ),
303
- ),
109
+ histories: transformTestCorrectHistories(content, validate.result),
304
110
  controllers: [
305
111
  createApplication({
306
112
  model: ctx.model,
113
+ artifacts: content.artifacts,
307
114
  build: (next) => {
308
115
  pointer.value = next;
309
116
  },
310
117
  }),
311
118
  ],
312
- tokenUsage: ctx.usage(),
313
119
  });
314
120
  enforceToolCall(agentica);
315
121
 
316
- await randomBackoffRetry(async () => {
317
- await agentica.conversate(
318
- [
319
- "# Instructions",
320
- "1. Focus on the specific error location and message",
321
- "2. Provide the corrected TypeScript code",
322
- "3. Ensure the fix resolves the compilation error",
323
- "",
324
- "Return only the fixed code without explanations.",
325
- ].join("\n"),
326
- );
327
- });
122
+ await agentica
123
+ .conversate(
124
+ "Fix the `AutoBeTest.IFunction` data to resolve the compilation error.",
125
+ )
126
+ .finally(() => {
127
+ const tokenUsage = agentica.getTokenUsage();
128
+ ctx.usage().record(tokenUsage, ["test"]);
129
+ });
328
130
  if (pointer.value === null) throw new Error("Failed to modify test code.");
329
131
 
330
- const typeReferences: string[] = Array.from(
331
- new Set(
332
- Object.keys(artifacts.document.components.schemas).map(
333
- (key) => key.split(".")[0]!,
334
- ),
335
- ),
336
- );
337
-
338
- pointer.value.content = pointer.value.content
339
- .replace(/^[ \t]*import\b[\s\S]*?;[ \t]*$/gm, "")
340
- .trim();
341
- pointer.value.content = [
342
- `import { TestValidator } from "@nestia/e2e";`,
343
- `import typia, { tags } from "typia";`,
344
- "",
345
- `import api from "@ORGANIZATION/PROJECT-api";`,
346
- ...typeReferences.map(
347
- (ref) =>
348
- `import type { ${ref} } from "@ORGANIZATION/PROJECT-api/lib/structures/${ref}";`,
349
- ),
350
- "",
351
- pointer.value.content,
352
- ].join("\n");
353
-
354
- pointer.value.content = pointer.value.content.replaceAll(
355
- 'string & Format<"uuid">',
356
- 'string & tags.Format<"uuid">',
357
- );
358
-
359
- return pointer.value;
360
- }
361
-
362
- function formatDiagnostic(
363
- code: string,
364
- lines: {
365
- line: number; // line number
366
- text: string;
367
- start: number;
368
- end: number; // exclusive
369
- }[],
370
- diagnostic: IAutoBeTypeScriptCompilerResult.IDiagnostic,
371
- ): string {
372
- const { start, length, messageText } = diagnostic;
373
- const message = messageText;
374
- if (typeof start === "number" && typeof length === "number") {
375
- const end = start + length;
376
- const problematicCode = code.substring(start, end);
377
- const errorLine = lines.find((line) => line.end > start) ?? null;
378
- const lineText = errorLine?.text ?? "";
379
-
380
- const hints = getHints(message, lineText);
381
-
382
- function createAdjustedArray(n: number): number[] {
383
- let start = n - 2;
384
-
385
- // 시작 값이 음수라면, 0부터 시작해서 5개의 숫자 생성
386
- if (start < 0) {
387
- start = 0;
388
- }
389
-
390
- return Array.from({ length: 5 }, (_, i) => start + i);
391
- }
392
-
393
- const errorLines = createAdjustedArray(errorLine?.line ?? 0);
394
-
395
- const context = errorLines
396
- .map((num) => {
397
- if (num === errorLine?.line) {
398
- if (lines[num - 1]) {
399
- return `${lines[num - 1]?.text} // <- ERROR LINE (line:${num})`;
400
- }
401
- }
402
- if (lines[num - 1]) {
403
- return lines[num - 1]?.text;
404
- }
405
-
406
- return null;
407
- })
408
- .filter((el) => el !== null);
409
-
410
- return [
411
- "## Error Information",
412
- `- Position: Characters ${start} to ${end}`,
413
- `- Error Message: ${message}`,
414
- `- Error Lines: \n${
415
- context.length
416
- ? [
417
- "\t```ts", //
418
- ...context.map((el) => `\t${el}`),
419
- "\t```",
420
- ].join("\n")
421
- : "(none)"
422
- }`,
423
- `- Problematic Code: ${problematicCode.length > 0 ? `\`${problematicCode}\`` : "(none)"}`,
424
- ...hints.map((hint) => `- Hint: ${hint}`),
425
- ].join("\n");
426
- }
427
- return ["## Error Information", `- Error Message: ${message}`].join("\n");
428
- }
429
-
430
- function getHints(message: string, lineText: string): string[] {
431
- const isTestValidator = lineText.includes("TestValidator");
432
- const isTypia =
433
- message === "Cannot find name 'Format'. Did you mean 'FormData'?";
434
- const isJest = message === "Cannot find name 'expect'.";
435
- const isCurrying =
436
- isTestValidator && message === "Expected 1 arguments, but got 2";
437
- const isAssignability =
438
- /Argument of type '([^']+)' is not assignable to parameter of type '([^']+)'/.test(
439
- message,
440
- );
441
-
442
- const hints: string[] = [];
443
-
444
- if (isTypia) {
445
- hints.push(
446
- "If you want to use typia tags, use `tags.Format` instead of `Format`.",
447
- );
448
- }
449
-
450
- if (isJest) {
451
- hints.push(
452
- 'Detected invalid `expect` usage. Use `TestValidator.equals("description")(expected)(actual)`.',
453
- );
454
- }
455
-
456
- if (isCurrying) {
457
- hints.push(
458
- "`TestValidator.equals` is a curried function and must be called in **three steps**: `title → expected → actual`.",
459
- );
460
- } else if (isTestValidator) {
461
- hints.push(
462
- "The second argument `expected` must be assignable from the type of `actual`. Consider swapping the order if you get a type error.",
463
- );
464
- }
465
-
466
- if (isAssignability && isTestValidator) {
467
- const match = lineText
468
- .trim()
469
- .match(/TestValidator\.equals\("([^"]+)"\)\(([^)]+)\)\(([^)]+)\)/);
470
- if (match) {
471
- const [, title, expected, actual] = match;
472
- if (actual.includes(expected)) {
473
- hints.push(
474
- `You can try rearranging the order like this: TestValidator.equals("${title}")(${actual})(${expected})`,
475
- );
476
- }
477
- }
478
- }
479
-
480
- return hints;
481
- }
132
+ ctx.dispatch({
133
+ type: "testCorrect",
134
+ created_at: new Date().toISOString(),
135
+ file: validate.file,
136
+ result: validate.result,
137
+ step: ctx.state().analyze?.step ?? 0,
138
+ ...pointer.value,
139
+ });
140
+ const newContent: IAutoBeTestFunction = {
141
+ ...content,
142
+ script: pointer.value.final,
143
+ };
144
+ const newValidate: AutoBeTestValidateEvent = await compile(ctx, newContent);
145
+ return predicate(ctx, newContent, newValidate, life);
146
+ };
482
147
 
483
- function createApplication<Model extends ILlmSchema.Model>(props: {
148
+ const createApplication = <Model extends ILlmSchema.Model>(props: {
484
149
  model: Model;
485
- build: (next: ICorrectTestFunctionProps) => void;
486
- }): IAgenticaController.IClass<Model> {
150
+ artifacts: IAutoBeTestScenarioArtifacts;
151
+ build: (next: IAutoBeTestCorrectApplication.IProps) => void;
152
+ }): IAgenticaController.IClass<Model> => {
487
153
  assertSchemaModel(props.model);
488
154
 
489
155
  const application: ILlmApplication<Model> = collection[
@@ -494,15 +160,17 @@ function createApplication<Model extends ILlmSchema.Model>(props: {
494
160
  name: "Modify Test Code",
495
161
  application,
496
162
  execute: {
497
- correctTestCode: (next) => {
163
+ rewrite: (next) => {
164
+ next.draft = completeTestCode(props.artifacts, next.draft);
165
+ next.final = completeTestCode(props.artifacts, next.final);
498
166
  props.build(next);
499
167
  },
500
- } satisfies IApplication,
168
+ } satisfies IAutoBeTestCorrectApplication,
501
169
  };
502
- }
170
+ };
503
171
 
504
172
  const claude = typia.llm.application<
505
- IApplication,
173
+ IAutoBeTestCorrectApplication,
506
174
  "claude",
507
175
  {
508
176
  reference: true;
@@ -510,7 +178,7 @@ const claude = typia.llm.application<
510
178
  >();
511
179
  const collection = {
512
180
  chatgpt: typia.llm.application<
513
- IApplication,
181
+ IAutoBeTestCorrectApplication,
514
182
  "chatgpt",
515
183
  { reference: true }
516
184
  >(),
@@ -518,60 +186,4 @@ const collection = {
518
186
  llama: claude,
519
187
  deepseek: claude,
520
188
  "3.1": claude,
521
- "3.0": typia.llm.application<IApplication, "3.0">(),
522
189
  };
523
-
524
- interface IApplication {
525
- correctTestCode(props: ICorrectTestFunctionProps): void;
526
- }
527
-
528
- interface ICorrectTestFunctionProps {
529
- /**
530
- * Step 1: Initial self-reflection on the source code without compiler error
531
- * context.
532
- *
533
- * The AI agent analyzes the previously generated test code to identify
534
- * potential issues, relying solely on its understanding of TypeScript syntax,
535
- * testing patterns, and best practices.
536
- *
537
- * This encourages the agent to develop independent debugging skills before
538
- * being influenced by external error messages.
539
- */
540
- think_without_compile_error: string;
541
-
542
- /**
543
- * Step 2: Re-evaluation of the code with compiler error messages as
544
- * additional context.
545
- *
546
- * After the initial analysis, the AI agent reviews the same code again, this
547
- * time incorporating the specific TypeScript compiler error messages.
548
- *
549
- * This allows the agent to correlate its initial observations with concrete
550
- * compilation failures and refine its understanding of what went wrong.
551
- */
552
- think_again_with_compile_error: string;
553
-
554
- /**
555
- * Step 3: Concrete action plan for fixing the identified issues.
556
- *
557
- * Based on the analysis from steps 1 and 2, the AI agent formulates a
558
- * specific, step-by-step solution strategy.
559
- *
560
- * This should include what changes need to be made, why those changes are
561
- * necessary, and how they will resolve the compilation errors while
562
- * maintaining the test's intended functionality.
563
- */
564
- solution: string;
565
-
566
- /**
567
- * Step 4: The corrected TypeScript test code.
568
- *
569
- * The final, properly fixed TypeScript code that should compile without
570
- * errors.
571
- *
572
- * This represents the implementation of the solution plan from step 3,
573
- * containing all necessary corrections to make the test code syntactically
574
- * valid and functionally correct.
575
- */
576
- content: string;
577
- }