@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.
- package/LICENSE +661 -661
- package/lib/example/AutoBeExampleLogger.js +16 -16
- package/lib/replay/AutoBeReplayDocumentation.js +39 -39
- package/package.json +4 -4
- package/src/example/AutoBeExampleArchiver.ts +381 -381
- package/src/example/AutoBeExampleBenchmark.ts +190 -190
- package/src/example/AutoBeExampleLogger.ts +85 -85
- package/src/example/AutoBeExampleStorage.ts +289 -289
- package/src/example/index.ts +4 -4
- package/src/index.ts +2 -2
- package/src/replay/AutoBeReplayComputer.ts +183 -183
- package/src/replay/AutoBeReplayDocumentation.ts +176 -176
- package/src/replay/AutoBeReplayStorage.ts +116 -116
- package/src/replay/index.ts +3 -3
- package/src/structures/IAutoBeExampleBenchmarkState.ts +30 -30
- package/src/structures/index.ts +1 -1
- package/README.md +0 -261
|
@@ -1,381 +1,381 @@
|
|
|
1
|
-
import { FileSystemIterator } from "@autobe/filesystem";
|
|
2
|
-
import {
|
|
3
|
-
AutoBeAggregateEventBase,
|
|
4
|
-
AutoBeDatabaseHistory,
|
|
5
|
-
AutoBeEventOfSerializable,
|
|
6
|
-
AutoBeEventSnapshot,
|
|
7
|
-
AutoBeExampleProject,
|
|
8
|
-
AutoBeHistory,
|
|
9
|
-
AutoBePhase,
|
|
10
|
-
AutoBeProcessAggregateCollection,
|
|
11
|
-
AutoBeUserConversateContent,
|
|
12
|
-
IAutoBeAgent,
|
|
13
|
-
IAutoBePlaygroundReplay,
|
|
14
|
-
IAutoBeTokenUsageJson,
|
|
15
|
-
} from "@autobe/interface";
|
|
16
|
-
import {
|
|
17
|
-
AutoBeProcessAggregateFactory,
|
|
18
|
-
TokenUsageComputer,
|
|
19
|
-
} from "@autobe/utils";
|
|
20
|
-
import typia from "typia";
|
|
21
|
-
|
|
22
|
-
import { AutoBeReplayComputer } from "../replay";
|
|
23
|
-
import { AutoBeExampleStorage } from "./AutoBeExampleStorage";
|
|
24
|
-
|
|
25
|
-
export namespace AutoBeExampleArchiver {
|
|
26
|
-
export interface IContext {
|
|
27
|
-
vendor: string;
|
|
28
|
-
project: AutoBeExampleProject;
|
|
29
|
-
imagePath?: string;
|
|
30
|
-
agent: (props: IAgentProps) => Promise<IAutoBeAgent>;
|
|
31
|
-
on: (snapshot: AutoBeEventSnapshot, agent: IAutoBeAgent) => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface IAgentProps {
|
|
35
|
-
vendor: string;
|
|
36
|
-
histories: AutoBeHistory[];
|
|
37
|
-
tokenUsage: IAutoBeTokenUsageJson;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const archiveAnalyze = (ctx: IContext): Promise<boolean> =>
|
|
41
|
-
archive(ctx, {
|
|
42
|
-
phase: "analyze",
|
|
43
|
-
trial: async (conversate): Promise<boolean> =>
|
|
44
|
-
(await conversate(
|
|
45
|
-
await AutoBeExampleStorage.getUserMessage({
|
|
46
|
-
project: ctx.project,
|
|
47
|
-
phase: "analyze",
|
|
48
|
-
imagePath: ctx.imagePath,
|
|
49
|
-
}),
|
|
50
|
-
)) ||
|
|
51
|
-
(await conversate(
|
|
52
|
-
"I'm not familiar with the analyze feature. Please determine everything by yourself, and just show me the analysis report.",
|
|
53
|
-
)) ||
|
|
54
|
-
(await conversate(
|
|
55
|
-
"I already told you to publish the analysis report. Never ask me anything, and just do anything right now by your decision.",
|
|
56
|
-
)) ||
|
|
57
|
-
(await conversate(
|
|
58
|
-
"Call analyze() function right now, never ask me anything again. You can do whatever you want.",
|
|
59
|
-
)),
|
|
60
|
-
predicate: (histories): boolean =>
|
|
61
|
-
histories.some((h) => h.type === "analyze"),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
export const archivePrisma = (ctx: IContext): Promise<boolean> =>
|
|
65
|
-
archive(ctx, {
|
|
66
|
-
phase: "database",
|
|
67
|
-
trial: getTrial({
|
|
68
|
-
project: ctx.project,
|
|
69
|
-
phase: "database",
|
|
70
|
-
}),
|
|
71
|
-
predicate: (histories): boolean => {
|
|
72
|
-
const prisma: AutoBeDatabaseHistory | undefined = histories.find(
|
|
73
|
-
(h) => h.type === "database",
|
|
74
|
-
);
|
|
75
|
-
return prisma !== undefined && prisma.compiled.type === "success";
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
export const archiveInterface = (ctx: IContext): Promise<boolean> =>
|
|
80
|
-
archive(ctx, {
|
|
81
|
-
phase: "interface",
|
|
82
|
-
trial: getTrial({
|
|
83
|
-
project: ctx.project,
|
|
84
|
-
phase: "interface",
|
|
85
|
-
}),
|
|
86
|
-
predicate: (histories): boolean => {
|
|
87
|
-
const interfaceHistory: AutoBeHistory | undefined = histories.find(
|
|
88
|
-
(h) => h.type === "interface",
|
|
89
|
-
);
|
|
90
|
-
return (
|
|
91
|
-
interfaceHistory !== undefined && interfaceHistory.missed.length === 0
|
|
92
|
-
);
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
export const archiveTest = (ctx: IContext): Promise<boolean> =>
|
|
97
|
-
archive(ctx, {
|
|
98
|
-
phase: "test",
|
|
99
|
-
trial: getTrial({
|
|
100
|
-
project: ctx.project,
|
|
101
|
-
phase: "test",
|
|
102
|
-
}),
|
|
103
|
-
predicate: (histories): boolean => {
|
|
104
|
-
const testHistory: AutoBeHistory | undefined = histories.find(
|
|
105
|
-
(h) => h.type === "test",
|
|
106
|
-
);
|
|
107
|
-
return (
|
|
108
|
-
testHistory !== undefined && testHistory.compiled.type === "success"
|
|
109
|
-
);
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
export const archiveRealize = (ctx: IContext): Promise<boolean> =>
|
|
114
|
-
archive(ctx, {
|
|
115
|
-
phase: "realize",
|
|
116
|
-
trial: getTrial({
|
|
117
|
-
project: ctx.project,
|
|
118
|
-
phase: "realize",
|
|
119
|
-
}),
|
|
120
|
-
predicate: (histories): boolean => {
|
|
121
|
-
const realizeHistory: AutoBeHistory | undefined = histories.find(
|
|
122
|
-
(h) => h.type === "realize",
|
|
123
|
-
);
|
|
124
|
-
return (
|
|
125
|
-
realizeHistory !== undefined &&
|
|
126
|
-
realizeHistory.compiled.type === "success"
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
const archive = async (
|
|
132
|
-
ctx: IContext,
|
|
133
|
-
props: {
|
|
134
|
-
phase: AutoBePhase;
|
|
135
|
-
trial: (
|
|
136
|
-
conversate: (
|
|
137
|
-
input:
|
|
138
|
-
| string
|
|
139
|
-
| AutoBeUserConversateContent
|
|
140
|
-
| AutoBeUserConversateContent[],
|
|
141
|
-
) => Promise<boolean>,
|
|
142
|
-
) => Promise<boolean>;
|
|
143
|
-
predicate: (histories: AutoBeHistory[]) => boolean;
|
|
144
|
-
},
|
|
145
|
-
): Promise<boolean> => {
|
|
146
|
-
// INITIALIZE AGENT
|
|
147
|
-
const asset: IAgentProps = await getAsset({
|
|
148
|
-
vendor: ctx.vendor,
|
|
149
|
-
project: ctx.project,
|
|
150
|
-
phase: props.phase,
|
|
151
|
-
});
|
|
152
|
-
const agent: IAutoBeAgent = await ctx.agent(asset);
|
|
153
|
-
const snapshots: AutoBeEventSnapshot[] = [];
|
|
154
|
-
for (const type of typia.misc.literals<AutoBeEventOfSerializable.Type>()) {
|
|
155
|
-
agent.on(type, (e) => {
|
|
156
|
-
const s: AutoBeEventSnapshot = {
|
|
157
|
-
event: e,
|
|
158
|
-
tokenUsage: typia.misc.clone<IAutoBeTokenUsageJson>(
|
|
159
|
-
agent.getTokenUsage(),
|
|
160
|
-
),
|
|
161
|
-
};
|
|
162
|
-
ctx.on(s, agent);
|
|
163
|
-
snapshots.push(s);
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const summarize = async (
|
|
168
|
-
histories: AutoBeHistory[],
|
|
169
|
-
error: boolean,
|
|
170
|
-
): Promise<void> => {
|
|
171
|
-
const replay: IAutoBePlaygroundReplay = {
|
|
172
|
-
vendor: ctx.vendor,
|
|
173
|
-
project: ctx.project,
|
|
174
|
-
histories,
|
|
175
|
-
analyze: null,
|
|
176
|
-
database: null,
|
|
177
|
-
interface: null,
|
|
178
|
-
test: null,
|
|
179
|
-
realize: null,
|
|
180
|
-
};
|
|
181
|
-
for (const phase of PHASES)
|
|
182
|
-
if (phase === props.phase) {
|
|
183
|
-
replay[phase] = snapshots;
|
|
184
|
-
break;
|
|
185
|
-
} else
|
|
186
|
-
replay[phase] = await AutoBeExampleStorage.getSnapshots({
|
|
187
|
-
vendor: ctx.vendor,
|
|
188
|
-
project: ctx.project,
|
|
189
|
-
phase,
|
|
190
|
-
});
|
|
191
|
-
const summary: IAutoBePlaygroundReplay.ISummary =
|
|
192
|
-
AutoBeReplayComputer.summarize(replay);
|
|
193
|
-
if (error === true) {
|
|
194
|
-
const aggregates: AutoBeProcessAggregateCollection =
|
|
195
|
-
AutoBeProcessAggregateFactory.createCollection();
|
|
196
|
-
for (const { event } of snapshots) {
|
|
197
|
-
if (typia.is<AutoBeAggregateEventBase>(event) === false) continue;
|
|
198
|
-
AutoBeProcessAggregateFactory.emplaceEvent(aggregates, event);
|
|
199
|
-
}
|
|
200
|
-
summary[props.phase] = {
|
|
201
|
-
aggregates,
|
|
202
|
-
success: false,
|
|
203
|
-
elapsed: 0,
|
|
204
|
-
commodity: {},
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
await AutoBeExampleStorage.save({
|
|
208
|
-
vendor: ctx.vendor,
|
|
209
|
-
project: ctx.project,
|
|
210
|
-
files: {
|
|
211
|
-
[`summary.json`]: JSON.stringify(summary),
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
let lastFunctionCallErrorMessage: string | null = null;
|
|
218
|
-
// CONVERSATE
|
|
219
|
-
const go = async (
|
|
220
|
-
c: string | AutoBeUserConversateContent | AutoBeUserConversateContent[],
|
|
221
|
-
): Promise<boolean> => {
|
|
222
|
-
try {
|
|
223
|
-
const result: AutoBeHistory[] = await agent.conversate(c);
|
|
224
|
-
const hasMeaningfulOutput: boolean = result.some(
|
|
225
|
-
(h) => h.type !== "userMessage",
|
|
226
|
-
);
|
|
227
|
-
return (
|
|
228
|
-
result.some((h) => h.type === props.phase) ||
|
|
229
|
-
(hasMeaningfulOutput &&
|
|
230
|
-
result.every((h) => h.type !== "assistantMessage"))
|
|
231
|
-
);
|
|
232
|
-
} catch (error: unknown) {
|
|
233
|
-
if (
|
|
234
|
-
error instanceof Error &&
|
|
235
|
-
error.message.includes("Failed to function calling")
|
|
236
|
-
) {
|
|
237
|
-
lastFunctionCallErrorMessage = error.message;
|
|
238
|
-
return false;
|
|
239
|
-
}
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
const done: boolean = await props.trial(go);
|
|
245
|
-
const histories: AutoBeHistory[] = agent.getHistories();
|
|
246
|
-
if (
|
|
247
|
-
done === false ||
|
|
248
|
-
histories.some((h) => h.type === props.phase) === false
|
|
249
|
-
) {
|
|
250
|
-
const detail: string | null = lastFunctionCallErrorMessage;
|
|
251
|
-
throw new Error(
|
|
252
|
-
detail
|
|
253
|
-
? `Failed to function calling in the "${props.phase}" phase of the "${ctx.project}" project.\n\n${detail}`
|
|
254
|
-
: `Failed to function calling in the "${props.phase}" phase of the "${ctx.project}" project.`,
|
|
255
|
-
);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// AGGREGATE
|
|
259
|
-
try {
|
|
260
|
-
await FileSystemIterator.save({
|
|
261
|
-
root: `${
|
|
262
|
-
AutoBeExampleStorage.TEST_ROOT
|
|
263
|
-
}/results/${AutoBeExampleStorage.slugModel(ctx.vendor, false)}/${
|
|
264
|
-
ctx.project
|
|
265
|
-
}/${props.phase}`,
|
|
266
|
-
files: {
|
|
267
|
-
...(await agent.getFiles()),
|
|
268
|
-
...Object.fromEntries(
|
|
269
|
-
histories
|
|
270
|
-
.filter(
|
|
271
|
-
(h) =>
|
|
272
|
-
h.type === "database" ||
|
|
273
|
-
h.type === "interface" ||
|
|
274
|
-
h.type === "test" ||
|
|
275
|
-
h.type === "realize",
|
|
276
|
-
)
|
|
277
|
-
.map((h) => [`autobe/${h.type}.instruction.md`, h.instruction]),
|
|
278
|
-
),
|
|
279
|
-
"pnpm-workspace.yaml": "",
|
|
280
|
-
},
|
|
281
|
-
});
|
|
282
|
-
} catch {}
|
|
283
|
-
await AutoBeExampleStorage.save({
|
|
284
|
-
vendor: ctx.vendor,
|
|
285
|
-
project: ctx.project,
|
|
286
|
-
files: {
|
|
287
|
-
[`${props.phase}.histories.json`]: JSON.stringify(histories),
|
|
288
|
-
[`${props.phase}.snapshots.json`]: JSON.stringify(snapshots),
|
|
289
|
-
[`${props.phase}.error.json`]: null,
|
|
290
|
-
},
|
|
291
|
-
});
|
|
292
|
-
await summarize([...asset.histories, ...histories], false);
|
|
293
|
-
return props.predicate(histories);
|
|
294
|
-
} catch (error) {
|
|
295
|
-
if (error instanceof Error)
|
|
296
|
-
await AutoBeExampleStorage.save({
|
|
297
|
-
vendor: ctx.vendor,
|
|
298
|
-
project: ctx.project,
|
|
299
|
-
files: {
|
|
300
|
-
[`${props.phase}.snapshots.json`]: JSON.stringify(snapshots),
|
|
301
|
-
[`${props.phase}.histories.json`]: JSON.stringify(
|
|
302
|
-
agent.getHistories(),
|
|
303
|
-
),
|
|
304
|
-
[`${props.phase}.error.json`]: JSON.stringify({
|
|
305
|
-
...error,
|
|
306
|
-
name: error.name,
|
|
307
|
-
message: error.message,
|
|
308
|
-
stack: error.stack,
|
|
309
|
-
}),
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
await summarize(asset.histories, true);
|
|
313
|
-
throw error;
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
const getTrial =
|
|
318
|
-
(props: { project: AutoBeExampleProject; phase: AutoBePhase }) =>
|
|
319
|
-
async (
|
|
320
|
-
conversate: (
|
|
321
|
-
input:
|
|
322
|
-
| string
|
|
323
|
-
| AutoBeUserConversateContent
|
|
324
|
-
| AutoBeUserConversateContent[],
|
|
325
|
-
) => Promise<boolean>,
|
|
326
|
-
): Promise<boolean> =>
|
|
327
|
-
(await conversate(await AutoBeExampleStorage.getUserMessage(props))) ||
|
|
328
|
-
(await conversate(
|
|
329
|
-
"Don't ask me to do that, and just do it right now.",
|
|
330
|
-
)) ||
|
|
331
|
-
(await conversate(
|
|
332
|
-
`I already told you to do ${props.phase} process. Never ask me anything, and just do it right now. Go go go!`,
|
|
333
|
-
));
|
|
334
|
-
|
|
335
|
-
const getAsset = async (props: {
|
|
336
|
-
vendor: string;
|
|
337
|
-
project: AutoBeExampleProject;
|
|
338
|
-
phase: AutoBePhase;
|
|
339
|
-
}): Promise<IAgentProps> => {
|
|
340
|
-
const previous: AutoBePhase | null =
|
|
341
|
-
PHASES[PHASES.indexOf(props.phase) - 1] ?? null;
|
|
342
|
-
if (previous === null)
|
|
343
|
-
return {
|
|
344
|
-
vendor: props.vendor,
|
|
345
|
-
histories: [],
|
|
346
|
-
tokenUsage: {
|
|
347
|
-
aggregate: TokenUsageComputer.zero(),
|
|
348
|
-
facade: TokenUsageComputer.zero(),
|
|
349
|
-
analyze: TokenUsageComputer.zero(),
|
|
350
|
-
database: TokenUsageComputer.zero(),
|
|
351
|
-
interface: TokenUsageComputer.zero(),
|
|
352
|
-
test: TokenUsageComputer.zero(),
|
|
353
|
-
realize: TokenUsageComputer.zero(),
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
const histories: AutoBeHistory[] = await AutoBeExampleStorage.getHistories({
|
|
357
|
-
vendor: props.vendor,
|
|
358
|
-
project: props.project,
|
|
359
|
-
phase: previous,
|
|
360
|
-
});
|
|
361
|
-
const tokenUsage: IAutoBeTokenUsageJson =
|
|
362
|
-
await AutoBeExampleStorage.getTokenUsage({
|
|
363
|
-
vendor: props.vendor,
|
|
364
|
-
project: props.project,
|
|
365
|
-
phase: previous,
|
|
366
|
-
});
|
|
367
|
-
return {
|
|
368
|
-
vendor: props.vendor,
|
|
369
|
-
histories,
|
|
370
|
-
tokenUsage,
|
|
371
|
-
};
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
const PHASES: AutoBePhase[] = [
|
|
376
|
-
"analyze",
|
|
377
|
-
"database",
|
|
378
|
-
"interface",
|
|
379
|
-
"test",
|
|
380
|
-
"realize",
|
|
381
|
-
];
|
|
1
|
+
import { FileSystemIterator } from "@autobe/filesystem";
|
|
2
|
+
import {
|
|
3
|
+
AutoBeAggregateEventBase,
|
|
4
|
+
AutoBeDatabaseHistory,
|
|
5
|
+
AutoBeEventOfSerializable,
|
|
6
|
+
AutoBeEventSnapshot,
|
|
7
|
+
AutoBeExampleProject,
|
|
8
|
+
AutoBeHistory,
|
|
9
|
+
AutoBePhase,
|
|
10
|
+
AutoBeProcessAggregateCollection,
|
|
11
|
+
AutoBeUserConversateContent,
|
|
12
|
+
IAutoBeAgent,
|
|
13
|
+
IAutoBePlaygroundReplay,
|
|
14
|
+
IAutoBeTokenUsageJson,
|
|
15
|
+
} from "@autobe/interface";
|
|
16
|
+
import {
|
|
17
|
+
AutoBeProcessAggregateFactory,
|
|
18
|
+
TokenUsageComputer,
|
|
19
|
+
} from "@autobe/utils";
|
|
20
|
+
import typia from "typia";
|
|
21
|
+
|
|
22
|
+
import { AutoBeReplayComputer } from "../replay";
|
|
23
|
+
import { AutoBeExampleStorage } from "./AutoBeExampleStorage";
|
|
24
|
+
|
|
25
|
+
export namespace AutoBeExampleArchiver {
|
|
26
|
+
export interface IContext {
|
|
27
|
+
vendor: string;
|
|
28
|
+
project: AutoBeExampleProject;
|
|
29
|
+
imagePath?: string;
|
|
30
|
+
agent: (props: IAgentProps) => Promise<IAutoBeAgent>;
|
|
31
|
+
on: (snapshot: AutoBeEventSnapshot, agent: IAutoBeAgent) => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface IAgentProps {
|
|
35
|
+
vendor: string;
|
|
36
|
+
histories: AutoBeHistory[];
|
|
37
|
+
tokenUsage: IAutoBeTokenUsageJson;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const archiveAnalyze = (ctx: IContext): Promise<boolean> =>
|
|
41
|
+
archive(ctx, {
|
|
42
|
+
phase: "analyze",
|
|
43
|
+
trial: async (conversate): Promise<boolean> =>
|
|
44
|
+
(await conversate(
|
|
45
|
+
await AutoBeExampleStorage.getUserMessage({
|
|
46
|
+
project: ctx.project,
|
|
47
|
+
phase: "analyze",
|
|
48
|
+
imagePath: ctx.imagePath,
|
|
49
|
+
}),
|
|
50
|
+
)) ||
|
|
51
|
+
(await conversate(
|
|
52
|
+
"I'm not familiar with the analyze feature. Please determine everything by yourself, and just show me the analysis report.",
|
|
53
|
+
)) ||
|
|
54
|
+
(await conversate(
|
|
55
|
+
"I already told you to publish the analysis report. Never ask me anything, and just do anything right now by your decision.",
|
|
56
|
+
)) ||
|
|
57
|
+
(await conversate(
|
|
58
|
+
"Call analyze() function right now, never ask me anything again. You can do whatever you want.",
|
|
59
|
+
)),
|
|
60
|
+
predicate: (histories): boolean =>
|
|
61
|
+
histories.some((h) => h.type === "analyze"),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const archivePrisma = (ctx: IContext): Promise<boolean> =>
|
|
65
|
+
archive(ctx, {
|
|
66
|
+
phase: "database",
|
|
67
|
+
trial: getTrial({
|
|
68
|
+
project: ctx.project,
|
|
69
|
+
phase: "database",
|
|
70
|
+
}),
|
|
71
|
+
predicate: (histories): boolean => {
|
|
72
|
+
const prisma: AutoBeDatabaseHistory | undefined = histories.find(
|
|
73
|
+
(h) => h.type === "database",
|
|
74
|
+
);
|
|
75
|
+
return prisma !== undefined && prisma.compiled.type === "success";
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export const archiveInterface = (ctx: IContext): Promise<boolean> =>
|
|
80
|
+
archive(ctx, {
|
|
81
|
+
phase: "interface",
|
|
82
|
+
trial: getTrial({
|
|
83
|
+
project: ctx.project,
|
|
84
|
+
phase: "interface",
|
|
85
|
+
}),
|
|
86
|
+
predicate: (histories): boolean => {
|
|
87
|
+
const interfaceHistory: AutoBeHistory | undefined = histories.find(
|
|
88
|
+
(h) => h.type === "interface",
|
|
89
|
+
);
|
|
90
|
+
return (
|
|
91
|
+
interfaceHistory !== undefined && interfaceHistory.missed.length === 0
|
|
92
|
+
);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export const archiveTest = (ctx: IContext): Promise<boolean> =>
|
|
97
|
+
archive(ctx, {
|
|
98
|
+
phase: "test",
|
|
99
|
+
trial: getTrial({
|
|
100
|
+
project: ctx.project,
|
|
101
|
+
phase: "test",
|
|
102
|
+
}),
|
|
103
|
+
predicate: (histories): boolean => {
|
|
104
|
+
const testHistory: AutoBeHistory | undefined = histories.find(
|
|
105
|
+
(h) => h.type === "test",
|
|
106
|
+
);
|
|
107
|
+
return (
|
|
108
|
+
testHistory !== undefined && testHistory.compiled.type === "success"
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
export const archiveRealize = (ctx: IContext): Promise<boolean> =>
|
|
114
|
+
archive(ctx, {
|
|
115
|
+
phase: "realize",
|
|
116
|
+
trial: getTrial({
|
|
117
|
+
project: ctx.project,
|
|
118
|
+
phase: "realize",
|
|
119
|
+
}),
|
|
120
|
+
predicate: (histories): boolean => {
|
|
121
|
+
const realizeHistory: AutoBeHistory | undefined = histories.find(
|
|
122
|
+
(h) => h.type === "realize",
|
|
123
|
+
);
|
|
124
|
+
return (
|
|
125
|
+
realizeHistory !== undefined &&
|
|
126
|
+
realizeHistory.compiled.type === "success"
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const archive = async (
|
|
132
|
+
ctx: IContext,
|
|
133
|
+
props: {
|
|
134
|
+
phase: AutoBePhase;
|
|
135
|
+
trial: (
|
|
136
|
+
conversate: (
|
|
137
|
+
input:
|
|
138
|
+
| string
|
|
139
|
+
| AutoBeUserConversateContent
|
|
140
|
+
| AutoBeUserConversateContent[],
|
|
141
|
+
) => Promise<boolean>,
|
|
142
|
+
) => Promise<boolean>;
|
|
143
|
+
predicate: (histories: AutoBeHistory[]) => boolean;
|
|
144
|
+
},
|
|
145
|
+
): Promise<boolean> => {
|
|
146
|
+
// INITIALIZE AGENT
|
|
147
|
+
const asset: IAgentProps = await getAsset({
|
|
148
|
+
vendor: ctx.vendor,
|
|
149
|
+
project: ctx.project,
|
|
150
|
+
phase: props.phase,
|
|
151
|
+
});
|
|
152
|
+
const agent: IAutoBeAgent = await ctx.agent(asset);
|
|
153
|
+
const snapshots: AutoBeEventSnapshot[] = [];
|
|
154
|
+
for (const type of typia.misc.literals<AutoBeEventOfSerializable.Type>()) {
|
|
155
|
+
agent.on(type, (e) => {
|
|
156
|
+
const s: AutoBeEventSnapshot = {
|
|
157
|
+
event: e,
|
|
158
|
+
tokenUsage: typia.misc.clone<IAutoBeTokenUsageJson>(
|
|
159
|
+
agent.getTokenUsage(),
|
|
160
|
+
),
|
|
161
|
+
};
|
|
162
|
+
ctx.on(s, agent);
|
|
163
|
+
snapshots.push(s);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const summarize = async (
|
|
168
|
+
histories: AutoBeHistory[],
|
|
169
|
+
error: boolean,
|
|
170
|
+
): Promise<void> => {
|
|
171
|
+
const replay: IAutoBePlaygroundReplay = {
|
|
172
|
+
vendor: ctx.vendor,
|
|
173
|
+
project: ctx.project,
|
|
174
|
+
histories,
|
|
175
|
+
analyze: null,
|
|
176
|
+
database: null,
|
|
177
|
+
interface: null,
|
|
178
|
+
test: null,
|
|
179
|
+
realize: null,
|
|
180
|
+
};
|
|
181
|
+
for (const phase of PHASES)
|
|
182
|
+
if (phase === props.phase) {
|
|
183
|
+
replay[phase] = snapshots;
|
|
184
|
+
break;
|
|
185
|
+
} else
|
|
186
|
+
replay[phase] = await AutoBeExampleStorage.getSnapshots({
|
|
187
|
+
vendor: ctx.vendor,
|
|
188
|
+
project: ctx.project,
|
|
189
|
+
phase,
|
|
190
|
+
});
|
|
191
|
+
const summary: IAutoBePlaygroundReplay.ISummary =
|
|
192
|
+
AutoBeReplayComputer.summarize(replay);
|
|
193
|
+
if (error === true) {
|
|
194
|
+
const aggregates: AutoBeProcessAggregateCollection =
|
|
195
|
+
AutoBeProcessAggregateFactory.createCollection();
|
|
196
|
+
for (const { event } of snapshots) {
|
|
197
|
+
if (typia.is<AutoBeAggregateEventBase>(event) === false) continue;
|
|
198
|
+
AutoBeProcessAggregateFactory.emplaceEvent(aggregates, event);
|
|
199
|
+
}
|
|
200
|
+
summary[props.phase] = {
|
|
201
|
+
aggregates,
|
|
202
|
+
success: false,
|
|
203
|
+
elapsed: 0,
|
|
204
|
+
commodity: {},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
await AutoBeExampleStorage.save({
|
|
208
|
+
vendor: ctx.vendor,
|
|
209
|
+
project: ctx.project,
|
|
210
|
+
files: {
|
|
211
|
+
[`summary.json`]: JSON.stringify(summary),
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
let lastFunctionCallErrorMessage: string | null = null;
|
|
218
|
+
// CONVERSATE
|
|
219
|
+
const go = async (
|
|
220
|
+
c: string | AutoBeUserConversateContent | AutoBeUserConversateContent[],
|
|
221
|
+
): Promise<boolean> => {
|
|
222
|
+
try {
|
|
223
|
+
const result: AutoBeHistory[] = await agent.conversate(c);
|
|
224
|
+
const hasMeaningfulOutput: boolean = result.some(
|
|
225
|
+
(h) => h.type !== "userMessage",
|
|
226
|
+
);
|
|
227
|
+
return (
|
|
228
|
+
result.some((h) => h.type === props.phase) ||
|
|
229
|
+
(hasMeaningfulOutput &&
|
|
230
|
+
result.every((h) => h.type !== "assistantMessage"))
|
|
231
|
+
);
|
|
232
|
+
} catch (error: unknown) {
|
|
233
|
+
if (
|
|
234
|
+
error instanceof Error &&
|
|
235
|
+
error.message.includes("Failed to function calling")
|
|
236
|
+
) {
|
|
237
|
+
lastFunctionCallErrorMessage = error.message;
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
const done: boolean = await props.trial(go);
|
|
245
|
+
const histories: AutoBeHistory[] = agent.getHistories();
|
|
246
|
+
if (
|
|
247
|
+
done === false ||
|
|
248
|
+
histories.some((h) => h.type === props.phase) === false
|
|
249
|
+
) {
|
|
250
|
+
const detail: string | null = lastFunctionCallErrorMessage;
|
|
251
|
+
throw new Error(
|
|
252
|
+
detail
|
|
253
|
+
? `Failed to function calling in the "${props.phase}" phase of the "${ctx.project}" project.\n\n${detail}`
|
|
254
|
+
: `Failed to function calling in the "${props.phase}" phase of the "${ctx.project}" project.`,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// AGGREGATE
|
|
259
|
+
try {
|
|
260
|
+
await FileSystemIterator.save({
|
|
261
|
+
root: `${
|
|
262
|
+
AutoBeExampleStorage.TEST_ROOT
|
|
263
|
+
}/results/${AutoBeExampleStorage.slugModel(ctx.vendor, false)}/${
|
|
264
|
+
ctx.project
|
|
265
|
+
}/${props.phase}`,
|
|
266
|
+
files: {
|
|
267
|
+
...(await agent.getFiles()),
|
|
268
|
+
...Object.fromEntries(
|
|
269
|
+
histories
|
|
270
|
+
.filter(
|
|
271
|
+
(h) =>
|
|
272
|
+
h.type === "database" ||
|
|
273
|
+
h.type === "interface" ||
|
|
274
|
+
h.type === "test" ||
|
|
275
|
+
h.type === "realize",
|
|
276
|
+
)
|
|
277
|
+
.map((h) => [`autobe/${h.type}.instruction.md`, h.instruction]),
|
|
278
|
+
),
|
|
279
|
+
"pnpm-workspace.yaml": "",
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
} catch {}
|
|
283
|
+
await AutoBeExampleStorage.save({
|
|
284
|
+
vendor: ctx.vendor,
|
|
285
|
+
project: ctx.project,
|
|
286
|
+
files: {
|
|
287
|
+
[`${props.phase}.histories.json`]: JSON.stringify(histories),
|
|
288
|
+
[`${props.phase}.snapshots.json`]: JSON.stringify(snapshots),
|
|
289
|
+
[`${props.phase}.error.json`]: null,
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
await summarize([...asset.histories, ...histories], false);
|
|
293
|
+
return props.predicate(histories);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (error instanceof Error)
|
|
296
|
+
await AutoBeExampleStorage.save({
|
|
297
|
+
vendor: ctx.vendor,
|
|
298
|
+
project: ctx.project,
|
|
299
|
+
files: {
|
|
300
|
+
[`${props.phase}.snapshots.json`]: JSON.stringify(snapshots),
|
|
301
|
+
[`${props.phase}.histories.json`]: JSON.stringify(
|
|
302
|
+
agent.getHistories(),
|
|
303
|
+
),
|
|
304
|
+
[`${props.phase}.error.json`]: JSON.stringify({
|
|
305
|
+
...error,
|
|
306
|
+
name: error.name,
|
|
307
|
+
message: error.message,
|
|
308
|
+
stack: error.stack,
|
|
309
|
+
}),
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
await summarize(asset.histories, true);
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const getTrial =
|
|
318
|
+
(props: { project: AutoBeExampleProject; phase: AutoBePhase }) =>
|
|
319
|
+
async (
|
|
320
|
+
conversate: (
|
|
321
|
+
input:
|
|
322
|
+
| string
|
|
323
|
+
| AutoBeUserConversateContent
|
|
324
|
+
| AutoBeUserConversateContent[],
|
|
325
|
+
) => Promise<boolean>,
|
|
326
|
+
): Promise<boolean> =>
|
|
327
|
+
(await conversate(await AutoBeExampleStorage.getUserMessage(props))) ||
|
|
328
|
+
(await conversate(
|
|
329
|
+
"Don't ask me to do that, and just do it right now.",
|
|
330
|
+
)) ||
|
|
331
|
+
(await conversate(
|
|
332
|
+
`I already told you to do ${props.phase} process. Never ask me anything, and just do it right now. Go go go!`,
|
|
333
|
+
));
|
|
334
|
+
|
|
335
|
+
const getAsset = async (props: {
|
|
336
|
+
vendor: string;
|
|
337
|
+
project: AutoBeExampleProject;
|
|
338
|
+
phase: AutoBePhase;
|
|
339
|
+
}): Promise<IAgentProps> => {
|
|
340
|
+
const previous: AutoBePhase | null =
|
|
341
|
+
PHASES[PHASES.indexOf(props.phase) - 1] ?? null;
|
|
342
|
+
if (previous === null)
|
|
343
|
+
return {
|
|
344
|
+
vendor: props.vendor,
|
|
345
|
+
histories: [],
|
|
346
|
+
tokenUsage: {
|
|
347
|
+
aggregate: TokenUsageComputer.zero(),
|
|
348
|
+
facade: TokenUsageComputer.zero(),
|
|
349
|
+
analyze: TokenUsageComputer.zero(),
|
|
350
|
+
database: TokenUsageComputer.zero(),
|
|
351
|
+
interface: TokenUsageComputer.zero(),
|
|
352
|
+
test: TokenUsageComputer.zero(),
|
|
353
|
+
realize: TokenUsageComputer.zero(),
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
const histories: AutoBeHistory[] = await AutoBeExampleStorage.getHistories({
|
|
357
|
+
vendor: props.vendor,
|
|
358
|
+
project: props.project,
|
|
359
|
+
phase: previous,
|
|
360
|
+
});
|
|
361
|
+
const tokenUsage: IAutoBeTokenUsageJson =
|
|
362
|
+
await AutoBeExampleStorage.getTokenUsage({
|
|
363
|
+
vendor: props.vendor,
|
|
364
|
+
project: props.project,
|
|
365
|
+
phase: previous,
|
|
366
|
+
});
|
|
367
|
+
return {
|
|
368
|
+
vendor: props.vendor,
|
|
369
|
+
histories,
|
|
370
|
+
tokenUsage,
|
|
371
|
+
};
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const PHASES: AutoBePhase[] = [
|
|
376
|
+
"analyze",
|
|
377
|
+
"database",
|
|
378
|
+
"interface",
|
|
379
|
+
"test",
|
|
380
|
+
"realize",
|
|
381
|
+
];
|