f16baefc by Ryan

Merge branch '26919_chatscreen' into 'master'

26919 chatscreen

See merge request !22
2 parents d0bd0a2e 648de563
...@@ -209,3 +209,87 @@ ...@@ -209,3 +209,87 @@
209 .submit:hover { 209 .submit:hover {
210 background:#066d55; 210 background:#066d55;
211 } 211 }
212
213 .suggested {
214 display: block;
215 z-index: 99999999;
216 color: #000;
217 position: absolute;
218 text-align: center;
219 padding: 25px;
220
221 top: 0;
222 right: 0;
223 bottom: 89px;
224 left: 0;
225 overflow-y: scroll;
226 }
227
228 .suggestedcol {
229 width: 30%;
230 display: inline-block;
231 margin: 0;
232 text-align: center;
233 vertical-align: top;
234 }
235
236 .suggestedcol ul {
237 list-style: none;
238 padding: 0 25px;
239 }
240
241 .suggestedrow.title {
242 padding: 100px 20px;
243 }
244
245 .suggestedcol ul li {
246 background: #5c6aa529;
247 padding: 10px;
248 border-radius: 5px;
249 margin: 10px 0;
250 margin-top: 10px;
251 margin-right: 0px;
252 margin-bottom: 10px;
253 margin-left: 0px;
254 }
255
256 ul.suggested-options {
257 cursor: pointer;
258 }
259
260
261 @media (max-width: 991px) {
262 .suggestedcol {
263 width: 100%;
264 }
265 .suggestedrow.title {
266 padding: 10px 10px 0 10px;
267 }
268 }
269
270 .message .error_msg {
271 background: rgb(18 0 255 / 20%);
272 padding: 10px;
273 border-radius: 5px;
274 display: flex;
275 }
276
277 .message .error_msg span {
278 background: #0023ff;
279 width: 25px;
280 height: 25px;
281 display: inline-block;
282 text-align: center;
283 padding-top: 1px;
284 border-radius: 50px;
285 font-family: auto;
286 font-weight: 600;
287 vertical-align: top;
288 }
289
290 .message .error_msg .msg {
291 display: inline-block;
292 margin: 0 10px;
293 font-style: italic;
294 width: 80%;
295 }
......
...@@ -23,6 +23,8 @@ function App() { ...@@ -23,6 +23,8 @@ function App() {
23 // clear chats 23 // clear chats
24 function clearChat(){ 24 function clearChat(){
25 setChatLog([]); 25 setChatLog([]);
26 setChatInput("");
27 setStartedInteraction(false);
26 } 28 }
27 29
28 function getEngines(){ 30 function getEngines(){
...@@ -43,11 +45,11 @@ function App() { ...@@ -43,11 +45,11 @@ function App() {
43 async function handleSubmit(e){ 45 async function handleSubmit(e){
44 e.preventDefault(); 46 e.preventDefault();
45 // console.log(chatInput) 47 // console.log(chatInput)
46 const userInput = ['what', 'why', 'when', 'where' , 'which', 'did', 'do', 'how', 'can', 'are', 'who', 'hey']; 48 const userInput = ['what', 'why', 'when', 'where' , 'which', 'did', 'do', 'how', 'can', 'are', 'who'];
47 const userInputRegex = new RegExp(`\\b(${userInput.join('|')})\\b`, 'gi'); 49 const userInputRegex = new RegExp(`\\b(${userInput.join('|')})\\b`, 'gi');
48 const inputMatches = chatInput.match(userInputRegex); 50 const inputMatches = chatInput.match(userInputRegex);
49 51
50 const userPunctuation = ['\.', '?', '!', ':', ';', ',']; 52 const userPunctuation = ['.', '?', '!', ':', ';', ','];
51 const userPunctuationRegex = new RegExp(`[${userPunctuation.join('')}]$`); 53 const userPunctuationRegex = new RegExp(`[${userPunctuation.join('')}]$`);
52 const punctuationMatches = chatInput.match(userPunctuationRegex); 54 const punctuationMatches = chatInput.match(userPunctuationRegex);
53 55
...@@ -71,6 +73,7 @@ function App() { ...@@ -71,6 +73,7 @@ function App() {
71 // fetch response to the api combining the chat log array of messages and seinding it as a message to localhost:3000 as a post 73 // fetch response to the api combining the chat log array of messages and seinding it as a message to localhost:3000 as a post
72 const messages = chatLogNew.map((message) => message.message).join("\n") 74 const messages = chatLogNew.map((message) => message.message).join("\n")
73 75
76 try {
74 const response = await fetch(process.env.REACT_APP_SERVER_URL + "/api", { 77 const response = await fetch(process.env.REACT_APP_SERVER_URL + "/api", {
75 method: "POST", 78 method: "POST",
76 headers: { 79 headers: {
...@@ -86,19 +89,20 @@ function App() { ...@@ -86,19 +89,20 @@ function App() {
86 const programmingKeywords = ['code', 'application', 'controller', 'rails' , 'PHP', 'java', 'javascript', 'script', 'console', 'python', 'programming', 'table']; 89 const programmingKeywords = ['code', 'application', 'controller', 'rails' , 'PHP', 'java', 'javascript', 'script', 'console', 'python', 'programming', 'table'];
87 90
88 const regex = new RegExp(`\\b(${programmingKeywords.join('|')})\\b`, 'gi'); 91 const regex = new RegExp(`\\b(${programmingKeywords.join('|')})\\b`, 'gi');
89 // console.log(regex)
90 const matches = parsedData.match(regex); 92 const matches = parsedData.match(regex);
91 // console.log(matches);
92 if (!matches) { 93 if (!matches) {
93 var replaceTags = (parsedData.replace(/(?:\r\n|\r|\n)/g, '<br>').replace(/\./g, '. ')) 94 var replaceTags = (parsedData.replace(/(?:\r\n|\r|\n)/g, '<br>').replace(/\./g, '. '))
94 // console.log("not programming!")
95 } else { 95 } else {
96 replaceTags = (parsedData.replace(':',':<code>').replace('<?','&#60;?').replace('?>','?&#62;').replace(/\n/g, '<br>')) 96 replaceTags = (parsedData.replace(':',':<code>').replace('<?','&#60;?').replace('?>','?&#62;').replace(/\n/g, '<br>'))
97 // console.log("programming!")
98 } 97 }
99 setChatLog([...chatLogNew, { user: "gpt", message: `${replaceTags}`} ]) 98 setChatLog([...chatLogNew, { user: "gpt", message: `${replaceTags}`} ])
99
100 var scrollToTheBottomChatLog = document.getElementsByClassName("chat-log")[0]; 100 var scrollToTheBottomChatLog = document.getElementsByClassName("chat-log")[0];
101 scrollToTheBottomChatLog.scrollTop = scrollToTheBottomChatLog.scrollHeight; 101 scrollToTheBottomChatLog.scrollTop = scrollToTheBottomChatLog.scrollHeight;
102 } catch (error) {
103 const errorMsg = "We apologize for any inconvenience caused due to the delay in the response time. Please try again.";
104 setChatLog([...chatLogNew, { user: "gpt", message: `<div class="errormsg"><span>i</span><div class="msg">${errorMsg}</div></div>`} ])
105 }
102 } 106 }
103 107
104 function handleTemp(temp) { 108 function handleTemp(temp) {
...@@ -111,7 +115,7 @@ function App() { ...@@ -111,7 +115,7 @@ function App() {
111 } 115 }
112 116
113 } 117 }
114 118 const [startedInteraction, setStartedInteraction] = useState(false);
115 return ( 119 return (
116 <div className="App"> 120 <div className="App">
117 <SideMenu 121 <SideMenu
...@@ -122,10 +126,13 @@ function App() { ...@@ -122,10 +126,13 @@ function App() {
122 temperature={temperature} 126 temperature={temperature}
123 clearChat={clearChat} 127 clearChat={clearChat}
124 /> 128 />
129
125 <ChatBox 130 <ChatBox
126 chatInput={chatInput} 131 chatInput={chatInput}
127 chatLog={chatLog} 132 chatLog={chatLog}
128 setChatInput={setChatInput} 133 setChatInput={setChatInput}
134 startedInteraction={startedInteraction}
135 setStartedInteraction={setStartedInteraction}
129 handleSubmit={handleSubmit} /> 136 handleSubmit={handleSubmit} />
130 </div> 137 </div>
131 ); 138 );
......
1 // import OpenAISVGLogo from './OpenAISVGLogo' 1 import React, { useState } from "react";
2 import SuggestedOptions from './suggestedOptions'
2 3
3 // Primary Chat Window 4 const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInteraction, setStartedInteraction}) => {
4 const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput}) => 5
6 return (
5 <section className="chatbox"> 7 <section className="chatbox">
8 {!startedInteraction ? (
9 <SuggestedOptions setChatInput={setChatInput}/>
10 ) : (
11 <>
6 <div className="chat-log"> 12 <div className="chat-log">
7 {chatLog.map((message, index) => ( 13 {chatLog.map((message, index) => (
8 <ChatMessage key={index} message={message} /> 14 <ChatMessage key={index} message={message} />
9 ))} 15 ))}
10 </div> 16 </div>
17
18 </>
19 )}
11 <div className="chat-input-holder"> 20 <div className="chat-input-holder">
12 <form className="form" onSubmit={handleSubmit}> 21 <form className="form" onSubmit={handleSubmit }>
13 <input 22 <input
14 rows="1" 23 rows="1"
15 value={chatInput} 24 value={chatInput}
16 onChange={(e)=> setChatInput(e.target.value)} 25 onChange={(e)=> {
17 className="chat-input-textarea" ></input> 26 setChatInput(e.target.value);
18 <button className="submit" type="submit">Submit</button> 27 }}
28 className="chat-input-textarea" >
29 </input>
30 <button className="submit" type="submit" onClick={(e)=> {
31 setStartedInteraction(true);
32 }}>Submit</button>
19 </form> 33 </form>
20 </div> 34 </div>
21 </section> 35 </section>
36 )
37 }
22 38
23 // Individual Chat Message
24 const ChatMessage = ({ message }) => { 39 const ChatMessage = ({ message }) => {
25 return ( 40 return (
26 <div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}> 41 <div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}>
......
...@@ -2,6 +2,32 @@ ...@@ -2,6 +2,32 @@
2 background-color: #101827 !important; 2 background-color: #101827 !important;
3 } 3 }
4 4
5 .errormsg {
6 border: 1px solid #7ac5ff;
7 padding: 15px 25px;
8 border-radius: 10px;
9 background: rgb(0 139 245 / 6%);
10 }
11
12 .errormsg .msg {
13 display: inline-block;
14 width: 90%;
15 }
16 .errormsg span {
17 background: #008BF5;
18 padding: 1px 11px;
19 border-radius: 50px;
20 width: 25px;
21 height: 25px;
22 margin-right: 10px;
23 color: #fff;
24 font-weight: 900;
25 display: inline-block;
26 vertical-align: top;
27 font-family: auto;
28 font-size: 15px;
29 }
30
5 .side-menu-button { 31 .side-menu-button {
6 border:0 solid white; 32 border:0 solid white;
7 /* 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 */ 33 /* 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) { ...@@ -172,9 +198,16 @@ code br:nth-child(-n+2) {
172 } 198 }
173 199
174 @media (max-width: 414px) { 200 @media (max-width: 414px) {
201 .errormsg .msg {
202 width: 80%;
203 }
175 .message { 204 .message {
176 font-size: 14px; 205 font-size: 14px;
177 } 206 }
207 .errormsg {
208 padding: 10px;
209 width: 100%;
210 }
178 .chat-message-center { 211 .chat-message-center {
179 padding: 20px 5vw !important; 212 padding: 20px 5vw !important;
180 } 213 }
......
1 const SuggestedOptions = ({ setChatInput }) => {
2 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."];
3 const handleExampleClick = (example) => {
4 setChatInput(example);
5 };
6
7 return (
8 <div className="suggested">
9 <div className="suggestedrow title">
10 <h1>Welcome to AI-PRO</h1>
11 <p>This chatbot is capable of answering questions and generating text based on the input you provide.</p>
12 </div>
13 <div className="suggestedcol rack1">
14 <h2>Examples</h2>
15 <ul className="suggested-options">
16 {examples.map((example, index) => (
17 <li key={index}
18 onClick={() => handleExampleClick(example)}>
19 {example}
20 </li>
21 ))}
22 </ul>
23 </div>
24 <div className="suggestedcol rack2">
25 <h2>Capabilities</h2>
26 <ul>
27 <li>Remembers the user's earlier statement in the ongoing discussion.</li>
28 <li>Allows the user to add more information or correct errors.</li>
29 <li>Trained to deny requests that are not appropriate.</li>
30 </ul>
31 </div>
32 <div className="suggestedcol rack3">
33 <h2>Limitations</h2>
34 <ul>
35 <li>May sometimes give wrong or incorrect information.</li>
36 <li>May at times produce harmful instructions or biased content.</li>
37 <li>Limited knowledge of what's been happening in the world since 2021.</li>
38 </ul>
39 </div>
40 </div>
41 );
42
43 };
44
45 export default SuggestedOptions;
...\ No newline at end of file ...\ No newline at end of file
...@@ -3,6 +3,7 @@ const express = require('express') ...@@ -3,6 +3,7 @@ const express = require('express')
3 const bodyParser = require('body-parser') 3 const bodyParser = require('body-parser')
4 const cors = require('cors') 4 const cors = require('cors')
5 require('dotenv').config() 5 require('dotenv').config()
6 const rateLimit = require('express-rate-limit')
6 7
7 // Open AI Configuration 8 // Open AI Configuration
8 // console.log(process.env.OPENAI_API_ORG) 9 // console.log(process.env.OPENAI_API_ORG)
...@@ -12,6 +13,12 @@ const configuration = new Configuration({ ...@@ -12,6 +13,12 @@ const configuration = new Configuration({
12 }); 13 });
13 const openai = new OpenAIApi(configuration); 14 const openai = new OpenAIApi(configuration);
14 15
16 const rateLimiter = rateLimit({
17 windowMs: 1000 * 60 * 1, // 1 minute (refreshTime)
18 max: 3000, // limit each IP to x requests per windowMs (refreshTime)
19 message: 'Sorry, too many requests. Please try again in a bit!',
20 });
21
15 // Express Configuration 22 // Express Configuration
16 const app = express() 23 const app = express()
17 const port = 3080 24 const port = 3080
...@@ -19,20 +26,31 @@ const port = 3080 ...@@ -19,20 +26,31 @@ const port = 3080
19 app.use(bodyParser.json()) 26 app.use(bodyParser.json())
20 app.use(cors()) 27 app.use(cors())
21 app.use(require('morgan')('dev')) 28 app.use(require('morgan')('dev'))
22 29 app.use(rateLimiter)
23 30
24 // Routing 31 // Routing
25 32
26 // Primary Open AI Route 33 // Primary Open AI Route
27 app.post('/api', async (req, res) => { 34 app.post('/api', async (req, res) => {
28 const { message, currentModel, temperature } = req.body; 35 const { message, currentModel, temperature } = req.body;
36
37 let greetingPrompt = 'Hello, how can I assist you?'
38 const greetings = ['hi', 'hello', 'hey']
39
40 if (greetings.some((greeting) => message.toLowerCase().includes(greeting))) {
41 greetingPrompt = 'Hello, how can I help you today?'
42 }
43
44 const prompt = `${greetingPrompt}\n${message}`;
45
29 const response = await openai.createCompletion({ 46 const response = await openai.createCompletion({
30 model: `${currentModel}`,// "text-davinci-003", 47 model: `${currentModel}`,// "text-davinci-003",
31 prompt: `${message}`, 48 prompt,
32 max_tokens: 2500, 49 max_tokens: 2500,
33 temperature, 50 temperature,
34 }); 51 });
35 52
53
36 res.json({ 54 res.json({
37 message: response.data.choices[0].text, 55 message: response.data.choices[0].text,
38 }) 56 })
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
13 "cors": "^2.8.5", 13 "cors": "^2.8.5",
14 "dotenv": "^16.0.3", 14 "dotenv": "^16.0.3",
15 "express": "^4.18.2", 15 "express": "^4.18.2",
16 "express-rate-limit": "^6.7.0",
16 "morgan": "^1.10.0", 17 "morgan": "^1.10.0",
17 "openai": "^3.1.0" 18 "openai": "^3.1.0"
18 } 19 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!