UNPKG

@autobe/agent

Version:

AI backend server code generator

411 lines 30.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.orchestrateInterfaceSchemas = orchestrateInterfaceSchemas; const __typia_transform__accessExpressionAsString = __importStar(require("typia/lib/internal/_accessExpressionAsString.js")); const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js")); const core_1 = require("@agentica/core"); const OpenApiV3_1Emender_1 = require("@samchon/openapi/lib/converters/OpenApiV3_1Emender"); const typia_1 = __importDefault(require("typia")); const assertSchemaModel_1 = require("../../context/assertSchemaModel"); const divideArray_1 = require("../../utils/divideArray"); const enforceToolCall_1 = require("../../utils/enforceToolCall"); const forceRetry_1 = require("../../utils/forceRetry"); const transformInterfaceSchemaHistories_1 = require("./histories/transformInterfaceSchemaHistories"); function orchestrateInterfaceSchemas(ctx_1, operations_1) { return __awaiter(this, arguments, void 0, function* (ctx, operations, capacity = 12) { const typeNames = new Set(); for (const op of operations) { if (op.requestBody !== null) typeNames.add(op.requestBody.typeName); if (op.responseBody !== null) typeNames.add(op.responseBody.typeName); } const matrix = (0, divideArray_1.divideArray)({ array: Array.from(typeNames), capacity, }); let progress = 0; const x = {}; for (const y of yield Promise.all(matrix.map((it) => __awaiter(this, void 0, void 0, function* () { var _a, _b; const row = yield divideAndConquer(ctx, operations, it, 3, (count) => { progress += count; }); ctx.dispatch({ type: "interfaceSchemas", schemas: row, completed: progress, total: typeNames.size, step: (_b = (_a = ctx.state().analyze) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0, created_at: new Date().toISOString(), }); return row; })))) { Object.assign(x, y); } return x; }); } function divideAndConquer(ctx, operations, typeNames, retry, progress) { return __awaiter(this, void 0, void 0, function* () { const remained = new Set(typeNames); const schemas = {}; for (let i = 0; i < retry; ++i) { if (remained.size === 0) break; const before = remained.size; const newbie = yield (0, forceRetry_1.forceRetry)(() => process(ctx, operations, schemas, remained)); for (const key of Object.keys(newbie)) { schemas[key] = newbie[key]; remained.delete(key); } if (before - remained.size !== 0) progress(before - remained.size); } return schemas; }); } function process(ctx, operations, oldbie, remained) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const pointer = { value: null, }; const agentica = new core_1.MicroAgentica({ model: ctx.model, vendor: ctx.vendor, config: Object.assign(Object.assign({}, ((_a = ctx.config) !== null && _a !== void 0 ? _a : {})), { executor: { describe: null, } }), histories: (0, transformInterfaceSchemaHistories_1.transformInterfaceSchemaHistories)(ctx.state(), operations), controllers: [ createApplication({ model: ctx.model, build: (next) => __awaiter(this, void 0, void 0, function* () { var _a; (_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = {}); Object.assign(pointer.value, next); }), pointer, }), ], }); (0, enforceToolCall_1.enforceToolCall)(agentica); const already = Object.keys(oldbie); yield agentica .conversate([ "Make type components please.", "", "Here is the list of request/response bodies' type names from", "OpenAPI operations. Make type components of them. If more object", "types are required during making the components, please make them", "too.", "", ...Array.from(remained).map((k) => `- \`${k}\``), ...(already.length !== 0 ? [ "", "> By the way, here is the list of components schemas what you've", "> already made. So, you don't need to make them again.", ">", ...already.map((k) => `> - \`${k}\``), ] : []), ].join("\n")) .finally(() => { const tokenUsage = agentica.getTokenUsage(); ctx.usage().record(tokenUsage, ["interface"]); }); if (pointer.value === null) { // never be happened throw new Error("Failed to create components."); } return ((_b = OpenApiV3_1Emender_1.OpenApiV3_1Emender.convertComponents({ schemas: pointer.value, }).schemas) !== null && _b !== void 0 ? _b : {}); }); } function createApplication(props) { (0, assertSchemaModel_1.assertSchemaModel)(props.model); const application = collection[props.model]; return { protocol: "class", name: "interface", application, execute: { makeComponents: (next) => __awaiter(this, void 0, void 0, function* () { yield props.build(next.schemas); }), }, }; } const claude = { model: "claude", options: { reference: true, separate: null }, functions: [ { name: "makeComponents", parameters: { description: " Properties containing components to generate.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeInterfaceSchemaApplication.IProps}", type: "object", properties: { schemas: { description: "Complete set of schema components for the OpenAPI specification.\n\nThis property contains comprehensive type definitions for all entities in\nthe system. It is the central repository of all named schema types that\nwill be used throughout the API specification.\n\nCRITICAL REQUIREMENT: All object types MUST be defined as named types in\nthe components.schemas section. Inline anonymous object definitions are\nstrictly prohibited.\n\nThis components object should include:\n\n- Main entity types (IEntityName)\n- Operation-specific variants (.ICreate, .IUpdate, .ISummary, etc.)\n- Container types (IPage<T> for pagination)\n- Enumeration types\n\nAll schema definitions must include detailed descriptions that reference\nthe original Prisma schema comments and thoroughly document each\nproperty. Every property that references an object must use a $ref to a\nnamed type in the components.schemas section. This applies to all objects\nin request bodies, response bodies, and properties that are objects or\narrays of objects.\n\nExample structure:\n\n```typescript\n{\n schemas: {\n IUser: {\n type: \"object\",\n properties: {\n id: { type: \"string\", format: \"uuid\" },\n email: { type: \"string\", format: \"email\" },\n profile: { \"$ref\": \"#/components/schemas/IUserProfile\" }\n },\n required: [\"id\", \"email\"],\n description: \"User entity representing system account holders...\"\n },\n \"IUser.ICreate\": { ... },\n // Additional schemas\n }\n}\n```", $ref: "#/$defs/RecordstringAutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema" } }, required: [ "schemas" ], additionalProperties: false, $defs: { "RecordstringAutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema": { description: "Construct a type with a set of properties K of type T", type: "object", properties: {}, required: [], additionalProperties: { $ref: "#/$defs/AutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema" } }, "AutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema": { description: "Descriptive type schema info.\n\n`AutoBeOpenApi.IJsonSchemaDescriptive` is a type schema info of the OpenAPI\nGenerative, but it has a `description` property which is required.\n\n`AutoBeOpenApi.IJsonSchemaDescriptive` basically follows the JSON schema\nspecification of OpenAPI v3.1, but a little bit shrunk to remove ambiguous\nand duplicated expressions of OpenAPI v3.1 for the convenience, clarity,\nand AI generation.\n\nCRITICAL INSTRUCTIONS FOR OPTIMAL AI GENERATION:\n\nWhen creating descriptions for components, types, and properties:\n\n1. ALWAYS refer to and incorporate the description comments from the\n corresponding Prisma DB schema tables and columns. The descriptions\n should match the style, level of detail, and terminology used in the\n Prisma schema.\n2. ALL descriptions MUST be organized into MULTIPLE PARAGRAPHS separated by\n line breaks. Single-paragraph descriptions should be avoided.\n3. Descriptions should comprehensively cover:\n\n - The purpose and business meaning of the type or property\n - Relationships to other entities\n - Validation rules, constraints, and edge cases\n - Usage context and examples when helpful\n4. For each property of an object type, ensure its description reflects the\n corresponding column description in the Prisma DB schema, maintaining\n the same level of detail and terminology\n5. Descriptions should be so detailed and clear that anyone reading them can\n fully understand the type or property without needing to reference any\n other documentation", type: "object", properties: { description: { description: "Description about the type.\n\nCRITICAL: This description MUST be extensively detailed and MUST\nreference and align with the description comments from the\ncorresponding Prisma DB schema tables and columns.\n\nThe description MUST be organized into MULTIPLE PARAGRAPHS (separated\nby line breaks) based on different aspects of the type:\n\n- The purpose and business meaning of the type\n- Relationships to other entities in the system\n- Validation rules, constraints, and edge cases\n- Usage context and examples when helpful\n\nThis structured approach improves readability and helps readers better\nunderstand the type's various characteristics and use cases. The\ndescription should be so comprehensive that anyone reading it can fully\nunderstand the type without needing to reference other documentation.\n\n> MUST be written in English. Never use other languages.", type: "string" } }, required: [ "description" ] } } }, description: "Generate OpenAPI components containing named schema types.\n\nThis method receives a complete set of schema components and integrates\nthem into the final OpenAPI specification. It processes all entity schemas,\ntheir variants, and related type definitions to ensure a comprehensive and\nconsistent API design.\n\nThe provided components should include schemas for all entities identified\nin the previous phases of API path/method definition and operation\ncreation. This ensures that the final OpenAPI document has complete type\ncoverage for all operations.\n\nCRITICAL: All schema definitions must follow the established naming\nconventions (IEntityName, IEntityName.ICreate, etc.) and must be thoroughly\ndocumented with descriptions that reference the original Prisma schema\ncomments.", validate: (() => { const _io0 = input => "object" === typeof input.schemas && null !== input.schemas && false === Array.isArray(input.schemas) && _io1(input.schemas); const _io1 = input => Object.keys(input).every(key => { const value = input[key]; if (undefined === value) return true; return "object" === typeof value && null !== value && _io2(value); }); const _io2 = input => "string" === typeof input.description; const _vo0 = (input, _path, _exceptionable = true) => [("object" === typeof input.schemas && null !== input.schemas && false === Array.isArray(input.schemas) || _report(_exceptionable, { path: _path + ".schemas", expected: "Record<string, AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>>", value: input.schemas })) && _vo1(input.schemas, _path + ".schemas", true && _exceptionable) || _report(_exceptionable, { path: _path + ".schemas", expected: "Record<string, AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>>", value: input.schemas })].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => { const value = input[key]; if (undefined === value) return true; return ("object" === typeof value && null !== value || _report(_exceptionable, { path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), expected: "AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>", value: value })) && _vo2(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, { path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), expected: "AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>", value: value }); }).every(flag => flag)].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.description || _report(_exceptionable, { path: _path + ".description", expected: "string", value: input.description })].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "IAutoBeInterfaceSchemaApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeInterfaceSchemaApplication.IProps", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })() } ] }; const collection = { chatgpt: { model: "chatgpt", options: { reference: true, strict: false, separate: null }, functions: [ { name: "makeComponents", parameters: { description: " Properties containing components to generate.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeInterfaceSchemaApplication.IProps}\n\n### Description of {@link schemas} property:\n\n> Complete set of schema components for the OpenAPI specification.\n> \n> This property contains comprehensive type definitions for all entities in\n> the system. It is the central repository of all named schema types that\n> will be used throughout the API specification.\n> \n> CRITICAL REQUIREMENT: All object types MUST be defined as named types in\n> the components.schemas section. Inline anonymous object definitions are\n> strictly prohibited.\n> \n> This components object should include:\n> \n> - Main entity types (IEntityName)\n> - Operation-specific variants (.ICreate, .IUpdate, .ISummary, etc.)\n> - Container types (IPage<T> for pagination)\n> - Enumeration types\n> \n> All schema definitions must include detailed descriptions that reference\n> the original Prisma schema comments and thoroughly document each\n> property. Every property that references an object must use a $ref to a\n> named type in the components.schemas section. This applies to all objects\n> in request bodies, response bodies, and properties that are objects or\n> arrays of objects.\n> \n> Example structure:\n> \n> ```typescript\n> {\n> schemas: {\n> IUser: {\n> type: \"object\",\n> properties: {\n> id: { type: \"string\", format: \"uuid\" },\n> email: { type: \"string\", format: \"email\" },\n> profile: { \"$ref\": \"#/components/schemas/IUserProfile\" }\n> },\n> required: [\"id\", \"email\"],\n> description: \"User entity representing system account holders...\"\n> },\n> \"IUser.ICreate\": { ... },\n> // Additional schemas\n> }\n> }\n> ```", type: "object", properties: { schemas: { $ref: "#/$defs/RecordstringAutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema" } }, required: [ "schemas" ], additionalProperties: false, $defs: { "RecordstringAutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema": { description: "Construct a type with a set of properties K of type T", type: "object", properties: {}, required: [], additionalProperties: { $ref: "#/$defs/AutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema" } }, "AutoBeOpenApi.IJsonSchemaDescriptiveAutoBeOpenApi.IJsonSchema": { description: "Descriptive type schema info.\n\n`AutoBeOpenApi.IJsonSchemaDescriptive` is a type schema info of the OpenAPI\nGenerative, but it has a `description` property which is required.\n\n`AutoBeOpenApi.IJsonSchemaDescriptive` basically follows the JSON schema\nspecification of OpenAPI v3.1, but a little bit shrunk to remove ambiguous\nand duplicated expressions of OpenAPI v3.1 for the convenience, clarity,\nand AI generation.\n\nCRITICAL INSTRUCTIONS FOR OPTIMAL AI GENERATION:\n\nWhen creating descriptions for components, types, and properties:\n\n1. ALWAYS refer to and incorporate the description comments from the\n corresponding Prisma DB schema tables and columns. The descriptions\n should match the style, level of detail, and terminology used in the\n Prisma schema.\n2. ALL descriptions MUST be organized into MULTIPLE PARAGRAPHS separated by\n line breaks. Single-paragraph descriptions should be avoided.\n3. Descriptions should comprehensively cover:\n\n - The purpose and business meaning of the type or property\n - Relationships to other entities\n - Validation rules, constraints, and edge cases\n - Usage context and examples when helpful\n4. For each property of an object type, ensure its description reflects the\n corresponding column description in the Prisma DB schema, maintaining\n the same level of detail and terminology\n5. Descriptions should be so detailed and clear that anyone reading them can\n fully understand the type or property without needing to reference any\n other documentation", type: "object", properties: { description: { description: "Description about the type.\n\nCRITICAL: This description MUST be extensively detailed and MUST\nreference and align with the description comments from the\ncorresponding Prisma DB schema tables and columns.\n\nThe description MUST be organized into MULTIPLE PARAGRAPHS (separated\nby line breaks) based on different aspects of the type:\n\n- The purpose and business meaning of the type\n- Relationships to other entities in the system\n- Validation rules, constraints, and edge cases\n- Usage context and examples when helpful\n\nThis structured approach improves readability and helps readers better\nunderstand the type's various characteristics and use cases. The\ndescription should be so comprehensive that anyone reading it can fully\nunderstand the type without needing to reference other documentation.\n\n> MUST be written in English. Never use other languages.", type: "string" } }, required: [ "description" ] } } }, description: "Generate OpenAPI components containing named schema types.\n\nThis method receives a complete set of schema components and integrates\nthem into the final OpenAPI specification. It processes all entity schemas,\ntheir variants, and related type definitions to ensure a comprehensive and\nconsistent API design.\n\nThe provided components should include schemas for all entities identified\nin the previous phases of API path/method definition and operation\ncreation. This ensures that the final OpenAPI document has complete type\ncoverage for all operations.\n\nCRITICAL: All schema definitions must follow the established naming\nconventions (IEntityName, IEntityName.ICreate, etc.) and must be thoroughly\ndocumented with descriptions that reference the original Prisma schema\ncomments.", validate: (() => { const _io0 = input => "object" === typeof input.schemas && null !== input.schemas && false === Array.isArray(input.schemas) && _io1(input.schemas); const _io1 = input => Object.keys(input).every(key => { const value = input[key]; if (undefined === value) return true; return "object" === typeof value && null !== value && _io2(value); }); const _io2 = input => "string" === typeof input.description; const _vo0 = (input, _path, _exceptionable = true) => [("object" === typeof input.schemas && null !== input.schemas && false === Array.isArray(input.schemas) || _report(_exceptionable, { path: _path + ".schemas", expected: "Record<string, AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>>", value: input.schemas })) && _vo1(input.schemas, _path + ".schemas", true && _exceptionable) || _report(_exceptionable, { path: _path + ".schemas", expected: "Record<string, AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>>", value: input.schemas })].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map(key => { const value = input[key]; if (undefined === value) return true; return ("object" === typeof value && null !== value || _report(_exceptionable, { path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), expected: "AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>", value: value })) && _vo2(value, _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), true && _exceptionable) || _report(_exceptionable, { path: _path + __typia_transform__accessExpressionAsString._accessExpressionAsString(key), expected: "AutoBeOpenApi.IJsonSchemaDescriptive<AutoBeOpenApi.IJsonSchema>", value: value }); }).every(flag => flag)].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.description || _report(_exceptionable, { path: _path + ".description", expected: "string", value: input.description })].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "IAutoBeInterfaceSchemaApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeInterfaceSchemaApplication.IProps", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })() } ] }, claude, llama: claude, deepseek: claude, "3.1": claude, }; //# sourceMappingURL=orchestrateInterfaceSchemas.js.map