0c874f9b by Jonille Arreglo

Merge branch 'master' of https://gitlab.baytech.ph/baytech/chatgpt.ai-pro.org in…

…to 28594_usage_tracking

# Conflicts:
#	index.js
2 parents 17eb87aa 1b4c3239
This diff could not be displayed because it is too large.
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
10 width:260px; 10 width:260px;
11 padding:10px; 11 padding:10px;
12 background-color:#202123; 12 background-color:#202123;
13 overflow: auto;
13 } 14 }
14 /* under 640px do this */ 15 /* under 640px do this */
15 @media (max-width: 640px) { 16 @media (max-width: 640px) {
...@@ -129,7 +130,7 @@ ...@@ -129,7 +130,7 @@
129 .message { 130 .message {
130 width: 100%; 131 width: 100%;
131 overflow: hidden; 132 overflow: hidden;
132 word-wrap: break-word; 133 /* word-wrap: break-word; */
133 padding-left: 40px; 134 padding-left: 40px;
134 padding-right: 40px; 135 padding-right: 40px;
135 } 136 }
......
...@@ -47,10 +47,10 @@ function App() { ...@@ -47,10 +47,10 @@ function App() {
47 let model_list = []; 47 let model_list = [];
48 for( var i = 1; i < data.models.data.length; i++ ) { 48 for( var i = 1; i < data.models.data.length; i++ ) {
49 let model = data.models.data[i]; 49 let model = data.models.data[i];
50 if( !(model.id == "whisper-1" 50 if( !(model.id === "whisper-1"
51 || model.id == "gpt-4" 51 || model.id === "gpt-4"
52 || model.id == "gpt-4-0314" 52 || model.id === "gpt-4-0314"
53 || model.id == "gpt-4-0613") ) model_list.push(model); 53 || model.id === "gpt-4-0613") ) model_list.push(model);
54 } 54 }
55 setModels(model_list) 55 setModels(model_list)
56 }) 56 })
...@@ -86,14 +86,14 @@ function App() { ...@@ -86,14 +86,14 @@ function App() {
86 } 86 }
87 } 87 }
88 88
89 let chatLogNew = [...chatLog, { user: "me", message: `${userModifiedInput}`} ] 89 let chatLogNew = [...chatLog, { user: "user", message: `${userModifiedInput}`} ]
90 setChatInput(""); 90 setChatInput("");
91 setChatLog(chatLogNew) 91 setChatLog(chatLogNew)
92 92
93 const userMessage = { user: "gpt", message: "..." }; 93 const userMessage = { user: "gpt", message: "..." };
94 setChatLog(prevChatLog => [...prevChatLog, userMessage]); 94 setChatLog(prevChatLog => [...prevChatLog, userMessage]);
95 95
96 var messages = chatLogNew.map((message) => message.message).join("\n") 96 var messages = chatLogNew.map((message) => { if(message.user !== 'me') return message.message }).join("\n")
97 if(currentModel == GPTTurbo || currentModel == GPTTurbo0301) { 97 if(currentModel == GPTTurbo || currentModel == GPTTurbo0301) {
98 // "gpt-3.5-turbo" 98 // "gpt-3.5-turbo"
99 let chatLogTurboNew = [...chatLogTurbo, { role: "user", content: chatInput }]; 99 let chatLogTurboNew = [...chatLogTurbo, { role: "user", content: chatInput }];
...@@ -116,7 +116,16 @@ function App() { ...@@ -116,7 +116,16 @@ function App() {
116 const data = await response.json(); 116 const data = await response.json();
117 const parsedData = data.message.trim(); 117 const parsedData = data.message.trim();
118 // "gpt-3.5-turbo" 118 // "gpt-3.5-turbo"
119 let chatLogTurboNew = [...chatLogTurbo, { role: "assistant", content: parsedData }]; 119 let chatLogTurboNew = chatLogTurbo;
120 if(data.success === false) {
121 setChatLog(prevChatLog => {
122 const lastMsg = prevChatLog[prevChatLog.length - 2];
123 return [...prevChatLog.slice(0, prevChatLog.length - 2), { user: "me", message: lastMsg.message }];
124 });
125 userModifiedInput = "";
126 }
127 chatLogTurboNew.push({ role: "user", content: userModifiedInput });
128 chatLogTurboNew.push({ role: "assistant", content: parsedData });
120 setChatLogTurbo(chatLogTurboNew); 129 setChatLogTurbo(chatLogTurboNew);
121 // 130 //
122 clearInterval(intervalId); 131 clearInterval(intervalId);
......
1 import React, { useState } from "react"; 1 import React, { useState } from "react";
2 import SuggestedOptions from './suggestedOptions' 2 import SuggestedOptions from './suggestedOptions'
3 3 import ExportButton from "./ExportButton";
4 const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInteraction, setStartedInteraction}) => { 4 const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInteraction, setStartedInteraction}) => {
5 5
6 return ( 6 return (
...@@ -9,10 +9,11 @@ const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInterac ...@@ -9,10 +9,11 @@ const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInterac
9 <SuggestedOptions setChatInput={setChatInput}/> 9 <SuggestedOptions setChatInput={setChatInput}/>
10 ) : ( 10 ) : (
11 <> 11 <>
12 <div className="chat-log"> 12 <div className="chat-log response-to-export">
13 {chatLog.map((message, index) => ( 13 {chatLog.map((message, index) => (
14 <ChatMessage key={index} message={message} /> 14 <ChatMessage key={index} message={message} />
15 ))} 15 ))}
16 <ExportButton className="export-button-mobile" label="Export Conversation" filename="Chat-Bot-Plus" />
16 </div> 17 </div>
17 18
18 </> 19 </>
...@@ -39,9 +40,9 @@ const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInterac ...@@ -39,9 +40,9 @@ const ChatBox = ({chatLog, setChatInput, handleSubmit, chatInput, startedInterac
39 const ChatMessage = ({ message }) => { 40 const ChatMessage = ({ message }) => {
40 return ( 41 return (
41 <div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}> 42 <div className={`chat-message ${message.user === "gpt" && "chatgpt"}`}>
42 <div className="chat-message-center"> 43 <div className="chat-message-center" style={ message.user === "gpt" ? { background: "#ddf1f9"} : {}}>
43 <div className={`avatar ${message.user === "gpt" && "chatgpt"}`}> 44 <div className={`avatar ${message.user === "gpt" && "chatgpt"}`}>
44 {message.user === "gpt" ? <img className="ai-logo" alt="Ai-pro bot" src="../assets/images/bot.png" width="30px"/> : <img className="ai-logo" alt="Ai-pro user" src="../assets/images/user.svg" />} 45 {message.user === "gpt" ? <img className="ai-logo" alt="Ai-pro bot" src="../assets/images/bot.png" width="30px"/> : <img className="ai-logo" alt="Ai-pro user" src="../assets/images/user.png" />}
45 </div> 46 </div>
46 {/* <div className="message"> 47 {/* <div className="message">
47 {message.message} 48 {message.message}
......
1 export default function ExportButton({
2 label = "Export",
3 filename = "export",
4 className = "",
5 id = "",
6 }) {
7 const responseToExport = () => {
8 const response_to_export = document.querySelector(".response-to-export");
9 if (!response_to_export) return;
10 return response_to_export?.innerHTML ?? "";
11 };
12 const generatePDF = window.generatePDF;
13
14 const onClickExportToPDF = () => {
15 const response = responseToExport();
16 generatePDF(response, filename);
17 };
18 const onClickExportButton = () => {
19 let modal = document.querySelector(".export-modal-container");
20 const response = responseToExport();
21 if (!response) return;
22
23 if (!modal) {
24 const btutil_buildExportModal = window.btutil_buildExportModal;
25
26 modal = btutil_buildExportModal(onClickExportToPDF);
27 document.body.appendChild(modal);
28 }
29 modal.classList.add("active");
30 };
31
32 return (
33 <>
34 <div
35 className={`export-button ${className}`}
36 id={id}
37 onClick={onClickExportButton}
38 >
39 <svg
40 fill="#ffffff"
41 xmlns="http://www.w3.org/2000/svg"
42 height="1em"
43 viewBox="0 0 512 512"
44 >
45 <path d="M216 0h80c13.3 0 24 10.7 24 24v168h87.7c17.8 0 26.7 21.5 14.1 34.1L269.7 378.3c-7.5 7.5-19.8 7.5-27.3 0L90.1 226.1c-12.6-12.6-3.7-34.1 14.1-34.1H192V24c0-13.3 10.7-24 24-24zm296 376v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h146.7l49 49c20.1 20.1 52.5 20.1 72.6 0l49-49H488c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z" />
46 </svg>
47 <span>{label}</span>
48 </div>
49 </>
50 );
51 }
1 const SideMenu = ({ clearChat, currentModel, setCurrentModel, models, setTemperature, temperature }) => 1 import ExportButton from "./ExportButton";
2 <aside className="sidemenu"> 2 const SideMenu = ({
3 clearChat,
4 currentModel,
5 setCurrentModel,
6 models,
7 setTemperature,
8 temperature,
9 }) => (
10 <aside className="sidemenu">
3 <div className="ai-logo-container"> 11 <div className="ai-logo-container">
4 <img className="ai-logo" alt="Ai-pro logo" src="../assets/images/chatgpt-aipro.png" height="50px"/> 12 <img
13 className="ai-logo"
14 alt="Ai-pro logo"
15 src="../assets/images/chatgpt-aipro.png"
16 height="50px"
17 />
5 </div> 18 </div>
6 <div className="side-menu-button" onClick={clearChat}> 19 <div className="side-menu-button" onClick={clearChat}>
7 <span>+</span> 20 <span>+</span>
...@@ -13,57 +26,61 @@ const SideMenu = ({ clearChat, currentModel, setCurrentModel, models, setTempera ...@@ -13,57 +26,61 @@ const SideMenu = ({ clearChat, currentModel, setCurrentModel, models, setTempera
13 // active if model is select is currentModel 26 // active if model is select is currentModel
14 value={currentModel} 27 value={currentModel}
15 className="select-models" 28 className="select-models"
16 onChange={(e)=>{ 29 onChange={(e) => {
17 setCurrentModel(e.target.value) 30 setCurrentModel(e.target.value);
18 }}> 31 }}
19 {models && models.length ? models.map((model, index) => ( 32 >
20 <option 33 {models && models.length ? (
21 key={model.id} 34 models.map((model, index) => (
22 value={model.id}>{model.id}</option> 35 <option key={model.id} value={model.id}>
23 )) : <option 36 {model.id}
24 key={"gpt-3.5-turbo"} 37 </option>
25 value={"gpt-3.5-turbo"}>{"gpt-3.5-turbo"}</option>} 38 ))
39 ) : (
40 <option key={"gpt-3.5-turbo"} value={"gpt-3.5-turbo"}>
41 {"gpt-3.5-turbo"}
42 </option>
43 )}
26 </select> 44 </select>
27 45
28 <Button 46 <Button
29 text="Smart - Davinci" 47 text="Smart - Davinci"
30 onClick={()=>setCurrentModel("text-davinci-003")} /> 48 onClick={() => setCurrentModel("text-davinci-003")}
49 />
31 <Button 50 <Button
32 text="Code - Crushman" 51 text="Code - Crushman"
33 onClick={()=>setCurrentModel("code-cushman-001")} /> 52 onClick={() => setCurrentModel("code-cushman-001")}
53 />
34 <span className="info"> 54 <span className="info">
35 The model parameter controls the engine used to generate the response. Davinci produces best results. 55 The model parameter controls the engine used to generate the response.
56 Davinci produces best results.
36 </span> 57 </span>
37 <label className="side-label" >Temperature</label> 58 <label className="side-label">Temperature</label>
38 <input 59 <input
39 className="select-models" 60 className="select-models"
40 type="number" 61 type="number"
41 onChange={(e)=> setTemperature(e.target.value)} 62 onChange={(e) => setTemperature(e.target.value)}
42 min="0" 63 min="0"
43 max="1" 64 max="1"
44 step="0.1" 65 step="0.1"
45 value={temperature} 66 value={temperature}
46 /> 67 />
47 <Button 68 <Button text="0 - Logical" onClick={() => setTemperature(0)} />
48 text="0 - Logical" 69 <Button text="0.5 - Balanced" onClick={() => setTemperature(0.5)} />
49 onClick={()=>setTemperature(0)} /> 70 <Button text="1 - Creative" onClick={() => setTemperature(1)} />
50 <Button
51 text="0.5 - Balanced"
52 onClick={()=>setTemperature(0.5)} />
53 <Button
54 text="1 - Creative"
55 onClick={()=>setTemperature(1)} />
56 <span className="info"> 71 <span className="info">
57 The temperature parameter controls the randomness of the model. 0 is the most logical, 1 is the most creative. 72 The temperature parameter controls the randomness of the model. 0 is the
73 most logical, 1 is the most creative.
58 </span> 74 </span>
75 <ExportButton label="Export Conversation" filename="Chat-Bot-Plus" />
59 </div> 76 </div>
60 </aside> 77 </aside>
78 );
61 79
62 const Button = ({ onClick, text }) => 80 const Button = ({ onClick, text }) => (
63 <div 81 <div className="button-picker" onClick={onClick}>
64 className="button-picker"
65 onClick={onClick}>
66 {text} 82 {text}
67 </div> 83 </div>
84 );
68 85
69 export default SideMenu
...\ No newline at end of file ...\ No newline at end of file
86 export default SideMenu;
......
1 @import url('https://fonts.googleapis.com/css2?family=Alegreya+Sans:ital,wght@0,400;0,500;1,400&display=swap'); 1 /* @import url('https://fonts.googleapis.com/css2?family=Alegreya+Sans:ital,wght@0,400;0,500;1,400&display=swap'); */
2 2
3 body { 3 body {
4 -webkit-font-smoothing: antialiased; 4 -webkit-font-smoothing: antialiased;
5 -moz-osx-font-smoothing: grayscale; 5 -moz-osx-font-smoothing: grayscale;
6 font-family: "Alegreya Sans", sans-serif; 6 /* font-family: "Alegreya Sans", sans-serif; */
7 } 7 }
8 .sidemenu { 8 .sidemenu {
9 background-color: #101827 !important; 9 background-color: #101827 !important;
......
...@@ -11,3 +11,22 @@ code { ...@@ -11,3 +11,22 @@ code {
11 font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 11 font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 monospace; 12 monospace;
13 } 13 }
14
15 .export-button-mobile {
16 display: none !important;
17 position: fixed;
18 bottom: 85px;
19 right: 0;
20 min-width: 50px;
21 box-shadow: 0px 4px 4px 0px #00000040;
22 }
23
24 .export-button-mobile span {
25 display: none;
26 }
27
28 @media screen and (max-width: 640px) {
29 .export-button-mobile {
30 display: flex !important;
31 }
32 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -98,6 +98,19 @@ app.post('/api', async (req, res) => { ...@@ -98,6 +98,19 @@ app.post('/api', async (req, res) => {
98 query_prompt = arr_body.join("\n") 98 query_prompt = arr_body.join("\n")
99 } 99 }
100 } 100 }
101 const moderation = await axios.post("https://api.openai.com/v1/moderations", {
102 input: query_prompt
103 }, { headers: { 'content-type': 'application/json', 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` } });
104
105 if(moderation.data.results[0].flagged) {
106 res.json({
107 success: false,
108 message: "I'm sorry, but I can't assist with that. We want everyone to use our tool safely and responsibly.\nIf you have any other questions or need advice on a different topic, feel free to ask."
109 });
110 res.end();
111 return;
112 }
113
101 try { 114 try {
102 const response = await openai.createCompletion({ 115 const response = await openai.createCompletion({
103 model: `${currentModel}`,// "text-davinci-003", 116 model: `${currentModel}`,// "text-davinci-003",
...@@ -153,6 +166,18 @@ async function runGPTTurbo(req, res) { ...@@ -153,6 +166,18 @@ async function runGPTTurbo(req, res) {
153 var input = ''; 166 var input = '';
154 const message_history = JSON.parse(message); 167 const message_history = JSON.parse(message);
155 const query_prompt = message_history.length ? message_history[message_history.length - 1].content : ""; 168 const query_prompt = message_history.length ? message_history[message_history.length - 1].content : "";
169 const moderation = await axios.post("https://api.openai.com/v1/moderations", {
170 input: query_prompt
171 }, { headers: { 'content-type': 'application/json', 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}` } });
172
173 if(moderation.data.results[0].flagged) {
174 res.json({
175 success: false,
176 message: "I'm sorry, but I can't assist with that. We want everyone to use our tool safely and responsibly.\nIf you have any other questions or need advice on a different topic, feel free to ask."
177 });
178 res.end();
179 return;
180 }
156 try { 181 try {
157 const response = await openai.createChatCompletion({ 182 const response = await openai.createChatCompletion({
158 model: `${currentModel}`, 183 model: `${currentModel}`,
...@@ -177,15 +202,15 @@ async function runGPTTurbo(req, res) { ...@@ -177,15 +202,15 @@ async function runGPTTurbo(req, res) {
177 usage.prompt_tokens = (enc.encode(query_prompt)).length; 202 usage.prompt_tokens = (enc.encode(query_prompt)).length;
178 usage.completion_tokens = (enc.encode(input)).length; 203 usage.completion_tokens = (enc.encode(input)).length;
179 usage.total_tokens = usage.prompt_tokens + usage.completion_tokens; 204 usage.total_tokens = usage.prompt_tokens + usage.completion_tokens;
180 } catch (e) {
181 console.log('Error encoding prompt text', e);
182 }
183 205
184 // TOKEN USAGE 206 // TOKEN USAGE
185 axios.post(`${process.env.API_URL}e/set-chat-usage`, 207 axios.post(`${process.env.API_URL}e/set-chat-usage`,
186 { app: 'chatbot', prompt_token: usage.prompt_tokens, total_token: usage.total_tokens }, 208 { app: 'chatbot', prompt_token: usage.prompt_tokens, total_token: usage.total_tokens },
187 { headers: { 'content-type': 'application/x-www-form-urlencoded' } 209 { headers: { 'content-type': 'application/x-www-form-urlencoded' }
188 }); 210 });
211 } catch (e) {
212 console.log('Error encoding prompt text', e);
213 }
189 214
190 res.json({ 215 res.json({
191 prompt: JSON.parse(message), 216 prompt: JSON.parse(message),
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!