UNPKG

@autobe/agent

Version:

AI backend server code generator

221 lines (212 loc) 6.91 kB
import { IAgenticaController } from "@agentica/core"; import { AutoBeAnalyze, AutoBeEventSource, AutoBeInterfaceAuthorization, AutoBeInterfaceAuthorizationEvent, AutoBeOpenApi, AutoBeProgressEventBase, } from "@autobe/interface"; import { NamingConvention } from "@typia/utils"; import { IPointer, Singleton } from "tstl"; import typia, { ILlmApplication, IValidation } from "typia"; import { v7 } from "uuid"; import { AutoBeContext } from "../../context/AutoBeContext"; import { executeCachedBatch } from "../../utils/executeCachedBatch"; import { AutoBePreliminaryController } from "../common/AutoBePreliminaryController"; import { transformInterfaceAuthorizationHistory } from "./histories/transformInterfaceAuthorizationHistory"; import { AutoBeInterfaceAuthorizationProgrammer } from "./programmers/AutoBeInterfaceAuthorizationProgrammer"; import { IAutoBeInterfaceAuthorizationApplication } from "./structures/IAutoBeInterfaceAuthorizationApplication"; import { AutoBeJsonSchemaFactory } from "./utils/AutoBeJsonSchemaFactory"; export async function orchestrateInterfaceAuthorization( ctx: AutoBeContext, props: { instruction: string; }, ): Promise<AutoBeInterfaceAuthorization[]> { const actors: AutoBeAnalyze.IActor[] = ctx.state().analyze?.actors ?? []; const progress: AutoBeProgressEventBase = { total: actors.length, completed: 0, }; return await executeCachedBatch( ctx, actors.map((a) => async (promptCacheKey) => { const counter = new Singleton(() => ++progress.completed); try { const event: AutoBeInterfaceAuthorizationEvent = await process(ctx, { actor: a, progress, counter, promptCacheKey, instruction: props.instruction, }); ctx.dispatch(event); return { name: a.name, operations: event.operations, }; } catch (error) { counter.get(); throw error; } }), ); } async function process( ctx: AutoBeContext, props: { instruction: string; actor: AutoBeAnalyze.IActor; progress: AutoBeProgressEventBase; counter: Singleton<number>; promptCacheKey: string; }, ): Promise<AutoBeInterfaceAuthorizationEvent> { const prefix: string = NamingConvention.camel(ctx.state().analyze!.prefix); const preliminary: AutoBePreliminaryController< | "analysisSections" | "previousAnalysisSections" | "databaseSchemas" | "previousDatabaseSchemas" | "complete" > = new AutoBePreliminaryController({ application: typia.json.application<IAutoBeInterfaceAuthorizationApplication>(), source: SOURCE, kinds: [ "analysisSections", "previousAnalysisSections", "databaseSchemas", "previousDatabaseSchemas", "complete", ], state: ctx.state(), dispatch: (e) => ctx.dispatch(e), }); return await preliminary.orchestrate(ctx, async (out) => { const pointer: IPointer<IAutoBeInterfaceAuthorizationApplication.IWrite | null> = { value: null, }; const result: AutoBeContext.IResult = await ctx.conversate({ source: SOURCE, controller: createController({ actor: props.actor, build: (next) => { pointer.value = next; }, preliminary, prefix, }), enforceFunctionCall: true, promptCacheKey: props.promptCacheKey, ...transformInterfaceAuthorizationHistory({ state: ctx.state(), prefix, instruction: props.instruction, actor: props.actor, preliminary, }), }); if (pointer.value === null) return out(result)(null); const operations: AutoBeOpenApi.IOperation[] = AutoBeInterfaceAuthorizationProgrammer.fixOperations({ operations: pointer.value?.operations ?? [], prefix, }); return out(result)({ type: SOURCE, id: v7(), analysis: pointer.value.analysis, rationale: pointer.value.rationale, operations, acquisition: preliminary.getAcquisition(), metric: result.metric, tokenUsage: result.tokenUsage, created_at: new Date().toISOString(), step: ctx.state().analyze?.step ?? 0, total: props.progress.total, completed: props.counter.get(), } satisfies AutoBeInterfaceAuthorizationEvent); }); } function createController(props: { prefix: string | null; actor: AutoBeAnalyze.IActor; preliminary: AutoBePreliminaryController< | "analysisSections" | "previousAnalysisSections" | "databaseSchemas" | "previousDatabaseSchemas" | "complete" >; build: (next: IAutoBeInterfaceAuthorizationApplication.IWrite) => void; }): IAgenticaController.IClass { const validate = ( next: unknown, ): IValidation<IAutoBeInterfaceAuthorizationApplication.IProps> => { const result: IValidation<IAutoBeInterfaceAuthorizationApplication.IProps> = typia.validate<IAutoBeInterfaceAuthorizationApplication.IProps>(next); if (result.success === false) return result; else if (result.data.request.type !== "write") return props.preliminary.validate({ thinking: result.data.thinking, request: result.data.request, }); const errors: IValidation.IError[] = []; AutoBeInterfaceAuthorizationProgrammer.validateAuthorizationTypes({ errors, actor: props.actor, operations: result.data.request.operations, accessor: "$input.request.operations", }); result.data.request.operations.forEach((operation, index) => AutoBeInterfaceAuthorizationProgrammer.validateOperation({ errors, prefix: props.prefix, actor: props.actor, operation, accessor: `$input.request.operations[${index}]`, }), ); if (errors.length !== 0) { return { success: false, errors, data: next, }; } return result; }; const application: ILlmApplication = props.preliminary.fixApplication( typia.llm.application<IAutoBeInterfaceAuthorizationApplication>({ validate: { process: validate, }, }), ); return { protocol: "class", name: SOURCE, application, execute: { process: (next) => { if (next.request.type === "write") { for (const o of next.request.operations) for (const p of o.parameters) AutoBeJsonSchemaFactory.fixSchema(p.schema); next.request.operations = next.request.operations.filter( (operation) => AutoBeInterfaceAuthorizationProgrammer.filter({ actor: props.actor.kind, operation, }), ); props.build(next.request); } }, } satisfies IAutoBeInterfaceAuthorizationApplication, }; } const SOURCE = "interfaceAuthorization" satisfies AutoBeEventSource;