f16baefc by Ryan

Merge branch '26919_chatscreen' into 'master'

26919 chatscreen

See merge request !22
2 parents d0bd0a2e 648de563
......@@ -208,4 +208,88 @@
}
.submit:hover {
background:#066d55;
}
\ No newline at end of file
}
.suggested {
display: block;
z-index: 99999999;
color: #000;
position: absolute;
text-align: center;
padding: 25px;
top: 0;
right: 0;
bottom: 89px;
left: 0;
overflow-y: scroll;
}
.suggestedcol {
width: 30%;
display: inline-block;
margin: 0;
text-align: center;
vertical-align: top;
}
.suggestedcol ul {
list-style: none;
padding: 0 25px;
}
.suggestedrow.title {
padding: 100px 20px;
}
.suggestedcol ul li {
background: #5c6aa529;
padding: 10px;
border-radius: 5px;
margin: 10px 0;
margin-top: 10px;
margin-right: 0px;
margin-bottom: 10px;
margin-left: 0px;
}
ul.suggested-options {
cursor: pointer;
}
@media (max-width: 991px) {
.suggestedcol {
width: 100%;
}
.suggestedrow.title {
padding: 10px 10px 0 10px;
}
}
.message .error_msg {
background: rgb(18 0 255 / 20%);
padding: 10px;
border-radius: 5px;
display: flex;
}
.message .error_msg span {
background: #0023ff;
width: 25px;
height: 25px;
display: inline-block;
text-align: center;
padding-top: 1px;
border-radius: 50px;
font-family: auto;
font-weight: 600;
vertical-align: top;
}
.message .error_msg .msg {
display: inline-block;
margin: 0 10px;
font-style: italic;
width: 80%;
}
......
......@@ -23,6 +23,8 @@ function App() {
// clear chats
function clearChat(){
setChatLog([]);
setChatInput("");
setStartedInteraction(false);
}
function getEngines(){
......@@ -43,11 +45,11 @@ function App() {
async function handleSubmit(e){
e.preventDefault();
// console.log(chatInput)
const userInput = ['what', 'why', 'when', 'where' , 'which', 'did', 'do', 'how', 'can', 'are', 'who', 'hey'];
const userInput = ['what', 'why', 'when', 'where' , 'which', 'did', 'do', 'how', 'can', 'are', 'who'];
const userInputRegex = new RegExp(`\\b(${userInput.join('|')})\\b`, 'gi');
const inputMatches = chatInput.match(userInputRegex);
const userPunctuation = ['\.', '?', '!', ':', ';', ','];
const userPunctuation = ['.', '?', '!', ':', ';', ','];
const userPunctuationRegex = new RegExp(`[${userPunctuation.join('')}]$`);
const punctuationMatches = chatInput.match(userPunctuationRegex);
......@@ -71,34 +73,36 @@ function App() {
// fetch response to the api combining the chat log array of messages and seinding it as a message to localhost:3000 as a post
const messages = chatLogNew.map((message) => message.message).join("\n")
const response = await fetch(process.env.REACT_APP_SERVER_URL + "/api", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
message: messages,
currentModel,
})
try {
const response = await fetch(process.env.REACT_APP_SERVER_URL + "/api", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
message: messages,
currentModel,
})
});
const data = await response.json();
const parsedData = data.message.trim();
const programmingKeywords = ['code', 'application', 'controller', 'rails' , 'PHP', 'java', 'javascript', 'script', 'console', 'python', 'programming', 'table'];
const regex = new RegExp(`\\b(${programmingKeywords.join('|')})\\b`, 'gi');
// console.log(regex)
const matches = parsedData.match(regex);
// console.log(matches);
if (!matches) {
var replaceTags = (parsedData.replace(/(?:\r\n|\r|\n)/g, '<br>').replace(/\./g, '. '))
// console.log("not programming!")
} else {
replaceTags = (parsedData.replace(':',':<code>').replace('<?','&#60;?').replace('?>','?&#62;').replace(/\n/g, '<br>'))
// console.log("programming!")
const data = await response.json();
const parsedData = data.message.trim();
const programmingKeywords = ['code', 'application', 'controller', 'rails' , 'PHP', 'java', 'javascript', 'script', 'console', 'python', 'programming', 'table'];
const regex = new RegExp(`\\b(${programmingKeywords.join('|')})\\b`, 'gi');
const matches = parsedData.match(regex);
if (!matches) {
var replaceTags = (parsedData.replace(/(?:\r\n|\r|\n)/g, '<br>').replace(/\./g, '. '))
} else {
replaceTags = (parsedData.replace(':',':<code>').replace('<?','&#60;?').replace('?>','?&#62;').replace(/\n/g, '<br>'))
}
setChatLog([...chatLogNew, { user: "gpt", message: `${replaceTags}`} ])
var scrollToTheBottomChatLog = document.getElementsByClassName("chat-log")[0];
scrollToTheBottomChatLog.scrollTop = scrollToTheBottomChatLog.scrollHeight;
} catch (error) {
const errorMsg = "We apologize for any inconvenience caused due to the delay in the response time. Please try again.";
setChatLog([...chatLogNew, { user: "gpt", message: `<div class="errormsg"><span>i</span><div class="msg">${errorMsg}</div></div>`} ])
}
setChatLog([...chatLogNew, { user: "gpt", message: `${replaceTags}`} ])
var scrollToTheBottomChatLog = document.getElementsByClassName("chat-log")[0];
scrollToTheBottomChatLog.scrollTop = scrollToTheBottomChatLog.scrollHeight;
}
function handleTemp(temp) {
......@@ -111,7 +115,7 @@ function App() {
}
}
const [startedInteraction, setStartedInteraction] = useState(false);
return (
<div className="App">
<SideMenu
......@@ -122,10 +126,13 @@ function App() {
temperature={temperature}
clearChat={clearChat}
/>
<ChatBox
chatInput={chatInput}
chatLog={chatLog}
setChatInput={setChatInput}
startedInteraction={startedInteraction}
setStartedInteraction={setStartedInteraction}
handleSubmit={handleSubmit} />
</div>
);
......
// import OpenAISVGLogo from './OpenAISVGLogo'
import React, { useState } from "react";
import SuggestedOptions from './suggestedOptions'
// Primary Chat Window
const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput}) =>
<section className="chatbox">
<div className="chat-log">
{chatLog.map((message, index) => (
<ChatMessage key={index} message={message} />
))}
</div>
<div className="chat-input-holder">
<form className="form" onSubmit={handleSubmit}>
<input
rows="1"
value={chatInput}
onChange={(e)=> setChatInput(e.target.value)}
className="chat-input-textarea" ></input>
<button className="submit" type="submit">Submit</button>
</form>
const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInteraction, setStartedInteraction}) => {
return (
<section className="chatbox">
{!startedInteraction ? (
<SuggestedOptions setChatInput={setChatInput}/>
) : (
<>
<div className="chat-log">
{chatLog.map((message, index) => (
<ChatMessage key={index} message={message} />
))}
</div>
</section>
// Individual Chat Message
</>
)}
<div className="chat-input-holder">
<form className="form" onSubmit={handleSubmit }>
<input
rows="1"
value={chatInput}
onChange={(e)=> {
setChatInput(e.target.value);
}}
className="chat-input-textarea" >
</input>
<button className="submit" type="submit" onClick={(e)=> {
setStartedInteraction(true);
}}>Submit</button>
</form>
</div>
</section>
)
}
const ChatMessage = ({ message }) => {
return (
<div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}>
......
......@@ -2,6 +2,32 @@
background-color: #101827 !important;
}
.errormsg {
border: 1px solid #7ac5ff;
padding: 15px 25px;
border-radius: 10px;
background: rgb(0 139 245 / 6%);
}
.errormsg .msg {
display: inline-block;
width: 90%;
}
.errormsg span {
background: #008BF5;
padding: 1px 11px;
border-radius: 50px;
width: 25px;
height: 25px;
margin-right: 10px;
color: #fff;
font-weight: 900;
display: inline-block;
vertical-align: top;
font-family: auto;
font-size: 15px;
}
.side-menu-button {
border:0 solid white;
/* Permalink - use to edit and share this gradient: https://colorzilla.com/gradient-editor/#cedbe9+0,aac5de+17,6199c7+50,3a84c3+51,419ad6+59,4bb8f0+71,3a8bc2+84,26558b+100;Blue+Gloss */
......@@ -172,9 +198,16 @@ code br:nth-child(-n+2) {
}
@media (max-width: 414px) {
.errormsg .msg {
width: 80%;
}
.message {
font-size: 14px;
}
.errormsg {
padding: 10px;
width: 100%;
}
.chat-message-center {
padding: 20px 5vw !important;
}
......
const SuggestedOptions = ({ setChatInput }) => {
const examples = ["Write an email requesting a 3-day vacation leave to my manager.", "Compose a song about nationalism and love for the country.", "Give me 3 easy-to-cook food recipes that I can prepare for a date night at home."];
const handleExampleClick = (example) => {
setChatInput(example);
};
return (
<div className="suggested">
<div className="suggestedrow title">
<h1>Welcome to AI-PRO</h1>
<p>This chatbot is capable of answering questions and generating text based on the input you provide.</p>
</div>
<div className="suggestedcol rack1">
<h2>Examples</h2>
<ul className="suggested-options">
{examples.map((example, index) => (
<li key={index}
onClick={() => handleExampleClick(example)}>
{example}
</li>
))}
</ul>
</div>
<div className="suggestedcol rack2">
<h2>Capabilities</h2>
<ul>
<li>Remembers the user's earlier statement in the ongoing discussion.</li>
<li>Allows the user to add more information or correct errors.</li>
<li>Trained to deny requests that are not appropriate.</li>
</ul>
</div>
<div className="suggestedcol rack3">
<h2>Limitations</h2>
<ul>
<li>May sometimes give wrong or incorrect information.</li>
<li>May at times produce harmful instructions or biased content.</li>
<li>Limited knowledge of what's been happening in the world since 2021.</li>
</ul>
</div>
</div>
);
};
export default SuggestedOptions;
\ No newline at end of file
......@@ -3,6 +3,7 @@ const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
require('dotenv').config()
const rateLimit = require('express-rate-limit')
// Open AI Configuration
// console.log(process.env.OPENAI_API_ORG)
......@@ -12,6 +13,12 @@ const configuration = new Configuration({
});
const openai = new OpenAIApi(configuration);
const rateLimiter = rateLimit({
windowMs: 1000 * 60 * 1, // 1 minute (refreshTime)
max: 3000, // limit each IP to x requests per windowMs (refreshTime)
message: 'Sorry, too many requests. Please try again in a bit!',
});
// Express Configuration
const app = express()
const port = 3080
......@@ -19,20 +26,31 @@ const port = 3080
app.use(bodyParser.json())
app.use(cors())
app.use(require('morgan')('dev'))
app.use(rateLimiter)
// Routing
// Primary Open AI Route
app.post('/api', async (req, res) => {
const { message, currentModel, temperature } = req.body;
let greetingPrompt = 'Hello, how can I assist you?'
const greetings = ['hi', 'hello', 'hey']
if (greetings.some((greeting) => message.toLowerCase().includes(greeting))) {
greetingPrompt = 'Hello, how can I help you today?'
}
const prompt = `${greetingPrompt}\n${message}`;
const response = await openai.createCompletion({
model: `${currentModel}`,// "text-davinci-003",
prompt: `${message}`,
prompt,
max_tokens: 2500,
temperature,
});
res.json({
message: response.data.choices[0].text,
})
......
......@@ -13,6 +13,7 @@
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-rate-limit": "^6.7.0",
"morgan": "^1.10.0",
"openai": "^3.1.0"
}
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!