From 47d5805844a4da9c2719cb9146bd2a252c035cdf Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 22:56:06 +0000 Subject: [PATCH 1/9] Refactor code formatting and update query description --- src/helper/gpt/tool/database/aiRepository.tool.js | 5 ++--- src/service/ai/ai.service.js | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/helper/gpt/tool/database/aiRepository.tool.js b/src/helper/gpt/tool/database/aiRepository.tool.js index 68bb2de..38da74a 100644 --- a/src/helper/gpt/tool/database/aiRepository.tool.js +++ b/src/helper/gpt/tool/database/aiRepository.tool.js @@ -14,7 +14,7 @@ const aiRepositoryTool = { query: { type: 'object', description: - 'The query parameters used for the operation. Structure depends on the transaction type, Required for update operations. Include subpropeties query.filter and query.update', + 'The query parameters used for the operation. Structure depends on the transaction type.', properties: { filter: { type: 'object', @@ -23,8 +23,7 @@ const aiRepositoryTool = { }, update: { type: 'object', - description: - 'Data to update. Required for update operations. Include subpropeties query.filter and query.update', + description: 'Data to update (required for update transactions).', }, }, required: ['filter'], diff --git a/src/service/ai/ai.service.js b/src/service/ai/ai.service.js index b986786..f0074f9 100644 --- a/src/service/ai/ai.service.js +++ b/src/service/ai/ai.service.js @@ -33,7 +33,7 @@ const aiService = async ({ message: 'Function not found', statusCode: 404, status: 'error', - }; // Retorna imediatamente + }; } else { functionResponse = await functions[name](JSON.parse(args)); console.log(functionResponse); @@ -44,18 +44,18 @@ const aiService = async ({ content: JSON.stringify(functionResponse), tool_call_id: gpt.tool_calls[0].id, }); - return null; // Retorna null se não houver erro + return null; } context.push(response); let retries = 0; while (!response.content && retries < 20) { - const toolErrorResponse = await callTool(response); // Captura a resposta da função + const toolErrorResponse = await callTool(response); + if (toolErrorResponse) { - return toolErrorResponse; // Se houve erro, retorna imediatamente + return toolErrorResponse; } - response = await gpt({ completion: context }); context.push(response); retries++; From 83e71fc39117697fc8435790f2be032ade40de49 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 22:56:13 +0000 Subject: [PATCH 2/9] Refactor swagger configuration and add user-related paths --- src/helper/swagger/path/user/user.swagger.js | 130 ++++++++++++++++ .../swagger/path/user/userNatural.swagger.js | 140 ++++++++++++++++++ src/helper/swagger/swagger.config.js | 17 ++- src/main.js | 4 +- 4 files changed, 282 insertions(+), 9 deletions(-) create mode 100644 src/helper/swagger/path/user/user.swagger.js create mode 100644 src/helper/swagger/path/user/userNatural.swagger.js diff --git a/src/helper/swagger/path/user/user.swagger.js b/src/helper/swagger/path/user/user.swagger.js new file mode 100644 index 0000000..23b326e --- /dev/null +++ b/src/helper/swagger/path/user/user.swagger.js @@ -0,0 +1,130 @@ +export default { + '/users': { + get: { + summary: 'Fetch All Users', + description: 'Retrieves a list of all users.', + tags: ['JSON'], + responses: { + 200: { + description: 'List of users retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + email: { + type: 'string', + }, + birthDate: { + type: 'string', + }, + mobile: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/user/name/{name}': { + get: { + summary: 'Fetch Specific User by Name', + description: 'Retrieves details of a specific user by their name.', + tags: ['JSON'], + parameters: [ + { + name: 'name', + in: 'path', + required: true, + description: 'Name of the user to retrieve', + schema: { + type: 'string', + }, + }, + ], + responses: { + 200: { + description: 'User details retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + }, + email: { + type: 'string', + }, + birthDate: { + type: 'string', + }, + mobile: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/user': { + post: { + summary: 'Create User', + description: 'Creates a new user by sending user details in JSON format.', + tags: ['JSON'], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + example: 'John Doe', + }, + email: { + type: 'string', + example: 'john.doe@example.com', + }, + password: { + type: 'string', + example: 'securepassword123', + }, + birthDate: { + type: 'string', + example: '1990-01-01', + }, + mobile: { + type: 'string', + example: '+1234567890', + }, + }, + required: ['name', 'email', 'password', 'birthDate', 'mobile'], + }, + }, + }, + }, + responses: { + 201: { + description: 'User created successfully', + }, + 400: { + description: 'Invalid input', + }, + }, + }, + }, +}; diff --git a/src/helper/swagger/path/user/userNatural.swagger.js b/src/helper/swagger/path/user/userNatural.swagger.js new file mode 100644 index 0000000..ee6b017 --- /dev/null +++ b/src/helper/swagger/path/user/userNatural.swagger.js @@ -0,0 +1,140 @@ +export default { + '/users/natural': { + post: { + summary: 'Fetch All Users via Natural Language', + description: + 'Retrieves a list of all users by interpreting natural language input.', + tags: ['Natural Language'], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + input: { + type: 'string', + example: 'Show me all users.', + }, + }, + required: ['input'], + }, + }, + }, + }, + responses: { + 200: { + description: 'List of users retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + email: { + type: 'string', + }, + birthDate: { + type: 'string', + }, + mobile: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/user/natural': { + post: { + summary: 'Fetch Specific User via Natural Language', + description: + 'Retrieves details of a specific user by interpreting natural language input.', + tags: ['Natural Language'], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + input: { + type: 'string', + example: 'Find the user named John Doe.', + }, + }, + required: ['input'], + }, + }, + }, + }, + responses: { + 200: { + description: 'User details retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + }, + email: { + type: 'string', + }, + birthDate: { + type: 'string', + }, + mobile: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/user/natural/create': { + post: { + summary: 'Create User via Natural Language', + description: 'Creates a new user by interpreting natural language input.', + tags: ['Natural Language'], + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + input: { + type: 'string', + example: + 'I want to create a user named John Doe, with email john.doe@example.com, password securepassword123, birth date 1990-01-01, and mobile +1234567890.', + }, + }, + required: ['input'], + }, + }, + }, + }, + responses: { + 201: { + description: 'User created successfully', + }, + 400: { + description: 'Invalid input', + }, + }, + }, + }, +}; diff --git a/src/helper/swagger/swagger.config.js b/src/helper/swagger/swagger.config.js index 225b27d..1652bd4 100644 --- a/src/helper/swagger/swagger.config.js +++ b/src/helper/swagger/swagger.config.js @@ -1,18 +1,22 @@ import swaggerJsDoc from 'swagger-jsdoc'; import swaggerUi from 'swagger-ui-express'; -import aiPath from './path/ai/ai.swagger.js'; - +import * as dotenv from 'dotenv'; +import userSwagger from './path/user/user.swagger.js'; +import userNaturalSwagger from './path/user/userNatural.swagger.js'; +dotenv.config(); const swaggerOptions = { swaggerDefinition: { openapi: '3.0.0', info: { - title: 'API Documentação', + title: 'GPT Integration API', version: '1.0.0', - description: 'Documentação da API usando Swagger', + description: `This API serves as a direct integration with GPT, showcasing the power of GPT combined with various tools and how it behaves in response to different requests. All routes described in this Swagger documentation are fictional. Every request sent to the API is processed by middleware that identifies the method used, the request body, and the headers. It then utilizes its tools to determine the appropriate actions to take with the request. + +Notably, the API is capable of handling both standard JSON calls and natural language inputs, such as “I want to create a user. My name is John Doe, my phone number is xxx-xxx-xxxx,” among others.`, }, servers: [ { - url: `http://localhost:${process.env.EXPRESS_PORT}`, + url: `http://${process.env.SWAGGER_URL}:${process.env.EXPRESS_PORT}`, }, ], }, @@ -23,7 +27,8 @@ const swaggerDocs = swaggerJsDoc(swaggerOptions); swaggerDocs.paths = { ...swaggerDocs.paths, - ...aiPath, + ...userSwagger, + ...userNaturalSwagger, }; const setupSwagger = app => { diff --git a/src/main.js b/src/main.js index cb9c890..ed195d7 100644 --- a/src/main.js +++ b/src/main.js @@ -14,12 +14,10 @@ const start = async () => { const app = express(); app.use(express.json()); + setupSwagger(app); app.use(asyncHandler(validateRequest)); app.use(asyncHandler(gptMiddleware)); app.use(errorHandler); - - setupSwagger(app); - app.listen(process.env.EXPRESS_PORT || 3000, () => { console.log(`Server running on port ${process.env.EXPRESS_PORT || 3000}`); }); From 363a96ff2b7f3b5475beaf9c25b8c416c738f661 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:10:17 +0000 Subject: [PATCH 3/9] Refactor swagger configuration and add product-related paths --- .../swagger/path/product/product.swagger.js | 187 ++++++++++++++++++ .../path/product/productNatural.swagger.js | 147 ++++++++++++++ .../swagger/path/user/userNatural.swagger.js | 101 +++++----- src/helper/swagger/swagger.config.js | 4 + 4 files changed, 388 insertions(+), 51 deletions(-) create mode 100644 src/helper/swagger/path/product/product.swagger.js create mode 100644 src/helper/swagger/path/product/productNatural.swagger.js diff --git a/src/helper/swagger/path/product/product.swagger.js b/src/helper/swagger/path/product/product.swagger.js new file mode 100644 index 0000000..cb6774c --- /dev/null +++ b/src/helper/swagger/path/product/product.swagger.js @@ -0,0 +1,187 @@ +export default { + '/products': { + get: { + summary: 'Fetch All Products', + description: + 'Retrieves a list of all products with optional filtering and pagination.', + tags: ['JSON'], // Tag para agrupar na seção JSON + parameters: [ + { + name: 'priceMin', + in: 'query', + description: 'Minimum price to filter products', + required: false, + schema: { + type: 'number', + }, + }, + { + name: 'priceMax', + in: 'query', + description: 'Maximum price to filter products', + required: false, + schema: { + type: 'number', + }, + }, + { + name: 'page', + in: 'query', + description: 'Page number for pagination', + required: false, + schema: { + type: 'integer', + example: 1, + }, + }, + { + name: 'limit', + in: 'query', + description: 'Number of products per page', + required: false, + schema: { + type: 'integer', + example: 10, + }, + }, + ], + responses: { + 200: { + description: 'List of products retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + total: { + type: 'integer', + description: 'Total number of products available', + }, + products: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + description: { + type: 'string', + }, + price: { + type: 'number', + }, + stock: { + type: 'number', + }, + category: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/product/name/{name}': { + get: { + summary: 'Fetch Specific Product by Name', + description: 'Retrieves details of a specific product by its name.', + tags: ['JSON'], // Tag para agrupar na seção JSON + parameters: [ + { + name: 'name', + in: 'path', + required: true, + description: 'Name of the product to retrieve', + schema: { + type: 'string', + }, + }, + ], + responses: { + 200: { + description: 'Product details retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + }, + description: { + type: 'string', + }, + price: { + type: 'number', + }, + stock: { + type: 'number', + }, + category: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/product': { + post: { + summary: 'Create Product', + description: + 'Creates a new product by sending product details in JSON format.', + tags: ['JSON'], // Tag para agrupar na seção JSON + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + example: 'Sample Product', + }, + description: { + type: 'string', + example: 'This is a sample product description.', + }, + price: { + type: 'number', + example: 29.99, + }, + stock: { + type: 'number', + example: 100, + }, + category: { + type: 'string', + example: 'Electronics', + }, + }, + required: ['name', 'description', 'price', 'category'], + }, + }, + }, + }, + responses: { + 201: { + description: 'Product created successfully', + }, + 400: { + description: 'Invalid input', + }, + }, + }, + }, +}; diff --git a/src/helper/swagger/path/product/productNatural.swagger.js b/src/helper/swagger/path/product/productNatural.swagger.js new file mode 100644 index 0000000..b180ee8 --- /dev/null +++ b/src/helper/swagger/path/product/productNatural.swagger.js @@ -0,0 +1,147 @@ +export default { + '/products/natural': { + get: { + summary: 'Fetch All Products via Natural Language', + description: + 'Retrieves a list of all products by interpreting natural language input with optional filters.', + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language + parameters: [ + { + name: 'input', + in: 'query', + required: true, + description: 'Natural language query to retrieve products', + schema: { + type: 'string', + example: + 'Show me all products priced between 10 and 50 and on page 2.', + }, + }, + ], + responses: { + 200: { + description: 'List of products retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + total: { + type: 'integer', + description: 'Total number of products available', + }, + products: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + description: { + type: 'string', + }, + price: { + type: 'number', + }, + stock: { + type: 'number', + }, + category: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/product/natural': { + get: { + summary: 'Fetch Specific Product via Natural Language', + description: + 'Retrieves details of a specific product by interpreting natural language input.', + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language + parameters: [ + { + name: 'input', + in: 'query', + required: true, + description: 'Natural language query to retrieve a specific product', + schema: { + type: 'string', + example: 'Find the product named Sample Product.', + }, + }, + ], + responses: { + 200: { + description: 'Product details retrieved successfully', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + name: { + type: 'string', + }, + description: { + type: 'string', + }, + price: { + type: 'number', + }, + stock: { + type: 'number', + }, + category: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, + }, + '/product/natural/create': { + post: { + summary: 'Create Product via Natural Language', + description: + 'Creates a new product by interpreting natural language input.', + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language + requestBody: { + required: true, + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + input: { + type: 'string', + example: + 'I want to create a product named Sample Product, with description "This is a sample product description.", price 29.99, stock 100, and category Electronics.', + }, + }, + required: ['input'], + }, + }, + }, + }, + responses: { + 201: { + description: 'Product created successfully', + }, + 400: { + description: 'Invalid input', + }, + }, + }, + }, +}; diff --git a/src/helper/swagger/path/user/userNatural.swagger.js b/src/helper/swagger/path/user/userNatural.swagger.js index ee6b017..0a1a3aa 100644 --- a/src/helper/swagger/path/user/userNatural.swagger.js +++ b/src/helper/swagger/path/user/userNatural.swagger.js @@ -1,48 +1,52 @@ export default { '/users/natural': { - post: { + get: { summary: 'Fetch All Users via Natural Language', description: - 'Retrieves a list of all users by interpreting natural language input.', - tags: ['Natural Language'], - requestBody: { - required: true, - content: { - 'application/json': { - schema: { - type: 'object', - properties: { - input: { - type: 'string', - example: 'Show me all users.', - }, - }, - required: ['input'], - }, + 'Retrieves a list of all users by interpreting natural language input with optional filters.', + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language + parameters: [ + { + name: 'input', + in: 'query', + required: true, + description: 'Natural language query to retrieve users', + schema: { + type: 'string', + example: 'Show me all users.', }, }, - }, + ], responses: { 200: { description: 'List of users retrieved successfully', content: { 'application/json': { schema: { - type: 'array', - items: { - type: 'object', - properties: { - name: { - type: 'string', - }, - email: { - type: 'string', - }, - birthDate: { - type: 'string', - }, - mobile: { - type: 'string', + type: 'object', + properties: { + total: { + type: 'integer', + description: 'Total number of users available', + }, + users: { + type: 'array', + items: { + type: 'object', + properties: { + name: { + type: 'string', + }, + email: { + type: 'string', + }, + birthDate: { + type: 'string', + }, + mobile: { + type: 'string', + }, + }, }, }, }, @@ -54,28 +58,23 @@ export default { }, }, '/user/natural': { - post: { + get: { summary: 'Fetch Specific User via Natural Language', description: 'Retrieves details of a specific user by interpreting natural language input.', - tags: ['Natural Language'], - requestBody: { - required: true, - content: { - 'application/json': { - schema: { - type: 'object', - properties: { - input: { - type: 'string', - example: 'Find the user named John Doe.', - }, - }, - required: ['input'], - }, + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language + parameters: [ + { + name: 'input', + in: 'query', + required: true, + description: 'Natural language query to retrieve a specific user', + schema: { + type: 'string', + example: 'Find the user named John Doe.', }, }, - }, + ], responses: { 200: { description: 'User details retrieved successfully', @@ -108,7 +107,7 @@ export default { post: { summary: 'Create User via Natural Language', description: 'Creates a new user by interpreting natural language input.', - tags: ['Natural Language'], + tags: ['Natural Language'], // Tag para agrupar na seção Natural Language requestBody: { required: true, content: { diff --git a/src/helper/swagger/swagger.config.js b/src/helper/swagger/swagger.config.js index 1652bd4..bf805e1 100644 --- a/src/helper/swagger/swagger.config.js +++ b/src/helper/swagger/swagger.config.js @@ -3,6 +3,8 @@ import swaggerUi from 'swagger-ui-express'; import * as dotenv from 'dotenv'; import userSwagger from './path/user/user.swagger.js'; import userNaturalSwagger from './path/user/userNatural.swagger.js'; +import productSwagger from './path/product/product.swagger.js'; +import productNaturalSwagger from './path/product/productNatural.swagger.js'; dotenv.config(); const swaggerOptions = { swaggerDefinition: { @@ -29,6 +31,8 @@ swaggerDocs.paths = { ...swaggerDocs.paths, ...userSwagger, ...userNaturalSwagger, + ...productSwagger, + ...productNaturalSwagger, }; const setupSwagger = app => { From 4fdce859794b97969e519ab1c0e32c24ee2950ce Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:20:42 +0000 Subject: [PATCH 4/9] Add docker-compose.yml for development environment setup --- docker-compose.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d08829e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3.8' + +services: + app: + image: node:20.17.0 + container_name: apigpt + working_dir: /usr/src/app + volumes: + - .:/usr/src/app + ports: + - "${EXPRESS_PORT}:${EXPRESS_PORT}" + command: npm run dev + env_file: + - .env + +# mongo: +# image: mongo:latest +# container_name: mongo +# ports: +# - "27017:27017" +# volumes: +# - mongo_data:/data/db + +# volumes: +# mongo_data: From 64f7ea8d4371d597d616d370401be80f15f31361 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:28:44 +0000 Subject: [PATCH 5/9] Refactor swagger configuration to use environment variable for URL --- src/helper/swagger/swagger.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helper/swagger/swagger.config.js b/src/helper/swagger/swagger.config.js index bf805e1..2361bc3 100644 --- a/src/helper/swagger/swagger.config.js +++ b/src/helper/swagger/swagger.config.js @@ -18,7 +18,7 @@ Notably, the API is capable of handling both standard JSON calls and natural lan }, servers: [ { - url: `http://${process.env.SWAGGER_URL}:${process.env.EXPRESS_PORT}`, + url: process.env.SWAGGER_URL, }, ], }, From 64aba22ef9ab8f58f075ea988f7aa9946991c3f0 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:32:01 +0000 Subject: [PATCH 6/9] Refactor AI service to handle error response in case of empty function response --- src/service/ai/ai.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/ai/ai.service.js b/src/service/ai/ai.service.js index f0074f9..7acbf53 100644 --- a/src/service/ai/ai.service.js +++ b/src/service/ai/ai.service.js @@ -41,7 +41,7 @@ const aiService = async ({ context.push({ role: 'tool', - content: JSON.stringify(functionResponse), + content: JSON.stringify(functionResponse) || 'Return error', tool_call_id: gpt.tool_calls[0].id, }); return null; From 637639105fa040cf24bd5de70c2b9beb5f100918 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:42:00 +0000 Subject: [PATCH 7/9] Refactor AI service to handle error response in case of empty function response and improve tool call handling --- src/service/ai/ai.service.js | 45 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/service/ai/ai.service.js b/src/service/ai/ai.service.js index 7acbf53..00fb76a 100644 --- a/src/service/ai/ai.service.js +++ b/src/service/ai/ai.service.js @@ -25,42 +25,41 @@ const aiService = async ({ let response = await gpt({ completion: context }); async function callTool(gpt) { - const { name, arguments: args } = gpt.tool_calls[0].function; - let functionResponse; + for (const toolCall of gpt.tool_calls) { + const { name, arguments: args } = toolCall.function; + let functionResponse; - if (!functions[name]) { - return { - message: 'Function not found', - statusCode: 404, - status: 'error', - }; - } else { - functionResponse = await functions[name](JSON.parse(args)); - console.log(functionResponse); - } + if (!functions[name]) { + return { + message: 'Function not found', + statusCode: 404, + status: 'error', + }; + } else { + functionResponse = await functions[name](JSON.parse(args)); + console.log(functionResponse); + } - context.push({ - role: 'tool', - content: JSON.stringify(functionResponse) || 'Return error', - tool_call_id: gpt.tool_calls[0].id, - }); - return null; + context.push({ + role: 'tool', + content: JSON.stringify(functionResponse) || 'Return error', + tool_call_id: toolCall.id, + }); + } } context.push(response); let retries = 0; while (!response.content && retries < 20) { - const toolErrorResponse = await callTool(response); + console.log(context); + await callTool(response); - if (toolErrorResponse) { - return toolErrorResponse; - } response = await gpt({ completion: context }); context.push(response); retries++; } - + console.log(context); return response; } catch (err) { return err.message; From c6eb9c4fb9841b0ceaad949a95583d3e75378020 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Mon, 30 Sep 2024 23:45:38 +0000 Subject: [PATCH 8/9] Refactor swagger configuration and update productNatural.swagger.js --- src/helper/swagger/path/product/productNatural.swagger.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/helper/swagger/path/product/productNatural.swagger.js b/src/helper/swagger/path/product/productNatural.swagger.js index b180ee8..4d6bd94 100644 --- a/src/helper/swagger/path/product/productNatural.swagger.js +++ b/src/helper/swagger/path/product/productNatural.swagger.js @@ -7,14 +7,13 @@ export default { tags: ['Natural Language'], // Tag para agrupar na seção Natural Language parameters: [ { - name: 'input', + name: 'prompt', in: 'query', required: true, description: 'Natural language query to retrieve products', schema: { type: 'string', - example: - 'Show me all products priced between 10 and 50 and on page 2.', + example: 'Show me all products priced between 10 and 50', }, }, ], @@ -69,7 +68,7 @@ export default { tags: ['Natural Language'], // Tag para agrupar na seção Natural Language parameters: [ { - name: 'input', + name: 'prompt', in: 'query', required: true, description: 'Natural language query to retrieve a specific product', From b322b2cc4c47be0578b4ce7fd7aad5c521e594d8 Mon Sep 17 00:00:00 2001 From: Thadeu Castelo Branco Ramos Date: Tue, 1 Oct 2024 00:00:32 +0000 Subject: [PATCH 9/9] Refactor swagger configuration and update AI endpoint description --- src/helper/swagger/path/ai/ai.swagger.js | 39 +++++++++++++++++++----- src/helper/swagger/swagger.config.js | 2 ++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/helper/swagger/path/ai/ai.swagger.js b/src/helper/swagger/path/ai/ai.swagger.js index 0e9e538..6eb908f 100644 --- a/src/helper/swagger/path/ai/ai.swagger.js +++ b/src/helper/swagger/path/ai/ai.swagger.js @@ -1,8 +1,14 @@ export default { '/ai': { post: { - summary: 'Processa a requisição AI', - description: 'Envia uma requisição para o serviço AI.', + summary: 'Interact with AI for API Commands', + description: + 'This endpoint allows users to send natural language commands to the API. You can use this to perform various actions such as creating users, fetching products, or retrieving information. Here are some examples of how to structure your commands:\n' + + '- "Create a user named John Doe with email john.doe@example.com."\n' + + '- "Find all products under $50."\n' + + '- "Show me details of the user named Jane Smith."\n' + + '- "List all users."', + tags: ['AI Command Interface'], requestBody: { required: true, content: { @@ -10,20 +16,37 @@ export default { schema: { type: 'object', properties: { - body: { - type: 'object', - }, - header: { - type: 'object', + prompt: { + type: 'string', + example: + 'Create a product named Sample Product with description "This is a sample product." and price 19.99.', }, }, + required: ['prompt'], }, }, }, }, responses: { 200: { - description: 'Resposta bem-sucedida', + description: 'Response from the API based on the provided command', + content: { + 'application/json': { + schema: { + type: 'object', + properties: { + response: { + type: 'string', + description: + 'The result of the command interpreted and executed by the API.', + }, + }, + }, + }, + }, + }, + 400: { + description: 'Invalid command, please check your input.', }, }, }, diff --git a/src/helper/swagger/swagger.config.js b/src/helper/swagger/swagger.config.js index 2361bc3..f3d7492 100644 --- a/src/helper/swagger/swagger.config.js +++ b/src/helper/swagger/swagger.config.js @@ -5,6 +5,7 @@ import userSwagger from './path/user/user.swagger.js'; import userNaturalSwagger from './path/user/userNatural.swagger.js'; import productSwagger from './path/product/product.swagger.js'; import productNaturalSwagger from './path/product/productNatural.swagger.js'; +import aiSwagger from './path/ai/ai.swagger.js'; dotenv.config(); const swaggerOptions = { swaggerDefinition: { @@ -33,6 +34,7 @@ swaggerDocs.paths = { ...userNaturalSwagger, ...productSwagger, ...productNaturalSwagger, + ...aiSwagger, }; const setupSwagger = app => {