import OpenAI from "openai"; import fsp from "fs/promises"; import { PdfReader } from "pdfreader"; const openaiClient = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, }); async function queryChatGPT(prompt: string) { let res = await openaiClient.chat.completions.create({ model: "gpt-4o", messages: [ { role: "system", content: prompt, }, ], response_format: { type: "json_object" }, }); return JSON.parse(res.choices[0].message.content); } async function parseBufferAsync(buffer: Buffer): Promise { let parsedData = ""; return new Promise((resolve, reject) => { new PdfReader().parseBuffer(buffer, (error, item) => { if (error) return reject(error); if (!item) return resolve(parsedData); if (item.text) parsedData += item.text; }); }); } export default async function generateNote( folderPath: string ): Promise { let energyData = {}; let checklistData = {}; let energyDataFlag = false; let checklistDataFlag = false; let energyFilePath = ""; let checklistFilePath = ""; const files = await fsp.readdir(folderPath); for (const file of files) { const input = await fsp.readFile(folderPath + `/${file}`); const pdfData = await parseBufferAsync(input); if ( Object.keys(checklistData).length == 0 && pdfData.toLowerCase().includes("general contractors") ) { const prompt = ` Extract the following fields and contractor info from the given data and return the response in JSON. Fields: ["Site Address", "Lot Number", "Estimated Construction Cost", "Total Square Footage", "A/C Square Footage", "Number of Bedrooms", "Number of Bathrooms", "Construction Type", "Number of Stories", "Height", "General Contractors License", "Mechanical Contractors License", "Electrical Contractors License", "Plumbing Contractors License", "Roofing Contractors License", "Concrete/Mason Contractors License", "Confirm the following"] Data: ${pdfData} `; checklistDataFlag = true; checklistFilePath = file; checklistData = await queryChatGPT(prompt); } if ( Object.keys(energyData).length == 0 && pdfData.toLowerCase().includes("energy efficiency") ) { const prompt = ` Extract the following fields form the given data and return the response in JSON. Fields: [Project Name, address, county] Data: ${pdfData} `; energyDataFlag = true; energyFilePath = file; energyData = await queryChatGPT(prompt); } } const addressCheck = {}; if (checklistDataFlag && Object.keys(checklistData).length > 0) { for (const file of files) { if (file == checklistFilePath) continue; const input = await fsp.readFile(folderPath + `${file}`); const pdfData = await parseBufferAsync(input); const prompt = ` Check if the address in the data given below matches this ${checklistData["Site Address"]}. Return the response in JSON with schema {match: Boolean}. Data: ${pdfData} `; const { match } = await queryChatGPT(prompt); addressCheck[file] = match; } } let note = ""; if (!energyDataFlag) { note += "Energy Efficiency document not found.\n"; } if (!checklistDataFlag) { note += `Checklist document not found.\n\n`; } let filesList = ""; for (const file in addressCheck) { if (!addressCheck[file]) { filesList += file.split("/").pop() + "\n"; } } if (filesList != "") { note += "Below files don't have address or the address doesn't match with the address in checklist\n\n"; note += filesList; note += "\n"; } if (energyDataFlag || checklistDataFlag) { note += "\nExtracted Data:\n"; } if (Object.keys(energyData).length > 0) { note += `\n${JSON.stringify(energyData, null, 2)}\n`; } if (Object.keys(checklistData).length > 0) { note += `\n${JSON.stringify(checklistData, null, 2)}\n`; } return note; }