@autobe/agent
Version:
AI backend server code generator
224 lines (214 loc) • 6.59 kB
text/typescript
import {
AutoBeFunctionCallingMetric,
AutoBeRealizeCorrectEvent,
AutoBeRealizeValidateEvent,
AutoBeTestCorrectEvent,
AutoBeTestValidateEvent,
IAutoBeTokenUsageJson,
IAutoBeTypeScriptCompileResult,
} from "@autobe/interface";
import { IPointer } from "tstl";
import typia, { ILlmApplication, ILlmController, IValidation } from "typia";
import { AutoBeConfigConstant } from "../../constants/AutoBeConfigConstant";
import { AutoBeContext } from "../../context/AutoBeContext";
import { transformCommonCorrectCastingHistory } from "./histories/transformCommonCorrectCastingHistory";
import { IAutoBeCommonCorrectCastingApplication } from "./structures/IAutoBeCommonCorrectCastingApplication";
interface IFactoryProps<
ValidateEvent extends AutoBeTestValidateEvent | AutoBeRealizeValidateEvent,
CorrectEvent extends AutoBeTestCorrectEvent | AutoBeRealizeCorrectEvent,
> {
compile(script: string): Promise<ValidateEvent>;
correct(next: {
failure: IAutoBeTypeScriptCompileResult.IFailure;
think: string;
draft: string;
review: string | undefined;
final: string | undefined;
metric: AutoBeFunctionCallingMetric;
tokenUsage: IAutoBeTokenUsageJson.IComponent;
}): Promise<CorrectEvent>;
script(event: ValidateEvent): string;
validateEmptyCode(props: {
path: string;
draft: string;
revise: {
final: string | null;
};
}): IValidation.IError[];
location: string;
source: "testCorrect" | "realizeCorrect";
}
export const orchestrateCommonCorrectCasting = async <
ValidateEvent extends AutoBeTestValidateEvent | AutoBeRealizeValidateEvent,
CorrectEvent extends AutoBeTestCorrectEvent | AutoBeRealizeCorrectEvent,
>(
ctx: AutoBeContext,
factory: IFactoryProps<ValidateEvent, CorrectEvent>,
script: string,
): Promise<ValidateEvent> => {
const event: ValidateEvent = await compileWithFiltering({
compile: factory.compile,
location: factory.location,
script,
});
return await predicate(
ctx,
factory,
[],
script,
event,
AutoBeConfigConstant.COMPILER_RETRY,
);
};
const predicate = async <
ValidateEvent extends AutoBeTestValidateEvent | AutoBeRealizeValidateEvent,
CorrectEvent extends AutoBeTestCorrectEvent | AutoBeRealizeCorrectEvent,
>(
ctx: AutoBeContext,
factory: IFactoryProps<ValidateEvent, CorrectEvent>,
failures: ValidateEvent[],
script: string,
event: ValidateEvent,
life: number,
): Promise<ValidateEvent> => {
if (event.result.type === "failure") {
ctx.dispatch(event);
try {
return await correct(ctx, factory, failures, script, event, life - 1);
} catch (error) {
console.log("correctCasting", error);
return await correct(ctx, factory, failures, script, event, life - 2);
}
}
return event;
};
const correct = async <
ValidateEvent extends AutoBeTestValidateEvent | AutoBeRealizeValidateEvent,
CorrectEvent extends AutoBeTestCorrectEvent | AutoBeRealizeCorrectEvent,
>(
ctx: AutoBeContext,
factory: IFactoryProps<ValidateEvent, CorrectEvent>,
failures: ValidateEvent[],
script: string,
event: ValidateEvent,
life: number,
): Promise<ValidateEvent> => {
if (event.result.type !== "failure") return event;
else if (life < 0) return event;
const pointer: IPointer<
IAutoBeCommonCorrectCastingApplication.IProps | false | null
> = {
value: null,
};
const { metric, tokenUsage } = await ctx.conversate({
source: factory.source,
controller: createController({
factory: factory,
then: (next) => {
pointer.value = next;
},
reject: () => {
pointer.value = false;
},
}),
enforceFunctionCall: true,
...transformCommonCorrectCastingHistory(
[...failures, event].map((e) => ({
diagnostics: (e.result as IAutoBeTypeScriptCompileResult.IFailure)
.diagnostics,
script: factory.script(e),
})),
),
});
if (pointer.value === null) throw new Error("Failed to correct test code.");
else if (pointer.value === false) return event;
ctx.dispatch(
await factory.correct({
failure: event.result,
think: pointer.value.think,
draft: pointer.value.draft,
review: pointer.value.revise.review,
final: pointer.value.revise.final ?? undefined,
metric,
tokenUsage,
}),
);
return await predicate(
ctx,
factory,
[...failures, event],
script,
await compileWithFiltering({
compile: factory.compile,
location: factory.location,
script: pointer.value.revise.final ?? pointer.value.draft,
}),
life - 1,
);
};
const compileWithFiltering = async <
ValidateEvent extends AutoBeTestValidateEvent | AutoBeRealizeValidateEvent,
>(props: {
compile: (script: string) => Promise<ValidateEvent>;
script: string;
location: string;
}): Promise<ValidateEvent> => {
const event: ValidateEvent = await props.compile(props.script);
if (event.result.type === "failure") {
event.result.diagnostics = event.result.diagnostics.filter(
(d) => d.file === props.location,
);
if (event.result.diagnostics.length === 0)
event.result = { type: "success" };
}
return event;
};
const createController = (props: {
// biome-ignore lint: intended
factory: IFactoryProps<any, any>;
then: (next: IAutoBeCommonCorrectCastingApplication.IProps) => void;
reject: () => void;
}): ILlmController => {
const validate = (
input: unknown,
): IValidation<IAutoBeCommonCorrectCastingApplication.IProps> => {
const result: IValidation<IAutoBeCommonCorrectCastingApplication.IProps> =
typia.validate<IAutoBeCommonCorrectCastingApplication.IProps>(input);
if (result.success === false) return result;
const errors: IValidation.IError[] = props.factory.validateEmptyCode({
draft: result.data.draft,
revise: result.data.revise,
path: "$input",
});
return errors.length
? {
success: false,
errors,
data: result.data,
}
: result;
};
const application: ILlmApplication =
typia.llm.application<IAutoBeCommonCorrectCastingApplication>({
validate: {
rewrite: validate,
reject: () => ({
success: true,
data: undefined,
}),
},
});
return {
protocol: "class",
name: "correctInvalidRequest",
application,
execute: {
rewrite: (next) => {
props.then(next);
},
reject: () => {
props.reject();
},
} satisfies IAutoBeCommonCorrectCastingApplication,
};
};