diff --git a/frontend/src/components/WorkspaceChat/index.jsx b/frontend/src/components/WorkspaceChat/index.jsx index d2d81c72..38c4dbde 100644 --- a/frontend/src/components/WorkspaceChat/index.jsx +++ b/frontend/src/components/WorkspaceChat/index.jsx @@ -5,6 +5,7 @@ import ChatContainer from "./ChatContainer"; import paths from "@/utils/paths"; import ModalWrapper from "../ModalWrapper"; import { useParams } from "react-router-dom"; +import { extractMetaData } from "@/utils/chat/extractMetaData"; export default function WorkspaceChat({ loading, workspace }) { const { threadSlug = null } = useParams(); diff --git a/frontend/src/utils/chat/extractMetaData.js b/frontend/src/utils/chat/extractMetaData.js new file mode 100644 index 00000000..2b7849f5 --- /dev/null +++ b/frontend/src/utils/chat/extractMetaData.js @@ -0,0 +1,53 @@ +/** + * Extracts JSON objects and arrays from a text response from OpenAI API call and returns the remaining text with the extracted JSON strings removed. + * @param {String} textResponse The text response from OpenAI API call + * @returns {Object} { remainingText, meta: extractedObjects } remainingText is the textResponse with the extracted JSON strings removed, and meta is an array of the extracted JSON objects/arrays + */ + +export const extractMetaData = (textResponse) => { + let remainingText = textResponse; + let inString = false; + let char, prevChar; + let braceCount = 0; + let bracketCount = 0; + let startIndex = null; + let extractedObjects = {}; // Keep as an object as requested + + for (let i = 0; i < textResponse.length; i++) { + char = textResponse[i]; + if (char === '"' && prevChar !== '\\') inString = !inString; + if (inString) continue; + + if (char === '{' || char === '[') { + if (braceCount === 0 && bracketCount === 0) startIndex = i; + if (char === '{') braceCount++; + if (char === '[') bracketCount++; + } else if (char === '}' || char === ']') { + if (char === '}') braceCount--; + if (char === ']') bracketCount--; + + if (braceCount === 0 && bracketCount === 0 && startIndex !== null) { + let json = textResponse.substring(startIndex, i + 1); + + try { + let parsedJson = JSON.parse(json); + for (let key in parsedJson) { + if (parsedJson.hasOwnProperty(key)) { + extractedObjects[key] = parsedJson[key]; + } + } + } catch (error) { + console.error("Error parsing JSON:", error, 'in JSON:', json); + } + startIndex = null; + } + } + prevChar = char; + } + + // Remove any json objects from the text tat starts with ```json nad ends with ``` + const jsonRegex = /```json[\s\S]*?```/g; + remainingText = remainingText.replace(jsonRegex, ''); + + return { remainingText, metaData: extractedObjects }; +} \ No newline at end of file