@autobe/agent 0.7.2 → 0.8.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 (58) hide show
  1. package/lib/AutoBeAgent.js +4 -0
  2. package/lib/AutoBeAgent.js.map +1 -1
  3. package/lib/constants/AutoBeSystemPromptConstant.d.ts +1 -1
  4. package/lib/index.mjs +100 -82
  5. package/lib/index.mjs.map +1 -1
  6. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +6 -7
  7. package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
  8. package/lib/orchestrate/analyze/orchestrateAnalyze.js +2 -5
  9. package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
  10. package/lib/orchestrate/interface/orchestrateInterfaceComplement.d.ts +1 -1
  11. package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +8 -10
  12. package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
  13. package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +9 -6
  14. package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
  15. package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js +3 -1
  16. package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js.map +1 -1
  17. package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +5 -8
  18. package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
  19. package/lib/orchestrate/prisma/orchestratePrismaComponent.js +5 -1
  20. package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
  21. package/lib/orchestrate/prisma/orchestratePrismaCorrect.d.ts +1 -1
  22. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +6 -7
  23. package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
  24. package/lib/orchestrate/prisma/orchestratePrismaSchema.js +11 -7
  25. package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
  26. package/lib/orchestrate/prisma/transformPrismaCorrectHistories.js +1 -1
  27. package/lib/orchestrate/prisma/transformPrismaCorrectHistories.js.map +1 -1
  28. package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +1 -1
  29. package/lib/orchestrate/test/orchestrateTestCorrect.js +4 -6
  30. package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
  31. package/lib/orchestrate/test/orchestrateTestProgress.js +2 -4
  32. package/lib/orchestrate/test/orchestrateTestProgress.js.map +1 -1
  33. package/lib/orchestrate/test/orchestrateTestScenario.d.ts +1 -1
  34. package/lib/orchestrate/test/orchestrateTestScenario.js +44 -14
  35. package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
  36. package/lib/orchestrate/test/transformTestScenarioHistories.d.ts +1 -1
  37. package/lib/orchestrate/test/transformTestScenarioHistories.js +2 -2
  38. package/lib/orchestrate/test/transformTestScenarioHistories.js.map +1 -1
  39. package/lib/utils/enforceToolCall.d.ts +3 -0
  40. package/lib/utils/enforceToolCall.js +13 -0
  41. package/lib/utils/enforceToolCall.js.map +1 -0
  42. package/package.json +5 -5
  43. package/src/AutoBeAgent.ts +4 -0
  44. package/src/constants/AutoBeSystemPromptConstant.ts +1 -1
  45. package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +4 -9
  46. package/src/orchestrate/analyze/orchestrateAnalyze.ts +2 -6
  47. package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +14 -13
  48. package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +7 -6
  49. package/src/orchestrate/interface/orchestrateInterfaceEndpoints.ts +2 -1
  50. package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +4 -9
  51. package/src/orchestrate/prisma/orchestratePrismaComponent.ts +4 -1
  52. package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +7 -8
  53. package/src/orchestrate/prisma/orchestratePrismaSchema.ts +10 -7
  54. package/src/orchestrate/test/orchestrateTestCorrect.ts +4 -8
  55. package/src/orchestrate/test/orchestrateTestProgress.ts +2 -5
  56. package/src/orchestrate/test/orchestrateTestScenario.ts +64 -16
  57. package/src/orchestrate/test/transformTestScenarioHistories.ts +2 -2
  58. package/src/utils/enforceToolCall.ts +13 -0
@@ -10,12 +10,13 @@ import typia from "typia";
10
10
 
11
11
  import { AutoBeContext } from "../../context/AutoBeContext";
12
12
  import { assertSchemaModel } from "../../context/assertSchemaModel";
13
+ import { enforceToolCall } from "../../utils/enforceToolCall";
13
14
  import { transformTestCorrectHistories } from "./transformTestCorrectHistories";
14
15
 
15
16
  export async function orchestrateTestCorrect<Model extends ILlmSchema.Model>(
16
17
  ctx: AutoBeContext<Model>,
17
18
  codes: AutoBeTestProgressEvent[],
18
- retry = 8,
19
+ life: number = 4,
19
20
  ): Promise<AutoBeTestValidateEvent> {
20
21
  // 1) Build map of new test files from progress events
21
22
  const testFiles = Object.fromEntries(
@@ -43,7 +44,7 @@ export async function orchestrateTestCorrect<Model extends ILlmSchema.Model>(
43
44
  );
44
45
 
45
46
  // 4) Ask the LLM to correct the filtered file set
46
- const response = await step(ctx, files, retry);
47
+ const response = await step(ctx, files, life);
47
48
 
48
49
  // 5) Combine original + corrected files and dispatch event
49
50
  const event: AutoBeTestValidateEvent = {
@@ -231,10 +232,7 @@ async function process<Model extends ILlmSchema.Model>(
231
232
  }),
232
233
  ],
233
234
  });
234
-
235
- agentica.on("request", async (event) => {
236
- if (event.body.tools) event.body.tool_choice = "required";
237
- });
235
+ enforceToolCall(agentica);
238
236
 
239
237
  await agentica.conversate(
240
238
  [
@@ -265,9 +263,7 @@ async function process<Model extends ILlmSchema.Model>(
265
263
  "Return only the fixed code without explanations.",
266
264
  ].join("\n"),
267
265
  );
268
-
269
266
  if (pointer.value === null) throw new Error("Failed to modify test code.");
270
-
271
267
  return pointer.value;
272
268
  }
273
269
 
@@ -6,6 +6,7 @@ import typia from "typia";
6
6
 
7
7
  import { AutoBeContext } from "../../context/AutoBeContext";
8
8
  import { assertSchemaModel } from "../../context/assertSchemaModel";
9
+ import { enforceToolCall } from "../../utils/enforceToolCall";
9
10
  import { transformTestProgressHistories } from "./transformTestProgressHistories";
10
11
 
11
12
  export async function orchestrateTestProgress<Model extends ILlmSchema.Model>(
@@ -91,10 +92,7 @@ async function process<Model extends ILlmSchema.Model>(
91
92
  }),
92
93
  ],
93
94
  });
94
-
95
- agentica.on("request", async (event) => {
96
- if (event.body.tools) event.body.tool_choice = "required";
97
- });
95
+ enforceToolCall(agentica);
98
96
 
99
97
  await agentica.conversate(
100
98
  [
@@ -105,7 +103,6 @@ async function process<Model extends ILlmSchema.Model>(
105
103
  "```",
106
104
  ].join("\n"),
107
105
  );
108
-
109
106
  if (pointer.value === null) throw new Error("Failed to create test code.");
110
107
  return pointer.value;
111
108
  }
@@ -2,15 +2,19 @@ import { IAgenticaController, MicroAgentica } from "@agentica/core";
2
2
  import { AutoBeOpenApi, AutoBeTest } from "@autobe/interface";
3
3
  import { AutoBeTestScenarioEvent } from "@autobe/interface/src/events/AutoBeTestScenarioEvent";
4
4
  import { ILlmApplication, ILlmSchema } from "@samchon/openapi";
5
- import { IPointer } from "tstl";
5
+ import { HashMap, HashSet, IPointer } from "tstl";
6
6
  import typia from "typia";
7
7
 
8
8
  import { AutoBeContext } from "../../context/AutoBeContext";
9
9
  import { assertSchemaModel } from "../../context/assertSchemaModel";
10
+ import { divideArray } from "../../utils/divideArray";
11
+ import { enforceToolCall } from "../../utils/enforceToolCall";
12
+ import { OpenApiEndpointComparator } from "../interface/OpenApiEndpointComparator";
10
13
  import { transformTestScenarioHistories } from "./transformTestScenarioHistories";
11
14
 
12
15
  export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
13
16
  ctx: AutoBeContext<Model>,
17
+ capacity: number = 4,
14
18
  ): Promise<AutoBeTestScenarioEvent> {
15
19
  const files = Object.entries(ctx.state().interface?.files ?? {})
16
20
  .filter(([filename]) => {
@@ -34,18 +38,25 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
34
38
  };
35
39
  });
36
40
 
41
+ const matrix: AutoBeOpenApi.IEndpoint[][] = divideArray({
42
+ array: endpoints,
43
+ capacity,
44
+ });
37
45
  const start: Date = new Date();
38
46
 
39
47
  let completed: number = 0;
40
48
 
41
49
  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(
50
+ matrix.map(async (e) => {
51
+ const rows: AutoBeTest.IScenario[] = await divideAndConquer(
45
52
  ctx,
46
- endpoint,
47
- endponits,
53
+ e,
54
+ endpoints,
48
55
  files,
56
+ 3,
57
+ (count) => {
58
+ completed += count;
59
+ },
49
60
  );
50
61
  ctx.dispatch({
51
62
  type: "testScenario",
@@ -69,10 +80,50 @@ export async function orchestrateTestScenario<Model extends ILlmSchema.Model>(
69
80
  };
70
81
  }
71
82
 
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,
110
+ );
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
+ }));
121
+ }
122
+
72
123
  async function process<Model extends ILlmSchema.Model>(
73
124
  ctx: AutoBeContext<Model>,
74
- endpoint: AutoBeOpenApi.IEndpoint,
75
125
  endpoints: AutoBeOpenApi.IEndpoint[],
126
+ allEndpoints: AutoBeOpenApi.IEndpoint[],
76
127
  files: Record<string, string>,
77
128
  ): Promise<AutoBeTest.IScenario[]> {
78
129
  const pointer: IPointer<AutoBeTest.IScenario[] | null> = {
@@ -92,32 +143,29 @@ async function process<Model extends ILlmSchema.Model>(
92
143
  },
93
144
  tokenUsage: ctx.usage(),
94
145
  histories: [
95
- ...transformTestScenarioHistories(ctx.state(), endpoints, files),
146
+ ...transformTestScenarioHistories(ctx.state(), allEndpoints, files),
96
147
  ],
97
148
  controllers: [
98
149
  createApplication({
99
150
  model: ctx.model,
100
151
  build: (next) => {
101
- pointer.value = next.scenarios;
152
+ pointer.value ??= [];
153
+ pointer.value.push(...next.scenarios);
102
154
  },
103
155
  }),
104
156
  ],
105
157
  });
106
-
107
- agentica.on("request", async (event) => {
108
- if (event.body.tools) event.body.tool_choice = "required";
109
- });
158
+ enforceToolCall(agentica);
110
159
 
111
160
  await agentica.conversate(
112
161
  [
113
- "Make User Scenarios for below endpoint:",
162
+ "Make User Scenarios for below endpoints:",
114
163
  "",
115
164
  "```json",
116
- JSON.stringify(endpoint, null, 2),
165
+ JSON.stringify(endpoints, null, 2),
117
166
  "```",
118
167
  ].join("\n"),
119
168
  );
120
-
121
169
  if (pointer.value === null) throw new Error("Failed to make scenarios.");
122
170
  return pointer.value;
123
171
  }
@@ -7,7 +7,7 @@ import { AutoBeState } from "../../context/AutoBeState";
7
7
 
8
8
  export const transformTestScenarioHistories = (
9
9
  state: AutoBeState,
10
- endponits: AutoBeOpenApi.IEndpoint[],
10
+ allEndpoints: AutoBeOpenApi.IEndpoint[],
11
11
  files: Record<string, string>,
12
12
  ): Array<
13
13
  IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
@@ -160,7 +160,7 @@ export const transformTestScenarioHistories = (
160
160
  `Different APIs may have to be called to create one.`,
161
161
  `Check which functions have been developed.`,
162
162
  "```json",
163
- JSON.stringify(endponits, null, 2),
163
+ JSON.stringify(allEndpoints, null, 2),
164
164
  "```",
165
165
  ].join("\n"),
166
166
  },
@@ -0,0 +1,13 @@
1
+ import { MicroAgentica } from "@agentica/core";
2
+ import { ILlmSchema } from "@samchon/openapi";
3
+
4
+ export function enforceToolCall<Model extends ILlmSchema.Model>(
5
+ agent: MicroAgentica<Model>,
6
+ ): MicroAgentica<Model> {
7
+ agent.on("request", (event) => {
8
+ if (event.body.tools) event.body.tool_choice = "required";
9
+ if (event.body.parallel_tool_calls !== undefined)
10
+ delete event.body.parallel_tool_calls;
11
+ });
12
+ return agent;
13
+ }