diff --git a/frontend/src/MarkdownRenderer.js b/frontend/src/MarkdownRenderer.js new file mode 100644 index 0000000..1875992 --- /dev/null +++ b/frontend/src/MarkdownRenderer.js @@ -0,0 +1,35 @@ +// MarkdownRenderer.js +import React from "react"; +import ReactMarkdown from "react-markdown"; +import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; +import { vscDarkPlus } from "react-syntax-highlighter/dist/esm/styles/prism"; + +const MarkdownRenderer = ({ content }) => { + return ( + + {String(children).replace(/\n$/, "")} + + ) : ( + + {children} + + ); + }, + }} + > + {content} + + ); +}; + +export default MarkdownRenderer; diff --git a/frontend/src/interface.js b/frontend/src/interface.js index a2c2594..7777544 100644 --- a/frontend/src/interface.js +++ b/frontend/src/interface.js @@ -1,148 +1,158 @@ +import ReactDOM from "react-dom"; +import MarkdownRenderer from "./MarkdownRenderer"; // Download a codebase export async function downloadCodebase() { - const ec2 = 'http://18.226.98.245:80'; - const local = 'http://localhost:3000'; - const apiURL = 'https://syntaxsorcerer-backend.fly.dev' - const url = document.getElementById('codebase-url').value; - - const response = await fetch(`${local}/api/download`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ url }) - }); - - const result = await response.json(); - if (result.error) { - alert(result.error); - } else { - alert('Codebase downloaded and cached'); - } + const ec2 = "http://18.226.98.245:80"; + const local = "http://localhost:3000"; + const apiURL = "https://syntaxsorcerer-backend.fly.dev"; + const url = document.getElementById("codebase-url").value; + + const response = await fetch(`${local}/api/download`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ url }), + }); + + const result = await response.json(); + if (result.error) { + alert(result.error); + } else { + alert("Codebase downloaded and cached"); + } } // Delete the existing codebase export async function deleteCodebase() { - const ec2 = 'http://18.226.98.245:80'; - const local = 'http://localhost:3000'; - const apiURL = 'https://syntaxsorcerer-backend.fly.dev' - - const response = await fetch(`${local}/api/delete`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ value: "Clicked" }) - }); - - const result = await response.json(); - if (result.error) { - alert(result.error); - } else { - alert('Codebase successfully deleted'); - } + const ec2 = "http://18.226.98.245:80"; + const local = "http://localhost:3000"; + const apiURL = "https://syntaxsorcerer-backend.fly.dev"; + + const response = await fetch(`${local}/api/delete`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ value: "Clicked" }), + }); + + const result = await response.json(); + if (result.error) { + alert(result.error); + } else { + alert("Codebase successfully deleted"); + } } // Send a message to the ChatGPT API export async function sendMessage() { - const userInput = document.getElementById('user-input').value; - if (userInput.trim() === '') return; + const userInput = document.getElementById("user-input").value; + if (userInput.trim() === "") return; - appendMessage('You', userInput); - document.getElementById('user-input').value = ''; + appendMessage("You", userInput); + document.getElementById("user-input").value = ""; - const sendButton = document.getElementById('send-button'); - const queryButton = document.getElementById('query-button'); - queryButton.disabled = true; - sendButton.disabled = true; + const sendButton = document.getElementById("send-button"); + const queryButton = document.getElementById("query-button"); + queryButton.disabled = true; + sendButton.disabled = true; - await fetchChatGPTResponse(userInput); + await fetchChatGPTResponse(userInput); - sendButton.disabled = false; - queryButton.disabled = false; + sendButton.disabled = false; + queryButton.disabled = false; } // Create a query from the user input that will be used to find the most relevant files export async function sendCodebaseQuery() { - const userInput = document.getElementById('user-input').value; - if (userInput.trim() === '') return; + const userInput = document.getElementById("user-input").value; + if (userInput.trim() === "") return; - appendMessage('You', userInput); - document.getElementById('user-input').value = ''; + appendMessage("You", userInput); + document.getElementById("user-input").value = ""; - const sendButton = document.getElementById('send-button'); - const queryButton = document.getElementById('query-button'); - queryButton.disabled = true; - sendButton.disabled = true; + const sendButton = document.getElementById("send-button"); + const queryButton = document.getElementById("query-button"); + queryButton.disabled = true; + sendButton.disabled = true; - await fetchPineconeResponse(userInput); + await fetchPineconeResponse(userInput); - sendButton.disabled = false; - queryButton.disabled = false; + sendButton.disabled = false; + queryButton.disabled = false; } // Display a message on the frontend export function appendMessage(sender, message) { - const messagesDiv = document.getElementById('messages'); - const messageElement = document.createElement('div'); - messageElement.classList.add('message'); + const messagesDiv = document.getElementById("messages"); + const messageElement = document.createElement("div"); + messageElement.classList.add("message"); - const senderElement = document.createElement('div'); - senderElement.classList.add('sender'); - senderElement.textContent = sender.toUpperCase(); + const senderElement = document.createElement("div"); + senderElement.classList.add("sender"); + senderElement.textContent = sender.toUpperCase(); - const contentElement = document.createElement('div'); - contentElement.classList.add('content'); - contentElement.textContent = message; + const contentElement = document.createElement("div"); + contentElement.classList.add("content"); - messageElement.appendChild(senderElement); - messageElement.appendChild(contentElement); - messagesDiv.appendChild(messageElement); + // Render the message using the MarkdownRenderer component + contentElement.innerHTML = `
`; - messagesDiv.scrollTop = messagesDiv.scrollHeight; + messageElement.appendChild(senderElement); + messageElement.appendChild(contentElement); + messagesDiv.appendChild(messageElement); + + // Using React to render MarkdownRenderer into the div + ReactDOM.render( + , + document.getElementById("markdown-content"), + ); + + messagesDiv.scrollTop = messagesDiv.scrollHeight; } // Fetch a response from the ChatGPT API export async function fetchChatGPTResponse(userInput) { - const ec2 = 'https://18.226.98.245:443'; - const local = 'http://localhost:3000'; - const apiURL = 'https://syntaxsorcerer-backend.fly.dev' - const codebasePath = '../../codebases'; - - const response = await fetch(`${local}/api/chatgpt`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ prompt: userInput, codebasePath}) - }); - - const botMessage = await response.json(); - if (botMessage.error) { - appendMessage('Error', botMessage.error); - } else { - appendMessage('Assistant', botMessage.text); - } + const ec2 = "https://18.226.98.245:443"; + const local = "http://localhost:3000"; + const apiURL = "https://syntaxsorcerer-backend.fly.dev"; + const codebasePath = "../../codebases"; + + const response = await fetch(`${local}/api/chatgpt`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ prompt: userInput, codebasePath }), + }); + + const botMessage = await response.json(); + if (botMessage.error) { + appendMessage("Error", botMessage.error); + } else { + appendMessage("Assistant", botMessage.text); + } } // Fetch a response from the Pinecone API, generate an embedding from the user input export async function fetchPineconeResponse(userInput) { - const ec2 = 'https://18.226.98.245:443'; - const local = 'http://localhost:3000'; - const apiURL = 'https://syntaxsorcerer-backend.fly.dev' - - const response = await fetch(`${local}/api/pinecone`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({ prompt: userInput }) - }); - - const botMessage = await response.json(); - if (botMessage.error) { - appendMessage('Error', botMessage.error); - } else { - appendMessage('Assistant', botMessage.text); - } -} \ No newline at end of file + const ec2 = "https://18.226.98.245:443"; + const local = "http://localhost:3000"; + const apiURL = "https://syntaxsorcerer-backend.fly.dev"; + + const response = await fetch(`${local}/api/pinecone`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ prompt: userInput }), + }); + + const botMessage = await response.json(); + if (botMessage.error) { + appendMessage("Error", botMessage.error); + } else { + appendMessage("Assistant", botMessage.text); + } +}