UNPKG

@autobe/agent

Version:

AI backend server code generator

262 lines (244 loc) 8.38 kB
import { IAgenticaController, MicroAgentica } from "@agentica/core"; import { AutoBeTest, AutoBeTestProgressEvent } from "@autobe/interface"; import { ILlmApplication, ILlmSchema } from "@samchon/openapi"; import { IPointer } from "tstl"; import typia from "typia"; import { AutoBeContext } from "../../context/AutoBeContext"; import { assertSchemaModel } from "../../context/assertSchemaModel"; import { enforceToolCall } from "../../utils/enforceToolCall"; import { transformTestProgressHistories } from "./transformTestProgressHistories"; export async function orchestrateTestProgress<Model extends ILlmSchema.Model>( ctx: AutoBeContext<Model>, scenarios: AutoBeTest.Scenario[], ): Promise<AutoBeTestProgressEvent[]> { const start: Date = new Date(); let complete: number = 0; const events: AutoBeTestProgressEvent[] = await Promise.all( /** * Generate test code for each scenario. Maps through scenarios array to * create individual test code implementations. Each scenario is processed * to generate corresponding test code and progress events. */ scenarios.map(async (scenario) => { const code: ICreateTestCodeProps = await process(ctx, scenario); const event: AutoBeTestProgressEvent = { type: "testProgress", created_at: start.toISOString(), filename: `${code.domain}/${scenario.functionName}.ts`, content: code.content, completed: ++complete, total: scenarios.length, step: ctx.state().interface?.step ?? 0, }; ctx.dispatch(event); return event; }), ); return events; } /** * Process function that generates test code for each individual scenario. Takes * the AutoBeContext and scenario information as input and uses MicroAgentica to * generate appropriate test code through LLM interaction. * * @param ctx - The AutoBeContext containing model, vendor and configuration * @param scenario - The test scenario information to generate code for * @returns Promise resolving to ICreateTestCodeProps containing the generated * test code */ async function process<Model extends ILlmSchema.Model>( ctx: AutoBeContext<Model>, scenario: AutoBeTest.Scenario, ): Promise<ICreateTestCodeProps> { const pointer: IPointer<ICreateTestCodeProps | null> = { value: null, }; const apiFiles = Object.entries(ctx.state().interface?.files ?? {}) .filter(([filename]) => { return filename.startsWith("src/api/"); }) .reduce<Record<string, string>>((acc, [filename, content]) => { return Object.assign(acc, { [filename]: content }); }, {}); const dtoFiles = Object.entries(ctx.state().interface?.files ?? {}) .filter(([filename]) => { return filename.startsWith("src/api/structures/"); }) .reduce<Record<string, string>>((acc, [filename, content]) => { return Object.assign(acc, { [filename]: content }); }, {}); const agentica = new MicroAgentica({ model: ctx.model, vendor: ctx.vendor, config: { ...(ctx.config ?? {}), }, histories: transformTestProgressHistories(apiFiles, dtoFiles), controllers: [ createApplication({ model: ctx.model, build: (next) => { pointer.value = next; }, }), ], }); enforceToolCall(agentica); await agentica.conversate( [ "Create test code for below scenario:", "", "```json", JSON.stringify(scenario, null, 2), "```", ].join("\n"), ); if (pointer.value === null) throw new Error("Failed to create test code."); return pointer.value; } function createApplication<Model extends ILlmSchema.Model>(props: { model: Model; build: (next: ICreateTestCodeProps) => void; }): IAgenticaController.IClass<Model> { assertSchemaModel(props.model); const application: ILlmApplication<Model> = collection[ props.model ] as unknown as ILlmApplication<Model>; return { protocol: "class", name: "Create Test Code", application, execute: { createTestCode: (next) => { props.build(next); }, } satisfies IApplication, }; } const claude = typia.llm.application< IApplication, "claude", { reference: true; } >(); const collection = { chatgpt: typia.llm.application< IApplication, "chatgpt", { reference: true } >(), claude, llama: claude, deepseek: claude, "3.1": claude, "3.0": typia.llm.application<IApplication, "3.0">(), }; interface IApplication { createTestCode(props: ICreateTestCodeProps): void; } interface ICreateTestCodeProps { /** * Strategic approach for test implementation. * * Define the high-level strategy and logical flow for testing the given * scenario. Focus on test methodology, data preparation, and assertion * strategy. * * ### Critical Requirements * * - Must follow the Test Generation Guildelines. * - Must Planning the test code Never occur the typescript compile error. * * ### Planning Elements: * * #### Test Methodology * * - Identify test scenario type (CRUD operation, authentication flow, * validation test) * - Define test data requirements and preparation strategy * - Plan positive/negative test cases and edge cases * - Design assertion logic and validation points * * #### Execution Strategy * * - Outline step-by-step test execution flow * - Plan error handling and exception scenarios * - Define cleanup and teardown procedures * - Identify dependencies and prerequisites * * ### Example Plan: * * Test Strategy: Article Creation Validation * 1. Prepare valid article data with required fields * 2. Execute POST request to create article * 3. Validate response structure and data integrity * 4. Test error scenarios (missing fields, invalid data) * 5. Verify database state changes * 6. Reconsider the plan if it doesn't follow the Test Generation * Guildelines. */ plan: string; /** * Functional domain classification for test organization. * * Determines file structure and test categorization based on API * functionality. Used for organizing tests into logical groups and directory * hierarchies. * * ### Naming Rules: * * - Lowercase English words only * - Singular nouns (e.g., "article", "user", "comment") * - Kebab-case for compound words (e.g., "user-profile", "payment-method") * - Match primary API resource being tested * - Domain Name must be named only one word. * * ### Domain Examples: * * - `article` → Article management operations * - `comment` → Comment-related functionality * - `auth` → Authentication and authorization * - `user` → User management operations * - `payment` → Payment processing * - `notification` → Notification system */ domain: string; /** * Complete TypeScript E2E test implementation. * * Generate fully functional, compilation-error-free test code following * * @nestia/e2e framework conventions and TypeScript best practices. * * ### Technical Implementation Requirements: * * #### Import Declarations * ```typescript * import api from "@ORGANIZATION/PROJECT-api"; * import { ITargetType } from "@ORGANIZATION/PROJECT-api/lib/structures/[path]"; * import { TestValidator } from "@nestia/e2e"; * import typia from "typia"; * ``` * - Must use exact `@ORGANIZATION/PROJECT-api` module path * - Include `@ORGANIZATION` prefix in all API-related imports * - Import specific DTO types from correct structure paths * * #### Code Quality Standards * - Zero TypeScript compilation errors (mandatory) * - Explicit type annotations for all variables * - Proper async/await patterns throughout * - Comprehensive error handling * - Clean, readable code structure * - Consistent formatting and naming conventions * * ### Critical Error Prevention * - Verify all import paths are correct and accessible * - Ensure type compatibility between variables and assignments * - Include all required object properties and methods * - Validate API function signatures and parameter types * - Confirm proper generic type usage * - Test async function declarations and Promise handling */ content: string; }