From 6dba7f1dce29bda879ccf35e8db66f622edbedf7 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Tue, 11 Feb 2025 21:55:59 +0900 Subject: [PATCH 1/5] Add `IJsonSchemaAttribute`. --- .github/workflows/website.yml | 1 + package.json | 2 +- src/OpenApi.ts | 28 +----------- src/index.ts | 1 + src/structures/IChatGptSchema.ts | 29 ++----------- src/structures/IGeminiSchema.ts | 30 ++----------- src/structures/IJsonSchemaAttribute.ts | 60 ++++++++++++++++++++++++++ src/structures/ILlmSchemaV3.ts | 29 ++----------- src/structures/ILlmSchemaV3_1.ts | 29 ++----------- 9 files changed, 77 insertions(+), 132 deletions(-) create mode 100644 src/structures/IJsonSchemaAttribute.ts diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 903e409..93784d1 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -4,6 +4,7 @@ on: branches: - master paths: + - README.md - 'src/**' - 'website/**' - 'package.json' diff --git a/package.json b/package.json index 938dd5d..e2b9128 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@samchon/openapi", - "version": "2.4.2", + "version": "3.0.0-dev.20250211", "description": "OpenAPI definitions and converters for 'typia' and 'nestia'.", "main": "./lib/index.js", "module": "./lib/index.mjs", diff --git a/src/OpenApi.ts b/src/OpenApi.ts index f7c8e79..4d28a98 100644 --- a/src/OpenApi.ts +++ b/src/OpenApi.ts @@ -6,6 +6,7 @@ import { OpenApiV3Upgrader } from "./converters/OpenApiV3Upgrader"; import { OpenApiV3_1Emender } from "./converters/OpenApiV3_1Emender"; import { SwaggerV2Downgrader } from "./converters/SwaggerV2Downgrader"; import { SwaggerV2Upgrader } from "./converters/SwaggerV2Upgrader"; +import { IJsonSchemaAttribute } from "./structures/IJsonSchemaAttribute"; /** * Emended OpenAPI v3.1 definition used by `typia` and `nestia`. @@ -1106,32 +1107,7 @@ export namespace OpenApi { /** * Common attributes that can be applied to all types. */ - export interface __IAttribute { - /** - * Title of the schema. - */ - title?: string; - - /** - * Detailed description of the schema. - */ - description?: string; - - /** - * Whether the type is deprecated or not. - */ - deprecated?: boolean; - - /** - * Example value. - */ - example?: any; - - /** - * List of example values as key-value pairs. - */ - examples?: Record; - } + export type __IAttribute = IJsonSchemaAttribute; } /** diff --git a/src/index.ts b/src/index.ts index 1abc509..bfaf9f4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export * from "./SwaggerV2"; export * from "./OpenApiV3"; export * from "./OpenApiV3_1"; +export * from "./structures/IJsonSchemaAttribute"; export * from "./utils/OpenApiTypeChecker"; //---- diff --git a/src/structures/IChatGptSchema.ts b/src/structures/IChatGptSchema.ts index 55ca83d..e3789ed 100644 --- a/src/structures/IChatGptSchema.ts +++ b/src/structures/IChatGptSchema.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./IJsonSchemaAttribute"; + /** * Type schema info of the ChatGPT. * @@ -279,32 +281,7 @@ export namespace IChatGptSchema { /** * Common attributes that can be applied to all types. */ - export interface __IAttribute { - /** - * Title of the schema. - */ - title?: string; - - /** - * Detailed description of the schema. - */ - description?: string; - - /** - * Whether the type is deprecated or not. - */ - deprecated?: boolean; - - /** - * Example value. - */ - example?: any; - - /** - * List of example values as key-value pairs. - */ - examples?: Record; - } + export type __IAttribute = IJsonSchemaAttribute; /** * Configuration for ChatGPT schema composition. diff --git a/src/structures/IGeminiSchema.ts b/src/structures/IGeminiSchema.ts index 9b78d56..b63f5d3 100644 --- a/src/structures/IGeminiSchema.ts +++ b/src/structures/IGeminiSchema.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./IJsonSchemaAttribute"; + /** * Type schema info for the Gemini function calling. * @@ -226,33 +228,7 @@ export namespace IGeminiSchema { /** * Common attributes that can be applied to all types. */ - export interface __IAttribute { - /** - * Detailed description of the schema. - */ - description?: string; - - /** - * Whether the type is deprecated or not. - * - * @warning document of Gemini says not supported, but cannot sure - */ - deprecated?: boolean; - - /** - * Example value. - * - * @warning document of Gemini says not supported, but cannot sure - */ - example?: any; - - /** - * List of example values as key-value pairs. - * - * @warning document of Gemini says not supported, but cannot sure - */ - examples?: Record; - } + export type __IAttribute = IJsonSchemaAttribute; /** * Configuration for the Gemini schema composition. diff --git a/src/structures/IJsonSchemaAttribute.ts b/src/structures/IJsonSchemaAttribute.ts new file mode 100644 index 0000000..863a2e0 --- /dev/null +++ b/src/structures/IJsonSchemaAttribute.ts @@ -0,0 +1,60 @@ +/** + * Common attributes for JSON schema types. + * + * `IJsonSchemaAttribute` is a common interface for all JSON schema types + * supported in here `@samchon/openapi`. Here is the list of affected JSON + * schema types in `@samchon/openapi`, and you can extend the interface by + * declaring module augmentation. + * + * - {@link OpenApi.IJsonSchema} + * - {@link IChatGptSchema} + * - {@link IClaudeSchema} + * - {@link IGeminiSchema} + * - {@link ILlmSchemaV3} + * - {@link ILlmSchemaV3_1} + * + * For example, if you extend the `IJsonSchemaAttribute` interface like + * below, every JSON schema types in `@samchon/openapi` will have a new + * custom attribute `x-wrtn-placeholder`. + * + * ```typescript + * declare module "@samchon/openapi" { + * export interface IJsonSchemaAttribute { + * /// Placeholder value for frontend application + * /// + * /// Placeholder ia label shown in the input field as a hint. + * /// For example, when an email input field exists, the label + * /// value would be "Insert your email address here". + * "x-wrtn-placeholder"?: string; + * } + * } + * ``` + * + * @author Jeongho Nam - https://github.com/samchon + */ +export interface IJsonSchemaAttribute { + /** + * Title of the schema. + */ + title?: string; + + /** + * Detailed description of the schema. + */ + description?: string; + + /** + * Whether the type is deprecated or not. + */ + deprecated?: boolean; + + /** + * Example value. + */ + example?: any; + + /** + * List of example values as key-value pairs. + */ + examples?: Record; +} diff --git a/src/structures/ILlmSchemaV3.ts b/src/structures/ILlmSchemaV3.ts index ee8b0ad..5eaccb8 100644 --- a/src/structures/ILlmSchemaV3.ts +++ b/src/structures/ILlmSchemaV3.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./IJsonSchemaAttribute"; + /** * Type schema based on OpenAPI v3.0 for LLM function calling. * @@ -435,32 +437,7 @@ export namespace ILlmSchemaV3 { /** * Common attributes that can be applied to all types. */ - export interface __IAttribute { - /** - * Title of the schema. - */ - title?: string; - - /** - * Detailed description of the schema. - */ - description?: string; - - /** - * Whether the type is deprecated or not. - */ - deprecated?: boolean; - - /** - * Example value. - */ - example?: any; - - /** - * List of example values as key-value pairs. - */ - examples?: Record; - } + export type __IAttribute = IJsonSchemaAttribute; /** * Configuration for OpenAPI v3.0 based LLM schema composition. diff --git a/src/structures/ILlmSchemaV3_1.ts b/src/structures/ILlmSchemaV3_1.ts index f9c44eb..f9a9231 100644 --- a/src/structures/ILlmSchemaV3_1.ts +++ b/src/structures/ILlmSchemaV3_1.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./IJsonSchemaAttribute"; + /** * Type schema based on OpenAPI v3.1 for LLM function calling. * @@ -478,32 +480,7 @@ export namespace ILlmSchemaV3_1 { /** * Common attributes that can be applied to all types. */ - export interface __IAttribute { - /** - * Title of the schema. - */ - title?: string; - - /** - * Detailed description of the schema. - */ - description?: string; - - /** - * Whether the type is deprecated or not. - */ - deprecated?: boolean; - - /** - * Example value. - */ - example?: any; - - /** - * List of example values as key-value pairs. - */ - examples?: Record; - } + export type __IAttribute = IJsonSchemaAttribute; /** * Configuration for OpenAPI v3.1 based LLM schema composition. From 01ca380feada0c7c4f8590e3dee55f360e00205e Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Tue, 11 Feb 2025 22:00:44 +0900 Subject: [PATCH 2/5] Publish as v2.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e2b9128..649c69a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@samchon/openapi", - "version": "3.0.0-dev.20250211", + "version": "2.5.0-dev.20250211", "description": "OpenAPI definitions and converters for 'typia' and 'nestia'.", "main": "./lib/index.js", "module": "./lib/index.mjs", From 35a85d5b474aeb099d0eb7835ce144d754c9cdce Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Wed, 12 Feb 2025 01:40:56 +0900 Subject: [PATCH 3/5] Enhance `IJsonSchemaAttribute` type with nested items. --- package.json | 2 +- src/OpenApi.ts | 59 ++++--- src/OpenApiV3.ts | 60 ++++--- src/OpenApiV3_1.ts | 99 ++++++----- src/SwaggerV2.ts | 54 +++--- src/composers/llm/ChatGptSchemaComposer.ts | 2 +- src/index.ts | 2 +- src/structures/IChatGptSchema.ts | 31 ++-- src/structures/IClaudeSchema.ts | 30 ++-- src/structures/IGeminiSchema.ts | 104 +++++++----- src/structures/IJsonSchemaAttribute.ts | 90 +++++++++- src/structures/ILlmSchemaV3.ts | 184 ++++++++++++--------- src/structures/ILlmSchemaV3_1.ts | 149 ++++++++--------- 13 files changed, 527 insertions(+), 339 deletions(-) diff --git a/package.json b/package.json index 649c69a..fd2bbea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@samchon/openapi", - "version": "2.5.0-dev.20250211", + "version": "2.5.0-dev.20250212", "description": "OpenAPI definitions and converters for 'typia' and 'nestia'.", "main": "./lib/index.js", "module": "./lib/index.mjs", diff --git a/src/OpenApi.ts b/src/OpenApi.ts index 4d28a98..d0efb94 100644 --- a/src/OpenApi.ts +++ b/src/OpenApi.ts @@ -669,7 +669,7 @@ export namespace OpenApi { /** * Constant value type. */ - export interface IConstant extends __IAttribute { + export interface IConstant extends IJsonSchemaAttribute { /** * The constant value. */ @@ -679,9 +679,9 @@ export namespace OpenApi { /** * Boolean type info. */ - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { /** - * The default value. + * The default value of the boolean type. */ default?: boolean; } @@ -689,9 +689,9 @@ export namespace OpenApi { /** * Integer type info. */ - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { /** - * Default value. + * Default value of the integer type. * * @type int64 */ @@ -743,9 +743,9 @@ export namespace OpenApi { /** * Number (double) type info. */ - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { /** - * Default value. + * Default value of the number type. */ default?: number; @@ -790,9 +790,9 @@ export namespace OpenApi { /** * String type info. */ - export interface IString extends __ISignificant<"string"> { + export interface IString extends IJsonSchemaAttribute.IString { /** - * Default value. + * Default value of the string type. */ default?: string; @@ -853,7 +853,7 @@ export namespace OpenApi { /** * Array type info. */ - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { /** * Items type info. * @@ -891,7 +891,19 @@ export namespace OpenApi { /** * Tuple type info. */ - export interface ITuple extends __ISignificant<"array"> { + export interface ITuple extends IJsonSchemaAttribute { + /** + * Discriminator value of the type. + * + * Note that, the tuple type cannot be distinguished with + * {@link IArray} type just by this `discriminator` property. + * + * To check whether the type is tuple or array, you have to check + * the existence of {@link IArray.items} or {@link ITuple.prefixItems} + * properties. + */ + type: "array"; + /** * Prefix items. * @@ -949,7 +961,7 @@ export namespace OpenApi { /** * Object type info. */ - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { /** * Properties of the object. * @@ -1017,7 +1029,7 @@ export namespace OpenApi { /** * Reference type directing named schema. */ - export interface IReference extends __IAttribute { + export interface IReference extends IJsonSchemaAttribute { /** * Reference to the named schema. * @@ -1041,7 +1053,7 @@ export namespace OpenApi { * defined `anyOf` instead of the `oneOf`, {@link OpenApi} forcibly * converts it to `oneOf` type. */ - export interface IOneOf extends __IAttribute { + export interface IOneOf extends IJsonSchemaAttribute { /** * List of the union types. */ @@ -1077,9 +1089,9 @@ export namespace OpenApi { /** * Null type. */ - export interface INull extends __ISignificant<"null"> { + export interface INull extends IJsonSchemaAttribute.INull { /** - * Default value. + * Default value of the `null` type. */ default?: null; } @@ -1087,17 +1099,21 @@ export namespace OpenApi { /** * Unknown, the `any` type. */ - export interface IUnknown extends __IAttribute { + export interface IUnknown extends IJsonSchemaAttribute.IUnknown { /** - * Type is never be defined. + * Default value of the `any` type. */ - type?: undefined; + default?: any; } /** * Significant attributes that can be applied to the most types. + * + * @deprecated + * @hidden */ - export interface __ISignificant extends __IAttribute { + export interface __ISignificant + extends IJsonSchemaAttribute { /** * Discriminator value of the type. */ @@ -1106,6 +1122,9 @@ export namespace OpenApi { /** * Common attributes that can be applied to all types. + * + * @deprecated + * @hidden */ export type __IAttribute = IJsonSchemaAttribute; } diff --git a/src/OpenApiV3.ts b/src/OpenApiV3.ts index 7a54559..085dafd 100644 --- a/src/OpenApiV3.ts +++ b/src/OpenApiV3.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./structures/IJsonSchemaAttribute"; + /** * OpenAPI 3.0 definition. * @@ -174,17 +176,19 @@ export namespace OpenApiV3 { | IJsonSchema.IArray | IJsonSchema.IObject | IJsonSchema.IReference - | IJsonSchema.IUnknown - | IJsonSchema.INullOnly | IJsonSchema.IAllOf | IJsonSchema.IAnyOf - | IJsonSchema.IOneOf; + | IJsonSchema.IOneOf + | IJsonSchema.INullOnly + | IJsonSchema.IUnknown; export namespace IJsonSchema { export interface IBoolean extends __ISignificant<"boolean"> { + nullable?: boolean; default?: boolean | null; enum?: Array; } export interface IInteger extends __ISignificant<"integer"> { + nullable?: boolean; /** @type int64 */ default?: number | null; /** @type int64 */ enum?: Array; /** @type int64 */ minimum?: number; @@ -198,6 +202,7 @@ export namespace OpenApiV3 { multipleOf?: number; } export interface INumber extends __ISignificant<"number"> { + nullable?: boolean; default?: number | null; enum?: Array; minimum?: number; @@ -207,6 +212,7 @@ export namespace OpenApiV3 { /** @exclusiveMinimum 0 */ multipleOf?: number; } export interface IString extends __ISignificant<"string"> { + nullable?: boolean; default?: string | null; enum?: Array; format?: @@ -239,37 +245,32 @@ export namespace OpenApiV3 { /** @type uint64 */ maxLength?: number; } - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { + nullable?: boolean; items: IJsonSchema; uniqueItems?: boolean; /** @type uint64 */ minItems?: number; /** @type uint64 */ maxItems?: number; } - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { + nullable?: boolean; properties?: Record; required?: string[]; additionalProperties?: boolean | IJsonSchema; maxProperties?: number; minProperties?: number; } - export interface IReference extends __IAttribute { + export interface IReference extends IJsonSchemaAttribute { $ref: Key; } - export interface IUnknown extends __IAttribute { - type?: undefined; - } - export interface INullOnly extends __IAttribute { - type: "null"; - default?: null; - } - export interface IAllOf extends __IAttribute { + export interface IAllOf extends IJsonSchemaAttribute { allOf: IJsonSchema[]; } - export interface IAnyOf extends __IAttribute { + export interface IAnyOf extends IJsonSchemaAttribute { anyOf: IJsonSchema[]; } - export interface IOneOf extends __IAttribute { + export interface IOneOf extends IJsonSchemaAttribute { oneOf: IJsonSchema[]; discriminator?: IOneOf.IDiscriminator; } @@ -280,17 +281,28 @@ export namespace OpenApiV3 { } } - export interface __ISignificant extends __IAttribute { + export interface INullOnly extends IJsonSchemaAttribute.INull { + default?: null; + } + export interface IUnknown extends IJsonSchemaAttribute.IUnknown { + default?: any; + } + + /** + * @deprecated + * @hidden + */ + export interface __ISignificant + extends IJsonSchemaAttribute { type: Type; nullable?: boolean; } - export interface __IAttribute { - title?: string; - description?: string; - deprecated?: boolean; - example?: any; - examples?: Record; - } + + /** + * @deprecated + * @hidden + */ + export type __IAttribute = IJsonSchemaAttribute; } export type ISecurityScheme = diff --git a/src/OpenApiV3_1.ts b/src/OpenApiV3_1.ts index 9ea2da4..29df727 100644 --- a/src/OpenApiV3_1.ts +++ b/src/OpenApiV3_1.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./structures/IJsonSchemaAttribute"; + /** * OpenAPI v3.1 definition. * @@ -182,11 +184,12 @@ export namespace OpenApiV3_1 { | IJsonSchema.IArray | IJsonSchema.IObject | IJsonSchema.IReference - | IJsonSchema.IUnknown - | IJsonSchema.INull + | IJsonSchema.IRecursiveReference | IJsonSchema.IAllOf | IJsonSchema.IAnyOf - | IJsonSchema.IOneOf; + | IJsonSchema.IOneOf + | IJsonSchema.INull + | IJsonSchema.IUnknown; export namespace IJsonSchema { export interface IMixed extends IConstant, @@ -212,14 +215,17 @@ export namespace OpenApiV3_1 { enum?: any[]; } - export interface IConstant extends __IAttribute { + export interface IConstant extends IJsonSchemaAttribute { const: boolean | number | string; + nullable?: boolean; } - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { + nullable?: boolean; default?: boolean | null; enum?: Array; } - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { + nullable?: boolean; /** @type int64 */ default?: number | null; /** @type int64 */ enum?: Array; /** @type int64 */ minimum?: number; @@ -232,7 +238,8 @@ export namespace OpenApiV3_1 { */ multipleOf?: number; } - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { + nullable?: boolean; default?: number | null; enum?: Array; minimum?: number; @@ -241,8 +248,8 @@ export namespace OpenApiV3_1 { exclusiveMaximum?: number | boolean; /** @exclusiveMinimum 0 */ multipleOf?: number; } - export interface IString extends __ISignificant<"string"> { - contentMediaType?: string; + export interface IString extends IJsonSchemaAttribute.IString { + nullable?: boolean; default?: string | null; enum?: Array; format?: @@ -271,23 +278,42 @@ export namespace OpenApiV3_1 { | "relative-json-pointer" | (string & {}); pattern?: string; + contentMediaType?: string; /** @type uint64 */ minLength?: number; /** @type uint64 */ maxLength?: number; } - export interface IUnknown extends __IAttribute { - type?: undefined; + export interface IObject extends IJsonSchemaAttribute.IObject { + nullable?: boolean; + properties?: Record; + required?: string[]; + additionalProperties?: boolean | IJsonSchema; + maxProperties?: number; + minProperties?: number; } - export interface INull extends __ISignificant<"null"> { - default?: null; + export interface IArray extends IJsonSchemaAttribute.IArray { + nullable?: boolean; + items?: IJsonSchema | IJsonSchema[]; + prefixItems?: IJsonSchema[]; + uniqueItems?: boolean; + additionalItems?: boolean | IJsonSchema; + /** @type uint64 */ minItems?: number; + /** @type uint64 */ maxItems?: number; } - export interface IAllOf extends __IAttribute { + export interface IReference extends IJsonSchemaAttribute { + $ref: Key; + } + export interface IRecursiveReference extends IJsonSchemaAttribute { + $recursiveRef: string; + } + + export interface IAllOf extends IJsonSchemaAttribute { allOf: IJsonSchema[]; } - export interface IAnyOf extends __IAttribute { + export interface IAnyOf extends IJsonSchemaAttribute { anyOf: IJsonSchema[]; } - export interface IOneOf extends __IAttribute { + export interface IOneOf extends IJsonSchemaAttribute { oneOf: IJsonSchema[]; discriminator?: IOneOf.IDiscriminator; } @@ -298,39 +324,28 @@ export namespace OpenApiV3_1 { } } - export interface IArray extends __ISignificant<"array"> { - items?: IJsonSchema | IJsonSchema[]; - prefixItems?: IJsonSchema[]; - uniqueItems?: boolean; - additionalItems?: boolean | IJsonSchema; - /** @type uint64 */ minItems?: number; - /** @type uint64 */ maxItems?: number; - } - export interface IObject extends __ISignificant<"object"> { - properties?: Record; - required?: string[]; - additionalProperties?: boolean | IJsonSchema; - maxProperties?: number; - minProperties?: number; - } - export interface IReference extends __IAttribute { - $ref: Key; + export interface INull extends IJsonSchemaAttribute.INull { + default?: null; } - export interface IRecursiveReference extends __IAttribute { - $recursiveRef: string; + export interface IUnknown extends IJsonSchemaAttribute.IUnknown { + type?: undefined; + default?: any; } + /** + * @deprecated + * @hidden + */ export interface __ISignificant extends __IAttribute { type: Type; nullable?: boolean; } - export interface __IAttribute { - title?: string; - description?: string; - deprecated?: boolean; - example?: any; - examples?: Record; - } + + /** + * @deprecated + * @hidden + */ + export type __IAttribute = IJsonSchemaAttribute; } export type ISecurityScheme = diff --git a/src/SwaggerV2.ts b/src/SwaggerV2.ts index cf28ec3..18809cb 100644 --- a/src/SwaggerV2.ts +++ b/src/SwaggerV2.ts @@ -1,3 +1,5 @@ +import { IJsonSchemaAttribute } from "./structures/IJsonSchemaAttribute"; + /** * Swagger v2.0 definition. * @@ -125,16 +127,20 @@ export namespace SwaggerV2 { | IJsonSchema.IArray | IJsonSchema.IObject | IJsonSchema.IReference - | IJsonSchema.IUnknown - | IJsonSchema.INullOnly | IJsonSchema.IAnyOf - | IJsonSchema.IOneOf; + | IJsonSchema.IOneOf + | IJsonSchema.INullOnly + | IJsonSchema.IUnknown; export namespace IJsonSchema { - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean + extends Omit, + __ISignificant<"boolean"> { default?: boolean | null; enum?: Array; } - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger + extends Omit, + __ISignificant<"integer"> { /** @type int64 */ default?: number | null; /** @type int64 */ enum?: Array; /** @type int64 */ minimum?: number; @@ -147,7 +153,9 @@ export namespace SwaggerV2 { */ multipleOf?: number; } - export interface INumber extends __ISignificant<"number"> { + export interface INumber + extends Omit, + __ISignificant<"number"> { default?: number | null; enum?: Array; minimum?: number; @@ -156,7 +164,9 @@ export namespace SwaggerV2 { exclusiveMaximum?: boolean; /** @exclusiveMinimum 0 */ multipleOf?: number; } - export interface IString extends __ISignificant<"string"> { + export interface IString + extends Omit, + __ISignificant<"string"> { default?: string | null; enum?: Array; format?: @@ -189,13 +199,17 @@ export namespace SwaggerV2 { /** @type uint64 */ maxLength?: number; } - export interface IArray extends __ISignificant<"array"> { + export interface IArray + extends Omit, + __ISignificant<"array"> { items: IJsonSchema; uniqueItems?: boolean; /** @type uint64 */ minItems?: number; /** @type uint64 */ maxItems?: number; } - export interface IObject extends __ISignificant<"object"> { + export interface IObject + extends Omit, + __ISignificant<"object"> { properties?: Record; required?: string[]; additionalProperties?: boolean | IJsonSchema; @@ -206,13 +220,6 @@ export namespace SwaggerV2 { $ref: Key; } - export interface IUnknown extends __IAttribute { - type?: undefined; - } - export interface INullOnly extends __IAttribute { - type: "null"; - default?: null; - } export interface IAllOf extends __IAttribute { allOf: IJsonSchema[]; } @@ -223,15 +230,20 @@ export namespace SwaggerV2 { "x-oneOf": IJsonSchema[]; } + export interface INullOnly extends __IAttribute { + type: "null"; + default?: null; + } + export interface IUnknown extends __IAttribute { + type?: undefined; + } + export interface __ISignificant extends __IAttribute { type: Type; "x-nullable"?: boolean; } - export interface __IAttribute { - title?: string; - description?: string; - deprecated?: boolean; - example?: any; + export interface __IAttribute + extends Omit { examples?: any[]; } } diff --git a/src/composers/llm/ChatGptSchemaComposer.ts b/src/composers/llm/ChatGptSchemaComposer.ts index ca5914b..c531c5a 100644 --- a/src/composers/llm/ChatGptSchemaComposer.ts +++ b/src/composers/llm/ChatGptSchemaComposer.ts @@ -161,7 +161,7 @@ export namespace ChatGptSchemaComposer { }; if (OpenApiTypeChecker.isConstant(input)) insert(input.const); else if (OpenApiTypeChecker.isOneOf(input)) - input.oneOf.forEach(visitConstant); + input.oneOf.forEach((s) => visitConstant(s as ILlmSchemaV3_1)); }; visit(schema); visitConstant(schema); diff --git a/src/index.ts b/src/index.ts index bfaf9f4..3c3de47 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,6 @@ export * from "./SwaggerV2"; export * from "./OpenApiV3"; export * from "./OpenApiV3_1"; -export * from "./structures/IJsonSchemaAttribute"; export * from "./utils/OpenApiTypeChecker"; //---- @@ -25,6 +24,7 @@ export * from "./HttpMigration"; // LLM //---- export * from "./typings/IResult"; +export * from "./structures/IJsonSchemaAttribute"; export * from "./structures/IOpenApiSchemaError"; export * from "./structures/IHttpLlmApplication"; diff --git a/src/structures/IChatGptSchema.ts b/src/structures/IChatGptSchema.ts index e3789ed..f261335 100644 --- a/src/structures/IChatGptSchema.ts +++ b/src/structures/IChatGptSchema.ts @@ -108,7 +108,7 @@ export namespace IChatGptSchema { /** * Boolean type info. */ - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { /** * Enumeration values. */ @@ -118,7 +118,7 @@ export namespace IChatGptSchema { /** * Integer type info. */ - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { /** * Enumeration values. */ @@ -128,7 +128,7 @@ export namespace IChatGptSchema { /** * Number (double) type info. */ - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { /** * Enumeration values. */ @@ -138,7 +138,7 @@ export namespace IChatGptSchema { /** * String type info. */ - export interface IString extends __ISignificant<"string"> { + export interface IString extends IJsonSchemaAttribute.IString { /** * Enumeration values. */ @@ -148,7 +148,7 @@ export namespace IChatGptSchema { /** * Array type info. */ - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { /** * Items type info. * @@ -161,7 +161,7 @@ export namespace IChatGptSchema { /** * Object type info. */ - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { /** * Properties of the object. * @@ -222,7 +222,7 @@ export namespace IChatGptSchema { /** * Reference type directing named schema. */ - export interface IReference extends __IAttribute { + export interface IReference extends IJsonSchemaAttribute { /** * Reference to the named schema. * @@ -246,7 +246,7 @@ export namespace IChatGptSchema { * defined `anyOf` instead of the `oneOf`, {@link IChatGptSchema} forcibly * converts it to `oneOf` type. */ - export interface IAnyOf extends __IAttribute { + export interface IAnyOf extends IJsonSchemaAttribute { /** * List of the union types. */ @@ -256,20 +256,18 @@ export namespace IChatGptSchema { /** * Null type. */ - export interface INull extends __ISignificant<"null"> {} + export interface INull extends IJsonSchemaAttribute.INull {} /** * Unknown, the `any` type. */ - export interface IUnknown extends __IAttribute { - /** - * Type is never be defined. - */ - type?: undefined; - } + export interface IUnknown extends IJsonSchemaAttribute.IUnknown {} /** * Significant attributes that can be applied to the most types. + * + * @deprecated + * @hidden */ export interface __ISignificant extends __IAttribute { /** @@ -280,6 +278,9 @@ export namespace IChatGptSchema { /** * Common attributes that can be applied to all types. + * + * @deprecated + * @hidden */ export type __IAttribute = IJsonSchemaAttribute; diff --git a/src/structures/IClaudeSchema.ts b/src/structures/IClaudeSchema.ts index 4873b72..6e2f22f 100644 --- a/src/structures/IClaudeSchema.ts +++ b/src/structures/IClaudeSchema.ts @@ -53,21 +53,6 @@ export type IClaudeSchema = | IClaudeSchema.INull | IClaudeSchema.IUnknown; export namespace IClaudeSchema { - export import IParameters = ILlmSchemaV3_1.IParameters; - - export import IConstant = ILlmSchemaV3_1.IConstant; - export import IBoolean = ILlmSchemaV3_1.IBoolean; - export import IInteger = ILlmSchemaV3_1.IInteger; - export import INumber = ILlmSchemaV3_1.INumber; - export import IString = ILlmSchemaV3_1.IString; - - export import IObject = ILlmSchemaV3_1.IObject; - export import IArray = ILlmSchemaV3_1.IArray; - export import IReference = ILlmSchemaV3_1.IReference; - export import IOneOf = ILlmSchemaV3_1.IOneOf; - export import INull = ILlmSchemaV3_1.INull; - export import IUnknown = ILlmSchemaV3_1.IUnknown; - /** * Configuration for Claude schema composition. */ @@ -92,4 +77,19 @@ export namespace IClaudeSchema { */ reference: boolean; } + + export import IParameters = ILlmSchemaV3_1.IParameters; + + export import IConstant = ILlmSchemaV3_1.IConstant; + export import IBoolean = ILlmSchemaV3_1.IBoolean; + export import IInteger = ILlmSchemaV3_1.IInteger; + export import INumber = ILlmSchemaV3_1.INumber; + export import IString = ILlmSchemaV3_1.IString; + + export import IObject = ILlmSchemaV3_1.IObject; + export import IArray = ILlmSchemaV3_1.IArray; + export import IReference = ILlmSchemaV3_1.IReference; + export import IOneOf = ILlmSchemaV3_1.IOneOf; + export import INull = ILlmSchemaV3_1.INull; + export import IUnknown = ILlmSchemaV3_1.IUnknown; } diff --git a/src/structures/IGeminiSchema.ts b/src/structures/IGeminiSchema.ts index b63f5d3..e15976d 100644 --- a/src/structures/IGeminiSchema.ts +++ b/src/structures/IGeminiSchema.ts @@ -69,6 +69,23 @@ export type IGeminiSchema = | IGeminiSchema.IUnknown | IGeminiSchema.INullOnly; export namespace IGeminiSchema { + /** + * Configuration for the Gemini schema composition. + */ + export interface IConfig { + /** + * Whether to allow recursive types or not. + * + * If allow, then how many times to repeat the recursive types. + * + * By the way, if the model is "chatgpt", the recursive types are always + * allowed without any limitation, due to it supports the reference type. + * + * @default 3 + */ + recursive: false | number; + } + /** * Type of the function parameters. * @@ -84,7 +101,12 @@ export namespace IGeminiSchema { /** * Boolean type schema info. */ - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Enumeration values. */ @@ -94,7 +116,12 @@ export namespace IGeminiSchema { /** * Integer type schema info. */ - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Enumeration values. * @@ -106,7 +133,12 @@ export namespace IGeminiSchema { /** * Number type schema info. */ - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Enumeration values. */ @@ -116,7 +148,12 @@ export namespace IGeminiSchema { /** * String type schema info. */ - export interface IString extends __ISignificant<"string"> { + export interface IString extends IJsonSchemaAttribute.IString { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Enumeration values. */ @@ -126,7 +163,12 @@ export namespace IGeminiSchema { /** * Array type schema info. */ - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Items type schema info. * @@ -139,7 +181,12 @@ export namespace IGeminiSchema { /** * Object type schema info. */ - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Properties of the object. * @@ -189,29 +236,22 @@ export namespace IGeminiSchema { } /** - * Unknown type schema info. - * - * It means the type of the value is `any`. + * Null only type schema info. */ - export interface IUnknown extends __IAttribute { - /** - * Type is never be defined. - */ - type?: undefined; - } + export interface INullOnly extends IJsonSchemaAttribute.INull {} /** - * Null only type schema info. + * Unknown type schema info. + * + * It means the type of the value is `any`. */ - export interface INullOnly extends __IAttribute { - /** - * Type is always `null`. - */ - type: "null"; - } + export interface IUnknown extends IJsonSchemaAttribute.IUnknown {} /** * Significant attributes that can be applied to the most types. + * + * @deprecated + * @hidden */ export interface __ISignificant extends __IAttribute { /** @@ -227,23 +267,9 @@ export namespace IGeminiSchema { /** * Common attributes that can be applied to all types. + * + * @deprecated + * @hidden */ export type __IAttribute = IJsonSchemaAttribute; - - /** - * Configuration for the Gemini schema composition. - */ - export interface IConfig { - /** - * Whether to allow recursive types or not. - * - * If allow, then how many times to repeat the recursive types. - * - * By the way, if the model is "chatgpt", the recursive types are always - * allowed without any limitation, due to it supports the reference type. - * - * @default 3 - */ - recursive: false | number; - } } diff --git a/src/structures/IJsonSchemaAttribute.ts b/src/structures/IJsonSchemaAttribute.ts index 863a2e0..f3defe4 100644 --- a/src/structures/IJsonSchemaAttribute.ts +++ b/src/structures/IJsonSchemaAttribute.ts @@ -1,21 +1,30 @@ /** * Common attributes for JSON schema types. * - * `IJsonSchemaAttribute` is a common interface for all JSON schema types - * supported in here `@samchon/openapi`. Here is the list of affected JSON - * schema types in `@samchon/openapi`, and you can extend the interface by - * declaring module augmentation. + * `IJsonSchemaAttribute` is a common interface for all JSON schema + * types supported in here `@samchon/openapi`. Here is the list of + * affected JSON schema types in `@samchon/openapi`, and you can extend + * the interface by declaring module augmentation. * * - {@link OpenApi.IJsonSchema} + * - {@link OpenApiV3_1.IJsonSchema} + * - {@link OpenApiV3.IJsonSchema} + * - {@link SwaggerV2.IJsonSchema} * - {@link IChatGptSchema} * - {@link IClaudeSchema} * - {@link IGeminiSchema} * - {@link ILlmSchemaV3} * - {@link ILlmSchemaV3_1} * - * For example, if you extend the `IJsonSchemaAttribute` interface like - * below, every JSON schema types in `@samchon/openapi` will have a new - * custom attribute `x-wrtn-placeholder`. + * For example, if you extend the `IJsonSchemaAttribute` interface + * like below, every JSON schema types in `@samchon/openapi` will have + * a new custom attribute `x-wrtn-placeholder`. + * + * Also, if you augment the nested type like + * `IJsonSchemaAttribute.IString`, you can add the custom attribute + * to every string types in the JSON schema. In the below example case, + * every string types will have a new custom attribute + * `x-wrtn-secret-key`. * * ```typescript * declare module "@samchon/openapi" { @@ -27,6 +36,17 @@ * /// value would be "Insert your email address here". * "x-wrtn-placeholder"?: string; * } + * export namespace IJsonSchemaAttribute { + * export interface IString { + * /// Secret key for the schema. + * /// + * /// `x-wrtn-secret-key` is a property means a secret key + * /// that is required for the target API endpoint calling. + * /// If the secret key is not filled, the API call would + * /// be failed. + * "x-wrtn-secret-key"?: string; + * } + * } * } * ``` * @@ -58,3 +78,59 @@ export interface IJsonSchemaAttribute { */ examples?: Record; } +export namespace IJsonSchemaAttribute { + /** + * Common attributes for boolean types. + */ + export interface IBoolean extends ISignificant<"boolean"> {} + + /** + * Common attributes for integer types. + */ + export interface IInteger extends ISignificant<"integer"> {} + + /** + * Common attributes for number types. + */ + export interface INumber extends ISignificant<"number"> {} + + /** + * Common attributes for string types. + */ + export interface IString extends ISignificant<"string"> {} + + /** + * Common attributes for object types. + */ + export interface IObject extends ISignificant<"object"> {} + + /** + * Common attributes for array types. + */ + export interface IArray extends ISignificant<"array"> {} + + /** + * Common attributes for null types. + */ + export interface INull extends ISignificant<"null"> {} + + /** + * Common attributes for unknown types. + */ + export interface IUnknown extends IJsonSchemaAttribute { + /** + * Type is never be defined. + */ + type?: undefined; + } + + /** + * Significant attributes that can be applied to the most types. + */ + interface ISignificant extends IJsonSchemaAttribute { + /** + * Discriminator value of the type. + */ + type: Type; + } +} diff --git a/src/structures/ILlmSchemaV3.ts b/src/structures/ILlmSchemaV3.ts index 5eaccb8..faadd0d 100644 --- a/src/structures/ILlmSchemaV3.ts +++ b/src/structures/ILlmSchemaV3.ts @@ -52,6 +52,56 @@ export type ILlmSchemaV3 = | ILlmSchemaV3.INullOnly | ILlmSchemaV3.IOneOf; export namespace ILlmSchemaV3 { + /** + * Configuration for OpenAPI v3.0 based LLM schema composition. + */ + export interface IConfig { + /** + * Whether to allow constraint properties or not. + * + * If you configure this property to `false`, the schemas do not contain + * the constraint properties of below. Instead, below properties would be + * written to the {@link ILlmSchemaV3.__IAttribute.description} property + * as a comment string like `"@format uuid"`. + * + * This is because some LLM schema model like {@link IGeminiSchema} + * has banned such constraint, because their LLM cannot understand the + * constraint properties and occur the hallucination. + * + * Therefore, considering your LLM model's performance, capability, + * and the complexity of your parameter types, determine which is better, + * to allow the constraint properties or not. + * + * - {@link ILlmSchemaV3.INumber.minimum} + * - {@link ILlmSchemaV3.INumber.maximum} + * - {@link ILlmSchemaV3.INumber.multipleOf} + * - {@link ILlmSchemaV3.IString.minLength} + * - {@link ILlmSchemaV3.IString.maxLength} + * - {@link ILlmSchemaV3.IString.format} + * - {@link ILlmSchemaV3.IString.pattern} + * - {@link ILlmSchemaV3.IString.contentMediaType} + * - {@link ILlmSchemaV3.IString.default} + * - {@link ILlmSchemaV3.IArray.minItems} + * - {@link ILlmSchemaV3.IArray.maxItems} + * - {@link ILlmSchemaV3.IArray.unique} + * + * @default true + */ + constraint: boolean; + + /** + * Whether to allow recursive types or not. + * + * If allow, then how many times to repeat the recursive types. + * + * By the way, if the model is "chatgpt", the recursive types are always + * allowed without any limitation, due to it supports the reference type. + * + * @default 3 + */ + recursive: false | number; + } + /** * Type of the function parameters. * @@ -77,7 +127,12 @@ export namespace ILlmSchemaV3 { /** * Boolean type schema info. */ - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Default value. */ @@ -92,7 +147,12 @@ export namespace ILlmSchemaV3 { /** * Integer type schema info. */ - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Default value. * @@ -153,7 +213,12 @@ export namespace ILlmSchemaV3 { /** * Number type schema info. */ - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Default value. */ @@ -205,7 +270,12 @@ export namespace ILlmSchemaV3 { /** * String type schema info. */ - export interface IString extends __ISignificant<"string"> { + export interface IString extends IJsonSchemaAttribute.IString { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Default value. */ @@ -273,7 +343,12 @@ export namespace ILlmSchemaV3 { /** * Array type schema info. */ - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Items type schema info. * @@ -311,7 +386,12 @@ export namespace ILlmSchemaV3 { /** * Object type schema info. */ - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { + /** + * Whether to allow `null` value or not. + */ + nullable?: boolean; + /** * Properties of the object. * @@ -377,26 +457,25 @@ export namespace ILlmSchemaV3 { } /** - * Unknown type schema info. + * One of type schema info. * - * It means the type of the value is `any`. + * `IOneOf` represents an union type of the TypeScript (`A | B | C`). + * + * For reference, even though your Swagger (or OpenAPI) document has + * defined `anyOf` instead of the `oneOf`, it has been forcibly converted + * to `oneOf` type by {@link OpenApi.convert OpenAPI conversion}. */ - export interface IUnknown extends __IAttribute { + export interface IOneOf extends IJsonSchemaAttribute { /** - * Type is never be defined. + * List of the union types. */ - type?: undefined; + oneOf: Exclude[]; } /** * Null only type schema info. */ - export interface INullOnly extends __IAttribute { - /** - * Type is always `null`. - */ - type: "null"; - + export interface INullOnly extends IJsonSchemaAttribute.INull { /** * Default value. */ @@ -404,23 +483,17 @@ export namespace ILlmSchemaV3 { } /** - * One of type schema info. - * - * `IOneOf` represents an union type of the TypeScript (`A | B | C`). + * Unknown type schema info. * - * For reference, even though your Swagger (or OpenAPI) document has - * defined `anyOf` instead of the `oneOf`, it has been forcibly converted - * to `oneOf` type by {@link OpenApi.convert OpenAPI conversion}. + * It means the type of the value is `any`. */ - export interface IOneOf extends __IAttribute { - /** - * List of the union types. - */ - oneOf: Exclude[]; - } + export interface IUnknown extends IJsonSchemaAttribute.IUnknown {} /** * Significant attributes that can be applied to the most types. + * + * @deprecated + * @hidden */ export interface __ISignificant extends __IAttribute { /** @@ -436,56 +509,9 @@ export namespace ILlmSchemaV3 { /** * Common attributes that can be applied to all types. + * + * @deprecated + * @hidden */ export type __IAttribute = IJsonSchemaAttribute; - - /** - * Configuration for OpenAPI v3.0 based LLM schema composition. - */ - export interface IConfig { - /** - * Whether to allow constraint properties or not. - * - * If you configure this property to `false`, the schemas do not contain - * the constraint properties of below. Instead, below properties would be - * written to the {@link ILlmSchemaV3.__IAttribute.description} property - * as a comment string like `"@format uuid"`. - * - * This is because some LLM schema model like {@link IGeminiSchema} - * has banned such constraint, because their LLM cannot understand the - * constraint properties and occur the hallucination. - * - * Therefore, considering your LLM model's performance, capability, - * and the complexity of your parameter types, determine which is better, - * to allow the constraint properties or not. - * - * - {@link ILlmSchemaV3.INumber.minimum} - * - {@link ILlmSchemaV3.INumber.maximum} - * - {@link ILlmSchemaV3.INumber.multipleOf} - * - {@link ILlmSchemaV3.IString.minLength} - * - {@link ILlmSchemaV3.IString.maxLength} - * - {@link ILlmSchemaV3.IString.format} - * - {@link ILlmSchemaV3.IString.pattern} - * - {@link ILlmSchemaV3.IString.contentMediaType} - * - {@link ILlmSchemaV3.IString.default} - * - {@link ILlmSchemaV3.IArray.minItems} - * - {@link ILlmSchemaV3.IArray.maxItems} - * - {@link ILlmSchemaV3.IArray.unique} - * - * @default true - */ - constraint: boolean; - - /** - * Whether to allow recursive types or not. - * - * If allow, then how many times to repeat the recursive types. - * - * By the way, if the model is "chatgpt", the recursive types are always - * allowed without any limitation, due to it supports the reference type. - * - * @default 3 - */ - recursive: false | number; - } } diff --git a/src/structures/ILlmSchemaV3_1.ts b/src/structures/ILlmSchemaV3_1.ts index f9a9231..d70eb3f 100644 --- a/src/structures/ILlmSchemaV3_1.ts +++ b/src/structures/ILlmSchemaV3_1.ts @@ -70,6 +70,64 @@ export type ILlmSchemaV3_1 = | ILlmSchemaV3_1.INull | ILlmSchemaV3_1.IUnknown; export namespace ILlmSchemaV3_1 { + /** + * Configuration for OpenAPI v3.1 based LLM schema composition. + */ + export interface IConfig { + /** + * Whether to allow constraint properties or not. + * + * If you configure this property to `false`, the schemas do not contain + * the constraint properties of below. Instead, below properties would be + * written to the {@link ILlmSchemaV3_1.__IAttribute.description} property + * as a comment string like `"@format uuid"`. + * + * This is because some LLM schema model like {@link IChatGptSchema} + * has banned such constraint, because their LLM cannot understand the + * constraint properties and occur the hallucination. + * + * Therefore, considering your LLM model's performance, capability, + * and the complexity of your parameter types, determine which is better, + * to allow the constraint properties or not. + * + * - {@link ILlmSchemaV3_1.INumber.minimum} + * - {@link ILlmSchemaV3_1.INumber.maximum} + * - {@link ILlmSchemaV3_1.INumber.multipleOf} + * - {@link ILlmSchemaV3_1.IString.minLength} + * - {@link ILlmSchemaV3_1.IString.maxLength} + * - {@link ILlmSchemaV3_1.IString.format} + * - {@link ILlmSchemaV3_1.IString.pattern} + * - {@link ILlmSchemaV3_1.IString.contentMediaType} + * - {@link ILlmSchemaV3_1.IString.default} + * - {@link ILlmSchemaV3_1.IArray.minItems} + * - {@link ILlmSchemaV3_1.IArray.maxItems} + * - {@link ILlmSchemaV3_1.IArray.unique} + * + * @default true + */ + constraint: boolean; + + /** + * Whether to allow reference type in everywhere. + * + * If you configure this property to `false`, most of reference types + * represented by {@link ILlmSchemaV3_1.IReference} would be escaped to + * a plain type unless recursive type case. + * + * This is because some low sized LLM models does not understand the + * reference type well, and even the large size LLM models sometimes occur + * the hallucination. + * + * However, the reference type makes the schema size smaller, so that reduces + * the LLM token cost. Therefore, if you're using the large size of LLM model, + * and want to reduce the LLM token cost, you can configure this property to + * `true`. + * + * @default false + */ + reference: boolean; + } + /** * Type of the function parameters. * @@ -100,7 +158,7 @@ export namespace ILlmSchemaV3_1 { /** * Constant value type. */ - export interface IConstant extends __IAttribute { + export interface IConstant extends IJsonSchemaAttribute { /** * The constant value. */ @@ -110,7 +168,7 @@ export namespace ILlmSchemaV3_1 { /** * Boolean type info. */ - export interface IBoolean extends __ISignificant<"boolean"> { + export interface IBoolean extends IJsonSchemaAttribute.IBoolean { /** * The default value. */ @@ -120,7 +178,7 @@ export namespace ILlmSchemaV3_1 { /** * Integer type info. */ - export interface IInteger extends __ISignificant<"integer"> { + export interface IInteger extends IJsonSchemaAttribute.IInteger { /** * Default value. * @@ -174,7 +232,7 @@ export namespace ILlmSchemaV3_1 { /** * Number (double) type info. */ - export interface INumber extends __ISignificant<"number"> { + export interface INumber extends IJsonSchemaAttribute.INumber { /** * Default value. */ @@ -221,7 +279,7 @@ export namespace ILlmSchemaV3_1 { /** * String type info. */ - export interface IString extends __ISignificant<"string"> { + export interface IString extends IJsonSchemaAttribute.IString { /** * Default value. */ @@ -284,7 +342,7 @@ export namespace ILlmSchemaV3_1 { /** * Array type info. */ - export interface IArray extends __ISignificant<"array"> { + export interface IArray extends IJsonSchemaAttribute.IArray { /** * Items type info. * @@ -322,7 +380,7 @@ export namespace ILlmSchemaV3_1 { /** * Object type info. */ - export interface IObject extends __ISignificant<"object"> { + export interface IObject extends IJsonSchemaAttribute.IObject { /** * Properties of the object. * @@ -390,7 +448,7 @@ export namespace ILlmSchemaV3_1 { /** * Reference type directing named schema. */ - export interface IReference extends __IAttribute { + export interface IReference extends IJsonSchemaAttribute { /** * Reference to the named schema. * @@ -414,7 +472,7 @@ export namespace ILlmSchemaV3_1 { * defined `anyOf` instead of the `oneOf`, {@link OpenApi} forcibly * converts it to `oneOf` type. */ - export interface IOneOf extends __IAttribute { + export interface IOneOf extends IJsonSchemaAttribute { /** * List of the union types. */ @@ -450,7 +508,7 @@ export namespace ILlmSchemaV3_1 { /** * Null type. */ - export interface INull extends __ISignificant<"null"> { + export interface INull extends IJsonSchemaAttribute.INull { /** * Default value. */ @@ -460,15 +518,13 @@ export namespace ILlmSchemaV3_1 { /** * Unknown, the `any` type. */ - export interface IUnknown extends __IAttribute { - /** - * Type is never be defined. - */ - type?: undefined; - } + export interface IUnknown extends IJsonSchemaAttribute.IUnknown {} /** * Significant attributes that can be applied to the most types. + * + * @deprecated + * @hidden */ export interface __ISignificant extends __IAttribute { /** @@ -479,64 +535,9 @@ export namespace ILlmSchemaV3_1 { /** * Common attributes that can be applied to all types. + * + * @deprecated + * @hidden */ export type __IAttribute = IJsonSchemaAttribute; - - /** - * Configuration for OpenAPI v3.1 based LLM schema composition. - */ - export interface IConfig { - /** - * Whether to allow constraint properties or not. - * - * If you configure this property to `false`, the schemas do not contain - * the constraint properties of below. Instead, below properties would be - * written to the {@link ILlmSchemaV3_1.__IAttribute.description} property - * as a comment string like `"@format uuid"`. - * - * This is because some LLM schema model like {@link IChatGptSchema} - * has banned such constraint, because their LLM cannot understand the - * constraint properties and occur the hallucination. - * - * Therefore, considering your LLM model's performance, capability, - * and the complexity of your parameter types, determine which is better, - * to allow the constraint properties or not. - * - * - {@link ILlmSchemaV3_1.INumber.minimum} - * - {@link ILlmSchemaV3_1.INumber.maximum} - * - {@link ILlmSchemaV3_1.INumber.multipleOf} - * - {@link ILlmSchemaV3_1.IString.minLength} - * - {@link ILlmSchemaV3_1.IString.maxLength} - * - {@link ILlmSchemaV3_1.IString.format} - * - {@link ILlmSchemaV3_1.IString.pattern} - * - {@link ILlmSchemaV3_1.IString.contentMediaType} - * - {@link ILlmSchemaV3_1.IString.default} - * - {@link ILlmSchemaV3_1.IArray.minItems} - * - {@link ILlmSchemaV3_1.IArray.maxItems} - * - {@link ILlmSchemaV3_1.IArray.unique} - * - * @default true - */ - constraint: boolean; - - /** - * Whether to allow reference type in everywhere. - * - * If you configure this property to `false`, most of reference types - * represented by {@link ILlmSchemaV3_1.IReference} would be escaped to - * a plain type unless recursive type case. - * - * This is because some low sized LLM models does not understand the - * reference type well, and even the large size LLM models sometimes occur - * the hallucination. - * - * However, the reference type makes the schema size smaller, so that reduces - * the LLM token cost. Therefore, if you're using the large size of LLM model, - * and want to reduce the LLM token cost, you can configure this property to - * `true`. - * - * @default false - */ - reference: boolean; - } } From 9a3a690fbee1b4d7c3a13425d1e70a95a8cd6ddb Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Wed, 12 Feb 2025 10:15:05 +0900 Subject: [PATCH 4/5] Change rule of the `IHTtpMigrateRoute.emendedPath` --- package.json | 2 +- src/http/HttpMigrateRouteFetcher.ts | 2 +- src/structures/IHttpMigrateRoute.ts | 3 +-- src/structures/ILlmApplication.ts | 13 ++++++++++++- src/utils/EndpointUtil.ts | 7 ++++--- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index fd2bbea..e5b122c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@samchon/openapi", - "version": "2.5.0-dev.20250212", + "version": "3.0.0-dev.20250212", "description": "OpenAPI definitions and converters for 'typia' and 'nestia'.", "main": "./lib/index.js", "module": "./lib/index.mjs", diff --git a/src/http/HttpMigrateRouteFetcher.ts b/src/http/HttpMigrateRouteFetcher.ts index c557801..5b8ce83 100644 --- a/src/http/HttpMigrateRouteFetcher.ts +++ b/src/http/HttpMigrateRouteFetcher.ts @@ -86,7 +86,7 @@ const _Propagate = async ( props.route.path[0] !== "/" ? `/${getPath(props)}` : getPath(props); - const url: URL = new URL(`${props.connection.host}/${path}`); + const url: URL = new URL(`${props.connection.host}${path}`); const response: Response = await (props.connection.fetch ?? fetch)(url, init); const status: number = response.status; diff --git a/src/structures/IHttpMigrateRoute.ts b/src/structures/IHttpMigrateRoute.ts index f1aef52..b4e9718 100644 --- a/src/structures/IHttpMigrateRoute.ts +++ b/src/structures/IHttpMigrateRoute.ts @@ -34,8 +34,7 @@ export interface IHttpMigrateRoute { * The difference between {@link path} is: * * 1. Path parameters are replaced with `:param` format. - * 2. Empty sub-paths are removed. - * 3. Do not starts with `/`. + * 2. Always starts with `/`. */ emendedPath: string; diff --git a/src/structures/ILlmApplication.ts b/src/structures/ILlmApplication.ts index 0ab2058..636e0e0 100644 --- a/src/structures/ILlmApplication.ts +++ b/src/structures/ILlmApplication.ts @@ -25,7 +25,10 @@ import { ILlmSchema } from "./ILlmSchema"; * @reference https://platform.openai.com/docs/guides/function-calling * @author Jeongho Nam - https://github.com/samchon */ -export interface ILlmApplication { +export interface ILlmApplication< + Model extends ILlmSchema.Model, + Class extends object = any, +> { /** * Model of the LLM. */ @@ -42,6 +45,14 @@ export interface ILlmApplication { * Configuration for the application. */ options: ILlmApplication.IOptions; + + /** + * Class type, the source of the LLM application. + * + * This property is just for the generic type inference, + * and its value is always `undefined`. + */ + __class?: Class | undefined; } export namespace ILlmApplication { /** diff --git a/src/utils/EndpointUtil.ts b/src/utils/EndpointUtil.ts index 125f68e..0af36ab 100644 --- a/src/utils/EndpointUtil.ts +++ b/src/utils/EndpointUtil.ts @@ -16,16 +16,17 @@ export namespace EndpointUtil { .map((str) => normalize(str.trim())) .filter((str) => !!str.length); - export const reJoinWithDecimalParameters = (path: string) => - path + export const reJoinWithDecimalParameters = (path: string) => { + path = path .split("/") - .filter((str) => !!str.length) .map((str) => str[0] === "{" && str[str.length - 1] === "}" ? `:${str.substring(1, str.length - 1)}` : str, ) .join("/"); + return `${path.startsWith("/") ? "" : "/"}${path}`; + }; export const normalize = (str: string): string => { str = str.split(".").join("_").split("-").join("_").trim(); From ed16b04db687725c246842fe968f90adca1bb3e5 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Wed, 12 Feb 2025 13:44:22 +0900 Subject: [PATCH 5/5] Test whether `IHttpLlmApplication` covers `ILlmApplication` --- .../llm/validate_llm_application_type.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 test/features/llm/validate_llm_application_type.ts diff --git a/test/features/llm/validate_llm_application_type.ts b/test/features/llm/validate_llm_application_type.ts new file mode 100644 index 0000000..e22ef53 --- /dev/null +++ b/test/features/llm/validate_llm_application_type.ts @@ -0,0 +1,54 @@ +import { + HttpLlm, + IHttpLlmApplication, + ILlmApplication, + ILlmSchema, + OpenApi, +} from "@samchon/openapi"; +import fs from "fs"; +import { Singleton } from "tstl"; +import typia from "typia"; + +import { TestGlobal } from "../../TestGlobal"; + +export const test_chatgpt_application_type = (): void => { + const http: IHttpLlmApplication<"chatgpt"> = application("chatgpt"); + const classic: ILlmApplication<"chatgpt"> = http; + typia.assert(classic); +}; + +export const test_claude_application_type = (): void => { + const http: IHttpLlmApplication<"claude"> = application("claude"); + const classic: ILlmApplication<"claude"> = http; + typia.assert(classic); +}; + +export const test_llama_application_type = (): void => { + const http: IHttpLlmApplication<"llama"> = application("llama"); + const classic: ILlmApplication<"llama"> = http; + typia.assert(classic); +}; + +export const test_llm_v30_application_type = (): void => { + const http: IHttpLlmApplication<"3.0"> = application("3.0"); + const classic: ILlmApplication<"3.0"> = http; + typia.assert(classic); +}; + +export const test_llm_v31_application_type = (): void => { + const http: IHttpLlmApplication<"3.1"> = application("3.1"); + const classic: ILlmApplication<"3.1"> = http; + typia.assert(classic); +}; + +const application = (model: Model) => + HttpLlm.application({ + model, + document: document.get(), + }); + +const document = new Singleton(() => + typia.json.assertParse( + fs.readFileSync(`${TestGlobal.ROOT}/examples/v3.1/shopping.json`, "utf8"), + ), +);