@autobe/agent
Version:
AI backend server code generator
617 lines (589 loc) • 20.4 kB
text/typescript
import { AgenticaExecuteHistory, MicroAgenticaHistory } from "@agentica/core";
import {
AutoBeDatabase,
AutoBeEventSource,
AutoBeOpenApi,
AutoBePreliminaryKind,
AutoBeRealizeCollectorFunction,
AutoBeRealizeTransformerFunction,
} from "@autobe/interface";
import { OpenApiTypeChecker } from "@typia/utils";
import { IPointer } from "tstl";
import typia from "typia";
import { v7 } from "uuid";
import { AutoBeContext } from "../../context/AutoBeContext";
import { AutoBePreliminaryController } from "./AutoBePreliminaryController";
import { complementPreliminaryCollection } from "./internal/complementPreliminaryCollection";
import { IAutoBePreliminaryRequest } from "./structures/AutoBePreliminaryRequest";
import { IAnalysisSectionEntry } from "./structures/IAnalysisSectionEntry";
import { IAutoBePreliminaryCollection } from "./structures/IAutoBePreliminaryCollection";
import { IAutoBePreliminaryComplete } from "./structures/IAutoBePreliminaryComplete";
export const orchestratePreliminary = async <
Kind extends AutoBePreliminaryKind,
>(
ctx: AutoBeContext,
props: {
source_id: string;
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
histories: MicroAgenticaHistory[];
preliminary: AutoBePreliminaryController<Kind>;
completed: IPointer<boolean>;
trial: number;
},
): Promise<void> => {
const executes: AgenticaExecuteHistory[] = props.histories.filter(
(h) => h.type === "execute",
);
if (executes.length === 0) {
// Some vendors (notably certain Qwen/OpenRouter routes) occasionally return
// an empty turn where only the user message is recorded. Treat it as a
// transient no-op so the outer RAG loop can retry instead of failing fast.
if (props.histories.every((h) => h.type === "userMessage")) return;
throw new Error("Failed to function calling from the preliminary step.");
}
for (const exec of executes) {
// COMPLETE
if (typia.is<{ request: IAutoBePreliminaryComplete }>(exec.arguments)) {
props.completed.value ||= true;
}
// ANALYSIS
else if (isAnalysisSections(props.preliminary, exec.arguments)) {
const ps: AutoBePreliminaryController<"analysisSections"> =
props.preliminary;
orchestrateAnalysisSections(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: ps.getAll().analysisSections,
local: ps.getLocal().analysisSections,
arguments: exec.arguments,
previous: false,
});
props.preliminary.advanceAnalysisPage();
} else if (isPreviousAnalysisSections(props.preliminary, exec.arguments)) {
const ps: AutoBePreliminaryController<"previousAnalysisSections"> =
props.preliminary;
orchestrateAnalysisSections(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: ps.getAll().previousAnalysisSections,
local: ps.getLocal().previousAnalysisSections,
arguments: exec.arguments,
previous: true,
});
props.preliminary.advanceAnalysisPage();
}
// PRISMA SCHEMAS
else if (isPrismaSchemas(props.preliminary, exec.arguments)) {
const pp: AutoBePreliminaryController<"databaseSchemas"> =
props.preliminary;
orchestratePrismaSchemas(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: pp.getAll().databaseSchemas,
local: pp.getLocal().databaseSchemas,
arguments: exec.arguments,
previous: false,
});
} else if (isPreviousPrismaSchemas(props.preliminary, exec.arguments)) {
const pp: AutoBePreliminaryController<"previousDatabaseSchemas"> =
props.preliminary;
orchestratePrismaSchemas(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: pp.getAll().previousDatabaseSchemas,
local: pp.getLocal().previousDatabaseSchemas,
arguments: exec.arguments,
previous: true,
});
}
// INTERFACE OPERATIONS
else if (isInterfaceOperations(props.preliminary, exec.arguments)) {
const pi: AutoBePreliminaryController<"interfaceOperations"> =
props.preliminary;
orchestrateInterfaceOperations(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: pi.getAll().interfaceOperations,
local: pi.getLocal().interfaceOperations,
arguments: exec.arguments,
previous: false,
});
} else if (
isPreviousInterfaceOperations(props.preliminary, exec.arguments)
) {
const pi: AutoBePreliminaryController<"previousInterfaceOperations"> =
props.preliminary;
orchestrateInterfaceOperations(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: pi.getAll().previousInterfaceOperations,
local: pi.getLocal().previousInterfaceOperations,
arguments: exec.arguments,
previous: true,
});
}
// INTERFACE SCHEMAS
else if (isInterfaceSchemas(props.preliminary, exec.arguments)) {
const ps: AutoBePreliminaryController<"interfaceSchemas"> =
props.preliminary;
orchestrateInterfaceSchemas(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: ps.getAll().interfaceSchemas,
local: ps.getLocal().interfaceSchemas,
arguments: exec.arguments,
previous: false,
});
} else if (isPreviousInterfaceSchemas(props.preliminary, exec.arguments)) {
const ps: AutoBePreliminaryController<"previousInterfaceSchemas"> =
props.preliminary;
orchestrateInterfaceSchemas(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: ps.getAll().previousInterfaceSchemas,
local: ps.getLocal().previousInterfaceSchemas,
arguments: exec.arguments,
previous: true,
});
}
// REALIZE COLLECTORS
else if (isRealizeCollectors(props.preliminary, exec.arguments)) {
const rc: AutoBePreliminaryController<"realizeCollectors"> =
props.preliminary;
orchestrateRealizeCollectors(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: rc.getAll().realizeCollectors,
local: rc.getLocal().realizeCollectors,
arguments: exec.arguments,
});
}
// REALIZE TRANSFORMERS
else if (isRealizeTransformers(props.preliminary, exec.arguments)) {
const rt: AutoBePreliminaryController<"realizeTransformers"> =
props.preliminary;
orchestrateRealizeTransformers(ctx, {
source: props.source,
source_id: props.source_id,
trial: props.trial,
all: rt.getAll().realizeTransformers,
local: rt.getLocal().realizeTransformers,
arguments: exec.arguments,
});
}
}
complementPreliminaryCollection({
kinds: props.preliminary.getKinds(),
all: props.preliminary.getAll() as IAutoBePreliminaryCollection,
local: props.preliminary.getLocal() as IAutoBePreliminaryCollection,
prerequisite: false,
});
};
/* -----------------------------------------------------------
TYPE CHECKERS
----------------------------------------------------------- */
const isAnalysisSections = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"analysisSections"> =>
typia.is<IAutoBePreliminaryRequest<"analysisSections">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "analysisSections">
>()[0]
] !== undefined;
const isPreviousAnalysisSections = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"previousAnalysisSections"> =>
typia.is<IAutoBePreliminaryRequest<"previousAnalysisSections">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "previousAnalysisSections">
>()[0]
] !== undefined;
const isPrismaSchemas = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"databaseSchemas"> =>
typia.is<IAutoBePreliminaryRequest<"databaseSchemas">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "databaseSchemas">
>()[0]
] !== undefined;
const isPreviousPrismaSchemas = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"previousDatabaseSchemas"> =>
typia.is<IAutoBePreliminaryRequest<"previousDatabaseSchemas">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "previousDatabaseSchemas">
>()[0]
] !== undefined;
const isInterfaceOperations = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"interfaceOperations"> =>
typia.is<IAutoBePreliminaryRequest<"interfaceOperations">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "interfaceOperations">
>()[0]
] !== undefined;
const isPreviousInterfaceOperations = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"previousInterfaceOperations"> =>
typia.is<IAutoBePreliminaryRequest<"previousInterfaceOperations">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "previousInterfaceOperations">
>()[0]
] !== undefined;
const isInterfaceSchemas = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"interfaceSchemas"> =>
typia.is<IAutoBePreliminaryRequest<"interfaceSchemas">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "interfaceSchemas">
>()[0]
] !== undefined;
const isPreviousInterfaceSchemas = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"previousInterfaceSchemas"> =>
typia.is<IAutoBePreliminaryRequest<"previousInterfaceSchemas">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "previousInterfaceSchemas">
>()[0]
] !== undefined;
const isRealizeCollectors = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"realizeCollectors"> =>
typia.is<IAutoBePreliminaryRequest<"realizeCollectors">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "realizeCollectors">
>()[0]
] !== undefined;
const isRealizeTransformers = (
// biome-ignore lint: intended
preliminary: AutoBePreliminaryController<any>,
input: unknown,
): preliminary is AutoBePreliminaryController<"realizeTransformers"> =>
typia.is<IAutoBePreliminaryRequest<"realizeTransformers">>(input) &&
preliminary.getAll()[
typia.misc.literals<
Extract<keyof IAutoBePreliminaryCollection, "realizeTransformers">
>()[0]
] !== undefined;
/* -----------------------------------------------------------
ORCHESTRATORS
----------------------------------------------------------- */
const orchestrateAnalysisSections = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: IAnalysisSectionEntry[];
local: IAnalysisSectionEntry[];
arguments: unknown;
previous: boolean;
},
): void => {
if (props.previous) {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"previousAnalysisSections">>(
props.arguments,
)
)
return;
} else if (
false ===
typia.is<IAutoBePreliminaryRequest<"analysisSections">>(props.arguments)
)
return;
const existing: number[] = props.local.map((s) => s.id);
for (const sectionId of props.arguments.request.sectionIds) {
const section: IAnalysisSectionEntry | undefined = props.all.find(
(s) => s.id === sectionId,
);
if (section === undefined) continue;
else if (props.local.find((s) => s.id === sectionId) === undefined)
props.local.push(section);
}
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: props.previous ? "previousAnalysisSections" : "analysisSections",
source: props.source,
source_id: props.source_id,
// biome-ignore lint/suspicious/noExplicitAny: conditional type narrowing not available at dispatch site
existing: existing as any,
// biome-ignore lint/suspicious/noExplicitAny: conditional type narrowing not available at dispatch site
requested: props.arguments.request.sectionIds as any,
trial: props.trial,
created_at: new Date().toISOString(),
});
};
const orchestratePrismaSchemas = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: AutoBeDatabase.IModel[];
local: AutoBeDatabase.IModel[];
arguments: unknown;
previous: boolean;
},
): void => {
if (props.previous) {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"previousDatabaseSchemas">>(
props.arguments,
)
)
return;
} else if (
false ===
typia.is<IAutoBePreliminaryRequest<"databaseSchemas">>(props.arguments)
)
return;
const existing: string[] = props.local.map((m) => m.name);
for (const name of props.arguments.request.schemaNames) {
const model: AutoBeDatabase.IModel | undefined = props.all.find(
(m) => m.name === name,
);
if (model === undefined) continue;
else if (props.local.find((m) => m.name === name) === undefined)
props.local.push(model);
}
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: props.previous ? "previousDatabaseSchemas" : "databaseSchemas",
source: props.source,
source_id: props.source_id,
existing,
requested: props.arguments.request.schemaNames,
trial: props.trial,
created_at: new Date().toISOString(),
});
};
const orchestrateInterfaceOperations = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: AutoBeOpenApi.IOperation[];
local: AutoBeOpenApi.IOperation[];
arguments: unknown;
previous: boolean;
},
): void => {
if (props.previous) {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"previousInterfaceOperations">>(
props.arguments,
)
)
return;
} else if (
false ===
typia.is<IAutoBePreliminaryRequest<"interfaceOperations">>(props.arguments)
)
return;
const existing: AutoBeOpenApi.IEndpoint[] = props.local.map((o) => ({
method: o.method,
path: o.path,
}));
for (const endpoint of props.arguments.request.endpoints) {
if (
props.local.find(
(v) => v.method === endpoint.method && v.path === endpoint.path,
) !== undefined
)
continue; // duplicated
const operation: AutoBeOpenApi.IOperation | undefined = props.all.find(
(v) => v.method === endpoint.method && v.path === endpoint.path,
);
if (operation !== undefined) props.local.push(operation);
}
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: props.previous
? "previousInterfaceOperations"
: "interfaceOperations",
source: props.source,
source_id: props.source_id,
existing,
requested: props.arguments.request.endpoints,
trial: props.trial,
created_at: new Date().toISOString(),
});
};
const orchestrateInterfaceSchemas = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: Record<string, AutoBeOpenApi.IJsonSchemaDescriptive>;
local: Record<string, AutoBeOpenApi.IJsonSchemaDescriptive>;
arguments: unknown;
previous: boolean;
},
dispatch: boolean = true,
): void => {
if (props.previous) {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"previousInterfaceSchemas">>(
props.arguments,
)
)
return;
} else if (
false ===
typia.is<IAutoBePreliminaryRequest<"interfaceSchemas">>(props.arguments)
)
return;
const existing: string[] = Object.keys(props.local);
const collected: Record<string, AutoBeOpenApi.IJsonSchemaDescriptive> = {};
for (const key of props.arguments.request.typeNames) {
OpenApiTypeChecker.visit({
components: {
schemas: props.all,
},
schema: { $ref: `#/components/schemas/${key}` },
closure: (next) => {
if (OpenApiTypeChecker.isReference(next)) {
const last: string = next.$ref.split("/").pop()!;
if (props.all[last] !== undefined) collected[last] = props.all[last];
}
},
});
}
Object.assign(props.local, collected);
if (dispatch === true)
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: props.previous
? "previousInterfaceSchemas"
: "interfaceSchemas",
source: props.source,
source_id: props.source_id,
existing,
requested: props.arguments.request.typeNames,
trial: props.trial,
created_at: new Date().toISOString(),
});
};
const orchestrateRealizeCollectors = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: AutoBeRealizeCollectorFunction[];
local: AutoBeRealizeCollectorFunction[];
arguments: unknown;
},
): void => {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"realizeCollectors">>(props.arguments)
)
return;
const existing: string[] = props.local.map((c) => c.plan.dtoTypeName);
for (const dtoTypeName of props.arguments.request.dtoTypeNames) {
const collector: AutoBeRealizeCollectorFunction | undefined =
props.all.find((c) => c.plan.dtoTypeName === dtoTypeName);
if (collector === undefined) continue;
else if (
props.local.find((c) => c.plan.dtoTypeName === dtoTypeName) === undefined
)
props.local.push(collector);
}
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: "realizeCollectors",
source: props.source,
source_id: props.source_id,
existing,
requested: props.arguments.request.dtoTypeNames,
trial: props.trial,
created_at: new Date().toISOString(),
});
};
const orchestrateRealizeTransformers = (
ctx: AutoBeContext,
props: {
source: Exclude<AutoBeEventSource, "facade" | "preliminaryAcquire">;
source_id: string;
trial: number;
all: AutoBeRealizeTransformerFunction[];
local: AutoBeRealizeTransformerFunction[];
arguments: unknown;
},
): void => {
if (
false ===
typia.is<IAutoBePreliminaryRequest<"realizeTransformers">>(props.arguments)
)
return;
const existing: string[] = props.local.map((t) => t.plan.dtoTypeName);
for (const dtoTypeName of props.arguments.request.dtoTypeNames) {
const transformer: AutoBeRealizeTransformerFunction | undefined =
props.all.find((t) => t.plan.dtoTypeName === dtoTypeName);
if (
transformer !== undefined &&
existing.find((e) => e === dtoTypeName) === undefined
)
props.local.push(transformer);
}
ctx.dispatch({
type: "preliminaryAcquire",
id: v7(),
function: "realizeTransformers",
source: props.source,
source_id: props.source_id,
existing,
requested: props.arguments.request.dtoTypeNames,
trial: props.trial,
created_at: new Date().toISOString(),
});
};