@autobe/benchmark 0.29.0 → 0.29.2

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 (39) hide show
  1. package/lib/example/AutoBeExampleArchiver.d.ts +19 -0
  2. package/lib/example/AutoBeExampleArchiver.js +239 -0
  3. package/lib/example/AutoBeExampleArchiver.js.map +1 -0
  4. package/lib/example/AutoBeExampleBenchmark.d.ts +15 -0
  5. package/lib/example/AutoBeExampleBenchmark.js +124 -0
  6. package/lib/example/AutoBeExampleBenchmark.js.map +1 -0
  7. package/lib/example/AutoBeExampleDocumentation.d.ts +4 -0
  8. package/lib/example/AutoBeExampleDocumentation.js +70 -0
  9. package/lib/example/AutoBeExampleDocumentation.js.map +1 -0
  10. package/lib/example/AutoBeExampleStorage.d.ts +2 -1
  11. package/lib/example/AutoBeExampleStorage.js +42 -41
  12. package/lib/example/AutoBeExampleStorage.js.map +1 -1
  13. package/lib/example/index.d.ts +3 -0
  14. package/lib/example/index.js +3 -0
  15. package/lib/example/index.js.map +1 -1
  16. package/lib/replay/AutoBeReplayComputer.js +2 -2
  17. package/lib/replay/AutoBeReplayComputer.js.map +1 -1
  18. package/lib/replay/AutoBeReplayDocumentation.js +3 -2
  19. package/lib/replay/AutoBeReplayDocumentation.js.map +1 -1
  20. package/lib/replay/AutoBeReplayStorage.d.ts +5 -0
  21. package/lib/replay/AutoBeReplayStorage.js +15 -0
  22. package/lib/replay/AutoBeReplayStorage.js.map +1 -1
  23. package/lib/structures/IAutoBeExampleBenchmarkState.d.ts +25 -0
  24. package/lib/structures/IAutoBeExampleBenchmarkState.js +3 -0
  25. package/lib/structures/IAutoBeExampleBenchmarkState.js.map +1 -0
  26. package/lib/structures/index.d.ts +1 -0
  27. package/lib/structures/index.js +18 -0
  28. package/lib/structures/index.js.map +1 -0
  29. package/package.json +4 -5
  30. package/src/example/AutoBeExampleArchiver.ts +337 -0
  31. package/src/example/AutoBeExampleBenchmark.ts +159 -0
  32. package/src/example/AutoBeExampleDocumentation.ts +84 -0
  33. package/src/example/AutoBeExampleStorage.ts +45 -44
  34. package/src/example/index.ts +3 -0
  35. package/src/replay/AutoBeReplayComputer.ts +1 -1
  36. package/src/replay/AutoBeReplayDocumentation.ts +3 -2
  37. package/src/replay/AutoBeReplayStorage.ts +29 -0
  38. package/src/structures/IAutoBeExampleBenchmarkState.ts +30 -0
  39. package/src/structures/index.ts +1 -0
@@ -0,0 +1,159 @@
1
+ import {
2
+ AutoBeEvent,
3
+ AutoBeExampleProject,
4
+ AutoBePhase,
5
+ IAutoBeAgent,
6
+ } from "@autobe/interface";
7
+
8
+ import { IAutoBeExampleBenchmarkState } from "../structures/IAutoBeExampleBenchmarkState";
9
+ import { AutoBeExampleArchiver } from "./AutoBeExampleArchiver";
10
+
11
+ export namespace AutoBeExampleBenchmark {
12
+ export interface IContext {
13
+ createAgent: (
14
+ props: AutoBeExampleArchiver.IAgentProps,
15
+ ) => Promise<IAutoBeAgent>;
16
+ }
17
+
18
+ export const execute = async (
19
+ ctx: IContext,
20
+ props: {
21
+ vendors: string[];
22
+ projects?: AutoBeExampleProject[];
23
+ phases?: AutoBePhase[];
24
+ progress: (state: IAutoBeExampleBenchmarkState) => void;
25
+ on?: (event: AutoBeEvent) => void;
26
+ },
27
+ ): Promise<void> => {
28
+ const state: IAutoBeExampleBenchmarkState = {
29
+ vendors: props.vendors.map(
30
+ (vendor): IAutoBeExampleBenchmarkState.IOfVendor => ({
31
+ name: vendor,
32
+ projects: PROJECT_SEQUENCE.filter(
33
+ (p) => !props.projects || props.projects.includes(p),
34
+ ).map(
35
+ (project): IAutoBeExampleBenchmarkState.IOfProject => ({
36
+ name: project,
37
+ phases: [],
38
+ success: null,
39
+ started_at: null,
40
+ completed_at: null,
41
+ }),
42
+ ),
43
+ }),
44
+ ),
45
+ };
46
+ const report = () => props.progress(state);
47
+ await Promise.all(
48
+ state.vendors.map((vendor) =>
49
+ executeVendor(ctx, {
50
+ phases: props.phases,
51
+ vendorState: vendor,
52
+ on: props.on,
53
+ report,
54
+ }),
55
+ ),
56
+ );
57
+ };
58
+
59
+ const executeVendor = async (
60
+ ctx: IContext,
61
+ props: {
62
+ vendorState: IAutoBeExampleBenchmarkState.IOfVendor;
63
+ phases?: AutoBePhase[];
64
+ report: () => void;
65
+ on?: (event: AutoBeEvent) => void;
66
+ },
67
+ ): Promise<void> => {
68
+ for (const project of props.vendorState.projects)
69
+ await executeProject(ctx, {
70
+ vendor: props.vendorState.name,
71
+ projectState: project,
72
+ phases: props.phases,
73
+ report: props.report,
74
+ on: props.on,
75
+ });
76
+ };
77
+
78
+ const executeProject = async (
79
+ ctx: IContext,
80
+ props: {
81
+ vendor: string;
82
+ projectState: IAutoBeExampleBenchmarkState.IOfProject;
83
+ phases?: AutoBePhase[];
84
+ report: () => void;
85
+ on?: (event: AutoBeEvent) => void;
86
+ },
87
+ ): Promise<void> => {
88
+ props.projectState.started_at = new Date();
89
+ for (const phase of PHASE_SEQUENCE) {
90
+ if (props.phases && props.phases.includes(phase) === false) continue;
91
+ const phaseState: IAutoBeExampleBenchmarkState.IOfPhase = {
92
+ name: phase,
93
+ snapshot: null,
94
+ success: null,
95
+ started_at: new Date(),
96
+ completed_at: null,
97
+ trial: 0,
98
+ };
99
+ props.projectState.phases.push(phaseState);
100
+ for (let i: number = 0; i < 3; ++i) {
101
+ try {
102
+ ++phaseState.trial;
103
+ phaseState.started_at = new Date();
104
+ phaseState.completed_at = null;
105
+ const success: boolean = await getArchiver(phase)({
106
+ vendor: props.vendor,
107
+ project: props.projectState.name,
108
+ agent: (next) => ctx.createAgent(next),
109
+ on: (s) => {
110
+ const event = s.event;
111
+ if (
112
+ event.type !== "jsonValidateError" &&
113
+ event.type !== "jsonParseError" &&
114
+ event.type !== "preliminary" &&
115
+ event.type !== "consentFunctionCall"
116
+ )
117
+ phaseState.snapshot = s;
118
+ props.report();
119
+ if (props.on) props.on(s.event);
120
+ },
121
+ });
122
+ phaseState.success = success;
123
+ phaseState.completed_at = new Date();
124
+ props.report();
125
+ if (success === true) break;
126
+ } catch (error) {
127
+ continue;
128
+ }
129
+ }
130
+ if (phaseState.success === null) break;
131
+ else if (phaseState.success === false && phaseState.name !== "test")
132
+ break;
133
+ }
134
+ props.projectState.completed_at = new Date();
135
+ props.projectState.success = props.projectState.phases.every(
136
+ (phase) => phase.success === true,
137
+ );
138
+ props.report();
139
+ };
140
+ }
141
+
142
+ const getArchiver = (phase: AutoBePhase) => {
143
+ if (phase === "analyze") return AutoBeExampleArchiver.archiveAnalyze;
144
+ else if (phase === "prisma") return AutoBeExampleArchiver.archivePrisma;
145
+ else if (phase === "interface") return AutoBeExampleArchiver.archiveInterface;
146
+ else if (phase === "test") return AutoBeExampleArchiver.archiveTest;
147
+ else if (phase === "realize") return AutoBeExampleArchiver.archiveRealize;
148
+ phase satisfies never;
149
+ throw new Error(`Unknown phase: ${phase}`);
150
+ };
151
+
152
+ const PROJECT_SEQUENCE = ["todo", "bbs", "reddit", "shopping"] as const;
153
+ const PHASE_SEQUENCE = [
154
+ "analyze",
155
+ "prisma",
156
+ "interface",
157
+ "test",
158
+ "realize",
159
+ ] as const;
@@ -0,0 +1,84 @@
1
+ import { AutoBeProgressEventBase } from "@autobe/interface";
2
+ import { StringUtil } from "@autobe/utils";
3
+ import typia from "typia";
4
+
5
+ import { IAutoBeExampleBenchmarkState } from "../structures";
6
+
7
+ export namespace AutoBeExampleDocumentation {
8
+ export const markdown = (state: IAutoBeExampleBenchmarkState): string =>
9
+ StringUtil.trim`
10
+ # AutoBe Example Benchmark Report
11
+
12
+ ${markdownIndex(state)}
13
+
14
+ ${state.vendors.map(markdownVendor).join("\n\n")}
15
+ `;
16
+
17
+ const markdownIndex = (
18
+ state: IAutoBeExampleBenchmarkState,
19
+ ): string => StringUtil.trim`
20
+ ## Table of Contents
21
+
22
+ ${state.vendors
23
+ .map(
24
+ (vendor) =>
25
+ `- [\`${vendor.name}\`](#${vendor.name
26
+ .replaceAll("/", "")
27
+ .replaceAll(":", "")})`,
28
+ )
29
+ .join("\n")}
30
+ `;
31
+
32
+ const markdownVendor = (
33
+ state: IAutoBeExampleBenchmarkState.IOfVendor,
34
+ ): string => StringUtil.trim`
35
+ ## \`${state.name}\`
36
+
37
+ Project | Phase | State | Elapsed Time
38
+ :-------|:------|:------|-------------:
39
+ ${state.projects.map(markdownProject).join("\n")}
40
+ `;
41
+
42
+ const markdownProject = (
43
+ state: IAutoBeExampleBenchmarkState.IOfProject,
44
+ ): string => {
45
+ // yellow circle emoji:
46
+ const phase: IAutoBeExampleBenchmarkState.IOfPhase | undefined =
47
+ state.phases.at(-1);
48
+ return [
49
+ state.name,
50
+ !!phase?.name ? `${phase.name} (${phase.trial})` : "-",
51
+ state.completed_at !== null
52
+ ? state.success
53
+ ? "🟢 success"
54
+ : "🔴 failure"
55
+ : phase !== undefined && phase.snapshot !== null
56
+ ? [
57
+ phase.trial !== 1 ? "🟠" : "🟡",
58
+ `\`${phase.snapshot.event.type}\``,
59
+ ...(typia.is<AutoBeProgressEventBase>(phase.snapshot.event)
60
+ ? [
61
+ `(${phase.snapshot.event.completed} of ${phase.snapshot.event.total})`,
62
+ ]
63
+ : []),
64
+ ].join(" ")
65
+ : "-",
66
+ state.started_at !== null
67
+ ? elapsedTime({
68
+ started_at: state.started_at,
69
+ completed_at: state.completed_at,
70
+ })
71
+ : "-",
72
+ ].join(" | ");
73
+ };
74
+ }
75
+
76
+ const elapsedTime = (props: {
77
+ started_at: Date;
78
+ completed_at: Date | null;
79
+ }): string =>
80
+ Math.round(
81
+ ((props.completed_at ?? new Date()).getTime() -
82
+ props.started_at.getTime()) /
83
+ 1_000,
84
+ ).toLocaleString() + " sec";
@@ -14,6 +14,8 @@ import { Singleton, VariadicSingleton } from "tstl";
14
14
  import { v7 } from "uuid";
15
15
 
16
16
  export namespace AutoBeExampleStorage {
17
+ export const TEST_ROOT: string = `${__dirname}/../../../../test`;
18
+
17
19
  export const repository = (): string => examples.get();
18
20
  export const getDirectory = (props: {
19
21
  vendor: string;
@@ -24,7 +26,7 @@ export namespace AutoBeExampleStorage {
24
26
  export const save = async (props: {
25
27
  vendor: string;
26
28
  project: AutoBeExampleProject;
27
- files: Record<string, string>;
29
+ files: Record<string, string | null>;
28
30
  }): Promise<void> => {
29
31
  await saveWithGzip({
30
32
  root: `${getDirectory(props)}`,
@@ -166,52 +168,51 @@ export namespace AutoBeExampleStorage {
166
168
  if (replaceSlash) model = model.replaceAll("/", "-");
167
169
  return model;
168
170
  };
169
- }
170
171
 
171
- const PROMPT_TEMPLATE = {
172
- prisma: "Design the database schema.",
173
- interface: "Create the API interface specification.",
174
- test: "Make the e2e test functions.",
175
- realize: "Implement API functions.",
176
- };
177
- const TEST_ROOT: string = `${__dirname}/../../../../test`;
172
+ const PROMPT_TEMPLATE = {
173
+ prisma: "Design the database schema.",
174
+ interface: "Create the API interface specification.",
175
+ test: "Make the e2e test functions.",
176
+ realize: "Implement API functions.",
177
+ };
178
178
 
179
- const examples = new Singleton(() => {
180
- const location: string = `${TEST_ROOT}/../../autobe-examples`;
181
- if (fs.existsSync(location) === false) {
182
- cp.execSync(`git clone https://github.com/wrtnlabs/autobe-examples`, {
183
- cwd: `${TEST_ROOT}/../../`,
184
- stdio: "inherit",
185
- });
186
- }
187
- cp.execSync("git pull", {
188
- cwd: location,
189
- stdio: "ignore",
179
+ const examples = new Singleton(() => {
180
+ const location: string = `${TEST_ROOT}/../../autobe-examples`;
181
+ if (fs.existsSync(location) === false)
182
+ cp.execSync(`git clone https://github.com/wrtnlabs/autobe-examples`, {
183
+ cwd: `${TEST_ROOT}/../../`,
184
+ stdio: "inherit",
185
+ });
186
+ if (fs.existsSync(`${location}/raw`) === false)
187
+ fs.mkdirSync(`${location}/raw`);
188
+ return location;
190
189
  });
191
- if (fs.existsSync(`${location}/raw`) === false)
192
- fs.mkdirSync(`${location}/raw`);
193
- return location;
194
- });
195
190
 
196
- const saveWithGzip = async (props: {
197
- root: string;
198
- files: Record<string, string>;
199
- overwrite?: boolean;
200
- }): Promise<void> => {
201
- if (props.overwrite !== true && fs.existsSync(props.root))
202
- await fs.promises.rm(props.root, {
203
- recursive: true,
204
- });
205
- const directory = new VariadicSingleton(async (location: string) => {
206
- try {
207
- await fs.promises.mkdir(location, {
191
+ const saveWithGzip = async (props: {
192
+ root: string;
193
+ files: Record<string, string | null>;
194
+ overwrite?: boolean;
195
+ }): Promise<void> => {
196
+ if (props.overwrite !== true && fs.existsSync(props.root))
197
+ await fs.promises.rm(props.root, {
208
198
  recursive: true,
209
199
  });
210
- } catch {}
211
- });
212
- for (const [key, value] of Object.entries(props.files)) {
213
- const file: string = path.resolve(`${props.root}/${key}.gz`);
214
- await directory.get(path.dirname(file));
215
- await fs.promises.writeFile(file, await CompressUtil.gzip(value ?? ""));
216
- }
217
- };
200
+ const directory = new VariadicSingleton(async (location: string) => {
201
+ try {
202
+ await fs.promises.mkdir(location, {
203
+ recursive: true,
204
+ });
205
+ } catch {}
206
+ });
207
+ for (const [key, value] of Object.entries(props.files)) {
208
+ const file: string = path.resolve(`${props.root}/${key}.gz`);
209
+ await directory.get(path.dirname(file));
210
+ if (value !== null)
211
+ await fs.promises.writeFile(file, await CompressUtil.gzip(value ?? ""));
212
+ else
213
+ try {
214
+ await fs.promises.unlink(file);
215
+ } catch {}
216
+ }
217
+ };
218
+ }
@@ -1 +1,4 @@
1
+ export * from "./AutoBeExampleArchiver";
2
+ export * from "./AutoBeExampleBenchmark";
1
3
  export * from "./AutoBeExampleStorage";
4
+ export * from "./AutoBeExampleDocumentation";
@@ -1,4 +1,3 @@
1
- import { AutoBeProcessAggregateFactory } from "@autobe/agent/src/factory/AutoBeProcessAggregateFactory";
2
1
  import {
3
2
  AutoBeExampleProject,
4
3
  AutoBeHistory,
@@ -6,6 +5,7 @@ import {
6
5
  IAutoBePlaygroundBenchmarkScore,
7
6
  IAutoBePlaygroundReplay,
8
7
  } from "@autobe/interface";
8
+ import { AutoBeProcessAggregateFactory } from "@autobe/utils";
9
9
 
10
10
  export namespace AutoBeReplayComputer {
11
11
  export const SIGNIFICANT_PROJECTS: AutoBeExampleProject[] = [
@@ -15,8 +15,8 @@ export namespace AutoBeReplayDocumentation {
15
15
 
16
16
  ## Benchmark
17
17
 
18
- AI Model | Score | FCSR | Status
19
- :--------|------:|-----:|:------:
18
+ AI Model | Success | Score | FCSR | Status
19
+ :--------|---------|------:|-----:|:------:
20
20
  ${experiments
21
21
  .map((e) =>
22
22
  [
@@ -26,6 +26,7 @@ export namespace AutoBeReplayDocumentation {
26
26
  )}\`](#${AutoBeExampleStorage.slugModel(e.vendor, false)
27
27
  .replaceAll("/", "")
28
28
  .replaceAll(".", "")})`,
29
+ e.replays.filter((r) => r.realize?.success === true).length,
29
30
  e.score.aggregate,
30
31
  (() => {
31
32
  const [x, y] = e.replays
@@ -1,3 +1,4 @@
1
+ import { CompressUtil } from "@autobe/filesystem";
1
2
  import {
2
3
  AutoBeEventSnapshot,
3
4
  AutoBeExampleProject,
@@ -5,6 +6,7 @@ import {
5
6
  AutoBePhase,
6
7
  IAutoBePlaygroundReplay,
7
8
  } from "@autobe/interface";
9
+ import fs from "fs";
8
10
  import typia from "typia";
9
11
 
10
12
  import { AutoBeExampleStorage } from "../example/AutoBeExampleStorage";
@@ -28,6 +30,22 @@ export namespace AutoBeReplayStorage {
28
30
  return replays.filter((r) => r !== null);
29
31
  };
30
32
 
33
+ export const getAllSummaries = async (
34
+ vendor: string,
35
+ projectFilter?: (project: AutoBeExampleProject) => boolean,
36
+ ): Promise<IAutoBePlaygroundReplay.ISummary[]> => {
37
+ const projects: AutoBeExampleProject[] = typia.misc
38
+ .literals<AutoBeExampleProject>()
39
+ .filter(projectFilter ?? (() => true));
40
+ const summaries: Array<IAutoBePlaygroundReplay.ISummary | null> =
41
+ await Promise.all(
42
+ projects.map((project) =>
43
+ AutoBeReplayStorage.getSummary({ vendor, project }),
44
+ ),
45
+ );
46
+ return summaries.filter((s) => s !== null);
47
+ };
48
+
31
49
  export const get = async (props: {
32
50
  vendor: string;
33
51
  project: AutoBeExampleProject;
@@ -60,6 +78,17 @@ export namespace AutoBeReplayStorage {
60
78
  };
61
79
  };
62
80
 
81
+ export const getSummary = async (props: {
82
+ vendor: string;
83
+ project: AutoBeExampleProject;
84
+ }): Promise<IAutoBePlaygroundReplay.ISummary | null> => {
85
+ const location: string = `${AutoBeExampleStorage.getDirectory(props)}/summary.json.gz`;
86
+ if (fs.existsSync(location) === false) return null;
87
+ return JSON.parse(
88
+ await CompressUtil.gunzip(await fs.promises.readFile(location)),
89
+ );
90
+ };
91
+
63
92
  const getHistories = async (props: {
64
93
  vendor: string;
65
94
  project: AutoBeExampleProject;
@@ -0,0 +1,30 @@
1
+ import {
2
+ AutoBeEventSnapshot,
3
+ AutoBeExampleProject,
4
+ AutoBePhase,
5
+ } from "@autobe/interface";
6
+
7
+ export interface IAutoBeExampleBenchmarkState {
8
+ vendors: IAutoBeExampleBenchmarkState.IOfVendor[];
9
+ }
10
+ export namespace IAutoBeExampleBenchmarkState {
11
+ export interface IOfVendor {
12
+ name: string;
13
+ projects: IOfProject[];
14
+ }
15
+ export interface IOfProject {
16
+ name: AutoBeExampleProject;
17
+ phases: IOfPhase[];
18
+ success: boolean | null;
19
+ started_at: Date | null;
20
+ completed_at: Date | null;
21
+ }
22
+ export interface IOfPhase {
23
+ name: AutoBePhase;
24
+ snapshot: AutoBeEventSnapshot | null;
25
+ success: boolean | null;
26
+ started_at: Date;
27
+ completed_at: Date | null;
28
+ trial: number;
29
+ }
30
+ }
@@ -0,0 +1 @@
1
+ export * from "./IAutoBeExampleBenchmarkState";