diff --git a/package.json b/package.json index b2c221c..9e13a46 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@wrtnio/schema", - "version": "3.0.0", + "version": "3.0.1", "description": "JSON and LLM function calling schemas extended for Wrtn Studio Pro", "main": "lib/index.js", "module": "./lib/index.mjs", @@ -31,7 +31,7 @@ }, "homepage": "https://github.com/wrtnio/schema#readme", "dependencies": { - "@samchon/openapi": "^2.0.0" + "@samchon/openapi": "^2.0.3" }, "devDependencies": { "@nestia/core": "^4.0.0", @@ -45,10 +45,12 @@ "@rollup/plugin-typescript": "^11.1.6", "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/multer": "^1.4.12", + "chalk": "4.1.2", "multer": "^1.4.5-lts.1", "prettier": "^3.3.3", "rimraf": "^6.0.1", "rollup": "^4.22.0", + "source-map-support": "^0.5.21", "ts-patch": "^3.2.1", "typescript": "5.5.4", "typescript-transform-paths": "^3.5.2", diff --git a/src/internal/HttpOpenAiSeparator.ts b/src/internal/HttpOpenAiSeparator.ts index 1792279..fd01e1d 100644 --- a/src/internal/HttpOpenAiSeparator.ts +++ b/src/internal/HttpOpenAiSeparator.ts @@ -60,11 +60,6 @@ export namespace HttpOpenAiSeparator { ( input: IOpenAiSchema.IObject, ): [IOpenAiSchema.IObject | null, IOpenAiSchema.IObject | null] => { - if ( - !!input.additionalProperties || - Object.keys(input.properties ?? {}).length === 0 - ) - return [input, null]; const llm = { ...input, properties: {} as Record, @@ -78,6 +73,14 @@ export namespace HttpOpenAiSeparator { if (x !== null) llm.properties[key] = x; if (y !== null) human.properties[key] = y; } + if ( + typeof input.additionalProperties === "object" && + input.additionalProperties !== null + ) { + const [dx, dy] = schema(predicator)(input.additionalProperties); + llm.additionalProperties = dx ?? false; + human.additionalProperties = dy ?? false; + } return [ Object.keys(llm.properties).length === 0 ? null : shrinkRequired(llm), Object.keys(human.properties).length === 0 diff --git a/test/features/test_http_llm_merge_parameters.ts b/test/features/test_http_llm_merge_parameters.ts new file mode 100644 index 0000000..258db25 --- /dev/null +++ b/test/features/test_http_llm_merge_parameters.ts @@ -0,0 +1,47 @@ +import { TestValidator } from "@nestia/e2e"; +import { IHttpOpenAiFunction, IOpenAiSchema } from "@wrtnio/schema"; +import { LlmDataMerger } from "@wrtnio/schema/lib/internal/HttpOpenAiMerger"; + +export const test_http_llm_merge_parameters = (): void => { + const p = LlmDataMerger.parameters({ + function: { + parameters: [ + { + type: "array", + items: {}, + }, + ] satisfies IOpenAiSchema[], + separated: { + human: [ + { + index: 0, + schema: { + type: "array", + items: {}, + }, + }, + ], + llm: [ + { + index: 0, + schema: { + type: "array", + items: {}, + }, + }, + ], + } satisfies IHttpOpenAiFunction.ISeparated, + } as IHttpOpenAiFunction, + llm: [], + human: [ + { + a: 1, + }, + ], + }); + TestValidator.equals(p as any)([ + { + a: 1, + }, + ]); +}; diff --git a/test/features/test_http_llm_separate_parameters.ts b/test/features/test_http_llm_separate_parameters.ts new file mode 100644 index 0000000..a6b4b51 --- /dev/null +++ b/test/features/test_http_llm_separate_parameters.ts @@ -0,0 +1,31 @@ +import { TestValidator } from "@nestia/e2e"; +import { OpenApi } from "@samchon/openapi"; +import { HttpOpenAi, OpenAiTypeChecker } from "@wrtnio/schema"; +import typia from "typia"; + +export const test_http_llm_separate_parameters = async (): Promise => { + const document: OpenApi.IDocument = typia.assert( + await fetch( + "https://wrtnio.github.io/connectors/swagger/swagger.json", + ).then((r) => r.json()), + ); + for (const path of Object.keys(document.paths ?? {})) + if (path !== "/connector/notion/database-item/{databaseId}") + delete document.paths?.[path]; + + const app = HttpOpenAi.application({ + document, + options: { + separate: (schema) => + OpenAiTypeChecker.isString(schema) && + schema["x-wrtn-secret-key"] !== undefined, + }, + }); + const func = app.functions.find( + (f) => + f.method === "post" && + f.path === "/connector/notion/database-item/{databaseId}", + ); + if (func === undefined) throw new Error("Function not found"); + TestValidator.equals("human")(func.separated?.human.at(0)?.index)(1); +};