@autobe/benchmark 0.30.0-dev.20260315 → 0.30.1

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.
@@ -1,289 +1,289 @@
1
- import { CompressUtil } from "@autobe/filesystem";
2
- import {
3
- AutoBeEventSnapshot,
4
- AutoBeExampleProject,
5
- AutoBeHistory,
6
- AutoBePhase,
7
- AutoBeUserConversateContent,
8
- AutoBeUserImageConversateContent,
9
- IAutoBeTokenUsageJson,
10
- } from "@autobe/interface";
11
- import cp from "child_process";
12
- import fs from "fs";
13
- import path from "path";
14
- import { Singleton, VariadicSingleton } from "tstl";
15
-
16
- export namespace AutoBeExampleStorage {
17
- export const TEST_ROOT: string = `${__dirname}/../../../../test`;
18
-
19
- export const repository = (): string => examples.get();
20
- export const getDirectory = (props: {
21
- vendor: string;
22
- project: string;
23
- }): string =>
24
- `${examples.get()}/raw/${slugModel(props.vendor, false)}/${props.project}`;
25
-
26
- export const save = async (props: {
27
- vendor: string;
28
- project: AutoBeExampleProject;
29
- files: Record<string, string | null>;
30
- }): Promise<void> => {
31
- await saveWithGzip({
32
- root: `${getDirectory(props)}`,
33
- files: props.files,
34
- overwrite: true,
35
- });
36
- };
37
-
38
- export const load = async <T>(props: {
39
- vendor: string;
40
- project: AutoBeExampleProject;
41
- file: string;
42
- }): Promise<T | null> => {
43
- const location: string = `${getDirectory(props)}/${props.file}.gz`;
44
- if (fs.existsSync(location) === false) return null;
45
- const content: string = await CompressUtil.gunzip(
46
- await fs.promises.readFile(location),
47
- );
48
- return JSON.parse(content) as T;
49
- };
50
-
51
- export const loadImages = async (
52
- imagePath: string,
53
- ): Promise<AutoBeUserConversateContent[]> => {
54
- const stat: fs.Stats = await fs.promises.lstat(imagePath);
55
-
56
- const filePaths: string[] = await (async () => {
57
- if (stat.isFile() === true) {
58
- if (imagePath.endsWith(".png") === false)
59
- throw new Error("Image Format must be .png");
60
- return [imagePath];
61
- }
62
- const files: string[] = await fs.promises.readdir(imagePath);
63
- return files
64
- .filter((f) => f.endsWith(".png"))
65
- .map((f) => path.join(imagePath, f));
66
- })();
67
-
68
- return Promise.all(
69
- filePaths.map(async (filePath) => {
70
- const extension: string = path.extname(filePath).toLowerCase().slice(1);
71
- const base64Data: string = `data:image/${extension};base64,${await fs.promises.readFile(filePath, "base64")}`;
72
- return {
73
- type: "image",
74
- image: {
75
- type: "base64",
76
- data: base64Data,
77
- } satisfies AutoBeUserImageConversateContent.IBase64,
78
- } satisfies AutoBeUserConversateContent;
79
- }),
80
- );
81
- };
82
-
83
- export const getUserMessage = async (props: {
84
- project: AutoBeExampleProject;
85
- phase: AutoBePhase;
86
- imagePath?: string;
87
- }): Promise<AutoBeUserConversateContent[]> => {
88
- const imageMessages: AutoBeUserConversateContent[] = props.imagePath
89
- ? await loadImages(props.imagePath)
90
- : [];
91
-
92
- const full: string = `${TEST_ROOT}/scripts/${props.project}/${props.phase}`;
93
- if (props.project === "account" && props.phase === "analyze") {
94
- const files: string[] = await fs.promises.readdir(full);
95
- const contents: AutoBeUserConversateContent[] = await Promise.all(
96
- files.map(async (filename) => {
97
- const filePath = path.join(full, filename);
98
- const extension = filename.split(".").pop() ?? "unknown";
99
- const base64Data = `data:image/${extension};base64,${await fs.promises.readFile(filePath, "base64")}`;
100
-
101
- return {
102
- type: "image",
103
- image: {
104
- type: "base64",
105
- data: base64Data,
106
- },
107
- } satisfies AutoBeUserConversateContent;
108
- }),
109
- );
110
- return [
111
- ...contents,
112
- ...imageMessages,
113
- {
114
- type: "text",
115
- text: "Convert the images into a planning document.",
116
- },
117
- ];
118
- }
119
-
120
- if (fs.existsSync(`${full}.md`) === false) {
121
- const text: string =
122
- props.phase === "analyze"
123
- ? await fs.promises.readFile(
124
- `${TEST_ROOT}/scripts/${props.project}.md`,
125
- "utf8",
126
- )
127
- : PROMPT_TEMPLATE[props.phase];
128
- return [
129
- ...imageMessages,
130
- {
131
- type: "text",
132
- text,
133
- },
134
- ];
135
- }
136
-
137
- const text: string = await fs.promises.readFile(`${full}.md`, "utf8");
138
-
139
- return [
140
- ...imageMessages,
141
- {
142
- type: "text",
143
- text,
144
- },
145
- ];
146
- };
147
-
148
- export const getVendorModels = async (): Promise<string[]> => {
149
- const result: string[] = [];
150
- const rawPath: string = `${repository()}/raw`;
151
- for (const vendor of await fs.promises.readdir(rawPath)) {
152
- if (
153
- (await fs.promises
154
- .lstat(`${rawPath}/${vendor}`)
155
- .then((stat) => stat.isDirectory())) === false
156
- )
157
- continue;
158
- for (const model of await fs.promises.readdir(`${rawPath}/${vendor}`)) {
159
- const stat: fs.Stats = await fs.promises.lstat(
160
- `${rawPath}/${vendor}/${model}`,
161
- );
162
- if (stat.isDirectory() === true) result.push(`${vendor}/${model}`);
163
- }
164
- }
165
- return result.sort();
166
- };
167
-
168
- export const getHistories = async (props: {
169
- vendor: string;
170
- project: AutoBeExampleProject;
171
- phase: AutoBePhase;
172
- }): Promise<AutoBeHistory[]> => {
173
- const location: string = `${getDirectory(props)}/${props.phase}.histories.json.gz`;
174
- const content: string = await CompressUtil.gunzip(
175
- await fs.promises.readFile(location),
176
- );
177
- return JSON.parse(content);
178
- };
179
-
180
- export const getSnapshots = async (props: {
181
- vendor: string;
182
- project: AutoBeExampleProject;
183
- phase: AutoBePhase;
184
- }): Promise<AutoBeEventSnapshot[]> => {
185
- const location: string = `${getDirectory(props)}/${props.phase}.snapshots.json.gz`;
186
- const content: string = await CompressUtil.gunzip(
187
- await fs.promises.readFile(location),
188
- );
189
- return JSON.parse(content);
190
- };
191
-
192
- export const getTokenUsage = async (props: {
193
- vendor: string;
194
- project: AutoBeExampleProject;
195
- phase: AutoBePhase;
196
- }): Promise<IAutoBeTokenUsageJson> => {
197
- const snapshots: AutoBeEventSnapshot[] = await getSnapshots(props);
198
- return (
199
- snapshots.at(-1)?.tokenUsage ??
200
- (() => {
201
- const component = (): IAutoBeTokenUsageJson.IComponent => ({
202
- total: 0,
203
- input: {
204
- total: 0,
205
- cached: 0,
206
- },
207
- output: {
208
- total: 0,
209
- reasoning: 0,
210
- accepted_prediction: 0,
211
- rejected_prediction: 0,
212
- },
213
- });
214
- return {
215
- aggregate: component(),
216
- facade: component(),
217
- analyze: component(),
218
- database: component(),
219
- interface: component(),
220
- test: component(),
221
- realize: component(),
222
- };
223
- })()
224
- );
225
- };
226
-
227
- export const has = async (props: {
228
- vendor: string;
229
- project: AutoBeExampleProject;
230
- phase: AutoBePhase;
231
- }): Promise<boolean> => {
232
- return fs.existsSync(
233
- `${getDirectory(props)}/${props.phase}.histories.json.gz`,
234
- );
235
- };
236
-
237
- export const slugModel = (model: string, replaceSlash: boolean): string => {
238
- model = model.replaceAll(":", "-");
239
- if (replaceSlash) model = model.replaceAll("/", "-");
240
- return model;
241
- };
242
-
243
- const PROMPT_TEMPLATE = {
244
- database: "Design the database schema.",
245
- interface: "Create the API interface specification.",
246
- test: "Make the e2e test functions.",
247
- realize: "Implement API functions.",
248
- };
249
-
250
- const examples = new Singleton(() => {
251
- const location: string = `${TEST_ROOT}/../../autobe-examples`;
252
- if (fs.existsSync(location) === false)
253
- cp.execSync(`git clone https://github.com/wrtnlabs/autobe-examples`, {
254
- cwd: `${TEST_ROOT}/../../`,
255
- stdio: "inherit",
256
- });
257
- if (fs.existsSync(`${location}/raw`) === false)
258
- fs.mkdirSync(`${location}/raw`);
259
- return location;
260
- });
261
-
262
- const saveWithGzip = async (props: {
263
- root: string;
264
- files: Record<string, string | null>;
265
- overwrite?: boolean;
266
- }): Promise<void> => {
267
- if (props.overwrite !== true && fs.existsSync(props.root))
268
- await fs.promises.rm(props.root, {
269
- recursive: true,
270
- });
271
- const directory = new VariadicSingleton(async (location: string) => {
272
- try {
273
- await fs.promises.mkdir(location, {
274
- recursive: true,
275
- });
276
- } catch {}
277
- });
278
- for (const [key, value] of Object.entries(props.files)) {
279
- const file: string = path.resolve(`${props.root}/${key}.gz`);
280
- await directory.get(path.dirname(file));
281
- if (value !== null)
282
- await fs.promises.writeFile(file, await CompressUtil.gzip(value ?? ""));
283
- else
284
- try {
285
- await fs.promises.unlink(file);
286
- } catch {}
287
- }
288
- };
289
- }
1
+ import { CompressUtil } from "@autobe/filesystem";
2
+ import {
3
+ AutoBeEventSnapshot,
4
+ AutoBeExampleProject,
5
+ AutoBeHistory,
6
+ AutoBePhase,
7
+ AutoBeUserConversateContent,
8
+ AutoBeUserImageConversateContent,
9
+ IAutoBeTokenUsageJson,
10
+ } from "@autobe/interface";
11
+ import cp from "child_process";
12
+ import fs from "fs";
13
+ import path from "path";
14
+ import { Singleton, VariadicSingleton } from "tstl";
15
+
16
+ export namespace AutoBeExampleStorage {
17
+ export const TEST_ROOT: string = `${__dirname}/../../../../test`;
18
+
19
+ export const repository = (): string => examples.get();
20
+ export const getDirectory = (props: {
21
+ vendor: string;
22
+ project: string;
23
+ }): string =>
24
+ `${examples.get()}/raw/${slugModel(props.vendor, false)}/${props.project}`;
25
+
26
+ export const save = async (props: {
27
+ vendor: string;
28
+ project: AutoBeExampleProject;
29
+ files: Record<string, string | null>;
30
+ }): Promise<void> => {
31
+ await saveWithGzip({
32
+ root: `${getDirectory(props)}`,
33
+ files: props.files,
34
+ overwrite: true,
35
+ });
36
+ };
37
+
38
+ export const load = async <T>(props: {
39
+ vendor: string;
40
+ project: AutoBeExampleProject;
41
+ file: string;
42
+ }): Promise<T | null> => {
43
+ const location: string = `${getDirectory(props)}/${props.file}.gz`;
44
+ if (fs.existsSync(location) === false) return null;
45
+ const content: string = await CompressUtil.gunzip(
46
+ await fs.promises.readFile(location),
47
+ );
48
+ return JSON.parse(content) as T;
49
+ };
50
+
51
+ export const loadImages = async (
52
+ imagePath: string,
53
+ ): Promise<AutoBeUserConversateContent[]> => {
54
+ const stat: fs.Stats = await fs.promises.lstat(imagePath);
55
+
56
+ const filePaths: string[] = await (async () => {
57
+ if (stat.isFile() === true) {
58
+ if (imagePath.endsWith(".png") === false)
59
+ throw new Error("Image Format must be .png");
60
+ return [imagePath];
61
+ }
62
+ const files: string[] = await fs.promises.readdir(imagePath);
63
+ return files
64
+ .filter((f) => f.endsWith(".png"))
65
+ .map((f) => path.join(imagePath, f));
66
+ })();
67
+
68
+ return Promise.all(
69
+ filePaths.map(async (filePath) => {
70
+ const extension: string = path.extname(filePath).toLowerCase().slice(1);
71
+ const base64Data: string = `data:image/${extension};base64,${await fs.promises.readFile(filePath, "base64")}`;
72
+ return {
73
+ type: "image",
74
+ image: {
75
+ type: "base64",
76
+ data: base64Data,
77
+ } satisfies AutoBeUserImageConversateContent.IBase64,
78
+ } satisfies AutoBeUserConversateContent;
79
+ }),
80
+ );
81
+ };
82
+
83
+ export const getUserMessage = async (props: {
84
+ project: AutoBeExampleProject;
85
+ phase: AutoBePhase;
86
+ imagePath?: string;
87
+ }): Promise<AutoBeUserConversateContent[]> => {
88
+ const imageMessages: AutoBeUserConversateContent[] = props.imagePath
89
+ ? await loadImages(props.imagePath)
90
+ : [];
91
+
92
+ const full: string = `${TEST_ROOT}/scripts/${props.project}/${props.phase}`;
93
+ if (props.project === "account" && props.phase === "analyze") {
94
+ const files: string[] = await fs.promises.readdir(full);
95
+ const contents: AutoBeUserConversateContent[] = await Promise.all(
96
+ files.map(async (filename) => {
97
+ const filePath = path.join(full, filename);
98
+ const extension = filename.split(".").pop() ?? "unknown";
99
+ const base64Data = `data:image/${extension};base64,${await fs.promises.readFile(filePath, "base64")}`;
100
+
101
+ return {
102
+ type: "image",
103
+ image: {
104
+ type: "base64",
105
+ data: base64Data,
106
+ },
107
+ } satisfies AutoBeUserConversateContent;
108
+ }),
109
+ );
110
+ return [
111
+ ...contents,
112
+ ...imageMessages,
113
+ {
114
+ type: "text",
115
+ text: "Convert the images into a planning document.",
116
+ },
117
+ ];
118
+ }
119
+
120
+ if (fs.existsSync(`${full}.md`) === false) {
121
+ const text: string =
122
+ props.phase === "analyze"
123
+ ? await fs.promises.readFile(
124
+ `${TEST_ROOT}/scripts/${props.project}.md`,
125
+ "utf8",
126
+ )
127
+ : PROMPT_TEMPLATE[props.phase];
128
+ return [
129
+ ...imageMessages,
130
+ {
131
+ type: "text",
132
+ text,
133
+ },
134
+ ];
135
+ }
136
+
137
+ const text: string = await fs.promises.readFile(`${full}.md`, "utf8");
138
+
139
+ return [
140
+ ...imageMessages,
141
+ {
142
+ type: "text",
143
+ text,
144
+ },
145
+ ];
146
+ };
147
+
148
+ export const getVendorModels = async (): Promise<string[]> => {
149
+ const result: string[] = [];
150
+ const rawPath: string = `${repository()}/raw`;
151
+ for (const vendor of await fs.promises.readdir(rawPath)) {
152
+ if (
153
+ (await fs.promises
154
+ .lstat(`${rawPath}/${vendor}`)
155
+ .then((stat) => stat.isDirectory())) === false
156
+ )
157
+ continue;
158
+ for (const model of await fs.promises.readdir(`${rawPath}/${vendor}`)) {
159
+ const stat: fs.Stats = await fs.promises.lstat(
160
+ `${rawPath}/${vendor}/${model}`,
161
+ );
162
+ if (stat.isDirectory() === true) result.push(`${vendor}/${model}`);
163
+ }
164
+ }
165
+ return result.sort();
166
+ };
167
+
168
+ export const getHistories = async (props: {
169
+ vendor: string;
170
+ project: AutoBeExampleProject;
171
+ phase: AutoBePhase;
172
+ }): Promise<AutoBeHistory[]> => {
173
+ const location: string = `${getDirectory(props)}/${props.phase}.histories.json.gz`;
174
+ const content: string = await CompressUtil.gunzip(
175
+ await fs.promises.readFile(location),
176
+ );
177
+ return JSON.parse(content);
178
+ };
179
+
180
+ export const getSnapshots = async (props: {
181
+ vendor: string;
182
+ project: AutoBeExampleProject;
183
+ phase: AutoBePhase;
184
+ }): Promise<AutoBeEventSnapshot[]> => {
185
+ const location: string = `${getDirectory(props)}/${props.phase}.snapshots.json.gz`;
186
+ const content: string = await CompressUtil.gunzip(
187
+ await fs.promises.readFile(location),
188
+ );
189
+ return JSON.parse(content);
190
+ };
191
+
192
+ export const getTokenUsage = async (props: {
193
+ vendor: string;
194
+ project: AutoBeExampleProject;
195
+ phase: AutoBePhase;
196
+ }): Promise<IAutoBeTokenUsageJson> => {
197
+ const snapshots: AutoBeEventSnapshot[] = await getSnapshots(props);
198
+ return (
199
+ snapshots.at(-1)?.tokenUsage ??
200
+ (() => {
201
+ const component = (): IAutoBeTokenUsageJson.IComponent => ({
202
+ total: 0,
203
+ input: {
204
+ total: 0,
205
+ cached: 0,
206
+ },
207
+ output: {
208
+ total: 0,
209
+ reasoning: 0,
210
+ accepted_prediction: 0,
211
+ rejected_prediction: 0,
212
+ },
213
+ });
214
+ return {
215
+ aggregate: component(),
216
+ facade: component(),
217
+ analyze: component(),
218
+ database: component(),
219
+ interface: component(),
220
+ test: component(),
221
+ realize: component(),
222
+ };
223
+ })()
224
+ );
225
+ };
226
+
227
+ export const has = async (props: {
228
+ vendor: string;
229
+ project: AutoBeExampleProject;
230
+ phase: AutoBePhase;
231
+ }): Promise<boolean> => {
232
+ return fs.existsSync(
233
+ `${getDirectory(props)}/${props.phase}.histories.json.gz`,
234
+ );
235
+ };
236
+
237
+ export const slugModel = (model: string, replaceSlash: boolean): string => {
238
+ model = model.replaceAll(":", "-");
239
+ if (replaceSlash) model = model.replaceAll("/", "-");
240
+ return model;
241
+ };
242
+
243
+ const PROMPT_TEMPLATE = {
244
+ database: "Design the database schema.",
245
+ interface: "Create the API interface specification.",
246
+ test: "Make the e2e test functions.",
247
+ realize: "Implement API functions.",
248
+ };
249
+
250
+ const examples = new Singleton(() => {
251
+ const location: string = `${TEST_ROOT}/../../autobe-examples`;
252
+ if (fs.existsSync(location) === false)
253
+ cp.execSync(`git clone https://github.com/wrtnlabs/autobe-examples`, {
254
+ cwd: `${TEST_ROOT}/../../`,
255
+ stdio: "inherit",
256
+ });
257
+ if (fs.existsSync(`${location}/raw`) === false)
258
+ fs.mkdirSync(`${location}/raw`);
259
+ return location;
260
+ });
261
+
262
+ const saveWithGzip = async (props: {
263
+ root: string;
264
+ files: Record<string, string | null>;
265
+ overwrite?: boolean;
266
+ }): Promise<void> => {
267
+ if (props.overwrite !== true && fs.existsSync(props.root))
268
+ await fs.promises.rm(props.root, {
269
+ recursive: true,
270
+ });
271
+ const directory = new VariadicSingleton(async (location: string) => {
272
+ try {
273
+ await fs.promises.mkdir(location, {
274
+ recursive: true,
275
+ });
276
+ } catch {}
277
+ });
278
+ for (const [key, value] of Object.entries(props.files)) {
279
+ const file: string = path.resolve(`${props.root}/${key}.gz`);
280
+ await directory.get(path.dirname(file));
281
+ if (value !== null)
282
+ await fs.promises.writeFile(file, await CompressUtil.gzip(value ?? ""));
283
+ else
284
+ try {
285
+ await fs.promises.unlink(file);
286
+ } catch {}
287
+ }
288
+ };
289
+ }
@@ -1,4 +1,4 @@
1
- export * from "./AutoBeExampleArchiver";
2
- export * from "./AutoBeExampleBenchmark";
3
- export * from "./AutoBeExampleStorage";
4
- export * from "./AutoBeExampleLogger";
1
+ export * from "./AutoBeExampleArchiver";
2
+ export * from "./AutoBeExampleBenchmark";
3
+ export * from "./AutoBeExampleStorage";
4
+ export * from "./AutoBeExampleLogger";
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./example";
2
- export * from "./replay";
1
+ export * from "./example";
2
+ export * from "./replay";