@autobe/agent 0.8.0 → 0.9.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 (73) hide show
  1. package/lib/AutoBeAgent.d.ts +183 -12
  2. package/lib/AutoBeAgent.js +245 -65
  3. package/lib/AutoBeAgent.js.map +1 -1
  4. package/lib/constants/AutoBeSystemPromptConstant.d.ts +4 -3
  5. package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
  6. package/lib/context/AutoBeContext.d.ts +2 -2
  7. package/lib/factory/index.d.ts +0 -1
  8. package/lib/factory/index.js +0 -1
  9. package/lib/factory/index.js.map +1 -1
  10. package/lib/index.mjs +976 -633
  11. package/lib/index.mjs.map +1 -1
  12. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +1 -1
  13. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
  14. package/lib/orchestrate/interface/orchestrateInterface.js +1 -1
  15. package/lib/orchestrate/interface/orchestrateInterface.js.map +1 -1
  16. package/lib/orchestrate/prisma/orchestratePrisma.js +1 -1
  17. package/lib/orchestrate/prisma/orchestratePrisma.js.map +1 -1
  18. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +1 -1
  19. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
  20. package/lib/orchestrate/test/orchestrateTest.js +4 -8
  21. package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
  22. package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +2 -2
  23. package/lib/orchestrate/test/orchestrateTestCorrect.js +89 -57
  24. package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
  25. package/lib/orchestrate/test/orchestrateTestProgress.d.ts +3 -2
  26. package/lib/orchestrate/test/orchestrateTestProgress.js +73 -46
  27. package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -1
  28. package/lib/orchestrate/test/orchestrateTestScenario.d.ts +2 -2
  29. package/lib/orchestrate/test/orchestrateTestScenario.js +616 -237
  30. package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
  31. package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +123 -0
  32. package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.js +3 -0
  33. package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.js.map +1 -0
  34. package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +2 -1
  35. package/lib/orchestrate/test/transformTestCorrectHistories.js +14 -10
  36. package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
  37. package/lib/orchestrate/test/transformTestProgressHistories.d.ts +7 -1
  38. package/lib/orchestrate/test/transformTestProgressHistories.js +20 -20
  39. package/lib/orchestrate/test/transformTestProgressHistories.js.map +1 -1
  40. package/lib/orchestrate/test/transformTestScenarioHistories.d.ts +1 -2
  41. package/lib/orchestrate/test/transformTestScenarioHistories.js +1 -77
  42. package/lib/orchestrate/test/transformTestScenarioHistories.js.map +1 -1
  43. package/lib/structures/IAutoBeConfig.d.ts +48 -10
  44. package/lib/structures/IAutoBeProps.d.ts +87 -0
  45. package/lib/structures/IAutoBeVendor.d.ts +64 -22
  46. package/lib/utils/backoffRetry.d.ts +7 -0
  47. package/lib/utils/backoffRetry.js +73 -0
  48. package/lib/utils/backoffRetry.js.map +1 -0
  49. package/lib/utils/types/BackoffOptions.d.ts +12 -0
  50. package/lib/utils/types/BackoffOptions.js +3 -0
  51. package/lib/utils/types/BackoffOptions.js.map +1 -0
  52. package/package.json +4 -4
  53. package/src/AutoBeAgent.ts +248 -52
  54. package/src/constants/AutoBeSystemPromptConstant.ts +4 -3
  55. package/src/context/AutoBeContext.ts +7 -2
  56. package/src/factory/index.ts +0 -1
  57. package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +1 -1
  58. package/src/orchestrate/interface/orchestrateInterface.ts +1 -1
  59. package/src/orchestrate/prisma/orchestratePrisma.ts +1 -0
  60. package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +4 -2
  61. package/src/orchestrate/test/orchestrateTest.ts +6 -13
  62. package/src/orchestrate/test/orchestrateTestCorrect.ts +125 -72
  63. package/src/orchestrate/test/orchestrateTestProgress.ts +86 -42
  64. package/src/orchestrate/test/orchestrateTestScenario.ts +192 -151
  65. package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +132 -0
  66. package/src/orchestrate/test/transformTestCorrectHistories.ts +14 -10
  67. package/src/orchestrate/test/transformTestProgressHistories.ts +25 -22
  68. package/src/orchestrate/test/transformTestScenarioHistories.ts +0 -79
  69. package/src/structures/IAutoBeConfig.ts +48 -10
  70. package/src/structures/IAutoBeProps.ts +91 -0
  71. package/src/structures/IAutoBeVendor.ts +64 -22
  72. package/src/utils/backoffRetry.ts +84 -0
  73. package/src/utils/types/BackoffOptions.ts +15 -0
@@ -1,198 +1,253 @@
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 { HashMap, HashSet, IPointer } from "tstl";
1
+ import {
2
+ IAgenticaController,
3
+ IAgenticaHistoryJson,
4
+ MicroAgentica,
5
+ } from "@agentica/core";
6
+ import { AutoBeOpenApi } from "@autobe/interface";
7
+ import { AutoBeTestScenarioEvent } from "@autobe/interface";
8
+ import { ILlmApplication, ILlmSchema, IValidation } from "@samchon/openapi";
9
+ import { IPointer } from "tstl";
6
10
  import typia from "typia";
11
+ import { v4 } from "uuid";
7
12
 
13
+ import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
8
14
  import { AutoBeContext } from "../../context/AutoBeContext";
9
15
  import { assertSchemaModel } from "../../context/assertSchemaModel";
10
16
  import { divideArray } from "../../utils/divideArray";
11
17
  import { enforceToolCall } from "../../utils/enforceToolCall";
12
- import { OpenApiEndpointComparator } from "../interface/OpenApiEndpointComparator";
13
- import { transformTestScenarioHistories } from "./transformTestScenarioHistories";
18
+ import { IAutoBeTestScenarioApplication } from "./structures/IAutoBeTestScenarioApplication";
14
19
 
15
20
  export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
16
21
  ctx: AutoBeContext<Model>,
17
- capacity: number = 4,
18
22
  ): Promise<AutoBeTestScenarioEvent> {
19
- const files = Object.entries(ctx.state().interface?.files ?? {})
20
- .filter(([filename]) => {
21
- return filename.startsWith("test/features/api/");
22
- })
23
- .reduce<Record<string, string>>((acc, [filename, content]) => {
24
- return Object.assign(acc, { [filename]: content });
25
- }, {});
26
-
27
23
  const operations = ctx.state().interface?.document.operations ?? [];
28
- const endpoints: Omit<AutoBeOpenApi.IOperation, "specification">[] =
29
- operations.map((it) => {
30
- return {
31
- method: it.method,
32
- path: it.path,
33
- summary: it.summary,
34
- description: it.description,
35
- parameters: it.parameters,
36
- requestBody: it.requestBody,
37
- responseBody: it.responseBody,
38
- };
39
- });
24
+ if (operations.length === 0) {
25
+ throw new Error(
26
+ "Cannot write test scenarios because these are no operations.",
27
+ );
28
+ }
40
29
 
41
- const matrix: AutoBeOpenApi.IEndpoint[][] = divideArray({
42
- array: endpoints,
43
- capacity,
44
- });
45
- const start: Date = new Date();
46
-
47
- let completed: number = 0;
48
-
49
- const scenarios: AutoBeTest.IScenario[][] = await Promise.all(
50
- matrix.map(async (e) => {
51
- const rows: AutoBeTest.IScenario[] = await divideAndConquer(
52
- ctx,
53
- e,
54
- endpoints,
55
- files,
56
- 3,
57
- (count) => {
58
- completed += count;
59
- },
60
- );
61
- ctx.dispatch({
62
- type: "testScenario",
63
- scenarios: rows,
64
- total: rows.flatMap((el) => el.scenarios).length,
65
- step: ctx.state().test?.step ?? 0,
66
- completed,
67
- created_at: start.toISOString(),
68
- });
69
- return rows;
70
- }),
71
- );
30
+ const exclude: IAutoBeTestScenarioApplication.IScenarioGroup[] = [];
31
+ let include: AutoBeOpenApi.IOperation[] = Array.from(operations);
72
32
 
73
- return {
74
- type: "testScenario",
75
- scenarios: scenarios.flat(),
76
- total: scenarios.flat().flatMap((el) => el.scenarios).length,
77
- step: ctx.state().test?.step ?? 0,
78
- completed,
79
- created_at: start.toISOString(),
80
- };
81
- }
33
+ do {
34
+ const matrix = divideArray({ array: include, capacity: 30 });
82
35
 
83
- async function divideAndConquer<Model extends ILlmSchema.Model>(
84
- ctx: AutoBeContext<Model>,
85
- endpoints: AutoBeOpenApi.IEndpoint[],
86
- allEndpoints: AutoBeOpenApi.IEndpoint[],
87
- files: Record<string, string>,
88
- retry: number,
89
- progress: (completed: number) => void,
90
- ): Promise<AutoBeTest.IScenario[]> {
91
- const remained: HashSet<AutoBeOpenApi.IEndpoint> = new HashSet(
92
- endpoints,
93
- OpenApiEndpointComparator.hashCode,
94
- OpenApiEndpointComparator.equals,
95
- );
96
- const scenarios: HashMap<AutoBeOpenApi.IEndpoint, AutoBeTest.Scenario[]> =
97
- new HashMap(
98
- OpenApiEndpointComparator.hashCode,
99
- OpenApiEndpointComparator.equals,
100
- );
101
- for (let i: number = 0; i < retry; ++i) {
102
- if (remained.empty() === true || scenarios.size() >= endpoints.length)
103
- break;
104
- const before: number = scenarios.size();
105
- const newbie: AutoBeTest.IScenario[] = await process(
106
- ctx,
107
- Array.from(remained),
108
- allEndpoints,
109
- files,
36
+ await Promise.all(
37
+ matrix.map(async (_include) => {
38
+ exclude.push(
39
+ ...(await execute(
40
+ ctx,
41
+ operations,
42
+ _include,
43
+ exclude.map((x) => x.endpoint),
44
+ )),
45
+ );
46
+ }),
110
47
  );
111
- for (const item of newbie) {
112
- scenarios.set(item.endpoint, item.scenarios);
113
- remained.erase(item.endpoint);
114
- }
115
- if (scenarios.size() - before !== 0) progress(scenarios.size() - before);
116
- }
117
- return Array.from(scenarios.toJSON()).map((it) => ({
118
- endpoint: it.first,
119
- scenarios: it.second,
120
- }));
48
+
49
+ include = include.filter((op) => {
50
+ if (
51
+ exclude.some(
52
+ (pg) =>
53
+ pg.endpoint.method === op.method && pg.endpoint.path === op.path,
54
+ )
55
+ ) {
56
+ return false;
57
+ }
58
+ return true;
59
+ });
60
+ } while (include.length > 0);
61
+
62
+ return {
63
+ type: "testScenario",
64
+ step: ctx.state().analyze?.step ?? 0,
65
+ scenarios: exclude.flatMap((pg) => {
66
+ return pg.scenarios.map((plan) => {
67
+ return {
68
+ endpoint: pg.endpoint,
69
+ draft: plan.draft,
70
+ functionName: plan.functionName,
71
+ dependencies: plan.dependsOn,
72
+ } satisfies AutoBeTestScenarioEvent.IScenario;
73
+ });
74
+ }),
75
+ created_at: new Date().toISOString(),
76
+ } as AutoBeTestScenarioEvent;
121
77
  }
122
78
 
123
- async function process<Model extends ILlmSchema.Model>(
79
+ const execute = async <Model extends ILlmSchema.Model>(
124
80
  ctx: AutoBeContext<Model>,
125
- endpoints: AutoBeOpenApi.IEndpoint[],
126
- allEndpoints: AutoBeOpenApi.IEndpoint[],
127
- files: Record<string, string>,
128
- ): Promise<AutoBeTest.IScenario[]> {
129
- const pointer: IPointer<AutoBeTest.IScenario[] | null> = {
130
- value: null,
81
+ ops: AutoBeOpenApi.IOperation[],
82
+ include: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
83
+ exclude: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
84
+ ) => {
85
+ const pointer: IPointer<IAutoBeTestScenarioApplication.IScenarioGroup[]> = {
86
+ value: [],
131
87
  };
132
-
133
- const agentica = new MicroAgentica({
88
+ const agentica: MicroAgentica<Model> = new MicroAgentica({
134
89
  model: ctx.model,
135
90
  vendor: ctx.vendor,
136
91
  config: {
137
- ...(ctx.config ?? { locale: "en-US" }),
138
- systemPrompt: {
139
- describe: () => {
140
- return "Answer only 'completion' or 'failure'.";
141
- },
92
+ ...(ctx.config ?? {}),
93
+ executor: {
94
+ describe: null,
142
95
  },
143
96
  },
144
97
  tokenUsage: ctx.usage(),
145
- histories: [
146
- ...transformTestScenarioHistories(ctx.state(), allEndpoints, files),
147
- ],
98
+ histories: createHistoryProperties(ops, include, exclude),
148
99
  controllers: [
149
100
  createApplication({
150
101
  model: ctx.model,
151
102
  build: (next) => {
152
103
  pointer.value ??= [];
153
- pointer.value.push(...next.scenarios);
104
+ pointer.value.push(...next.scenarioGroups);
154
105
  },
155
106
  }),
156
107
  ],
157
108
  });
158
109
  enforceToolCall(agentica);
159
110
 
160
- await agentica.conversate(
161
- [
162
- "Make User Scenarios for below endpoints:",
111
+ await agentica.conversate(`create test scenarios.`);
112
+ if (pointer.value.length === 0) {
113
+ throw new Error("Failed to create test plans.");
114
+ }
115
+
116
+ return pointer.value;
117
+ };
118
+
119
+ const createHistoryProperties = (
120
+ operations: AutoBeOpenApi.IOperation[],
121
+ include: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
122
+ exclude: Pick<AutoBeOpenApi.IOperation, "method" | "path">[],
123
+ ) => [
124
+ {
125
+ id: v4(),
126
+ created_at: new Date().toISOString(),
127
+ type: "systemMessage",
128
+ text: AutoBeSystemPromptConstant.TEST_SCENARIO,
129
+ } satisfies IAgenticaHistoryJson.ISystemMessage,
130
+ {
131
+ id: v4(),
132
+ created_at: new Date().toISOString(),
133
+ type: "systemMessage",
134
+ text: [
135
+ "Below are the full operations. Please refer to this.",
136
+ "Your role is to draft all test cases for each given Operation.",
137
+ "It is also permissible to write multiple test codes on a single endpoint.",
138
+ "However, rather than meaningless tests, business logic tests should be written and an E2E test situation should be assumed.",
163
139
  "",
164
140
  "```json",
165
- JSON.stringify(endpoints, null, 2),
141
+ JSON.stringify(
142
+ operations.map((el) => ({
143
+ path: el.path,
144
+ method: el.method,
145
+ summary: el.summary,
146
+ })),
147
+ ),
166
148
  "```",
167
149
  ].join("\n"),
168
- );
169
- if (pointer.value === null) throw new Error("Failed to make scenarios.");
170
- return pointer.value;
171
- }
150
+ } satisfies IAgenticaHistoryJson.ISystemMessage,
151
+ {
152
+ id: v4(),
153
+ created_at: new Date().toISOString(),
154
+ type: "systemMessage",
155
+ text: [
156
+ "# Included in Test Plan",
157
+ include
158
+ .map((el) => `- ${el.method.toUpperCase()}: ${el.path}`)
159
+ .join("\n"),
160
+ "",
161
+ "# Excluded from Test Plan",
162
+ "These are the endpoints that have already been used in test codes generated as part of a plan group.",
163
+ "These endpoints do not need to be tested again.",
164
+ "However, it is allowed to reference or depend on these endpoints when writing test codes for other purposes.",
165
+ exclude
166
+ .map((el) => `- ${el.method.toUpperCase()}: ${el.path}`)
167
+ .join("\n"),
168
+ ].join("\n"),
169
+ } satisfies IAgenticaHistoryJson.ISystemMessage,
170
+ ];
172
171
 
173
172
  function createApplication<Model extends ILlmSchema.Model>(props: {
174
173
  model: Model;
175
- build: (next: IMakeScenarioProps) => void;
174
+ build: (next: IAutoBeTestScenarioApplication.IProps) => void;
176
175
  }): IAgenticaController.IClass<Model> {
177
176
  assertSchemaModel(props.model);
178
177
 
179
178
  const application: ILlmApplication<Model> = collection[
180
179
  props.model
181
180
  ] as unknown as ILlmApplication<Model>;
181
+
182
+ application.functions[0].validate = (next: unknown): IValidation => {
183
+ const result: IValidation<IAutoBeTestScenarioApplication.IProps> =
184
+ typia.validate<IAutoBeTestScenarioApplication.IProps>(next);
185
+ if (result.success === false) return result;
186
+
187
+ const errors: IValidation.IError[] = [];
188
+ result.data.scenarioGroups.forEach((pg, i, arr) => {
189
+ arr.forEach((target, j) => {
190
+ if (
191
+ i !== j &&
192
+ target.endpoint.method === pg.endpoint.method &&
193
+ target.endpoint.path === pg.endpoint.path
194
+ ) {
195
+ if (
196
+ !errors.some(
197
+ (el) =>
198
+ el.path !== `planGroups[${j}].path` &&
199
+ el.value !== target.endpoint.path,
200
+ )
201
+ ) {
202
+ errors.push({
203
+ path: `planGroups[${j}].path`,
204
+ expected: `planGroup's {method + path} cannot duplicated.`,
205
+ value: target.endpoint.path,
206
+ });
207
+ }
208
+
209
+ if (
210
+ !errors.some(
211
+ (el) =>
212
+ el.path !== `planGroups[${j}].method` &&
213
+ el.value !== target.endpoint.method,
214
+ )
215
+ ) {
216
+ errors.push({
217
+ path: `planGroups[${j}].method`,
218
+ expected: `planGroup's {method + path} cannot duplicated.`,
219
+ value: target.endpoint.method,
220
+ });
221
+ }
222
+ }
223
+ });
224
+ });
225
+
226
+ if (errors.length !== 0) {
227
+ console.log(JSON.stringify(errors, null, 2), "errors");
228
+ return {
229
+ success: false,
230
+ errors,
231
+ data: next,
232
+ };
233
+ }
234
+
235
+ return result;
236
+ };
182
237
  return {
183
238
  protocol: "class",
184
- name: "Make User Scenarios",
239
+ name: "Make test plans",
185
240
  application,
186
241
  execute: {
187
242
  makeScenario: (next) => {
188
243
  props.build(next);
189
244
  },
190
- } satisfies IApplication,
245
+ } satisfies IAutoBeTestScenarioApplication,
191
246
  };
192
247
  }
193
248
 
194
249
  const claude = typia.llm.application<
195
- IApplication,
250
+ IAutoBeTestScenarioApplication,
196
251
  "claude",
197
252
  {
198
253
  reference: true;
@@ -200,7 +255,7 @@ const claude = typia.llm.application<
200
255
  >();
201
256
  const collection = {
202
257
  chatgpt: typia.llm.application<
203
- IApplication,
258
+ IAutoBeTestScenarioApplication,
204
259
  "chatgpt",
205
260
  { reference: true }
206
261
  >(),
@@ -208,19 +263,5 @@ const collection = {
208
263
  llama: claude,
209
264
  deepseek: claude,
210
265
  "3.1": claude,
211
- "3.0": typia.llm.application<IApplication, "3.0">(),
266
+ "3.0": typia.llm.application<IAutoBeTestScenarioApplication, "3.0">(),
212
267
  };
213
-
214
- interface IApplication {
215
- /**
216
- * Make user scenarios for the given endpoints.
217
- *
218
- * @param props Properties containing the endpoints and user scenarios.
219
- */
220
- makeScenario(props: IMakeScenarioProps): void;
221
- }
222
-
223
- interface IMakeScenarioProps {
224
- /** Array of user scenarios. */
225
- scenarios: AutoBeTest.IScenario[];
226
- }
@@ -0,0 +1,132 @@
1
+ import { AutoBeOpenApi } from "@autobe/interface";
2
+
3
+ export interface IAutoBeTestScenarioApplication {
4
+ /**
5
+ * Make test scenarios for the given endpoints.
6
+ *
7
+ * @param props Properties containing the endpoints and test scenarios.
8
+ */
9
+ makeScenario(props: IAutoBeTestScenarioApplication.IProps): void;
10
+ }
11
+
12
+ export namespace IAutoBeTestScenarioApplication {
13
+ export interface IProps {
14
+ /** Array of test scenario groups. */
15
+ scenarioGroups: IAutoBeTestScenarioApplication.IScenarioGroup[];
16
+ }
17
+
18
+ export interface IScenarioGroup {
19
+ /** Target API endpoint to test. */
20
+ endpoint: AutoBeOpenApi.IEndpoint;
21
+
22
+ /** Array of test scenarios. */
23
+ scenarios: IScenario[];
24
+ }
25
+
26
+ /**
27
+ * Represents a test scenario for a single API operation.
28
+ *
29
+ * This interface extends `AutoBeOpenApi.IEndpoint`, inheriting its HTTP
30
+ * method and path information, and adds two key properties:
31
+ *
32
+ * - `draft`: A free-form, human-readable test scenario description for the API
33
+ * endpoint.
34
+ * - `dependsOn`: A list of other API endpoints that must be invoked beforehand
35
+ * in order to prepare the context for this test. Each dependency includes
36
+ * the purpose of the dependency.
37
+ *
38
+ * This structure is intended to help organize test specifications for complex
39
+ * workflows and ensure that all prerequisites are explicitly declared.
40
+ */
41
+ export interface IScenario {
42
+ /**
43
+ * A detailed natural language description of how this API endpoint should
44
+ * be tested. This should include both successful and failure scenarios,
45
+ * business rule validations, edge cases, and any sequence of steps
46
+ * necessary to perform the test. A subsequent agent will use this draft to
47
+ * generate multiple test scenarios.
48
+ */
49
+ draft: string;
50
+
51
+ /**
52
+ * Descriptive function name derived from the user scenario.
53
+ *
54
+ * The function name serves as a concise, technical identifier that clearly
55
+ * represents the specific user scenario being described. It should be
56
+ * immediately understandable and directly correspond to the user situation
57
+ * without requiring additional context.
58
+ *
59
+ * ## Naming Convention
60
+ *
61
+ * - Must start with `test_` prefix (mandatory requirement)
62
+ * - Use snake_case formatting throughout
63
+ * - Include the primary user action (create, get, update, delete, list, etc.)
64
+ * - Specify the target resource (user, product, order, profile, etc.)
65
+ * - Add scenario-specific context (valid_data, invalid_email, not_found,
66
+ * etc.)
67
+ *
68
+ * ## Content Structure
69
+ *
70
+ * Function names should follow this pattern:
71
+ * `test_[user_action]_[resource]_[scenario_context]`
72
+ *
73
+ * Where:
74
+ *
75
+ * - `user_action`: What the user is trying to do
76
+ * - `resource`: What the user is interacting with
77
+ * - `scenario_context`: The specific situation or condition
78
+ *
79
+ * ## User-Focused Examples
80
+ *
81
+ * - `test_create_user_profile_with_complete_information` - User providing all
82
+ * available profile data
83
+ * - `test_retrieve_user_profile_when_profile_exists` - User accessing their
84
+ * existing profile
85
+ * - `test_update_user_email_with_valid_new_address` - User changing their
86
+ * email to a valid new one
87
+ * - `test_delete_user_account_when_user_lacks_permission` - User attempting
88
+ * account deletion without authorization
89
+ * - `test_search_user_profiles_with_pagination_preferences` - User browsing
90
+ * profiles with specific pagination
91
+ *
92
+ * ## Clarity Guidelines
93
+ *
94
+ * - Prioritize clarity over brevity
95
+ * - Avoid technical jargon or implementation terms
96
+ * - Use terminology that reflects user perspective
97
+ * - Ensure the name alone conveys the user's intent
98
+ * - Make it understandable to non-technical stakeholders
99
+ * - Keep consistent with user scenario description
100
+ *
101
+ * ## Single Endpoint Alignment
102
+ *
103
+ * Function names must reflect scenarios that:
104
+ *
105
+ * - Accomplish user goals through this single endpoint only
106
+ * - Don't imply dependency on other API operations
107
+ * - Represent complete user interactions
108
+ */
109
+ functionName: string;
110
+
111
+ /**
112
+ * A list of other API endpoints that must be executed before this test
113
+ * scenario. This helps express dependencies such as data creation or
114
+ * authentication steps required to reach the intended test state.
115
+ */
116
+ dependsOn: IDependsOn[];
117
+ }
118
+
119
+ export interface IDependsOn {
120
+ /** Target API endpoint that must be executed before the main operation. */
121
+ endpoint: AutoBeOpenApi.IEndpoint;
122
+
123
+ /**
124
+ * A concise exscenarioation of why this API call is required before
125
+ * executing the test for the main operation.
126
+ *
127
+ * Example: "Creates a category so that a product can be linked to it during
128
+ * creation."
129
+ */
130
+ purpose: string;
131
+ }
132
+ }
@@ -1,11 +1,11 @@
1
1
  import { IAgenticaHistoryJson } from "@agentica/core";
2
+ import { AutoBeOpenApi } from "@autobe/interface";
2
3
  import { v4 } from "uuid";
3
4
 
4
5
  import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
5
6
 
6
7
  export const transformTestCorrectHistories = (
7
- apiFiles: Record<string, string>,
8
- dtoFiles: Record<string, string>,
8
+ document: AutoBeOpenApi.IDocument | null,
9
9
  ): Array<
10
10
  IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
11
11
  > => {
@@ -33,15 +33,19 @@ export const transformTestCorrectHistories = (
33
33
  "- Keep all tests deterministic and reliable.",
34
34
  "",
35
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),
36
+ "### OpenAPI Like Document",
37
+ "```json",
38
+ JSON.stringify(document),
44
39
  "```",
40
+ // "### API Files",
41
+ // "```typescript",
42
+ // JSON.stringify(apiFiles, null, 2),
43
+ // "```",
44
+ // "",
45
+ // "### DTO Files",
46
+ // "```typescript",
47
+ // JSON.stringify(dtoFiles, null, 2),
48
+ // "```",
45
49
  "",
46
50
  "Now Fix the E2E test function based on the given error information.",
47
51
  "Only output a single `async function` named `test_api_{...}`. No explanation, no commentary.",
@@ -1,12 +1,15 @@
1
1
  import { IAgenticaHistoryJson } from "@agentica/core";
2
+ import { AutoBeTestScenarioEvent } from "@autobe/interface";
2
3
  import { v4 } from "uuid";
3
4
 
4
5
  import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
5
6
 
6
- export const transformTestProgressHistories = (
7
- apiFiles: Record<string, string>,
8
- dtoFiles: Record<string, string>,
9
- ): Array<
7
+ export const transformTestProgressHistories = (props: {
8
+ scenario: AutoBeTestScenarioEvent.IScenario;
9
+ dto: Record<string, string>;
10
+ sdk: Record<string, string>;
11
+ e2e: Record<string, string>;
12
+ }): Array<
10
13
  IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
11
14
  > => {
12
15
  return [
@@ -21,30 +24,30 @@ export const transformTestProgressHistories = (
21
24
  created_at: new Date().toISOString(),
22
25
  type: "assistantMessage",
23
26
  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.",
27
+ "Here is the list of input material composition.",
26
28
  "",
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.",
29
+ "Make e2e test functions based on the following information.",
34
30
  "",
35
- "## File References",
36
- "### API Files",
37
- "```typescript",
38
- JSON.stringify(apiFiles, null, 2),
31
+ "## Secnario Plan",
32
+ "```json",
33
+ JSON.stringify(props.scenario),
39
34
  "```",
40
35
  "",
41
- "### DTO Files",
42
- "```typescript",
43
- JSON.stringify(dtoFiles, null, 2),
36
+ "## DTO Definitions",
37
+ "```json",
38
+ JSON.stringify(props.dto),
39
+ "```",
40
+ "",
41
+ "## API (SDK) Functions",
42
+ "```json",
43
+ JSON.stringify(props.sdk),
44
+ "```",
45
+ "",
46
+ "## E2E Mockup Functions",
47
+ "```json",
48
+ JSON.stringify(props.e2e),
44
49
  "```",
45
50
  "",
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
51
  ].join("\n"),
49
52
  },
50
53
  ];