@autobe/agent
Version:
AI backend server code generator
199 lines (193 loc) • 7.41 kB
text/typescript
import {
AutoBeOpenApi,
AutoBeProgressEventBase,
AutoBeRealizeAuthorization,
AutoBeRealizeCollectorFunction,
AutoBeRealizeOperationFunction,
AutoBeRealizeTransformerFunction,
} from "@autobe/interface";
import typia, { ILlmApplication, IValidation } from "typia";
import { AutoBeContext } from "../../context/AutoBeContext";
import { validateEmptyCode } from "../../utils/validateEmptyCode";
import { AutoBePreliminaryController } from "../common/AutoBePreliminaryController";
import { orchestrateRealizeCorrectOverall } from "./correct/orchestrateRealizeCorrectOverall";
import { transformRealizeOperationCorrectHistory } from "./histories/transformRealizeOperationCorrectHistory";
import { AutoBeRealizeOperationProgrammer } from "./programmers/AutoBeRealizeOperationProgrammer";
import { IAutoBeRealizeFunctionResult } from "./structures/IAutoBeRealizeFunctionResult";
import { IAutoBeRealizeOperationCorrectApplication } from "./structures/IAutoBeRealizeOperationCorrectApplication";
import { IAutoBeRealizeScenarioResult } from "./structures/IAutoBeRealizeScenarioResult";
export const orchestrateRealizeOperationCorrectOverall = async (
ctx: AutoBeContext,
props: {
authorizations: AutoBeRealizeAuthorization[];
collectors: AutoBeRealizeCollectorFunction[];
transformers: AutoBeRealizeTransformerFunction[];
functions: AutoBeRealizeOperationFunction[];
progress: AutoBeProgressEventBase;
},
): Promise<IAutoBeRealizeFunctionResult<AutoBeRealizeOperationFunction>[]> => {
const document: AutoBeOpenApi.IDocument = ctx.state().interface!.document;
return await orchestrateRealizeCorrectOverall(ctx, {
programmer: {
location: "src/providers",
template: (func) =>
AutoBeRealizeOperationProgrammer.writeTemplate({
authorizations: props.authorizations,
schemas: document.components.schemas,
operation: document.operations.find(
(o) =>
o.method === func.endpoint.method &&
o.path === func.endpoint.path,
)!,
collectors: props.collectors,
transformers: props.transformers,
}),
replaceImportStatements: async (next) => {
const scenario: IAutoBeRealizeScenarioResult =
AutoBeRealizeOperationProgrammer.getScenario({
authorizations: props.authorizations,
operation: document.operations.find(
(o) =>
o.method === next.function.endpoint.method &&
o.path === next.function.endpoint.path,
)!,
});
return await AutoBeRealizeOperationProgrammer.replaceImportStatements(
ctx,
{
operation: scenario.operation,
schemas: document.components.schemas,
code: next.code,
payload: scenario.decoratorEvent?.payload.name,
},
);
},
additional: () =>
AutoBeRealizeOperationProgrammer.getAdditional({
authorizations: props.authorizations,
collectors: props.collectors,
transformers: props.transformers,
}),
preliminary: (next) => {
const scenario: IAutoBeRealizeScenarioResult =
AutoBeRealizeOperationProgrammer.getScenario({
authorizations: props.authorizations,
operation: document.operations.find(
(o) =>
o.method === next.function.endpoint.method &&
o.path === next.function.endpoint.path,
)!,
});
return new AutoBePreliminaryController({
source: next.source,
dispatch: (e) => ctx.dispatch(e),
application:
typia.json.application<IAutoBeRealizeOperationCorrectApplication>(),
kinds: [
"analysisSections",
"databaseSchemas",
"realizeCollectors",
"realizeTransformers",
],
state: ctx.state(),
all: {
realizeCollectors: props.collectors,
realizeTransformers: props.transformers,
},
local: {
realizeCollectors: props.collectors.filter(
(c) =>
c.plan.dtoTypeName === scenario.operation.requestBody?.typeName,
),
realizeTransformers:
AutoBeRealizeOperationProgrammer.getLocalTransformers({
operation: scenario.operation,
schemas: document.components.schemas,
transformers: props.transformers,
}),
},
});
},
histories: async (next) => {
const operation: AutoBeOpenApi.IOperation = document.operations.find(
(o) =>
o.method === next.function.endpoint.method &&
o.path === next.function.endpoint.path,
)!;
const dto: Record<string, string> =
await AutoBeRealizeOperationProgrammer.writeStructures(
ctx,
operation,
);
return transformRealizeOperationCorrectHistory({
state: ctx.state(),
authorizations: props.authorizations,
collectors: props.collectors,
transformers: props.transformers,
function: next.function,
preliminary: next.preliminary,
dto,
failures: next.failures,
});
},
controller: (next) => {
const validate: Validator = (input) => {
const result: IValidation<IAutoBeRealizeOperationCorrectApplication.IProps> =
typia.validate<IAutoBeRealizeOperationCorrectApplication.IProps>(
input,
);
if (result.success === false) return result;
else if (result.data.request.type !== "write")
return next.preliminary.validate({
thinking: result.data.thinking,
request: result.data.request,
});
const errors: IValidation.IError[] = [
...validateEmptyCode({
name: next.function.name,
draft: result.data.request.draft,
revise: result.data.request.revise,
path: "$input.request",
asynchronous: true,
}),
...AutoBeRealizeOperationProgrammer.validateSelectTransformContract(
{
draft: result.data.request.draft,
revise: result.data.request.revise,
},
),
];
return errors.length
? {
success: false,
errors,
data: result.data,
}
: result;
};
const application: ILlmApplication = next.preliminary.fixApplication(
typia.llm.application<IAutoBeRealizeOperationCorrectApplication>({
validate: {
process: validate,
},
}),
);
return {
protocol: "class",
name: next.source,
application,
execute: {
process: (v) => {
if (v.request.type === "write") next.build(v.request);
},
} satisfies IAutoBeRealizeOperationCorrectApplication,
};
},
},
functions: props.functions,
progress: props.progress,
});
};
type Validator = (
input: unknown,
) => IValidation<IAutoBeRealizeOperationCorrectApplication.IProps>;