Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ban multipart/form-data type in the LLM #67

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/converters/HttpLlmConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,30 @@ export namespace HttpLlmConverter {
}));
const functions: IHttpLlmFunction[] = migrate.routes
.map((route) => {
if (route.method === "head") return null;
if (route.method === "head") {
errors.push({
method: route.method,
path: route.path,
messages: ["HEAD method is not supported in the LLM application."],
operation: () => route.operation(),
route: () => route,
});
return null;
} else if (
route.body?.type === "multipart/form-data" ||
route.success?.type === "multipart/form-data"
) {
errors.push({
method: route.method,
path: route.path,
messages: [
`The "multipart/form-data" content type is not supported in the LLM application.`,
],
operation: () => route.operation(),
route: () => route,
});
return null;
}
const func: IHttpLlmFunction | null = composeFunction(options)(
migrate.document().components,
)(route);
Expand Down
6 changes: 3 additions & 3 deletions test/controllers/AppController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ export class AppController {
};
}

/**
* @deprecated
*/
@TypedRoute.Post(":index/:level/:optimal/multipart")
public query_multipart(
@TypedParam("index")
Expand All @@ -94,6 +91,9 @@ export class AppController {
};
}

/**
* @deprecated
*/
@TypedRoute.Get("nothing")
public nothing(): void {}
}
Expand Down
3 changes: 1 addition & 2 deletions test/features/llm/test_http_llm_function_deprecated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ export const test_http_llm_function_deprecated = (): void => {
keyword: true,
});
const func: IHttpLlmFunction | undefined = application.functions.find(
(f) =>
f.method === "post" && f.path === "/{index}/{level}/{optimal}/multipart",
(f) => f.method === "get" && f.path === "/nothing",
);
TestValidator.equals("deprecated")(func?.deprecated)(true);
};
18 changes: 18 additions & 0 deletions test/features/llm/test_http_llm_function_multipart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { TestValidator } from "@nestia/e2e";
import { HttpLlm, IHttpLlmApplication, OpenApi } from "@samchon/openapi";

import swagger from "../../swagger.json";

export const test_http_llm_function_multipart = (): void => {
const document: OpenApi.IDocument = OpenApi.convert(swagger as any);
const application: IHttpLlmApplication = HttpLlm.application(document, {
keyword: true,
});
TestValidator.equals("multipart not suppported")(
!!application.errors.find(
(e) =>
e.method === "post" &&
e.path === "/{index}/{level}/{optimal}/multipart",
),
)(true);
};
104 changes: 104 additions & 0 deletions test/features/llm/test_llm_schema_recursive_array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { TestValidator } from "@nestia/e2e";
import { HttpLlmConverter } from "@samchon/openapi/lib/converters/HttpLlmConverter";

export const test_llm_schema_recursive_array = (): void => {
const schema = HttpLlmConverter.schema({
components: {
schemas: {
Department: {
type: "object",
properties: {
id: {
type: "string",
format: "uuid",
},
name: {
type: "string",
},
children: {
type: "array",
items: {
$ref: "#/components/schemas/Department",
},
},
},
required: ["id", "name", "children"],
},
},
},
schema: {
$ref: "#/components/schemas/Department",
},
recursive: 3,
});
TestValidator.equals("recursive")(schema)({
type: "object",
properties: {
id: {
type: "string",
format: "uuid",
},
name: {
type: "string",
},
children: {
type: "array",
items: {
type: "object",
properties: {
id: {
type: "string",
format: "uuid",
},
name: {
type: "string",
},
children: {
type: "array",
items: {
type: "object",
properties: {
id: {
type: "string",
format: "uuid",
},
name: {
type: "string",
},
children: {
type: "array",
items: {
type: "object",
properties: {
id: {
type: "string",
format: "uuid",
},
name: {
type: "string",
},
children: {
type: "array",
items: {},
maxItems: 0,
},
},
required: ["id", "name", "children"],
additionalProperties: false,
},
},
},
required: ["id", "name", "children"],
additionalProperties: false,
},
},
},
required: ["id", "name", "children"],
additionalProperties: false,
},
},
},
required: ["id", "name", "children"],
additionalProperties: false,
});
};
113 changes: 107 additions & 6 deletions test/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}
],
"info": {
"version": "1.1.1-dev.20241008-2",
"version": "1.2.0",
"title": "@samchon/openapi",
"description": "OpenAPI definitions and converters for 'typia' and 'nestia'.",
"license": {
Expand Down Expand Up @@ -53,7 +53,24 @@
"application/json": {
"schema": {
"type": "object",
"properties": {}
"properties": {
"index": {
"type": "string",
"format": "uri",
"contentMediaType": "text/html"
},
"level": {
"type": "number"
},
"optimal": {
"type": "boolean"
}
},
"required": [
"index",
"level",
"optimal"
]
}
}
}
Expand Down Expand Up @@ -117,7 +134,28 @@
"application/json": {
"schema": {
"type": "object",
"properties": {}
"properties": {
"index": {
"type": "string",
"format": "uri",
"contentMediaType": "text/html"
},
"level": {
"type": "number"
},
"optimal": {
"type": "boolean"
},
"query": {
"$ref": "#/components/schemas/IQuery"
}
},
"required": [
"index",
"level",
"optimal",
"query"
]
}
}
}
Expand Down Expand Up @@ -176,7 +214,28 @@
"application/json": {
"schema": {
"type": "object",
"properties": {}
"properties": {
"index": {
"type": "string",
"format": "uri",
"contentMediaType": "text/html"
},
"level": {
"type": "number"
},
"optimal": {
"type": "boolean"
},
"body": {
"$ref": "#/components/schemas/IBody"
}
},
"required": [
"index",
"level",
"optimal",
"body"
]
}
}
}
Expand Down Expand Up @@ -251,20 +310,44 @@
"schema": {
"type": "object",
"properties": {
"index": {
"type": "string",
"format": "uri",
"contentMediaType": "text/html"
},
"level": {
"type": "number"
},
"optimal": {
"type": "boolean"
},
"query": {
"type": "object",
"properties": {
"thumbnail": {
"type": "string",
"format": "uri",
"contentMediaType": "image/*"
},
"summary": {
"type": "string"
}
},
"required": [
"thumbnail",
"summary"
]
},
"body": {
"$ref": "#/components/schemas/IBody"
}
},
"required": [
"query"
"index",
"level",
"optimal",
"query",
"body"
]
}
}
Expand All @@ -275,7 +358,6 @@
},
"/{index}/{level}/{optimal}/multipart": {
"post": {
"deprecated": true,
"tags": [],
"parameters": [
{
Expand Down Expand Up @@ -341,6 +423,20 @@
"schema": {
"type": "object",
"properties": {
"index": {
"type": "string",
"format": "uri",
"contentMediaType": "text/html"
},
"level": {
"type": "number"
},
"optimal": {
"type": "boolean"
},
"query": {
"$ref": "#/components/schemas/IQuery"
},
"body": {
"type": "object",
"properties": {
Expand All @@ -366,6 +462,10 @@
}
},
"required": [
"index",
"level",
"optimal",
"query",
"body"
]
}
Expand All @@ -377,6 +477,7 @@
},
"/nothing": {
"get": {
"deprecated": true,
"tags": [],
"parameters": [],
"responses": {
Expand Down