UNPKG

@autobe/agent

Version:

AI backend server code generator

860 lines (859 loc) 257 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.orchestrateInterfaceSchemaRefine = orchestrateInterfaceSchemaRefine; const __typia_transform__isTypeUint32 = __importStar(require("typia/lib/internal/_isTypeUint32")); const __typia_transform__accessExpressionAsString = __importStar(require("typia/lib/internal/_accessExpressionAsString")); const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport")); const __typia_transform__llmApplicationFinalize = __importStar(require("typia/lib/internal/_llmApplicationFinalize")); const utils_1 = require("@autobe/utils"); const tstl_1 = require("tstl"); const typia_1 = __importDefault(require("typia")); const uuid_1 = require("uuid"); const executeCachedBatch_1 = require("../../utils/executeCachedBatch"); const AutoBePreliminaryController_1 = require("../common/AutoBePreliminaryController"); const AutoBeDatabaseModelProgrammer_1 = require("../database/programmers/AutoBeDatabaseModelProgrammer"); const transformInterfaceSchemaRefineHistory_1 = require("./histories/transformInterfaceSchemaRefineHistory"); const AutoBeInterfaceSchemaProgrammer_1 = require("./programmers/AutoBeInterfaceSchemaProgrammer"); const AutoBeInterfaceSchemaRefineProgrammer_1 = require("./programmers/AutoBeInterfaceSchemaRefineProgrammer"); const AutoBeJsonSchemaValidator_1 = require("./utils/AutoBeJsonSchemaValidator"); const fulfillJsonSchemaErrorMessages_1 = require("./utils/fulfillJsonSchemaErrorMessages"); function orchestrateInterfaceSchemaRefine(ctx, props) { return __awaiter(this, void 0, void 0, function* () { // Filter to only process object-type schemas (non-preset and object type) const typeNames = Object.entries(props.schemas) .filter(([k, v]) => AutoBeJsonSchemaValidator_1.AutoBeJsonSchemaValidator.isPreset(k) === false && utils_1.AutoBeOpenApiTypeChecker.isObject(v)) .map(([k]) => k); props.progress.total += typeNames.length; const x = {}; yield (0, executeCachedBatch_1.executeCachedBatch)(ctx, typeNames.map((it) => (promptCacheKey) => __awaiter(this, void 0, void 0, function* () { const counter = new tstl_1.Singleton(() => ++props.progress.completed); const predicate = (key) => key === it; const operations = props.document.operations.filter((op) => (op.requestBody && predicate(op.requestBody.typeName)) || (op.responseBody && predicate(op.responseBody.typeName))); try { const schema = props.schemas[it]; if (utils_1.AutoBeOpenApiTypeChecker.isObject(schema) === false) { counter.get(); return; } const refined = yield process(ctx, { instruction: props.instruction, document: props.document, typeName: it, operations, schema, progress: props.progress, promptCacheKey, counter, }); x[it] = refined; } catch (error) { console.log("interfaceSchemaRefine failure", it, error); counter.get(); } }))); return x; }); } function process(ctx, props) { return __awaiter(this, void 0, void 0, function* () { const preliminary = new AutoBePreliminaryController_1.AutoBePreliminaryController({ dispatch: (e) => ctx.dispatch(e), application: { version: "3.1", components: { schemas: { "IAutoBeInterfaceSchemaRefineApplication.IProps": { type: "object", properties: { thinking: { type: "string", description: "Think before you act.\n\nFor preliminary requests: what critical information is missing and why?\n\nFor write: what refinements you're submitting and key decisions.\n\nFor complete: why you consider the last write final." }, request: { oneOf: [ { $ref: "#/components/schemas/IAutoBePreliminaryComplete" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetAnalysisSections" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetDatabaseSchemas" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetInterfaceOperations" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetInterfaceSchemas" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetPreviousAnalysisSections" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetPreviousDatabaseSchemas" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetPreviousInterfaceOperations" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetPreviousInterfaceSchemas" }, { $ref: "#/components/schemas/IAutoBeInterfaceSchemaRefineApplication.IWrite" } ], discriminator: { propertyName: "type", mapping: { complete: "#/components/schemas/IAutoBePreliminaryComplete", getAnalysisSections: "#/components/schemas/IAutoBePreliminaryGetAnalysisSections", getDatabaseSchemas: "#/components/schemas/IAutoBePreliminaryGetDatabaseSchemas", getInterfaceOperations: "#/components/schemas/IAutoBePreliminaryGetInterfaceOperations", getInterfaceSchemas: "#/components/schemas/IAutoBePreliminaryGetInterfaceSchemas", getPreviousAnalysisSections: "#/components/schemas/IAutoBePreliminaryGetPreviousAnalysisSections", getPreviousDatabaseSchemas: "#/components/schemas/IAutoBePreliminaryGetPreviousDatabaseSchemas", getPreviousInterfaceOperations: "#/components/schemas/IAutoBePreliminaryGetPreviousInterfaceOperations", getPreviousInterfaceSchemas: "#/components/schemas/IAutoBePreliminaryGetPreviousInterfaceSchemas", write: "#/components/schemas/IAutoBeInterfaceSchemaRefineApplication.IWrite" } }, description: "Action to perform. Exhausted preliminary types are removed from the\nunion, physically preventing repeated calls." } }, required: [ "thinking", "request" ] }, IAutoBePreliminaryComplete: { type: "object", properties: { type: { "const": "complete", description: "Type discriminator for completion request." } }, required: [ "type" ], description: "Finalize the write loop by accepting your most recent `write` as-is.\n\nAfter submitting a `write`, review it yourself thoroughly against the review\nchecklist in your instructions. If you find issues worth fixing, submit\nanother `write` with corrections. When you are satisfied with the quality,\ncall `complete` to finalize.\n\nYou have a maximum of 3 write attempts, but this is a safety cap \u2014 not a\ntarget to fill.\n\nOnly valid after at least one `write` submission \u2014 rejected otherwise." }, IAutoBePreliminaryGetAnalysisSections: { type: "object", properties: { type: { "const": "getAnalysisSections", description: "Type discriminator." }, sectionIds: { type: "array", items: { type: "integer", minimum: 0 }, minItems: 1, maxItems: 100, description: "Section IDs to retrieve. DO NOT request same IDs already requested in\nprevious calls." } }, required: [ "type", "sectionIds" ], description: "Request to retrieve individual analysis sections by numeric ID." }, IAutoBePreliminaryGetDatabaseSchemas: { type: "object", properties: { type: { "const": "getDatabaseSchemas", description: "Type discriminator." }, schemaNames: { type: "array", items: { type: "string" }, minItems: 1, description: "Database table names to retrieve. DO NOT request same names already\nrequested in previous calls." } }, required: [ "type", "schemaNames" ], description: "Request to retrieve database schema definitions for context." }, IAutoBePreliminaryGetInterfaceOperations: { type: "object", properties: { type: { "const": "getInterfaceOperations", description: "Type discriminator." }, endpoints: { type: "array", items: { $ref: "#/components/schemas/AutoBeOpenApi.IEndpoint" }, minItems: 1, description: "API operation endpoints to retrieve. DO NOT request same endpoints already\nrequested in previous calls." } }, required: [ "type", "endpoints" ], description: "Request to retrieve existing interface operations for context." }, "AutoBeOpenApi.IEndpoint": { type: "object", properties: { path: { type: "string", pattern: "^\\/[a-zA-Z0-9\\/_{}.-]*$", description: "HTTP path of the API operation.\n\nMust start with `/`. Parameters use curly braces: `{paramName}`. Resource\nnames in camelCase. No quotes, spaces, role prefixes (`/admin/`), or API\nversion prefixes (`/api/v1/`).\n\nAllowed characters: letters, digits, `/`, `{`, `}`, `-`, `_`, `.`" }, method: { oneOf: [ { "const": "get" }, { "const": "post" }, { "const": "put" }, { "const": "delete" }, { "const": "patch" } ], description: "HTTP method (lowercase only).\n\nUse `patch` (not `get`) when a read operation needs a complex\n{@link requestBody}. `get` cannot have a request body." } }, required: [ "path", "method" ], description: "API endpoint information." }, IAutoBePreliminaryGetInterfaceSchemas: { type: "object", properties: { type: { "const": "getInterfaceSchemas", description: "Type discriminator." }, typeNames: { type: "array", items: { type: "string" }, minItems: 1, description: "Schema type names to retrieve. DO NOT request same names already requested\nin previous calls." } }, required: [ "type", "typeNames" ], description: "Request to retrieve OpenAPI schema type definitions for context." }, IAutoBePreliminaryGetPreviousAnalysisSections: { type: "object", properties: { type: { "const": "getPreviousAnalysisSections", description: "Type discriminator." }, sectionIds: { type: "array", items: { type: "integer", minimum: 0 }, minItems: 1, description: "Section IDs to retrieve from previous iteration. DO NOT request same IDs\nalready requested in previous calls." } }, required: [ "type", "sectionIds" ], description: "Request to retrieve analysis sections from the previous iteration by numeric\nID." }, IAutoBePreliminaryGetPreviousDatabaseSchemas: { type: "object", properties: { type: { "const": "getPreviousDatabaseSchemas", description: "Type discriminator." }, schemaNames: { type: "array", items: { type: "string" }, minItems: 1, description: "Table names to retrieve from previous iteration. DO NOT request same names\nalready requested in previous calls." } }, required: [ "type", "schemaNames" ], description: "Request to retrieve database schemas from the previous iteration.\n\nLoads database table definitions from the last successfully generated\nversion, used as reference context during regeneration or modification\ncycles." }, IAutoBePreliminaryGetPreviousInterfaceOperations: { type: "object", properties: { type: { "const": "getPreviousInterfaceOperations", description: "Type discriminator." }, endpoints: { type: "array", items: { $ref: "#/components/schemas/AutoBeOpenApi.IEndpoint" }, minItems: 1, description: "Endpoints to retrieve from previous iteration. DO NOT request same\nendpoints already requested in previous calls." } }, required: [ "type", "endpoints" ], description: "Request to retrieve interface operations from the previous iteration.\n\nLoads API operation definitions from the last successfully generated version,\nused as reference context during regeneration or modification cycles." }, IAutoBePreliminaryGetPreviousInterfaceSchemas: { type: "object", properties: { type: { "const": "getPreviousInterfaceSchemas", description: "Type discriminator." }, typeNames: { type: "array", items: { type: "string" }, minItems: 1, description: "Schema type names to retrieve from previous iteration. DO NOT request same\nnames already requested in previous calls." } }, required: [ "type", "typeNames" ], description: "Request to retrieve interface schemas from the previous iteration.\n\nLoads OpenAPI schema definitions (DTOs) from the last successfully generated\nversion, used as reference context during regeneration or modification\ncycles." }, "IAutoBeInterfaceSchemaRefineApplication.IWrite": { type: "object", properties: { type: { "const": "write", description: "Type discriminator for write submission." }, review: { type: "string", description: "Summary of refinement analysis and actions taken." }, databaseSchema: { oneOf: [ { type: "null" }, { type: "string" } ], description: "Database table this schema maps to, or `null` for non-table types\n(aggregations, joins, utility)." }, specification: { type: "string", description: "HOW the schema should be implemented (data source mappings,\ntransformation rules). **MANDATORY**: Always provide, even if existing\nvalue is correct \u2014 this forces explicit review of implementation\ndetails." }, description: { type: "string", description: "WHAT the schema represents for API consumers. **MANDATORY**: Always\nprovide, even if existing value is correct \u2014 this forces explicit review\nof consumer-facing documentation." }, excludes: { type: "array", items: { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyExclude" }, description: "Database properties explicitly excluded from this DTO. Together with\n`revises`, must cover every database property exactly once." }, revises: { type: "array", items: { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyRefine" }, description: "Property-level refinement operations (depict/create/update/erase). Every\nDTO property must appear exactly once. Database properties go here (via\n`databaseSchemaProperty`) or in `excludes`. No omissions allowed." } }, required: [ "type", "review", "databaseSchema", "specification", "description", "excludes", "revises" ], description: "Submit schema refinement with object-level and property-level enrichment." }, AutoBeInterfaceSchemaPropertyExclude: { type: "object", properties: { databaseSchemaProperty: { type: "string", description: "Database property name (column or relation) to exclude from this DTO." }, reason: { type: "string", description: "Explanation of why this database property is excluded." } }, required: [ "databaseSchemaProperty", "reason" ], description: "Exclude a database property from the DTO.\n\nUse when a database property should NOT appear in this DTO:\n\n- DTO purpose mismatch: `id`, `created_at` excluded from Create DTO\n- Summary DTO: only essential display fields included\n- Immutability: `id`, `created_at` excluded from Update DTO\n- Security: `password`, `salt`, `refresh_token` excluded from Read DTO\n- Aggregation relations: use computed counts instead of nested arrays" }, AutoBeInterfaceSchemaPropertyRefine: { oneOf: [ { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyCreate" }, { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyDepict" }, { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyErase" }, { $ref: "#/components/schemas/AutoBeInterfaceSchemaPropertyUpdate" } ], discriminator: { propertyName: "type", mapping: { create: "#/components/schemas/AutoBeInterfaceSchemaPropertyCreate", depict: "#/components/schemas/AutoBeInterfaceSchemaPropertyDepict", erase: "#/components/schemas/AutoBeInterfaceSchemaPropertyErase", update: "#/components/schemas/AutoBeInterfaceSchemaPropertyUpdate" } }, description: "Property-level enrichment: depict | create | update | erase.\n\nEvery DTO property must be handled. DB properties go here or in `excludes`." }, AutoBeInterfaceSchemaPropertyCreate: { type: "object", properties: { key: { type: "string", description: "Property key to add." }, databaseSchemaProperty: { oneOf: [ { type: "null" }, { type: "string" } ], description: "Database schema property this maps to, or `null` for computed properties.\n\nWhen `null`, `specification` must explain the computation logic." }, reason: { type: "string", description: "Evidence and reasoning for adding this property.\n\nDescribe what you found that requires this addition." }, type: { "const": "create", description: "Discriminator for property revision type." }, specification: { type: "string", description: "Implementation guidance for downstream agents.\n\nInternal documentation for Realize/Test agents. When\n`databaseSchemaProperty` is `null`, this must fully explain the computation\nlogic." }, description: { type: "string", description: "API documentation for consumers (Swagger UI). Explain what the property\nrepresents. No implementation details.\n\nFormat: summary sentence first, `\\n\\n`, then paragraphs grouped by topic." }, schema: { oneOf: [ { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INumber" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IInteger" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IString" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IConstant" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INull" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IBoolean" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IArray" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IReference" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IOneOf" } ], description: "Schema definition for the new property.\n\nMust be consistent with `specification`. Inline objects forbidden; use\n`$ref` for nested structures." }, required: { type: "boolean", description: "Whether property should be in `required` array." } }, required: [ "key", "databaseSchemaProperty", "reason", "type", "specification", "description", "schema", "required" ], description: "Add a new property to a DTO schema.\n\nUse when a property is missing: database field not included, relation not\nexposed, or computed property needed." }, "AutoBeOpenApi.IJsonSchema.INumber": { type: "object", properties: { minimum: { type: "number" }, maximum: { type: "number" }, exclusiveMinimum: { type: "number" }, exclusiveMaximum: { type: "number" }, multipleOf: { type: "number", exclusiveMinimum: 0 }, type: { "const": "number", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "type" ], description: "Number (double) type info." }, "AutoBeOpenApi.IJsonSchema.IInteger": { type: "object", properties: { minimum: { type: "integer" }, maximum: { type: "integer" }, exclusiveMinimum: { type: "integer" }, exclusiveMaximum: { type: "integer" }, multipleOf: { type: "integer", exclusiveMinimum: 0 }, type: { "const": "integer", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "type" ], description: "Integer type info." }, "AutoBeOpenApi.IJsonSchema.IString": { type: "object", properties: { format: { oneOf: [ { "const": "password" }, { "const": "regex" }, { "const": "uuid" }, { "const": "email" }, { "const": "hostname" }, { "const": "idn-email" }, { "const": "idn-hostname" }, { "const": "iri" }, { "const": "iri-reference" }, { "const": "ipv4" }, { "const": "ipv6" }, { "const": "uri" }, { "const": "uri-reference" }, { "const": "uri-template" }, { "const": "url" }, { "const": "date-time" }, { "const": "date" }, { "const": "time" }, { "const": "duration" }, { "const": "json-pointer" }, { "const": "relative-json-pointer" } ], description: "Format restriction." }, pattern: { type: "string", description: "Pattern restriction." }, contentMediaType: { type: "string", description: "Content media type restriction.\n\nFor multiple media types, use `oneOf` with separate string schemas per\n`contentMediaType` value. Never use an array here." }, minLength: { type: "integer", minimum: 0 }, maxLength: { type: "integer", minimum: 0 }, type: { "const": "string", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "type" ], description: "String type info." }, "AutoBeOpenApi.IJsonSchema.IConstant": { type: "object", properties: { "const": { oneOf: [ { type: "string" }, { type: "number" }, { type: "boolean" } ], description: "The constant value." } }, required: [ "const" ], description: "Constant value type." }, "AutoBeOpenApi.IJsonSchema.INull": { type: "object", properties: { type: { "const": "null", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "type" ], description: "Null type." }, "AutoBeOpenApi.IJsonSchema.IBoolean": { type: "object", properties: { type: { "const": "boolean", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "type" ], description: "Boolean type info." }, "AutoBeOpenApi.IJsonSchema.IArray": { type: "object", properties: { items: { oneOf: [ { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INumber" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IInteger" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IString" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IConstant" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INull" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IBoolean" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IArray" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IReference" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IOneOf" } ], description: "Type schema of array elements." }, uniqueItems: { type: "boolean", description: "If `true`, array elements must be unique." }, minItems: { type: "integer", minimum: 0 }, maxItems: { type: "integer", minimum: 0 }, type: { "const": "array", description: "Discriminator value. MUST be a single string, NEVER an array.\n\nFor nullable types, use `IOneOf` instead: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`" } }, required: [ "items", "type" ], description: "Array type info." }, "AutoBeOpenApi.IJsonSchema.IReference": { type: "object", properties: { $ref: { type: "string", description: "JSON Pointer reference to a named schema (e.g.,\n`#/components/schemas/SomeObject`)." } }, required: [ "$ref" ], description: "Reference type directing named schema."