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 <div className="ai-logo-container"> 3 clearChat,
4 <img className="ai-logo" alt="Ai-pro logo" src="../assets/images/chatgpt-aipro.png" height="50px"/> 4 currentModel,
5 </div> 5 setCurrentModel,
6 <div className="side-menu-button" onClick={clearChat}> 6 models,
7 <span>+</span> 7 setTemperature,
8 New Chat 8 temperature,
9 </div> 9 }) => (
10 <div className="models"> 10 <aside className="sidemenu">
11 <div className="ai-logo-container">
12 <img
13 className="ai-logo"
14 alt="Ai-pro logo"
15 src="../assets/images/chatgpt-aipro.png"
16 height="50px"
17 />
18 </div>
19 <div className="side-menu-button" onClick={clearChat}>
20 <span>+</span>
21 New Chat
22 </div>
23 <div className="models">
11 <label className="side-label">Model</label> 24 <label className="side-label">Model</label>
12 <select 25 <select
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 ))
26 </select> 39 ) : (
40 <option key={"gpt-3.5-turbo"} value={"gpt-3.5-turbo"}>
41 {"gpt-3.5-turbo"}
42 </option>
43 )}
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")}
31 <Button 49 />
32 text="Code - Crushman" 50 <Button
33 onClick={()=>setCurrentModel("code-cushman-001")} /> 51 text="Code - Crushman"
34 <span className="info"> 52 onClick={() => setCurrentModel("code-cushman-001")}
35 The model parameter controls the engine used to generate the response. Davinci produces best results. 53 />
36 </span> 54 <span className="info">
37 <label className="side-label" >Temperature</label> 55 The model parameter controls the engine used to generate the response.
38 <input 56 Davinci produces best results.
39 className="select-models" 57 </span>
40 type="number" 58 <label className="side-label">Temperature</label>
41 onChange={(e)=> setTemperature(e.target.value)} 59 <input
42 min="0" 60 className="select-models"
43 max="1" 61 type="number"
44 step="0.1" 62 onChange={(e) => setTemperature(e.target.value)}
45 value={temperature} 63 min="0"
46 /> 64 max="1"
47 <Button 65 step="0.1"
48 text="0 - Logical" 66 value={temperature}
49 onClick={()=>setTemperature(0)} /> 67 />
50 <Button 68 <Button text="0 - Logical" onClick={() => setTemperature(0)} />
51 text="0.5 - Balanced" 69 <Button text="0.5 - Balanced" onClick={() => setTemperature(0.5)} />
52 onClick={()=>setTemperature(0.5)} /> 70 <Button text="1 - Creative" onClick={() => setTemperature(1)} />
53 <Button 71 <span className="info">
54 text="1 - Creative" 72 The temperature parameter controls the randomness of the model. 0 is the
55 onClick={()=>setTemperature(1)} /> 73 most logical, 1 is the most creative.
56 <span className="info"> 74 </span>
57 The temperature parameter controls the randomness of the model. 0 is the most logical, 1 is the most creative. 75 <ExportButton label="Export Conversation" filename="Chat-Bot-Plus" />
58 </span> 76 </div>
59 </div> 77 </aside>
60 </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;
......
...@@ -10,4 +10,23 @@ body { ...@@ -10,4 +10,23 @@ body {
10 code { 10 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 }
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 }
13 } 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,16 +202,16 @@ async function runGPTTurbo(req, res) { ...@@ -177,16 +202,16 @@ 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;
205
206 // TOKEN USAGE
207 axios.post(`${process.env.API_URL}e/set-chat-usage`,
208 { app: 'chatbot', prompt_token: usage.prompt_tokens, total_token: usage.total_tokens },
209 { headers: { 'content-type': 'application/x-www-form-urlencoded' }
210 });
180 } catch (e) { 211 } catch (e) {
181 console.log('Error encoding prompt text', e); 212 console.log('Error encoding prompt text', e);
182 } 213 }
183 214
184 // TOKEN USAGE
185 axios.post(`${process.env.API_URL}e/set-chat-usage`,
186 { app: 'chatbot', prompt_token: usage.prompt_tokens, total_token: usage.total_tokens },
187 { headers: { 'content-type': 'application/x-www-form-urlencoded' }
188 });
189
190 res.json({ 215 res.json({
191 prompt: JSON.parse(message), 216 prompt: JSON.parse(message),
192 message: anchorme({ 217 message: anchorme({
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!