UNPKG

@autobe/agent

Version:

AI backend server code generator

865 lines (864 loc) 227 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.orchestrateInterfaceSchemaComplement = void 0; 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 RAGRetrieval_1 = require("../../utils/RAGRetrieval"); const executeCachedBatch_1 = require("../../utils/executeCachedBatch"); const getEmbedder_1 = require("../../utils/getEmbedder"); const AutoBePreliminaryController_1 = require("../common/AutoBePreliminaryController"); const convertToSectionEntries_1 = require("../common/internal/convertToSectionEntries"); const transformInterfaceSchemaComplementHistory_1 = require("./histories/transformInterfaceSchemaComplementHistory"); const AutoBeInterfaceSchemaProgrammer_1 = require("./programmers/AutoBeInterfaceSchemaProgrammer"); const AutoBeJsonSchemaFactory_1 = require("./utils/AutoBeJsonSchemaFactory"); const AutoBeJsonSchemaValidator_1 = require("./utils/AutoBeJsonSchemaValidator"); const fulfillJsonSchemaErrorMessages_1 = require("./utils/fulfillJsonSchemaErrorMessages"); const orchestrateInterfaceSchemaComplement = (ctx, props) => __awaiter(void 0, void 0, void 0, function* () { const typeNames = (0, utils_1.missedOpenApiSchemas)(props.document).filter((k) => AutoBeJsonSchemaValidator_1.AutoBeJsonSchemaValidator.isPreset(k) === false); if (typeNames.length === 0) return {}; props.progress.total += typeNames.length; const result = {}; yield (0, executeCachedBatch_1.executeCachedBatch)(ctx, typeNames.map((it) => (promptCacheKey) => __awaiter(void 0, void 0, void 0, function* () { const counter = new tstl_1.Singleton(() => ++props.progress.completed); try { result[it] = yield process(ctx, { instruction: props.instruction, document: props.document, typeName: it, progress: props.progress, promptCacheKey, counter, }); } catch (error) { console.log("interfaceSchemaComplement failure", it, error); counter.get(); const count = props.failures.get(it); if (count === undefined) props.failures.set(it, 1); else if (count < 3) props.failures.set(it, count + 1); else throw error; } }))); return result; }); exports.orchestrateInterfaceSchemaComplement = orchestrateInterfaceSchemaComplement; function process(ctx, props) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const allSections = (0, convertToSectionEntries_1.convertToSectionEntries)((_b = (_a = ctx.state().analyze) === null || _a === void 0 ? void 0 : _a.files) !== null && _b !== void 0 ? _b : []); const relatedOp = props.document.operations.find((o) => { var _a, _b; return ((_a = o.requestBody) === null || _a === void 0 ? void 0 : _a.typeName) === props.typeName || ((_b = o.responseBody) === null || _b === void 0 ? void 0 : _b.typeName) === props.typeName; }); const opHint = relatedOp ? `${relatedOp.method} ${relatedOp.path}` : ""; const task = props.instruction.replace(/\s+/g, " ").trim().slice(0, 200); const queryText = ` Type: ${props.typeName} Ops: ${opHint || "N/A"} Task: ${task} `.trim(); const ragSections = yield (0, RAGRetrieval_1.buildAnalysisContextSections)((0, getEmbedder_1.getEmbedder)(), allSections, queryText, "TOPK", { log: false, logPrefix: "interfaceComplement" }); const preliminary = new AutoBePreliminaryController_1.AutoBePreliminaryController({ dispatch: (e) => ctx.dispatch(e), application: { version: "3.1", components: { schemas: { "IAutoBeInterfaceSchemaComplementApplication.IProps": { type: "object", properties: { thinking: { type: "string", description: "Reasoning: what's missing (preliminary), what you're submitting (write),\nor why you're finalizing (complete)." }, 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/IAutoBeInterfaceSchemaComplementApplication.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/IAutoBeInterfaceSchemaComplementApplication.IWrite" } }, description: "Action to perform. Exhausted preliminary types are removed from the\nunion." } }, 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." }, "IAutoBeInterfaceSchemaComplementApplication.IWrite": { type: "object", properties: { type: { "const": "write", description: "Type discriminator for write submission." }, analysis: { type: "string", description: "Analysis of the missing type's purpose and reference context." }, rationale: { type: "string", description: "Rationale for the schema design decisions." }, design: { $ref: "#/components/schemas/AutoBeInterfaceSchemaDesign", description: "Schema design: database mapping, specification, description, and JSON\nSchema." } }, required: [ "type", "analysis", "rationale", "design" ], description: "Submit a missing schema definition referenced by $ref in\ncomponents.schemas." }, AutoBeInterfaceSchemaDesign: { type: "object", properties: { databaseSchema: { oneOf: [ { type: "null" }, { type: "string" } ], description: "Database model name this schema maps to, or `null` for computed/aggregated\ntypes.\n\nWhen `null`, `specification` becomes critical for downstream agents." }, specification: { type: "string", description: "Implementation guidance for downstream agents (Realize, Test). NOT exposed\nin public API docs.\n\nWhen `databaseSchema` is set: brief mapping details. When `null`: MUST\ninclude source tables, JOINs, aggregation formulas, business rules, and\nedge cases." }, description: { type: "string", description: "API documentation for consumers (Swagger UI). Focus on WHAT the type\nrepresents, referencing DB schema documentation for consistency.\n\nFormat: summary sentence first, `\\n\\n`, then paragraphs grouped by topic.\n\n> MUST be written in English." }, schema: { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema", description: "JSON Schema definition.\n\nFor union/nullable types, use `oneOf` \u2014 NEVER array in `type` field. Use\n`$ref` for referencing named schemas. Object property names in camelCase." } }, required: [ "databaseSchema", "specification", "description", "schema" ], description: "Design structure for creating an OpenAPI schema component.\n\nSeparates schema metadata (specification, description) from the JSON Schema\ndefinition (schema)." }, "AutoBeOpenApi.IJsonSchema": { oneOf: [ { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IInteger" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INumber" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IString" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IConstant" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IBoolean" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IArray" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IObject" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IReference" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IOneOf" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INull" } ], description: "JSON Schema type following OpenAPI v3.1 (simplified).\n\nCRITICAL: Union types MUST use `IOneOf`. NEVER use array in `type` field.\n\nWrong: `{ type: [\"string\", \"null\"] }` Correct: `{ oneOf: [{ type: \"string\"\n}, { type: \"null\" }] }`\n\nThe `type` field is a discriminator and MUST be a single string value." }, "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.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.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.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.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.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." }, "AutoBeOpenApi.IJsonSchema.IOneOf": { type: "object", properties: { oneOf: { type: "array", 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.IBoolean" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IArray" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IReference" }, { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.INull" } ] }, description: "List of the union types." }, discriminator: { $ref: "#/components/schemas/AutoBeOpenApi.IJsonSchema.IOneOf.IDiscriminator", description: "Discriminator info of the union type." } }, required: [ "oneOf" ], description: "Union type.\n\n`IOneOf` represents a union type in TypeScript (`A | B | C`).\n\nFor reference, even though your Swagger (or OpenAPI) document has defined\n`anyOf` instead of the `oneOf`, {@link AutoBeOpenApi} forcibly converts it\nto `oneOf` type." }, "AutoBeOpenApi.IJsonSchema.IOneOf.IDiscriminator": { type: "object", properties: { propertyName: { type: "string", description: "Property name for the discriminator." }, mapping: { $ref: "#/components/schemas/Recordstringstring", description: "Mapping of the discriminator value to the schema name.\n\nThis property is valid only for {@link IReference} typed\n{@link IOneOf.oneOf} elements. Therefore, `key` of `mapping` is the\ndiscriminator value, and `value` of `mapping` is the schema name like\n`#/components/schemas/SomeObject`." } }, required: [ "propertyName" ], description: "Discriminator info of the union type." }, Recordstringstring: { type: "object", properties: {}, required: [], description: "Construct a type with a set of properties K of type T", additionalProperties: { type: "string" } }, "AutoBeOpenApi.IJsonSchema.IObject": { type: "object", properties: { properties: { $ref: "#/components/schemas/RecordstringAutoBeOpenApi.IJsonSchema", description: "Key-value pairs of the object's named properties." }, additionalProperties: {